cpu.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,156 行 · 第 1/2 页
C
1,156 行
}
switch (*Format) {
case 'X':
Flags |= PREFIX_ZERO;
Width = sizeof (UINT64) * 2;
//
// break skiped on purpose
//
case 'x':
if ((Flags & LONG_TYPE) == LONG_TYPE) {
Value = VA_ARG (Marker, UINT64);
} else {
Value = VA_ARG (Marker, UINTN);
}
EfiValueToHexStr (Buffer+Index, Value, Flags, Width);
for ( ; Buffer[Index] != L'\0'; Index ++) {
}
break;
default:
//
// if the type is unknown print it to the screen
//
Buffer[Index++] = *Format;
}
}
}
Buffer[Index++] = '\0';
VA_END (Marker);
return Index;
}
STATIC
VOID
DumpExceptionDataVgaOut (
IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
UINTN COLUMN_MAX;
UINTN ROW_MAX;
UINT32 ErrorCodeFlag;
CHAR16 *VideoBufferBase;
CHAR16 *VideoBuffer;
UINTN Index;
COLUMN_MAX = 80;
ROW_MAX = 25;
ErrorCodeFlag = 0x00027d00;
VideoBufferBase = (CHAR16 *) (UINTN) 0xb8000;
VideoBuffer = (CHAR16 *) (UINTN) 0xb8000;
#ifdef EFI32
SPrint (
VideoBuffer,
L"!!!! IA32 Exception Type - %08x !!!!",
InterruptType
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"EIP - %08x, CS - %08x, EFLAGS - %08x",
SystemContext.SystemContextIa32->Eip,
SystemContext.SystemContextIa32->Cs,
SystemContext.SystemContextIa32->Eflags
);
VideoBuffer += COLUMN_MAX;
if (ErrorCodeFlag & (1 << InterruptType)) {
SPrint (
VideoBuffer,
L"ExceptionData - %08x",
SystemContext.SystemContextIa32->ExceptionData
);
VideoBuffer += COLUMN_MAX;
}
SPrint (
VideoBuffer,
L"EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x",
SystemContext.SystemContextIa32->Eax,
SystemContext.SystemContextIa32->Ecx,
SystemContext.SystemContextIa32->Edx,
SystemContext.SystemContextIa32->Ebx
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x",
SystemContext.SystemContextIa32->Esp,
SystemContext.SystemContextIa32->Ebp,
SystemContext.SystemContextIa32->Esi,
SystemContext.SystemContextIa32->Edi
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x",
SystemContext.SystemContextIa32->Ds,
SystemContext.SystemContextIa32->Es,
SystemContext.SystemContextIa32->Fs,
SystemContext.SystemContextIa32->Gs,
SystemContext.SystemContextIa32->Ss
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"GDTR - %08x %08x, IDTR - %08x %08x",
SystemContext.SystemContextIa32->Gdtr[0],
SystemContext.SystemContextIa32->Gdtr[1],
SystemContext.SystemContextIa32->Idtr[0],
SystemContext.SystemContextIa32->Idtr[1]
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"LDTR - %08x, TR - %08x",
SystemContext.SystemContextIa32->Ldtr,
SystemContext.SystemContextIa32->Tr
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x",
SystemContext.SystemContextIa32->Cr0,
SystemContext.SystemContextIa32->Cr2,
SystemContext.SystemContextIa32->Cr3,
SystemContext.SystemContextIa32->Cr4
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x",
SystemContext.SystemContextIa32->Dr0,
SystemContext.SystemContextIa32->Dr1,
SystemContext.SystemContextIa32->Dr2,
SystemContext.SystemContextIa32->Dr3
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"DR6 - %08x, DR7 - %08x",
SystemContext.SystemContextIa32->Dr6,
SystemContext.SystemContextIa32->Dr7
);
VideoBuffer += COLUMN_MAX;
#else
SPrint (
VideoBuffer,
L"!!!! X64 Exception Type - %016lx !!!!",
(UINT64)InterruptType
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"RIP - %016lx, CS - %016lx, RFLAGS - %016lx",
SystemContext.SystemContextX64->Rip,
SystemContext.SystemContextX64->Cs,
SystemContext.SystemContextX64->Rflags
);
VideoBuffer += COLUMN_MAX;
if (ErrorCodeFlag & (1 << InterruptType)) {
SPrint (
VideoBuffer,
L"ExceptionData - %016lx",
SystemContext.SystemContextX64->ExceptionData
);
VideoBuffer += COLUMN_MAX;
}
SPrint (
VideoBuffer,
L"RAX - %016lx, RCX - %016lx, RDX - %016lx",
SystemContext.SystemContextX64->Rax,
SystemContext.SystemContextX64->Rcx,
SystemContext.SystemContextX64->Rdx
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"RBX - %016lx, RSP - %016lx, RBP - %016lx",
SystemContext.SystemContextX64->Rbx,
SystemContext.SystemContextX64->Rsp,
SystemContext.SystemContextX64->Rbp
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"RSI - %016lx, RDI - %016lx",
SystemContext.SystemContextX64->Rsi,
SystemContext.SystemContextX64->Rdi
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"R8 - %016lx, R9 - %016lx, R10 - %016lx",
SystemContext.SystemContextX64->R8,
SystemContext.SystemContextX64->R9,
SystemContext.SystemContextX64->R10
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"R11 - %016lx, R12 - %016lx, R13 - %016lx",
SystemContext.SystemContextX64->R11,
SystemContext.SystemContextX64->R12,
SystemContext.SystemContextX64->R13
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"R14 - %016lx, R15 - %016lx",
SystemContext.SystemContextX64->R14,
SystemContext.SystemContextX64->R15
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"DS - %016lx, ES - %016lx, FS - %016lx",
SystemContext.SystemContextX64->Ds,
SystemContext.SystemContextX64->Es,
SystemContext.SystemContextX64->Fs
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"GS - %016lx, SS - %016lx",
SystemContext.SystemContextX64->Gs,
SystemContext.SystemContextX64->Ss
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"GDTR - %016lx %016lx, LDTR - %016lx",
SystemContext.SystemContextX64->Gdtr[0],
SystemContext.SystemContextX64->Gdtr[1],
SystemContext.SystemContextX64->Ldtr
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"IDTR - %016lx %016lx, TR - %016lx",
SystemContext.SystemContextX64->Idtr[0],
SystemContext.SystemContextX64->Idtr[1],
SystemContext.SystemContextX64->Tr
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"CR0 - %016lx, CR2 - %016lx, CR3 - %016lx",
SystemContext.SystemContextX64->Cr0,
SystemContext.SystemContextX64->Cr2,
SystemContext.SystemContextX64->Cr3
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"CR4 - %016lx, CR8 - %016lx",
SystemContext.SystemContextX64->Cr4,
SystemContext.SystemContextX64->Cr8
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"DR0 - %016lx, DR1 - %016lx, DR2 - %016lx",
SystemContext.SystemContextX64->Dr0,
SystemContext.SystemContextX64->Dr1,
SystemContext.SystemContextX64->Dr2
);
VideoBuffer += COLUMN_MAX;
SPrint (
VideoBuffer,
L"DR3 - %016lx, DR6 - %016lx, DR7 - %016lx",
SystemContext.SystemContextX64->Dr3,
SystemContext.SystemContextX64->Dr6,
SystemContext.SystemContextX64->Dr7
);
VideoBuffer += COLUMN_MAX;
#endif
for (Index = 0; Index < COLUMN_MAX * ROW_MAX; Index ++) {
if (Index > (UINTN)(VideoBuffer - VideoBufferBase)) {
VideoBufferBase[Index] = 0x0c20;
} else {
VideoBufferBase[Index] |= 0x0c00;
}
}
return ;
}
#if CPU_EXCEPTION_VGA_SWITCH
STATIC
UINT16
SwitchVideoMode (
UINT16 NewVideoMode
)
/*++
Description
Switch Video Mode from current mode to new mode, and return the old mode.
Use Thuink
Arguments
NewVideoMode - new video mode want to set
Return
UINT16 - (UINT16) -1 indicates failure
Other value indicates the old mode, which can be used for restore later
--*/
{
EFI_STATUS Status;
EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios;
EFI_IA32_REGISTER_SET Regs;
UINT16 OriginalVideoMode = (UINT16) -1;
//
// See if the Legacy BIOS Protocol is available
//
Status = gBS->LocateProtocol (&gEfiLegacyBiosThunkProtocolGuid, NULL, (VOID **) &LegacyBios);
if (EFI_ERROR (Status)) {
return OriginalVideoMode;
}
//
// VESA SuperVGA BIOS - GET CURRENT VIDEO MODE
// AX = 4F03h
// Return:AL = 4Fh if function supported
// AH = status 00h successful
// BX = video mode (see #0082,#0083)
//
gBS->SetMem (&Regs, sizeof (Regs), 0);
Regs.X.AX = 0x4F03;
LegacyBios->Int86 (LegacyBios, 0x10, &Regs);
if (Regs.X.AX == 0x004F) {
OriginalVideoMode = Regs.X.BX;
} else {
//
// VIDEO - GET CURRENT VIDEO MODE
// AH = 0Fh
// Return:AH = number of character columns
// AL = display mode (see #0009 at AH=00h)
// BH = active page (see AH=05h)
//
gBS->SetMem (&Regs, sizeof (Regs), 0);
Regs.H.AH = 0x0F;
LegacyBios->Int86 (LegacyBios, 0x10, &Regs);
OriginalVideoMode = Regs.H.AL;
}
//
// Set new video mode
//
if (NewVideoMode < 0x100) {
//
// Set the 80x25 Text VGA Mode: Assume successful always
//
// VIDEO - SET VIDEO MODE
// AH = 00h
// AL = desired video mode (see #0009)
// Return:AL = video mode flag (Phoenix, AMI BIOS)
// 20h mode > 7
// 30h modes 0-5 and 7
// 3Fh mode 6
// AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
//
gBS->SetMem (&Regs, sizeof (Regs), 0);
Regs.H.AH = 0x00;
Regs.H.AL = (UINT8) NewVideoMode;
LegacyBios->Int86 (LegacyBios, 0x10, &Regs);
//
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
// AX = 1114h
// BL = block to load
// Return:Nothing
//
gBS->SetMem (&Regs, sizeof (Regs), 0);
Regs.H.AH = 0x11;
Regs.H.AL = 0x14;
Regs.H.BL = 0;
LegacyBios->Int86 (LegacyBios, 0x10, &Regs);
} else {
//
// VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
// AX = 4F02h
// BX = mode (see #0082,#0083)
// bit 15 set means don't clear video memory
// bit 14 set means enable linear framebuffer mode (VBE v2.0+)
// Return:AL = 4Fh if function supported
// AH = status
// 00h successful
// 01h failed
//
gBS->SetMem (&Regs, sizeof (Regs), 0);
Regs.X.AX = 0x4F02;
Regs.X.BX = NewVideoMode;
LegacyBios->Int86 (LegacyBios, 0x10, &Regs);
if (Regs.X.AX != 0x004F) {
DEBUG ((EFI_D_ERROR, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode));
return (UINT16) -1;
}
}
return OriginalVideoMode;
}
#endif
VOID
ExceptionHandler (
IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
#if CPU_EXCEPTION_VGA_SWITCH
UINT16 VideoMode;
#endif
#if CPU_EXCEPTION_DEBUG_OUTPUT
DumpExceptionDataDebugOut (InterruptType, SystemContext);
#endif
#if CPU_EXCEPTION_VGA_SWITCH
//
// Switch to text mode for RED-SCREEN output
//
VideoMode = SwitchVideoMode (0x83);
if (VideoMode == (UINT16) -1) {
DEBUG ((EFI_D_ERROR, "Video Mode Unknown!\n"));
}
#endif
DumpExceptionDataVgaOut (InterruptType, SystemContext);
//
// Use this macro to hang so that the compiler does not optimize out
// the following RET instructions. This allows us to return if we
// have a debugger attached.
//
EFI_DEADLOOP ();
#if CPU_EXCEPTION_VGA_SWITCH
//
// Switch back to the old video mode
//
if (VideoMode != (UINT16)-1) {
SwitchVideoMode (VideoMode);
}
#endif
return ;
}
VOID
TimerHandler (
IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
if (mTimerHandler != NULL) {
mTimerHandler (InterruptType, SystemContext);
}
}
EFI_DRIVER_ENTRY_POINT (InitializeCpu)
EFI_STATUS
EFIAPI
InitializeCpu (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Initialize the state information for the CPU Architectural Protocol
Arguments:
ImageHandle of the loaded driver
Pointer to the System Table
Returns:
EFI_SUCCESS - thread can be successfully created
EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure
EFI_DEVICE_ERROR - cannot create the thread
--*/
{
EFI_STATUS Status;
EFI_8259_IRQ Irq;
UINT32 InterruptVector;
EfiInitializeDriverLib (ImageHandle, SystemTable);
//
// Find the Legacy8259 protocol.
//
Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &gLegacy8259);
ASSERT_EFI_ERROR (Status);
//
// Get the interrupt vector number corresponding to IRQ0 from the 8259 driver
//
Status = gLegacy8259->GetVector (gLegacy8259, Efi8259Irq0, (UINT8 *) &mTimerVector);
ASSERT_EFI_ERROR (Status);
//
// Reload GDT, IDT
//
InitDescriptor ();
//
// Install Exception Handler (0x00 ~ 0x1F)
//
for (InterruptVector = 0; InterruptVector < 0x20; InterruptVector++) {
InstallInterruptHandler (
InterruptVector,
(VOID (*)(VOID))(UINTN)((UINTN)SystemExceptionHandler + mExceptionCodeSize * InterruptVector)
);
}
//
// Install Timer Handler
//
InstallInterruptHandler (mTimerVector, SystemTimerHandler);
//
// BUGBUG: We add all other interrupt vector
//
for (Irq = Efi8259Irq1; Irq <= Efi8259Irq15; Irq++) {
InterruptVector = 0;
Status = gLegacy8259->GetVector (gLegacy8259, Irq, (UINT8 *) &InterruptVector);
ASSERT_EFI_ERROR (Status);
InstallInterruptHandler (InterruptVector, SystemTimerHandler);
}
//
// Install CPU Architectural Protocol and the thunk protocol
//
mHandle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&mHandle,
&gEfiCpuArchProtocolGuid,
&mCpu,
NULL
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?