Ejemplo n.º 1
0
/*
 * @implemented
 */
VOID
NTAPI
HalHandleNMI(IN PVOID NmiInfo)
{
    UCHAR ucStatus;

    /* Get the NMI Flag */
    ucStatus = READ_PORT_UCHAR((PUCHAR)0x61);

    /* Display NMI failure string */
    HalDisplayString ("\n*** Hardware Malfunction\n\n");
    HalDisplayString ("Call your hardware vendor for support\n\n");

    /* Check for parity error */
    if (ucStatus & 0x80)
    {
        /* Display message */
        HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
    }

    /* Check for I/O failure */
    if (ucStatus & 0x40)
    {
        /* Display message */
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
    }

    /* Halt the system */
    HalDisplayString("\n*** The system has halted ***\n");
    //KeEnterKernelDebugger();
}
Ejemplo n.º 2
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It print the appropriate
   status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    UCHAR   StatusByte;
    
#ifdef IDLE_PROCESSOR
    //
    // Clear interrupt flag
    //

    HalpInterruptReceived = 0;
#endif

    StatusByte =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (StatusByte & 0x80) {
        HalDisplayString ("NMI: Parity Check / Parity Error\n");
    }

    if (StatusByte & 0x40) {
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
    }

     //
     // This is an Sio machine, no extnded nmi information, so just do it.
     //


    KeBugCheck(NMI_HARDWARE_FAILURE);
    return(TRUE);
}
Ejemplo n.º 3
0
VOID
HalHandleNMI(
    IN OUT PVOID NmiInfo
    )
/*++

Routine Description:

    Called DURING an NMI.  The system will BugCheck when an NMI occurs.
    This function can return the proper bugcheck code, bugcheck itself,
    or return success which will cause the system to iret from the nmi.

    This function is called during an NMI - no system services are available.
    In addition, you don't want to touch any spinlock which is normally
    used since we may have been interrupted while owning it, etc, etc...

Warnings:

    Do NOT:
      Make any system calls
      Attempt to acquire any spinlock used by any code outside the NMI handler
      Change the interrupt state.  Do not execute any IRET inside this code

    Passing data to non-NMI code must be done using manual interlocked
    functions.  (xchg instructions).

Arguments:

    NmiInfo - Pointer to NMI information structure  (TBD)
            - NULL means no NMI information structure was passed

Return Value:

    BugCheck code

--*/
{
    //
    // We can not look at the hardware to determine the source
    // of the error because reads of many error registers clear
    // the error and the IMP board is racing with us.
    //
    // If support for systems without an IMP board is added, we need
    // to duplicate all the error reporting of the IMP board here.
    //

    HalDisplayString (MSG_HARDWARE_ERROR1);
    HalDisplayString (MSG_HARDWARE_ERROR2);
    HalDisplayString ("NMI: The system has detected a fatal NMI\n");
    HalDisplayString (MSG_HALT);

    KeEnterKernelDebugger();
}
Ejemplo n.º 4
0
VOID
R98DebugOutPut(
    ULONG DebugPrintLevel,	// Debug Level
    PCSZ DebugMessageLed,	// For LED strings. shuld be 4Byte.
    PCSZ DebugMessage,		// For DISPLAY or SIO
    ...
    )

/*++

Routine Description:

    Debug print routine.

Arguments:

    Debug print level between 0,and 3, with 3 being the most verbose.

Return Value:

    None.

--*/

{
    va_list ap;
    char *p,LedNumber;
    CHAR buffer[128];

    if (DebugPrintLevel >= R98DebugLevel) {
        if (DebugOutput & DBG_LED) {
	    //	Message is "1-a-f"
	    for(p=(char *)DebugMessageLed,LedNumber=0; LedNumber<4;p++,LedNumber++) // A002
	            HalpDisplaySegment(LedNumber,*p);
        }

	//	sdk/inc/crt/stdarg.h
	va_start(ap, DebugMessage);		

	//	stdlib ?? (sdk/inc/crt/stdio.h)
        (VOID) vsprintf(buffer, DebugMessage, ap);

	// 
        if (DebugOutput & DBG_SERIAL) {
            DbgPrint(buffer);
        }

	//	Console =Vram Write
	//
        if (DebugOutput & DBG_COLOR) {		
            HalDisplayString(buffer);
        }

    }

    va_end(ap);

}
Ejemplo n.º 5
0
Archivo: stop.c Proyecto: Ttech/dux
void KrnlStop(uint32_t error, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4)
{
	if (in_stop) {
		/* Its recursive! */
		HalShutdown();
	}
	in_stop = 1;

	HalInitDisplay();
	HalDisplaySetAttr(0x4f);
	HalDisplayClear();

	HalDisplayString("An error has occured and Dux has been shutdown to prevent damage.\n\n");

	printf("STOP: %x (%x, %x, %x, %x)\n", error, arg1, arg2, arg3, arg4);
 
#ifdef DEBUG
	HalDisplayString("BREAK\n");
	HalBreak();
#else
	HalShutdown();
#endif
}
Ejemplo n.º 6
0
VOID
SerMouDebugPrint(
    ULONG DebugPrintLevel,
    PCSZ DebugMessage,
    ...
    )

/*++

Routine Description:

    Debug print routine.

Arguments:

    Debug print level between 0 and 3, with 3 being the most verbose.

Return Value:

    None.

--*/

{
    va_list ap;

    va_start(ap, DebugMessage);

    if (DebugPrintLevel <= SerialMouseDebug) {

        CHAR buffer[128];

        (VOID) vsprintf(buffer, DebugMessage, ap);

        if (DebugOutput & DBG_SERIAL) {
            DbgPrint(buffer);
        }

        if (DebugOutput & DBG_COLOR) {
            HalDisplayString(buffer);
        }
    }

    va_end(ap);

}
Ejemplo n.º 7
0
void
HalpInitNvram(void)
{
    ULONG Size;
    int Entry;

    CpuAuxControl = (volatile UCHAR *)SGI_AUX_BASE;

    Size = VenNvramTable(NvramTable, sizeof(NvramTable));

    if(Size) {
#ifdef DBG
        char buf[64];
	sprintf(buf, "Nvram table has grown (%d).\n", Size);
	HalDisplayString(buf);
	DbgBreakPoint();
#endif
	return;
    }

    RtlZeroMemory (NvramValues, sizeof NvramValues);
    for (Entry = 0; Entry < NVRAM_ENTRIES; ++Entry) {
	if (NvramTable[Entry].NvLen == 0) {
            // DbgPrint ("Nvram has %d entries\n", Entry);
	    break;
	}
	NvramTable[Entry].NvValue = &NvramValues[Entry * MAX_ENTRY_LEN];
	if (NvramTable[Entry].NvLen <= MAX_ENTRY_LEN) {
	    NvramReadString(NvramTable[Entry].NvAddr, NvramTable[Entry].NvLen,
		NvramTable[Entry].NvValue);
	}
	else {
#ifdef DBG
	    DbgPrint ("NvEntry %s too large\n", NvramTable[Entry].NvName);
#endif
	    NvramTable[Entry].NvName[0] = 0;
	}
    }
#ifdef DBG
    if (Entry >= NVRAM_ENTRIES)
        DbgPrint("Nvram: too many entries\n");
#endif
}
Ejemplo n.º 8
0
VOID
KiDisplayString (
    IN ULONG Column,
    IN ULONG Row,
    IN PCHAR Buffer
)

/*++

Routine Description:

    This function display a string starting at the specified column and row
    position on the screen.

Arguments:

    Column - Supplies the starting column of where the string is displayed.

    Row - Supplies the starting row of where the string is displayed.

    Bufer - Supplies a pointer to the string that is displayed.

Return Value:

    None.

--*/

{

    //
    // Position the cursor and display the string.
    //

    HalSetDisplayParameters(Column, Row);
    HalDisplayString(Buffer);
    return;
}
Ejemplo n.º 9
0
NTSTATUS
Cbus2ResolveNMI(
    IN PVOID  NmiInfo
    )
/*++

Routine Description:

    This function determines the cause of the NMI so that the user can
    replace any offending SIMMs.

Arguments:

    NmiInfo - pointer to the NMI information structure

Return Value:

    Returns the byte address which caused the NMI, 0 if indeterminate

--*/
{
	PCSR			csr;
	UCHAR			syndrome;
	UCHAR			memsyndrome;
	UCHAR			EccError;
	ULONG			Processor;
	ULONG			InterruptIndication;
	ULONG			FaultIndication;
	ULONG			ErrorType;
	PMEMCSR			memcsr;
        PMEMORY_CARD            pm;
	ULONG			board;
	UCHAR			NmiMessage[80];
	PHYSICAL_ADDRESS	FaultAddress;
	BOOLEAN                 founderror = FALSE;
        ULONG                   original_bridge;
        ULONG                   BridgeId;
        ULONG                   BusNumber;
        extern ULONG            Cbus2BridgeId[];
        extern PCSR             Cbus2BridgeCSR[];
	extern NTSTATUS		DefaultHalHandleNMI( IN OUT PVOID);
	extern VOID		CbusClearEISANMI(VOID);

	if (NMI_BUTTON_PRESSED()) {

		//
		// NMI button was pressed, so go to the debugger
		//

		_asm {
			int 3
		}

		//
		// Clear the NMI in hardware so the system can continue
		//
		// assume that bridge 0 needs the clear in this case.
                // save the original value for restoral after the clear.
                // repoint our I/O references to the default bus bridge number.
                //
                BusNumber =0;

                BridgeId = Cbus2BridgeId[BusNumber];
                csr = Cbus2BridgeCSR[BusNumber];

                original_bridge = csr->BusBridgeSelection.csr_register;
                csr->BusBridgeSelection.csr_register =
                     ((original_bridge & ~MAX_ELEMENT_CSRS) | BridgeId);


		CbusClearEISANMI();

                //
                // restore our default bridge references to what they
                // were when we started...
                //
                csr->BusBridgeSelection.csr_register = original_bridge;

		return STATUS_SUCCESS;		// ignore this NMI
	}

	if (CbusGlobal.nonstdecc)
		return DefaultHalHandleNMI(NmiInfo);

        //
        // All Cbus2 faults will generate an NMI on all the processors.
        // An EISA NMI will also go to all CPUs.  Only directed NMIs
        // (sent by software) can go to less than all the processors.
        //
        // only one processor may proceed beyond this point,
        // so first get the Cbus HAL's NMI lock.
        //

	KiAcquireSpinLock(&Cbus2NMILock);

	if (Cbus2NMIHandler) {
		KiReleaseSpinLock(&Cbus2NMILock);
		//
		// another processor is handling it, so just spin forever
		//
		while (1)
		     ;
	}

        Cbus2NMIHandler = 1;

	KiReleaseSpinLock(&Cbus2NMILock);

        //
        // Now display all the CSRs of:
        //      a) all the processors and
        //      b) all the memory boards and
        //      c) all the I/O bridges
        //

	//
	// print out a leading newline so if he's running a checked
        // build, he'll be able to see the whole line.  otherwise,
        // the kernel debugger CTS/SEND/etc. serial line status will
        // overwrite the first NMI line from our processor loop below.
	//
        HalDisplayString (MSG_NEWLINE);

	//
	// first go through the processors.  there is no need to disable
        // ecc to safely take the system down because we will not iret,
        // (which is needed to re-enable NMI).
	//
        for (Processor = 0; Processor < CbusBootedProcessors; Processor++) {
	        csr = CbusCSR[Processor].csr;
	
		InterruptIndication = csr->InterruptIndication.LowDword;
	
	        //
	        // if the interrupt indication is not set, then it's not
                // a Cbus2 NMI, so it must be something from EISA.  we'll
                // handle EISA NMI detection last.
	        //
		if ((InterruptIndication & CBUS2_FAULT_DETECTED) == 0) {
	                sprintf(NmiMessage, MSG_NMI_ECC0, Processor);
	                HalDisplayString (NmiMessage);
	                continue;
	        }
	
                founderror = TRUE;
		FaultIndication = (csr->FaultIndication.LowDword & 0xFF);

		if ((FaultIndication & (CBUS2_BUS_DATA_UNCORRECTABLE | CBUS2_BUS_ADDRESS_UNCORRECTABLE)) == 0) {
		        //
		        // it is a Cbus2 NMI, but we cannot determine the
                        // address.  at least display the fault indication
                        // register so we can see what type of error it was.
		        //
	                sprintf(NmiMessage, MSG_NMI_ECC1, Processor,
				FaultIndication & CbusGlobal.FaultControlMask);
	                HalDisplayString (NmiMessage);
                        continue;
		}

		FaultAddress.LowPart = 0;
		FaultAddress.HighPart = 0;
	
	        //
	        // EccError contains the quadword index of which quadword
                // in the cache line is bad.  since words in a cacheline
                // are not always transferred in order, we must print this
                // value as well as the address of the cacheline.  the
	        // transfer order is deterministic based on the specific
	        // addresses, but not all addresses are read in the same order.
	        //
		EccError = ((UCHAR)csr->EccError.LowDword & 0x03);
	
		syndrome = ((UCHAR)csr->EccSyndrome.LowDword & 0xFF);
	
		//
		// check if this memory board generated the ecc error
		//
	
		ErrorType = cbus2_edac_syndrome[syndrome];
	
		ASSERT (ErrorType != NOECCERROR && ErrorType != SINGLEBIT);
	
		//
		// the error is latched in this processor's DPX registers.
		// now we need to figure out which register is correct, since
		// the error could have happened in the memory or on the bus.
		//
	
		//
		// display the values this processor has latched.
		//
		FaultAddress.HighPart = csr->EccWriteAddress.LowDword;
		FaultAddress.LowPart = csr->EccReadAddress.LowDword;

                sprintf(NmiMessage, MSG_NMI_ECC2,
                        Processor,
                        FaultAddress.HighPart,
                        FaultAddress.LowPart,
                        EccError,
			FaultIndication & CbusGlobal.FaultControlMask);

                HalDisplayString (NmiMessage);
        }

	//
	// next go through the memory boards...
	//

        pm = CbusMemoryBoards;
        for (board = 0; board < CbusMemoryBoardIndex; board++, pm++) {

                memcsr = (PMEMCSR)pm->regmap;

                if ((memcsr->MemoryFaultStatus.LowDword & CBUS2_MEMORY_FAULT_DETECTED) == 0) {
	                sprintf(NmiMessage, MSG_NMI_ECC3, board);
	                HalDisplayString (NmiMessage);
                        continue;
                }

                founderror = TRUE;

                //
                // this board contains an error
                //
		memsyndrome = ((UCHAR)memcsr->MemoryEccSyndrome.LowDword & 0xFF);
		ErrorType = cbus2_edac_syndrome[memsyndrome];
	
		ASSERT (ErrorType != NOECCERROR && ErrorType != SINGLEBIT);

		FaultAddress.HighPart = memcsr->MemoryEccWriteAddress.LowDword;
		FaultAddress.LowPart = memcsr->MemoryEccReadAddress.LowDword;

                sprintf(NmiMessage, MSG_NMI_ECC4,
		                        board,
					FaultAddress.HighPart,
					FaultAddress.LowPart);

                HalDisplayString (NmiMessage);
        }

	//
	// lastly, go through the I/O bridges...
	//
        for (BusNumber = 0; BusNumber < Cbus2BridgesFound; BusNumber++) {
	        csr = Cbus2BridgeCSR[BusNumber];
	
		InterruptIndication = csr->InterruptIndication.LowDword;
	
	        //
	        // if the interrupt indication is not set, then it's not
                // a Cbus2 NMI, so it must be something from EISA.  we'll
                // handle EISA NMI detection last.
	        //
		if ((InterruptIndication & CBUS2_FAULT_DETECTED) == 0) {
	                sprintf(NmiMessage, MSG_NMI_ECC5, BusNumber);
	                HalDisplayString (NmiMessage);
	                continue;
	        }
	
                founderror = TRUE;
		FaultIndication = (csr->FaultIndication.LowDword & 0xFF);

		if ((FaultIndication & (CBUS2_BUS_DATA_UNCORRECTABLE | CBUS2_BUS_ADDRESS_UNCORRECTABLE)) == 0) {
		        //
		        // it is a Cbus2 NMI, but we cannot determine the
                        // address.  at least display the fault indication
                        // register so we can see what type of error it was.
		        //
	                sprintf(NmiMessage, MSG_NMI_ECC6, BusNumber,
				FaultIndication & CbusGlobal.FaultControlMask);
	                HalDisplayString (NmiMessage);
                        continue;
		}

		FaultAddress.LowPart = 0;
		FaultAddress.HighPart = 0;
	
	        //
	        // EccError contains the quadword index of which quadword
                // in the cache line is bad.  since words in a cacheline
                // are not always transferred in order, we must print this
                // value as well as the address of the cacheline.  the
	        // transfer order is deterministic based on the specific
	        // addresses, but not all addresses are read in the same order.
	        //
		EccError = ((UCHAR)csr->EccError.LowDword & 0x03);
	
		syndrome = ((UCHAR)csr->EccSyndrome.LowDword & 0xFF);
	
		//
		// check if this memory board generated the ecc error
		//
	
		ErrorType = cbus2_edac_syndrome[syndrome];
	
		ASSERT (ErrorType != NOECCERROR && ErrorType != SINGLEBIT);
	
		//
		// the error is latched in this processor's DPX registers.
		// now we need to figure out which register is correct, since
		// the error could have happened in the memory or on the bus.
		//
	
		//
		// display the values this processor has latched.
		//
		FaultAddress.HighPart = csr->EccWriteAddress.LowDword;
		FaultAddress.LowPart = csr->EccReadAddress.LowDword;

                sprintf(NmiMessage, MSG_NMI_ECC7,
                        BusNumber,
                        FaultAddress.HighPart,
                        FaultAddress.LowPart,
                        EccError,
			FaultIndication & CbusGlobal.FaultControlMask);

                HalDisplayString (NmiMessage);
        }

	if (founderror == TRUE) {
	        //
	        // this call will not return
	        //
                CbusHardwareFailure (MSG_NMI_ECC8);
	}
	
	//
	// No errors were found in Cbus RAM, so check for EISA errors
	//

        DefaultHalHandleNMI(NmiInfo);
}
Ejemplo n.º 10
0
ULONG
NTAPI
KdpServiceDispatcher(ULONG Service,
                     PVOID Buffer1,
                     ULONG Buffer1Length)
{
    ULONG Result = 0;

    switch (Service)
    {
        case BREAKPOINT_PRINT: /* DbgPrint */
            Result = KdpPrintString(Buffer1, Buffer1Length);
            break;

#if DBG
        case ' soR': /* ROS-INTERNAL */
        {
            switch ((ULONG_PTR)Buffer1)
            {
                case DumpAllThreads:
                    PspDumpThreads(TRUE);
                    break;

                case DumpUserThreads:
                    PspDumpThreads(FALSE);
                    break;

                case KdSpare3:
                    MmDumpArmPfnDatabase(FALSE);
                    break;

                default:
                    break;
            }
            break;
        }

#if defined(_M_IX86) && !defined(_WINKD_) // See ke/i386/traphdlr.c
        /* Register a debug callback */
        case 'CsoR':
        {
            switch (Buffer1Length)
            {
                case ID_Win32PreServiceHook:
                    KeWin32PreServiceHook = Buffer1;
                    break;

                case ID_Win32PostServiceHook:
                    KeWin32PostServiceHook = Buffer1;
                    break;

            }
            break;
        }
#endif

        /* Special  case for stack frame dumps */
        case 'DsoR':
        {
            KeRosDumpStackFrames((PULONG)Buffer1, Buffer1Length);
            break;
        }

#if defined(KDBG)
        /* Register KDBG CLI callback */
        case 'RbdK':
        {
            Result = KdbRegisterCliCallback(Buffer1, Buffer1Length);
            break;
        }
#endif /* KDBG */
#endif /* DBG */
        default:
            DPRINT1("Invalid debug service call!\n");
            HalDisplayString("Invalid debug service call!\r\n");
            break;
    }

    return Result;
}
Ejemplo n.º 11
0
VOID
KeDumpMachineState (
    IN PKPROCESSOR_STATE ProcessorState,
    IN PCHAR Buffer,
    IN PULONG BugCheckParameters,
    IN ULONG NumberOfParameters,
    IN PKE_BUGCHECK_UNICODE_TO_ANSI UnicodeToAnsiRoutine
    )

/*++

Routine Description:

    This function formats and displays the machine state at the time of the
    to bug check.

Arguments:

    ProcessorState - Supplies a pointer to the processor's state

    Buffer - Supplies a pointer to a buffer to be used to output machine
        state information.

    BugCheckParameters - Supplies additional bugcheck information

    NumberOfParameters - sizeof BugCheckParameters array

    UnicodeToAnsiRoutine - Supplies a pointer to a routine to convert Unicode strings
        to Ansi strings without touching paged translation tables.

Return Value:

    None.

--*/

{
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY Next;
    ULONG StackAddr;
    ULONG PossiblePc;
    ULONG Index, NoLines;
    ULONG DisplayWidth, DisplayHeight;
    ULONG CursorColumn, CursorRow;
    ULONG i, j;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PVOID ImageBase;
    PKPRCB  Prcb;
    UCHAR AnsiBuffer[ 32 ];
    ULONG DateStamp;


    //
    // Query display parameters.
    //

    HalQueryDisplayParameters(&DisplayWidth,
                              &DisplayHeight,
                              &CursorColumn,
                              &CursorRow);

    //
    // At this point the context record contains the machine state at the
    // call to bug check.
    //
    // Put out the system version and the title line with the PSR and FSR.
    //

    //
    // Check to see if any BugCheckParameters are valid code addresses.
    // If so, print them for the user
    //

    NoLines = 8;
    for (i=0; i < NumberOfParameters; i++) {
        ImageBase = KiPcToFileHeader((PVOID) BugCheckParameters[i], &DataTableEntry);
        if (ImageBase == NULL) {
            continue;
        }

        sprintf (Buffer, "*** Address %08lx has base at %08lx - %-12.12s\n",
            BugCheckParameters[i], ImageBase,
            (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));
        HalDisplayString(Buffer);
        NoLines++;
    }
    Prcb = KeGetCurrentPrcb();
    if (Prcb->CpuID) {
        sprintf(Buffer, "\n\nCPUID:%.12s %x.%x.%x",
            Prcb->VendorString,
            Prcb->CpuType,
            Prcb->CpuStep >> 8,
            Prcb->CpuStep & 0x0f
            );

    } else {
Ejemplo n.º 12
0
BOOLEAN
HalInitSystem (
    IN ULONG Phase,
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This function initializes the Hardware Architecture Layer (HAL) for a
    MIPS R3000 or R4000 system.

Arguments:

    Phase - Supplies the initialization phase (zero or one).

    LoaderBlock - Supplies a pointer to a loader parameter block.

Return Value:

    A value of TRUE is returned is the initialization was successfully
    complete. Otherwise a value of FALSE is returend.

--*/

{
    PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
    PLIST_ENTRY NextMd;
    PKPRCB Prcb;
    ULONG  BuildType = 0;

    Prcb = KeGetCurrentPrcb();
    if (Phase == 0) {

        //
        // Phase 0 initialization.
        //
        // Verify that the processor block major version number conform
        // to the system that is being loaded.
        //

        if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) {
            KeBugCheck(MISMATCHED_HAL);
        }

        //
        // Set the number of process id's and TB entries.
        //

        **((PULONG *)(&KeNumberProcessIds)) = 256;
        **((PULONG *)(&KeNumberTbEntries)) = 48;

        //
        // Set the time increment value.
        //

        HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
        HalpNextTimeIncrement = MAXIMUM_INCREMENT;
        HalpNextIntervalCount = 0;
        KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);
        LessThan16Mb = TRUE;

        SecondaryCachePurgeBaseAddress = NULL;

        NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;

        while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
            Descriptor = CONTAINING_RECORD( NextMd,
                                            MEMORY_ALLOCATION_DESCRIPTOR,
                                            ListEntry );

// To purge the secondary cache on an ArcStation I, a valid Firmware Permanent
// region must be found that starts on a 512 KB boundry and is at least
// 512 KB long.  The secondary cache is purged by reading from the appropriate
// range of this 512 KB region for the page being purged.

            if (Descriptor->MemoryType == LoaderFirmwarePermanent &&
                (Descriptor->BasePage % 128)==0 &&
                Descriptor->PageCount>=128) {

                SecondaryCachePurgeBaseAddress = (PVOID)(KSEG0_BASE | (Descriptor->BasePage*4096));

                Descriptor->BasePage+=128;
                Descriptor->PageCount-=128;

            }

            if (Descriptor->BasePage + Descriptor->PageCount > 0x1000) {
                LessThan16Mb = FALSE;
            }

            NextMd = Descriptor->ListEntry.Flink;
        }

        if (SecondaryCachePurgeBaseAddress==NULL) {
          HalDisplayString("ERROR : A valid Firmware Permanent area does not exist\n");
          KeBugCheck(PHASE0_INITIALIZATION_FAILED);
        }

        //
        // Determine the size need for map buffers.  If this system has
        // memory with a physical address of greater than
        // MAXIMUM_PHYSICAL_ADDRESS, then allocate a large chunk; otherwise,
        // allocate a small chunk.
        //

        if (LessThan16Mb) {

            //
            // Allocate a small set of map buffers.  They are only need for
            // slave DMA devices.
            //

            HalpMapBufferSize = INITIAL_MAP_BUFFER_SMALL_SIZE;

        } else {

            //
            // Allocate a larger set of map buffers.  These are used for
            // slave DMA controllers and Isa cards.
            //

            HalpMapBufferSize = INITIAL_MAP_BUFFER_LARGE_SIZE;

        }

        HalpMapBufferPhysicalAddress.LowPart =
           HalpAllocPhysicalMemory (LoaderBlock, MAXIMUM_ISA_PHYSICAL_ADDRESS,
             HalpMapBufferSize >> PAGE_SHIFT, FALSE);
        HalpMapBufferPhysicalAddress.HighPart = 0;

        if (!HalpMapBufferPhysicalAddress.LowPart) {

            //
            // There was not a satisfactory block.  Clear the allocation.
            //

            HalpMapBufferSize = 0;
        }

        //
        // Initialize interrupts.
        //


        HalpInitializeInterrupts();
        return TRUE;

    } else {

        //
        // Phase 1 initialization.
        //

        if (IoSpaceAlreadyMapped == FALSE) {
Ejemplo n.º 13
0
ULONG
DetectMPS(
    OUT PBOOLEAN IsConfiguredMp
)

/*++

Routine Description:

   This function is called from HalInitializeProcessors to determine
   if this is an appropriate system to run the MPS hal on.

   The recommended detection mechanism is:

   if ( MPS information does not exist )
       then
           System is not MPS compliant. Return false.

   In MP table:
       if ( number IO APICs < 1 )
           then
               Not a MPS System - return false

       if ( # CPUs = 1 )
           then
               Found a Single Processor MPS System
           else
               Found a MP MPS System


    A side effect of this routine is the mapping of the IO UNits and
    Local unit virtual addresses.

   Return TRUE


 Arguments:

   IsConfiguredMp - TRUE if this machine is a MP instance of the MPS spec, else FALSE.

 Return Value:
   0 - if not a MPS
   1 - if MPS

*/
{

    UCHAR ApicVersion, i;
    PUCHAR  LocalApic;
    PPCMPIOAPIC IoEntryPtr;

    //
    // Initialize MpInfo table
    //

    RtlZeroMemory (&HalpMpInfoTable, sizeof HalpMpInfoTable);

    //
    // Set the return Values to the default
    //

    *IsConfiguredMp = FALSE;

    //
    // See if there is a MP Table
    //

#if 1
    if ((PcMpTablePtr = GetPcMpTable()) == NULL) {
        FAILMSG (rgzNoMpsTable);
        return(FALSE);
    }
#else
    //********
    //******** HACK! To make down level 1.0 machine work
    //********

    if ((PcMpTablePtr = MPS10_GetPcMpTable()) == NULL) {
        FAILMSG (rgzNoMpsTable);
        return(FALSE);
    }
#endif

#ifdef SETUP
    // During setup, if we detected a default MPS configuration, we have
    // no more checking to do.
    if (PcMpTablePtr ==  (struct PcMpTable *) DEFAULT_MPS_INDICATOR)  {
        *IsConfiguredMp = TRUE;
        return(TRUE);
    }
#endif // SETUP

#if DEBUGGING
    HalpDisplayConfigTable();
#endif

    // We have a MPS table. Initialize a HAL specific MP information
    // structure that gets information from the MPS table.

    HalpInitMpInfo(PcMpTablePtr);


    // Verify the information in the MPS table as best as we can.

    if (HalpMpInfoTable.IOApicCount == 0) {
        //
        //  Someone Has a MP Table and no IO Units -- Weird
        //  We have to assume the BIOS knew what it was doing
        //  when it built the table.  so ..
        //
        FAILMSG (rgzNoApic);
        return (FALSE);
    }

    //
    //  It's a MPS System.  It could be a UP System though.
    //

#ifdef SETUP
    //
    // If this is a MPS (MPS) compliant system, but has only 1 processor,
    // for now we want to install a standard UP kernel and HAL.
    //

    if (HalpMpInfoTable.ProcessorCount <= 1) {
        return FALSE;
    }
#endif

    if (HalpMpInfoTable.ProcessorCount > 1) {
        *IsConfiguredMp = TRUE;
    }

    HalpMpInfoTable.LocalApicBase = (ULONG) PcMpTablePtr->LocalApicAddress;
    LocalApic = (PUCHAR) HalpMapPhysicalMemoryWriteThrough(
                            (PVOID) HalpMpInfoTable.LocalApicBase,1);

#ifndef SETUP
    HalpRemapVirtualAddress (
        (PVOID) LOCALAPIC,
        (PVOID) HalpMpInfoTable.LocalApicBase,
        TRUE
        );
#endif

    ApicVersion = (UCHAR) *(LocalApic + LU_VERS_REGISTER);

    if (ApicVersion > 0x1f) {
        //
        //  Only known Apics are 82489dx with version 0.x and
        //  Embedded Apics with version 1.x (where x is don't care)
        //
        //  Return of 0xFF?   Can't have an MPS system without a Local Unit.
        //

#ifdef DEBUGGING
        sprintf(Cbuf, "HALMPS: apic version %x, read from %x\n",
            ApicVersion, LocalApic + LU_VERS_REGISTER);

        HalDisplayString(Cbuf);
#endif

        FAILMSG (rgzBadApicVersion);
        return (FALSE);
    }

#ifdef SETUP
    //
    // MP MPS table, and the local APIC ID looked OK.
    //

    return TRUE;
#endif  //SETUP


#ifdef DEBUGGING
    if ((ApicVersion & 0xf0) == 0) {
        if (HalpMpInfoTable.ApicVersion != APIC_82489DX)
        HalDisplayString("HAL:Invalid Local Apic version in MP table\n");
        else {
            sprintf(Cbuf, "HAL: DetectMPS: Found 82489DX Local APIC (Ver 0x%x) at 0x%lx\n",
                    ApicVersion, LocalApic);
            HalDisplayString(Cbuf);
        }
    } else {
        sprintf(Cbuf, "HAL: DetectMPS: Found Embedded Local APIC (Ver 0x%x) at 0x%lx\n",
                ApicVersion, LocalApic);
        HalDisplayString(Cbuf);

    }
#endif // DEBUGGING

    IoEntryPtr = HalpMpInfoTable.IoApicEntryPtr;

    for(i=0; i < HalpMpInfoTable.IOApicCount; i++, IoEntryPtr++)
    {
        if (IoEntryPtr->IoApicFlag & IO_APIC_ENABLED) {
            //
            //  Verify the existance of the IO Units
            //

            HalpMpInfoTable.IoApicPhys[i] = (ULONG) IoEntryPtr->IoApicAddress;
            HalpMpInfoTable.IoApicBase[i] = (PULONG)
                HalpMapPhysicalMemoryWriteThrough(
                (PVOID)(IoEntryPtr->IoApicAddress), 1);

            //
            //  Verify the existance of the IO Unit
            //
            if (!(HalpVerifyIOUnit((PUCHAR)HalpMpInfoTable.IoApicBase[i]))) {
                FAILMSG (rgzApicNotVerified);
                return (FALSE);
            }
        }
    }

    DBGMSG("HAL: DetectMPS: MPS system found - Returning TRUE\n");
    return(TRUE);
}
Ejemplo n.º 14
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It prints the 
   appropriate status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    LEGO_SRV_MGMT  SmRegister;
    UCHAR   NmiControl, NmiStatus;
    BOOLEAN GotSerr, GotIochk, GotSmFan, GotSmTemp, GotHalt;
    
    NMIcount++;

#if DBG
    if (NMIcount<5) {
        DbgPrint("II<NMI><");
    }
    if (NMIcount % 100 == 0) {
        DbgPrint("II<NMI><%08x><", NMIcount);
    }
#endif

    GotSerr = GotIochk = GotSmFan = GotSmTemp = GotHalt = FALSE;

    //
    // Set the Eisa NMI disable bit. We do this to mask further NMI 
    // interrupts while we're servicing this one.
    //
    NmiControl = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 1;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);

#ifdef DBG
    DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
#endif

    NmiStatus =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (NmiStatus & 0x80) {
        GotSerr = TRUE;

#ifdef DBG
        DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
#endif
        HalAcquireDisplayOwnership(NULL);
        HalDisplayString ("NMI: Parity Check / Parity Error\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }

    if (NmiStatus & 0x40) {
        GotIochk = TRUE;
#ifdef DBG
        DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
#endif
        HalAcquireDisplayOwnership(NULL);
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }

    // Read server management register
    //  Events that can be reported as NMI are:
    //      Enclosure temperature too high
    //      CPU Fan failure
    //
    // For now, generate a bugcheck.
    // [wem] Future: perform secondary dispatch to give
    //       driver shot at reporting problem.
    //
    SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );

    GotSmFan = SmRegister.CpuFanFailureNmi == 1;
    GotSmTemp = SmRegister.EnclTempFailureNmi == 1;

    if (GotSmFan || GotSmTemp) {

#ifdef DBG
        DbgPrint("HalHandleNMI: Server management NMI\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
        DbgPrint("HalHandleNMI:    Server Management Status = 0x%x\n", SmRegister);
#endif

        //
        // If secondary dispatch enabled, do it now.
        //
#if 0
        if (HalpLegoDispatchNmi
            && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SM_ERROR_VECTOR])(
                    PCR->InterruptRoutine[SM_ERROR_VECTOR],
                    TrapFrame)
           ) {
            return TRUE;
        }
#endif

        //
        // Build uncorrectable error frame and 
        // prepare for orderly shutdown
        //
        // The delayed shutdown depends on watchdog timer support
        // A power off cannot be directly done since KeBugChk() turns
        // off interrupts, so there's no way to get control back.
        //
        // WARNING: Pick a delay that allows a dump to complete.
        //

        LegoServerMgmtReportFatalError(SmRegister.All);
        LegoServerMgmtDelayedShutdown(8);                  // Issue reset in 8 seconds

        HalAcquireDisplayOwnership(NULL);

        HalDisplayString ("NMI: Hardware Failure -- ");
        HalDisplayString ((SmRegister.CpuFanFailureNmi==1) ? "CPU fan failed."
                                                           : "Enclosure termperature too high.");
        HalDisplayString ("\nSystem Power Down will be attempted in 8 seconds...\n\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }


    // 
    // Halt button was hit.
    //
    // [wem] Perform second-level dispatch here too?
    //
    if (!GotSerr && !GotIochk && !GotSmFan && !GotSmTemp) {

        //
        // If secondary dispatch enabled, do it now.
        //
#if 0
        if (HalpLegoDispatchHalt
            && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[HALT_BUTTON_VECTOR])(
                    PCR->InterruptRoutine[HALT_BUTTON_VECTOR],
                    TrapFrame)
           ) {
            return TRUE;
        }
#endif

        GotHalt = TRUE;
        HalDisplayString ("NMI: Halt button pressed.\n");

        if (HalpHaltButtonBreak) {
            DbgBreakPoint();
        }

        return (TRUE);
    }

    //
    // Clear and re-enable SERR# and IOCHK#, then re-enable NMI
    //

#ifdef DBG
    DbgPrint("HalHandleNMI: Shouldn't get here!\n");
#endif

    if (GotSerr) {
#ifdef DBG
        DbgPrint("HalHandleNMI: Resetting SERR#; NMI count = %d\n", NMIcount);
#endif
        //
        // Reset SERR# (and disable it), then re-enable it.
        //
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
    }

    if (GotIochk) {
#ifdef DBG
        DbgPrint("HalHandleNMI: Resetting IOCHK#; NMI count = %d\n", NMIcount);
#endif
        //
        // Reset IOCHK# (and disable it), then re-enable it.
        //
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x08);
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
    }

    if (GotSmFan || GotSmTemp) {
        //
        // Reset Server management condition.
        //
        // Interrupt must be cleared or the NMI will continue
        // to occur.
        //
        SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
        if (GotSmFan) {
            SmRegister.CpuFanFailureNmi = 1;
        }
        else {
            SmRegister.EnclTempFailureNmi = 1;
        }
        WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
    }

    //
    // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
    // now that we're done servicing this one.
    //
    NmiControl = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 0;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);
#ifdef DBG
    DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
#endif

    return(TRUE);
}
Ejemplo n.º 15
0
VOID
HalpCiaReportFatalError(
    VOID
    )
/*++

Routine Description:

   This function reports and interprets a fatal hardware error
   detected by the CIA chipset. It is assumed that HalGetDisplayOwnership()
   has been called prior to this function.

Arguments:

   None.

Return Value:

   None.

--*/
{
    UCHAR   OutBuffer[ MAX_ERROR_STRING ];
    CIA_ERR CiaError;
    CIA_STAT CiaStat;
    CIA_SYN  CiaSyn;
    CIA_CONTROL CiaControl;
    CIA_MEM_ERR0 MemErr0;
    CIA_MEM_ERR1 MemErr1;
    CIA_PCI_ERR0 PciErr0;
    CIA_PCI_ERR1 PciErr1;
    CIA_PCI_ERR2 PciErr2;
    CIA_CPU_ERR0 CpuErr0;
    CIA_CPU_ERR1 CpuErr1;

    PUNCORRECTABLE_ERROR     uncorr = NULL;
    PCIA_UNCORRECTABLE_FRAME ciauncorr = NULL;
    PEXTENDED_ERROR PExtErr;

    //
    // We will Build the uncorrectable error frame as we read 
    // the registers to report the error to the blue screen.
    // We generate the extended error frame as we generate 
    // extended messages to print to the screen.
    //

    if(PUncorrectableError){
        uncorr = (PUNCORRECTABLE_ERROR) 
                    &PUncorrectableError->UncorrectableFrame;
        ciauncorr = (PCIA_UNCORRECTABLE_FRAME)
            PUncorrectableError->UncorrectableFrame.RawSystemInformation;
        PExtErr = &PUncorrectableError->UncorrectableFrame.ErrorInformation;
    }
    if(uncorr){
        uncorr->Flags.ProcessorInformationValid = 1;
        HalpGetProcessorInfo(&uncorr->ReportingProcessor);
    }

    if(ciauncorr)
        HalpBuildCiaConfigurationFrame(&ciauncorr->Configuration);
    //
    //  Read the CIA Error register and decode its contents:
    //

    CiaError.all = (ULONG)READ_CIA_REGISTER(
                          &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CiaErr
                                        );

    if(ciauncorr)
        ciauncorr->CiaErr = CiaError.all ;

    //
    //  Read the rest of the error registers and then unlock them by
    //  writing to CIA_ERR
    //

    CiaStat.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CiaStat
                                        );


    CiaSyn.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CiaSyn
                                        );


    MemErr0.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->MemErr0
                                        );


    MemErr1.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->MemErr1
                                        );


    PciErr0.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->PciErr0
                                        );


    PciErr1.PciAddress = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->PciErr1
                                        );

    PciErr2.PciAddress = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->PciErr2
                                        );

    CpuErr0.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CpuErr0
                                        );


    CpuErr1.all = (ULONG)READ_CIA_REGISTER(
                              &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CpuErr1
                                        );

    CiaControl.all = READ_CIA_REGISTER(
                        &((PCIA_GENERAL_CSRS)(CIA_GENERAL_CSRS_QVA))->CiaCtrl);

    if(ciauncorr){
        ciauncorr->CiaStat = CiaStat.all;
        ciauncorr->CiaSyn = CiaSyn.all;
        ciauncorr->MemErr0 = MemErr0.all;
        ciauncorr->MemErr1 = MemErr1.all;
        ciauncorr->PciErr0 = PciErr0.all;
        ciauncorr->PciErr1 = PciErr1.PciAddress;

        ciauncorr->PciErr2 = (ULONG)READ_CIA_REGISTER( 
                        &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->PciErr2
                            );
        ciauncorr->CpuErr0 = CpuErr0.all;

        ciauncorr->CpuErr1 = CpuErr1.all;

        ciauncorr->ErrMask = (ULONG)READ_CIA_REGISTER(
                          &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->ErrMask
                                        );

    }

    WRITE_CIA_REGISTER( &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CiaErr,
                        CiaError.all
                      );


    sprintf( OutBuffer, "CIA_CTRL : %08x\n", CiaControl.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "CIA_ERR  : %08x\n", CiaError.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "CIA_STAT : %08x\n", CiaStat.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "CIA_SYN  : %08x\n", CiaSyn.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "PCI_ERR0 : %08x\n", PciErr0.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "PCI_ERR1 : %08x\n", PciErr1.PciAddress );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "PCI_ERR2 : %08x\n", PciErr2.PciAddress );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "CPU_ERR0 : %08x\n", CpuErr0.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "CPU_ERR1 : %08x\n", CpuErr1.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "MEM_ERR0 : %08x\n", MemErr0.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    sprintf( OutBuffer, "MEM_ERR1 : %08x\n", MemErr1.all );
    HalDisplayString( OutBuffer );
    DbgPrint( OutBuffer );

    //
    // If no valid error then no interpretation.
    //

    if ( CiaError.ErrValid == 0 ){

        return;                         // No CIA error detected

    }

    //
    //  Interpret any detected errors:
    //

    if ( CiaError.UnCorErr == 1 ){

        sprintf( OutBuffer,
                 "CIA Uncorrectable ECC error, Addr=%x%x, Cmd=%x\n",
                  CpuErr1.Addr34_32,        // bits 34:32
                  CpuErr0.Addr,             // bits 31:4
                  CpuErr1.Cmd
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
        }

    } else if ( CiaError.CpuPe == 1 ){

        sprintf( OutBuffer,
                 "EV5 bus parity error, Addr=%x%x, Cmd=%x\n",
                  CpuErr1.Addr34_32,        // bits 34:32
                  CpuErr0.Addr,             // bits 31:4
                  CpuErr1.Cmd
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
        }

    } else if ( CiaError.MemNem == 1 ){

        sprintf( OutBuffer,
                 "CIA Access to non-existent memory, Source=%s, Addr=%x%x\n",
                 MemErr1.MemPortSrc == 1 ? "DMA" : "CPU",
                 MemErr1.MemPortSrc == 1 ? 0 : MemErr1.Addr33_32,
                 MemErr1.MemPortSrc == 1 ? PciErr1.PciAddress : MemErr0.Addr31_4
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
        }

    } else if ( CiaError.PciSerr == 1 ){

        sprintf( OutBuffer,
                 "PCI bus SERR detected, Cmd=%x, Window=%d, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );

        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }

    } else if ( CiaError.PciPerr == 1 ){

        sprintf( OutBuffer,
                 "PCI bus Data Parity error, Cmd=%x, Window=%d, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );

        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }

    } else if ( CiaError.PciAddrPe == 1 ){

        sprintf( OutBuffer,
                 "Pci bus Address Parity error, Cmd=%x, Window=%x, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }

    } else if ( CiaError.RcvdMasAbt == 1 ){

        sprintf( OutBuffer,
                 "PCI Master abort occurred, Cmd=%x, Window=%x, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }

    } else if ( CiaError.RcvdTarAbt == 1 ){

        sprintf( OutBuffer,
                 "PCI Target abort occurred, Cmd=%x, Window=%x, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }

    } else if ( CiaError.PaPteInv == 1 ){

        sprintf( OutBuffer,
                 "Invalid Scatter/Gather PTE, Cmd=%x, Window=%x, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }

    } else if  ( CiaError.FromWrtErr == 1 ){

        sprintf( OutBuffer,
                 "Write to Flash ROM with FROM_WRT_EN clear"
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
        }

    } else if ( CiaError.IoaTimeout == 1){

        sprintf( OutBuffer,
                 "PCI bus I/O timeout occurred, Cmd=%x, Window=%x, Addr=%x\n",
                 PciErr0.Cmd,
                 PciErr0.Window,
                 PciErr1.PciAddress
                );
        if(uncorr){
            uncorr->Flags.ErrorStringValid = 1;
            strcpy( uncorr->ErrorString, OutBuffer);
            uncorr->Flags.AddressSpace = IO_SPACE;
            uncorr->Flags.PhysicalAddressValid = 1;
            uncorr->PhysicalAddress = PciErr1.PciAddress;
    
            uncorr->Flags.ExtendedErrorValid = 1;
            PExtErr->IoError.Interface = PCIBus;
            PExtErr->IoError.BusNumber = 0;
            PExtErr->IoError.BusAddress.LowPart = PciErr1.PciAddress;
        }
    }
                  

    //
    //  Output the detected error message:
    //

    HalDisplayString( "\n" );
    HalDisplayString( OutBuffer );

#if HALDBG
        DbgPrint( OutBuffer );
#endif


    //
    //  Check for lost errors and output message if any occurred:
    //

    if ( (CiaError.all & CIA_ERR_LOST_MASK) != 0 ){

        HalDisplayString("\nCIA Lost errors were detected\n\n");
    }

    return;                                 // Fatal error detected
}
Ejemplo n.º 16
0
VOID
HalpNMIInterrupt(
    ULONG DumpStatus
    )

/*++

Routine Description:

    This routine was called when dump swich was pressed or Fatal NMI occued.
    We call KeBugCheckEx() in order to Dump.

Arguments:

    DumpStatus:   Dump Switch Status
    
               0        Dump Switch was not pressed.
               1        Dump Switch was pressed.

Return Value:

    None.

--*/

{
    ULONG NMISource;
    ULONG MemoryFailed;
    LARGE_INTEGER InvalidAddressValue;
    LARGE_INTEGER EccDiagnosticValue;
    UCHAR Buffer[100];

    HalpChangePanicFlag(16, (UCHAR)(0x01 | (4 * DumpStatus)), 0x10); // S014,S018

    //
    // M007,M012
    // Check DumpStatus.and Display NMI status.
    //

    if (DumpStatus == 1) {  
        HalDisplayString("HAL:Dump Switch Pressed!\n");
    } else {
        HalDisplayString("HAL:NMI occured\n");
    }

    //
    // Display NMI registers
    //

    NMISource = READ_REGISTER_ULONG(&DMA_CONTROL->NmiSource.Long);
    sprintf(Buffer, "HAL:NmiSource register = %x\n",NMISource);
    HalDisplayString((UCHAR *)Buffer);

    MemoryFailed = READ_REGISTER_ULONG(
                       &((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long);
    sprintf(Buffer,
        "HAL:MemoryFailedAddress register = %x\n",
         MemoryFailed);
    HalDisplayString((UCHAR *)Buffer);

    READ_REGISTER_DWORD(
        (PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress,
        &InvalidAddressValue);
    sprintf(Buffer,
        "HAL:Processor Invalid Address register = %x %x\n",
        InvalidAddressValue.HighPart,InvalidAddressValue.LowPart);
    HalDisplayString((UCHAR *)Buffer);

    READ_REGISTER_DWORD(
        (PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic,
        &EccDiagnosticValue);
    sprintf(Buffer,
        "HAL:EccDiagnostic register = %x %x\n",
        EccDiagnosticValue.HighPart,EccDiagnosticValue.LowPart);
    HalDisplayString((UCHAR *)Buffer);

    //
    // M007,M008
    // call KeBugCheckEx() for dump.
    //

    KeBugCheckEx(NMI_HARDWARE_FAILURE,DumpStatus,NMISource,0,0);

    return;

}
Ejemplo n.º 17
0
PVOID
NTAPI
PciGetAcpiTable(IN ULONG TableCode)
{
    PDESCRIPTION_HEADER Header;
    PACPI_BIOS_MULTI_NODE AcpiMultiNode;
    PRSDT Rsdt;
    PXSDT Xsdt;
    ULONG EntryCount, TableLength, Offset, CurrentEntry;
    PVOID TableBuffer, MappedAddress;
    PHYSICAL_ADDRESS PhysicalAddress;
    NTSTATUS Status;

    /* Try to find the RSDT or XSDT */
    Status = PciAcpiFindRsdt(&AcpiMultiNode);
    if (!NT_SUCCESS(Status))
    {
        /* No ACPI on the machine */
        DPRINT1("AcpiFindRsdt() Failed!\n");
        return NULL;
    }

    /* Map the RSDT with the minimum size allowed */
    MappedAddress = MmMapIoSpace(AcpiMultiNode->RsdtAddress,
                                 sizeof(DESCRIPTION_HEADER),
                                 MmNonCached);
    Header = MappedAddress;
    if (!Header) return NULL;

    /* Check how big the table really is and get rid of the temporary header */
    TableLength = Header->Length;
    MmUnmapIoSpace(Header, sizeof(DESCRIPTION_HEADER));
    Header = NULL;

    /* Map its true size */
    MappedAddress = MmMapIoSpace(AcpiMultiNode->RsdtAddress,
                                 TableLength,
                                 MmNonCached);
    Rsdt = MappedAddress;
    Xsdt = MappedAddress;
    ExFreePoolWithTag(AcpiMultiNode, 0);
    if (!Rsdt) return NULL;

    /* Validate the table's signature */
    if ((Rsdt->Header.Signature != RSDT_SIGNATURE) &&
        (Rsdt->Header.Signature != XSDT_SIGNATURE))
    {
        /* Very bad: crash */
        HalDisplayString("RSDT table contains invalid signature\r\n");
        MmUnmapIoSpace(Rsdt, TableLength);
        return NULL;
    }

    /* Smallest RSDT/XSDT is one without table entries */
    Offset = FIELD_OFFSET(RSDT, Tables);
    if (Rsdt->Header.Signature == XSDT_SIGNATURE)
    {
        /* Figure out total size of table and the offset */
        TableLength = Xsdt->Header.Length;
        if (TableLength < Offset) Offset = Xsdt->Header.Length;

        /* The entries are each 64-bits, so count them */
        EntryCount = (TableLength - Offset) / sizeof(PHYSICAL_ADDRESS);
    }
    else
    {
        /* Figure out total size of table and the offset */
        TableLength = Rsdt->Header.Length;
        if (TableLength < Offset) Offset = Rsdt->Header.Length;

        /* The entries are each 32-bits, so count them */
        EntryCount = (TableLength - Offset) / sizeof(ULONG);
    }

    /* Start at the beginning of the array and loop it */
    for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++)
    {
        /* Are we using the XSDT? */
        if (Rsdt->Header.Signature != XSDT_SIGNATURE)
        {
            /* Read the 32-bit physical address */
            PhysicalAddress.QuadPart = Rsdt->Tables[CurrentEntry];
        }
        else
        {
            /* Read the 64-bit physical address */
            PhysicalAddress = Xsdt->Tables[CurrentEntry];
        }

        /* Map this table */
        Header = MmMapIoSpace(PhysicalAddress,
                              sizeof(DESCRIPTION_HEADER),
                              MmNonCached);
        if (!Header) break;

        /* Check if this is the table that's being asked for */
        if (Header->Signature == TableCode)
        {
            /* Allocate a buffer for it */
            TableBuffer = ExAllocatePoolWithTag(PagedPool,
                                                Header->Length,
                                                PCI_POOL_TAG);
            if (!TableBuffer) break;

            /* Copy the table into the buffer */
            RtlCopyMemory(TableBuffer, Header, Header->Length);
        }

        /* Done with this table, keep going */
        MmUnmapIoSpace(Header, sizeof(DESCRIPTION_HEADER));
    }

    if (Header) MmUnmapIoSpace(Header, sizeof(DESCRIPTION_HEADER));
    return NULL;
}
Ejemplo n.º 18
0
BOOLEAN
HalpCiaMachineCheck(
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )
/*++

Routine Description:

    This routine is given control when an hard error is acknowledged
    by the CIA chipset.  The routine is given the chance to
    correct and dismiss the error.

Arguments:

    ExceptionRecord - Supplies a pointer to the exception record generated
                      at the point of the exception.

    ExceptionFrame - Supplies a pointer to the exception frame generated
                     at the point of the exception.

    TrapFrame - Supplies a pointer to the trap frame generated
                at the point of the exception.

Return Value:

    TRUE is returned if the machine check has been handled and dismissed -
    indicating that execution can continue.  FALSE is return otherwise.

--*/
{
    CIA_ERR CiaError;

    //
    // Read the CIA error register to determine the source of the
    // error.
    //

    CiaError.all = READ_CIA_REGISTER( 
                    &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CiaErr );

#if HALDBG

    DbgPrint( "Cia Mchk: 0x%x\n", CiaError.all );

#endif //HALDBG

    //
    // Check that an error is valid.  If it is not this is a pretty
    // weird fatal condition.
    //

    if( CiaError.ErrValid == 0 ){
        DbgPrint( "Error reported but error valid = 0, CiaErr = 0x%x\n",
                    CiaError.all );
        goto FatalError;
    }

    //
    // Check for any uncorrectable error other than a master abort
    // on a PCI transaction.  Any of these other errors indicate a
    // fatal condition.
    //

	if( (CiaError.UnCorErr == 1) ||          // Uncorrectable error
	    (CiaError.CpuPe == 1) ||             // Ev5 bus parity error
	    (CiaError.MemNem == 1) ||            // Nonexistent memory error
	    (CiaError.PciSerr == 1) ||           // PCI bus serr detected
	    (CiaError.PciPerr == 1) ||           // PCI bus perr detected
	    (CiaError.PciAddrPe == 1) ||         // PCI bus address parity error
	    (CiaError.RcvdTarAbt == 1) ||        // Pci Target Abort
	    (CiaError.PaPteInv == 1) ||          // Invalid Pte
	    (CiaError.FromWrtErr == 1) ||        // Invalid write to flash rom
	    (CiaError.IoaTimeout == 1) ||        // Io Timeout occurred
	    (CiaError.LostUnCorErr == 1) ||      // Lost uncorrectable error
	    (CiaError.LostCpuPe == 1) ||         // Lost Ev5 bus parity error
	    (CiaError.LostMemNem == 1) ||        // Lost Nonexistent memory error
	    (CiaError.LostPciPerr == 1) ||       // Lost PCI bus perr detected
	    (CiaError.LostPciAddrPe == 1) ||     // Lost PCI address parity error
	    (CiaError.LostRcvdMasAbt == 1) ||    // Lost Pci Master Abort
	    (CiaError.LostRcvdTarAbt == 1) ||    // Lost Pci Target Abort
	    (CiaError.LostPaPteInv == 1) ||      // Lost Invalid Pte
	    (CiaError.LostFromWrtErr == 1) ||    // Lost Invalid write to flash rom
	    (CiaError.LostIoaTimeout == 1)       // Lost Io Timeout occurred
    ){
        DbgPrint( "Explicit fatal error, CiaErr = 0x%x\n",
                    CiaError.all );
        goto FatalError;
    }

    //
    // Check for a PCI configuration read error.  The CIA experiences
    // a master abort on a read to a non-existent PCI slot.
    //

   if( (CiaError.RcvdMasAbt == 1) && (HalpMasterAbortExpected != 0) ){ 

        //
        // So far, the error looks like a PCI configuration space read
        // that accessed a device that does not exist.  In order to fix
        // this up we expect that the original faulting instruction must 
        // be a load with v0 as the destination register.  Unfortunately,
        // machine checks are not precise exceptions so we may have exectued
        // many instructions since the faulting load.  For EV5 a pair of 
        // memory barrier instructions following the load will stall the pipe
        // waiting for load completion before the second memory barrier can
        // be issued.  Therefore, we expect the exception PC to point to either
        // the load instruction of one of the two memory barriers.  We will 
        // assume that if the exception pc is not an mb that instead it
        // points to the load that machine checked.  We must be careful to
        // not reexectute the load.
        //

        ALPHA_INSTRUCTION FaultingInstruction;
        BOOLEAN PreviousInstruction = FALSE;

        FaultingInstruction.Long = *(PULONG)((ULONG)TrapFrame->Fir); 
        if( FaultingInstruction.Memory.Opcode != MEMSPC_OP ){

            //
            // Exception pc does not point to a memory barrier, return
            // to the instruction after the exception pc.
            //

            TrapFrame->Fir += 4;

        }

        //
        // The error has matched all of our conditions.  Fix it up by
        // writing the value 0xffffffff into the destination of the load.
        // 

        TrapFrame->IntV0 = (ULONGLONG)0xffffffffffffffff;

        //
        // Clear the error condition in CIA_ERR.
        //

        CiaError.all = 0;
        CiaError.RcvdMasAbt = 1;
        CiaError.ErrValid = 1;
        WRITE_CIA_REGISTER( &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->CiaErr,
                            CiaError.all );

        return TRUE;

    } //end if( (CiaError.RcvdMasAbt == 1) && (HalpMasterAbortExpected != 0) )

    DbgPrint( "Unexpected master abort\n" );

//
// The system is not well and cannot continue reliable execution.
// Print some useful messages and return FALSE to indicate that the error
// was not handled.
//

FatalError:

    DbgPrint( "Handling fatal error\n" );

    //
    // Clear the error condition in the MCES register.
    //

    HalpUpdateMces( TRUE, TRUE );

    //
    // Proceed to display the error.
    //

    HalAcquireDisplayOwnership(NULL);

    //
    // Display the dreaded banner.
    //

    HalDisplayString( "\nFatal system hardware error.\n\n" );


    HalpCiaReportFatalError();

    return( FALSE );

}
Ejemplo n.º 19
0
VOID
KeDumpMachineState (
    IN PKPROCESSOR_STATE ProcessorState,
    IN PCHAR Buffer,
    IN PULONG BugCheckParameters,
    IN ULONG NumberOfParameters,
    IN PKE_BUGCHECK_UNICODE_TO_ANSI UnicodeToAnsiRoutine
)

/*++

Routine Description:

    This function formats and displays the machine state at the time of the
    to bug check.

Arguments:

    ProcessorState - Supplies a pointer to a processor state record.

    Buffer - Supplies a pointer to a buffer to be used to output machine
        state information.

    BugCheckParameters - Supplies a pointer to an array of additional
        bug check information.

    NumberOfParameters - Suppiles the size of the bug check parameters
        array.

    UnicodeToAnsiRoutine - Supplies a pointer to a routine to convert Unicode strings
        to Ansi strings without touching paged translation tables.

Return Value:

    None.

--*/

{

    PCONTEXT ContextRecord;
    ULONG ControlPc;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    ULONG DisplayColumn;
    ULONG DisplayHeight;
    ULONG DisplayRow;
    ULONG DisplayWidth;
    UNICODE_STRING DllName;
    ULONG EstablisherFrame;
    PRUNTIME_FUNCTION FunctionEntry;
    PVOID ImageBase;
    ULONG Index;
    BOOLEAN InFunction;
    ULONG LastStack;
    PLIST_ENTRY ModuleListHead;
    PLIST_ENTRY NextEntry;
    ULONG NextPc;
    ULONG StackLimit;
    UCHAR AnsiBuffer[ 32 ];
    ULONG DateStamp;

    //
    // Call the HAL to force all external interrupts to be disabled
    // at the interrupt controller. PowerPC optimization does not
    // do this when raising to high level.
    //
    for (Index = 0; Index < MAXIMUM_VECTOR; Index++) {
        HalDisableSystemInterrupt(Index, HIGH_LEVEL);
    }

    //
    // Query display parameters.
    //

    HalQueryDisplayParameters(&DisplayWidth,
                              &DisplayHeight,
                              &DisplayColumn,
                              &DisplayRow);

    //
    // Display any addresses that fall within the range of any module in
    // the loaded module list.
    //

    for (Index = 0; Index < NumberOfParameters; Index += 1) {
        ImageBase = KiPcToFileHeader((PVOID)*BugCheckParameters,
                                     &ImageBase,
                                     &DataTableEntry);

        if (ImageBase != NULL) {
            sprintf(Buffer,
                    "*** %08lX has base at %08lX - %s\n",
                    *BugCheckParameters,
                    ImageBase,
                    (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));

            HalDisplayString(Buffer);
        }

        BugCheckParameters += 1;
    }

    //
    // Virtually unwind to the caller of bug check.
    //

    ContextRecord = &ProcessorState->ContextFrame;
    LastStack = ContextRecord->Gpr1;
    ControlPc = ContextRecord->Lr - 4;
    NextPc = ControlPc;
    FunctionEntry = KiLookupFunctionEntry(ControlPc);
    if (FunctionEntry != NULL) {
        NextPc = RtlVirtualUnwind(ControlPc,
                                  FunctionEntry,
                                  ContextRecord,
                                  &InFunction,
                                  &EstablisherFrame,
                                  NULL,
                                  0,
                                  0xffffffff);
    }

    //
    // At this point the context record contains the machine state at the
    // call to bug check.
    //
    // Put out the machine state at the time of the bugcheck.
    //

    sprintf(Buffer,
            "\n Machine State at Call to Bug Check    IAR:%08lX MSR:%08lX\n",
            ContextRecord->Lr,
            ContextRecord->Msr);

    HalDisplayString(Buffer);

    //
    // Format and output the integer registers.
    //

    sprintf(Buffer,
            " R0:%8lX  R1:%8lX  R2:%8lX  R3:%8lX  R4:%8lX  R5:%8lX\n",
            ContextRecord->Gpr0,
            ContextRecord->Gpr1,
            ContextRecord->Gpr2,
            ContextRecord->Gpr3,
            ContextRecord->Gpr4,
            ContextRecord->Gpr5);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            " R6:%8lX  R7:%8lX  R8:%8lX  R9:%8lX R10:%8lX R11:%8lX\n",
            ContextRecord->Gpr6,
            ContextRecord->Gpr7,
            ContextRecord->Gpr8,
            ContextRecord->Gpr9,
            ContextRecord->Gpr10,
            ContextRecord->Gpr11);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R12:%8lX R13:%8lX R14:%8lX R15:%8lX R16:%8lX R17:%8lX\n",
            ContextRecord->Gpr12,
            ContextRecord->Gpr13,
            ContextRecord->Gpr14,
            ContextRecord->Gpr15,
            ContextRecord->Gpr16,
            ContextRecord->Gpr17);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R18:%8lX R19:%8lX R20:%8lX R21:%8lX R22:%8lX R23:%8lX\n",
            ContextRecord->Gpr18,
            ContextRecord->Gpr19,
            ContextRecord->Gpr20,
            ContextRecord->Gpr21,
            ContextRecord->Gpr22,
            ContextRecord->Gpr23);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R24:%8lX R25:%8lX R26:%8lX R27:%8lX R28:%8lX R29:%8lX\n",
            ContextRecord->Gpr24,
            ContextRecord->Gpr25,
            ContextRecord->Gpr26,
            ContextRecord->Gpr27,
            ContextRecord->Gpr28,
            ContextRecord->Gpr29);

    HalDisplayString(Buffer);

    sprintf(Buffer,
            "R30:%8lX R31:%8lX  CR:%8lX CTR:%8lX XER:%8lX\n",
            ContextRecord->Gpr30,
            ContextRecord->Gpr31,
            ContextRecord->Cr,
            ContextRecord->Ctr,
            ContextRecord->Xer);

    HalDisplayString(Buffer);

#if 0

    //
    // I'd much rather see a longer stack trace and skip the floating
    // point stuff when the system crashes.  plj
    //

    //
    // Format and output the floating registers.
    //
    DumpFloat = (PULONG)(&ContextRecord->Fpr0);
    sprintf(Buffer,
            " F0- F3:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr4);
    sprintf(Buffer,
            " F4- F7:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr8);
    sprintf(Buffer,
            " F8-F11:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr12);
    sprintf(Buffer,
            "F12-F15:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr16);
    sprintf(Buffer,
            "F16-F19:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr20);
    sprintf(Buffer,
            "F20-F23:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr24);
    sprintf(Buffer,
            "F24-F27:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);

    DumpFloat = (PULONG)(&ContextRecord->Fpr28);
    sprintf(Buffer,
            "F28-F31:%08lX%08lX %08lX%08lX %08lX%08lX %08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat,
            *(DumpFloat+3),
            *(DumpFloat+2),
            *(DumpFloat+5),
            *(DumpFloat+4),
            *(DumpFloat+7),
            *(DumpFloat+6));

    HalDisplayString(Buffer);


    DumpFloat = (PULONG)(&ContextRecord->Fpscr);
    sprintf(Buffer,
            "  FPSCR:%08lX%08lX\n",
            *(DumpFloat+1),
            *DumpFloat);

    HalDisplayString(Buffer);

#define STAKWALK 4
#else
#define STAKWALK 8
#endif

    //
    // Output short stack back trace with base address.
    //

    DllName.Length = 0;
    DllName.Buffer = L"";
    if (FunctionEntry != NULL) {
        StackLimit = (ULONG)KeGetCurrentThread()->KernelStack;
        HalDisplayString("Callee-Sp Return-Ra  Dll Base - Name\n");
        for (Index = 0; Index < STAKWALK; Index += 1) {
            ImageBase = KiPcToFileHeader((PVOID)ControlPc,
                                         &ImageBase,
                                         &DataTableEntry);

            sprintf(Buffer,
                    " %08lX %08lX : %08lX - %s\n",
                    ContextRecord->Gpr1,
                    NextPc + 4,
                    ImageBase,
                    (*UnicodeToAnsiRoutine)( (ImageBase != NULL) ? &DataTableEntry->BaseDllName : &DllName,
                                             AnsiBuffer, sizeof( AnsiBuffer )));

            HalDisplayString(Buffer);

            if ((NextPc != ControlPc) || (ContextRecord->Gpr1 != LastStack)) {
                ControlPc = NextPc;
                LastStack = ContextRecord->Gpr1;
                FunctionEntry = KiLookupFunctionEntry(ControlPc);
                if ((FunctionEntry != NULL) && (LastStack < StackLimit)) {
                    NextPc = RtlVirtualUnwind(ControlPc,
                                              FunctionEntry,
                                              ContextRecord,
                                              &InFunction,
                                              &EstablisherFrame,
                                              NULL,
                                              0,
                                              0xffffffff);
                } else {
                    NextPc = ContextRecord->Lr;
                }

            } else {
                break;
            }
        }
    }

    //
    // Output the build number and other useful information.
    //

    sprintf(Buffer,
            "\nIRQL : %d, DPC Active : %s, SYSVER 0x%08x\n",
            KeGetCurrentIrql(),
            KeIsExecutingDpc() ? "TRUE" : "FALSE",
            NtBuildNumber);

    HalDisplayString(Buffer);

    //
    // Output the processor id and the primary cache sizes.
    //

    sprintf(Buffer,
            "Processor Id: %d.%d, Icache: %d, Dcache: %d",
            PCR->ProcessorVersion,
            PCR->ProcessorRevision,
            PCR->FirstLevelIcacheSize,
            PCR->FirstLevelDcacheSize);

    HalDisplayString(Buffer);

    //
    // If the display width is greater than 80 + 24 (the size of a DLL
    // name and base address), then display all the modules loaded in
    // the system.
    //

    HalQueryDisplayParameters(&DisplayWidth,
                              &DisplayHeight,
                              &DisplayColumn,
                              &DisplayRow);

    if (DisplayWidth > (80 + 24)) {
        HalDisplayString("\n");
        if (KeLoaderBlock != NULL) {
            ModuleListHead = &KeLoaderBlock->LoadOrderListHead;

        } else {
            ModuleListHead = &PsLoadedModuleList;
        }

        //
        // Output display headers.
        //

        Index = 1;
        KiDisplayString(80, Index, "Dll Base DateStmp - Name");
        NextEntry = ModuleListHead->Flink;
        if (NextEntry != NULL) {

            //
            // Scan the list of loaded modules and display their base
            // address and name.
            //

            while (NextEntry != ModuleListHead) {
                Index += 1;
                DataTableEntry = CONTAINING_RECORD(NextEntry,
                                                   LDR_DATA_TABLE_ENTRY,
                                                   InLoadOrderLinks);

                if (MmDbgReadCheck(DataTableEntry->DllBase) != NULL) {
                    PIMAGE_NT_HEADERS NtHeaders;

                    NtHeaders = RtlImageNtHeader(DataTableEntry->DllBase);
                    DateStamp = NtHeaders->FileHeader.TimeDateStamp;

                } else {
                    DateStamp = 0;
                }
                sprintf(Buffer,
                        "%08lX %08lx - %s",
                        DataTableEntry->DllBase,
                        DateStamp,
                        (*UnicodeToAnsiRoutine)( &DataTableEntry->BaseDllName, AnsiBuffer, sizeof( AnsiBuffer )));

                KiDisplayString(80, Index, Buffer);
                NextEntry = NextEntry->Flink;
                if (Index > DisplayHeight) {
                    break;
                }
            }
        }
    }

    //
    // Reset the current display position.
    //

    HalSetDisplayParameters(DisplayColumn, DisplayRow);

    //
    // The system has crashed, if we are running without the Kernel
    // debugger attached, attach it now.
    //

    KdInitSystem(NULL, FALSE);

    return;
}
Ejemplo n.º 20
0
VOID
HalpBootCpuRestart(
    VOID
    )

/*++

Routine Description:

    This function returns control to the firmware Arcreboot routine.
    it waits until all other cpu's have beet shut down.
    this code is executed only on the boot cpu

Arguments:

    None

Return Value:

    Does not return.

--*/
{
    UCHAR DataByte;
    ULONG cpt;


        HalpColumn = 0;HalpRow = 0;    // if we already were in VGA mode
        HalDisplayString("\n");
        HalpClearVGADisplay();
        HalDisplayString("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); 
        HalDisplayString("                   ���������������������������������������ͻ\n");
        HalDisplayString("                   �                                       �\n");
        HalDisplayString("                   �          Restart in Progress          �\n");
        HalDisplayString("                   �                                       �\n");
        HalDisplayString("                   ���������������������������������������ͼ\n");

    cpt = 0;
    while(*(PULONG)(& (((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->ActiveProcessor[0]) )) {
        KeStallExecutionProcessor(500000);
        ++cpt;if (cpt == 20) break;
    }    
    //
    // if there are still ssome processors active, we do a reset of the entire machine
    //
    if (*(PULONG)(& (((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->ActiveProcessor[0]) )) {

#if DBG
    DbgPrint(" Some processors did not answer . Reset machine started. \n");
#endif
        if (HalpIsTowerPci) {
            WRITE_REGISTER_ULONG((PULONG) PCI_TOWER_DCU_CONTROL, DC_SWRESET);
        }else {
            
            WRITE_REGISTER_UCHAR((PUCHAR) PCI_MCR_ADDR, PCI_MCR_SOFTRESET);
        }
    } else {

#if DBG
    DbgPrint("Reboot started \n");
#endif

    }

        DataByte = READ_REGISTER_UCHAR(
                      &((PEISA_CONTROL) HalpOnboardControlBase)->ExtendedNmiResetControl);

        ((PNMI_EXTENDED_CONTROL) &DataByte)->BusReset = 1;

        WRITE_REGISTER_UCHAR(
            &((PEISA_CONTROL) HalpOnboardControlBase)->ExtendedNmiResetControl,
            DataByte
            );

        KeStallExecutionProcessor(10000);

        ((PNMI_EXTENDED_CONTROL) &DataByte)->BusReset = 0;

        WRITE_REGISTER_UCHAR(
            &((PEISA_CONTROL) HalpOnboardControlBase)->ExtendedNmiResetControl,
            DataByte
            );


        ArcReboot();

        for (;;) ;
}
Ejemplo n.º 21
0
VOID
HalReturnToFirmware(
    IN FIRMWARE_REENTRY Routine
    )



/*++

Routine Description:

    This function returns control to the specified firmware routine.
    In most cases it generates a soft reset.

Arguments:

    Routine - Supplies a value indicating which firmware routine to invoke.

Return Value:

    Does not return.

--*/

{
    KIRQL OldIrql;
    UCHAR DataByte;

    //
    // Disable Interrupts.
    //
    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    //
    // Case on the type of return.
    //

    switch (Routine) {
    case HalHaltRoutine:

        //
        // Hang looping.
        //

        // power off asked by DCU/IDC (power - fan or ... failure)
        if (((ULONG)(((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipRoutine) != (ULONG)-1) &&
            (((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipHalInfo == 1))

            ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipRoutine(
                    ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipContext
                       );
        for (;;) {}

    case HalPowerDownRoutine:

        // power off always done by DCU

        if ((ULONG)(((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipRoutine) != (ULONG)-1) 

            ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipRoutine(
                    ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipContext
                       );
        //
        // PowerOff is done by the SNI machines by writing the Power_Off bit to the machine control register ...
        //
        if (HalpIsTowerPci){
            WRITE_REGISTER_ULONG((PULONG) PCI_TOWER_DCU_CONTROL, DC_POWEROFF);
        }else{
            WRITE_REGISTER_UCHAR((PUCHAR) PCI_MCR_ADDR, PCI_MCR_POWEROFF);
        }

        for (;;) {}  // hang looping


    case HalRestartRoutine:
    case HalRebootRoutine:
    case HalInteractiveModeRoutine:

        // power off asked by DCU/IDC (power - fan or ... failure)
        if (((ULONG)(((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipRoutine) != (ULONG)-1) &&
            (((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipHalInfo == 1))

            ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipRoutine(
                    ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->EipContext
                       );

        if (HalpIsMulti) {
            ULONG Mask,i;

            for (i=0;i<HalpIsMulti;i++)
                if (((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->ActiveProcessor[PCR->Number])
                    Mask |= 1<<i;


            Mask = Mask & ~(PCR->SetMember);
#if DBGG
            DbgPrint("Send message RESTART to maskcpu = %x \n",Mask);
#endif

            HalpRequestIpi(Mask,MPA_RESTART_MESSAGE);
            //
            // if this is not the Boot CPU, we call a special Firmware entry to stop it
            //

            //
            // remove this processor from the list of active processors
            //
                
            ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->ActiveProcessor[PCR->Number]=0;

            if (PCR->Number ) {
                
#if DBGG
                 DbgPrint(" Reinit slave %x \n", ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->reinit_slave);    
#endif
                ((SNI_PRIVATE_VECTOR *)(SYSTEM_BLOCK->VendorVector))->reinit_slave();

            } else HalpBootCpuRestart();
        }

        HalpColumn = 0;HalpRow = 0;    // if we already were in VGA mode
        HalDisplayString("\n");
        HalpClearVGADisplay();
        HalDisplayString("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        HalDisplayString("                   ���������������������������������������ͻ\n");
        HalDisplayString("                   �                                       �\n");
        HalDisplayString("                   �          Restart in Progress          �\n");
        HalDisplayString("                   �                                       �\n");
        HalDisplayString("                   ���������������������������������������ͼ\n");

        DataByte = READ_REGISTER_UCHAR(
                      &((PEISA_CONTROL) HalpOnboardControlBase)->ExtendedNmiResetControl);

        ((PNMI_EXTENDED_CONTROL) &DataByte)->BusReset = 1;

        WRITE_REGISTER_UCHAR(
            &((PEISA_CONTROL) HalpOnboardControlBase)->ExtendedNmiResetControl,
            DataByte
            );

        KeStallExecutionProcessor(10000);

        ((PNMI_EXTENDED_CONTROL) &DataByte)->BusReset = 0;

        WRITE_REGISTER_UCHAR(
            &((PEISA_CONTROL) HalpOnboardControlBase)->ExtendedNmiResetControl,
            DataByte
            );

        ArcReboot();

        for (;;) ;

    default:
        DbgPrint("HalReturnToFirmware invalid argument\n");
        KeLowerIrql(OldIrql);
        DbgBreakPoint();
    }
}
Ejemplo n.º 22
0
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.  This is a JENSEN feature.
    //

    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;
}
Ejemplo n.º 23
0
BOOLEAN
NTAPI
KdPortInitializeEx(
    IN PCPPORT PortInformation,
    IN ULONG ComPortNumber)
{
    NTSTATUS Status;
    CHAR buffer[80];

#if 0 // Deactivated because never used in fact (was in KdPortInitialize but we use KdPortInitializeEx)
    /*
     * Find the port if needed
     */
    SIZE_T i;

    if (!PortInitialized)
    {
        DefaultPort.BaudRate = PortInformation->BaudRate;

        if (ComPortNumber == 0)
        {
            /*
             * Start enumerating COM ports from the last one to the first one,
             * and break when we find a valid port.
             * If we reach the first element of the list, the invalid COM port,
             * then it means that no valid port was found.
             */
            for (i = sizeof(BaseArray) / sizeof(BaseArray[0]) - 1; i > 0; i--)
            {
                if (CpDoesPortExist(UlongToPtr(BaseArray[i])))
                {
                    PortInformation->Address = DefaultPort.Address = BaseArray[i];
                    ComPortNumber = (ULONG)i;
                    break;
                }
            }
            if (ComPortNumber == 0)
            {
                sprintf(buffer,
                        "\nKernel Debugger: No COM port found!\n\n");
                HalDisplayString(buffer);
                return FALSE;
            }
        }

        PortInitialized = TRUE;
    }
#endif

    /*
     * Initialize the port
     */
    Status = CpInitialize(PortInformation,
                          (ComPortNumber == 0 ? PortInformation->Address
                                              : UlongToPtr(BaseArray[ComPortNumber])),
                          (PortInformation->BaudRate == 0 ? DEFAULT_BAUD_RATE
                                                          : PortInformation->BaudRate));
    if (!NT_SUCCESS(Status))
    {
        sprintf(buffer,
                "\nKernel Debugger: Serial port not found!\n\n");
        HalDisplayString(buffer);
        return FALSE;
    }
    else
    {
#ifndef NDEBUG
        /* Print message to blue screen */
        sprintf(buffer,
                "\nKernel Debugger: Serial port found: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
                ComPortNumber,
                PortInformation->Address,
                PortInformation->BaudRate);
        HalDisplayString(buffer);
#endif /* NDEBUG */

#if 0
        /* Set global info */
        KdComPortInUse = DefaultPort.Address;
#endif
        return TRUE;
    }
}
Ejemplo n.º 24
0
NTSTATUS
NtDisplayString(
    IN PUNICODE_STRING String
    )

/*++

Routine Description:

    This service calls the HAL to display a string on the console.

    The caller must have SeTcbPrivilege to display a message.

Arguments:

    String - A pointer to the string that is to be displayed.

Return Value:

    !NT_SUCCESS - The operation failed or the caller did not have appropriate
        priviledges.

--*/

{
    KPROCESSOR_MODE PreviousMode;
    UNICODE_STRING CapturedString;
    PUCHAR StringBuffer = NULL;
    PUCHAR AnsiStringBuffer = NULL;
    STRING AnsiString;

    //
    // Check to determine if the caller has the privilege to make this
    // call.
    //

    PreviousMode = KeGetPreviousMode();
    if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) {
        return STATUS_PRIVILEGE_NOT_HELD;
    }

    try {

        //
        // If the previous mode was user, then check the input parameters.
        //

        if (PreviousMode != KernelMode) {

            //
            // Probe and capture the input unicode string descriptor.
            //

            CapturedString = ProbeAndReadUnicodeString(String);

            //
            // If the captured string descriptor has a length of zero, then
            // return success.
            //

            if ((CapturedString.Buffer == 0) ||
                (CapturedString.MaximumLength == 0)) {
                return STATUS_SUCCESS;
            }

            //
            // Probe and capture the input string.
            //
            // N.B. Note the length is in bytes.
            //

            ProbeForRead(
                CapturedString.Buffer,
                CapturedString.MaximumLength,
                sizeof(UCHAR)
                );

            //
            // Allocate a non-paged string buffer because the buffer passed to
            // HalDisplay string must be non-paged.
            //

            StringBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                                  CapturedString.MaximumLength,
                                                  'grtS');

            if ( !StringBuffer ) {
                return STATUS_NO_MEMORY;
            }

            RtlMoveMemory(StringBuffer,
                          CapturedString.Buffer,
                          CapturedString.MaximumLength);

            CapturedString.Buffer = (PWSTR)StringBuffer;

            //
            // Allocate a string buffer for the ansi string.
            //

            AnsiStringBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                                 CapturedString.MaximumLength,
                                                 'grtS');


            if (AnsiStringBuffer == NULL) {
                ExFreePool(StringBuffer);
                return STATUS_NO_MEMORY;
            }

            AnsiString.MaximumLength = CapturedString.MaximumLength;
            AnsiString.Length = 0;
            AnsiString.Buffer = AnsiStringBuffer;

            //
            // Transform the string to ANSI until the HAL handles unicode.
            //

            RtlUnicodeStringToOemString(
                &AnsiString,
                &CapturedString,
                FALSE
                );

        } else {

            //
            // Allocate a string buffer for the ansi string.
            //

            AnsiStringBuffer = ExAllocatePoolWithTag(NonPagedPool,
                                                     String->MaximumLength,
                                                     'grtS');


            if (AnsiStringBuffer == NULL) {
                return STATUS_NO_MEMORY;
            }

            AnsiString.MaximumLength = String->MaximumLength;
            AnsiString.Length = 0;
            AnsiString.Buffer = AnsiStringBuffer;

            //
            // We were in kernel mode; just transform the original string.
            //

            RtlUnicodeStringToOemString(
                &AnsiString,
                String,
                FALSE
                );
        }

        HalDisplayString( AnsiString.Buffer );

        //
        // Free up the memory we used to store the strings.
        //

        if (PreviousMode != KernelMode) {
            ExFreePool(StringBuffer);
        }

        ExFreePool(AnsiStringBuffer);

    } except(EXCEPTION_EXECUTE_HANDLER) {
        if (StringBuffer != NULL) {
            ExFreePool(StringBuffer);
        }

        return GetExceptionCode();
    }

    return STATUS_SUCCESS;
}
Ejemplo n.º 25
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It prints the 
   appropriate status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    UCHAR   StatusByte;
    UCHAR   EisaPort;
    ULONG   port;
    ULONG   AddressSpace = 1; // 1 = I/O address space
    BOOLEAN Status;
    PHYSICAL_ADDRESS BusAddress;
    PHYSICAL_ADDRESS TranslatedAddress;
    UCHAR Datum;
    
    NMIcount++;

    //
    // Set the Eisa NMI disable bit. We do this to mask further NMI 
    // interrupts while we're servicing this one.
    //
    Datum = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&Datum))->NmiDisable = 1;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, Datum);
#ifdef HALDBG
    DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n\r", Datum);
#endif

    StatusByte =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (StatusByte & 0x80) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
#else
        //
        // jwlfix - For the present, we're commenting out an NMI parity
        //          error bugcheck, until investigation into its causes
        //          yields a better solution.
        //
        //    HalDisplayString ("NMI: Parity Check / Parity Error\n");
        //    KeBugCheck(NMI_HARDWARE_FAILURE);
        //    return (TRUE);
#endif
    }

    Datum = READ_REGISTER_UCHAR((PUCHAR)HalpServerControlQva );
    if (((PMIKASA_SRV)(&Datum))->HaltIncoming == 0 ||
        ((PMIKASA_SRV)(&Datum))->TempFail == 1     ||
        ((PMIKASA_SRV)(&Datum))->Fan1Fault == 0    ||
        ((PMIKASA_SRV)(&Datum))->Fan2Fault == 0) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Server management NMI\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
        DbgPrint("HalHandleNMI:    Server Management Byte = 0x%x\r\n", Datum);
#else
        //
        // jwlfix - All the above conditions are for handling server 
        //          management features.  Implementing more than simple 
        //          dismissal waits upon definition of desired behavior 
        //          by platform designers or Microsoft Windows NT 
        //          requirements for server behavior.
#endif
    }

    if (StatusByte & 0x40) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
#else
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
#endif
    }

#if 0
     // jwlfix - This code can be added in later, as we have need
     //          for it.  It's good to have it here, for when it
     //          might be of use.
     //
     // This is an Eisa machine, check for extnded nmi information...
     //

     StatusByte = READ_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl);

     if (StatusByte & 0x80) {
         HalDisplayString ("NMI: Fail-safe timer\n");
     }

     if (StatusByte & 0x40) {
         HalDisplayString ("NMI: Bus Timeout\n");
     }

     if (StatusByte & 0x20) {
         HalDisplayString ("NMI: Software NMI generated\n");
     }

     //
     // Look for any Eisa expansion board.  See if it asserted NMI.
     //
     // jwlfix - The following doesn't work, at this moment; it's 
     //          likey the 12-bit shift, which should be a 5-bit 
     //          shift on Mikasa.
     //

     BusAddress.HighPart = 0;

     for (EisaPort = 0; EisaPort <= 0xf; EisaPort++)
     {
         BusAddress.LowPart = (EisaPort << 12) + 0xC80;

         Status = HalTranslateBusAddress(Eisa,  // InterfaceType
                                         0,     // BusNumber
                                         BusAddress,
                                         &AddressSpace,  // 1=I/O address space
                                         &TranslatedAddress); // QVA
         if (Status == FALSE)
         {
             UCHAR pbuf[80];
             sprintf(pbuf,
                     "Unable to translate bus address %x for EISA slot %d\n",
                     BusAddress.LowPart, EisaPort);
             HalDisplayString(pbuf);
             KeBugCheck(NMI_HARDWARE_FAILURE);
         }

         port = TranslatedAddress.LowPart;

         WRITE_PORT_UCHAR ((PUCHAR) port, 0xff);
         StatusByte = READ_PORT_UCHAR ((PUCHAR) port);

         if ((StatusByte & 0x80) == 0) {
             //
             // Found valid Eisa board,  Check to see if its
             // IOCHKERR is asserted.
             //

             StatusByte = READ_PORT_UCHAR ((PUCHAR) port+4);
             if (StatusByte & 0x2) {
                 EisaNMIMsg[25] = (EisaPort > 9 ? 'A'-10 : '0') + EisaPort;
                 HalDisplayString (EisaNMIMsg);
                 KeBugCheck(NMI_HARDWARE_FAILURE);
             }
         }
     }
#ifdef HALDBG
    // Reset extended NMI interrupts (for debugging purposes only).
    WRITE_PORT_UCHAR(
      &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl, 0x00);
    WRITE_PORT_UCHAR(
      &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl, 0x02);
#endif
#endif

#ifdef HALDBG
    DbgPrint("HalHandleNMI: Resetting PERR#; NMI count = %d\r\n", NMIcount);
#endif

    //
    // Reset PERR# and disable it.
    //
    WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);

    //
    //   now enable it again.
    //
    WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);

    //
    // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
    // now that we're done servicing this one.
    //
    Datum = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&Datum))->NmiDisable = 0;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, Datum);
#ifdef HALDBG
    DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n\r", Datum);
#endif

    return(TRUE);
}
Ejemplo n.º 26
0
BOOLEAN
HalpCalibrateStall (
    VOID
    )

/*++

Routine Description:

    This function calibrates the stall execution HAL service and connects
    the clock and profile interrupts to the appropriate NT service routines.

Arguments:

    None.

Return Value:

    A value of TRUE is returned if the calibration is successfully
    completed. Otherwise a value of FALSE is returned.

--*/

{

    ULONG Index;
    KIRQL OldIrql;

    //
    // Use a range of scale factors from 50ns down to 10ns assuming a
    // five instruction stall loop.
    //

    for (Index = 200; Index > 0; Index -= 10) {

        //
        // Disable all interrupts and establish calibration parameters.
        //

        KeRaiseIrql(HIGH_LEVEL, &OldIrql);

        //
        // Set the scale factor, stall count, starting stall count, and
        // ending stall count values.
        //

        PCR->StallScaleFactor = 4000 / (Index * 5);
        PCR->StallExecutionCount = 0;
        HalpStallStart = 0;
        HalpStallEnd = 0;

        //
        // Enable interrupts and stall execution.
        //

        KeLowerIrql(OldIrql);

        //
        // Stall execution for (MAXIMUM_INCREMENT / 10) * 4 us.
        //

        KeStallExecutionProcessor((MAXIMUM_INCREMENT / 10) * 4);

        //
        // If both the starting and ending stall counts have been captured,
        // then break out of loop.
        //

        if ((HalpStallStart != 0) && (HalpStallEnd != 0)) {
            break;
        }

    }

    if (Index == 0) {
	    HalDisplayString("������������������������������������������������������������ͻ\n");
    	HalDisplayString("�WARNING:     Cannot compute stall factor                    �\n");
    	HalDisplayString("�WARNING:     Using default value (250 Mhz)                  �\n");
    	HalDisplayString("������������������������������������������������������������ͼ\n");
		HalpStallScaleFactor = 0x20;
		HalpProfileCountRate = 125*1000000;
    }
	else {
    	//
    	// Compute the profile interrupt rate.
    	//

    	HalpProfileCountRate =
                	HalpProfileCountRate * ((1000 * 1000 * 10) / MAXIMUM_INCREMENT);

    	//
    	// Compute the stall execution scale factor.
    	//

    	HalpStallScaleFactor = (HalpStallEnd - HalpStallStart +
                            	((MAXIMUM_INCREMENT / 10) - 1)) / (MAXIMUM_INCREMENT / 10);

    	if (HalpStallScaleFactor <= 0) {
	        HalpStallScaleFactor = 1;
	    }
	}

    PCR->StallScaleFactor = HalpStallScaleFactor;

    //
    // Set the time increment value and connect the real clock interrupt
    // routine.
    //

    PCR->InterruptRoutine[CLOCK2_LEVEL] = (PKINTERRUPT_ROUTINE) HalpClockInterrupt;

    //
    // Write the compare register and clear the count register, and
    // connect the profile interrupt if profiling is done via count/compare interrupt.
    //

    HalpWriteCompareRegisterAndClear(DEFAULT_PROFILE_COUNT);
    PCR->InterruptRoutine[PROFILE_LEVEL] = (PKINTERRUPT_ROUTINE) HalpProfileInterrupt;
    return TRUE;
}