/*++ Copyright (c) 1993 Digital Equipment Corporation Module Name: ev4parit.c Abstract: This module implements machine check handling for machines with parity memory protection that are based on the DECchip 21064 microprocessor. Author: Joe Notarangelo 11-Feb-1993 Environment: Kernel mode only. Revision History: --*/ #include "halp.h" #include "axp21064.h" VOID HalpDisplayLogout21064( PLOGOUT_FRAME_21064 LogoutFrame ); BOOLEAN HalMachineCheck ( IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame ) /*++ Routine Description: This function fields machine check for 21064-based machines with parity memory protection. Arguments: ExceptionRecord - Supplies a pointer to the exception record for the machine check. Included in the exception information is the pointer to the logout frame. ExceptionFrame - Supplies a pointer to the kernel exception frame. TrapFrame - Supplies a pointer to the kernel trap frame. Return Value: A value of TRUE is returned if the machine check has been handled by the HAL. If it has been handled then execution may resume at the faulting address. Otherwise, a value of FALSE is returned. N.B. - under some circumstances this routine may not return at all. --*/ { PMCHK_STATUS MachineCheckStatus; // // This is a parity machine. If we receive a machine check it // is uncorrectable. We will print the logout frame and then we // will bugcheck. // // However, we will first check that the machine check is not // marked as correctable. If the machine check is correctable it uses // a differently formatted logout frame. We will ignore the frame // for any machine check marked as correctable since it is an impossible // condition on a parity machine. // MachineCheckStatus = (PMCHK_STATUS)&ExceptionRecord->ExceptionInformation[0]; if( MachineCheckStatus->Correctable == 0 ){ HalpDisplayLogout21064( (PLOGOUT_FRAME_21064)(ExceptionRecord->ExceptionInformation[1]) ); } // // Bugcheck to dump the rest of the machine state, this will help // if the machine check is software-related. // KeBugCheckEx( DATA_BUS_ERROR, (ULONG)MachineCheckStatus->Correctable, (ULONG)MachineCheckStatus->Retryable, 0, 0 ); } #define MAX_ERROR_STRING 100 VOID HalpDisplayLogout21064 ( IN PLOGOUT_FRAME_21064 LogoutFrame ) /*++ Routine Description: This function displays the logout frame for a 21064. Arguments: LogoutFrame - Supplies a pointer to the logout frame generated by the 21064. Return Value: None. --*/ { UCHAR OutBuffer[ MAX_ERROR_STRING ]; // // Acquire ownership of the display. This is done here in case we take // a machine check before the display has been taken away from the HAL. // When the HAL begins displaying strings after it has lost the // display ownership then the HAL will be careful not to scroll information // off of the screen. // HalAcquireDisplayOwnership(NULL); // // Display the machine state via the logout frame. // HalDisplayString( "\nFatal system hardware error.\n\n" ); sprintf( OutBuffer, "BIU_STAT : %016Lx BIU_ADDR: %016Lx\n", BIUSTAT_ALL_21064( LogoutFrame->BiuStat ), LogoutFrame->BiuAddr.QuadPart ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "FILL_ADDR: %016Lx FILL_SYN: %016Lx\n", LogoutFrame->FillAddr.QuadPart, FILLSYNDROME_ALL_21064(LogoutFrame->FillSyndrome) ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "DC_STAT : %016Lx BC_TAG : %016Lx\n", DCSTAT_ALL_21064(LogoutFrame->DcStat), BCTAG_ALL_21064(LogoutFrame->BcTag) ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "ICCSR : %016Lx ABOX_CTL: %016Lx EXC_SUM: %016Lx\n", ICCSR_ALL_21064(LogoutFrame->Iccsr), ABOXCTL_ALL_21064(LogoutFrame->AboxCtl), EXCSUM_ALL_21064(LogoutFrame->ExcSum) ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "EXC_ADDR : %016Lx VA : %016Lx MM_CSR : %016Lx\n", LogoutFrame->ExcAddr.QuadPart, LogoutFrame->Va.QuadPart, MMCSR_ALL_21064(LogoutFrame->MmCsr) ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "HIRR : %016Lx HIER : %016Lx PS : %016Lx\n", IRR_ALL_21064(LogoutFrame->Hirr), IER_ALL_21064(LogoutFrame->Hier), PS_ALL_21064(LogoutFrame->Ps) ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "PAL_BASE : %016Lx \n", LogoutFrame->PalBase.QuadPart ); HalDisplayString( OutBuffer ); // // Print out interpretation of the error. // HalDisplayString( "\n" ); // // Check for tag control parity error. // if( BIUSTAT_TCPERR_21064(LogoutFrame->BiuStat) == 1 ){ sprintf( OutBuffer, "Tag control parity error, Tag control: P: %1x D: %1x S: %1x V: %1x\n", BCTAG_TAGCTLP_21064( LogoutFrame->BcTag ), BCTAG_TAGCTLD_21064( LogoutFrame->BcTag ), BCTAG_TAGCTLS_21064( LogoutFrame->BcTag ), BCTAG_TAGCTLV_21064( LogoutFrame->BcTag ) ); HalDisplayString( OutBuffer ); } // // Check for tag parity error. // if( BIUSTAT_TPERR_21064(LogoutFrame->BiuStat) == 1 ){ sprintf( OutBuffer, "Tag parity error, Tag: 0b%17b Parity: %1x\n", BCTAG_TAG_21064(LogoutFrame->BcTag), BCTAG_TAGP_21064(LogoutFrame->BcTag) ); HalDisplayString( OutBuffer ); } // // Check for hard error. // if( BIUSTAT_HERR_21064(LogoutFrame->BiuStat) == 1 ){ sprintf( OutBuffer, "Hard error acknowledge: BIU CMD: %x PA: %16Lx\n", BIUSTAT_CMD_21064(LogoutFrame->BiuStat), LogoutFrame->BiuAddr.QuadPart ); HalDisplayString( OutBuffer ); } // // Check for soft error. // if( BIUSTAT_SERR_21064(LogoutFrame->BiuStat) == 1 ){ sprintf( OutBuffer, "Soft error acknowledge: BIU CMD: %x PA: %16Lx\n", BIUSTAT_CMD_21064(LogoutFrame->BiuStat), LogoutFrame->BiuAddr.QuadPart ); HalDisplayString( OutBuffer ); } // // Check for fill ECC errors. // if( BIUSTAT_FILLECC_21064(LogoutFrame->BiuStat) == 1 ){ sprintf( OutBuffer, "ECC error: %s\n", (BIUSTAT_FILLIRD_21064(LogoutFrame->BiuStat) ? "Icache Fill" : "Dcache Fill") ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "PA: %16Lx Quadword: %x Longword0: %x Longword1: %x\n", LogoutFrame->FillAddr.QuadPart, BIUSTAT_FILLQW_21064(LogoutFrame->BiuStat), FILLSYNDROME_LO_21064(LogoutFrame->FillSyndrome), FILLSYNDROME_HI_21064(LogoutFrame->FillSyndrome) ); HalDisplayString( OutBuffer ); } // // Check for fill Parity errors. // if( BIUSTAT_FILLDPERR_21064(LogoutFrame->BiuStat) == 1 ){ sprintf( OutBuffer, "Parity error: %s\n", (BIUSTAT_FILLIRD_21064(LogoutFrame->BiuStat) ? "Icache Fill" : "Dcache Fill") ); HalDisplayString( OutBuffer ); sprintf( OutBuffer, "PA: %16Lx Quadword: %x Longword0: %x Longword1: %x\n", LogoutFrame->FillAddr.QuadPart, BIUSTAT_FILLQW_21064(LogoutFrame->BiuStat), FILLSYNDROME_LO_21064(LogoutFrame->FillSyndrome), FILLSYNDROME_HI_21064(LogoutFrame->FillSyndrome) ); HalDisplayString( OutBuffer ); } // // Check for multiple hard errors. // if( BIUSTAT_FATAL1_21064(LogoutFrame->BiuStat) == 1 ){ HalDisplayString( "Multiple external/tag errors detected.\n" ); } // // Check for multiple fill errors. // if( BIUSTAT_FATAL2_21064(LogoutFrame->BiuStat) == 1 ){ HalDisplayString( "Multiple fill errors detected.\n" ); } // // return to caller // return; }