ASM_GLOBAL ASM_PFX(gSmiCr3)\r
ASM_GLOBAL ASM_PFX(gSmiStack)\r
ASM_GLOBAL ASM_PFX(gSmbase)\r
-ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))\r
ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)\r
\r
# jmp _SmiHandler # instruction is not needed\r
\r
_SmiHandler:\r
- cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))\r
- jz L3\r
-\r
-L6:\r
- call L1\r
-L1:\r
- popl %ebp\r
- movl $0x80000001, %eax\r
- cpuid\r
- btl $29, %edx # check cpuid to identify X64 or IA32\r
- leal (0x7fc8 - (L1 - _SmiEntryPoint))(%ebp), %edi\r
- leal 4(%edi), %esi\r
- jnc L2\r
- addl $4, %esi\r
-L2:\r
- movl (%esi), %ecx\r
- movl (%edi), %edx\r
-L7:\r
- movl %ecx, %dr6\r
- movl %edx, %dr7 # restore DR6 & DR7 before running C code\r
-L3:\r
-\r
- pushl (%esp)\r
+ movl (%esp), %ebx\r
\r
+ pushl %ebx\r
+ movl $ASM_PFX(CpuSmmDebugEntry), %eax\r
+ call *%eax\r
+ popl %ecx\r
+ \r
+ pushl %ebx\r
movl $ASM_PFX(SmiRendezvous), %eax\r
call *%eax\r
popl %ecx\r
\r
-\r
- cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))\r
- jz L4\r
-\r
- movl %dr6, %ecx\r
- movl %dr7, %edx\r
- movl %ecx, (%esi)\r
- movl %edx, (%edi)\r
-L4:\r
+ pushl %ebx\r
+ movl $ASM_PFX(CpuSmmDebugExit), %eax\r
+ call *%eax\r
+ popl %ecx\r
\r
rsm\r
\r
PROTECT_MODE_DS EQU 20h\r
TSS_SEGMENT EQU 40h\r
\r
-SmiRendezvous PROTO C\r
+SmiRendezvous PROTO C\r
+CpuSmmDebugEntry PROTO C\r
+CpuSmmDebugExit PROTO C\r
\r
EXTERNDEF gcSmiHandlerTemplate:BYTE\r
EXTERNDEF gcSmiHandlerSize:WORD\r
EXTERNDEF gSmiCr3:DWORD\r
EXTERNDEF gSmiStack:DWORD\r
EXTERNDEF gSmbase:DWORD\r
-EXTERNDEF FeaturePcdGet (PcdCpuSmmDebug):BYTE\r
EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE\r
EXTERNDEF gSmiHandlerIdtr:FWORD\r
\r
; jmp _SmiHandler ; instruction is not needed\r
\r
_SmiHandler PROC\r
- cmp FeaturePcdGet (PcdCpuSmmDebug), 0\r
- jz @3\r
- call @1\r
-@1:\r
- pop ebp\r
- mov eax, 80000001h\r
- cpuid\r
- bt edx, 29 ; check cpuid to identify X64 or IA32\r
- lea edi, [ebp - (@1 - _SmiEntryPoint) + 7fc8h]\r
- lea esi, [edi + 4]\r
- jnc @2\r
- add esi, 4\r
-@2:\r
- mov ecx, [esi]\r
- mov edx, [edi]\r
-@5:\r
- mov dr6, ecx\r
- mov dr7, edx ; restore DR6 & DR7 before running C code\r
-@3:\r
- mov ecx, [esp] ; CPU Index\r
-\r
- push ecx\r
- mov eax, SmiRendezvous\r
+ mov ebx, [esp] ; CPU Index\r
+\r
+ push ebx\r
+ mov eax, CpuSmmDebugEntry\r
call eax\r
pop ecx\r
\r
- cmp FeaturePcdGet (PcdCpuSmmDebug), 0\r
- jz @4\r
+ push ebx\r
+ mov eax, SmiRendezvous\r
+ call eax\r
+ pop ecx\r
+ \r
+ push ebx\r
+ mov eax, CpuSmmDebugExit\r
+ call eax\r
+ pop ecx\r
\r
- mov ecx, dr6\r
- mov edx, dr7\r
- mov [esi], ecx\r
- mov [edi], edx\r
-@4:\r
rsm\r
_SmiHandler ENDP\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This funciton sets DR6 & DR7 according to SMM save state, before running SMM C code.\r
+ They are useful when you want to enable hardware breakpoints in SMM without entry SMM mode.\r
+\r
+ NOTE: It might not be appreciated in runtime since it might\r
+ conflict with OS debugging facilities. Turn them off in RELEASE.\r
+\r
+ @param CpuIndex CPU Index\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuSmmDebugEntry (\r
+ IN UINTN CpuIndex\r
+ )\r
+{\r
+ SMRAM_SAVE_STATE_MAP *CpuSaveState;\r
+ \r
+ if (FeaturePcdGet (PcdCpuSmmDebug)) {\r
+ CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];\r
+ if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {\r
+ AsmWriteDr6 (CpuSaveState->x86._DR6);\r
+ AsmWriteDr7 (CpuSaveState->x86._DR7);\r
+ } else {\r
+ AsmWriteDr6 ((UINTN)CpuSaveState->x64._DR6);\r
+ AsmWriteDr7 ((UINTN)CpuSaveState->x64._DR7);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ This funciton restores DR6 & DR7 to SMM save state.\r
+\r
+ NOTE: It might not be appreciated in runtime since it might\r
+ conflict with OS debugging facilities. Turn them off in RELEASE.\r
+\r
+ @param CpuIndex CPU Index\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuSmmDebugExit (\r
+ IN UINTN CpuIndex\r
+ )\r
+{\r
+ SMRAM_SAVE_STATE_MAP *CpuSaveState;\r
+\r
+ if (FeaturePcdGet (PcdCpuSmmDebug)) {\r
+ CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuIndex];\r
+ if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {\r
+ CpuSaveState->x86._DR7 = (UINT32)AsmReadDr7 ();\r
+ CpuSaveState->x86._DR6 = (UINT32)AsmReadDr6 ();\r
+ } else {\r
+ CpuSaveState->x64._DR7 = AsmReadDr7 ();\r
+ CpuSaveState->x64._DR6 = AsmReadDr6 ();\r
+ }\r
+ }\r
+}\r
+\r
/**\r
C function for SMI entry, each processor comes here upon SMI trigger.\r
\r
ASM_GLOBAL ASM_PFX(gSmiCr3)\r
ASM_GLOBAL ASM_PFX(gSmiStack)\r
ASM_GLOBAL ASM_PFX(gSmbase)\r
-ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))\r
ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)\r
\r
#\r
# jmp _SmiHandler ; instruction is not needed\r
\r
_SmiHandler:\r
- movabsq $ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug)), %rax\r
- cmpb $0, (%rax)\r
- jz L1\r
-\r
- .byte 0x48, 0x8b, 0x0d # mov rcx, [rip + disp32]\r
- .long SSM_DR6 - (. + 4 - _SmiEntryPoint + 0x8000)\r
- .byte 0x48, 0x8b, 0x15 # mov rdx, [rip + disp32]\r
- .long SSM_DR7 - (. + 4 - _SmiEntryPoint + 0x8000)\r
- movq %rcx, %dr6\r
- movq %rdx, %dr7\r
-L1:\r
-\r
- movabsq $ASM_PFX(SmiRendezvous), %rax\r
- movq (%rsp), %rcx\r
+ movq (%rsp), %rbx\r
# Save FP registers\r
\r
subq $0x208, %rsp\r
fxsave (%rsp)\r
\r
addq $-0x20, %rsp\r
+\r
+ movq %rbx, %rcx\r
+ movabsq $ASM_PFX(CpuSmmDebugEntry), %rax\r
call *%rax\r
+\r
+ movq %rbx, %rcx\r
+ movabsq $ASM_PFX(SmiRendezvous), %rax\r
+ call *%rax\r
+\r
+ movq %rbx, %rcx\r
+ movabsq $ASM_PFX(CpuSmmDebugExit), %rax\r
+ call *%rax\r
+\r
addq $0x20, %rsp\r
\r
#\r
.byte 0x48 # FXRSTOR64\r
fxrstor (%rsp)\r
\r
- movabsq $ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug)), %rax\r
- cmpb $0, (%rax)\r
- jz L2\r
-\r
- movq %dr7, %rdx\r
- movq %dr6, %rcx\r
- .byte 0x48, 0x89, 0x15 # mov [rip + disp32], rdx\r
- .long SSM_DR7 - (. + 4 - _SmiEntryPoint + 0x8000)\r
- .byte 0x48, 0x89, 0x0d # mov [rip + disp32], rcx\r
- .long SSM_DR6 - (. + 4 - _SmiEntryPoint + 0x8000)\r
-L2:\r
rsm\r
\r
ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint\r
; Variables referenced by C code\r
;\r
EXTERNDEF SmiRendezvous:PROC\r
+EXTERNDEF CpuSmmDebugEntry:PROC\r
+EXTERNDEF CpuSmmDebugExit:PROC\r
EXTERNDEF gcSmiHandlerTemplate:BYTE\r
EXTERNDEF gcSmiHandlerSize:WORD\r
EXTERNDEF gSmiCr3:DWORD\r
EXTERNDEF gSmiStack:DWORD\r
EXTERNDEF gSmbase:DWORD\r
-EXTERNDEF FeaturePcdGet (PcdCpuSmmDebug):BYTE\r
EXTERNDEF gSmiHandlerIdtr:FWORD\r
\r
\r
; jmp _SmiHandler ; instruction is not needed\r
\r
_SmiHandler:\r
-;\r
-; The following lines restore DR6 & DR7 before running C code. They are useful\r
-; when you want to enable hardware breakpoints in SMM.\r
-;\r
-; NOTE: These lines might not be appreciated in runtime since they might\r
-; conflict with OS debugging facilities. Turn them off in RELEASE.\r
-;\r
- mov rax, offset FeaturePcdGet (PcdCpuSmmDebug) ;Get absolute address. Avoid RIP relative addressing\r
- cmp byte ptr [rax], 0\r
- jz @1\r
-\r
- DB 48h, 8bh, 0dh ; mov rcx, [rip + disp32]\r
- DD SSM_DR6 - ($ + 4 - _SmiEntryPoint + 8000h)\r
- DB 48h, 8bh, 15h ; mov rdx, [rip + disp32]\r
- DD SSM_DR7 - ($ + 4 - _SmiEntryPoint + 8000h)\r
- mov dr6, rcx\r
- mov dr7, rdx\r
-@1:\r
- mov rcx, [rsp] ; rcx <- CpuIndex\r
- mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous\r
+ mov rbx, [rsp] ; rbx <- CpuIndex\r
\r
;\r
; Save FP registers\r
fxsave [rsp]\r
\r
add rsp, -20h\r
+\r
+ mov rcx, rbx\r
+ mov rax, CpuSmmDebugEntry\r
+ call rax\r
+ \r
+ mov rcx, rbx\r
+ mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous\r
+ call rax\r
+ \r
+ mov rcx, rbx\r
+ mov rax, CpuSmmDebugExit\r
call rax\r
+ \r
add rsp, 20h\r
\r
;\r
DB 48h ; FXRSTOR64\r
fxrstor [rsp]\r
\r
- mov rax, offset FeaturePcdGet (PcdCpuSmmDebug) ;Get absolute address. Avoid RIP relative addressing\r
- cmp byte ptr [rax], 0\r
- jz @2\r
-\r
- mov rdx, dr7\r
- mov rcx, dr6\r
- DB 48h, 89h, 15h ; mov [rip + disp32], rdx\r
- DD SSM_DR7 - ($ + 4 - _SmiEntryPoint + 8000h)\r
- DB 48h, 89h, 0dh ; mov [rip + disp32], rcx\r
- DD SSM_DR6 - ($ + 4 - _SmiEntryPoint + 8000h)\r
-@2:\r
rsm\r
\r
gcSmiHandlerSize DW $ - _SmiEntryPoint\r