Move SmmDebug feature from ASM to C.

SmmDebug feature is implemented in ASM, which is not easy to maintain.
So we move it to C function.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com>
Reviewed-by: "Kinney, Michael D" <michael.d.kinney@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18946 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Yao, Jiewen 2015-11-25 08:51:15 +00:00 committed by jyao1
parent 0b256fb1dd
commit f45f2d4ad4
5 changed files with 113 additions and 122 deletions

View File

@ -24,7 +24,6 @@ ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
ASM_GLOBAL ASM_PFX(gSmiCr3)
ASM_GLOBAL ASM_PFX(gSmiStack)
ASM_GLOBAL ASM_PFX(gSmbase)
ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
@ -148,43 +147,22 @@ L5:
# jmp _SmiHandler # instruction is not needed
_SmiHandler:
cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
jz L3
L6:
call L1
L1:
popl %ebp
movl $0x80000001, %eax
cpuid
btl $29, %edx # check cpuid to identify X64 or IA32
leal (0x7fc8 - (L1 - _SmiEntryPoint))(%ebp), %edi
leal 4(%edi), %esi
jnc L2
addl $4, %esi
L2:
movl (%esi), %ecx
movl (%edi), %edx
L7:
movl %ecx, %dr6
movl %edx, %dr7 # restore DR6 & DR7 before running C code
L3:
pushl (%esp)
movl (%esp), %ebx
pushl %ebx
movl $ASM_PFX(CpuSmmDebugEntry), %eax
call *%eax
popl %ecx
pushl %ebx
movl $ASM_PFX(SmiRendezvous), %eax
call *%eax
popl %ecx
cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
jz L4
movl %dr6, %ecx
movl %dr7, %edx
movl %ecx, (%esi)
movl %edx, (%edi)
L4:
pushl %ebx
movl $ASM_PFX(CpuSmmDebugExit), %eax
call *%eax
popl %ecx
rsm

View File

@ -34,14 +34,15 @@ PROTECT_MODE_CS EQU 08h
PROTECT_MODE_DS EQU 20h
TSS_SEGMENT EQU 40h
SmiRendezvous PROTO C
SmiRendezvous PROTO C
CpuSmmDebugEntry PROTO C
CpuSmmDebugExit PROTO C
EXTERNDEF gcSmiHandlerTemplate:BYTE
EXTERNDEF gcSmiHandlerSize:WORD
EXTERNDEF gSmiCr3:DWORD
EXTERNDEF gSmiStack:DWORD
EXTERNDEF gSmbase:DWORD
EXTERNDEF FeaturePcdGet (PcdCpuSmmDebug):BYTE
EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE
EXTERNDEF gSmiHandlerIdtr:FWORD
@ -151,40 +152,23 @@ gSmiCr3 DD ?
; jmp _SmiHandler ; instruction is not needed
_SmiHandler PROC
cmp FeaturePcdGet (PcdCpuSmmDebug), 0
jz @3
call @1
@1:
pop ebp
mov eax, 80000001h
cpuid
bt edx, 29 ; check cpuid to identify X64 or IA32
lea edi, [ebp - (@1 - _SmiEntryPoint) + 7fc8h]
lea esi, [edi + 4]
jnc @2
add esi, 4
@2:
mov ecx, [esi]
mov edx, [edi]
@5:
mov dr6, ecx
mov dr7, edx ; restore DR6 & DR7 before running C code
@3:
mov ecx, [esp] ; CPU Index
mov ebx, [esp] ; CPU Index
push ecx
mov eax, SmiRendezvous
push ebx
mov eax, CpuSmmDebugEntry
call eax
pop ecx
cmp FeaturePcdGet (PcdCpuSmmDebug), 0
jz @4
push ebx
mov eax, SmiRendezvous
call eax
pop ecx
push ebx
mov eax, CpuSmmDebugExit
call eax
pop ecx
mov ecx, dr6
mov edx, dr7
mov [esi], ecx
mov [edi], edx
@4:
rsm
_SmiHandler ENDP

View File

@ -940,6 +940,65 @@ SmmStartupThisAp (
return EFI_SUCCESS;
}
/**
This funciton sets DR6 & DR7 according to SMM save state, before running SMM C code.
They are useful when you want to enable hardware breakpoints in SMM without entry SMM mode.
NOTE: It might not be appreciated in runtime since it might
conflict with OS debugging facilities. Turn them off in RELEASE.
@param CpuIndex CPU Index
**/
VOID
EFIAPI
CpuSmmDebugEntry (
IN UINTN CpuIndex
)
{
SMRAM_SAVE_STATE_MAP *CpuSaveState;
if (FeaturePcdGet (PcdCpuSmmDebug)) {
CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
AsmWriteDr6 (CpuSaveState->x86._DR6);
AsmWriteDr7 (CpuSaveState->x86._DR7);
} else {
AsmWriteDr6 ((UINTN)CpuSaveState->x64._DR6);
AsmWriteDr7 ((UINTN)CpuSaveState->x64._DR7);
}
}
}
/**
This funciton restores DR6 & DR7 to SMM save state.
NOTE: It might not be appreciated in runtime since it might
conflict with OS debugging facilities. Turn them off in RELEASE.
@param CpuIndex CPU Index
**/
VOID
EFIAPI
CpuSmmDebugExit (
IN UINTN CpuIndex
)
{
SMRAM_SAVE_STATE_MAP *CpuSaveState;
if (FeaturePcdGet (PcdCpuSmmDebug)) {
CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];
if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
CpuSaveState->x86._DR7 = (UINT32)AsmReadDr7 ();
CpuSaveState->x86._DR6 = (UINT32)AsmReadDr6 ();
} else {
CpuSaveState->x64._DR7 = AsmReadDr7 ();
CpuSaveState->x64._DR6 = AsmReadDr6 ();
}
}
}
/**
C function for SMI entry, each processor comes here upon SMI trigger.

View File

@ -24,7 +24,6 @@ ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
ASM_GLOBAL ASM_PFX(gSmiCr3)
ASM_GLOBAL ASM_PFX(gSmiStack)
ASM_GLOBAL ASM_PFX(gSmbase)
ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
#
@ -163,20 +162,7 @@ LongMode: # long mode (64-bit code) starts here
# jmp _SmiHandler ; instruction is not needed
_SmiHandler:
movabsq $ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug)), %rax
cmpb $0, (%rax)
jz L1
.byte 0x48, 0x8b, 0x0d # mov rcx, [rip + disp32]
.long SSM_DR6 - (. + 4 - _SmiEntryPoint + 0x8000)
.byte 0x48, 0x8b, 0x15 # mov rdx, [rip + disp32]
.long SSM_DR7 - (. + 4 - _SmiEntryPoint + 0x8000)
movq %rcx, %dr6
movq %rdx, %dr7
L1:
movabsq $ASM_PFX(SmiRendezvous), %rax
movq (%rsp), %rcx
movq (%rsp), %rbx
# Save FP registers
subq $0x208, %rsp
@ -184,7 +170,19 @@ L1:
fxsave (%rsp)
addq $-0x20, %rsp
movq %rbx, %rcx
movabsq $ASM_PFX(CpuSmmDebugEntry), %rax
call *%rax
movq %rbx, %rcx
movabsq $ASM_PFX(SmiRendezvous), %rax
call *%rax
movq %rbx, %rcx
movabsq $ASM_PFX(CpuSmmDebugExit), %rax
call *%rax
addq $0x20, %rsp
#
@ -193,17 +191,6 @@ L1:
.byte 0x48 # FXRSTOR64
fxrstor (%rsp)
movabsq $ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug)), %rax
cmpb $0, (%rax)
jz L2
movq %dr7, %rdx
movq %dr6, %rcx
.byte 0x48, 0x89, 0x15 # mov [rip + disp32], rdx
.long SSM_DR7 - (. + 4 - _SmiEntryPoint + 0x8000)
.byte 0x48, 0x89, 0x0d # mov [rip + disp32], rcx
.long SSM_DR6 - (. + 4 - _SmiEntryPoint + 0x8000)
L2:
rsm
ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint

View File

@ -22,12 +22,13 @@
; Variables referenced by C code
;
EXTERNDEF SmiRendezvous:PROC
EXTERNDEF CpuSmmDebugEntry:PROC
EXTERNDEF CpuSmmDebugExit:PROC
EXTERNDEF gcSmiHandlerTemplate:BYTE
EXTERNDEF gcSmiHandlerSize:WORD
EXTERNDEF gSmiCr3:DWORD
EXTERNDEF gSmiStack:DWORD
EXTERNDEF gSmbase:DWORD
EXTERNDEF FeaturePcdGet (PcdCpuSmmDebug):BYTE
EXTERNDEF gSmiHandlerIdtr:FWORD
@ -157,26 +158,7 @@ Base:
; jmp _SmiHandler ; instruction is not needed
_SmiHandler:
;
; The following lines restore DR6 & DR7 before running C code. They are useful
; when you want to enable hardware breakpoints in SMM.
;
; NOTE: These lines might not be appreciated in runtime since they might
; conflict with OS debugging facilities. Turn them off in RELEASE.
;
mov rax, offset FeaturePcdGet (PcdCpuSmmDebug) ;Get absolute address. Avoid RIP relative addressing
cmp byte ptr [rax], 0
jz @1
DB 48h, 8bh, 0dh ; mov rcx, [rip + disp32]
DD SSM_DR6 - ($ + 4 - _SmiEntryPoint + 8000h)
DB 48h, 8bh, 15h ; mov rdx, [rip + disp32]
DD SSM_DR7 - ($ + 4 - _SmiEntryPoint + 8000h)
mov dr6, rcx
mov dr7, rdx
@1:
mov rcx, [rsp] ; rcx <- CpuIndex
mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
mov rbx, [rsp] ; rbx <- CpuIndex
;
; Save FP registers
@ -186,7 +168,19 @@ _SmiHandler:
fxsave [rsp]
add rsp, -20h
mov rcx, rbx
mov rax, CpuSmmDebugEntry
call rax
mov rcx, rbx
mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
call rax
mov rcx, rbx
mov rax, CpuSmmDebugExit
call rax
add rsp, 20h
;
@ -195,17 +189,6 @@ _SmiHandler:
DB 48h ; FXRSTOR64
fxrstor [rsp]
mov rax, offset FeaturePcdGet (PcdCpuSmmDebug) ;Get absolute address. Avoid RIP relative addressing
cmp byte ptr [rax], 0
jz @2
mov rdx, dr7
mov rcx, dr6
DB 48h, 89h, 15h ; mov [rip + disp32], rdx
DD SSM_DR7 - ($ + 4 - _SmiEntryPoint + 8000h)
DB 48h, 89h, 0dh ; mov [rip + disp32], rcx
DD SSM_DR6 - ($ + 4 - _SmiEntryPoint + 8000h)
@2:
rsm
gcSmiHandlerSize DW $ - _SmiEntryPoint