+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
- Cpu.c\r
-\r
-Abstract:\r
-\r
---*/\r
-\r
-#include "CpuDxe.h"\r
-\r
-//\r
-// Global Variables\r
-//\r
-\r
-BOOLEAN mInterruptState = FALSE;\r
-extern UINT32 mExceptionCodeSize;\r
-UINTN mTimerVector = 0;\r
-volatile EFI_CPU_INTERRUPT_HANDLER mTimerHandler = NULL;\r
-EFI_LEGACY_8259_PROTOCOL *gLegacy8259 = NULL;\r
-THUNK_CONTEXT mThunkContext;\r
-#define EFI_CPU_EFLAGS_IF 0x200\r
-\r
-VOID\r
-InitializeBiosIntCaller (\r
- VOID\r
- );\r
- \r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
- IN UINT8 BiosInt,\r
- IN EFI_IA32_REGISTER_SET *Regs\r
- );\r
- \r
-//\r
-// The Cpu Architectural Protocol that this Driver produces\r
-//\r
-EFI_HANDLE mHandle = NULL;\r
-EFI_CPU_ARCH_PROTOCOL mCpu = {\r
- CpuFlushCpuDataCache,\r
- CpuEnableInterrupt,\r
- CpuDisableInterrupt,\r
- CpuGetInterruptState,\r
- CpuInit,\r
- CpuRegisterInterruptHandler,\r
- CpuGetTimerValue,\r
- CpuSetMemoryAttributes,\r
- 1, // NumberOfTimers\r
- 4, // DmaBufferAlignment\r
-};\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuFlushCpuDataCache (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS Start,\r
- IN UINT64 Length,\r
- IN EFI_CPU_FLUSH_TYPE FlushType\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Flush CPU data cache. If the instruction cache is fully coherent\r
- with all DMA operations then function can just return EFI_SUCCESS.\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
- Start - Physical address to start flushing from.\r
- Length - Number of bytes to flush. Round up to chipset \r
- granularity.\r
- FlushType - Specifies the type of flush operation to perform.\r
-\r
-Returns: \r
-\r
- EFI_SUCCESS - If cache was flushed\r
- EFI_UNSUPPORTED - If flush type is not supported.\r
- EFI_DEVICE_ERROR - If requested range could not be flushed.\r
-\r
---*/\r
-{\r
- if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {\r
- AsmWbinvd ();\r
- return EFI_SUCCESS;\r
- } else if (FlushType == EfiCpuFlushTypeInvalidate) {\r
- AsmInvd ();\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuEnableInterrupt (\r
- IN EFI_CPU_ARCH_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Enables CPU interrupts.\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
-\r
-Returns: \r
- EFI_SUCCESS - If interrupts were enabled in the CPU\r
- EFI_DEVICE_ERROR - If interrupts could not be enabled on the CPU.\r
-\r
---*/\r
-{\r
- EnableInterrupts (); \r
-\r
- mInterruptState = TRUE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuDisableInterrupt (\r
- IN EFI_CPU_ARCH_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Disables CPU interrupts.\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
-\r
-Returns: \r
- EFI_SUCCESS - If interrupts were disabled in the CPU.\r
- EFI_DEVICE_ERROR - If interrupts could not be disabled on the CPU.\r
-\r
---*/\r
-{\r
- DisableInterrupts ();\r
- \r
- mInterruptState = FALSE;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuGetInterruptState (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- OUT BOOLEAN *State\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Return the state of interrupts.\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
- State - Pointer to the CPU's current interrupt state\r
-\r
-Returns: \r
- EFI_SUCCESS - If interrupts were disabled in the CPU.\r
- EFI_INVALID_PARAMETER - State is NULL.\r
- \r
---*/\r
-{\r
- if (State == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *State = mInterruptState;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuInit (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_CPU_INIT_TYPE InitType\r
- )\r
-\r
-/*++\r
-\r
-Routine Description:\r
- Generates an INIT to the CPU\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
- InitType - Type of CPU INIT to perform\r
-\r
-Returns: \r
- EFI_SUCCESS - If CPU INIT occurred. This value should never be\r
- seen.\r
- EFI_DEVICE_ERROR - If CPU INIT failed.\r
- EFI_NOT_SUPPORTED - Requested type of CPU INIT not supported.\r
-\r
---*/\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuRegisterInterruptHandler (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_EXCEPTION_TYPE InterruptType,\r
- IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Registers a function to be called from the CPU interrupt handler.\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
- InterruptType - Defines which interrupt to hook. IA-32 valid range\r
- is 0x00 through 0xFF\r
- InterruptHandler - A pointer to a function of type \r
- EFI_CPU_INTERRUPT_HANDLER that is called when a\r
- processor interrupt occurs. A null pointer\r
- is an error condition.\r
-\r
-Returns: \r
- EFI_SUCCESS - If handler installed or uninstalled.\r
- EFI_ALREADY_STARTED - InterruptHandler is not NULL, and a handler for \r
- InterruptType was previously installed\r
- EFI_INVALID_PARAMETER - InterruptHandler is NULL, and a handler for \r
- InterruptType was not previously installed.\r
- EFI_UNSUPPORTED - The interrupt specified by InterruptType is not\r
- supported.\r
-\r
---*/\r
-{\r
- if ((InterruptType < 0) || (InterruptType >= INTERRUPT_VECTOR_NUMBER)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- if ((UINTN)(UINT32)InterruptType != mTimerVector) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- if ((mTimerHandler == NULL) && (InterruptHandler == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- } else if ((mTimerHandler != NULL) && (InterruptHandler != NULL)) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
- mTimerHandler = InterruptHandler;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuGetTimerValue (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN UINT32 TimerIndex,\r
- OUT UINT64 *TimerValue,\r
- OUT UINT64 *TimerPeriod OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Returns a timer value from one of the CPU's internal timers. There is no\r
- inherent time interval between ticks but is a function of the CPU \r
- frequency.\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
- TimerIndex - Specifies which CPU timer ie requested\r
- TimerValue - Pointer to the returned timer value\r
- TimerPeriod - \r
-\r
-Returns: \r
- EFI_SUCCESS - If the CPU timer count was returned.\r
- EFI_UNSUPPORTED - If the CPU does not have any readable timers\r
- EFI_DEVICE_ERROR - If an error occurred reading the timer.\r
- EFI_INVALID_PARAMETER - TimerIndex is not valid\r
-\r
---*/\r
-{ \r
- if (TimerValue == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- \r
- if (TimerIndex == 0) {\r
- *TimerValue = AsmReadTsc ();\r
- if (TimerPeriod != NULL) {\r
- //\r
- // BugBug: Hard coded. Don't know how to do this generically\r
- //\r
- *TimerPeriod = 1000000000;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
- return EFI_INVALID_PARAMETER;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuSetMemoryAttributes (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Set memory cacheability attributes for given range of memeory\r
-\r
-Arguments:\r
- This - Protocol instance structure\r
- BaseAddress - Specifies the start address of the memory range\r
- Length - Specifies the length of the memory range\r
- Attributes - The memory cacheability for the memory range\r
-\r
-Returns: \r
- EFI_SUCCESS - If the cacheability of that memory range is set successfully\r
- EFI_UNSUPPORTED - If the desired operation cannot be done\r
- EFI_INVALID_PARAMETER - The input parameter is not correct, such as Length = 0\r
-\r
---*/\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-#if CPU_EXCEPTION_DEBUG_OUTPUT\r
-VOID\r
-DumpExceptionDataDebugOut (\r
- IN EFI_EXCEPTION_TYPE InterruptType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
- UINT32 ErrorCodeFlag;\r
-\r
- ErrorCodeFlag = 0x00027d00;\r
-\r
-#ifdef MDE_CPU_IA32\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "!!!! IA32 Exception Type - %08x !!!!\n",\r
- InterruptType\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "EIP - %08x, CS - %08x, EFLAGS - %08x\n",\r
- SystemContext.SystemContextIa32->Eip,\r
- SystemContext.SystemContextIa32->Cs,\r
- SystemContext.SystemContextIa32->Eflags\r
- ));\r
- if (ErrorCodeFlag & (1 << InterruptType)) {\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "ExceptionData - %08x\n",\r
- SystemContext.SystemContextIa32->ExceptionData\r
- ));\r
- }\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x\n",\r
- SystemContext.SystemContextIa32->Eax,\r
- SystemContext.SystemContextIa32->Ecx,\r
- SystemContext.SystemContextIa32->Edx,\r
- SystemContext.SystemContextIa32->Ebx\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",\r
- SystemContext.SystemContextIa32->Esp,\r
- SystemContext.SystemContextIa32->Ebp,\r
- SystemContext.SystemContextIa32->Esi,\r
- SystemContext.SystemContextIa32->Edi\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x\n",\r
- SystemContext.SystemContextIa32->Ds,\r
- SystemContext.SystemContextIa32->Es,\r
- SystemContext.SystemContextIa32->Fs,\r
- SystemContext.SystemContextIa32->Gs,\r
- SystemContext.SystemContextIa32->Ss\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "GDTR - %08x %08x, IDTR - %08x %08x\n",\r
- SystemContext.SystemContextIa32->Gdtr[0],\r
- SystemContext.SystemContextIa32->Gdtr[1],\r
- SystemContext.SystemContextIa32->Idtr[0],\r
- SystemContext.SystemContextIa32->Idtr[1]\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "LDTR - %08x, TR - %08x\n",\r
- SystemContext.SystemContextIa32->Ldtr,\r
- SystemContext.SystemContextIa32->Tr\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",\r
- SystemContext.SystemContextIa32->Cr0,\r
- SystemContext.SystemContextIa32->Cr2,\r
- SystemContext.SystemContextIa32->Cr3,\r
- SystemContext.SystemContextIa32->Cr4\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",\r
- SystemContext.SystemContextIa32->Dr0,\r
- SystemContext.SystemContextIa32->Dr1,\r
- SystemContext.SystemContextIa32->Dr2,\r
- SystemContext.SystemContextIa32->Dr3\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "DR6 - %08x, DR7 - %08x\n",\r
- SystemContext.SystemContextIa32->Dr6,\r
- SystemContext.SystemContextIa32->Dr7\r
- ));\r
-#else\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "!!!! X64 Exception Type - %016lx !!!!\n",\r
- (UINT64)InterruptType\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "RIP - %016lx, CS - %016lx, RFLAGS - %016lx\n",\r
- SystemContext.SystemContextX64->Rip,\r
- SystemContext.SystemContextX64->Cs,\r
- SystemContext.SystemContextX64->Rflags\r
- ));\r
- if (ErrorCodeFlag & (1 << InterruptType)) {\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "ExceptionData - %016lx\n",\r
- SystemContext.SystemContextX64->ExceptionData\r
- ));\r
- }\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",\r
- SystemContext.SystemContextX64->Rax,\r
- SystemContext.SystemContextX64->Rcx,\r
- SystemContext.SystemContextX64->Rdx\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",\r
- SystemContext.SystemContextX64->Rbx,\r
- SystemContext.SystemContextX64->Rsp,\r
- SystemContext.SystemContextX64->Rbp\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "RSI - %016lx, RDI - %016lx\n",\r
- SystemContext.SystemContextX64->Rsi,\r
- SystemContext.SystemContextX64->Rdi\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",\r
- SystemContext.SystemContextX64->R8,\r
- SystemContext.SystemContextX64->R9,\r
- SystemContext.SystemContextX64->R10\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",\r
- SystemContext.SystemContextX64->R11,\r
- SystemContext.SystemContextX64->R12,\r
- SystemContext.SystemContextX64->R13\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "R14 - %016lx, R15 - %016lx\n",\r
- SystemContext.SystemContextX64->R14,\r
- SystemContext.SystemContextX64->R15\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "DS - %016lx, ES - %016lx, FS - %016lx\n",\r
- SystemContext.SystemContextX64->Ds,\r
- SystemContext.SystemContextX64->Es,\r
- SystemContext.SystemContextX64->Fs\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "GS - %016lx, SS - %016lx\n",\r
- SystemContext.SystemContextX64->Gs,\r
- SystemContext.SystemContextX64->Ss\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "GDTR - %016lx %016lx, LDTR - %016lx\n",\r
- SystemContext.SystemContextX64->Gdtr[0],\r
- SystemContext.SystemContextX64->Gdtr[1],\r
- SystemContext.SystemContextX64->Ldtr\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "IDTR - %016lx %016lx, TR - %016lx\n",\r
- SystemContext.SystemContextX64->Idtr[0],\r
- SystemContext.SystemContextX64->Idtr[1],\r
- SystemContext.SystemContextX64->Tr\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",\r
- SystemContext.SystemContextX64->Cr0,\r
- SystemContext.SystemContextX64->Cr2,\r
- SystemContext.SystemContextX64->Cr3\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "CR4 - %016lx, CR8 - %016lx\n",\r
- SystemContext.SystemContextX64->Cr4,\r
- SystemContext.SystemContextX64->Cr8\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",\r
- SystemContext.SystemContextX64->Dr0,\r
- SystemContext.SystemContextX64->Dr1,\r
- SystemContext.SystemContextX64->Dr2\r
- ));\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",\r
- SystemContext.SystemContextX64->Dr3,\r
- SystemContext.SystemContextX64->Dr6,\r
- SystemContext.SystemContextX64->Dr7\r
- ));\r
-#endif\r
- return ;\r
-}\r
-#endif\r
-\r
-\r
-VOID\r
-DumpExceptionDataVgaOut (\r
- IN EFI_EXCEPTION_TYPE InterruptType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
- UINTN COLUMN_MAX;\r
- UINTN ROW_MAX;\r
- UINT32 ErrorCodeFlag;\r
- CHAR16 *VideoBufferBase;\r
- CHAR16 *VideoBuffer;\r
- UINTN Index;\r
-\r
- COLUMN_MAX = 80;\r
- ROW_MAX = 25;\r
- ErrorCodeFlag = 0x00027d00;\r
- VideoBufferBase = (CHAR16 *) (UINTN) 0xb8000;\r
- VideoBuffer = (CHAR16 *) (UINTN) 0xb8000;\r
-\r
-#ifdef MDE_CPU_IA32\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "!!!! IA32 Exception Type - %08x !!!!",\r
- InterruptType\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "EIP - %08x, CS - %08x, EFLAGS - %08x",\r
- SystemContext.SystemContextIa32->Eip,\r
- SystemContext.SystemContextIa32->Cs,\r
- SystemContext.SystemContextIa32->Eflags\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
- if (ErrorCodeFlag & (1 << InterruptType)) {\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "ExceptionData - %08x",\r
- SystemContext.SystemContextIa32->ExceptionData\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
- }\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "EAX - %08x, ECX - %08x, EDX - %08x, EBX - %08x",\r
- SystemContext.SystemContextIa32->Eax,\r
- SystemContext.SystemContextIa32->Ecx,\r
- SystemContext.SystemContextIa32->Edx,\r
- SystemContext.SystemContextIa32->Ebx\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x",\r
- SystemContext.SystemContextIa32->Esp,\r
- SystemContext.SystemContextIa32->Ebp,\r
- SystemContext.SystemContextIa32->Esi,\r
- SystemContext.SystemContextIa32->Edi\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "DS - %08x, ES - %08x, FS - %08x, GS - %08x, SS - %08x",\r
- SystemContext.SystemContextIa32->Ds,\r
- SystemContext.SystemContextIa32->Es,\r
- SystemContext.SystemContextIa32->Fs,\r
- SystemContext.SystemContextIa32->Gs,\r
- SystemContext.SystemContextIa32->Ss\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "GDTR - %08x %08x, IDTR - %08x %08x",\r
- SystemContext.SystemContextIa32->Gdtr[0],\r
- SystemContext.SystemContextIa32->Gdtr[1],\r
- SystemContext.SystemContextIa32->Idtr[0],\r
- SystemContext.SystemContextIa32->Idtr[1]\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "LDTR - %08x, TR - %08x",\r
- SystemContext.SystemContextIa32->Ldtr,\r
- SystemContext.SystemContextIa32->Tr\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x",\r
- SystemContext.SystemContextIa32->Cr0,\r
- SystemContext.SystemContextIa32->Cr2,\r
- SystemContext.SystemContextIa32->Cr3,\r
- SystemContext.SystemContextIa32->Cr4\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x",\r
- SystemContext.SystemContextIa32->Dr0,\r
- SystemContext.SystemContextIa32->Dr1,\r
- SystemContext.SystemContextIa32->Dr2,\r
- SystemContext.SystemContextIa32->Dr3\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "DR6 - %08x, DR7 - %08x",\r
- SystemContext.SystemContextIa32->Dr6,\r
- SystemContext.SystemContextIa32->Dr7\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-#else\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "!!!! X64 Exception Type - %016lx !!!!",\r
- (UINT64)InterruptType\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "RIP - %016lx, CS - %016lx, RFLAGS - %016lx",\r
- SystemContext.SystemContextX64->Rip,\r
- SystemContext.SystemContextX64->Cs,\r
- SystemContext.SystemContextX64->Rflags\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- if (ErrorCodeFlag & (1 << InterruptType)) {\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "ExceptionData - %016lx",\r
- SystemContext.SystemContextX64->ExceptionData\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
- }\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "RAX - %016lx, RCX - %016lx, RDX - %016lx",\r
- SystemContext.SystemContextX64->Rax,\r
- SystemContext.SystemContextX64->Rcx,\r
- SystemContext.SystemContextX64->Rdx\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "RBX - %016lx, RSP - %016lx, RBP - %016lx",\r
- SystemContext.SystemContextX64->Rbx,\r
- SystemContext.SystemContextX64->Rsp,\r
- SystemContext.SystemContextX64->Rbp\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "RSI - %016lx, RDI - %016lx",\r
- SystemContext.SystemContextX64->Rsi,\r
- SystemContext.SystemContextX64->Rdi\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "R8 - %016lx, R9 - %016lx, R10 - %016lx",\r
- SystemContext.SystemContextX64->R8,\r
- SystemContext.SystemContextX64->R9,\r
- SystemContext.SystemContextX64->R10\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "R11 - %016lx, R12 - %016lx, R13 - %016lx",\r
- SystemContext.SystemContextX64->R11,\r
- SystemContext.SystemContextX64->R12,\r
- SystemContext.SystemContextX64->R13\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "R14 - %016lx, R15 - %016lx",\r
- SystemContext.SystemContextX64->R14,\r
- SystemContext.SystemContextX64->R15\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "DS - %016lx, ES - %016lx, FS - %016lx",\r
- SystemContext.SystemContextX64->Ds,\r
- SystemContext.SystemContextX64->Es,\r
- SystemContext.SystemContextX64->Fs\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "GS - %016lx, SS - %016lx",\r
- SystemContext.SystemContextX64->Gs,\r
- SystemContext.SystemContextX64->Ss\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "GDTR - %016lx %016lx, LDTR - %016lx",\r
- SystemContext.SystemContextX64->Gdtr[0],\r
- SystemContext.SystemContextX64->Gdtr[1],\r
- SystemContext.SystemContextX64->Ldtr\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "IDTR - %016lx %016lx, TR - %016lx",\r
- SystemContext.SystemContextX64->Idtr[0],\r
- SystemContext.SystemContextX64->Idtr[1],\r
- SystemContext.SystemContextX64->Tr\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx",\r
- SystemContext.SystemContextX64->Cr0,\r
- SystemContext.SystemContextX64->Cr2,\r
- SystemContext.SystemContextX64->Cr3\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "CR4 - %016lx, CR8 - %016lx",\r
- SystemContext.SystemContextX64->Cr4,\r
- SystemContext.SystemContextX64->Cr8\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx",\r
- SystemContext.SystemContextX64->Dr0,\r
- SystemContext.SystemContextX64->Dr1,\r
- SystemContext.SystemContextX64->Dr2\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-\r
- UnicodeSPrintAsciiFormat (\r
- VideoBuffer,\r
- COLUMN_MAX * sizeof (CHAR16),\r
- "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx",\r
- SystemContext.SystemContextX64->Dr3,\r
- SystemContext.SystemContextX64->Dr6,\r
- SystemContext.SystemContextX64->Dr7\r
- );\r
- VideoBuffer += COLUMN_MAX;\r
-#endif\r
-\r
- for (Index = 0; Index < COLUMN_MAX * ROW_MAX; Index ++) {\r
- if (Index > (UINTN)(VideoBuffer - VideoBufferBase)) {\r
- VideoBufferBase[Index] = 0x0c20;\r
- } else {\r
- VideoBufferBase[Index] |= 0x0c00;\r
- }\r
- }\r
-\r
- return ;\r
-}\r
-\r
-#if CPU_EXCEPTION_VGA_SWITCH\r
-UINT16\r
-SwitchVideoMode (\r
- UINT16 NewVideoMode\r
- )\r
-/*++\r
-Description\r
- Switch Video Mode from current mode to new mode, and return the old mode.\r
- Use Thuink\r
-\r
-Arguments\r
- NewVideoMode - new video mode want to set\r
-\r
-Return\r
- UINT16 - (UINT16) -1 indicates failure\r
- Other value indicates the old mode, which can be used for restore later\r
- \r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_LEGACY_BIOS_THUNK_PROTOCOL *LegacyBios;\r
- EFI_IA32_REGISTER_SET Regs;\r
- UINT16 OriginalVideoMode = (UINT16) -1;\r
- \r
-\r
- //\r
- // VESA SuperVGA BIOS - GET CURRENT VIDEO MODE\r
- // AX = 4F03h\r
- // Return:AL = 4Fh if function supported\r
- // AH = status 00h successful\r
- // BX = video mode (see #0082,#0083)\r
- //\r
- gBS->SetMem (&Regs, sizeof (Regs), 0);\r
- Regs.X.AX = 0x4F03;\r
- LegacyBiosInt86 (0x10, &Regs);\r
- if (Regs.X.AX == 0x004F) {\r
- OriginalVideoMode = Regs.X.BX;\r
- } else {\r
- //\r
- // VIDEO - GET CURRENT VIDEO MODE\r
- // AH = 0Fh\r
- // Return:AH = number of character columns\r
- // AL = display mode (see #0009 at AH=00h)\r
- // BH = active page (see AH=05h)\r
- //\r
- gBS->SetMem (&Regs, sizeof (Regs), 0);\r
- Regs.H.AH = 0x0F;\r
- LegacyBiosInt86 (0x10, &Regs);\r
- OriginalVideoMode = Regs.H.AL;\r
- }\r
-\r
- //\r
- // Set new video mode\r
- //\r
- if (NewVideoMode < 0x100) {\r
- //\r
- // Set the 80x25 Text VGA Mode: Assume successful always\r
- //\r
- // VIDEO - SET VIDEO MODE\r
- // AH = 00h\r
- // AL = desired video mode (see #0009)\r
- // Return:AL = video mode flag (Phoenix, AMI BIOS)\r
- // 20h mode > 7\r
- // 30h modes 0-5 and 7\r
- // 3Fh mode 6\r
- // AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)\r
- //\r
- gBS->SetMem (&Regs, sizeof (Regs), 0);\r
- Regs.H.AH = 0x00;\r
- Regs.H.AL = (UINT8) NewVideoMode;\r
- LegacyBiosInt86 (0x10, &Regs);\r
-\r
- //\r
- // VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)\r
- // AX = 1114h\r
- // BL = block to load\r
- // Return:Nothing\r
- //\r
- gBS->SetMem (&Regs, sizeof (Regs), 0);\r
- Regs.H.AH = 0x11;\r
- Regs.H.AL = 0x14;\r
- Regs.H.BL = 0;\r
- LegacyBiosInt86 (0x10, &Regs);\r
- } else {\r
- //\r
- // VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE\r
- // AX = 4F02h\r
- // BX = mode (see #0082,#0083)\r
- // bit 15 set means don't clear video memory\r
- // bit 14 set means enable linear framebuffer mode (VBE v2.0+)\r
- // Return:AL = 4Fh if function supported\r
- // AH = status\r
- // 00h successful\r
- // 01h failed\r
- //\r
- gBS->SetMem (&Regs, sizeof (Regs), 0);\r
- Regs.X.AX = 0x4F02;\r
- Regs.X.BX = NewVideoMode;\r
- LegacyBiosInt86 (0x10, &Regs);\r
- if (Regs.X.AX != 0x004F) {\r
- DEBUG ((EFI_D_ERROR, "SORRY: Cannot set to video mode: 0x%04X!\n", NewVideoMode));\r
- return (UINT16) -1;\r
- }\r
- }\r
-\r
- return OriginalVideoMode;\r
-}\r
-#endif\r
-\r
-VOID\r
-ExceptionHandler (\r
- IN EFI_EXCEPTION_TYPE InterruptType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
-#if CPU_EXCEPTION_VGA_SWITCH\r
- UINT16 VideoMode;\r
-#endif\r
-\r
-#if CPU_EXCEPTION_DEBUG_OUTPUT\r
- DumpExceptionDataDebugOut (InterruptType, SystemContext);\r
-#endif\r
-\r
-#if CPU_EXCEPTION_VGA_SWITCH\r
- //\r
- // Switch to text mode for RED-SCREEN output\r
- //\r
- VideoMode = SwitchVideoMode (0x83);\r
- if (VideoMode == (UINT16) -1) {\r
- DEBUG ((EFI_D_ERROR, "Video Mode Unknown!\n"));\r
- }\r
-#endif\r
-\r
- DumpExceptionDataVgaOut (InterruptType, SystemContext);\r
-\r
- //\r
- // Use this macro to hang so that the compiler does not optimize out\r
- // the following RET instructions. This allows us to return if we\r
- // have a debugger attached.\r
- //\r
- CpuDeadLoop ();\r
-\r
-#if CPU_EXCEPTION_VGA_SWITCH\r
- //\r
- // Switch back to the old video mode\r
- //\r
- if (VideoMode != (UINT16)-1) {\r
- SwitchVideoMode (VideoMode);\r
- }\r
-#endif\r
-\r
- return ;\r
-}\r
-\r
-VOID\r
-TimerHandler (\r
- IN EFI_EXCEPTION_TYPE InterruptType,\r
- IN EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
- if (mTimerHandler != NULL) {\r
- mTimerHandler (InterruptType, SystemContext);\r
- }\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeCpu (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Initialize the state information for the CPU Architectural Protocol\r
-\r
-Arguments:\r
- ImageHandle of the loaded driver\r
- Pointer to the System Table\r
-\r
-Returns:\r
- EFI_SUCCESS - thread can be successfully created\r
- EFI_OUT_OF_RESOURCES - cannot allocate protocol data structure\r
- EFI_DEVICE_ERROR - cannot create the thread\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_8259_IRQ Irq;\r
- UINT32 InterruptVector;\r
-\r
- //\r
- // Find the Legacy8259 protocol.\r
- //\r
- Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &gLegacy8259);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver\r
- //\r
- Status = gLegacy8259->GetVector (gLegacy8259, Efi8259Irq0, (UINT8 *) &mTimerVector);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Reload GDT, IDT\r
- //\r
- InitDescriptor ();\r
-\r
- //\r
- // Install Exception Handler (0x00 ~ 0x1F)\r
- //\r
- for (InterruptVector = 0; InterruptVector < 0x20; InterruptVector++) {\r
- InstallInterruptHandler (\r
- InterruptVector,\r
- (VOID (*)(VOID))(UINTN)((UINTN)SystemExceptionHandler + mExceptionCodeSize * InterruptVector)\r
- );\r
- }\r
-\r
- //\r
- // Install Timer Handler\r
- //\r
- InstallInterruptHandler (mTimerVector, SystemTimerHandler);\r
-\r
- //\r
- // BUGBUG: We add all other interrupt vector\r
- //\r
- for (Irq = Efi8259Irq1; Irq <= Efi8259Irq15; Irq++) {\r
- InterruptVector = 0;\r
- Status = gLegacy8259->GetVector (gLegacy8259, Irq, (UINT8 *) &InterruptVector);\r
- ASSERT_EFI_ERROR (Status);\r
- InstallInterruptHandler (InterruptVector, SystemTimerHandler);\r
- }\r
-\r
- InitializeBiosIntCaller();\r
- \r
- //\r
- // Install CPU Architectural Protocol and the thunk protocol\r
- //\r
- mHandle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mHandle,\r
- &gEfiCpuArchProtocolGuid,\r
- &mCpu,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-InitializeBiosIntCaller (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 RealModeBufferSize;\r
- UINT32 ExtraStackSize;\r
- EFI_PHYSICAL_ADDRESS LegacyRegionBase;\r
- \r
- //\r
- // Get LegacyRegion\r
- //\r
- AsmGetThunk16Properties (&RealModeBufferSize, &ExtraStackSize);\r
-\r
- LegacyRegionBase = 0x100000;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES(RealModeBufferSize + ExtraStackSize + 200),\r
- &LegacyRegionBase\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- mThunkContext.RealModeBuffer = (VOID*)(UINTN)LegacyRegionBase;\r
- mThunkContext.RealModeBufferSize = EFI_PAGES_TO_SIZE (RealModeBufferSize);\r
- mThunkContext.ThunkAttributes = 3;\r
- AsmPrepareThunk16(&mThunkContext);\r
- \r
-}\r
-\r
-BOOLEAN\r
-EFIAPI\r
-LegacyBiosInt86 (\r
- IN UINT8 BiosInt,\r
- IN EFI_IA32_REGISTER_SET *Regs\r
- )\r
-{\r
- UINTN Status;\r
- UINTN Eflags;\r
- IA32_REGISTER_SET ThunkRegSet;\r
- BOOLEAN Ret;\r
- UINT16 *Stack16;\r
- \r
- Regs->X.Flags.Reserved1 = 1;\r
- Regs->X.Flags.Reserved2 = 0;\r
- Regs->X.Flags.Reserved3 = 0;\r
- Regs->X.Flags.Reserved4 = 0;\r
- Regs->X.Flags.IOPL = 3;\r
- Regs->X.Flags.NT = 0;\r
- Regs->X.Flags.IF = 1;\r
- Regs->X.Flags.TF = 0;\r
- Regs->X.Flags.CF = 0;\r
-\r
- ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet));\r
- ThunkRegSet.E.EDI = Regs->E.EDI;\r
- ThunkRegSet.E.ESI = Regs->E.ESI;\r
- ThunkRegSet.E.EBP = Regs->E.EBP;\r
- ThunkRegSet.E.EBX = Regs->E.EBX;\r
- ThunkRegSet.E.EDX = Regs->E.EDX;\r
- ThunkRegSet.E.ECX = Regs->E.ECX;\r
- ThunkRegSet.E.EAX = Regs->E.EAX;\r
- ThunkRegSet.E.DS = Regs->E.DS;\r
- ThunkRegSet.E.ES = Regs->E.ES;\r
-\r
- CopyMem (&(ThunkRegSet.E.EFLAGS), &(Regs->E.EFlags), sizeof (UINT32));\r
- \r
- //\r
- // The call to Legacy16 is a critical section to EFI\r
- //\r
- Eflags = AsmReadEflags ();\r
- if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
- DisableInterrupts ();\r
- }\r
-\r
- //\r
- // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases.\r
- //\r
- Status = gLegacy8259->SetMode (gLegacy8259, Efi8259LegacyMode, NULL, NULL);\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16));\r
- Stack16 -= sizeof (ThunkRegSet.E.EFLAGS) / sizeof (UINT16);\r
- CopyMem (Stack16, &ThunkRegSet.E.EFLAGS, sizeof (ThunkRegSet.E.EFLAGS));\r
-\r
- ThunkRegSet.E.SS = (UINT16) (((UINTN) Stack16 >> 16) << 12);\r
- ThunkRegSet.E.ESP = (UINT16) (UINTN) Stack16;\r
- ThunkRegSet.E.Eip = (UINT16)((UINT32 *)NULL)[BiosInt];\r
- ThunkRegSet.E.CS = (UINT16)(((UINT32 *)NULL)[BiosInt] >> 16);\r
- mThunkContext.RealModeState = &ThunkRegSet;\r
- AsmThunk16 (&mThunkContext);\r
-\r
- //\r
- // Restore protected mode interrupt state\r
- //\r
- Status = gLegacy8259->SetMode (gLegacy8259, Efi8259ProtectedMode, NULL, NULL);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // End critical section\r
- //\r
- if ((Eflags | EFI_CPU_EFLAGS_IF) != 0) {\r
- EnableInterrupts ();\r
- }\r
-\r
- Regs->E.EDI = ThunkRegSet.E.EDI; \r
- Regs->E.ESI = ThunkRegSet.E.ESI; \r
- Regs->E.EBP = ThunkRegSet.E.EBP; \r
- Regs->E.EBX = ThunkRegSet.E.EBX; \r
- Regs->E.EDX = ThunkRegSet.E.EDX; \r
- Regs->E.ECX = ThunkRegSet.E.ECX; \r
- Regs->E.EAX = ThunkRegSet.E.EAX;\r
- Regs->E.SS = ThunkRegSet.E.SS;\r
- Regs->E.CS = ThunkRegSet.E.CS; \r
- Regs->E.DS = ThunkRegSet.E.DS; \r
- Regs->E.ES = ThunkRegSet.E.ES;\r
-\r
- CopyMem (&(Regs->E.EFlags), &(ThunkRegSet.E.EFLAGS), sizeof (UINT32));\r
-\r
- Ret = (BOOLEAN) (Regs->E.EFlags.CF == 1);\r
-\r
- return Ret;\r
-}\r
+++ /dev/null
-## @file\r
-# \r
-# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials \r
-# are licensed and made available under the terms and conditions of the BSD License \r
-# which accompanies this distribution. The full text of the license may be found at \r
-# http://opensource.org/licenses/bsd-license.php \r
-# \r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-#\r
-# Module Name:\r
-# Cpu.inf\r
-#\r
-# Abstract:\r
-#\r
-##\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = Cpu\r
- FILE_GUID = 10527025-78B2-4d3e-A9DF-41E75C220F5A\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
-\r
- ENTRY_POINT = InitializeCpu\r
-\r
-[Packages]\r
- DuetPkg/DuetPkg.dec\r
- MdePkg/MdePkg.dec\r
- IntelFrameworkPkg/IntelFrameworkPkg.dec\r
-\r
-[LibraryClasses]\r
- UefiDriverEntryPoint\r
- PrintLib\r
- UefiBootServicesTableLib\r
- BaseMemoryLib\r
-\r
-[Sources.IA32]\r
- Ia32/CpuInterrupt.asm |INTEL\r
- Ia32/CpuInterrupt.asm |MSFT\r
- Ia32/CpuInterrupt.S |GCC\r
-\r
-[Sources.X64]\r
- X64/CpuInterrupt.asm | INTEL\r
- X64/CpuInterrupt.asm | MSFT\r
- X64/CpuInterrupt.S |GCC\r
- \r
-[Sources]\r
- Cpu.c\r
- CpuDxe.h\r
-\r
-[Protocols]\r
- gEfiCpuArchProtocolGuid\r
- gEfiLegacy8259ProtocolGuid\r
-\r
-[Depex]\r
- gEfiLegacy8259ProtocolGuid\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
- CpuDxe.h\r
-\r
-Abstract:\r
-\r
---*/\r
-#ifndef _CPU_DXE_H\r
-#define _CPU_DXE_H\r
-\r
-#include <FrameworkDxe.h>\r
-\r
-#include <Protocol/Cpu.h>\r
-#include <Protocol/Legacy8259.h>\r
-\r
-#include <Protocol/LegacyBios.h>\r
-\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-#define CPU_EXCEPTION_DEBUG_OUTPUT 1\r
-#define CPU_EXCEPTION_VGA_SWITCH 0\r
-\r
-#define INTERRUPT_VECTOR_NUMBER 0x100\r
-\r
-//\r
-// Print primitives\r
-//\r
-//#define LEFT_JUSTIFY 0x01\r
-#define PREFIX_SIGN 0x02\r
-#define PREFIX_BLANK 0x04\r
-//#define COMMA_TYPE 0x08\r
-#define LONG_TYPE 0x10\r
-//#define PREFIX_ZERO 0x20\r
-#define OUTPUT_UNICODE 0x40\r
-//#define RADIX_HEX 0x80\r
-#define FORMAT_UNICODE 0x100\r
-#define PAD_TO_WIDTH 0x200\r
-#define ARGUMENT_UNICODE 0x400\r
-#define PRECISION 0x800\r
-#define ARGUMENT_REVERSED 0x1000\r
-\r
-//\r
-// Function declarations\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeCpu (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuFlushCpuDataCache (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS Start,\r
- IN UINT64 Length,\r
- IN EFI_CPU_FLUSH_TYPE FlushType\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuEnableInterrupt (\r
- IN EFI_CPU_ARCH_PROTOCOL *This\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuDisableInterrupt (\r
- IN EFI_CPU_ARCH_PROTOCOL *This\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuGetInterruptState (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- OUT BOOLEAN *State\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuInit (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_CPU_INIT_TYPE InitType\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuRegisterInterruptHandler (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_EXCEPTION_TYPE InterruptType,\r
- IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-CpuGetTimerValue (\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN UINT32 TimerIndex,\r
- OUT UINT64 *TimerValue,\r
- OUT UINT64 *TimerPeriod OPTIONAL\r
- );\r
- \r
-EFI_STATUS\r
-EFIAPI\r
-CpuSetMemoryAttributes(\r
- IN EFI_CPU_ARCH_PROTOCOL *This,\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN UINT64 Attributes\r
- ); \r
-\r
-VOID\r
-InstallInterruptHandler (\r
- UINTN Vector,\r
- VOID (*Handler)(VOID)\r
- );\r
-\r
-VOID\r
-SystemExceptionHandler (\r
- VOID\r
- );\r
-\r
-VOID\r
-SystemTimerHandler (\r
- VOID\r
- );\r
-\r
-VOID\r
-InitDescriptor (\r
- VOID\r
- );\r
-\r
-#endif\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#*\r
-#* Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-#* This program and the accompanying materials \r
-#* are licensed and made available under the terms and conditions of the BSD License \r
-#* which accompanies this distribution. The full text of the license may be found at \r
-#* http://opensource.org/licenses/bsd-license.php \r
-#* \r
-#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-#* \r
-#* CpuInterrupt.S\r
-#* \r
-#* Abstract:\r
-#*\r
-#------------------------------------------------------------------------------\r
-\r
-#PUBLIC SystemTimerHandler\r
-#PUBLIC SystemExceptionHandler\r
-#EXTERNDEF mExceptionCodeSize:DWORD\r
-\r
-#EXTERN TimerHandler: NEAR\r
-#EXTERN ExceptionHandler: NEAR\r
-#EXTERN mTimerVector: DWORD\r
-\r
- .data\r
- ASM_GLOBAL ASM_PFX(mExceptionCodeSize)\r
-ASM_PFX(mExceptionCodeSize): .long 9\r
-\r
- .text\r
- ASM_GLOBAL ASM_PFX(InitDescriptor)\r
-\r
-ASM_PFX(InitDescriptor):\r
- movl $GDT_BASE,%eax # EAX=PHYSICAL address of gdt\r
- movl %eax, gdtr + 2 # Put address of gdt into the gdtr\r
- lgdt gdtr\r
- movl $IDT_BASE,%eax # EAX=PHYSICAL address of idt\r
- movl %eax, idtr + 2 # Put address of idt into the idtr\r
- lidt idtr\r
- ret\r
-\r
-# VOID\r
-# InstallInterruptHandler (\r
-# UINTN Vector,\r
-# VOID (*Handler)(VOID)\r
-# )\r
- ASM_GLOBAL ASM_PFX(InstallInterruptHandler)\r
-ASM_PFX(InstallInterruptHandler):\r
-# Vector:DWORD @ 4(%esp)\r
-# Handler:DWORD @ 8(%esp)\r
-\r
- push %edi\r
- pushf # save eflags\r
- cli # turn off interrupts\r
- subl $6,%esp # open some space on the stack\r
- movl %esp,%edi\r
- sidt (%edi) # get fword address of IDT\r
- movl 2(%edi), %edi # move offset of IDT into EDI\r
- addl $6,%esp # correct stack\r
- movl 12(%esp),%eax # Get vector number\r
- shl $3,%eax # multiply by 8 to get offset\r
- addl %eax,%edi # add to IDT base to get entry\r
- movl 16(%esp),%eax # load new address into IDT entry\r
- movw %ax,(%edi) # write bits 15..0 of offset\r
- shrl $16,%eax # use ax to copy 31..16 to descriptors\r
- movw %ax,6(%edi) # write bits 31..16 of offset\r
- popf # restore flags (possible enabling interrupts)\r
- pop %edi\r
- ret\r
-\r
- .macro JmpCommonIdtEntry\r
- # jmp commonIdtEntry - this must be hand coded to keep the assembler from\r
- # using a 8 bit reletive jump when the entries are\r
- # within 255 bytes of the common entry. This must\r
- # be done to maintain the consistency of the size\r
- # of entry points...\r
- .byte 0xe9 # jmp 16 bit reletive \r
- .long commonIdtEntry - . - 4 # offset to jump to\r
- .endm\r
-\r
- .p2align 1\r
- ASM_GLOBAL ASM_PFX(SystemExceptionHandler)\r
-ASM_PFX(SystemExceptionHandler):\r
-INT0:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x0 \r
- JmpCommonIdtEntry\r
-# db 0e9h # jmp 16 bit reletive \r
-# dd commonIdtEntry - $ - 4 # offset to jump to\r
- \r
-INT1:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x1 \r
- JmpCommonIdtEntry\r
- \r
-INT2:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x2 \r
- JmpCommonIdtEntry\r
- \r
-INT3:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x3 \r
- JmpCommonIdtEntry\r
- \r
-INT4:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x4 \r
- JmpCommonIdtEntry\r
- \r
-INT5:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x5 \r
- JmpCommonIdtEntry\r
- \r
-INT6:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x6 \r
- JmpCommonIdtEntry\r
- \r
-INT7:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x7 \r
- JmpCommonIdtEntry\r
- \r
-INT8:\r
-# Double fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $0x8 \r
- JmpCommonIdtEntry\r
- \r
-INT9:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $0x9 \r
- JmpCommonIdtEntry\r
- \r
-INT10:\r
-# Invalid TSS causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $10\r
- JmpCommonIdtEntry\r
- \r
-INT11:\r
-# Segment Not Present causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $11\r
- JmpCommonIdtEntry\r
- \r
-INT12:\r
-# Stack fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $12\r
- JmpCommonIdtEntry\r
- \r
-INT13:\r
-# GP fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $13\r
- JmpCommonIdtEntry\r
- \r
-INT14:\r
-# Page fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $14\r
- JmpCommonIdtEntry\r
- \r
-INT15:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $15\r
- JmpCommonIdtEntry\r
- \r
-INT16:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $16\r
- JmpCommonIdtEntry\r
- \r
-INT17:\r
-# Alignment check causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- pushl $17\r
- JmpCommonIdtEntry\r
- \r
-INT18:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $18\r
- JmpCommonIdtEntry\r
- \r
-INT19:\r
- pushl $0x0 # push error code place holder on the stack\r
- pushl $19\r
- JmpCommonIdtEntry\r
-\r
-INTUnknown:\r
- # The following segment repeats (32 - 20) times:\r
- # No. 1\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 2\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 3\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 4\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 5\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 6\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 7\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 8\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 9\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 10\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 11\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 12\r
- pushl $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
-\r
-\r
- ASM_GLOBAL ASM_PFX(SystemTimerHandler)\r
-ASM_PFX(SystemTimerHandler):\r
- pushl $0\r
- pushl $ASM_PFX(mTimerVector)\r
- JmpCommonIdtEntry\r
-\r
-commonIdtEntry:\r
-# +---------------------+\r
-# + EFlags +\r
-# +---------------------+\r
-# + CS +\r
-# +---------------------+\r
-# + EIP +\r
-# +---------------------+\r
-# + Error Code +\r
-# +---------------------+\r
-# + Vector Number +\r
-# +---------------------+\r
-# + EBP +\r
-# +---------------------+ <-- EBP\r
-\r
- cli\r
- push %ebp\r
- movl %esp,%ebp\r
-\r
- #\r
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- # is 16-byte aligned\r
- #\r
- andl $0xfffffff0,%esp\r
- subl $12,%esp\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax#\r
- push %eax\r
- push %ecx\r
- push %edx\r
- push %ebx\r
- leal 6*4(%ebp),%ecx\r
- push %ecx # ESP\r
- push (%ebp) # EBP\r
- push %esi\r
- push %edi\r
-\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss#\r
- movw %ss,%ax\r
- push %eax\r
- movzx 4*4(%ebp),%eax\r
- push %eax\r
- movw %ds,%ax\r
- push %eax\r
- movw %es,%ax\r
- push %eax\r
- movw %fs,%ax\r
- push %eax\r
- movw %gs,%ax\r
- push %eax\r
-\r
-## UINT32 Eip#\r
- pushl 3*4(%ebp)\r
-\r
-## UINT32 Gdtr[2], Idtr[2]#\r
- subl $8,%esp\r
- sidt (%esp)\r
- subl $8,%esp\r
- sgdt (%esp)\r
-\r
-## UINT32 Ldtr, Tr#\r
- xorl %eax, %eax\r
- str %ax\r
- push %eax\r
- sldt %eax\r
- push %eax\r
-\r
-## UINT32 EFlags#\r
- pushl 5*4(%ebp)\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4#\r
- mov %cr4,%eax\r
- orl $0x208,%eax\r
- mov %eax,%cr4\r
- push %eax\r
- mov %cr3,%eax\r
- push %eax\r
- mov %cr2,%eax\r
- push %eax\r
- xor %eax, %eax\r
- push %eax\r
- mov %cr0,%eax\r
- push %eax\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#\r
- mov %dr7,%eax\r
- push %eax\r
-## clear Dr7 while executing debugger itself\r
- xor %eax, %eax\r
- mov %eax,%dr7\r
-\r
- mov %dr6,%eax\r
- push %eax\r
-## insure all status bits in dr6 are clear...\r
- xor %eax, %eax\r
- mov %eax,%dr6\r
-\r
- mov %dr3,%eax\r
- push %eax\r
- mov %dr2,%eax\r
- push %eax\r
- mov %dr1,%eax\r
- push %eax\r
- mov %dr0,%eax\r
- push %eax\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- sub $512,%esp\r
- mov %esp,%edi\r
- fxsave (%edi)\r
-\r
-## UINT32 ExceptionData;\r
- pushl 2*4(%ebp)\r
-\r
-## Prepare parameter and call\r
- mov %esp,%edx\r
- push %edx\r
- mov 1*4(%ebp),%eax\r
- push %eax\r
- cmpl $32,%eax\r
- jb CallException\r
- call ASM_PFX(TimerHandler)\r
- jmp ExceptionDone\r
-CallException:\r
- call ASM_PFX(ExceptionHandler)\r
-ExceptionDone:\r
- addl $8,%esp\r
-\r
- cli\r
-## UINT32 ExceptionData;\r
- addl $4,%esp\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- mov %esp,%esi\r
- fxrstor (%esi)\r
- addl $512,%esp\r
-\r
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop %eax\r
- mov %eax,%dr0\r
- pop %eax\r
- mov %eax,%dr1\r
- pop %eax\r
- mov %eax,%dr2\r
- pop %eax\r
- mov %eax,%dr3\r
-## skip restore of dr6. We cleared dr6 during the context save.\r
- addl $4,%esp\r
- pop %eax\r
- mov %eax,%dr7\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop %eax\r
- mov %eax,%cr0\r
- addl $4,%esp # not for Cr1\r
- pop %eax\r
- mov %eax,%cr2\r
- pop %eax\r
- mov %eax,%cr3\r
- pop %eax\r
- mov %eax,%cr4\r
-\r
-## UINT32 EFlags;\r
- popl 5*4(%ebp)\r
-\r
-## UINT32 Ldtr, Tr;\r
-## UINT32 Gdtr[2], Idtr[2];\r
-## Best not let anyone mess with these particular registers...\r
- addl $24,%esp\r
-\r
-## UINT32 Eip;\r
- popl 3*4(%ebp)\r
-\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-## NOTE - modified segment registers could hang the debugger... We\r
-## could attempt to insulate ourselves against this possibility,\r
-## but that poses risks as well.\r
-##\r
- pop %gs\r
- pop %fs\r
- pop %es\r
- pop %ds\r
- popl 4*4(%ebp)\r
- pop %ss\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pop %edi\r
- pop %esi\r
- addl $4,%esp # not for ebp\r
- addl $4,%esp # not for esp\r
- pop %ebx\r
- pop %edx\r
- pop %ecx\r
- pop %eax\r
-\r
- mov %ebp,%esp\r
- pop %ebp\r
- addl $8,%esp\r
- iret\r
-\r
-\r
-#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-# data\r
-#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- .data\r
- .p2align 2\r
-\r
-gdtr: .short GDT_END - GDT_BASE - 1 # GDT limit\r
- .long 0 # (GDT base gets set above)\r
-#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-# global descriptor table (GDT)\r
-#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- .p2align 2\r
-\r
-GDT_BASE:\r
-# null descriptor\r
-NULL_SEL = .-GDT_BASE\r
- .short 0 # limit 15:0\r
- .short 0 # base 15:0\r
- .byte 0 # base 23:16\r
- .byte 0 # type\r
- .byte 0 # limit 19:16, flags\r
- .byte 0 # base 31:24\r
-\r
-# linear data segment descriptor\r
-LINEAR_SEL = .-GDT_BASE\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x092 # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# linear code segment descriptor\r
-LINEAR_CODE_SEL = .-GDT_BASE\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x09A # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# system data segment descriptor\r
-SYS_DATA_SEL = .-GDT_BASE\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x092 # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# system code segment descriptor\r
-SYS_CODE_SEL = .-GDT_BASE\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x09A # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# spare segment descriptor\r
-SPARE3_SEL = .-GDT_BASE\r
- .short 0 # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0 # present, ring 0, data, expand-up, writable\r
- .byte 0 # page-granular, 32-bit\r
- .byte 0\r
-\r
-# spare segment descriptor\r
-SPARE4_SEL = .-GDT_BASE\r
- .short 0 # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0 # present, ring 0, data, expand-up, writable\r
- .byte 0 # page-granular, 32-bit\r
- .byte 0\r
-\r
-# spare segment descriptor\r
-SPARE5_SEL = .-GDT_BASE\r
- .short 0 # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0 # present, ring 0, data, expand-up, writable\r
- .byte 0 # page-granular, 32-bit\r
- .byte 0\r
-\r
-GDT_END:\r
-\r
- .p2align 2\r
-\r
-\r
-\r
-idtr: .short IDT_END - IDT_BASE - 1 # IDT limit\r
- .long 0 # (IDT base gets set above)\r
-#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-# interrupt descriptor table (IDT)\r
-#\r
-# Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
-# mappings. This implementation only uses the system timer and all other\r
-# IRQs will remain masked. The descriptors for vectors 33+ are provided\r
-# for convenience.\r
-#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-#idt_tag .byte "IDT",0 \r
- .p2align 2\r
-\r
-IDT_BASE:\r
-# divide by zero (INT 0)\r
-DIV_ZERO_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# debug exception (INT 1)\r
-DEBUG_EXCEPT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# NMI (INT 2)\r
-NMI_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# soft breakpoint (INT 3)\r
-BREAKPOINT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# overflow (INT 4)\r
-OVERFLOW_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# bounds check (INT 5)\r
-BOUNDS_CHECK_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# invalid opcode (INT 6)\r
-INVALID_OPCODE_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# device not available (INT 7)\r
-DEV_NOT_AVAIL_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# double fault (INT 8)\r
-DOUBLE_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# Coprocessor segment overrun - reserved (INT 9)\r
-RSVD_INTR_SEL1 = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# invalid TSS (INT 0ah)\r
-INVALID_TSS_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# segment not present (INT 0bh)\r
-SEG_NOT_PRESENT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# stack fault (INT 0ch)\r
-STACK_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# general protection (INT 0dh)\r
-GP_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# page fault (INT 0eh)\r
-PAGE_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# Intel reserved - do not use (INT 0fh)\r
-RSVD_INTR_SEL2 = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# floating point error (INT 0x10)\r
-FLT_POINT_ERR_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# alignment check (INT 0x11)\r
-ALIGNMENT_CHECK_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# machine check (INT 0x12)\r
-MACHINE_CHECK_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# SIMD floating-point exception (INT 0x13)\r
-SIMD_EXCEPTION_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
- # The following segment repeats (32 - 20) times:\r
- # No. 1\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 2\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 3\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 4\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 5\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 6\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 7\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 8\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 9\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 10\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 11\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- # No. 12\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-\r
-# 72 unspecified descriptors\r
- .fill 72 * 8, 1, 0\r
- \r
-# IRQ 0 (System timer) - (INT 0x68)\r
-IRQ0_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 1 (8042 Keyboard controller) - (INT 0x69)\r
-IRQ1_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
-IRQ2_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 3 (COM 2) - (INT 6bh)\r
-IRQ3_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 4 (COM 1) - (INT 6ch)\r
-IRQ4_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 5 (LPT 2) - (INT 6dh)\r
-IRQ5_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 6 (Floppy controller) - (INT 6eh)\r
-IRQ6_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 7 (LPT 1) - (INT 6fh)\r
-IRQ7_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 8 (RTC Alarm) - (INT 0x70)\r
-IRQ8_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 9 - (INT 0x71)\r
-IRQ9_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 10 - (INT 0x72)\r
-IRQ10_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 11 - (INT 0x73)\r
-IRQ11_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 12 (PS/2 mouse) - (INT 0x74)\r
-IRQ12_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 13 (Floating point error) - (INT 0x75)\r
-IRQ13_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 14 (Secondary IDE) - (INT 0x76)\r
-IRQ14_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
-# IRQ 15 (Primary IDE) - (INT 0x77)\r
-IRQ15_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
-\r
- .fill 1 * 8, 1, 0\r
-\r
-IDT_END:\r
-\r
+++ /dev/null
- TITLE CpuInterrupt.asm: \r
-;------------------------------------------------------------------------------\r
-;*\r
-;* Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-;* This program and the accompanying materials \r
-;* are licensed and made available under the terms and conditions of the BSD License \r
-;* which accompanies this distribution. The full text of the license may be found at \r
-;* http://opensource.org/licenses/bsd-license.php \r
-;* \r
-;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-;* \r
-;* CpuInterrupt.asm\r
-;* \r
-;* Abstract:\r
-;*\r
-;------------------------------------------------------------------------------\r
-\r
-.686p\r
-.model flat, C\r
-\r
-PUBLIC SystemTimerHandler\r
-PUBLIC SystemExceptionHandler\r
-EXTERNDEF mExceptionCodeSize:DWORD\r
-\r
-.code\r
-.stack\r
-.MMX\r
-.XMM\r
-\r
-EXTERN TimerHandler: NEAR\r
-EXTERN ExceptionHandler: NEAR\r
-EXTERN mTimerVector: DWORD\r
-\r
-mExceptionCodeSize DD 9\r
-\r
-InitDescriptor PROC C\r
- lea eax, [GDT_BASE] ; EAX=PHYSICAL address of gdt\r
- mov dword ptr [gdtr + 2],eax ; Put address of gdt into the gdtr\r
- lgdt fword ptr [gdtr]\r
- lea eax, [IDT_BASE] ; EAX=PHYSICAL address of idt\r
- mov dword ptr [idtr + 2],eax ; Put address of idt into the idtr\r
- lidt fword ptr [idtr]\r
- ret\r
-InitDescriptor ENDP\r
-\r
-; VOID\r
-; InstallInterruptHandler (\r
-; UINTN Vector,\r
-; VOID (*Handler)(VOID)\r
-; )\r
-InstallInterruptHandler PROC C \\r
- Vector:DWORD, \\r
- Handler:DWORD\r
-\r
- push edi\r
- pushfd ; save eflags\r
- cli ; turn off interrupts\r
- sub esp, 6 ; open some space on the stack\r
- mov edi, esp\r
- sidt es:[edi] ; get fword address of IDT\r
- mov edi, es:[edi+2] ; move offset of IDT into EDI\r
- add esp, 6 ; correct stack\r
- mov eax, Vector ; Get vector number\r
- shl eax, 3 ; multiply by 8 to get offset\r
- add edi, eax ; add to IDT base to get entry\r
- mov eax, Handler ; load new address into IDT entry\r
- mov word ptr es:[edi], ax ; write bits 15..0 of offset\r
- shr eax, 16 ; use ax to copy 31..16 to descriptors\r
- mov word ptr es:[edi+6], ax ; write bits 31..16 of offset\r
- popfd ; restore flags (possible enabling interrupts)\r
- pop edi\r
- ret\r
-\r
-InstallInterruptHandler ENDP\r
-\r
-JmpCommonIdtEntry macro\r
- ; jmp commonIdtEntry - this must be hand coded to keep the assembler from\r
- ; using a 8 bit reletive jump when the entries are\r
- ; within 255 bytes of the common entry. This must\r
- ; be done to maintain the consistency of the size\r
- ; of entry points...\r
- db 0e9h ; jmp 16 bit reletive \r
- dd commonIdtEntry - $ - 4 ; offset to jump to\r
-endm\r
-\r
- align 02h\r
-SystemExceptionHandler PROC\r
-INT0:\r
- push 0h ; push error code place holder on the stack\r
- push 0h\r
- JmpCommonIdtEntry\r
-; db 0e9h ; jmp 16 bit reletive \r
-; dd commonIdtEntry - $ - 4 ; offset to jump to\r
- \r
-INT1:\r
- push 0h ; push error code place holder on the stack\r
- push 1h\r
- JmpCommonIdtEntry\r
- \r
-INT2:\r
- push 0h ; push error code place holder on the stack\r
- push 2h\r
- JmpCommonIdtEntry\r
- \r
-INT3:\r
- push 0h ; push error code place holder on the stack\r
- push 3h\r
- JmpCommonIdtEntry\r
- \r
-INT4:\r
- push 0h ; push error code place holder on the stack\r
- push 4h\r
- JmpCommonIdtEntry\r
- \r
-INT5:\r
- push 0h ; push error code place holder on the stack\r
- push 5h\r
- JmpCommonIdtEntry\r
- \r
-INT6:\r
- push 0h ; push error code place holder on the stack\r
- push 6h\r
- JmpCommonIdtEntry\r
- \r
-INT7:\r
- push 0h ; push error code place holder on the stack\r
- push 7h\r
- JmpCommonIdtEntry\r
- \r
-INT8:\r
-; Double fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 8h\r
- JmpCommonIdtEntry\r
- \r
-INT9:\r
- push 0h ; push error code place holder on the stack\r
- push 9h\r
- JmpCommonIdtEntry\r
- \r
-INT10:\r
-; Invalid TSS causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 10\r
- JmpCommonIdtEntry\r
- \r
-INT11:\r
-; Segment Not Present causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 11\r
- JmpCommonIdtEntry\r
- \r
-INT12:\r
-; Stack fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 12\r
- JmpCommonIdtEntry\r
- \r
-INT13:\r
-; GP fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 13\r
- JmpCommonIdtEntry\r
- \r
-INT14:\r
-; Page fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 14\r
- JmpCommonIdtEntry\r
- \r
-INT15:\r
- push 0h ; push error code place holder on the stack\r
- push 15\r
- JmpCommonIdtEntry\r
- \r
-INT16:\r
- push 0h ; push error code place holder on the stack\r
- push 16\r
- JmpCommonIdtEntry\r
- \r
-INT17:\r
-; Alignment check causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 17\r
- JmpCommonIdtEntry\r
- \r
-INT18:\r
- push 0h ; push error code place holder on the stack\r
- push 18\r
- JmpCommonIdtEntry\r
- \r
-INT19:\r
- push 0h ; push error code place holder on the stack\r
- push 19\r
- JmpCommonIdtEntry\r
-\r
-INTUnknown:\r
-REPEAT (32 - 20)\r
- push 0h ; push error code place holder on the stack\r
-; push xxh ; push vector number\r
- db 06ah\r
- db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number\r
- JmpCommonIdtEntry\r
-ENDM\r
-SystemExceptionHandler ENDP\r
-\r
-SystemTimerHandler PROC\r
- push 0\r
- push mTimerVector\r
- JmpCommonIdtEntry\r
-SystemTimerHandler ENDP\r
-\r
-commonIdtEntry:\r
-; +---------------------+\r
-; + EFlags +\r
-; +---------------------+\r
-; + CS +\r
-; +---------------------+\r
-; + EIP +\r
-; +---------------------+\r
-; + Error Code +\r
-; +---------------------+\r
-; + Vector Number +\r
-; +---------------------+\r
-; + EBP +\r
-; +---------------------+ <-- EBP\r
-\r
- cli\r
- push ebp\r
- mov ebp, esp\r
-\r
- ;\r
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- ; is 16-byte aligned\r
- ;\r
- and esp, 0fffffff0h\r
- sub esp, 12\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- push eax\r
- push ecx\r
- push edx\r
- push ebx\r
- lea ecx, [ebp + 6 * 4]\r
- push ecx ; ESP\r
- push dword ptr [ebp] ; EBP\r
- push esi\r
- push edi\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- mov eax, ss\r
- push eax\r
- movzx eax, word ptr [ebp + 4 * 4]\r
- push eax\r
- mov eax, ds\r
- push eax\r
- mov eax, es\r
- push eax\r
- mov eax, fs\r
- push eax\r
- mov eax, gs\r
- push eax\r
-\r
-;; UINT32 Eip;\r
- push dword ptr [ebp + 3 * 4]\r
-\r
-;; UINT32 Gdtr[2], Idtr[2];\r
- sub esp, 8\r
- sidt fword ptr [esp]\r
- sub esp, 8\r
- sgdt fword ptr [esp]\r
-\r
-;; UINT32 Ldtr, Tr;\r
- xor eax, eax\r
- str ax\r
- push eax\r
- sldt ax\r
- push eax\r
-\r
-;; UINT32 EFlags;\r
- push dword ptr [ebp + 5 * 4]\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- mov eax, cr4\r
- or eax, 208h\r
- mov cr4, eax\r
- push eax\r
- mov eax, cr3\r
- push eax\r
- mov eax, cr2\r
- push eax\r
- xor eax, eax\r
- push eax\r
- mov eax, cr0\r
- push eax\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov eax, dr7\r
- push eax\r
-;; clear Dr7 while executing debugger itself\r
- xor eax, eax\r
- mov dr7, eax\r
-\r
- mov eax, dr6\r
- push eax\r
-;; insure all status bits in dr6 are clear...\r
- xor eax, eax\r
- mov dr6, eax\r
-\r
- mov eax, dr3\r
- push eax\r
- mov eax, dr2\r
- push eax\r
- mov eax, dr1\r
- push eax\r
- mov eax, dr0\r
- push eax\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- sub esp, 512\r
- mov edi, esp\r
- db 0fh, 0aeh, 00000111y ;fxsave [edi]\r
-\r
-;; UINT32 ExceptionData;\r
- push dword ptr [ebp + 2 * 4]\r
-\r
-;; Prepare parameter and call\r
- mov edx, esp\r
- push edx\r
- mov eax, dword ptr [ebp + 1 * 4]\r
- push eax\r
- cmp eax, 32\r
- jb CallException\r
- call TimerHandler\r
- jmp ExceptionDone\r
-CallException:\r
- call ExceptionHandler\r
-ExceptionDone:\r
- add esp, 8\r
-\r
- cli\r
-;; UINT32 ExceptionData;\r
- add esp, 4\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- mov esi, esp\r
- db 0fh, 0aeh, 00001110y ; fxrstor [esi]\r
- add esp, 512\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop eax\r
- mov dr0, eax\r
- pop eax\r
- mov dr1, eax\r
- pop eax\r
- mov dr2, eax\r
- pop eax\r
- mov dr3, eax\r
-;; skip restore of dr6. We cleared dr6 during the context save.\r
- add esp, 4\r
- pop eax\r
- mov dr7, eax\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop eax\r
- mov cr0, eax\r
- add esp, 4 ; not for Cr1\r
- pop eax\r
- mov cr2, eax\r
- pop eax\r
- mov cr3, eax\r
- pop eax\r
- mov cr4, eax\r
-\r
-;; UINT32 EFlags;\r
- pop dword ptr [ebp + 5 * 4]\r
-\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add esp, 24\r
-\r
-;; UINT32 Eip;\r
- pop dword ptr [ebp + 3 * 4]\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; NOTE - modified segment registers could hang the debugger... We\r
-;; could attempt to insulate ourselves against this possibility,\r
-;; but that poses risks as well.\r
-;;\r
- pop gs\r
- pop fs\r
- pop es\r
- pop ds\r
- pop dword ptr [ebp + 4 * 4]\r
- pop ss\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pop edi\r
- pop esi\r
- add esp, 4 ; not for ebp\r
- add esp, 4 ; not for esp\r
- pop ebx\r
- pop edx\r
- pop ecx\r
- pop eax\r
-\r
- mov esp, ebp\r
- pop ebp\r
- add esp, 8\r
- iretd\r
-\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; data\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- align 02h\r
-\r
-gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit\r
- dd 0 ; (GDT base gets set above)\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; global descriptor table (GDT)\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- align 02h\r
-\r
-public GDT_BASE\r
-GDT_BASE:\r
-; null descriptor\r
-NULL_SEL equ $-GDT_BASE\r
- dw 0 ; limit 15:0\r
- dw 0 ; base 15:0\r
- db 0 ; base 23:16\r
- db 0 ; type\r
- db 0 ; limit 19:16, flags\r
- db 0 ; base 31:24\r
-\r
-; linear data segment descriptor\r
-LINEAR_SEL equ $-GDT_BASE\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 092h ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; linear code segment descriptor\r
-LINEAR_CODE_SEL equ $-GDT_BASE\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 09Ah ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; system data segment descriptor\r
-SYS_DATA_SEL equ $-GDT_BASE\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 092h ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; system code segment descriptor\r
-SYS_CODE_SEL equ $-GDT_BASE\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 09Ah ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; spare segment descriptor\r
-SPARE3_SEL equ $-GDT_BASE\r
- dw 0 ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 0 ; present, ring 0, data, expand-up, writable\r
- db 0 ; page-granular, 32-bit\r
- db 0\r
-\r
-; spare segment descriptor\r
-SPARE4_SEL equ $-GDT_BASE\r
- dw 0 ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 0 ; present, ring 0, data, expand-up, writable\r
- db 0 ; page-granular, 32-bit\r
- db 0\r
-\r
-; spare segment descriptor\r
-SPARE5_SEL equ $-GDT_BASE\r
- dw 0 ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 0 ; present, ring 0, data, expand-up, writable\r
- db 0 ; page-granular, 32-bit\r
- db 0\r
-\r
-GDT_END:\r
-\r
- align 02h\r
-\r
-\r
-\r
-idtr dw IDT_END - IDT_BASE - 1 ; IDT limit\r
- dd 0 ; (IDT base gets set above)\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; interrupt descriptor table (IDT)\r
-;\r
-; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
-; mappings. This implementation only uses the system timer and all other\r
-; IRQs will remain masked. The descriptors for vectors 33+ are provided\r
-; for convenience.\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-;idt_tag db "IDT",0 \r
- align 02h\r
-\r
-public IDT_BASE\r
-IDT_BASE:\r
-; divide by zero (INT 0)\r
-DIV_ZERO_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; debug exception (INT 1)\r
-DEBUG_EXCEPT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; NMI (INT 2)\r
-NMI_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; soft breakpoint (INT 3)\r
-BREAKPOINT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; overflow (INT 4)\r
-OVERFLOW_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; bounds check (INT 5)\r
-BOUNDS_CHECK_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; invalid opcode (INT 6)\r
-INVALID_OPCODE_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; device not available (INT 7)\r
-DEV_NOT_AVAIL_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; double fault (INT 8)\r
-DOUBLE_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; Coprocessor segment overrun - reserved (INT 9)\r
-RSVD_INTR_SEL1 equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; invalid TSS (INT 0ah)\r
-INVALID_TSS_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; segment not present (INT 0bh)\r
-SEG_NOT_PRESENT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; stack fault (INT 0ch)\r
-STACK_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; general protection (INT 0dh)\r
-GP_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; page fault (INT 0eh)\r
-PAGE_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; Intel reserved - do not use (INT 0fh)\r
-RSVD_INTR_SEL2 equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; floating point error (INT 10h)\r
-FLT_POINT_ERR_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; alignment check (INT 11h)\r
-ALIGNMENT_CHECK_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; machine check (INT 12h)\r
-MACHINE_CHECK_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; SIMD floating-point exception (INT 13h)\r
-SIMD_EXCEPTION_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-REPEAT (32 - 20)\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-ENDM\r
-\r
-; 72 unspecified descriptors\r
- db (72 * 8) dup(0)\r
- \r
-; IRQ 0 (System timer) - (INT 68h)\r
-IRQ0_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 1 (8042 Keyboard controller) - (INT 69h)\r
-IRQ1_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
-IRQ2_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 3 (COM 2) - (INT 6bh)\r
-IRQ3_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 4 (COM 1) - (INT 6ch)\r
-IRQ4_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 5 (LPT 2) - (INT 6dh)\r
-IRQ5_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 6 (Floppy controller) - (INT 6eh)\r
-IRQ6_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 7 (LPT 1) - (INT 6fh)\r
-IRQ7_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 8 (RTC Alarm) - (INT 70h)\r
-IRQ8_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 9 - (INT 71h)\r
-IRQ9_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 10 - (INT 72h)\r
-IRQ10_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 11 - (INT 73h)\r
-IRQ11_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 12 (PS/2 mouse) - (INT 74h)\r
-IRQ12_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 13 (Floating point error) - (INT 75h)\r
-IRQ13_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 14 (Secondary IDE) - (INT 76h)\r
-IRQ14_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
-; IRQ 15 (Primary IDE) - (INT 77h)\r
-IRQ15_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
-\r
- db (1 * 8) dup(0)\r
-\r
-IDT_END:\r
-\r
-END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#*\r
-#* Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-#* This program and the accompanying materials \r
-#* are licensed and made available under the terms and conditions of the BSD License \r
-#* which accompanies this distribution. The full text of the license may be found at \r
-#* http://opensource.org/licenses/bsd-license.php \r
-#* \r
-#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-#* \r
-#* CpuInterrupt.S\r
-#* \r
-#* Abstract:\r
-#*\r
-#------------------------------------------------------------------------------\r
-\r
-#PUBLIC SystemTimerHandler\r
-#PUBLIC SystemExceptionHandler\r
-#EXTERNDEF mExceptionCodeSize:DWORD\r
-\r
-#EXTERN TimerHandler: NEAR\r
-#EXTERN ExceptionHandler: NEAR\r
-#EXTERN mTimerVector: DWORD\r
-\r
- .data\r
- ASM_GLOBAL ASM_PFX(mExceptionCodeSize)\r
-ASM_PFX(mExceptionCodeSize): .long 9\r
-\r
- .text\r
- ASM_GLOBAL ASM_PFX(InitDescriptor)\r
-\r
-ASM_PFX(InitDescriptor):\r
- movq $GDT_BASE,%rax # EAX=PHYSICAL address of gdt\r
- movq %rax, gdtr + 2 # Put address of gdt into the gdtr\r
- lgdt gdtr\r
- movq $0x18, %rax\r
- movq %rax, %gs\r
- movq %rax, %fs\r
- movq $IDT_BASE,%rax # EAX=PHYSICAL address of idt\r
- movq %rax, idtr + 2 # Put address of idt into the idtr\r
- lidt idtr\r
- ret\r
-\r
-# VOID\r
-# InstallInterruptHandler (\r
-# UINTN Vector,\r
-# VOID (*Handler)(VOID)\r
-# )\r
- ASM_GLOBAL ASM_PFX(InstallInterruptHandler)\r
-ASM_PFX(InstallInterruptHandler):\r
-# Vector:DWORD @ 4(%esp)\r
-# Handler:DWORD @ 8(%esp)\r
- push %rbx\r
- pushfq # save eflags\r
- cli # turn off interrupts\r
- subq $0x10, %rsp # open some space on the stack\r
- movq %rsp, %rbx\r
- \r
- sidt (%rbx) # get fword address of IDT\r
- movq 2(%rbx), %rbx # move offset of IDT into RBX\r
- addq $0x10, %rsp # correct stack\r
- movq %rcx, %rax # Get vector number\r
- shlq $4, %rax # multiply by 16 to get offset\r
- addq %rax, %rbx # add to IDT base to get entry\r
- movq %rdx, %rax # load new address into IDT entry\r
- movw %ax, (%rbx) # write bits 15..0 of offset\r
- shrq $16, %rax # use ax to copy 31..16 to descriptors\r
- movw %ax, 6(%rbx) # write bits 31..16 of offset\r
- shrq $16, %rax # use eax to copy 63..32 to descriptors\r
- movl %eax, 8(%rbx) # write bits 63..32 of offset\r
- popfq # restore flags (possible enabling interrupts)\r
- pop %rbx\r
- ret\r
-\r
- .macro JmpCommonIdtEntry\r
- # jmp commonIdtEntry - this must be hand coded to keep the assembler from\r
- # using a 8 bit reletive jump when the entries are\r
- # within 255 bytes of the common entry. This must\r
- # be done to maintain the consistency of the size\r
- # of entry points...\r
- .byte 0xe9 # jmp 16 bit reletive \r
- .long commonIdtEntry - . - 4 # offset to jump to\r
- .endm\r
-\r
- .p2align 1\r
- ASM_GLOBAL ASM_PFX(SystemExceptionHandler)\r
-ASM_PFX(SystemExceptionHandler):\r
-INT0:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x0 \r
- JmpCommonIdtEntry\r
-# db 0e9h # jmp 16 bit reletive \r
-# dd commonIdtEntry - $ - 4 # offset to jump to\r
- \r
-INT1:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x1 \r
- JmpCommonIdtEntry\r
- \r
-INT2:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x2 \r
- JmpCommonIdtEntry\r
- \r
-INT3:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x3 \r
- JmpCommonIdtEntry\r
- \r
-INT4:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x4 \r
- JmpCommonIdtEntry\r
- \r
-INT5:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x5 \r
- JmpCommonIdtEntry\r
- \r
-INT6:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x6 \r
- JmpCommonIdtEntry\r
- \r
-INT7:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x7 \r
- JmpCommonIdtEntry\r
- \r
-INT8:\r
-# Double fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $0x8 \r
- JmpCommonIdtEntry\r
- \r
-INT9:\r
- push $0x0 # push error code place holder on the stack\r
- push $0x9 \r
- JmpCommonIdtEntry\r
- \r
-INT10:\r
-# Invalid TSS causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $10\r
- JmpCommonIdtEntry\r
- \r
-INT11:\r
-# Segment Not Present causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $11\r
- JmpCommonIdtEntry\r
- \r
-INT12:\r
-# Stack fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $12\r
- JmpCommonIdtEntry\r
- \r
-INT13:\r
-# GP fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $13\r
- JmpCommonIdtEntry\r
- \r
-INT14:\r
-# Page fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $14\r
- JmpCommonIdtEntry\r
- \r
-INT15:\r
- push $0x0 # push error code place holder on the stack\r
- push $15\r
- JmpCommonIdtEntry\r
- \r
-INT16:\r
- push $0x0 # push error code place holder on the stack\r
- push $16\r
- JmpCommonIdtEntry\r
- \r
-INT17:\r
-# Alignment check causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push $17\r
- JmpCommonIdtEntry\r
- \r
-INT18:\r
- push $0x0 # push error code place holder on the stack\r
- push $18\r
- JmpCommonIdtEntry\r
- \r
-INT19:\r
- push $0x0 # push error code place holder on the stack\r
- push $19\r
- JmpCommonIdtEntry\r
-\r
-INTUnknown:\r
- # The following segment repeats (32 - 20) times:\r
- # macro .rept isn't used here because Apple GAS compiler doesn't support it.\r
- # No. 1\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 2\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 3\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 4\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 5\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 6\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 7\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 8\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 9\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 10\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 11\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
- # No. 12\r
- push $0x0 # push error code place holder on the stack\r
-# push xxh # push vector number\r
- .byte 0x6a\r
- .byte ( . - INTUnknown - 3 ) / 9 + 20 # vector number\r
- JmpCommonIdtEntry\r
-\r
-\r
- ASM_GLOBAL ASM_PFX(SystemTimerHandler)\r
-ASM_PFX(SystemTimerHandler):\r
- push $0\r
- push $ASM_PFX(mTimerVector)\r
- JmpCommonIdtEntry\r
-\r
-commonIdtEntry:\r
-# +---------------------+\r
-# + EFlags +\r
-# +---------------------+\r
-# + CS +\r
-# +---------------------+\r
-# + EIP +\r
-# +---------------------+\r
-# + Error Code +\r
-# +---------------------+\r
-# + Vector Number +\r
-# +---------------------+\r
-# + EBP +\r
-# +---------------------+ <-- EBP\r
-\r
- cli\r
- push %rbp\r
- movq %rsp,%rbp\r
-\r
- #\r
- # Since here the stack pointer is 16-byte aligned, so\r
- # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
- # is 16-byte aligned\r
- # \r
-\r
-## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax#\r
-## UINT64 R8, R9, R10, R11, R12, R13, R14, R15#\r
- push %r15\r
- push %r14\r
- push %r13\r
- push %r12\r
- push %r11\r
- push %r10\r
- push %r9\r
- push %r8\r
- push %rax\r
- push %rcx\r
- push %rdx\r
- push %rbx\r
- push 6*8(%rbp)\r
- push (%rbp)\r
- push %rsi\r
- push %rdi\r
- \r
-## UINT64 Gs, Fs, Es, Ds, Cs, Ss# insure high 16 bits of each is zero\r
- movzx 7*8(%rbp), %rax\r
- push %rax # for ss\r
- movzx 4*8(%rbp), %rax\r
- push %rax # for cs\r
- movq %ds, %rax\r
- push %rax\r
- movq %es, %rax\r
- push %rax\r
- movq %fs, %rax\r
- push %rax\r
- movq %gs, %rax\r
- push %rax\r
-\r
-## UINT64 Rip#\r
- push 3*8(%rbp)\r
- \r
-## UINT64 Gdtr[2], Idtr[2]#\r
- subq $16, %rsp\r
- sidt (%rsp)\r
- subq $16, %rsp\r
- sgdt (%rsp)\r
- \r
-## UINT64 Ldtr, Tr#\r
- xorq %rax, %rax\r
- str %ax\r
- push %rax\r
- sldt %ax\r
- push %rax\r
- \r
-## UINT64 RFlags#\r
- push 5*8(%rbp)\r
-\r
-## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8#\r
- movq %cr8, %rax\r
- push %rax\r
- movq %cr4, %rax\r
- orq $0x208, %rax\r
- movq %rax, %cr4\r
- push %rax\r
- movq %cr3, %rax\r
- push %rax\r
- movq %cr2, %rax\r
- push %rax\r
- xorq %rax, %rax\r
- push %rax\r
- movq %cr0, %rax\r
- push %rax\r
-\r
-## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#\r
- movq %dr7, %rax\r
- push %rax\r
-\r
-## clear Dr7 while executing debugger itself\r
- xorq %rax, %rax\r
- movq %rax, %dr7\r
-\r
- movq %dr6, %rax\r
- push %rax\r
- \r
-## insure all status bits in dr6 are clear...\r
- xorq %rax, %rax\r
- movq %rax, %dr6\r
-\r
- movq %dr3, %rax\r
- push %rax\r
- movq %dr2, %rax\r
- push %rax\r
- movq %dr1, %rax\r
- push %rax\r
- movq %dr0, %rax\r
- push %rax\r
-\r
-\r
-## FX_SAVE_STATE_X64 FxSaveState#\r
- subq $512, %rsp\r
- movq %rsp, %rdi\r
- fxsave (%rdi)\r
-\r
-## UINT64 ExceptionData#\r
- push 2*8 (%rbp) \r
- \r
-## call into exception handler\r
-## Prepare parameter and call\r
- movq 1*8(%rbp), %rcx\r
- movq %rsp, %rdx\r
- #\r
- # Per X64 calling convention, allocate maximum parameter stack space\r
- # and make sure RSP is 16-byte aligned\r
- #\r
- subq $(4*8+8), %rsp\r
- cmpq $32, %rcx\r
- jb CallException\r
- call ASM_PFX(TimerHandler)\r
- jmp ExceptionDone\r
-CallException:\r
- call ASM_PFX(ExceptionHandler)\r
-ExceptionDone:\r
- addq $(4*8+8), %rsp\r
-\r
- cli\r
-## UINT64 ExceptionData#\r
- addq $8, %rsp\r
-\r
-## FX_SAVE_STATE_X64 FxSaveState#\r
- movq %rsp, %rsi\r
- fxrstor (%esi)\r
- addq $512, %rsp\r
-\r
-\r
-## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7#\r
- pop %rax\r
- movq %rax, %dr0\r
- pop %rax\r
- movq %rax, %dr1\r
- pop %rax\r
- movq %rax, %dr2\r
- pop %rax\r
- movq %rax, %dr3\r
-## skip restore of dr6. We cleared dr6 during the context save.\r
- addq $8, %rsp\r
- pop %rax\r
- movq %rax, %dr7\r
-\r
-## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8#\r
- pop %rax\r
- movq %rax, %cr0\r
- addq $8, %rsp # not for Cr1\r
- pop %rax\r
- movq %rax, %cr2\r
- pop %rax\r
- movq %rax, %cr3\r
- pop %rax\r
- movq %rax, %cr4\r
- pop %rax\r
- mov %rax, %cr8\r
- \r
-## UINT64 RFlags#\r
- pop 5*8(%rbp) \r
-\r
-## UINT64 Ldtr, Tr#\r
-## UINT64 Gdtr[2], Idtr[2]#\r
-## Best not let anyone mess with these particular registers...\r
- addq $48, %rsp\r
-\r
-## UINT64 Rip#\r
- pop 3*8(%rbp)\r
-\r
-## UINT64 Gs, Fs, Es, Ds, Cs, Ss#\r
- pop %rax\r
- # mov gs, rax # not for gs\r
- pop %rax\r
- # mov fs, rax # not for fs\r
- # (X64 will not use fs and gs, so we do not restore it)\r
- pop %rax\r
- movq %rax, %es\r
- pop %rax\r
- movq %rax, %ds\r
- pop 4*8(%rbp) # for cs\r
- pop 7*8(%rbp) # for ss\r
-\r
-## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax#\r
-## UINT64 R8, R9, R10, R11, R12, R13, R14, R15#\r
- pop %rdi\r
- pop %rsi\r
- addq $8, %rsp # not for rbp\r
- pop 6*8(%rbp) # for rsp\r
- pop %rbx\r
- pop %rdx\r
- pop %rcx\r
- pop %rax\r
- pop %r8\r
- pop %r9\r
- pop %r10\r
- pop %r11\r
- pop %r12\r
- pop %r13\r
- pop %r14\r
- pop %r15\r
-\r
- movq %rbp, %rsp\r
- pop %rbp\r
- addq $16, %rsp\r
- iretq\r
-\r
-\r
-##############################################################################\r
-# data\r
-##############################################################################\r
-\r
- .data\r
-\r
-gdtr: .short GDT_END - GDT_BASE - 1 # GDT limit\r
- .quad 0 # (GDT base gets set above)\r
-##############################################################################\r
-# global descriptor table (GDT)\r
-##############################################################################\r
-\r
- .p2align 4 # make GDT 16-byte align\r
-\r
-GDT_BASE:\r
-# null descriptor\r
-NULL_SEL = .-GDT_BASE # Selector [0x0]\r
- .short 0 # limit 15:0\r
- .short 0 # base 15:0\r
- .byte 0 # base 23:16\r
- .byte 0 # type\r
- .byte 0 # limit 19:16, flags\r
- .byte 0 # base 31:24\r
-\r
-# linear data segment descriptor\r
-LINEAR_SEL = .-GDT_BASE # Selector [0x8]\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x092 # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# linear code segment descriptor\r
-LINEAR_CODE_SEL = .-GDT_BASE # Selector [0x10]\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x09A # present, ring 0, code, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# system data segment descriptor\r
-SYS_DATA_SEL = .-GDT_BASE # Selector [0x18]\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x092 # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# system code segment descriptor\r
-SYS_CODE_SEL = .-GDT_BASE # Selector [0x20]\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x09A # present, ring 0, code, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# spare segment descriptor\r
-SPARE3_SEL = .-GDT_BASE # Selector [0x28]\r
- .short 0\r
- .short 0\r
- .byte 0\r
- .byte 0\r
- .byte 0\r
- .byte 0\r
-\r
-# system data segment descriptor\r
-SYS_DATA64_SEL = .-GDT_BASE # Selector [0x30]\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x092 # present, ring 0, data, expand-up, writable\r
- .byte 0x0CF # page-granular, 32-bit\r
- .byte 0\r
-\r
-# system code segment descriptor\r
-SYS_CODE64_SEL = .-GDT_BASE # Selector [0x38]\r
- .short 0x0FFFF # limit 0xFFFFF\r
- .short 0 # base 0\r
- .byte 0\r
- .byte 0x09A # present, ring 0, code, expand-up, writable\r
- .byte 0x0AF # page-granular, 64-bit\r
- .byte 0\r
-\r
-# spare segment descriptor\r
-SPARE4_SEL = .-GDT_BASE # Selector [0x40]\r
- .short 0\r
- .short 0\r
- .byte 0\r
- .byte 0\r
- .byte 0\r
- .byte 0\r
-\r
-GDT_END:\r
-\r
-idtr: .short IDT_END - IDT_BASE - 1 # IDT limit\r
- .quad 0 # (IDT base gets set above)\r
-##############################################################################\r
-# interrupt descriptor table (IDT)\r
-#\r
-# Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
-# mappings. This implementation only uses the system timer and all other\r
-# IRQs will remain masked. The descriptors for vectors 33+ are provided\r
-# for convenience.\r
-##############################################################################\r
-\r
- .p2align 3 # make IDT 8-byte align\r
-\r
-IDT_BASE:\r
-# divide by zero (INT 0)\r
-DIV_ZERO_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# debug exception (INT 1)\r
-DEBUG_EXCEPT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# NMI (INT 2)\r
-NMI_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# soft breakpoint (INT 3)\r
-BREAKPOINT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# overflow (INT 4)\r
-OVERFLOW_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# bounds check (INT 5)\r
-BOUNDS_CHECK_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# invalid opcode (INT 6)\r
-INVALID_OPCODE_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# device not available (INT 7)\r
-DEV_NOT_AVAIL_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# double fault (INT 8)\r
-DOUBLE_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# Coprocessor segment overrun - reserved (INT 9)\r
-RSVD_INTR_SEL1 = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# invalid TSS (INT 0ah)\r
-INVALID_TSS_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# segment not present (INT 0bh)\r
-SEG_NOT_PRESENT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# stack fault (INT 0ch)\r
-STACK_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# general protection (INT 0dh)\r
-GP_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# page fault (INT 0eh)\r
-PAGE_FAULT_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# Intel reserved - do not use (INT 0fh)\r
-RSVD_INTR_SEL2 = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# floating point error (INT 0x10)\r
-FLT_POINT_ERR_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# alignment check (INT 0x11)\r
-ALIGNMENT_CHECK_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# machine check (INT 0x12)\r
-MACHINE_CHECK_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# SIMD floating-point exception (INT 0x13)\r
-SIMD_EXCEPTION_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
- # The following segment repeats (32 - 20) times:\r
- # macro .rept isn't used here because Apple GAS compiler doesn't support it.\r
- # No. 1\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 2\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 3\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 4\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 5\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 6\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 7\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 8\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 9\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 10\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 11\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
- # No. 12\r
- .short 0 # offset 15:0\r
- .short SYS_CODE_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-\r
-# 72 unspecified descriptors\r
- .fill 72 * 16, 1, 0\r
- \r
-# IRQ 0 (System timer) - (INT 0x68)\r
-IRQ0_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # 0 for reserved\r
-\r
-# IRQ 1 (8042 Keyboard controller) - (INT 0x69)\r
-IRQ1_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
-IRQ2_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 3 (COM 2) - (INT 6bh)\r
-IRQ3_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 4 (COM 1) - (INT 6ch)\r
-IRQ4_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 5 (LPT 2) - (INT 6dh)\r
-IRQ5_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 6 (Floppy controller) - (INT 6eh)\r
-IRQ6_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 7 (LPT 1) - (INT 6fh)\r
-IRQ7_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 8 (RTC Alarm) - (INT 0x70)\r
-IRQ8_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 9 - (INT 0x71)\r
-IRQ9_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 10 - (INT 0x72)\r
-IRQ10_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 11 - (INT 0x73)\r
-IRQ11_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 12 (PS/2 mouse) - (INT 0x74)\r
-IRQ12_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 13 (Floating point error) - (INT 0x75)\r
-IRQ13_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 14 (Secondary IDE) - (INT 0x76)\r
-IRQ14_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
-# IRQ 15 (Primary IDE) - (INT 0x77)\r
-IRQ15_SEL = .-IDT_BASE\r
- .short 0 # offset 15:0\r
- .short SYS_CODE64_SEL # selector 15:0\r
- .byte 0 # 0 for interrupt gate\r
- .byte 0x0e | 0x80 # (10001110)type = 386 interrupt gate, present\r
- .short 0 # offset 31:16\r
- .long 0 # offset 63:32\r
- .long 0 # for reserved\r
-\r
- .fill 16, 1, 0\r
-\r
-IDT_END:\r
-\r
+++ /dev/null
- TITLE CpuInterrupt.asm: \r
-;------------------------------------------------------------------------------\r
-;*\r
-;* Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-;* This program and the accompanying materials \r
-;* are licensed and made available under the terms and conditions of the BSD License \r
-;* which accompanies this distribution. The full text of the license may be found at \r
-;* http://opensource.org/licenses/bsd-license.php \r
-;* \r
-;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-;* \r
-;* CpuInterrupt.asm\r
-;* \r
-;* Abstract:\r
-;*\r
-;------------------------------------------------------------------------------\r
-\r
-EXTERNDEF mExceptionCodeSize:DWORD\r
-\r
-.code\r
-\r
-EXTERN TimerHandler: FAR\r
-EXTERN ExceptionHandler: NEAR\r
-EXTERN mTimerVector: QWORD\r
-\r
-mExceptionCodeSize DD 9\r
-\r
-InitDescriptor PROC\r
- lea rax, [GDT_BASE] ; RAX=PHYSICAL address of gdt\r
- mov qword ptr [gdtr + 2], rax ; Put address of gdt into the gdtr\r
- lgdt fword ptr [gdtr]\r
- mov rax, 18h\r
- mov gs, rax\r
- mov fs, rax\r
- lea rax, [IDT_BASE] ; RAX=PHYSICAL address of idt\r
- mov qword ptr [idtr + 2], rax ; Put address of idt into the idtr\r
- lidt fword ptr [idtr]\r
- ret\r
-InitDescriptor ENDP\r
-\r
-; VOID\r
-; InstallInterruptHandler (\r
-; UINTN Vector, // rcx\r
-; void (*Handler)(void) // rdx\r
-; )\r
-InstallInterruptHandler PROC \r
- push rbx\r
- pushfq ; save eflags\r
- cli ; turn off interrupts\r
- sub rsp, 10h ; open some space on the stack\r
- mov rbx, rsp\r
- sidt [rbx] ; get fword address of IDT\r
- mov rbx, [rbx+2] ; move offset of IDT into RBX\r
- add rsp, 10h ; correct stack\r
- mov rax, rcx ; Get vector number\r
- shl rax, 4 ; multiply by 16 to get offset\r
- add rbx, rax ; add to IDT base to get entry\r
- mov rax, rdx ; load new address into IDT entry\r
- mov word ptr [rbx], ax ; write bits 15..0 of offset\r
- shr rax, 16 ; use ax to copy 31..16 to descriptors\r
- mov word ptr [rbx+6], ax ; write bits 31..16 of offset\r
- shr rax, 16 ; use eax to copy 63..32 to descriptors\r
- mov dword ptr [rbx+8], eax ; write bits 63..32 of offset\r
- popfq ; restore flags (possible enabling interrupts)\r
- pop rbx\r
- ret\r
-\r
-InstallInterruptHandler ENDP\r
-\r
-JmpCommonIdtEntry macro\r
- ; jmp commonIdtEntry - this must be hand coded to keep the assembler from\r
- ; using a 8 bit reletive jump when the entries are\r
- ; within 255 bytes of the common entry. This must\r
- ; be done to maintain the consistency of the size\r
- ; of entry points...\r
- db 0e9h ; jmp 16 bit reletive \r
- dd commonIdtEntry - $ - 4 ; offset to jump to\r
-endm\r
-\r
- align 02h\r
-SystemExceptionHandler PROC\r
-INT0:\r
- push 0h ; push error code place holder on the stack\r
- push 0h\r
- JmpCommonIdtEntry\r
-; db 0e9h ; jmp 16 bit reletive \r
-; dd commonIdtEntry - $ - 4 ; offset to jump to\r
- \r
-INT1:\r
- push 0h ; push error code place holder on the stack\r
- push 1h\r
- JmpCommonIdtEntry\r
- \r
-INT2:\r
- push 0h ; push error code place holder on the stack\r
- push 2h\r
- JmpCommonIdtEntry\r
- \r
-INT3:\r
- push 0h ; push error code place holder on the stack\r
- push 3h\r
- JmpCommonIdtEntry\r
- \r
-INT4:\r
- push 0h ; push error code place holder on the stack\r
- push 4h\r
- JmpCommonIdtEntry\r
- \r
-INT5:\r
- push 0h ; push error code place holder on the stack\r
- push 5h\r
- JmpCommonIdtEntry\r
- \r
-INT6:\r
- push 0h ; push error code place holder on the stack\r
- push 6h\r
- JmpCommonIdtEntry\r
- \r
-INT7:\r
- push 0h ; push error code place holder on the stack\r
- push 7h\r
- JmpCommonIdtEntry\r
- \r
-INT8:\r
-; Double fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 8h\r
- JmpCommonIdtEntry\r
- \r
-INT9:\r
- push 0h ; push error code place holder on the stack\r
- push 9h\r
- JmpCommonIdtEntry\r
- \r
-INT10:\r
-; Invalid TSS causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 10\r
- JmpCommonIdtEntry\r
- \r
-INT11:\r
-; Segment Not Present causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 11\r
- JmpCommonIdtEntry\r
- \r
-INT12:\r
-; Stack fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 12\r
- JmpCommonIdtEntry\r
- \r
-INT13:\r
-; GP fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 13\r
- JmpCommonIdtEntry\r
- \r
-INT14:\r
-; Page fault causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 14\r
- JmpCommonIdtEntry\r
- \r
-INT15:\r
- push 0h ; push error code place holder on the stack\r
- push 15\r
- JmpCommonIdtEntry\r
- \r
-INT16:\r
- push 0h ; push error code place holder on the stack\r
- push 16\r
- JmpCommonIdtEntry\r
- \r
-INT17:\r
-; Alignment check causes an error code to be pushed so no phony push necessary\r
- nop\r
- nop\r
- push 17\r
- JmpCommonIdtEntry\r
- \r
-INT18:\r
- push 0h ; push error code place holder on the stack\r
- push 18\r
- JmpCommonIdtEntry\r
- \r
-INT19:\r
- push 0h ; push error code place holder on the stack\r
- push 19\r
- JmpCommonIdtEntry\r
-\r
-INTUnknown:\r
-REPEAT (32 - 20)\r
- push 0h ; push error code place holder on the stack\r
-; push xxh ; push vector number\r
- db 06ah\r
- db ( $ - INTUnknown - 3 ) / 9 + 20 ; vector number\r
- JmpCommonIdtEntry\r
-ENDM\r
-SystemExceptionHandler ENDP\r
-\r
-SystemTimerHandler PROC\r
- push 0\r
- push mTimerVector\r
- JmpCommonIdtEntry\r
-SystemTimerHandler ENDP\r
-\r
-commonIdtEntry:\r
-; +---------------------+ <-- 16-byte aligned ensured by processor\r
-; + Old SS +\r
-; +---------------------+\r
-; + Old RSP +\r
-; +---------------------+\r
-; + RFlags +\r
-; +---------------------+\r
-; + CS +\r
-; +---------------------+\r
-; + RIP +\r
-; +---------------------+\r
-; + Error Code +\r
-; +---------------------+\r
-; + Vector Number +\r
-; +---------------------+\r
-; + RBP +\r
-; +---------------------+ <-- RBP, 16-byte aligned\r
-\r
- cli\r
- push rbp\r
- mov rbp, rsp\r
-\r
- ;\r
- ; Since here the stack pointer is 16-byte aligned, so\r
- ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
- ; is 16-byte aligned\r
- ; \r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- push r15\r
- push r14\r
- push r13\r
- push r12\r
- push r11\r
- push r10\r
- push r9\r
- push r8\r
- push rax\r
- push rcx\r
- push rdx\r
- push rbx\r
- push qword ptr [rbp + 6 * 8] ; RSP\r
- push qword ptr [rbp] ; RBP\r
- push rsi\r
- push rdi\r
-\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- movzx rax, word ptr [rbp + 7 * 8]\r
- push rax ; for ss\r
- movzx rax, word ptr [rbp + 4 * 8]\r
- push rax ; for cs\r
- mov rax, ds\r
- push rax\r
- mov rax, es\r
- push rax\r
- mov rax, fs\r
- push rax\r
- mov rax, gs\r
- push rax\r
-\r
-;; UINT64 Rip;\r
- push qword ptr [rbp + 3 * 8]\r
-\r
-;; UINT64 Gdtr[2], Idtr[2];\r
- sub rsp, 16\r
- sidt fword ptr [rsp]\r
- sub rsp, 16\r
- sgdt fword ptr [rsp]\r
-\r
-;; UINT64 Ldtr, Tr;\r
- xor rax, rax\r
- str ax\r
- push rax\r
- sldt ax\r
- push rax\r
-\r
-;; UINT64 RFlags;\r
- push qword ptr [rbp + 5 * 8]\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- mov rax, cr8\r
- push rax\r
- mov rax, cr4\r
- or rax, 208h\r
- mov cr4, rax\r
- push rax\r
- mov rax, cr3\r
- push rax\r
- mov rax, cr2\r
- push rax\r
- xor rax, rax\r
- push rax\r
- mov rax, cr0\r
- push rax\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov rax, dr7\r
- push rax\r
-;; clear Dr7 while executing debugger itself\r
- xor rax, rax\r
- mov dr7, rax\r
-\r
- mov rax, dr6\r
- push rax\r
-;; insure all status bits in dr6 are clear...\r
- xor rax, rax\r
- mov dr6, rax\r
-\r
- mov rax, dr3\r
- push rax\r
- mov rax, dr2\r
- push rax\r
- mov rax, dr1\r
- push rax\r
- mov rax, dr0\r
- push rax\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- sub rsp, 512\r
- mov rdi, rsp\r
- db 0fh, 0aeh, 00000111y ;fxsave [rdi]\r
-\r
-;; UINT32 ExceptionData;\r
- push qword ptr [rbp + 2 * 8]\r
-\r
-;; call into exception handler\r
-;; Prepare parameter and call\r
- mov rcx, qword ptr [rbp + 1 * 8]\r
- mov rdx, rsp\r
- ;\r
- ; Per X64 calling convention, allocate maximum parameter stack space\r
- ; and make sure RSP is 16-byte aligned\r
- ;\r
- sub rsp, 4 * 8 + 8\r
- cmp rcx, 32\r
- jb CallException\r
- call TimerHandler\r
- jmp ExceptionDone\r
-CallException:\r
- call ExceptionHandler\r
-ExceptionDone:\r
- add rsp, 4 * 8 + 8\r
-\r
- cli\r
-;; UINT64 ExceptionData;\r
- add rsp, 8\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- mov rsi, rsp\r
- db 0fh, 0aeh, 00001110y ; fxrstor [rsi]\r
- add rsp, 512\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop rax\r
- mov dr0, rax\r
- pop rax\r
- mov dr1, rax\r
- pop rax\r
- mov dr2, rax\r
- pop rax\r
- mov dr3, rax\r
-;; skip restore of dr6. We cleared dr6 during the context save.\r
- add rsp, 8\r
- pop rax\r
- mov dr7, rax\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- pop rax\r
- mov cr0, rax\r
- add rsp, 8 ; not for Cr1\r
- pop rax\r
- mov cr2, rax\r
- pop rax\r
- mov cr3, rax\r
- pop rax\r
- mov cr4, rax\r
- pop rax\r
- mov cr8, rax\r
-\r
-;; UINT64 RFlags;\r
- pop qword ptr [rbp + 5 * 8]\r
-\r
-;; UINT64 Ldtr, Tr;\r
-;; UINT64 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add rsp, 48\r
-\r
-;; UINT64 Rip;\r
- pop qword ptr [rbp + 3 * 8]\r
-\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
- pop rax\r
- ; mov gs, rax ; not for gs\r
- pop rax\r
- ; mov fs, rax ; not for fs\r
- ; (X64 will not use fs and gs, so we do not restore it)\r
- pop rax\r
- mov es, rax\r
- pop rax\r
- mov ds, rax\r
- pop qword ptr [rbp + 4 * 8] ; for cs\r
- pop qword ptr [rbp + 7 * 8] ; for ss\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pop rdi\r
- pop rsi\r
- add rsp, 8 ; not for rbp\r
- pop qword ptr [rbp + 6 * 8] ; for rsp\r
- pop rbx\r
- pop rdx\r
- pop rcx\r
- pop rax\r
- pop r8\r
- pop r9\r
- pop r10\r
- pop r11\r
- pop r12\r
- pop r13\r
- pop r14\r
- pop r15\r
-\r
- mov rsp, rbp\r
- pop rbp\r
- add rsp, 16\r
- iretq\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; data\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
-\r
-gdtr dw GDT_END - GDT_BASE - 1 ; GDT limit\r
- dq 0 ; (GDT base gets set above)\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; global descriptor table (GDT)\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- align 010h ; make GDT 16-byte align\r
-\r
-public GDT_BASE\r
-GDT_BASE:\r
-; null descriptor\r
-NULL_SEL equ $-GDT_BASE ; Selector [0x0]\r
- dw 0 ; limit 15:0\r
- dw 0 ; base 15:0\r
- db 0 ; base 23:16\r
- db 0 ; type\r
- db 0 ; limit 19:16, flags\r
- db 0 ; base 31:24\r
-\r
-; linear data segment descriptor\r
-LINEAR_SEL equ $-GDT_BASE ; Selector [0x8]\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 092h ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; linear code segment descriptor\r
-LINEAR_CODE_SEL equ $-GDT_BASE ; Selector [0x10]\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 09Ah ; present, ring 0, code, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; system data segment descriptor\r
-SYS_DATA_SEL equ $-GDT_BASE ; Selector [0x18]\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 092h ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; system code segment descriptor\r
-SYS_CODE_SEL equ $-GDT_BASE ; Selector [0x20]\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 09Ah ; present, ring 0, code, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; spare segment descriptor\r
-SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]\r
- dw 0\r
- dw 0\r
- db 0\r
- db 0\r
- db 0\r
- db 0\r
-\r
-; system data segment descriptor\r
-SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 092h ; present, ring 0, data, expand-up, writable\r
- db 0CFh ; page-granular, 32-bit\r
- db 0\r
-\r
-; system code segment descriptor\r
-SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]\r
- dw 0FFFFh ; limit 0xFFFFF\r
- dw 0 ; base 0\r
- db 0\r
- db 09Ah ; present, ring 0, code, expand-up, writable\r
- db 0AFh ; page-granular, 64-bit\r
- db 0\r
-\r
-; spare segment descriptor\r
-SPARE4_SEL equ $-GDT_BASE ; Selector [0x40]\r
- dw 0\r
- dw 0\r
- db 0\r
- db 0\r
- db 0\r
- db 0\r
-\r
-GDT_END:\r
-\r
-idtr dw IDT_END - IDT_BASE - 1 ; IDT limit\r
- dq 0 ; (IDT base gets set above)\r
-\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-; interrupt descriptor table (IDT)\r
-;\r
-; Note: The hardware IRQ's specified in this table are the normal PC/AT IRQ\r
-; mappings. This implementation only uses the system timer and all other\r
-; IRQs will remain masked. The descriptors for vectors 33+ are provided\r
-; for convenience.\r
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\r
-\r
- align 08h ; make IDT 8-byte align\r
-\r
-public IDT_BASE\r
-IDT_BASE:\r
-; divide by zero (INT 0)\r
-DIV_ZERO_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; debug exception (INT 1)\r
-DEBUG_EXCEPT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; NMI (INT 2)\r
-NMI_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; soft breakpoint (INT 3)\r
-BREAKPOINT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; overflow (INT 4)\r
-OVERFLOW_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; bounds check (INT 5)\r
-BOUNDS_CHECK_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; invalid opcode (INT 6)\r
-INVALID_OPCODE_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; device not available (INT 7)\r
-DEV_NOT_AVAIL_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; double fault (INT 8)\r
-DOUBLE_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; Coprocessor segment overrun - reserved (INT 9)\r
-RSVD_INTR_SEL1 equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; invalid TSS (INT 0ah)\r
-INVALID_TSS_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; segment not present (INT 0bh)\r
-SEG_NOT_PRESENT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; stack fault (INT 0ch)\r
-STACK_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; general protection (INT 0dh)\r
-GP_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; page fault (INT 0eh)\r
-PAGE_FAULT_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; Intel reserved - do not use (INT 0fh)\r
-RSVD_INTR_SEL2 equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; floating point error (INT 10h)\r
-FLT_POINT_ERR_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; alignment check (INT 11h)\r
-ALIGNMENT_CHECK_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; machine check (INT 12h)\r
-MACHINE_CHECK_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; SIMD floating-point exception (INT 13h)\r
-SIMD_EXCEPTION_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-REPEAT (32 - 20) \r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-ENDM\r
-\r
-; 72 unspecified descriptors\r
- db (72 * 16) dup(0)\r
- \r
-; IRQ 0 (System timer) - (INT 68h)\r
-IRQ0_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 1 (8042 Keyboard controller) - (INT 69h)\r
-IRQ1_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; Reserved - IRQ 2 redirect (IRQ 2) - DO NOT USE!!! - (INT 6ah)\r
-IRQ2_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 3 (COM 2) - (INT 6bh)\r
-IRQ3_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 4 (COM 1) - (INT 6ch)\r
-IRQ4_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 5 (LPT 2) - (INT 6dh)\r
-IRQ5_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 6 (Floppy controller) - (INT 6eh)\r
-IRQ6_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 7 (LPT 1) - (INT 6fh)\r
-IRQ7_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 8 (RTC Alarm) - (INT 70h)\r
-IRQ8_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 9 - (INT 71h)\r
-IRQ9_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 10 - (INT 72h)\r
-IRQ10_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 11 - (INT 73h)\r
-IRQ11_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 12 (PS/2 mouse) - (INT 74h)\r
-IRQ12_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 13 (Floating point error) - (INT 75h)\r
-IRQ13_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 14 (Secondary IDE) - (INT 76h)\r
-IRQ14_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
-; IRQ 15 (Primary IDE) - (INT 77h)\r
-IRQ15_SEL equ $-IDT_BASE\r
- dw 0 ; offset 15:0\r
- dw SYS_CODE64_SEL ; selector 15:0\r
- db 0 ; 0 for interrupt gate\r
- db 0eh OR 80h ; (10001110)type = 386 interrupt gate, present\r
- dw 0 ; offset 31:16\r
- dd 0 ; offset 63:32\r
- dd 0 ; 0 for reserved\r
-\r
- db (1 * 16) dup(0)\r
-\r
-IDT_END:\r
-\r
-\r
-END\r
INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf\r
INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf\r
-INF DuetPkg/CpuDxe/Cpu.inf\r
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf\r
\r
INF PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf\r
INF DuetPkg/AcpiResetDxe/Reset.inf\r
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf\r
SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf\r
+ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf\r
\r
#\r
# To save size, use NULL library for DebugLib and ReportStatusCodeLib.\r
}\r
MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf\r
- DuetPkg/CpuDxe/Cpu.inf\r
+ UefiCpuPkg/CpuDxe/CpuDxe.inf\r
PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf\r
DuetPkg/AcpiResetDxe/Reset.inf\r
DuetPkg/LegacyMetronome/Metronome.inf\r
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf\r
SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf\r
+ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf\r
\r
#\r
# To save size, use NULL library for DebugLib and ReportStatusCodeLib.\r
}\r
MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf\r
- DuetPkg/CpuDxe/Cpu.inf\r
+ UefiCpuPkg/CpuDxe/CpuDxe.inf\r
PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf\r
DuetPkg/AcpiResetDxe/Reset.inf\r
DuetPkg/LegacyMetronome/Metronome.inf\r