From: Yao, Jiewen Date: Wed, 25 Nov 2015 08:51:15 +0000 (+0000) Subject: Move SmmDebug feature from ASM to C. X-Git-Tag: edk2-stable201903~8514 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=f45f2d4ad4d803eb33c608bca8242992f1841fec 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" Reviewed-by: "Kinney, Michael D" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18946 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S index 6fcf41a677..fbaa0725f0 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S @@ -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 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm index b628fe8bd8..8a12927300 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm @@ -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 - - push ecx - mov eax, SmiRendezvous + mov ebx, [esp] ; CPU Index + + 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 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c index 3e8b0936aa..83f5bf962d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c @@ -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. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S index 95e6dfa814..b488b74b70 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S @@ -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 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm index 4d53db5b00..4f5c03c5cf 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm @@ -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