//** Copyright (C) 1996-98 Intel Corporation. All rights reserved. //** //** The information and source code contained herein is the exclusive //** property of Intel Corporation and may not be disclosed, examined //** or reproduced in whole or in part without explicit written authorization //** from the company. //** //########################################################################### //----------------------------------------------------------------------------- // Version control information follows. // // // 10 Jun 1999 Bugcheck Bernard Lint // M. Jayakumar (Muthurajan.Jayakumar@intel.com) /////////////////////////////////////////////////////////////////////////////// // // Module Name: OSINIT.C - Merced OS INIT Handler // // Description: // This module has OS INIT Event Handler Reference Code. // // Contents: HalpOsInitInit() // HalpInitHandler() // // // Target Platform: Merced // // Reuse: None // ////////////////////////////////////////////////////////////////////////////M// #include "halp.h" #include "nthal.h" #include "arc.h" #include "i64fw.h" #include "check.h" #include "inbv.h" #include "osmca.h" // i64fwasm.s: low-level protection data structures extern KSPIN_LOCK HalpInitSpinLock; // // Temporary location for INIT_EXCEPTION definition. // typedef ERROR_RECORD_HEADER INIT_EXCEPTION, *PINIT_EXCEPTION; // Init Event Record HALP_INIT_INFO HalpInitInfo; volatile ULONG HalpOsInitInProgress = 0; VOID HalpInitBugCheck( ULONG InitBugCheckType, PINIT_EXCEPTION InitLog, ULONGLONG InitAllocatedLogSize, ULONGLONG SalStatus ) //++ // Name: HalpInitBugCheck() // // Routine Description: // // This function is called to bugcheck the system in a case of a fatal INIT // or fatal FW interface errors. The OS must guarantee as much as possible // error containment in this path. // With the current implementation, this function should be only called from // the OS_INIT path. // // Arguments On Entry: // ULONG InitBugCheckType // PINIT_EXCEPTION InitLog // ULONGLONG InitAllocatedLogSize // ULONGLONG SalStatus // // Return: // None. // // Implementation notes: // This code CANNOT [as default rules - at least entry and through fatal INITs handling] // - make any system call // - attempt to acquire any spinlock used by any code outside the INIT handler // - change the interrupt state. // Passing data to non-INIT code must be done using manual semaphore instructions. // This code should minimize the path and the global or memory allocated data accesses. // This code should only access INIT-namespace structures. // This code is called under the MP protection of HalpInitSpinLock and with the flag // HalpOsInitInProgress set. // //-- { if ( HalpOsInitInProgress ) { // // Enable InbvDisplayString calls to make it through to bootvid driver. // if ( InbvIsBootDriverInstalled() ) { InbvAcquireDisplayOwnership(); InbvResetDisplay(); InbvSolidColorFill(0,0,639,479,4); // make the screen blue InbvSetTextColor(15); InbvInstallDisplayStringFilter((INBV_DISPLAY_STRING_FILTER)NULL); InbvEnableDisplayString(TRUE); // enable display string InbvSetScrollRegion(0,0,639,479); // set to use entire screen } HalDisplayString (MSG_INIT_HARDWARE_ERROR); HalDisplayString (MSG_HARDWARE_ERROR2); // // Thierry 09/2000: // // - if desired, process the INIT log HERE... // // and use HalDisplayString() to dump info for the field or hardware vendor. // The processing could be based on processor or platform independent record definitions. // HalDisplayString( MSG_HALT ); KeBugCheckEx( MACHINE_CHECK_EXCEPTION, (ULONG_PTR)InitBugCheckType, (ULONG_PTR)InitLog, (ULONG_PTR)InitAllocatedLogSize, (ULONG_PTR)SalStatus ); } if ( ((*KdDebuggerNotPresent) == FALSE) && ((*KdDebuggerEnabled) != FALSE) ) { KeEnterKernelDebugger(); } while( TRUE ) { // ; // Simply sit here so the INIT HARDWARE ERROR screen does not get corrupted... // } // noreturn } // HalpInitBugCheck() ERROR_SEVERITY HalpInitProcessLog( PINIT_EXCEPTION InitLog ) //++ // Name: HalpInitProcessLog() // // Routine Description: // // This function is called to process the INIT event log in the OS_INIT path. // // Arguments On Entry: // PINIT_EXCEPTION InitLog - Pointer to the INIT event log. // // Return: // ERROR_SEVERITY // // Implementation notes: // This code does not do anything right now. // Testing will allow to determine the right filtering depending on FW functionalities // and user requested operations like warm reset. // //-- { ERROR_SEVERITY initSeverity; initSeverity = InitLog->ErrorSeverity; switch( initSeverity ) { case ErrorFatal: break; case ErrorRecoverable: break; case ErrorCorrected: break; default: // // These ERRROR_SEVERITY values have no HAL INIT specific handling. // As specified by the SAL Specs July 2000, we should not get these values in this path. // break; } return( initSeverity ); } // HalpInitProcessLog() //++ // Name: HalpInitHandler() // // Routine Description: // // This is the OsInit handler for firmware uncorrected errors // It is our option to run this in physical or virtual mode // // Arguments On Entry: // arg0 = Function ID // // Return: // rtn0=Success/Failure (0/!0) // rtn1=Alternate MinState Pointer if any else NULL //-- SAL_PAL_RETURN_VALUES HalpInitHandler( ULONG64 RendezvousState, PPAL_MINI_SAVE_AREA Pmsa ) { SAL_PAL_RETURN_VALUES rv; LONGLONG salStatus; KIRQL oldIrql; PINIT_EXCEPTION initLog; ULONGLONG initAllocatedLogSize; PSAL_EVENT_RESOURCES initResources; volatile KPCR * const pcr = KeGetPcr(); // // Block various I/O interrupts. // KeRaiseIrql(SYNCH_LEVEL, &oldIrql); // // Enable interrupts so the debugger will work. // HalpEnableInterrupts(); HalpAcquireMcaSpinLock(&HalpInitSpinLock); HalpOsInitInProgress++; // // Save OsToSal minimum state // initResources = pcr->OsMcaResourcePtr; initResources->OsToSalHandOff.SalReturnAddress = initResources->SalToOsHandOff.SalReturnAddress; initResources->OsToSalHandOff.SalGlobalPointer = initResources->SalToOsHandOff.SalGlobalPointer; // // update local variables with pre-initialized INIT log data. // initLog = (PINIT_EXCEPTION)(initResources->EventPool); initAllocatedLogSize = initResources->EventPoolSize; if ( !initLog || !initAllocatedLogSize ) { // // The following code should never happen or the implementation of the HAL INIT logs // pre-allocation failed miserably. This would be a development error. // HalpInitBugCheck( (ULONG_PTR)HAL_BUGCHECK_INIT_ASSERT, initLog, initAllocatedLogSize, (ULONGLONG)Pmsa ); } // // Get the INIT logs // salStatus = (LONGLONG)0; while( salStatus >= 0 ) { ERROR_SEVERITY errorSeverity; rv = HalpGetStateInfo( INIT_EVENT, initLog ); salStatus = rv.ReturnValues[0]; switch( salStatus ) { case SAL_STATUS_SUCCESS: errorSeverity = HalpInitProcessLog( initLog ); if ( errorSeverity == ErrorFatal ) { // // We are now going down with a MACHINE_CHECK_EXCEPTION. // No return... // KeBugCheckEx( MANUALLY_INITIATED_CRASH, (ULONG_PTR) initLog, initAllocatedLogSize, salStatus, (ULONG_PTR) Pmsa ); } rv = HalpClearStateInfo( INIT_EVENT ); if ( !SAL_SUCCESSFUL(rv) ) { // // Current consideration for this implementation - 08/2000: // if clearing the event fails, we assume that FW has a real problem; // continuing will be dangerous. We bugcheck. // HalpInitBugCheck( HAL_BUGCHECK_INIT_CLEAR_STATEINFO, initLog, initAllocatedLogSize, rv.ReturnValues[0] ); } // SAL_STATUS_SUCCESS, SAL_STATUS_SUCCESS_MORE_RECORDS ... and // ErrorSeverity != ErrorFatal. break; case SAL_STATUS_NO_INFORMATION_AVAILABLE: // // The salStatus value will break the salStatus loop. // rv.ReturnValues[0] = SAL_STATUS_SUCCESS; break; case SAL_STATUS_SUCCESS_WITH_OVERFLOW: case SAL_STATUS_INVALID_ARGUMENT: case SAL_STATUS_ERROR: case SAL_STATUS_VA_NOT_REGISTERED: default: // Thierry 08/00: WARNING - SAL July 2000 - v2.90. // default includes possible unknown positive salStatus values. HalpInitBugCheck( HAL_BUGCHECK_INIT_GET_STATEINFO, initLog, initAllocatedLogSize, salStatus ); break; } } if (RendezvousState == 2) { KeBugCheckEx( MANUALLY_INITIATED_CRASH, (ULONG_PTR) initLog, initAllocatedLogSize, salStatus, (ULONG_PTR) Pmsa ); } else { KeBugCheckEx( NMI_HARDWARE_FAILURE, (ULONG_PTR) initLog, initAllocatedLogSize, salStatus, (ULONG_PTR) Pmsa ); } // // Currently 08/2000, we do not support the modification of the minstate. // initResources->OsToSalHandOff.MinStateSavePtr = initResources->SalToOsHandOff.MinStateSavePtr; initResources->OsToSalHandOff.Result = rv.ReturnValues[0]; initResources->OsToSalHandOff.NewContextFlag = 0; // continue the same context and NOT new // // Release INIT spinlock protecting OS_INIT resources. // HalpOsInitInProgress = 0; HalpReleaseMcaSpinLock(&HalpInitSpinLock); return(rv); } // HalpInitHandler() //EndProc//////////////////////////////////////////////////////////////////////