From a33f3dd1783f7d8d824ef858b18573f9f0ccdd78 Mon Sep 17 00:00:00 2001 From: bbahnsen Date: Fri, 14 Jul 2006 05:33:55 +0000 Subject: Fixes for Linux builds. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@995 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/DebugSupport/Dxe/Ia32/AsmFuncs.S | 270 ++++++++++ .../Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm | 547 +++++++++++++++++++++ .../DebugSupport/Dxe/Ia32/plDebugSupport.c | 440 +++++++++++++++++ .../DebugSupport/Dxe/Ia32/plDebugSupport.h | 312 ++++++++++++ .../Universal/DebugSupport/Dxe/ia32/AsmFuncs.S | 270 ---------- .../Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm | 547 --------------------- .../DebugSupport/Dxe/ia32/plDebugSupport.c | 440 ----------------- .../DebugSupport/Dxe/ia32/plDebugSupport.h | 312 ------------ 8 files changed, 1569 insertions(+), 1569 deletions(-) create mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.S create mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm create mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.c create mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.h delete mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.S delete mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm delete mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c delete mode 100644 EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h (limited to 'EdkModulePkg') diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.S b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.S new file mode 100644 index 0000000..131464a --- /dev/null +++ b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.S @@ -0,0 +1,270 @@ +#****************************************************************************** +#* +#* Copyright (c) 2006, Intel Corporation +#* All rights reserved. This program and the accompanying materials +#* are licensed and made available under the terms and conditions of the BSD License +#* which accompanies this distribution. The full text of the license may be found at +#* http://opensource.org/licenses/bsd-license.php +#* +#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +#* +#****************************************************************************** + +.global _OrigVector +.global _InterruptEntryStub +.global _StubSize +.global _CommonIdtEntry +.global _FxStorSupport + +_AppEsp: .long 0x11111111 # ? +_DebugEsp: .long 0x22222222 # ? +_ExtraPush: .long 0x33333333 # ? +_ExceptData: .long 0x44444444 # ? +_Eflags: .long 0x55555555 # ? +_OrigVector: .long 0x66666666 # ? +_StubSize: .long _InterruptEntryStubEnd - _InterruptEntryStub + +.global _FxStorSupport +_FxStorSupport: + push %ebx + mov $0x1,%eax + cpuid + mov %edx,%eax + and $0x1000000,%eax + shr $0x18,%eax + pop %ebx + ret + +.global _GetIdtr +_GetIdtr: + push %ebp + mov %esp,%ebp + add $0xfffffff8,%esp + sidtl 0xfffffffa(%ebp) + mov 0xfffffffc(%ebp),%eax + leave + ret + +.global _WriteInterruptFlag +_WriteInterruptFlag: + push %ebp + mov %esp,%ebp + pushf + pop %eax + and $0x200,%eax + shr $0x9,%eax + mov 0x8(%ebp),%ecx + or %ecx,%ecx + jne _WriteInterruptFlag+0x17 + cli + jmp _WriteInterruptFlag+0x18 + sti + leave + ret + +.global _Vect2Desc +_Vect2Desc: + push %ebp + mov %esp,%ebp + mov 0xc(%ebp),%eax + mov 0x8(%ebp),%ecx + mov %ax,(%ecx) + movw $0x20,0x2(%ecx) + movw $0x8e00,0x4(%ecx) + shr $0x10,%eax + mov %ax,0x6(%ecx) + leave + ret + +.global _InterruptEntryStub +_InterruptEntryStub: + mov %esp,0x0 + mov $0x0,%esp + push $0x0 + jmp _CommonIdtEntry +.global _InterruptEntryStubEnd +_InterruptEntryStubEnd: + +.global _CommonIdtEntry +_CommonIdtEntry: + pusha + pushf + pop %eax + mov %eax,0x0 + cmpl $0x8,0x0 + jne _CommonIdtEntry+0x20 + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + cmpl $0xa,0x0 + jne _CommonIdtEntry+0x35 + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + cmpl $0xb,0x0 + jne _CommonIdtEntry+0x4a + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + cmpl $0xc,0x0 + jne _CommonIdtEntry+0x5f + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + cmpl $0xd,0x0 + jne _CommonIdtEntry+0x74 + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + cmpl $0xe,0x0 + jne _CommonIdtEntry+0x89 + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + cmpl $0x11,0x0 + jne _CommonIdtEntry+0x9e + movl $0x1,0x0 + jmp _CommonIdtEntry+0xa8 + movl $0x0,0x0 + cmpl $0x1,0x0 + jne _CommonIdtEntry+0xc8 + mov 0x0,%eax + mov (%eax),%ebx + mov %ebx,0x0 + add $0x4,%eax + mov %eax,0x0 + jmp _CommonIdtEntry+0xd2 + movl $0x0,0x0 + mov 0xc(%esp),%eax + mov %eax,0x0 + mov 0x0,%eax + add $0xc,%eax + mov %eax,0xc(%esp) + mov %ss,%eax + push %eax + mov 0x0,%eax + movzwl 0x4(%eax),%eax + push %eax + mov %ds,%eax + push %eax + mov %es,%eax + push %eax + mov %fs,%eax + push %eax + mov %gs,%eax + push %eax + mov 0x0,%eax + pushl (%eax) + push $0x0 + push $0x0 + sidtl (%esp) + push $0x0 + push $0x0 + sgdtl (%esp) + xor %eax,%eax + str %eax + push %eax + sldt %eax + push %eax + mov 0x0,%eax + pushl 0x8(%eax) + mov %cr4,%eax + or $0x208,%eax + mov %eax,%cr4 + push %eax + mov %cr3,%eax + push %eax + mov %cr2,%eax + push %eax + push $0x0 + mov %cr0,%eax + push %eax + mov %db7,%eax + push %eax + xor %eax,%eax + mov %eax,%db7 + mov %db6,%eax + push %eax + xor %eax,%eax + mov %eax,%db6 + mov %db3,%eax + push %eax + mov %db2,%eax + push %eax + mov %db1,%eax + push %eax + mov %db0,%eax + push %eax + sub $0x200,%esp + mov %esp,%edi + fxsave (%edi) + mov 0x0,%eax + push %eax + mov %esp,%eax + push %eax + mov 0x0,%eax + push %eax + call _CommonIdtEntry+0x184 + add $0x8,%esp + add $0x4,%esp + mov %esp,%esi + fxrstor (%esi) + add $0x200,%esp + pop %eax + mov %eax,%db0 + pop %eax + mov %eax,%db1 + pop %eax + mov %eax,%db2 + pop %eax + mov %eax,%db3 + add $0x4,%esp + pop %eax + mov %eax,%db7 + pop %eax + mov %eax,%cr0 + add $0x4,%esp + pop %eax + mov %eax,%cr2 + pop %eax + mov %eax,%cr3 + pop %eax + mov %eax,%cr4 + mov 0x0,%eax + popl 0x8(%eax) + add $0x18,%esp + popl (%eax) + pop %gs + pop %fs + pop %es + pop %ds + popl 0x4(%eax) + pop %ss + mov 0xc(%esp),%ebx + mov 0x0,%eax + add $0xc,%eax + cmp %eax,%ebx + je _CommonIdtEntry+0x202 + mov 0x0,%eax + mov (%eax),%ecx + mov %ecx,(%ebx) + mov 0x4(%eax),%ecx + mov %ecx,0x4(%ebx) + mov 0x8(%eax),%ecx + mov %ecx,0x8(%ebx) + mov %ebx,%eax + mov %eax,0x0 + mov 0x0,%eax + mov %eax,0xc(%esp) + cmpl $0x68,0x0 + jne PhonyIretd+0xd + mov 0x0,%eax + mov 0x8(%eax),%ebx + and $0xfffffcff,%ebx + push %ebx + push %cs + push $0x0 + iret + +PhonyIretd: + popa + mov 0x0,%esp + jmp *0x0 + popa + mov 0x0,%esp + iret diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm new file mode 100644 index 0000000..89c9f83 --- /dev/null +++ b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm @@ -0,0 +1,547 @@ +;****************************************************************************** +;* +;* Copyright (c) 2006, Intel Corporation +;* All rights reserved. This program and the accompanying materials +;* are licensed and made available under the terms and conditions of the BSD License +;* which accompanies this distribution. The full text of the license may be found at +;* http://opensource.org/licenses/bsd-license.php +;* +;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;* +;****************************************************************************** + +.586p +.MODEL FLAT, C + +EXCPT32_DIVIDE_ERROR EQU 0 +EXCPT32_DEBUG EQU 1 +EXCPT32_NMI EQU 2 +EXCPT32_BREAKPOINT EQU 3 +EXCPT32_OVERFLOW EQU 4 +EXCPT32_BOUND EQU 5 +EXCPT32_INVALID_OPCODE EQU 6 +EXCPT32_DOUBLE_FAULT EQU 8 +EXCPT32_INVALID_TSS EQU 10 +EXCPT32_SEG_NOT_PRESENT EQU 11 +EXCPT32_STACK_FAULT EQU 12 +EXCPT32_GP_FAULT EQU 13 +EXCPT32_PAGE_FAULT EQU 14 +EXCPT32_FP_ERROR EQU 16 +EXCPT32_ALIGNMENT_CHECK EQU 17 +EXCPT32_MACHINE_CHECK EQU 18 +EXCPT32_SIMD EQU 19 + +FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags + +;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87, +;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver +;; MUST check the CPUID feature flags to see that these instructions are available +;; and fail to init if they are not. + +;; fxstor [edi] +FXSTOR_EDI MACRO + db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi] +ENDM + +;; fxrstor [esi] +FXRSTOR_ESI MACRO + db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi] +ENDM +.DATA + +public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport + +StubSize dd InterruptEntryStubEnd - InterruptEntryStub +AppEsp dd 11111111h ; ? +DebugEsp dd 22222222h ; ? +ExtraPush dd 33333333h ; ? +ExceptData dd 44444444h ; ? +Eflags dd 55555555h ; ? +OrigVector dd 66666666h ; ? + +;; The declarations below define the memory region that will be used for the debug stack. +;; The context record will be built by pushing register values onto this stack. +;; It is imparitive that alignment be carefully managed, since the FXSTOR and +;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. +;; +;; The stub will switch stacks from the application stack to the debuger stack +;; and pushes the exception number. +;; +;; Then we building the context record on the stack. Since the stack grows down, +;; we push the fields of the context record from the back to the front. There +;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be +;; used as the memory buffer for the fxstor instruction. Therefore address of +;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which +;; must be 16 byte aligned. +;; +;; We carefully locate the stack to make this happen. +;; +;; For reference, the context structure looks like this: +;; struct { +;; UINT32 ExceptionData; +;; FX_SAVE_STATE FxSaveState; // 512 bytes, must be 16 byte aligned +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; +;; UINT32 Ldtr, Tr; +;; UINT64 Gdtr, Idtr; +;; UINT32 EFlags; +;; UINT32 Eip; +;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; +;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record + + +align 16 +DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment + dd 1ffdh dup (000000000h) ;; 32K should be enough stack + ;; This allocation is coocked to insure + ;; that the the buffer for the FXSTORE instruction + ;; will be 16 byte aligned also. + ;; +ExceptionNumber dd ? ;; first entry will be the vector number pushed by the stub + +DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub + +.CODE + +externdef InterruptDistrubutionHub:near + +;------------------------------------------------------------------------------ +; BOOLEAN +; FxStorSupport ( +; void +; ) +; +; Abstract: Returns TRUE if FxStor instructions are supported +; +FxStorSupport PROC C PUBLIC + +; +; cpuid corrupts ebx which must be preserved per the C calling convention +; + push ebx + mov eax, 1 + cpuid + mov eax, edx + and eax, FXSTOR_FLAG + shr eax, 24 + pop ebx + ret +FxStorSupport ENDP + + +;------------------------------------------------------------------------------ +; DESCRIPTOR * +; GetIdtr ( +; void +; ) +; +; Abstract: Returns physical address of IDTR +; +GetIdtr PROC C PUBLIC + LOCAL IdtrBuf:FWORD + + sidt IdtrBuf + mov eax, DWORD PTR IdtrBuf + 2 + ret +GetIdtr ENDP + + +;------------------------------------------------------------------------------ +; BOOLEAN +; WriteInterruptFlag ( +; BOOLEAN NewState +; ) +; +; Abstract: Programs interrupt flag to the requested state and returns previous +; state. +; +WriteInterruptFlag PROC C PUBLIC State:DWORD + + pushfd + pop eax + and eax, 200h + shr eax, 9 + mov ecx, State + .IF ecx == 0 + cli + .ELSE + sti + .ENDIF + ret + +WriteInterruptFlag ENDP + + + +;------------------------------------------------------------------------------ +; void +; Vect2Desc ( +; DESCRIPTOR * DestDesc, +; void (*Vector) (void) +; ) +; +; Abstract: Encodes an IDT descriptor with the given physical address +; +Vect2Desc PROC C PUBLIC DestPtr:DWORD, Vector:DWORD + + mov eax, Vector + mov ecx, DestPtr + mov word ptr [ecx], ax ; write bits 15..0 of offset + mov word ptr [ecx+2], 20h ; SYS_CODE_SEL from GDT + mov word ptr [ecx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present + shr eax, 16 + mov word ptr [ecx+6], ax ; write bits 31..16 of offset + + ret + +Vect2Desc ENDP + + + +;------------------------------------------------------------------------------ +; InterruptEntryStub +; +; Abstract: This code is not a function, but is a small piece of code that is +; copied and fixed up once for each IDT entry that is hooked. +; +InterruptEntryStub:: + mov AppEsp, esp ; save stack top + mov esp, offset DebugStackBegin ; switch to debugger stack + push 0 ; push vector number - will be modified before installed + db 0e9h ; jump rel32 + dd 0 ; fixed up to relative address of CommonIdtEntry +InterruptEntryStubEnd: + + + +;------------------------------------------------------------------------------ +; CommonIdtEntry +; +; Abstract: This code is not a function, but is the common part for all IDT +; vectors. +; +CommonIdtEntry:: +;; +;; At this point, the stub has saved the current application stack esp into AppEsp +;; and switched stacks to the debug stack, where it pushed the vector number +;; +;; The application stack looks like this: +;; +;; ... +;; (last application stack entry) +;; eflags from interrupted task +;; CS from interrupted task +;; EIP from interrupted task +;; Error code <-------------------- Only present for some exeption types +;; +;; + + +;; The stub switched us to the debug stack and pushed the interrupt number. +;; +;; Next, construct the context record. It will be build on the debug stack by +;; pushing the registers in the correct order so as to create the context structure +;; on the debug stack. The context record must be built from the end back to the +;; beginning because the stack grows down... +; +;; For reference, the context record looks like this: +;; +;; typedef +;; struct { +;; UINT32 ExceptionData; +;; FX_SAVE_STATE FxSaveState; +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; +;; UINT32 Cr0, Cr2, Cr3, Cr4; +;; UINT32 Ldtr, Tr; +;; UINT64 Gdtr, Idtr; +;; UINT32 EFlags; +;; UINT32 Eip; +;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; +;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + pushad + +;; Save interrupt state eflags register... + pushfd + pop eax + mov dword ptr Eflags, eax + +;; We need to determine if any extra data was pushed by the exception, and if so, save it +;; To do this, we check the exception number pushed by the stub, and cache the +;; result in a variable since we'll need this again. + .IF ExceptionNumber == EXCPT32_DOUBLE_FAULT + mov ExtraPush, 1 + .ELSEIF ExceptionNumber == EXCPT32_INVALID_TSS + mov ExtraPush, 1 + .ELSEIF ExceptionNumber == EXCPT32_SEG_NOT_PRESENT + mov ExtraPush, 1 + .ELSEIF ExceptionNumber == EXCPT32_STACK_FAULT + mov ExtraPush, 1 + .ELSEIF ExceptionNumber == EXCPT32_GP_FAULT + mov ExtraPush, 1 + .ELSEIF ExceptionNumber == EXCPT32_PAGE_FAULT + mov ExtraPush, 1 + .ELSEIF ExceptionNumber == EXCPT32_ALIGNMENT_CHECK + mov ExtraPush, 1 + .ELSE + mov ExtraPush, 0 + .ENDIF + +;; If there's some extra data, save it also, and modify the saved AppEsp to effectively +;; pop this value off the application's stack. + .IF ExtraPush == 1 + mov eax, AppEsp + mov ebx, [eax] + mov ExceptData, ebx + add eax, 4 + mov AppEsp, eax + .ELSE + mov ExceptData, 0 + .ENDIF + +;; The "pushad" above pushed the debug stack esp. Since what we're actually doing +;; is building the context record on the debug stack, we need to save the pushed +;; debug ESP, and replace it with the application's last stack entry... + mov eax, [esp + 12] + mov DebugEsp, eax + mov eax, AppEsp + add eax, 12 + ; application stack has eflags, cs, & eip, so + ; last actual application stack entry is + ; 12 bytes into the application stack. + mov [esp + 12], eax + +;; continue building context record +;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero + mov eax, ss + push eax + + ; CS from application is one entry back in application stack + mov eax, AppEsp + movzx eax, word ptr [eax + 4] + push eax + + mov eax, ds + push eax + mov eax, es + push eax + mov eax, fs + push eax + mov eax, gs + push eax + +;; UINT32 Eip; + ; Eip from application is on top of application stack + mov eax, AppEsp + push dword ptr [eax] + +;; UINT64 Gdtr, Idtr; + push 0 + push 0 + sidt fword ptr [esp] + push 0 + push 0 + sgdt fword ptr [esp] + +;; UINT32 Ldtr, Tr; + xor eax, eax + str ax + push eax + sldt ax + push eax + +;; UINT32 EFlags; +;; Eflags from application is two entries back in application stack + mov eax, AppEsp + push dword ptr [eax + 8] + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; +;; insure FXSAVE/FXRSTOR is enabled in CR4... +;; ... while we're at it, make sure DE is also enabled... + mov eax, cr4 + or eax, 208h + mov cr4, eax + push eax + mov eax, cr3 + push eax + mov eax, cr2 + push eax + push 0 + mov eax, cr0 + push eax + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + mov eax, dr7 + push eax +;; clear Dr7 while executing debugger itself + xor eax, eax + mov dr7, eax + + mov eax, dr6 + push eax +;; insure all status bits in dr6 are clear... + xor eax, eax + mov dr6, eax + + mov eax, dr3 + push eax + mov eax, dr2 + push eax + mov eax, dr1 + push eax + mov eax, dr0 + push eax + +;; FX_SAVE_STATE FxSaveState; + sub esp, 512 + mov edi, esp + ; IMPORTANT!! The debug stack has been carefully constructed to + ; insure that esp and edi are 16 byte aligned when we get here. + ; They MUST be. If they are not, a GP fault will occur. + FXSTOR_EDI + +;; UINT32 ExceptionData; + mov eax, ExceptData + push eax + +; call to C code which will in turn call registered handler +; pass in the vector number + mov eax, esp + push eax + mov eax, ExceptionNumber + push eax + call InterruptDistrubutionHub + add esp, 8 + +; restore context... +;; UINT32 ExceptionData; + add esp, 4 + +;; FX_SAVE_STATE FxSaveState; + mov esi, esp + FXRSTOR_ESI + add esp, 512 + +;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + pop eax + mov dr0, eax + pop eax + mov dr1, eax + pop eax + mov dr2, eax + pop eax + mov dr3, eax +;; skip restore of dr6. We cleared dr6 during the context save. + add esp, 4 + pop eax + mov dr7, eax + +;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; + pop eax + mov cr0, eax + add esp, 4 + pop eax + mov cr2, eax + pop eax + mov cr3, eax + pop eax + mov cr4, eax + +;; UINT32 EFlags; + mov eax, AppEsp + pop dword ptr [eax + 8] + +;; UINT16 Ldtr, Tr; +;; UINT64 Gdtr, Idtr; +;; Best not let anyone mess with these particular registers... + add esp, 24 + +;; UINT32 Eip; + pop dword ptr [eax] + +;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; +;; NOTE - modified segment registers could hang the debugger... We +;; could attempt to insulate ourselves against this possibility, +;; but that poses risks as well. +;; + + pop gs + pop fs + pop es + pop ds + pop [eax + 4] + pop ss + +;; The next stuff to restore is the general purpose registers that were pushed +;; using the pushad instruction. +;; +;; The value of ESP as stored in the context record is the application ESP +;; including the 3 entries on the application stack caused by the exception +;; itself. It may have been modified by the debug agent, so we need to +;; determine if we need to relocate the application stack. + + mov ebx, [esp + 12] ; move the potentially modified AppEsp into ebx + mov eax, AppEsp + add eax, 12 + cmp ebx, eax + je NoAppStackMove + + mov eax, AppEsp + mov ecx, [eax] ; EIP + mov [ebx], ecx + + mov ecx, [eax + 4] ; CS + mov [ebx + 4], ecx + + mov ecx, [eax + 8] ; EFLAGS + mov [ebx + 8], ecx + + mov eax, ebx ; modify the saved AppEsp to the new AppEsp + mov AppEsp, eax +NoAppStackMove: + mov eax, DebugEsp ; restore the DebugEsp on the debug stack + ; so our popad will not cause a stack switch + mov [esp + 12], eax + + cmp ExceptionNumber, 068h + jne NoChain + +Chain: + +;; Restore eflags so when we chain, the flags will be exactly as if we were never here. +;; We gin up the stack to do an iretd so we can get ALL the flags. + mov eax, AppEsp + mov ebx, [eax + 8] + and ebx, NOT 300h ; special handling for IF and TF + push ebx + push cs + push PhonyIretd + iretd +PhonyIretd: + +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + popad + +;; Switch back to application stack + mov esp, AppEsp + +;; Jump to original handler + jmp OrigVector + +NoChain: +;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; + popad + +;; Switch back to application stack + mov esp, AppEsp + +;; We're outa here... + iretd +END + + + diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.c b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.c new file mode 100644 index 0000000..2198192 --- /dev/null +++ b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.c @@ -0,0 +1,440 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + plDebugSupport.c + +Abstract: + + IA32 specific debug support functions + +Revision History + +--*/ + +// +// private header files +// +#include "plDebugSupport.h" + +// +// This the global main table to keep track of the interrupts +// +IDT_ENTRY *IdtEntryTable = NULL; +DESCRIPTOR NullDesc = 0; + +#ifndef EFI_NT_EMULATOR +STATIC +EFI_STATUS +CreateEntryStub ( + IN EFI_EXCEPTION_TYPE ExceptionType, + OUT VOID **Stub + ) +/*++ + +Routine Description: Allocate pool for a new IDT entry stub. Copy the generic + stub into the new buffer and fixup the vector number and jump target address. + +Arguments: + ExceptionType - This is the exception type that the new stub will be created + for. + Stub - On successful exit, *Stub contains the newly allocated entry stub. +Returns: + Typically EFI_SUCCESS + other possibilities are passed through from AllocatePool + +--*/ +{ + EFI_STATUS Status; + UINT8 *StubCopy; + + // + // First, allocate a new buffer and copy the stub code into it + // + Status = gBS->AllocatePool (EfiBootServicesData, StubSize, Stub); + if (Status == EFI_SUCCESS) { + StubCopy = *Stub; + gBS->CopyMem (StubCopy, InterruptEntryStub, StubSize); + + // + // Next fixup the stub code for this vector + // + + // The stub code looks like this: + // + // 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top + // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack + // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed + // 0000000D E9 db 0e9h ; jump rel32 + // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry + // + + // + // poke in the exception type so the second push pushes the exception type + // + StubCopy[0x0c] = (UINT8) ExceptionType; + + // + // fixup the jump target to point to the common entry + // + *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize]; + } + + return Status; +} + +STATIC +EFI_STATUS +HookEntry ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN VOID (*NewCallback) () + ) +/*++ + +Routine Description: + Creates a nes entry stub. Then saves the current IDT entry and replaces it + with an interrupt gate for the new entry point. The IdtEntryTable is updated + with the new registered function. + + This code executes in boot services context. The stub entry executes in interrupt + context. + +Arguments: + ExceptionType - specifies which vector to hook. + NewCallback - a pointer to the new function to be registered. + +Returns: + EFI_SUCCESS + Other possibilities are passed through by CreateEntryStub + +--*/ +// TODO: ) - add argument and description to function comment +{ + BOOLEAN OldIntFlagState; + EFI_STATUS Status; + + Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry); + if (Status == EFI_SUCCESS) { + OldIntFlagState = WriteInterruptFlag (0); + ReadIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + + ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[0]; + ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[3]; + + Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); + IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; + WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); + WriteInterruptFlag (OldIntFlagState); + } + + return Status; +} + +STATIC +EFI_STATUS +UnhookEntry ( + IN EFI_EXCEPTION_TYPE ExceptionType + ) +/*++ + +Routine Description: + Undoes HookEntry. This code executes in boot services context. + +Arguments: + ExceptionType - specifies which entry to unhook + +Returns: + EFI_SUCCESS + Other values are passed through from FreePool + +--*/ +{ + BOOLEAN OldIntFlagState; + EFI_STATUS Status; + + OldIntFlagState = WriteInterruptFlag (0); + WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + Status = gBS->FreePool ((VOID *) (UINTN) IdtEntryTable[ExceptionType].StubEntry); + ZeroMem (&IdtEntryTable[ExceptionType], sizeof (IDT_ENTRY)); + WriteInterruptFlag (OldIntFlagState); + + return (Status); +} +#endif + +EFI_STATUS +ManageIdtEntryTable ( + VOID (*NewCallback)(), + EFI_EXCEPTION_TYPE ExceptionType + ) +/*++ + +Routine Description: + This is the main worker function that manages the state of the interrupt + handlers. It both installs and uninstalls interrupt handlers based on the + value of NewCallback. If NewCallback is NULL, then uninstall is indicated. + If NewCallback is non-NULL, then install is indicated. + +Arguments: + NewCallback - If non-NULL, NewCallback specifies the new handler to register. + If NULL, specifies that the previously registered handler should + be uninstalled. + ExceptionType - Indicates which entry to manage + +Returns: + EFI_SUCCESS + EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has + no handler registered for it + EFI_ALREADY_STARTED - requested install to a vector that already has a handler registered. + + Other possible return values are passed through from UnHookEntry and HookEntry. + +--*/ +// TODO: ) - add argument and description to function comment +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + +#ifndef EFI_NT_EMULATOR + if (CompareDescriptor (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) { + // + // we've already installed to this vector + // + if (NewCallback != NULL) { + // + // if the input handler is non-null, error + // + Status = EFI_ALREADY_STARTED; + } else { + Status = UnhookEntry (ExceptionType); + } + } else { + // + // no user handler installed on this vector + // + if (NewCallback == NULL) { + // + // if the input handler is null, error + // + Status = EFI_INVALID_PARAMETER; + } else { + Status = HookEntry (ExceptionType, NewCallback); + } + } +#endif + return Status; +} + +EFI_STATUS +EFIAPI +GetMaximumProcessorIndex ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + OUT UINTN *MaxProcessorIndex + ) +/*++ + +Routine Description: This is a DebugSupport protocol member function. + +Arguments: + +Returns: Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0 + +--*/ +// TODO: This - add argument and description to function comment +// TODO: MaxProcessorIndex - add argument and description to function comment +{ + *MaxProcessorIndex = 0; + return (EFI_SUCCESS); +} + +EFI_STATUS +EFIAPI +RegisterPeriodicCallback ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_PERIODIC_CALLBACK PeriodicCallback + ) +/*++ + +Routine Description: This is a DebugSupport protocol member function. + +Arguments: + +Returns: + +--*/ +// TODO: This - add argument and description to function comment +// TODO: ProcessorIndex - add argument and description to function comment +// TODO: PeriodicCallback - add argument and description to function comment +{ + return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR); +} + +EFI_STATUS +EFIAPI +RegisterExceptionCallback ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_EXCEPTION_CALLBACK NewCallback, + IN EFI_EXCEPTION_TYPE ExceptionType + ) +/*++ + +Routine Description: + This is a DebugSupport protocol member function. + + This code executes in boot services context. + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: ProcessorIndex - add argument and description to function comment +// TODO: NewCallback - add argument and description to function comment +// TODO: ExceptionType - add argument and description to function comment +{ + return ManageIdtEntryTable (NewCallback, ExceptionType); +} + +EFI_STATUS +EFIAPI +InvalidateInstructionCache ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN VOID *Start, + IN UINT64 Length + ) +/*++ + +Routine Description: + This is a DebugSupport protocol member function. + For IA32, this is a no-op since the instruction and data caches are coherent. + +Arguments: + +Returns: + + None + +--*/ +// TODO: This - add argument and description to function comment +// TODO: ProcessorIndex - add argument and description to function comment +// TODO: Start - add argument and description to function comment +// TODO: Length - add argument and description to function comment +// TODO: EFI_SUCCESS - add return value to function comment +{ + return EFI_SUCCESS; +} + +EFI_STATUS +plInitializeDebugSupportDriver ( + VOID + ) +/*++ + +Routine Description: + Initializes driver's handler registration database. + + This code executes in boot services context. + +Arguments: + None + +Returns: + EFI_SUCCESS + EFI_UNSUPPORTED - if IA32 processor does not support FXSTOR/FXRSTOR instructions, + the context save will fail, so these processor's are not supported. + +--*/ +// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +{ + if (!FxStorSupport ()) { + return EFI_UNSUPPORTED; + } else { + IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES); + if (IdtEntryTable != NULL) { + return EFI_SUCCESS; + } else { + return EFI_OUT_OF_RESOURCES; + } + } +} + +EFI_STATUS +EFIAPI +plUnloadDebugSupportDriver ( + IN EFI_HANDLE ImageHandle + ) +/*++ + +Routine Description: + This is the callback that is written to the LoadedImage protocol instance + on the image handle. It uninstalls all registered handlers and frees all entry + stub memory. + + This code executes in boot services context. + +Arguments: + ImageHandle - The image handle of the unload handler + +Returns: + + None + +--*/ +// TODO: EFI_SUCCESS - add return value to function comment +{ + EFI_EXCEPTION_TYPE ExceptionType; + + for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) { + ManageIdtEntryTable (NULL, ExceptionType); + } + + gBS->FreePool (IdtEntryTable); + return EFI_SUCCESS; +} + +VOID +InterruptDistrubutionHub ( + EFI_EXCEPTION_TYPE ExceptionType, + EFI_SYSTEM_CONTEXT_IA32 *ContextRecord + ) +/*++ + +Routine Description: Common piece of code that invokes the registered handlers. + + This code executes in exception context so no efi calls are allowed. + +Arguments: + +Returns: + + None + +--*/ +// TODO: ExceptionType - add argument and description to function comment +// TODO: ContextRecord - add argument and description to function comment +{ + if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) { + if (ExceptionType != SYSTEM_TIMER_VECTOR) { + IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord); + } else { + OrigVector = IdtEntryTable[ExceptionType].OrigVector; + IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord); + } + } +} diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.h b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.h new file mode 100644 index 0000000..abb6967 --- /dev/null +++ b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/plDebugSupport.h @@ -0,0 +1,312 @@ +/*++ + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + plDebugSupport.h + +Abstract: + + IA32 specific debug support macros, typedefs and prototypes. + +Revision History + +--*/ + +#ifndef _PLDEBUG_SUPPORT_H +#define _PLDEBUG_SUPPORT_H + +#define NUM_IDT_ENTRIES 0x78 +#define SYSTEM_TIMER_VECTOR 0x68 +#define VECTOR_ENTRY_PAGES 1 +#define CopyDescriptor(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR)) +#define ZeroDescriptor(Dest) CopyDescriptor ((Dest), &NullDesc) +#define ReadIdt(Vector, Dest) CopyDescriptor ((Dest), &((GetIdtr ())[(Vector)])) +#define WriteIdt(Vector, Src) CopyDescriptor (&((GetIdtr ())[(Vector)]), (Src)) +#define CompareDescriptor(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR)) +#define EFI_ISA IsaIa32 +#define FF_FXSR (1 << 24) + +typedef UINT64 DESCRIPTOR; + +typedef struct { + DESCRIPTOR OrigDesc; + VOID (*OrigVector) (VOID); + DESCRIPTOR NewDesc; + VOID (*StubEntry) (VOID); + VOID (*RegisteredCallback) (); +} IDT_ENTRY; + +extern EFI_SYSTEM_CONTEXT SystemContext; +extern UINT8 InterruptEntryStub[]; +extern UINT32 StubSize; +extern VOID (*OrigVector) (VOID); + +VOID +CommonIdtEntry ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +FxStorSupport ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +DESCRIPTOR * +GetIdtr ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +VOID +Vect2Desc ( + DESCRIPTOR * DestDesc, + VOID (*Vector) (VOID) + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + DestDesc - TODO: add argument description + ) - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +WriteInterruptFlag ( + BOOLEAN NewState + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + NewState - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +plInitializeDebugSupportDriver ( + VOID + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + None + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +plUnloadDebugSupportDriver ( + IN EFI_HANDLE ImageHandle + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + ImageHandle - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +// +// DebugSupport protocol member functions +// +EFI_STATUS +EFIAPI +GetMaximumProcessorIndex ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + OUT UINTN *MaxProcessorIndex + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + MaxProcessorIndex - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +RegisterPeriodicCallback ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_PERIODIC_CALLBACK PeriodicCallback + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + ProcessorIndex - TODO: add argument description + PeriodicCallback - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +RegisterExceptionCallback ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_EXCEPTION_CALLBACK NewCallback, + IN EFI_EXCEPTION_TYPE ExceptionType + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + ProcessorIndex - TODO: add argument description + NewCallback - TODO: add argument description + ExceptionType - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +EFI_STATUS +EFIAPI +InvalidateInstructionCache ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN VOID *Start, + IN UINT64 Length + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + This - TODO: add argument description + ProcessorIndex - TODO: add argument description + Start - TODO: add argument description + Length - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +#endif diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.S b/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.S deleted file mode 100644 index 131464a..0000000 --- a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.S +++ /dev/null @@ -1,270 +0,0 @@ -#****************************************************************************** -#* -#* Copyright (c) 2006, Intel Corporation -#* All rights reserved. This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#****************************************************************************** - -.global _OrigVector -.global _InterruptEntryStub -.global _StubSize -.global _CommonIdtEntry -.global _FxStorSupport - -_AppEsp: .long 0x11111111 # ? -_DebugEsp: .long 0x22222222 # ? -_ExtraPush: .long 0x33333333 # ? -_ExceptData: .long 0x44444444 # ? -_Eflags: .long 0x55555555 # ? -_OrigVector: .long 0x66666666 # ? -_StubSize: .long _InterruptEntryStubEnd - _InterruptEntryStub - -.global _FxStorSupport -_FxStorSupport: - push %ebx - mov $0x1,%eax - cpuid - mov %edx,%eax - and $0x1000000,%eax - shr $0x18,%eax - pop %ebx - ret - -.global _GetIdtr -_GetIdtr: - push %ebp - mov %esp,%ebp - add $0xfffffff8,%esp - sidtl 0xfffffffa(%ebp) - mov 0xfffffffc(%ebp),%eax - leave - ret - -.global _WriteInterruptFlag -_WriteInterruptFlag: - push %ebp - mov %esp,%ebp - pushf - pop %eax - and $0x200,%eax - shr $0x9,%eax - mov 0x8(%ebp),%ecx - or %ecx,%ecx - jne _WriteInterruptFlag+0x17 - cli - jmp _WriteInterruptFlag+0x18 - sti - leave - ret - -.global _Vect2Desc -_Vect2Desc: - push %ebp - mov %esp,%ebp - mov 0xc(%ebp),%eax - mov 0x8(%ebp),%ecx - mov %ax,(%ecx) - movw $0x20,0x2(%ecx) - movw $0x8e00,0x4(%ecx) - shr $0x10,%eax - mov %ax,0x6(%ecx) - leave - ret - -.global _InterruptEntryStub -_InterruptEntryStub: - mov %esp,0x0 - mov $0x0,%esp - push $0x0 - jmp _CommonIdtEntry -.global _InterruptEntryStubEnd -_InterruptEntryStubEnd: - -.global _CommonIdtEntry -_CommonIdtEntry: - pusha - pushf - pop %eax - mov %eax,0x0 - cmpl $0x8,0x0 - jne _CommonIdtEntry+0x20 - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - cmpl $0xa,0x0 - jne _CommonIdtEntry+0x35 - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - cmpl $0xb,0x0 - jne _CommonIdtEntry+0x4a - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - cmpl $0xc,0x0 - jne _CommonIdtEntry+0x5f - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - cmpl $0xd,0x0 - jne _CommonIdtEntry+0x74 - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - cmpl $0xe,0x0 - jne _CommonIdtEntry+0x89 - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - cmpl $0x11,0x0 - jne _CommonIdtEntry+0x9e - movl $0x1,0x0 - jmp _CommonIdtEntry+0xa8 - movl $0x0,0x0 - cmpl $0x1,0x0 - jne _CommonIdtEntry+0xc8 - mov 0x0,%eax - mov (%eax),%ebx - mov %ebx,0x0 - add $0x4,%eax - mov %eax,0x0 - jmp _CommonIdtEntry+0xd2 - movl $0x0,0x0 - mov 0xc(%esp),%eax - mov %eax,0x0 - mov 0x0,%eax - add $0xc,%eax - mov %eax,0xc(%esp) - mov %ss,%eax - push %eax - mov 0x0,%eax - movzwl 0x4(%eax),%eax - push %eax - mov %ds,%eax - push %eax - mov %es,%eax - push %eax - mov %fs,%eax - push %eax - mov %gs,%eax - push %eax - mov 0x0,%eax - pushl (%eax) - push $0x0 - push $0x0 - sidtl (%esp) - push $0x0 - push $0x0 - sgdtl (%esp) - xor %eax,%eax - str %eax - push %eax - sldt %eax - push %eax - mov 0x0,%eax - pushl 0x8(%eax) - mov %cr4,%eax - or $0x208,%eax - mov %eax,%cr4 - push %eax - mov %cr3,%eax - push %eax - mov %cr2,%eax - push %eax - push $0x0 - mov %cr0,%eax - push %eax - mov %db7,%eax - push %eax - xor %eax,%eax - mov %eax,%db7 - mov %db6,%eax - push %eax - xor %eax,%eax - mov %eax,%db6 - mov %db3,%eax - push %eax - mov %db2,%eax - push %eax - mov %db1,%eax - push %eax - mov %db0,%eax - push %eax - sub $0x200,%esp - mov %esp,%edi - fxsave (%edi) - mov 0x0,%eax - push %eax - mov %esp,%eax - push %eax - mov 0x0,%eax - push %eax - call _CommonIdtEntry+0x184 - add $0x8,%esp - add $0x4,%esp - mov %esp,%esi - fxrstor (%esi) - add $0x200,%esp - pop %eax - mov %eax,%db0 - pop %eax - mov %eax,%db1 - pop %eax - mov %eax,%db2 - pop %eax - mov %eax,%db3 - add $0x4,%esp - pop %eax - mov %eax,%db7 - pop %eax - mov %eax,%cr0 - add $0x4,%esp - pop %eax - mov %eax,%cr2 - pop %eax - mov %eax,%cr3 - pop %eax - mov %eax,%cr4 - mov 0x0,%eax - popl 0x8(%eax) - add $0x18,%esp - popl (%eax) - pop %gs - pop %fs - pop %es - pop %ds - popl 0x4(%eax) - pop %ss - mov 0xc(%esp),%ebx - mov 0x0,%eax - add $0xc,%eax - cmp %eax,%ebx - je _CommonIdtEntry+0x202 - mov 0x0,%eax - mov (%eax),%ecx - mov %ecx,(%ebx) - mov 0x4(%eax),%ecx - mov %ecx,0x4(%ebx) - mov 0x8(%eax),%ecx - mov %ecx,0x8(%ebx) - mov %ebx,%eax - mov %eax,0x0 - mov 0x0,%eax - mov %eax,0xc(%esp) - cmpl $0x68,0x0 - jne PhonyIretd+0xd - mov 0x0,%eax - mov 0x8(%eax),%ebx - and $0xfffffcff,%ebx - push %ebx - push %cs - push $0x0 - iret - -PhonyIretd: - popa - mov 0x0,%esp - jmp *0x0 - popa - mov 0x0,%esp - iret diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm b/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm deleted file mode 100644 index 89c9f83..0000000 --- a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/AsmFuncs.asm +++ /dev/null @@ -1,547 +0,0 @@ -;****************************************************************************** -;* -;* Copyright (c) 2006, Intel Corporation -;* All rights reserved. This program and the accompanying materials -;* are licensed and made available under the terms and conditions of the BSD License -;* which accompanies this distribution. The full text of the license may be found at -;* http://opensource.org/licenses/bsd-license.php -;* -;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -;* -;****************************************************************************** - -.586p -.MODEL FLAT, C - -EXCPT32_DIVIDE_ERROR EQU 0 -EXCPT32_DEBUG EQU 1 -EXCPT32_NMI EQU 2 -EXCPT32_BREAKPOINT EQU 3 -EXCPT32_OVERFLOW EQU 4 -EXCPT32_BOUND EQU 5 -EXCPT32_INVALID_OPCODE EQU 6 -EXCPT32_DOUBLE_FAULT EQU 8 -EXCPT32_INVALID_TSS EQU 10 -EXCPT32_SEG_NOT_PRESENT EQU 11 -EXCPT32_STACK_FAULT EQU 12 -EXCPT32_GP_FAULT EQU 13 -EXCPT32_PAGE_FAULT EQU 14 -EXCPT32_FP_ERROR EQU 16 -EXCPT32_ALIGNMENT_CHECK EQU 17 -EXCPT32_MACHINE_CHECK EQU 18 -EXCPT32_SIMD EQU 19 - -FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags - -;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87, -;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver -;; MUST check the CPUID feature flags to see that these instructions are available -;; and fail to init if they are not. - -;; fxstor [edi] -FXSTOR_EDI MACRO - db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi] -ENDM - -;; fxrstor [esi] -FXRSTOR_ESI MACRO - db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi] -ENDM -.DATA - -public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport - -StubSize dd InterruptEntryStubEnd - InterruptEntryStub -AppEsp dd 11111111h ; ? -DebugEsp dd 22222222h ; ? -ExtraPush dd 33333333h ; ? -ExceptData dd 44444444h ; ? -Eflags dd 55555555h ; ? -OrigVector dd 66666666h ; ? - -;; The declarations below define the memory region that will be used for the debug stack. -;; The context record will be built by pushing register values onto this stack. -;; It is imparitive that alignment be carefully managed, since the FXSTOR and -;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. -;; -;; The stub will switch stacks from the application stack to the debuger stack -;; and pushes the exception number. -;; -;; Then we building the context record on the stack. Since the stack grows down, -;; we push the fields of the context record from the back to the front. There -;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be -;; used as the memory buffer for the fxstor instruction. Therefore address of -;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which -;; must be 16 byte aligned. -;; -;; We carefully locate the stack to make this happen. -;; -;; For reference, the context structure looks like this: -;; struct { -;; UINT32 ExceptionData; -;; FX_SAVE_STATE FxSaveState; // 512 bytes, must be 16 byte aligned -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; -;; UINT32 Ldtr, Tr; -;; UINT64 Gdtr, Idtr; -;; UINT32 EFlags; -;; UINT32 Eip; -;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record - - -align 16 -DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment - dd 1ffdh dup (000000000h) ;; 32K should be enough stack - ;; This allocation is coocked to insure - ;; that the the buffer for the FXSTORE instruction - ;; will be 16 byte aligned also. - ;; -ExceptionNumber dd ? ;; first entry will be the vector number pushed by the stub - -DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub - -.CODE - -externdef InterruptDistrubutionHub:near - -;------------------------------------------------------------------------------ -; BOOLEAN -; FxStorSupport ( -; void -; ) -; -; Abstract: Returns TRUE if FxStor instructions are supported -; -FxStorSupport PROC C PUBLIC - -; -; cpuid corrupts ebx which must be preserved per the C calling convention -; - push ebx - mov eax, 1 - cpuid - mov eax, edx - and eax, FXSTOR_FLAG - shr eax, 24 - pop ebx - ret -FxStorSupport ENDP - - -;------------------------------------------------------------------------------ -; DESCRIPTOR * -; GetIdtr ( -; void -; ) -; -; Abstract: Returns physical address of IDTR -; -GetIdtr PROC C PUBLIC - LOCAL IdtrBuf:FWORD - - sidt IdtrBuf - mov eax, DWORD PTR IdtrBuf + 2 - ret -GetIdtr ENDP - - -;------------------------------------------------------------------------------ -; BOOLEAN -; WriteInterruptFlag ( -; BOOLEAN NewState -; ) -; -; Abstract: Programs interrupt flag to the requested state and returns previous -; state. -; -WriteInterruptFlag PROC C PUBLIC State:DWORD - - pushfd - pop eax - and eax, 200h - shr eax, 9 - mov ecx, State - .IF ecx == 0 - cli - .ELSE - sti - .ENDIF - ret - -WriteInterruptFlag ENDP - - - -;------------------------------------------------------------------------------ -; void -; Vect2Desc ( -; DESCRIPTOR * DestDesc, -; void (*Vector) (void) -; ) -; -; Abstract: Encodes an IDT descriptor with the given physical address -; -Vect2Desc PROC C PUBLIC DestPtr:DWORD, Vector:DWORD - - mov eax, Vector - mov ecx, DestPtr - mov word ptr [ecx], ax ; write bits 15..0 of offset - mov word ptr [ecx+2], 20h ; SYS_CODE_SEL from GDT - mov word ptr [ecx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present - shr eax, 16 - mov word ptr [ecx+6], ax ; write bits 31..16 of offset - - ret - -Vect2Desc ENDP - - - -;------------------------------------------------------------------------------ -; InterruptEntryStub -; -; Abstract: This code is not a function, but is a small piece of code that is -; copied and fixed up once for each IDT entry that is hooked. -; -InterruptEntryStub:: - mov AppEsp, esp ; save stack top - mov esp, offset DebugStackBegin ; switch to debugger stack - push 0 ; push vector number - will be modified before installed - db 0e9h ; jump rel32 - dd 0 ; fixed up to relative address of CommonIdtEntry -InterruptEntryStubEnd: - - - -;------------------------------------------------------------------------------ -; CommonIdtEntry -; -; Abstract: This code is not a function, but is the common part for all IDT -; vectors. -; -CommonIdtEntry:: -;; -;; At this point, the stub has saved the current application stack esp into AppEsp -;; and switched stacks to the debug stack, where it pushed the vector number -;; -;; The application stack looks like this: -;; -;; ... -;; (last application stack entry) -;; eflags from interrupted task -;; CS from interrupted task -;; EIP from interrupted task -;; Error code <-------------------- Only present for some exeption types -;; -;; - - -;; The stub switched us to the debug stack and pushed the interrupt number. -;; -;; Next, construct the context record. It will be build on the debug stack by -;; pushing the registers in the correct order so as to create the context structure -;; on the debug stack. The context record must be built from the end back to the -;; beginning because the stack grows down... -; -;; For reference, the context record looks like this: -;; -;; typedef -;; struct { -;; UINT32 ExceptionData; -;; FX_SAVE_STATE FxSaveState; -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT32 Cr0, Cr2, Cr3, Cr4; -;; UINT32 Ldtr, Tr; -;; UINT64 Gdtr, Idtr; -;; UINT32 EFlags; -;; UINT32 Eip; -;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pushad - -;; Save interrupt state eflags register... - pushfd - pop eax - mov dword ptr Eflags, eax - -;; We need to determine if any extra data was pushed by the exception, and if so, save it -;; To do this, we check the exception number pushed by the stub, and cache the -;; result in a variable since we'll need this again. - .IF ExceptionNumber == EXCPT32_DOUBLE_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_INVALID_TSS - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_SEG_NOT_PRESENT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_STACK_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_GP_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_PAGE_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_ALIGNMENT_CHECK - mov ExtraPush, 1 - .ELSE - mov ExtraPush, 0 - .ENDIF - -;; If there's some extra data, save it also, and modify the saved AppEsp to effectively -;; pop this value off the application's stack. - .IF ExtraPush == 1 - mov eax, AppEsp - mov ebx, [eax] - mov ExceptData, ebx - add eax, 4 - mov AppEsp, eax - .ELSE - mov ExceptData, 0 - .ENDIF - -;; The "pushad" above pushed the debug stack esp. Since what we're actually doing -;; is building the context record on the debug stack, we need to save the pushed -;; debug ESP, and replace it with the application's last stack entry... - mov eax, [esp + 12] - mov DebugEsp, eax - mov eax, AppEsp - add eax, 12 - ; application stack has eflags, cs, & eip, so - ; last actual application stack entry is - ; 12 bytes into the application stack. - mov [esp + 12], eax - -;; continue building context record -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov eax, ss - push eax - - ; CS from application is one entry back in application stack - mov eax, AppEsp - movzx eax, word ptr [eax + 4] - push eax - - mov eax, ds - push eax - mov eax, es - push eax - mov eax, fs - push eax - mov eax, gs - push eax - -;; UINT32 Eip; - ; Eip from application is on top of application stack - mov eax, AppEsp - push dword ptr [eax] - -;; UINT64 Gdtr, Idtr; - push 0 - push 0 - sidt fword ptr [esp] - push 0 - push 0 - sgdt fword ptr [esp] - -;; UINT32 Ldtr, Tr; - xor eax, eax - str ax - push eax - sldt ax - push eax - -;; UINT32 EFlags; -;; Eflags from application is two entries back in application stack - mov eax, AppEsp - push dword ptr [eax + 8] - -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; -;; insure FXSAVE/FXRSTOR is enabled in CR4... -;; ... while we're at it, make sure DE is also enabled... - mov eax, cr4 - or eax, 208h - mov cr4, eax - push eax - mov eax, cr3 - push eax - mov eax, cr2 - push eax - push 0 - mov eax, cr0 - push eax - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov eax, dr7 - push eax -;; clear Dr7 while executing debugger itself - xor eax, eax - mov dr7, eax - - mov eax, dr6 - push eax -;; insure all status bits in dr6 are clear... - xor eax, eax - mov dr6, eax - - mov eax, dr3 - push eax - mov eax, dr2 - push eax - mov eax, dr1 - push eax - mov eax, dr0 - push eax - -;; FX_SAVE_STATE FxSaveState; - sub esp, 512 - mov edi, esp - ; IMPORTANT!! The debug stack has been carefully constructed to - ; insure that esp and edi are 16 byte aligned when we get here. - ; They MUST be. If they are not, a GP fault will occur. - FXSTOR_EDI - -;; UINT32 ExceptionData; - mov eax, ExceptData - push eax - -; call to C code which will in turn call registered handler -; pass in the vector number - mov eax, esp - push eax - mov eax, ExceptionNumber - push eax - call InterruptDistrubutionHub - add esp, 8 - -; restore context... -;; UINT32 ExceptionData; - add esp, 4 - -;; FX_SAVE_STATE FxSaveState; - mov esi, esp - FXRSTOR_ESI - add esp, 512 - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - pop eax - mov dr0, eax - pop eax - mov dr1, eax - pop eax - mov dr2, eax - pop eax - mov dr3, eax -;; skip restore of dr6. We cleared dr6 during the context save. - add esp, 4 - pop eax - mov dr7, eax - -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - pop eax - mov cr0, eax - add esp, 4 - pop eax - mov cr2, eax - pop eax - mov cr3, eax - pop eax - mov cr4, eax - -;; UINT32 EFlags; - mov eax, AppEsp - pop dword ptr [eax + 8] - -;; UINT16 Ldtr, Tr; -;; UINT64 Gdtr, Idtr; -;; Best not let anyone mess with these particular registers... - add esp, 24 - -;; UINT32 Eip; - pop dword ptr [eax] - -;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; -;; NOTE - modified segment registers could hang the debugger... We -;; could attempt to insulate ourselves against this possibility, -;; but that poses risks as well. -;; - - pop gs - pop fs - pop es - pop ds - pop [eax + 4] - pop ss - -;; The next stuff to restore is the general purpose registers that were pushed -;; using the pushad instruction. -;; -;; The value of ESP as stored in the context record is the application ESP -;; including the 3 entries on the application stack caused by the exception -;; itself. It may have been modified by the debug agent, so we need to -;; determine if we need to relocate the application stack. - - mov ebx, [esp + 12] ; move the potentially modified AppEsp into ebx - mov eax, AppEsp - add eax, 12 - cmp ebx, eax - je NoAppStackMove - - mov eax, AppEsp - mov ecx, [eax] ; EIP - mov [ebx], ecx - - mov ecx, [eax + 4] ; CS - mov [ebx + 4], ecx - - mov ecx, [eax + 8] ; EFLAGS - mov [ebx + 8], ecx - - mov eax, ebx ; modify the saved AppEsp to the new AppEsp - mov AppEsp, eax -NoAppStackMove: - mov eax, DebugEsp ; restore the DebugEsp on the debug stack - ; so our popad will not cause a stack switch - mov [esp + 12], eax - - cmp ExceptionNumber, 068h - jne NoChain - -Chain: - -;; Restore eflags so when we chain, the flags will be exactly as if we were never here. -;; We gin up the stack to do an iretd so we can get ALL the flags. - mov eax, AppEsp - mov ebx, [eax + 8] - and ebx, NOT 300h ; special handling for IF and TF - push ebx - push cs - push PhonyIretd - iretd -PhonyIretd: - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popad - -;; Switch back to application stack - mov esp, AppEsp - -;; Jump to original handler - jmp OrigVector - -NoChain: -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popad - -;; Switch back to application stack - mov esp, AppEsp - -;; We're outa here... - iretd -END - - - diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c b/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c deleted file mode 100644 index 2198192..0000000 --- a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.c +++ /dev/null @@ -1,440 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - plDebugSupport.c - -Abstract: - - IA32 specific debug support functions - -Revision History - ---*/ - -// -// private header files -// -#include "plDebugSupport.h" - -// -// This the global main table to keep track of the interrupts -// -IDT_ENTRY *IdtEntryTable = NULL; -DESCRIPTOR NullDesc = 0; - -#ifndef EFI_NT_EMULATOR -STATIC -EFI_STATUS -CreateEntryStub ( - IN EFI_EXCEPTION_TYPE ExceptionType, - OUT VOID **Stub - ) -/*++ - -Routine Description: Allocate pool for a new IDT entry stub. Copy the generic - stub into the new buffer and fixup the vector number and jump target address. - -Arguments: - ExceptionType - This is the exception type that the new stub will be created - for. - Stub - On successful exit, *Stub contains the newly allocated entry stub. -Returns: - Typically EFI_SUCCESS - other possibilities are passed through from AllocatePool - ---*/ -{ - EFI_STATUS Status; - UINT8 *StubCopy; - - // - // First, allocate a new buffer and copy the stub code into it - // - Status = gBS->AllocatePool (EfiBootServicesData, StubSize, Stub); - if (Status == EFI_SUCCESS) { - StubCopy = *Stub; - gBS->CopyMem (StubCopy, InterruptEntryStub, StubSize); - - // - // Next fixup the stub code for this vector - // - - // The stub code looks like this: - // - // 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top - // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack - // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed - // 0000000D E9 db 0e9h ; jump rel32 - // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry - // - - // - // poke in the exception type so the second push pushes the exception type - // - StubCopy[0x0c] = (UINT8) ExceptionType; - - // - // fixup the jump target to point to the common entry - // - *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize]; - } - - return Status; -} - -STATIC -EFI_STATUS -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN VOID (*NewCallback) () - ) -/*++ - -Routine Description: - Creates a nes entry stub. Then saves the current IDT entry and replaces it - with an interrupt gate for the new entry point. The IdtEntryTable is updated - with the new registered function. - - This code executes in boot services context. The stub entry executes in interrupt - context. - -Arguments: - ExceptionType - specifies which vector to hook. - NewCallback - a pointer to the new function to be registered. - -Returns: - EFI_SUCCESS - Other possibilities are passed through by CreateEntryStub - ---*/ -// TODO: ) - add argument and description to function comment -{ - BOOLEAN OldIntFlagState; - EFI_STATUS Status; - - Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry); - if (Status == EFI_SUCCESS) { - OldIntFlagState = WriteInterruptFlag (0); - ReadIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - - ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[0]; - ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[3]; - - Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); - IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; - WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); - WriteInterruptFlag (OldIntFlagState); - } - - return Status; -} - -STATIC -EFI_STATUS -UnhookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType - ) -/*++ - -Routine Description: - Undoes HookEntry. This code executes in boot services context. - -Arguments: - ExceptionType - specifies which entry to unhook - -Returns: - EFI_SUCCESS - Other values are passed through from FreePool - ---*/ -{ - BOOLEAN OldIntFlagState; - EFI_STATUS Status; - - OldIntFlagState = WriteInterruptFlag (0); - WriteIdt (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - Status = gBS->FreePool ((VOID *) (UINTN) IdtEntryTable[ExceptionType].StubEntry); - ZeroMem (&IdtEntryTable[ExceptionType], sizeof (IDT_ENTRY)); - WriteInterruptFlag (OldIntFlagState); - - return (Status); -} -#endif - -EFI_STATUS -ManageIdtEntryTable ( - VOID (*NewCallback)(), - EFI_EXCEPTION_TYPE ExceptionType - ) -/*++ - -Routine Description: - This is the main worker function that manages the state of the interrupt - handlers. It both installs and uninstalls interrupt handlers based on the - value of NewCallback. If NewCallback is NULL, then uninstall is indicated. - If NewCallback is non-NULL, then install is indicated. - -Arguments: - NewCallback - If non-NULL, NewCallback specifies the new handler to register. - If NULL, specifies that the previously registered handler should - be uninstalled. - ExceptionType - Indicates which entry to manage - -Returns: - EFI_SUCCESS - EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has - no handler registered for it - EFI_ALREADY_STARTED - requested install to a vector that already has a handler registered. - - Other possible return values are passed through from UnHookEntry and HookEntry. - ---*/ -// TODO: ) - add argument and description to function comment -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - -#ifndef EFI_NT_EMULATOR - if (CompareDescriptor (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) { - // - // we've already installed to this vector - // - if (NewCallback != NULL) { - // - // if the input handler is non-null, error - // - Status = EFI_ALREADY_STARTED; - } else { - Status = UnhookEntry (ExceptionType); - } - } else { - // - // no user handler installed on this vector - // - if (NewCallback == NULL) { - // - // if the input handler is null, error - // - Status = EFI_INVALID_PARAMETER; - } else { - Status = HookEntry (ExceptionType, NewCallback); - } - } -#endif - return Status; -} - -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ) -/*++ - -Routine Description: This is a DebugSupport protocol member function. - -Arguments: - -Returns: Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0 - ---*/ -// TODO: This - add argument and description to function comment -// TODO: MaxProcessorIndex - add argument and description to function comment -{ - *MaxProcessorIndex = 0; - return (EFI_SUCCESS); -} - -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ) -/*++ - -Routine Description: This is a DebugSupport protocol member function. - -Arguments: - -Returns: - ---*/ -// TODO: This - add argument and description to function comment -// TODO: ProcessorIndex - add argument and description to function comment -// TODO: PeriodicCallback - add argument and description to function comment -{ - return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR); -} - -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK NewCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ) -/*++ - -Routine Description: - This is a DebugSupport protocol member function. - - This code executes in boot services context. - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: ProcessorIndex - add argument and description to function comment -// TODO: NewCallback - add argument and description to function comment -// TODO: ExceptionType - add argument and description to function comment -{ - return ManageIdtEntryTable (NewCallback, ExceptionType); -} - -EFI_STATUS -EFIAPI -InvalidateInstructionCache ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN VOID *Start, - IN UINT64 Length - ) -/*++ - -Routine Description: - This is a DebugSupport protocol member function. - For IA32, this is a no-op since the instruction and data caches are coherent. - -Arguments: - -Returns: - - None - ---*/ -// TODO: This - add argument and description to function comment -// TODO: ProcessorIndex - add argument and description to function comment -// TODO: Start - add argument and description to function comment -// TODO: Length - add argument and description to function comment -// TODO: EFI_SUCCESS - add return value to function comment -{ - return EFI_SUCCESS; -} - -EFI_STATUS -plInitializeDebugSupportDriver ( - VOID - ) -/*++ - -Routine Description: - Initializes driver's handler registration database. - - This code executes in boot services context. - -Arguments: - None - -Returns: - EFI_SUCCESS - EFI_UNSUPPORTED - if IA32 processor does not support FXSTOR/FXRSTOR instructions, - the context save will fail, so these processor's are not supported. - ---*/ -// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment -{ - if (!FxStorSupport ()) { - return EFI_UNSUPPORTED; - } else { - IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES); - if (IdtEntryTable != NULL) { - return EFI_SUCCESS; - } else { - return EFI_OUT_OF_RESOURCES; - } - } -} - -EFI_STATUS -EFIAPI -plUnloadDebugSupportDriver ( - IN EFI_HANDLE ImageHandle - ) -/*++ - -Routine Description: - This is the callback that is written to the LoadedImage protocol instance - on the image handle. It uninstalls all registered handlers and frees all entry - stub memory. - - This code executes in boot services context. - -Arguments: - ImageHandle - The image handle of the unload handler - -Returns: - - None - ---*/ -// TODO: EFI_SUCCESS - add return value to function comment -{ - EFI_EXCEPTION_TYPE ExceptionType; - - for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) { - ManageIdtEntryTable (NULL, ExceptionType); - } - - gBS->FreePool (IdtEntryTable); - return EFI_SUCCESS; -} - -VOID -InterruptDistrubutionHub ( - EFI_EXCEPTION_TYPE ExceptionType, - EFI_SYSTEM_CONTEXT_IA32 *ContextRecord - ) -/*++ - -Routine Description: Common piece of code that invokes the registered handlers. - - This code executes in exception context so no efi calls are allowed. - -Arguments: - -Returns: - - None - ---*/ -// TODO: ExceptionType - add argument and description to function comment -// TODO: ContextRecord - add argument and description to function comment -{ - if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) { - if (ExceptionType != SYSTEM_TIMER_VECTOR) { - IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord); - } else { - OrigVector = IdtEntryTable[ExceptionType].OrigVector; - IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord); - } - } -} diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h b/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h deleted file mode 100644 index abb6967..0000000 --- a/EdkModulePkg/Universal/DebugSupport/Dxe/ia32/plDebugSupport.h +++ /dev/null @@ -1,312 +0,0 @@ -/*++ - -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - plDebugSupport.h - -Abstract: - - IA32 specific debug support macros, typedefs and prototypes. - -Revision History - ---*/ - -#ifndef _PLDEBUG_SUPPORT_H -#define _PLDEBUG_SUPPORT_H - -#define NUM_IDT_ENTRIES 0x78 -#define SYSTEM_TIMER_VECTOR 0x68 -#define VECTOR_ENTRY_PAGES 1 -#define CopyDescriptor(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR)) -#define ZeroDescriptor(Dest) CopyDescriptor ((Dest), &NullDesc) -#define ReadIdt(Vector, Dest) CopyDescriptor ((Dest), &((GetIdtr ())[(Vector)])) -#define WriteIdt(Vector, Src) CopyDescriptor (&((GetIdtr ())[(Vector)]), (Src)) -#define CompareDescriptor(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR)) -#define EFI_ISA IsaIa32 -#define FF_FXSR (1 << 24) - -typedef UINT64 DESCRIPTOR; - -typedef struct { - DESCRIPTOR OrigDesc; - VOID (*OrigVector) (VOID); - DESCRIPTOR NewDesc; - VOID (*StubEntry) (VOID); - VOID (*RegisteredCallback) (); -} IDT_ENTRY; - -extern EFI_SYSTEM_CONTEXT SystemContext; -extern UINT8 InterruptEntryStub[]; -extern UINT32 StubSize; -extern VOID (*OrigVector) (VOID); - -VOID -CommonIdtEntry ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -FxStorSupport ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -DESCRIPTOR * -GetIdtr ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -VOID -Vect2Desc ( - DESCRIPTOR * DestDesc, - VOID (*Vector) (VOID) - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - DestDesc - TODO: add argument description - ) - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -BOOLEAN -WriteInterruptFlag ( - BOOLEAN NewState - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - NewState - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -plInitializeDebugSupportDriver ( - VOID - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - None - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -plUnloadDebugSupportDriver ( - IN EFI_HANDLE ImageHandle - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - ImageHandle - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -// -// DebugSupport protocol member functions -// -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - MaxProcessorIndex - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - ProcessorIndex - TODO: add argument description - PeriodicCallback - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK NewCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - ProcessorIndex - TODO: add argument description - NewCallback - TODO: add argument description - ExceptionType - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -EFI_STATUS -EFIAPI -InvalidateInstructionCache ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN VOID *Start, - IN UINT64 Length - ) -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - This - TODO: add argument description - ProcessorIndex - TODO: add argument description - Start - TODO: add argument description - Length - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - -#endif -- cgit v1.1