mirror of
https://github.com/acidanthera/audk.git
synced 2025-05-04 14:40:11 +02:00
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3790 Replace Opcode with the corresponding instructions. The code changes have been verified with CompareBuild.py tool, which can be used to compare the results of two different EDK II builds to determine if they generate the same binaries. (tool link: https://github.com/mdkinney/edk2/tree/sandbox/CompareBuild) Signed-off-by: Jason Lou <yun.lou@intel.com> Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
414 lines
9.5 KiB
NASM
414 lines
9.5 KiB
NASM
;------------------------------------------------------------------------------
|
|
;
|
|
; Copyright (c) 2010 - 2022, Intel Corporation. All rights reserved.<BR>
|
|
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
;
|
|
; Module Name:
|
|
;
|
|
; AsmFuncs.nasm
|
|
;
|
|
; Abstract:
|
|
;
|
|
; Debug interrupt handle functions.
|
|
;
|
|
;------------------------------------------------------------------------------
|
|
|
|
#include "DebugException.h"
|
|
|
|
;
|
|
; InterruptProcess()
|
|
;
|
|
extern ASM_PFX(InterruptProcess)
|
|
|
|
global ASM_PFX(Exception0Handle)
|
|
global ASM_PFX(TimerInterruptHandle)
|
|
global ASM_PFX(ExceptionStubHeaderSize)
|
|
|
|
%macro AGENT_HANDLER_SIGNATURE 0
|
|
db 0x41, 0x47, 0x54, 0x48 ; SIGNATURE_32('A','G','T','H')
|
|
%endmacro
|
|
|
|
SECTION .data
|
|
|
|
ASM_PFX(ExceptionStubHeaderSize): DD Exception1Handle - ASM_PFX(Exception0Handle)
|
|
CommonEntryAddr: DD CommonEntry
|
|
|
|
SECTION .text
|
|
|
|
AGENT_HANDLER_SIGNATURE
|
|
ASM_PFX(Exception0Handle):
|
|
cli
|
|
push eax
|
|
mov eax, 0
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception1Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 1
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception2Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 2
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception3Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 3
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception4Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 4
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception5Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 5
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception6Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 6
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception7Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 7
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception8Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 8
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception9Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 9
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception10Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 10
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception11Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 11
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception12Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 12
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception13Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 13
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception14Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 14
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception15Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 15
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception16Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 16
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception17Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 17
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception18Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 18
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
Exception19Handle:
|
|
cli
|
|
push eax
|
|
mov eax, 19
|
|
jmp dword [CommonEntryAddr]
|
|
AGENT_HANDLER_SIGNATURE
|
|
ASM_PFX(TimerInterruptHandle):
|
|
cli
|
|
push eax
|
|
mov eax, 32
|
|
jmp dword [CommonEntryAddr]
|
|
|
|
CommonEntry:
|
|
;
|
|
; +---------------------+
|
|
; + EFlags +
|
|
; +---------------------+
|
|
; + CS +
|
|
; +---------------------+
|
|
; + EIP +
|
|
; +---------------------+
|
|
; + Error Code +
|
|
; +---------------------+
|
|
; + EAX / Vector Number +
|
|
; +---------------------+
|
|
; + EBP +
|
|
; +---------------------+ <-- EBP
|
|
;
|
|
cmp eax, DEBUG_EXCEPT_DOUBLE_FAULT
|
|
je NoExtrPush
|
|
cmp eax, DEBUG_EXCEPT_INVALID_TSS
|
|
je NoExtrPush
|
|
cmp eax, DEBUG_EXCEPT_SEG_NOT_PRESENT
|
|
je NoExtrPush
|
|
cmp eax, DEBUG_EXCEPT_STACK_FAULT
|
|
je NoExtrPush
|
|
cmp eax, DEBUG_EXCEPT_GP_FAULT
|
|
je NoExtrPush
|
|
cmp eax, DEBUG_EXCEPT_PAGE_FAULT
|
|
je NoExtrPush
|
|
cmp eax, DEBUG_EXCEPT_ALIGNMENT_CHECK
|
|
je NoExtrPush
|
|
|
|
push dword [esp]
|
|
mov dword [esp + 4], 0
|
|
|
|
NoExtrPush:
|
|
|
|
push ebp
|
|
mov ebp, esp ; save esp in ebp
|
|
;
|
|
; Make stack 16-byte alignment to make sure save fxrstor later
|
|
;
|
|
and esp, 0xfffffff0
|
|
sub esp, 12
|
|
|
|
; store UINT32 Edi, Esi, Ebp, Ebx, Edx, Ecx, Eax;
|
|
push dword [ebp + 4] ; original eax
|
|
push ebx
|
|
push ecx
|
|
push edx
|
|
mov ebx, eax ; save vector in ebx
|
|
mov eax, ebp
|
|
add eax, 4 * 6
|
|
push eax ; original ESP
|
|
push dword [ebp] ; EBP
|
|
push esi
|
|
push edi
|
|
|
|
;; 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, 1
|
|
push ebx ; temporarily save value of ebx on stack
|
|
cpuid ; use CPUID to determine if FXSAVE/FXRESTOR and
|
|
; DE are supported
|
|
pop ebx ; restore value of ebx that was overwritten by CPUID
|
|
mov eax, cr4
|
|
push eax ; push cr4 firstly
|
|
test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
|
|
jz .0
|
|
or eax, BIT9 ; Set CR4.OSFXSR
|
|
.0:
|
|
test edx, BIT2 ; Test for Debugging Extensions support
|
|
jz .1
|
|
or eax, BIT3 ; Set CR4.DE
|
|
.1:
|
|
mov cr4, eax
|
|
mov eax, cr3
|
|
push eax
|
|
mov eax, cr2
|
|
push eax
|
|
push 0 ; cr0 will not saved???
|
|
mov eax, cr0
|
|
push eax
|
|
|
|
xor ecx, ecx
|
|
mov ecx, Ss
|
|
push ecx
|
|
mov ecx, Cs
|
|
push ecx
|
|
mov ecx, Ds
|
|
push ecx
|
|
mov ecx, Es
|
|
push ecx
|
|
mov ecx, Fs
|
|
push ecx
|
|
mov ecx, Gs
|
|
push ecx
|
|
|
|
;; EIP
|
|
mov ecx, [ebp + 4 * 3] ; EIP
|
|
push ecx
|
|
|
|
;; UINT32 Gdtr[2], Idtr[2];
|
|
sub esp, 8
|
|
sidt [esp]
|
|
sub esp, 8
|
|
sgdt [esp]
|
|
|
|
;; UINT32 Ldtr, Tr;
|
|
xor eax, eax
|
|
str ax
|
|
push eax
|
|
sldt ax
|
|
push eax
|
|
|
|
;; EFlags
|
|
mov ecx, [ebp + 4 * 5]
|
|
push ecx
|
|
|
|
;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
|
|
mov eax, dr7
|
|
push eax
|
|
|
|
;; clear Dr7 while executing debugger itself
|
|
xor eax, eax
|
|
mov dr7, eax
|
|
|
|
;; Dr6
|
|
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
|
|
|
|
;; Clear Direction Flag
|
|
cld
|
|
|
|
;; FX_SAVE_STATE_IA32 FxSaveState;
|
|
sub esp, 512
|
|
mov edi, esp
|
|
;; Clear the buffer
|
|
xor eax, eax
|
|
mov ecx, 128 ;= 512 / 4
|
|
rep stosd
|
|
mov edi, esp
|
|
|
|
test edx, BIT24 ; Test for FXSAVE/FXRESTOR support.
|
|
; edx still contains result from CPUID above
|
|
jz .2
|
|
fxsave [edi]
|
|
.2:
|
|
|
|
;; save the exception data
|
|
push dword [ebp + 8]
|
|
|
|
; call the C interrupt process function
|
|
push esp ; Structure
|
|
push ebx ; vector
|
|
call ASM_PFX(InterruptProcess)
|
|
add esp, 8
|
|
|
|
; skip the exception data
|
|
add esp, 4
|
|
|
|
;; FX_SAVE_STATE_IA32 FxSaveState;
|
|
mov esi, esp
|
|
mov eax, 1
|
|
cpuid ; use CPUID to determine if FXSAVE/FXRESTOR are supported
|
|
test edx, BIT24 ; Test for FXSAVE/FXRESTOR support
|
|
jz .3
|
|
fxrstor [esi]
|
|
.3:
|
|
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
|
|
|
|
;; set EFlags
|
|
pop dword [ebp + 4 * 5] ; set EFLAGS in stack
|
|
|
|
;; UINT32 Ldtr, Tr;
|
|
;; UINT32 Gdtr[2], Idtr[2];
|
|
;; Best not let anyone mess with these particular registers...
|
|
add esp, 24
|
|
|
|
;; UINT32 Eip;
|
|
pop dword [ebp + 4 * 3] ; set EIP in stack
|
|
|
|
;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
|
|
;; 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 dword [ebp + 4 * 4] ; set CS in stack
|
|
pop ss
|
|
|
|
;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
|
|
pop eax
|
|
mov cr0, eax
|
|
add esp, 4 ; skip for Cr1
|
|
pop eax
|
|
mov cr2, eax
|
|
pop eax
|
|
mov cr3, eax
|
|
pop eax
|
|
mov cr4, eax
|
|
|
|
;; restore general register
|
|
pop edi
|
|
pop esi
|
|
pop dword [ebp] ; save updated ebp
|
|
pop dword [ebp + 4] ; save updated esp
|
|
pop edx
|
|
pop ecx
|
|
pop ebx
|
|
pop eax
|
|
|
|
mov esp, ebp
|
|
pop ebp ; restore ebp maybe updated
|
|
pop esp ; restore esp maybe updated
|
|
sub esp, 4 * 3 ; restore interrupt pushced stack
|
|
|
|
iretd
|
|
|