442 lines
8.7 KiB
C
442 lines
8.7 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1993 Digital Equipment Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
fwhalt.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
|
|||
|
This module implements routines to process halts from the operating
|
|||
|
system.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Joe Notarangelo 24-Feb-1993
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Firmware in Kernel mode only.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#include "fwp.h"
|
|||
|
#include "fwpexcpt.h"
|
|||
|
#include "axp21064.h"
|
|||
|
#include "fwstring.h"
|
|||
|
|
|||
|
//
|
|||
|
// Maximum size of Machine Check output string.
|
|||
|
//
|
|||
|
|
|||
|
#define MAX_ERROR_STRING 100
|
|||
|
|
|||
|
//
|
|||
|
// Function prototypes
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
FwDisplayMchk(
|
|||
|
IN PLOGOUT_FRAME_21064 LogoutFrame,
|
|||
|
IN ULONG HaltReason
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
FwHaltToMonitor(
|
|||
|
IN PALPHA_RESTART_SAVE_AREA AlphaSaveArea,
|
|||
|
IN ULONG Reason
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
FwHalt(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function receives control on a halt from the operating
|
|||
|
system.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
PRESTART_BLOCK RestartBlock;
|
|||
|
PALPHA_RESTART_SAVE_AREA AlphaSaveArea;
|
|||
|
ALPHA_VIDEO_TYPE VideoType;
|
|||
|
UCHAR Character;
|
|||
|
ULONG Count;
|
|||
|
|
|||
|
//
|
|||
|
// N.B. we will continue running on the stack re-established by
|
|||
|
// the operating system for us.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Reset the video state. If video init fails, continue as we may
|
|||
|
// be directing output to the serial port.
|
|||
|
//
|
|||
|
|
|||
|
DisplayBootInitialize(&VideoType);
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Verify the restart block.
|
|||
|
//
|
|||
|
|
|||
|
if (FwVerifyRestartBlock() == FALSE) {
|
|||
|
FwPrint (FW_INVALID_RESTART_BLOCK_MSG); // temp message
|
|||
|
FwStallExecution(2 * 1000 * 1000);
|
|||
|
//FwRestart(); // this will be real one day
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Dispatch on the halt reason code in the restart block.
|
|||
|
//
|
|||
|
|
|||
|
// AlphaSaveArea = (PALPHA_RESTART_SAVE_AREA)
|
|||
|
// &SYSTEM_BLOCK->RestartBlock->SaveArea;
|
|||
|
AlphaSaveArea = (PALPHA_RESTART_SAVE_AREA)
|
|||
|
&SYSTEM_BLOCK->RestartBlock->u.SaveArea;
|
|||
|
|
|||
|
switch (AlphaSaveArea->HaltReason) {
|
|||
|
|
|||
|
|
|||
|
case AXP_HALT_REASON_HALT:
|
|||
|
|
|||
|
//
|
|||
|
// Dispatch to monitor so that Joe can find his bug.
|
|||
|
//
|
|||
|
|
|||
|
FwHaltToMonitor(AlphaSaveArea, FW_EXC_HALT);
|
|||
|
|
|||
|
//
|
|||
|
// If we return then it is time to restart to get a real stack.
|
|||
|
//
|
|||
|
|
|||
|
FwRestart();
|
|||
|
|
|||
|
|
|||
|
case AXP_HALT_REASON_DBLMCHK:
|
|||
|
case AXP_HALT_REASON_PALMCHK:
|
|||
|
|
|||
|
//
|
|||
|
// Machine Check.
|
|||
|
//
|
|||
|
|
|||
|
FwDisplayMchk(AlphaSaveArea->LogoutFrame, AlphaSaveArea->HaltReason);
|
|||
|
|
|||
|
//
|
|||
|
// Find out what the user wants to do next. We will give her
|
|||
|
// 2 choices: 1. enter monitor 2. restart
|
|||
|
//
|
|||
|
|
|||
|
FwPrint(FW_SYSRQ_MONITOR_MSG);
|
|||
|
FwRead(ARC_CONSOLE_INPUT, &Character, 1, &Count);
|
|||
|
|
|||
|
if (Character == ASCII_SYSRQ) {
|
|||
|
FwHaltToMonitor(AlphaSaveArea, FW_EXC_MCHK);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Restart the firmware when we return.
|
|||
|
//
|
|||
|
|
|||
|
FwRestart();
|
|||
|
|
|||
|
|
|||
|
case AXP_HALT_REASON_REBOOT:
|
|||
|
|
|||
|
FwReboot();
|
|||
|
|
|||
|
|
|||
|
case AXP_HALT_REASON_RESTART:
|
|||
|
default:
|
|||
|
|
|||
|
FwRestart();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
FwDisplayMchk(
|
|||
|
IN PLOGOUT_FRAME_21064 LogoutFrame,
|
|||
|
IN ULONG HaltReason
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function displays the logout frame for a 21064.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
LogoutFrame - Supplies a pointer to the logout frame.
|
|||
|
HaltReason - Supplies the reason for the halt.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
UCHAR OutBuffer[ MAX_ERROR_STRING ];
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// PRINT_LOGOUT_VERBOSE controls the amount of text displayed
|
|||
|
// of the logout frame. The macro can be undefined to save code and
|
|||
|
// initialized data space in the rom. If the space exists it would be
|
|||
|
// preferable to give the entire print out.
|
|||
|
//
|
|||
|
|
|||
|
#define PRINT_LOGOUT_VERBOSE 1
|
|||
|
|
|||
|
|
|||
|
switch (HaltReason) {
|
|||
|
|
|||
|
case AXP_HALT_REASON_DBLMCHK:
|
|||
|
|
|||
|
FwPrint(FW_FATAL_DMC_MSG);
|
|||
|
break;
|
|||
|
|
|||
|
case AXP_HALT_REASON_PALMCHK:
|
|||
|
|
|||
|
FwPrint(FW_FATAL_MCINPALMODE_MSG);
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
FwPrint(FW_FATAL_UNKNOWN_MSG);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef PRINT_LOGOUT_VERBOSE
|
|||
|
|
|||
|
FwPrint("BIU_STAT : %16Lx BIU_ADDR: %16Lx\r\n",
|
|||
|
BIUSTAT_ALL_21064(LogoutFrame->BiuStat),
|
|||
|
LogoutFrame->BiuAddr.QuadPart);
|
|||
|
|
|||
|
FwPrint("FILL_ADDR: %16Lx FILL_SYN: %16Lx\r\n",
|
|||
|
LogoutFrame->FillAddr.QuadPart,
|
|||
|
FILLSYNDROME_ALL_21064(LogoutFrame->FillSyndrome) );
|
|||
|
|
|||
|
FwPrint("DC_STAT : %16Lx BC_TAG : %16Lx\r\n",
|
|||
|
DCSTAT_ALL_21064(LogoutFrame->DcStat),
|
|||
|
BCTAG_ALL_21064(LogoutFrame->BcTag) );
|
|||
|
|
|||
|
FwPrint("ICCSR : %16Lx ABOX_CTL: %16Lx EXC_SUM: %16Lx\r\n",
|
|||
|
ICCSR_ALL_21064(LogoutFrame->Iccsr),
|
|||
|
ABOXCTL_ALL_21064(LogoutFrame->AboxCtl),
|
|||
|
EXCSUM_ALL_21064(LogoutFrame->ExcSum) );
|
|||
|
|
|||
|
FwPrint("EXC_ADDR : %16Lx VA : %16Lx MM_CSR : %16Lx\r\n",
|
|||
|
LogoutFrame->ExcAddr.QuadPart,
|
|||
|
LogoutFrame->Va.QuadPart,
|
|||
|
MMCSR_ALL_21064(LogoutFrame->MmCsr) );
|
|||
|
|
|||
|
FwPrint("HIRR : %16Lx HIER : %16Lx PS : %16Lx\r\n",
|
|||
|
IRR_ALL_21064(LogoutFrame->Hirr),
|
|||
|
IER_ALL_21064(LogoutFrame->Hier),
|
|||
|
PS_ALL_21064(LogoutFrame->Ps) );
|
|||
|
|
|||
|
FwPrint("PAL_BASE: %16Lx\r\n",
|
|||
|
LogoutFrame->PalBase.QuadPart);
|
|||
|
|
|||
|
#endif //PRINT_LOGOUT_VERBOSE
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Print out interpretation of the error.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Check for tag control parity error.
|
|||
|
//
|
|||
|
|
|||
|
if (BIUSTAT_TCPERR_21064(LogoutFrame->BiuStat) == 1) {
|
|||
|
|
|||
|
FwPrint(FW_FATAL_TAGCNTRL_PE_MSG,
|
|||
|
BCTAG_TAGCTLP_21064(LogoutFrame->BcTag),
|
|||
|
BCTAG_TAGCTLD_21064(LogoutFrame->BcTag),
|
|||
|
BCTAG_TAGCTLS_21064(LogoutFrame->BcTag),
|
|||
|
BCTAG_TAGCTLV_21064(LogoutFrame->BcTag) );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check for tag parity error.
|
|||
|
//
|
|||
|
|
|||
|
if (BIUSTAT_TPERR_21064(LogoutFrame->BiuStat) == 1) {
|
|||
|
|
|||
|
FwPrint(FW_FATAL_TAG_PE_MSG,
|
|||
|
BCTAG_TAG_21064(LogoutFrame->BcTag),
|
|||
|
BCTAG_TAG_21064(LogoutFrame->BcTag) );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check for hard error.
|
|||
|
//
|
|||
|
|
|||
|
if (BIUSTAT_HERR_21064(LogoutFrame->BiuStat) == 1) {
|
|||
|
|
|||
|
FwPrint(FW_FATAL_HEACK_MSG,
|
|||
|
BIUSTAT_CMD_21064(LogoutFrame->BiuStat),
|
|||
|
LogoutFrame->BiuAddr.QuadPart);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check for soft error.
|
|||
|
//
|
|||
|
|
|||
|
if( BIUSTAT_SERR_21064(LogoutFrame->BiuStat) == 1 ){
|
|||
|
|
|||
|
FwPrint(FW_FATAL_SEACK_MSG,
|
|||
|
BIUSTAT_CMD_21064(LogoutFrame->BiuStat),
|
|||
|
LogoutFrame->BiuAddr.QuadPart);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Check for fill ECC errors.
|
|||
|
//
|
|||
|
|
|||
|
if( BIUSTAT_FILLECC_21064(LogoutFrame->BiuStat) == 1 ){
|
|||
|
|
|||
|
FwPrint(FW_FATAL_ECC_ERROR_MSG,
|
|||
|
(BIUSTAT_FILLIRD_21064(LogoutFrame->BiuStat) ?
|
|||
|
"Icache Fill" : "Dcache Fill") );
|
|||
|
|
|||
|
FwPrint(FW_FATAL_QWLWLW_MSG,
|
|||
|
LogoutFrame->FillAddr.QuadPart,
|
|||
|
BIUSTAT_FILLQW_21064(LogoutFrame->BiuStat),
|
|||
|
FILLSYNDROME_LO_21064(LogoutFrame->FillSyndrome),
|
|||
|
FILLSYNDROME_HI_21064(LogoutFrame->FillSyndrome) );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check for fill Parity errors.
|
|||
|
//
|
|||
|
|
|||
|
if( BIUSTAT_FILLDPERR_21064(LogoutFrame->BiuStat) == 1 ){
|
|||
|
|
|||
|
FwPrint(FW_FATAL_PE_MSG,
|
|||
|
(BIUSTAT_FILLIRD_21064(LogoutFrame->BiuStat) ?
|
|||
|
"Icache Fill" : "Dcache Fill") );
|
|||
|
|
|||
|
FwPrint(FW_FATAL_QWLWLW_MSG,
|
|||
|
LogoutFrame->FillAddr.QuadPart,
|
|||
|
BIUSTAT_FILLQW_21064(LogoutFrame->BiuStat),
|
|||
|
FILLSYNDROME_LO_21064(LogoutFrame->FillSyndrome),
|
|||
|
FILLSYNDROME_HI_21064(LogoutFrame->FillSyndrome) );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check for multiple hard errors.
|
|||
|
//
|
|||
|
|
|||
|
if (BIUSTAT_FATAL1_21064(LogoutFrame->BiuStat) == 1) {
|
|||
|
FwPrint(FW_FATAL_MULTIPLE_EXT_TAG_ERRORS_MSG);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check for multiple fill errors.
|
|||
|
//
|
|||
|
|
|||
|
if (BIUSTAT_FATAL2_21064(LogoutFrame->BiuStat) == 1) {
|
|||
|
FwPrint(FW_FATAL_MULTIPLE_FILL_ERRORS_MSG);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// return to caller
|
|||
|
//
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FwHaltToMonitor(
|
|||
|
IN PALPHA_RESTART_SAVE_AREA AlphaSaveArea,
|
|||
|
IN ULONG Reason
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function transfers control to the firmware Monitor.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
AlphaSaveArea - Supplies a pointer to the Alpha save area portion
|
|||
|
of the restart block.
|
|||
|
|
|||
|
Reason - The reason for going to the monitor.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PFW_EXCEPTION_FRAME ExceptionFrame;
|
|||
|
|
|||
|
//
|
|||
|
// Allocate the exception frame.
|
|||
|
//
|
|||
|
|
|||
|
ExceptionFrame = FwAllocatePool(sizeof(FW_EXCEPTION_FRAME));
|
|||
|
|
|||
|
//
|
|||
|
// Copy the integer registers to the exception frame.
|
|||
|
//
|
|||
|
|
|||
|
RtlMoveMemory(&ExceptionFrame->ExceptionV0, &AlphaSaveArea->IntV0,
|
|||
|
32 * 8);
|
|||
|
|
|||
|
//
|
|||
|
// Copy the floating point registers to the exception frame.
|
|||
|
//
|
|||
|
|
|||
|
RtlMoveMemory(&ExceptionFrame->ExceptionF0, &AlphaSaveArea->FltF0,
|
|||
|
32 * 8);
|
|||
|
|
|||
|
//
|
|||
|
// Copy miscellaneous registers.
|
|||
|
//
|
|||
|
|
|||
|
ExceptionFrame->ExceptionFaultingInstructionAddress =
|
|||
|
(LONG)(AlphaSaveArea->ReiRestartAddress - 4);
|
|||
|
|
|||
|
ExceptionFrame->ExceptionProcessorStatus = AlphaSaveArea->Psr;
|
|||
|
|
|||
|
ExceptionFrame->ExceptionType = Reason;
|
|||
|
|
|||
|
ExceptionFrame->ExceptionParameter1 = (LONG)AlphaSaveArea;
|
|||
|
|
|||
|
//
|
|||
|
// Dispatch to the monitor.
|
|||
|
//
|
|||
|
|
|||
|
Monitor( 0, ExceptionFrame );
|
|||
|
|
|||
|
return;
|
|||
|
}
|