windows-nt/Source/XPSP1/NT/base/hals/halia64/ia64/osinit.c

371 lines
11 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//** 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//////////////////////////////////////////////////////////////////////