asmfuncs.asm
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· 汇编 代码 · 共 562 行 · 第 1/2 页
ASM
562 行
;******************************************************************************
;*
;* Copyright (c) 2004 - 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_IA32 FxSaveState; // 512 bytes, must be 16 byte aligned
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
;; UINT32 EFlags;
;; UINT32 Ldtr, Tr;
;; UINT32 Gdtr[2], Idtr[2];
;; UINT32 Eip;
;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
;; 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
;------------------------------------------------------------------------------
; VOID
; EfiWbinvd (
; VOID
; )
;
; Abstract: Writeback and invalidate cache
;
EfiWbinvd PROC PUBLIC
wbinvd
ret
EfiWbinvd ENDP
;------------------------------------------------------------------------------
; 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 dx, cs
mov word ptr [ecx+2], dx ; 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_IA32 FxSaveState;
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
;; UINT32 Cr0, Cr2, Cr3, Cr4;
;; UINT32 EFlags;
;; UINT32 Ldtr, Tr;
;; UINT32 Gdtr[2], Idtr[2];
;; UINT32 Eip;
;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
;; 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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?