windows-nt/Source/XPSP1/NT/base/boot/startup/i386/trapdump.c

420 lines
6.7 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
trap.c
Author:
Thomas Parslow [TomP] Mar-01-90
Abstract:
General purpose trap handler for 80386 boot loader. When built in
debugger is present, output is redirected to the com port. When no
debugger is present, output goes to the display.
--*/
#include "su.h"
extern
USHORT
InDebugger;
extern
UCHAR
GDTregister;
extern
UCHAR
IDTregister;
extern
VOID
OutPort(
USHORT
);
extern
USHORT
InPort(
VOID
);
extern
VOID
ReEnterDebugger(
VOID
);
extern
USHORT
TssKernel;
extern
USHORT
Redirect;
extern
VOID RealMode(
VOID
);
VOID
TrapHandler(
IN ULONG,
IN USHORT
);
VOID
DumpProcessorContext(
VOID
);
VOID
DumpSystemRegisters(
VOID
);
VOID
DumpCommonRegisters(
VOID
);
VOID
DisplayFlags(
ULONG f
);
VOID
DumpTSS(
VOID
);
ULONG
GetAddress(
VOID
);
VOID
GetNumber(
PCHAR cp
);
USHORT
GetChar(
VOID
);
VOID
DumpAddress(
ULONG
);
#define PG_FAULT_MSG " =================== PAGE FAULT ================================= \n\n"
#define DBL_FAULT_MSG " ================== DOUBLE FAULT ================================ \n\n"
#define GP_FAULT_MSG " ============== GENERAL PROTECTION FAULT ======================== \n\n"
#define STK_OVERRUN_MSG " ===== STACK SEGMENT OVERRUN or NOT PRESENT FAULT =============== \n\n"
#define EX_FAULT_MSG " ===================== EXCEPTION ================================ \n\n"
#define DEBUG_EXCEPTION "\nDEBUG TRAP "
#define ishex(x) ( ( x >= '0' && x <= '9') || (x >= 'A' && x <= 'F') || (x >= 'a' && x <= 'f') )
//
// Global Trap Frame Pointer
//
PTF TrapFrame=0;
VOID
TrapHandler(
IN ULONG Padding,
IN USHORT TF_base
)
/*++
Routine Description:
Prints minimal trap information
Arguments:
386 Trap Frame on Stack
Environment:
16-bit protect mode only.
--*/
{
//
// Initialize global trap frame pointer and print trap number
//
TrapFrame = (PTF)&TF_base;
//
// Fix esp to point to where it pointed before trap
//
TrapFrame->Fesp += 24;
BlPrint("\n TRAP %lx ",TrapFrame->TrapNum);
//
// Print the trap specific header and display processor context
//
switch(TrapFrame->TrapNum) {
case 1:
case 3:
puts( DEBUG_EXCEPTION );
DumpCommonRegisters();
break;
case 8:
puts( DBL_FAULT_MSG );
DumpTSS();
break;
case 12:
puts( STK_OVERRUN_MSG );
DumpProcessorContext();
break;
case 13:
puts( GP_FAULT_MSG );
DumpProcessorContext();
break;
case 14:
puts( PG_FAULT_MSG );
BlPrint("** At linear address %lx\n",TrapFrame->Fcr2);
DumpProcessorContext();
break;
default :
puts( EX_FAULT_MSG );
DumpProcessorContext();
break;
}
RealMode();
while (1); //**** WAITFOREVER *** //
}
VOID
DumpProcessorContext(
VOID
)
/*++
Routine Description:
Dumps all the processors registers. Called whenever a trap or fault
occurs.
Arguments:
None
Returns:
Nothing
--*/
{
DumpSystemRegisters();
DumpCommonRegisters();
}
VOID
DumpSystemRegisters(
VOID
)
/*++
Routine Description:
Dumps (writes to the display or com poirt) the x86 processor control
registers only. Does not dump the common registers (see
DumpCommonRegisters)
Arguments:
None
Returns:
Nothing
--*/
{
BlPrint("\n tr=%x cr0=%lx cr2=%lx cr3=%lx\n",
TrapFrame->Ftr,TrapFrame->Fcr0,TrapFrame->Fcr2,TrapFrame->Fcr3);
BlPrint(" gdt limit=%x base=%lx idt limit=%x base=%lx\n",
*(PUSHORT)&GDTregister,*(PULONG)(&GDTregister + 2),
*(PUSHORT)&IDTregister,*(PULONG)(&IDTregister + 2));
}
VOID
DumpCommonRegisters(
VOID
)
/*++
Routine Description:
Dumps (writes to the display or com poirt) the x86 processor
commond registers only.
Arguments:
None
Returns:
Nothing
--*/
{
USHORT err;
//
// Is the error code valid or just a padding dword
//
if ((TrapFrame->TrapNum == 8) || (TrapFrame->TrapNum >= 10 && TrapFrame->TrapNum <= 14) )
err = (USHORT)TrapFrame->Error;
else
err = 0;
//
// Display the processor's common registers
//
BlPrint("\n cs:eip=%x:%lx ss:esp=%x:%lx errcode=%x\n",
(USHORT)(TrapFrame->Fcs & 0xffff),TrapFrame->Feip,(USHORT)TrapFrame->Fss,TrapFrame->Fesp,err);
DisplayFlags(TrapFrame->Feflags);
BlPrint(" eax=%lx ebx=%lx ecx=%lx edx=%lx",TrapFrame->Feax,TrapFrame->Febx,TrapFrame->Fecx,TrapFrame->Fedx);
BlPrint(" ds=%x es=%x\n",TrapFrame->Fds,TrapFrame->Fes);
BlPrint(" edi=%lx esi=%lx ebp=%lx cr0=%lx",TrapFrame->Fedi,TrapFrame->Fesi,TrapFrame->Febp,TrapFrame->Fcr0);
BlPrint(" fs=%x gs=%x\n",TrapFrame->Ffs,TrapFrame->Fgs);
}
VOID
DisplayFlags(
ULONG f
)
/*++
Routine Description:
Writes the value of the key flags in the flags register to
the display or com port.
Arguments:
f - the 32bit flags word
Returns:
Nothing
--*/
{
BlPrint(" flags=%lx ",f);
if (f & FLAG_CF) puts("Cy "); else puts("NoCy ");
if (f & FLAG_ZF) puts("Zr "); else puts("NoZr ");
if (f & FLAG_IE) puts("IntEn"); else puts("IntDis ");
if (f & FLAG_DF) puts("Up "); else puts("Down ");
if (f & FLAG_TF) puts("TrapEn \n"); else puts("TrapDis \n");
}
VOID
DumpTSS(
VOID
)
/*++
Routine Description:
Writes the contents of the TSS to the display or com port when
called after a double fault.
Arguments:
None
Returns:
Nothing
--*/
{
PTSS_FRAME pTss;
// FP_SEG(Fp) = Fcs;
// FP_OFF(Fp) = Fip;
pTss = (PTSS_FRAME) &TssKernel;
//
// Dump the outgoing TSS
//
BlPrint("Link %x\n",pTss->Link);
BlPrint("Esp0 %x\n",pTss->Esp0);
BlPrint("SS0 %x\n",pTss->SS0);
BlPrint("Esp1 %lx\n",pTss->Esp1);
BlPrint("Cr3 %lx\n",pTss->Cr3);
BlPrint("Eip %lx\n",pTss->Eip);
BlPrint("Eflg %lx\n",pTss->Eflags);
BlPrint("Eax %lx\n",pTss->Eax);
BlPrint("Ebx %lx\n",pTss->Ebx);
BlPrint("Ecx %lx\n",pTss->Ecx);
BlPrint("Edx %lx\n",pTss->Edx);
BlPrint("Esp %lx\n",pTss->Esp);
BlPrint("Ebp %lx\n",pTss->Ebp);
BlPrint("Esi %lx\n",pTss->Esi);
BlPrint("Edi %lx\n",pTss->Edi);
BlPrint("ES %x\n",pTss->ES);
BlPrint("CS %x\n",pTss->CS);
BlPrint("SS %x\n",pTss->SS);
BlPrint("DS %x\n",pTss->DS);
BlPrint("FS %x\n",pTss->FS);
BlPrint("GS %x\n",pTss->GS);
BlPrint("Ldt %x\n",pTss->Ldt);
RealMode();
while(1);
}
// END OF FILE