+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# MpFuncs.S\r
-#\r
-# Abstract:\r
-#\r
-# This is the assembly code for Multi-processor S3 support\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-.equ VacantFlag, 0x0\r
-.equ NotVacantFlag, 0xff\r
-\r
-.equ LockLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
-.equ StackStart, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x04\r
-.equ StackSize, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08\r
-.equ RendezvousProc, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x0C\r
-.equ GdtrProfile, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10\r
-.equ IdtrProfile, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16\r
-.equ BufferStart, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x1C\r
-\r
-#-------------------------------------------------------------------------------------\r
-#RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
-#procedure serializes all the AP processors through an Init sequence. It must be\r
-#noted that APs arrive here very raw...ie: real mode, no stack.\r
-#ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
-#IS IN MACHINE CODE.\r
-#-------------------------------------------------------------------------------------\r
-#RendezvousFunnelProc (&WakeUpBuffer,MemAddress);\r
-\r
-ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)\r
-ASM_PFX(RendezvousFunnelProc):\r
-RendezvousFunnelProcStart:\r
-\r
-# At this point CS = 0x(vv00) and ip= 0x0.\r
-\r
- .byte 0x8c,0xc8 # mov ax, cs\r
- .byte 0x8e,0xd8 # mov ds, ax\r
- .byte 0x8e,0xc0 # mov es, ax\r
- .byte 0x8e,0xd0 # mov ss, ax\r
- .byte 0x33,0xc0 # xor ax, ax\r
- .byte 0x8e,0xe0 # mov fs, ax\r
- .byte 0x8e,0xe8 # mov gs, ax\r
-\r
-flat32Start:\r
-\r
- .byte 0xBE\r
- .word BufferStart\r
- .byte 0x66,0x8B,0x14 # mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer\r
-\r
- .byte 0xBE\r
- .word GdtrProfile\r
- .byte 0x66 # db 66h\r
- .byte 0x2E,0xF,0x1,0x14 # lgdt fword ptr cs:[si]\r
-\r
- .byte 0xBE\r
- .word IdtrProfile\r
- .byte 0x66 # db 66h\r
- .byte 0x2E,0xF,0x1,0x1C # lidt fword ptr cs:[si]\r
-\r
- .byte 0x33,0xC0 # xor ax, ax\r
- .byte 0x8E,0xD8 # mov ds, ax\r
-\r
- .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Get control register 0\r
- .byte 0x66,0x83,0xC8,0x1 # or eax, 000000001h ; Set PE bit (bit #0)\r
- .byte 0xF,0x22,0xC0 # mov cr0, eax\r
-\r
-FLAT32_JUMP:\r
-\r
- .byte 0x66,0x67,0xEA # far jump\r
- .long 0x0 # 32-bit offset\r
- .word 0x20 # 16-bit selector\r
-\r
-PMODE_ENTRY: # protected mode entry point\r
-\r
- movw $0x8,%ax\r
- .byte 0x66\r
- movw %ax,%ds\r
- .byte 0x66\r
- movw %ax,%es\r
- .byte 0x66\r
- movw %ax,%fs\r
- .byte 0x66\r
- movw %ax,%gs\r
- .byte 0x66\r
- movw %ax,%ss # Flat mode setup.\r
-\r
- movl %edx,%esi\r
-\r
- movl %esi,%edi\r
- addl $LockLocation, %edi\r
- movb $NotVacantFlag, %al\r
-TestLock:\r
- xchgb (%edi), %al\r
- cmpb $NotVacantFlag, %al\r
- jz TestLock\r
-\r
-ProgramStack:\r
-\r
- movl %esi,%edi\r
- addl $StackSize, %edi\r
- movl (%edi),%eax\r
- movl %esi,%edi\r
- addl $StackStart, %edi\r
- addl (%edi),%eax\r
- movl %eax,%esp\r
- movl %eax,(%edi)\r
-\r
-Releaselock:\r
-\r
- movb $VacantFlag, %al\r
- movl %esi,%edi\r
- addl $LockLocation, %edi\r
- xchgb (%edi), %al\r
-\r
- #\r
- # Call assembly function to initialize FPU.\r
- #\r
- lea ASM_PFX(InitializeFloatingPointUnits), %ebx\r
- call *%ebx\r
- #\r
- # Call C Function\r
- #\r
- movl %esi,%edi\r
- addl $RendezvousProc, %edi\r
- movl (%edi),%eax\r
-\r
- testl %eax,%eax\r
- jz GoToSleep\r
- call *%eax # Call C function\r
-\r
-GoToSleep:\r
- cli\r
- hlt\r
- jmp GoToSleep\r
-\r
-RendezvousFunnelProcEnd:\r
-#-------------------------------------------------------------------------------------\r
-# AsmGetAddressMap (&AddressMap);\r
-#-------------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(AsmGetAddressMap)\r
-ASM_PFX(AsmGetAddressMap):\r
-\r
- pushal\r
- movl %esp,%ebp\r
-\r
- movl 0x24(%ebp), %ebx\r
- movl $RendezvousFunnelProcStart, (%ebx)\r
- movl $(PMODE_ENTRY - RendezvousFunnelProcStart), 0x4(%ebx)\r
- movl $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x8(%ebx)\r
- movl $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x0c(%ebx)\r
-\r
- popal\r
- ret\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; MpFuncs.asm\r
-;\r
-; Abstract:\r
-;\r
-; This is the assembly code for Multi-processor S3 support\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
-.686p\r
-.model flat,C\r
-.code\r
-\r
-EXTERN InitializeFloatingPointUnits:PROC\r
-\r
-VacantFlag Equ 00h\r
-NotVacantFlag Equ 0ffh\r
-\r
-LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
-StackStart equ LockLocation + 4h\r
-StackSize equ LockLocation + 8h\r
-RendezvousProc equ LockLocation + 0Ch\r
-GdtrProfile equ LockLocation + 10h\r
-IdtrProfile equ LockLocation + 16h\r
-BufferStart equ LockLocation + 1Ch\r
-\r
-;-------------------------------------------------------------------------------------\r
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
-;procedure serializes all the AP processors through an Init sequence. It must be\r
-;noted that APs arrive here very raw...ie: real mode, no stack.\r
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
-;IS IN MACHINE CODE.\r
-;-------------------------------------------------------------------------------------\r
-;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);\r
-\r
-RendezvousFunnelProc PROC near C PUBLIC\r
-RendezvousFunnelProcStart::\r
-\r
-; At this point CS = 0x(vv00) and ip= 0x0.\r
-\r
- db 8ch, 0c8h ; mov ax, cs\r
- db 8eh, 0d8h ; mov ds, ax\r
- db 8eh, 0c0h ; mov es, ax\r
- db 8eh, 0d0h ; mov ss, ax\r
- db 33h, 0c0h ; xor ax, ax\r
- db 8eh, 0e0h ; mov fs, ax\r
- db 8eh, 0e8h ; mov gs, ax\r
-\r
-flat32Start::\r
-\r
- db 0BEh\r
- dw BufferStart ; mov si, BufferStart\r
- db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer\r
-\r
- db 0BEh\r
- dw GdtrProfile ; mov si, GdtrProfile\r
- db 66h ; db 66h\r
- db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]\r
-\r
- db 0BEh\r
- dw IdtrProfile ; mov si, IdtrProfile\r
- db 66h ; db 66h\r
- db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]\r
-\r
- db 33h, 0C0h ; xor ax, ax\r
- db 8Eh, 0D8h ; mov ds, ax\r
-\r
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0\r
- db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)\r
- db 0Fh, 22h, 0C0h ; mov cr0, eax\r
-\r
-FLAT32_JUMP::\r
-\r
- db 66h, 67h, 0EAh ; far jump\r
- dd 0h ; 32-bit offset\r
- dw 20h ; 16-bit selector\r
-\r
-PMODE_ENTRY:: ; protected mode entry point\r
-\r
- mov ax, 8h\r
- mov ds, ax\r
- mov es, ax\r
- mov fs, ax\r
- mov gs, ax\r
- mov ss, ax ; Flat mode setup.\r
-\r
- mov esi, edx\r
-\r
- mov edi, esi\r
- add edi, LockLocation\r
- mov al, NotVacantFlag\r
-TestLock::\r
- xchg byte ptr [edi], al\r
- cmp al, NotVacantFlag\r
- jz TestLock\r
-\r
-ProgramStack::\r
-\r
- mov edi, esi\r
- add edi, StackSize\r
- mov eax, dword ptr [edi]\r
- mov edi, esi\r
- add edi, StackStart\r
- add eax, dword ptr [edi]\r
- mov esp, eax\r
- mov dword ptr [edi], eax\r
-\r
-Releaselock::\r
-\r
- mov al, VacantFlag\r
- mov edi, esi\r
- add edi, LockLocation\r
- xchg byte ptr [edi], al\r
-\r
- ;\r
- ; Call assembly function to initialize FPU.\r
- ;\r
- mov ebx, InitializeFloatingPointUnits\r
- call ebx\r
- ;\r
- ; Call C Function\r
- ;\r
- mov edi, esi\r
- add edi, RendezvousProc\r
- mov eax, dword ptr [edi]\r
-\r
- test eax, eax\r
- jz GoToSleep\r
- call eax ; Call C function\r
-\r
-GoToSleep::\r
- cli\r
- hlt\r
- jmp $-2\r
-\r
-RendezvousFunnelProc ENDP\r
-RendezvousFunnelProcEnd::\r
-;-------------------------------------------------------------------------------------\r
-; AsmGetAddressMap (&AddressMap);\r
-;-------------------------------------------------------------------------------------\r
-AsmGetAddressMap PROC near C PUBLIC\r
-\r
- pushad\r
- mov ebp,esp\r
-\r
- mov ebx, dword ptr [ebp+24h]\r
- mov dword ptr [ebx], RendezvousFunnelProcStart\r
- mov dword ptr [ebx+4h], PMODE_ENTRY - RendezvousFunnelProcStart\r
- mov dword ptr [ebx+8h], FLAT32_JUMP - RendezvousFunnelProcStart\r
- mov dword ptr [ebx+0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
-\r
- popad\r
- ret\r
-\r
-AsmGetAddressMap ENDP\r
-\r
-END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# SmiEntry.S\r
-#\r
-# Abstract:\r
-#\r
-# Code template of the SMI handler for a particular processor\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)\r
-ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)\r
-ASM_GLOBAL ASM_PFX(gSmiCr3)\r
-ASM_GLOBAL ASM_PFX(gSmiStack)\r
-ASM_GLOBAL ASM_PFX(gSmbase)\r
-ASM_GLOBAL ASM_PFX(mXdSupported)\r
-ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
-ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)\r
-\r
-.equ MSR_IA32_MISC_ENABLE, 0x1A0\r
-.equ MSR_EFER, 0xc0000080\r
-.equ MSR_EFER_XD, 0x800\r
-\r
-#\r
-# Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
-#\r
-.equ DSC_OFFSET, 0xfb00\r
-.equ DSC_GDTPTR, 0x30\r
-.equ DSC_GDTSIZ, 0x38\r
-.equ DSC_CS, 14\r
-.equ DSC_DS, 16\r
-.equ DSC_SS, 18\r
-.equ DSC_OTHERSEG, 20\r
-\r
-.equ PROTECT_MODE_CS, 0x08\r
-.equ PROTECT_MODE_DS, 0x20\r
-.equ TSS_SEGMENT, 0x40\r
-\r
- .text\r
-\r
-ASM_PFX(gcSmiHandlerTemplate):\r
-\r
-_SmiEntryPoint:\r
- .byte 0xbb # mov bx, imm16\r
- .word _GdtDesc - _SmiEntryPoint + 0x8000\r
- .byte 0x2e,0xa1 # mov ax, cs:[offset16]\r
- .word DSC_OFFSET + DSC_GDTSIZ\r
- decl %eax\r
- movl %eax, %cs:(%edi) # mov cs:[bx], ax\r
- .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]\r
- .word DSC_OFFSET + DSC_GDTPTR\r
- movw %ax, %cs:2(%edi)\r
- movw %ax, %bp # ebp = GDT base\r
- .byte 0x66\r
- lgdt %cs:(%edi)\r
-# Patch ProtectedMode Segment\r
- .byte 0xb8 # mov ax, imm16\r
- .word PROTECT_MODE_CS # set AX for segment directly\r
- movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax\r
-# Patch ProtectedMode entry\r
- .byte 0x66, 0xbf # mov edi, SMBASE\r
-ASM_PFX(gSmbase): .space 4\r
- .byte 0x67\r
- lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax\r
- movw %ax, %cs:-6(%edi)\r
- movl %cr0, %ebx\r
- .byte 0x66\r
- andl $0x9ffafff3, %ebx\r
- .byte 0x66\r
- orl $0x23, %ebx\r
- movl %ebx, %cr0\r
- .byte 0x66,0xea\r
- .space 4\r
- .space 2\r
-_GdtDesc: .space 4\r
- .space 2\r
-\r
-Start32bit:\r
- movw $PROTECT_MODE_DS, %ax\r
- movl %eax,%ds\r
- movl %eax,%es\r
- movl %eax,%fs\r
- movl %eax,%gs\r
- movl %eax,%ss\r
- .byte 0xbc # mov esp, imm32\r
-ASM_PFX(gSmiStack): .space 4\r
- movl $ASM_PFX(gSmiHandlerIdtr), %eax\r
- lidt (%eax)\r
- jmp ProtFlatMode\r
-\r
-ProtFlatMode:\r
- .byte 0xb8 # mov eax, imm32\r
-ASM_PFX(gSmiCr3): .space 4\r
- movl %eax, %cr3\r
-#\r
-# Need to test for CR4 specific bit support\r
-#\r
- movl $1, %eax\r
- cpuid # use CPUID to determine if specific CR4 bits are supported\r
- xorl %eax, %eax # Clear EAX\r
- testl $BIT2, %edx # Check for DE capabilities\r
- jz L8\r
- orl $BIT3, %eax\r
-L8:\r
- testl $BIT6, %edx # Check for PAE capabilities\r
- jz L9\r
- orl $BIT5, %eax\r
-L9:\r
- testl $BIT7, %edx # Check for MCE capabilities\r
- jz L10\r
- orl $BIT6, %eax\r
-L10:\r
- testl $BIT24, %edx # Check for FXSR capabilities\r
- jz L11\r
- orl $BIT9, %eax\r
-L11:\r
- testl $BIT25, %edx # Check for SSE capabilities\r
- jz L12\r
- orl $BIT10, %eax\r
-L12: # as cr4.PGE is not set here, refresh cr3\r
- movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.\r
-\r
- cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
- jz L5\r
-# Load TSS\r
- movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag\r
- movl $TSS_SEGMENT, %eax\r
- ltrw %ax\r
-L5:\r
-\r
-# enable NXE if supported\r
- .byte 0xb0 # mov al, imm8\r
-ASM_PFX(mXdSupported): .byte 1\r
- cmpb $0, %al\r
- jz SkipNxe\r
-#\r
-# Check XD disable bit\r
-#\r
- movl $MSR_IA32_MISC_ENABLE, %ecx\r
- rdmsr\r
- pushl %edx # save MSR_IA32_MISC_ENABLE[63-32]\r
- testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34]\r
- jz L13\r
- andw $0x0FFFB, %dx # clear XD Disable bit if it is set\r
- wrmsr\r
-L13:\r
- movl $MSR_EFER, %ecx\r
- rdmsr\r
- orw $MSR_EFER_XD,%ax # enable NXE\r
- wrmsr\r
- jmp NxeDone\r
-SkipNxe:\r
- subl $4, %esp\r
-NxeDone:\r
-\r
- movl %cr0, %ebx\r
- orl $0x080010023, %ebx # enable paging + WP + NE + MP + PE\r
- movl %ebx, %cr0\r
- leal DSC_OFFSET(%edi),%ebx\r
- movw DSC_DS(%ebx),%ax\r
- movl %eax, %ds\r
- movw DSC_OTHERSEG(%ebx),%ax\r
- movl %eax, %es\r
- movl %eax, %fs\r
- movl %eax, %gs\r
- movw DSC_SS(%ebx),%ax\r
- movl %eax, %ss\r
-\r
-# jmp _SmiHandler # instruction is not needed\r
-\r
-_SmiHandler:\r
- movl 4(%esp), %ebx\r
-\r
- pushl %ebx\r
- movl $ASM_PFX(CpuSmmDebugEntry), %eax\r
- call *%eax\r
- addl $4, %esp\r
-\r
- pushl %ebx\r
- movl $ASM_PFX(SmiRendezvous), %eax\r
- call *%eax\r
- addl $4, %esp\r
-\r
- pushl %ebx\r
- movl $ASM_PFX(CpuSmmDebugExit), %eax\r
- call *%eax\r
- addl $4, %esp\r
-\r
- movl $ASM_PFX(mXdSupported), %eax\r
- movb (%eax), %al\r
- cmpb $0, %al\r
- jz L16\r
- popl %edx # get saved MSR_IA32_MISC_ENABLE[63-32]\r
- testl $BIT2, %edx\r
- jz L16\r
- movl $MSR_IA32_MISC_ENABLE, %ecx\r
- rdmsr\r
- orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM\r
- wrmsr\r
-\r
-L16:\r
- rsm\r
-\r
-ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; SmiEntry.asm\r
-;\r
-; Abstract:\r
-;\r
-; Code template of the SMI handler for a particular processor\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
- .686p\r
- .model flat,C\r
- .xmm\r
-\r
-MSR_IA32_MISC_ENABLE EQU 1A0h\r
-MSR_EFER EQU 0c0000080h\r
-MSR_EFER_XD EQU 0800h\r
-\r
-;\r
-; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
-;\r
-DSC_OFFSET EQU 0fb00h\r
-DSC_GDTPTR EQU 30h\r
-DSC_GDTSIZ EQU 38h\r
-DSC_CS EQU 14\r
-DSC_DS EQU 16\r
-DSC_SS EQU 18\r
-DSC_OTHERSEG EQU 20\r
-\r
-PROTECT_MODE_CS EQU 08h\r
-PROTECT_MODE_DS EQU 20h\r
-TSS_SEGMENT EQU 40h\r
-\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 mXdSupported:BYTE\r
-EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE\r
-EXTERNDEF gSmiHandlerIdtr:FWORD\r
-\r
- .code\r
-\r
-gcSmiHandlerTemplate LABEL BYTE\r
-\r
-_SmiEntryPoint:\r
- DB 0bbh ; mov bx, imm16\r
- DW offset _GdtDesc - _SmiEntryPoint + 8000h\r
- DB 2eh, 0a1h ; mov ax, cs:[offset16]\r
- DW DSC_OFFSET + DSC_GDTSIZ\r
- dec eax\r
- mov cs:[edi], eax ; mov cs:[bx], ax\r
- DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]\r
- DW DSC_OFFSET + DSC_GDTPTR\r
- mov cs:[edi + 2], ax ; mov cs:[bx + 2], eax\r
- mov bp, ax ; ebp = GDT base\r
- DB 66h\r
- lgdt fword ptr cs:[edi] ; lgdt fword ptr cs:[bx]\r
-; Patch ProtectedMode Segment\r
- DB 0b8h ; mov ax, imm16\r
- DW PROTECT_MODE_CS ; set AX for segment directly\r
- mov cs:[edi - 2], eax ; mov cs:[bx - 2], ax\r
-; Patch ProtectedMode entry\r
- DB 66h, 0bfh ; mov edi, SMBASE\r
-gSmbase DD ?\r
- DB 67h\r
- lea ax, [edi + (@32bit - _SmiEntryPoint) + 8000h]\r
- mov cs:[edi - 6], ax ; mov cs:[bx - 6], eax\r
- mov ebx, cr0\r
- DB 66h\r
- and ebx, 9ffafff3h\r
- DB 66h\r
- or ebx, 23h\r
- mov cr0, ebx\r
- DB 66h, 0eah\r
- DD ?\r
- DW ?\r
-_GdtDesc FWORD ?\r
-\r
-@32bit:\r
- mov ax, PROTECT_MODE_DS\r
- mov ds, ax\r
- mov es, ax\r
- mov fs, ax\r
- mov gs, ax\r
- mov ss, ax\r
- DB 0bch ; mov esp, imm32\r
-gSmiStack DD ?\r
- mov eax, offset gSmiHandlerIdtr\r
- lidt fword ptr [eax]\r
- jmp ProtFlatMode\r
-\r
-ProtFlatMode:\r
- DB 0b8h ; mov eax, imm32\r
-gSmiCr3 DD ?\r
- mov cr3, eax\r
-;\r
-; Need to test for CR4 specific bit support\r
-;\r
- mov eax, 1\r
- cpuid ; use CPUID to determine if specific CR4 bits are supported\r
- xor eax, eax ; Clear EAX\r
- test edx, BIT2 ; Check for DE capabilities\r
- jz @f\r
- or eax, BIT3\r
-@@:\r
- test edx, BIT6 ; Check for PAE capabilities\r
- jz @f\r
- or eax, BIT5\r
-@@:\r
- test edx, BIT7 ; Check for MCE capabilities\r
- jz @f\r
- or eax, BIT6\r
-@@:\r
- test edx, BIT24 ; Check for FXSR capabilities\r
- jz @f\r
- or eax, BIT9\r
-@@:\r
- test edx, BIT25 ; Check for SSE capabilities\r
- jz @f\r
- or eax, BIT10\r
-@@: ; as cr4.PGE is not set here, refresh cr3\r
- mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
-\r
- cmp FeaturePcdGet (PcdCpuSmmStackGuard), 0\r
- jz @F\r
-; Load TSS\r
- mov byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag\r
- mov eax, TSS_SEGMENT\r
- ltr ax\r
-@@:\r
-\r
-; enable NXE if supported\r
- DB 0b0h ; mov al, imm8\r
-mXdSupported DB 1\r
- cmp al, 0\r
- jz @SkipXd\r
-;\r
-; Check XD disable bit\r
-;\r
- mov ecx, MSR_IA32_MISC_ENABLE\r
- rdmsr\r
- push edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
- test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
- jz @f\r
- and dx, 0FFFBh ; clear XD Disable bit if it is set\r
- wrmsr\r
-@@:\r
- mov ecx, MSR_EFER\r
- rdmsr\r
- or ax, MSR_EFER_XD ; enable NXE\r
- wrmsr\r
- jmp @XdDone\r
-@SkipXd:\r
- sub esp, 4\r
-@XdDone:\r
-\r
- mov ebx, cr0\r
- or ebx, 080010023h ; enable paging + WP + NE + MP + PE\r
- mov cr0, ebx\r
- lea ebx, [edi + DSC_OFFSET]\r
- mov ax, [ebx + DSC_DS]\r
- mov ds, eax\r
- mov ax, [ebx + DSC_OTHERSEG]\r
- mov es, eax\r
- mov fs, eax\r
- mov gs, eax\r
- mov ax, [ebx + DSC_SS]\r
- mov ss, eax\r
-\r
-; jmp _SmiHandler ; instruction is not needed\r
-\r
-_SmiHandler PROC\r
- mov ebx, [esp + 4] ; CPU Index\r
- push ebx\r
- mov eax, CpuSmmDebugEntry\r
- call eax\r
- add esp, 4\r
-\r
- push ebx\r
- mov eax, SmiRendezvous\r
- call eax\r
- add esp, 4\r
-\r
- push ebx\r
- mov eax, CpuSmmDebugExit\r
- call eax\r
- add esp, 4\r
-\r
- mov eax, offset mXdSupported\r
- mov al, [eax]\r
- cmp al, 0\r
- jz @f\r
- pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
- test edx, BIT2\r
- jz @f\r
- mov ecx, MSR_IA32_MISC_ENABLE\r
- rdmsr\r
- or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
- wrmsr\r
-\r
-@@:\r
- rsm\r
-_SmiHandler ENDP\r
-\r
-gcSmiHandlerSize DW $ - _SmiEntryPoint\r
-\r
- END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# SmiException.S\r
-#\r
-# Abstract:\r
-#\r
-# Exception handlers used in SM mode\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(SmiPFHandler)\r
-ASM_GLOBAL ASM_PFX(PageFaultStubFunction)\r
-ASM_GLOBAL ASM_PFX(gcSmiIdtr)\r
-ASM_GLOBAL ASM_PFX(gcSmiGdtr)\r
-ASM_GLOBAL ASM_PFX(gTaskGateDescriptor)\r
-ASM_GLOBAL ASM_PFX(gcPsd)\r
-ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))\r
-\r
- .data\r
-\r
-NullSeg: .quad 0 # reserved by architecture\r
-CodeSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x9b\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-ProtModeCodeSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x9b\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-ProtModeSsSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x93\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-DataSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x93\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-CodeSeg16:\r
- .word -1\r
- .word 0\r
- .byte 0\r
- .byte 0x9b\r
- .byte 0x8f\r
- .byte 0\r
-DataSeg16:\r
- .word -1\r
- .word 0\r
- .byte 0\r
- .byte 0x93\r
- .byte 0x8f\r
- .byte 0\r
-CodeSeg64:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x9b\r
- .byte 0xaf # LimitHigh\r
- .byte 0 # BaseHigh\r
-.equ GDT_SIZE, .- NullSeg\r
-\r
-TssSeg:\r
- .word TSS_DESC_SIZE -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x89\r
- .byte 0x00 # LimitHigh\r
- .byte 0 # BaseHigh\r
-ExceptionTssSeg:\r
- .word TSS_DESC_SIZE - 1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x89\r
- .byte 0x00 # LimitHigh\r
- .byte 0 # BaseHigh\r
-\r
-.equ CODE_SEL, CodeSeg32 - NullSeg\r
-.equ DATA_SEL, DataSeg32 - NullSeg\r
-.equ TSS_SEL, TssSeg - NullSeg\r
-.equ EXCEPTION_TSS_SEL, ExceptionTssSeg - NullSeg\r
-\r
-# IA32 TSS fields\r
-.equ TSS_ESP0, 4\r
-.equ TSS_SS0, 8\r
-.equ TSS_ESP1, 12\r
-.equ TSS_SS1, 16\r
-.equ TSS_ESP2, 20\r
-.equ TSS_SS2, 24\r
-.equ TSS_CR3, 28\r
-.equ TSS_EIP, 32\r
-.equ TSS_EFLAGS, 36\r
-.equ TSS_EAX, 40\r
-.equ TSS_ECX, 44\r
-.equ TSS_EDX, 48\r
-.equ TSS_EBX, 52\r
-.equ TSS_ESP, 56\r
-.equ TSS_EBP, 60\r
-.equ TSS_ESI, 64\r
-.equ TSS_EDI, 68\r
-.equ TSS_ES, 72\r
-.equ TSS_CS, 76\r
-.equ TSS_SS, 80\r
-.equ TSS_DS, 84\r
-.equ TSS_FS, 88\r
-.equ TSS_GS, 92\r
-.equ TSS_LDT, 96\r
-\r
-# Create 2 TSS segments just after GDT\r
-TssDescriptor:\r
- .word 0 # PreviousTaskLink\r
- .word 0 # Reserved\r
- .long 0 # ESP0\r
- .word 0 # SS0\r
- .word 0 # Reserved\r
- .long 0 # ESP1\r
- .word 0 # SS1\r
- .word 0 # Reserved\r
- .long 0 # ESP2\r
- .word 0 # SS2\r
- .word 0 # Reserved\r
- .long 0 # CR3\r
- .long 0 # EIP\r
- .long 0 # EFLAGS\r
- .long 0 # EAX\r
- .long 0 # ECX\r
- .long 0 # EDX\r
- .long 0 # EBX\r
- .long 0 # ESP\r
- .long 0 # EBP\r
- .long 0 # ESI\r
- .long 0 # EDI\r
- .word 0 # ES\r
- .word 0 # Reserved\r
- .word 0 # CS\r
- .word 0 # Reserved\r
- .word 0 # SS\r
- .word 0 # Reserved\r
- .word 0 # DS\r
- .word 0 # Reserved\r
- .word 0 # FS\r
- .word 0 # Reserved\r
- .word 0 # GS\r
- .word 0 # Reserved\r
- .word 0 # LDT Selector\r
- .word 0 # Reserved\r
- .word 0 # T\r
- .word 0 # I/O Map Base\r
-.equ TSS_DESC_SIZE, . - TssDescriptor\r
-\r
-ExceptionTssDescriptor:\r
- .word 0 # PreviousTaskLink\r
- .word 0 # Reserved\r
- .long 0 # ESP0\r
- .word 0 # SS0\r
- .word 0 # Reserved\r
- .long 0 # ESP1\r
- .word 0 # SS1\r
- .word 0 # Reserved\r
- .long 0 # ESP2\r
- .word 0 # SS2\r
- .word 0 # Reserved\r
- .long 0 # CR3\r
- .long PFHandlerEntry # EIP\r
- .long 00000002 # EFLAGS\r
- .long 0 # EAX\r
- .long 0 # ECX\r
- .long 0 # EDX\r
- .long 0 # EBX\r
- .long 0 # ESP\r
- .long 0 # EBP\r
- .long 0 # ESI\r
- .long 0 # EDI\r
- .word DATA_SEL # ES\r
- .word 0 # Reserved\r
- .word CODE_SEL # CS\r
- .word 0 # Reserved\r
- .word DATA_SEL # SS\r
- .word 0 # Reserved\r
- .word DATA_SEL # DS\r
- .word 0 # Reserved\r
- .word DATA_SEL # FS\r
- .word 0 # Reserved\r
- .word DATA_SEL # GS\r
- .word 0 # Reserved\r
- .word 0 # LDT Selector\r
- .word 0 # Reserved\r
- .word 0 # T\r
- .word 0 # I/O Map Base\r
-\r
-ASM_PFX(gcPsd):\r
- .ascii "PSDSIG "\r
- .word PSD_SIZE\r
- .word 2\r
- .word 1 << 2\r
- .word CODE_SEL\r
- .word DATA_SEL\r
- .word DATA_SEL\r
- .word DATA_SEL\r
- .word 0\r
- .long 0\r
- .long 0\r
- .long 0\r
- .long 0\r
- .quad 0\r
- .long NullSeg\r
- .long 0\r
- .long GDT_SIZE\r
- .long 0\r
- .space 24, 0\r
- .long 0\r
- .long 0\r
-.equ PSD_SIZE, . - ASM_PFX(gcPsd)\r
-\r
-ASM_PFX(gcSmiGdtr): .word GDT_SIZE - 1\r
- .long NullSeg\r
-\r
-ASM_PFX(gcSmiIdtr): .word 0\r
- .long 0\r
-\r
-ASM_PFX(gTaskGateDescriptor):\r
- .word 0 # Reserved\r
- .word EXCEPTION_TSS_SEL # TSS Segment selector\r
- .byte 0 # Reserved\r
- .byte 0x85 # Task Gate, present, DPL = 0\r
- .word 0 # Reserved\r
-\r
- .text\r
-\r
-#------------------------------------------------------------------------------\r
-# PageFaultIdtHandlerSmmProfile is the entry point for all exceptions\r
-#\r
-# Stack:\r
-#+---------------------+\r
-#+ EFlags +\r
-#+---------------------+\r
-#+ CS +\r
-#+---------------------+\r
-#+ EIP +\r
-#+---------------------+\r
-#+ Error Code +\r
-#+---------------------+\r
-#+ Vector Number +\r
-#+---------------------+\r
-#+ EBP +\r
-#+---------------------+ <-- EBP\r
-#\r
-# RSP set to odd multiple of 8 means ErrCode PRESENT\r
-#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)\r
-ASM_PFX(PageFaultIdtHandlerSmmProfile):\r
- pushl $0x0e # Page Fault\r
- pushl %ebp\r
- movl %esp, %ebp\r
-\r
-\r
- #\r
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- # is 16-byte aligned\r
- #\r
- andl $0xfffffff0, %esp\r
- subl $12, %esp\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pushl %eax\r
- pushl %ecx\r
- pushl %edx\r
- pushl %ebx\r
- leal (6*4)(%ebp), %ecx\r
- pushl %ecx # ESP\r
- pushl (%ebp) # EBP\r
- pushl %esi\r
- pushl %edi\r
-\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- movl %ss, %eax\r
- pushl %eax\r
- movzwl (4*4)(%ebp), %eax\r
- pushl %eax\r
- movl %ds, %eax\r
- pushl %eax\r
- movl %es, %eax\r
- pushl %eax\r
- movl %fs, %eax\r
- pushl %eax\r
- movl %gs, %eax\r
- pushl %eax\r
-\r
-## UINT32 Eip;\r
- movl (3*4)(%ebp), %eax\r
- pushl %eax\r
-\r
-## UINT32 Gdtr[2], Idtr[2];\r
- subl $8, %esp\r
- sidt (%esp)\r
- movl 2(%esp), %eax\r
- xchgl (%esp), %eax\r
- andl $0xffff, %eax\r
- movl %eax, 4(%esp)\r
-\r
- subl $8, %esp\r
- sgdt (%esp)\r
- movl 2(%esp), %eax\r
- xchgl (%esp), %eax\r
- andl $0xffff, %eax\r
- movl %eax, 4(%esp)\r
-\r
-## UINT32 Ldtr, Tr;\r
- xorl %eax, %eax\r
- strw %ax\r
- pushl %eax\r
- sldtw %ax\r
- pushl %eax\r
-\r
-## UINT32 EFlags;\r
- movl (5*4)(%ebp), %eax\r
- pushl %eax\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- movl %cr4, %eax\r
- orl $0x208, %eax\r
- movl %eax, %cr4\r
- pushl %eax\r
- movl %cr3, %eax\r
- pushl %eax\r
- movl %cr2, %eax\r
- pushl %eax\r
- xorl %eax, %eax\r
- pushl %eax\r
- movl %cr0, %eax\r
- pushl %eax\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- movl %dr7, %eax\r
- pushl %eax\r
- movl %dr6, %eax\r
- pushl %eax\r
- movl %dr3, %eax\r
- pushl %eax\r
- movl %dr2, %eax\r
- pushl %eax\r
- movl %dr1, %eax\r
- pushl %eax\r
- movl %dr0, %eax\r
- pushl %eax\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- subl $512, %esp\r
- movl %esp, %edi\r
- .byte 0x0f, 0xae, 0x07 #fxsave [edi]\r
-\r
-# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-## UINT32 ExceptionData;\r
- pushl (2*4)(%ebp)\r
-\r
-## call into exception handler\r
-\r
-## Prepare parameter and call\r
- movl %esp, %edx\r
- pushl %edx\r
- movl (1*4)(%ebp), %edx\r
- pushl %edx\r
-\r
- #\r
- # Call External Exception Handler\r
- #\r
- movl $ASM_PFX(SmiPFHandler), %eax\r
- call *%eax\r
- addl $8, %esp\r
- jmp L4\r
-\r
-L4:\r
-## UINT32 ExceptionData;\r
- addl $4, %esp\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- movl %esp, %esi\r
- .byte 0xf, 0xae, 0xe # fxrstor [esi]\r
- addl $512, %esp\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-## Skip restoration of DRx registers to support debuggers\r
-## that set breakpoints in interrupt/exception context\r
- addl $4*6, %esp\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- popl %eax\r
- movl %eax, %cr0\r
- addl $4, %esp # not for Cr1\r
- popl %eax\r
- movl %eax, %cr2\r
- popl %eax\r
- movl %eax, %cr3\r
- popl %eax\r
- movl %eax, %cr4\r
-\r
-## UINT32 EFlags;\r
- popl (5*4)(%ebp)\r
-\r
-## UINT32 Ldtr, Tr;\r
-## UINT32 Gdtr[2], Idtr[2];\r
-## Best not let anyone mess with these particular registers...\r
- addl $24, %esp\r
-\r
-## UINT32 Eip;\r
- popl (3*4)(%ebp)\r
-\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-## NOTE - modified segment registers could hang the debugger... We\r
-## could attempt to insulate ourselves against this possibility,\r
-## but that poses risks as well.\r
-##\r
- popl %gs\r
- popl %fs\r
- popl %es\r
- popl %ds\r
- popl (4*4)(%ebp)\r
- popl %ss\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popl %edi\r
- popl %esi\r
- addl $4, %esp # not for ebp\r
- addl $4, %esp # not for esp\r
- popl %ebx\r
- popl %edx\r
- popl %ecx\r
- popl %eax\r
-\r
- movl %ebp, %esp\r
- popl %ebp\r
-\r
-# Enable TF bit after page fault handler runs\r
- btsl $8, 16(%esp) # EFLAGS\r
-\r
- addl $8, %esp # skip INT# & ErrCode\r
-Return:\r
- iret\r
-#\r
-# Page Fault Exception Handler entry when SMM Stack Guard is enabled\r
-# Executiot starts here after a task switch\r
-#\r
-PFHandlerEntry:\r
-#\r
-# Get this processor's TSS\r
-#\r
- subl $8, %esp\r
- sgdt 2(%esp)\r
- movl 4(%esp), %eax # GDT base\r
- addl $8, %esp\r
- movl (TSS_SEL+2)(%eax), %ecx\r
- shll $8, %ecx\r
- movb (TSS_SEL+7)(%eax), %cl\r
- rorl $8, %ecx # ecx = TSS base\r
-\r
- movl %esp, %ebp\r
-\r
- #\r
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- # is 16-byte aligned\r
- #\r
- andl $0xfffffff0, %esp\r
- subl $12, %esp\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pushl TSS_EAX(%ecx)\r
- pushl TSS_ECX(%ecx)\r
- pushl TSS_EDX(%ecx)\r
- pushl TSS_EBX(%ecx)\r
- pushl TSS_ESP(%ecx)\r
- pushl TSS_EBP(%ecx)\r
- pushl TSS_ESI(%ecx)\r
- pushl TSS_EDI(%ecx)\r
-\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- movzwl TSS_SS(%ecx), %eax\r
- pushl %eax\r
- movzwl TSS_CS(%ecx), %eax\r
- pushl %eax\r
- movzwl TSS_DS(%ecx), %eax\r
- pushl %eax\r
- movzwl TSS_ES(%ecx), %eax\r
- pushl %eax\r
- movzwl TSS_FS(%ecx), %eax\r
- pushl %eax\r
- movzwl TSS_GS(%ecx), %eax\r
- pushl %eax\r
-\r
-## UINT32 Eip;\r
- pushl TSS_EIP(%ecx)\r
-\r
-## UINT32 Gdtr[2], Idtr[2];\r
- subl $8, %esp\r
- sidt (%esp)\r
- movl 2(%esp), %eax\r
- xchgl (%esp), %eax\r
- andl $0xFFFF, %eax\r
- movl %eax, 4(%esp)\r
-\r
- subl $8, %esp\r
- sgdt (%esp)\r
- movl 2(%esp), %eax\r
- xchgl (%esp), %eax\r
- andl $0xFFFF, %eax\r
- movl %eax, 4(%esp)\r
-\r
-## UINT32 Ldtr, Tr;\r
- movl $TSS_SEL, %eax\r
- pushl %eax\r
- movzwl TSS_LDT(%ecx), %eax\r
- pushl %eax\r
-\r
-## UINT32 EFlags;\r
- pushl TSS_EFLAGS(%ecx)\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- movl %cr4, %eax\r
- orl $0x208, %eax\r
- movl %eax, %cr4\r
- pushl %eax\r
- movl %cr3, %eax\r
- pushl %eax\r
- movl %cr2, %eax\r
- pushl %eax\r
- xorl %eax, %eax\r
- pushl %eax\r
- movl %cr0, %eax\r
- pushl %eax\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- movl %dr7, %eax\r
- pushl %eax\r
- movl %dr6, %eax\r
- pushl %eax\r
- movl %dr3, %eax\r
- pushl %eax\r
- movl %dr2, %eax\r
- pushl %eax\r
- movl %dr1, %eax\r
- pushl %eax\r
- movl %dr0, %eax\r
- pushl %eax\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
-## Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)\r
-## when executing fxsave/fxrstor instruction\r
- clts\r
- subl $512, %esp\r
- movl %esp, %edi\r
- .byte 0x0f, 0xae, 0x07 #fxsave [edi]\r
-\r
-# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-## UINT32 ExceptionData;\r
- pushl (%ebp)\r
-\r
-## call into exception handler\r
- movl %ecx, %ebx\r
- movl $ASM_PFX(SmiPFHandler), %eax\r
-\r
-## Prepare parameter and call\r
- movl %esp, %edx\r
- pushl %edx\r
- movl $14, %edx\r
- pushl %edx\r
-\r
- #\r
- # Call External Exception Handler\r
- #\r
- call *%eax\r
- addl $8, %esp\r
-\r
- movl %ebx, %ecx\r
-## UINT32 ExceptionData;\r
- addl $4, %esp\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- movl %esp, %esi\r
- .byte 0xf, 0xae, 0xe # fxrstor [esi]\r
- addl $512, %esp\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-## Skip restoration of DRx registers to support debuggers\r
-## that set breakpoints in interrupt/exception context\r
- addl $4*6, %esp\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- popl %eax\r
- movl %eax, %cr0\r
- addl $4, %esp # not for Cr1\r
- popl %eax\r
- movl %eax, %cr2\r
- popl %eax\r
- movl %eax, TSS_CR3(%ecx)\r
- popl %eax\r
- movl %eax, %cr4\r
-\r
-## UINT32 EFlags;\r
- popl TSS_EFLAGS(%ecx)\r
-\r
-## UINT32 Ldtr, Tr;\r
-## UINT32 Gdtr[2], Idtr[2];\r
-## Best not let anyone mess with these particular registers...\r
- addl $24, %esp\r
-\r
-## UINT32 Eip;\r
- popl TSS_EIP(%ecx)\r
-\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-## NOTE - modified segment registers could hang the debugger... We\r
-## could attempt to insulate ourselves against this possibility,\r
-## but that poses risks as well.\r
-##\r
- popl %eax\r
- movw %ax, TSS_GS(%ecx)\r
- popl %eax\r
- movw %ax, TSS_FS(%ecx)\r
- popl %eax\r
- movw %ax, TSS_ES(%ecx)\r
- popl %eax\r
- movw %ax, TSS_DS(%ecx)\r
- popl %eax\r
- movw %ax, TSS_CS(%ecx)\r
- popl %eax\r
- movw %ax, TSS_SS(%ecx)\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popl TSS_EDI(%ecx)\r
- popl TSS_ESI(%ecx)\r
- addl $4, %esp # not for ebp\r
- addl $4, %esp # not for esp\r
- popl TSS_EBX(%ecx)\r
- popl TSS_EDX(%ecx)\r
- popl TSS_ECX(%ecx)\r
- popl TSS_EAX(%ecx)\r
-\r
- movl %ebp, %esp\r
-\r
-# Set single step DB# if SMM profile is enabled and page fault exception happens\r
- cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))\r
- jz Done2\r
-# Create return context for iret in stub function\r
- movl TSS_ESP(%ecx), %eax # Get old stack pointer\r
- movl TSS_EIP(%ecx), %ebx\r
- movl %ebx, -0xc(%eax) # create EIP in old stack\r
- movzwl TSS_CS(%ecx), %ebx\r
- movl %ebx, -0x8(%eax) # create CS in old stack\r
- movl TSS_EFLAGS(%ecx), %ebx\r
- btsl $8,%ebx\r
- movl %ebx, -0x4(%eax) # create eflags in old stack\r
- movl TSS_ESP(%ecx), %eax # Get old stack pointer\r
- subl $12, %eax # minus 12 byte\r
- movl %eax, TSS_ESP(%ecx) # Set new stack pointer\r
-\r
-# Replace the EIP of interrupted task with stub function\r
- movl $ASM_PFX(PageFaultStubFunction), %eax\r
- movl %eax, TSS_EIP(%ecx)\r
-# Jump to the iret so next page fault handler as a task will start again after iret.\r
-\r
-Done2:\r
-\r
- addl $4, %esp # skip ErrCode\r
-\r
- jmp Return\r
-\r
-ASM_PFX(PageFaultStubFunction):\r
-#\r
-# we need clean TS bit in CR0 to execute\r
-# x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.\r
-#\r
- clts\r
- iret\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; SmiException.asm\r
-;\r
-; Abstract:\r
-;\r
-; Exception handlers used in SM mode\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
- .686p\r
- .model flat,C\r
-\r
-EXTERNDEF SmiPFHandler:PROC\r
-EXTERNDEF PageFaultStubFunction:PROC\r
-EXTERNDEF gcSmiIdtr:FWORD\r
-EXTERNDEF gcSmiGdtr:FWORD\r
-EXTERNDEF gTaskGateDescriptor:QWORD\r
-EXTERNDEF gcPsd:BYTE\r
-EXTERNDEF FeaturePcdGet (PcdCpuSmmProfileEnable):BYTE\r
-\r
-\r
- .data\r
-\r
-NullSeg DQ 0 ; reserved by architecture\r
-CodeSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 9bh\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-ProtModeCodeSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 9bh\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-ProtModeSsSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 93h\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-DataSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 93h\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-CodeSeg16 LABEL QWORD\r
- DW -1\r
- DW 0\r
- DB 0\r
- DB 9bh\r
- DB 8fh\r
- DB 0\r
-DataSeg16 LABEL QWORD\r
- DW -1\r
- DW 0\r
- DB 0\r
- DB 93h\r
- DB 8fh\r
- DB 0\r
-CodeSeg64 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 9bh\r
- DB 0afh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-GDT_SIZE = $ - offset NullSeg\r
-\r
-TssSeg LABEL QWORD\r
- DW TSS_DESC_SIZE - 1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 89h\r
- DB 00h ; LimitHigh\r
- DB 0 ; BaseHigh\r
-ExceptionTssSeg LABEL QWORD\r
- DW TSS_DESC_SIZE - 1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 89h\r
- DB 00h ; LimitHigh\r
- DB 0 ; BaseHigh\r
-\r
-CODE_SEL = offset CodeSeg32 - offset NullSeg\r
-DATA_SEL = offset DataSeg32 - offset NullSeg\r
-TSS_SEL = offset TssSeg - offset NullSeg\r
-EXCEPTION_TSS_SEL = offset ExceptionTssSeg - offset NullSeg\r
-\r
-IA32_TSS STRUC\r
- DW ?\r
- DW ?\r
- ESP0 DD ?\r
- SS0 DW ?\r
- DW ?\r
- ESP1 DD ?\r
- SS1 DW ?\r
- DW ?\r
- ESP2 DD ?\r
- SS2 DW ?\r
- DW ?\r
- _CR3 DD ?\r
- EIP DD ?\r
- EFLAGS DD ?\r
- _EAX DD ?\r
- _ECX DD ?\r
- _EDX DD ?\r
- _EBX DD ?\r
- _ESP DD ?\r
- _EBP DD ?\r
- _ESI DD ?\r
- _EDI DD ?\r
- _ES DW ?\r
- DW ?\r
- _CS DW ?\r
- DW ?\r
- _SS DW ?\r
- DW ?\r
- _DS DW ?\r
- DW ?\r
- _FS DW ?\r
- DW ?\r
- _GS DW ?\r
- DW ?\r
- LDT DW ?\r
- DW ?\r
- DW ?\r
- DW ?\r
-IA32_TSS ENDS\r
-\r
-; Create 2 TSS segments just after GDT\r
-TssDescriptor LABEL BYTE\r
- DW 0 ; PreviousTaskLink\r
- DW 0 ; Reserved\r
- DD 0 ; ESP0\r
- DW 0 ; SS0\r
- DW 0 ; Reserved\r
- DD 0 ; ESP1\r
- DW 0 ; SS1\r
- DW 0 ; Reserved\r
- DD 0 ; ESP2\r
- DW 0 ; SS2\r
- DW 0 ; Reserved\r
- DD 0 ; CR3\r
- DD 0 ; EIP\r
- DD 0 ; EFLAGS\r
- DD 0 ; EAX\r
- DD 0 ; ECX\r
- DD 0 ; EDX\r
- DD 0 ; EBX\r
- DD 0 ; ESP\r
- DD 0 ; EBP\r
- DD 0 ; ESI\r
- DD 0 ; EDI\r
- DW 0 ; ES\r
- DW 0 ; Reserved\r
- DW 0 ; CS\r
- DW 0 ; Reserved\r
- DW 0 ; SS\r
- DW 0 ; Reserved\r
- DW 0 ; DS\r
- DW 0 ; Reserved\r
- DW 0 ; FS\r
- DW 0 ; Reserved\r
- DW 0 ; GS\r
- DW 0 ; Reserved\r
- DW 0 ; LDT Selector\r
- DW 0 ; Reserved\r
- DW 0 ; T\r
- DW 0 ; I/O Map Base\r
-TSS_DESC_SIZE = $ - offset TssDescriptor\r
-\r
-ExceptionTssDescriptor LABEL BYTE\r
- DW 0 ; PreviousTaskLink\r
- DW 0 ; Reserved\r
- DD 0 ; ESP0\r
- DW 0 ; SS0\r
- DW 0 ; Reserved\r
- DD 0 ; ESP1\r
- DW 0 ; SS1\r
- DW 0 ; Reserved\r
- DD 0 ; ESP2\r
- DW 0 ; SS2\r
- DW 0 ; Reserved\r
- DD 0 ; CR3\r
- DD offset PFHandlerEntry ; EIP\r
- DD 00000002 ; EFLAGS\r
- DD 0 ; EAX\r
- DD 0 ; ECX\r
- DD 0 ; EDX\r
- DD 0 ; EBX\r
- DD 0 ; ESP\r
- DD 0 ; EBP\r
- DD 0 ; ESI\r
- DD 0 ; EDI\r
- DW DATA_SEL ; ES\r
- DW 0 ; Reserved\r
- DW CODE_SEL ; CS\r
- DW 0 ; Reserved\r
- DW DATA_SEL ; SS\r
- DW 0 ; Reserved\r
- DW DATA_SEL ; DS\r
- DW 0 ; Reserved\r
- DW DATA_SEL ; FS\r
- DW 0 ; Reserved\r
- DW DATA_SEL ; GS\r
- DW 0 ; Reserved\r
- DW 0 ; LDT Selector\r
- DW 0 ; Reserved\r
- DW 0 ; T\r
- DW 0 ; I/O Map Base\r
-\r
-gcPsd LABEL BYTE\r
- DB 'PSDSIG '\r
- DW PSD_SIZE\r
- DW 2\r
- DW 1 SHL 2\r
- DW CODE_SEL\r
- DW DATA_SEL\r
- DW DATA_SEL\r
- DW DATA_SEL\r
- DW 0\r
- DQ 0\r
- DQ 0\r
- DQ 0\r
- DQ offset NullSeg\r
- DD GDT_SIZE\r
- DD 0\r
- DB 24 dup (0)\r
- DQ 0\r
-PSD_SIZE = $ - offset gcPsd\r
-\r
-gcSmiGdtr LABEL FWORD\r
- DW GDT_SIZE - 1\r
- DD offset NullSeg\r
-\r
-gcSmiIdtr LABEL FWORD\r
- DW 0\r
- DD 0\r
-\r
-gTaskGateDescriptor LABEL QWORD\r
- DW 0 ; Reserved\r
- DW EXCEPTION_TSS_SEL ; TSS Segment selector\r
- DB 0 ; Reserved\r
- DB 85h ; Task Gate, present, DPL = 0\r
- DW 0 ; Reserved\r
-\r
-\r
- .code\r
-;------------------------------------------------------------------------------\r
-; PageFaultIdtHandlerSmmProfile is the entry point page fault only\r
-;\r
-;\r
-; Stack:\r
-; +---------------------+\r
-; + EFlags +\r
-; +---------------------+\r
-; + CS +\r
-; +---------------------+\r
-; + EIP +\r
-; +---------------------+\r
-; + Error Code +\r
-; +---------------------+\r
-; + Vector Number +\r
-; +---------------------+\r
-; + EBP +\r
-; +---------------------+ <-- EBP\r
-;\r
-;\r
-;------------------------------------------------------------------------------\r
-PageFaultIdtHandlerSmmProfile PROC\r
- push 0eh ; Page Fault\r
-\r
- push ebp\r
- mov ebp, esp\r
-\r
-\r
- ;\r
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- ; is 16-byte aligned\r
- ;\r
- and esp, 0fffffff0h\r
- sub esp, 12\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- push eax\r
- push ecx\r
- push edx\r
- push ebx\r
- lea ecx, [ebp + 6 * 4]\r
- push ecx ; ESP\r
- push dword ptr [ebp] ; EBP\r
- push esi\r
- push edi\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- mov eax, ss\r
- push eax\r
- movzx eax, word ptr [ebp + 4 * 4]\r
- push eax\r
- mov eax, ds\r
- push eax\r
- mov eax, es\r
- push eax\r
- mov eax, fs\r
- push eax\r
- mov eax, gs\r
- push eax\r
-\r
-;; UINT32 Eip;\r
- mov eax, [ebp + 3 * 4]\r
- push eax\r
-\r
-;; UINT32 Gdtr[2], Idtr[2];\r
- sub esp, 8\r
- sidt [esp]\r
- mov eax, [esp + 2]\r
- xchg eax, [esp]\r
- and eax, 0FFFFh\r
- mov [esp+4], eax\r
-\r
- sub esp, 8\r
- sgdt [esp]\r
- mov eax, [esp + 2]\r
- xchg eax, [esp]\r
- and eax, 0FFFFh\r
- mov [esp+4], eax\r
-\r
-;; UINT32 Ldtr, Tr;\r
- xor eax, eax\r
- str ax\r
- push eax\r
- sldt ax\r
- push eax\r
-\r
-;; UINT32 EFlags;\r
- mov eax, [ebp + 5 * 4]\r
- push eax\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- mov eax, cr4\r
- or eax, 208h\r
- mov cr4, eax\r
- push eax\r
- mov eax, cr3\r
- push eax\r
- mov eax, cr2\r
- push eax\r
- xor eax, eax\r
- push eax\r
- mov eax, cr0\r
- push eax\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov eax, dr7\r
- push eax\r
- mov eax, dr6\r
- push eax\r
- mov eax, dr3\r
- push eax\r
- mov eax, dr2\r
- push eax\r
- mov eax, dr1\r
- push eax\r
- mov eax, dr0\r
- push eax\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- sub esp, 512\r
- mov edi, esp\r
- db 0fh, 0aeh, 07h ;fxsave [edi]\r
-\r
-; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-;; UINT32 ExceptionData;\r
- push dword ptr [ebp + 2 * 4]\r
-\r
-;; call into exception handler\r
-\r
-;; Prepare parameter and call\r
- mov edx, esp\r
- push edx\r
- mov edx, dword ptr [ebp + 1 * 4]\r
- push edx\r
-\r
- ;\r
- ; Call External Exception Handler\r
- ;\r
- mov eax, SmiPFHandler\r
- call eax\r
- add esp, 8\r
-\r
-;; UINT32 ExceptionData;\r
- add esp, 4\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- mov esi, esp\r
- db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
- add esp, 512\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; Skip restoration of DRx registers to support debuggers\r
-;; that set breakpoint in interrupt/exception context\r
- add esp, 4 * 6\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop eax\r
- mov cr0, eax\r
- add esp, 4 ; not for Cr1\r
- pop eax\r
- mov cr2, eax\r
- pop eax\r
- mov cr3, eax\r
- pop eax\r
- mov cr4, eax\r
-\r
-;; UINT32 EFlags;\r
- pop dword ptr [ebp + 5 * 4]\r
-\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add esp, 24\r
-\r
-;; UINT32 Eip;\r
- pop dword ptr [ebp + 3 * 4]\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; NOTE - modified segment registers could hang the debugger... We\r
-;; could attempt to insulate ourselves against this possibility,\r
-;; but that poses risks as well.\r
-;;\r
- pop gs\r
- pop fs\r
- pop es\r
- pop ds\r
- pop dword ptr [ebp + 4 * 4]\r
- pop ss\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pop edi\r
- pop esi\r
- add esp, 4 ; not for ebp\r
- add esp, 4 ; not for esp\r
- pop ebx\r
- pop edx\r
- pop ecx\r
- pop eax\r
-\r
- mov esp, ebp\r
- pop ebp\r
-\r
-; Enable TF bit after page fault handler runs\r
- bts dword ptr [esp + 16], 8 ; EFLAGS\r
-\r
- add esp, 8 ; skip INT# & ErrCode\r
-Return:\r
- iretd\r
-;\r
-; Page Fault Exception Handler entry when SMM Stack Guard is enabled\r
-; Executiot starts here after a task switch\r
-;\r
-PFHandlerEntry::\r
-;\r
-; Get this processor's TSS\r
-;\r
- sub esp, 8\r
- sgdt [esp + 2]\r
- mov eax, [esp + 4] ; GDT base\r
- add esp, 8\r
- mov ecx, [eax + TSS_SEL + 2]\r
- shl ecx, 8\r
- mov cl, [eax + TSS_SEL + 7]\r
- ror ecx, 8 ; ecx = TSS base\r
-\r
- mov ebp, esp\r
-\r
- ;\r
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- ; is 16-byte aligned\r
- ;\r
- and esp, 0fffffff0h\r
- sub esp, 12\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- push (IA32_TSS ptr [ecx])._EAX\r
- push (IA32_TSS ptr [ecx])._ECX\r
- push (IA32_TSS ptr [ecx])._EDX\r
- push (IA32_TSS ptr [ecx])._EBX\r
- push (IA32_TSS ptr [ecx])._ESP\r
- push (IA32_TSS ptr [ecx])._EBP\r
- push (IA32_TSS ptr [ecx])._ESI\r
- push (IA32_TSS ptr [ecx])._EDI\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- movzx eax, (IA32_TSS ptr [ecx])._SS\r
- push eax\r
- movzx eax, (IA32_TSS ptr [ecx])._CS\r
- push eax\r
- movzx eax, (IA32_TSS ptr [ecx])._DS\r
- push eax\r
- movzx eax, (IA32_TSS ptr [ecx])._ES\r
- push eax\r
- movzx eax, (IA32_TSS ptr [ecx])._FS\r
- push eax\r
- movzx eax, (IA32_TSS ptr [ecx])._GS\r
- push eax\r
-\r
-;; UINT32 Eip;\r
- push (IA32_TSS ptr [ecx]).EIP\r
-\r
-;; UINT32 Gdtr[2], Idtr[2];\r
- sub esp, 8\r
- sidt [esp]\r
- mov eax, [esp + 2]\r
- xchg eax, [esp]\r
- and eax, 0FFFFh\r
- mov [esp+4], eax\r
-\r
- sub esp, 8\r
- sgdt [esp]\r
- mov eax, [esp + 2]\r
- xchg eax, [esp]\r
- and eax, 0FFFFh\r
- mov [esp+4], eax\r
-\r
-;; UINT32 Ldtr, Tr;\r
- mov eax, TSS_SEL\r
- push eax\r
- movzx eax, (IA32_TSS ptr [ecx]).LDT\r
- push eax\r
-\r
-;; UINT32 EFlags;\r
- push (IA32_TSS ptr [ecx]).EFLAGS\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- mov eax, cr4\r
- or eax, 208h\r
- mov cr4, eax\r
- push eax\r
- mov eax, cr3\r
- push eax\r
- mov eax, cr2\r
- push eax\r
- xor eax, eax\r
- push eax\r
- mov eax, cr0\r
- push eax\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov eax, dr7\r
- push eax\r
- mov eax, dr6\r
- push eax\r
- mov eax, dr3\r
- push eax\r
- mov eax, dr2\r
- push eax\r
- mov eax, dr1\r
- push eax\r
- mov eax, dr0\r
- push eax\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
-;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)\r
-;; when executing fxsave/fxrstor instruction\r
- clts\r
- sub esp, 512\r
- mov edi, esp\r
- db 0fh, 0aeh, 07h ;fxsave [edi]\r
-\r
-; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-;; UINT32 ExceptionData;\r
- push dword ptr [ebp]\r
-\r
-;; call into exception handler\r
- mov ebx, ecx\r
- mov eax, SmiPFHandler\r
-\r
-;; Prepare parameter and call\r
- mov edx, esp\r
- push edx\r
- mov edx, 14\r
- push edx\r
-\r
- ;\r
- ; Call External Exception Handler\r
- ;\r
- call eax\r
- add esp, 8\r
-\r
- mov ecx, ebx\r
-;; UINT32 ExceptionData;\r
- add esp, 4\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- mov esi, esp\r
- db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
- add esp, 512\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; Skip restoration of DRx registers to support debuggers\r
-;; that set breakpoints in interrupt/exception context\r
- add esp, 4 * 6\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop eax\r
- mov cr0, eax\r
- add esp, 4 ; not for Cr1\r
- pop eax\r
- mov cr2, eax\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._CR3, eax\r
- pop eax\r
- mov cr4, eax\r
-\r
-;; UINT32 EFlags;\r
- pop (IA32_TSS ptr [ecx]).EFLAGS\r
-\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add esp, 24\r
-\r
-;; UINT32 Eip;\r
- pop (IA32_TSS ptr [ecx]).EIP\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; NOTE - modified segment registers could hang the debugger... We\r
-;; could attempt to insulate ourselves against this possibility,\r
-;; but that poses risks as well.\r
-;;\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._GS, ax\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._FS, ax\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._ES, ax\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._DS, ax\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._CS, ax\r
- pop eax\r
- mov (IA32_TSS ptr [ecx])._SS, ax\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pop (IA32_TSS ptr [ecx])._EDI\r
- pop (IA32_TSS ptr [ecx])._ESI\r
- add esp, 4 ; not for ebp\r
- add esp, 4 ; not for esp\r
- pop (IA32_TSS ptr [ecx])._EBX\r
- pop (IA32_TSS ptr [ecx])._EDX\r
- pop (IA32_TSS ptr [ecx])._ECX\r
- pop (IA32_TSS ptr [ecx])._EAX\r
-\r
- mov esp, ebp\r
-\r
-; Set single step DB# if SMM profile is enabled and page fault exception happens\r
- cmp FeaturePcdGet (PcdCpuSmmProfileEnable), 0\r
- jz @Done2\r
-\r
-; Create return context for iretd in stub function\r
- mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer\r
- mov ebx, (IA32_TSS ptr [ecx]).EIP\r
- mov [eax - 0ch], ebx ; create EIP in old stack\r
- movzx ebx, (IA32_TSS ptr [ecx])._CS\r
- mov [eax - 08h], ebx ; create CS in old stack\r
- mov ebx, (IA32_TSS ptr [ecx]).EFLAGS\r
- bts ebx, 8\r
- mov [eax - 04h], ebx ; create eflags in old stack\r
- mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer\r
- sub eax, 0ch ; minus 12 byte\r
- mov (IA32_TSS ptr [ecx])._ESP, eax ; Set new stack pointer\r
-; Replace the EIP of interrupted task with stub function\r
- mov eax, PageFaultStubFunction\r
- mov (IA32_TSS ptr [ecx]).EIP, eax\r
-; Jump to the iretd so next page fault handler as a task will start again after iretd.\r
-@Done2:\r
- add esp, 4 ; skip ErrCode\r
-\r
- jmp Return\r
-PageFaultIdtHandlerSmmProfile ENDP\r
-\r
-PageFaultStubFunction PROC\r
-;\r
-; we need clean TS bit in CR0 to execute\r
-; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.\r
-;\r
- clts\r
- iretd\r
-PageFaultStubFunction ENDP\r
-\r
- END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# SmmInit.S\r
-#\r
-# Abstract:\r
-#\r
-# Functions for relocating SMBASE's for all processors\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(gSmmCr0)\r
-ASM_GLOBAL ASM_PFX(gSmmCr3)\r
-ASM_GLOBAL ASM_PFX(gSmmCr4)\r
-ASM_GLOBAL ASM_PFX(gcSmmInitTemplate)\r
-ASM_GLOBAL ASM_PFX(gcSmmInitSize)\r
-ASM_GLOBAL ASM_PFX(gSmmJmpAddr)\r
-ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete)\r
-ASM_GLOBAL ASM_PFX(gSmmInitStack)\r
-ASM_GLOBAL ASM_PFX(gcSmiInitGdtr)\r
-\r
-.equ PROTECT_MODE_CS, 0x08\r
-.equ PROTECT_MODE_DS, 0x20\r
-\r
- .text\r
-\r
-ASM_PFX(gcSmiInitGdtr):\r
- .word 0\r
- .quad 0\r
-\r
-SmmStartup:\r
- .byte 0x66,0xb8\r
-ASM_PFX(gSmmCr3): .space 4\r
- movl %eax, %cr3\r
- .byte 0x67,0x66\r
- lgdt %cs:(ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp)\r
- .byte 0x66,0xb8\r
-ASM_PFX(gSmmCr4): .space 4\r
- movl %eax, %cr4\r
- .byte 0x66,0xb8\r
-ASM_PFX(gSmmCr0): .space 4\r
- .byte 0xbf, PROTECT_MODE_DS, 0 # mov di, PROTECT_MODE_DS\r
- movl %eax, %cr0\r
- .byte 0x66,0xea # jmp far [ptr48]\r
-ASM_PFX(gSmmJmpAddr): .long Start32bit\r
- .word PROTECT_MODE_CS\r
-Start32bit:\r
- movl %edi,%ds\r
- movl %edi,%es\r
- movl %edi,%fs\r
- movl %edi,%gs\r
- movl %edi,%ss\r
- .byte 0xbc # mov esp, imm32\r
-ASM_PFX(gSmmInitStack): .space 4\r
- call ASM_PFX(SmmInitHandler)\r
- rsm\r
-\r
-ASM_PFX(gcSmmInitTemplate):\r
-\r
-_SmmInitTemplate:\r
- .byte 0x66\r
- movl $SmmStartup, %ebp\r
- .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000\r
- jmp *%bp # jmp ebp actually\r
-\r
-ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate)\r
-\r
-\r
-ASM_PFX(SmmRelocationSemaphoreComplete):\r
- pushl %eax\r
- movl ASM_PFX(mRebasedFlag), %eax\r
- movb $1, (%eax)\r
- popl %eax\r
- jmp *ASM_PFX(mSmmRelocationOriginalAddress)\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; SmmInit.Asm\r
-;\r
-; Abstract:\r
-;\r
-; Functions for relocating SMBASE's for all processors\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
- .686p\r
- .xmm\r
- .model flat,C\r
-\r
-SmmInitHandler PROTO C\r
-\r
-EXTERNDEF C gSmmCr0:DWORD\r
-EXTERNDEF C gSmmCr3:DWORD\r
-EXTERNDEF C gSmmCr4:DWORD\r
-EXTERNDEF C gcSmmInitTemplate:BYTE\r
-EXTERNDEF C gcSmmInitSize:WORD\r
-EXTERNDEF C gSmmJmpAddr:QWORD\r
-EXTERNDEF C mRebasedFlag:PTR BYTE\r
-EXTERNDEF C mSmmRelocationOriginalAddress:DWORD\r
-EXTERNDEF C gSmmInitStack:DWORD\r
-EXTERNDEF C gcSmiInitGdtr:FWORD\r
-\r
-PROTECT_MODE_CS EQU 08h\r
-PROTECT_MODE_DS EQU 20h\r
-\r
- .code\r
-\r
-gcSmiInitGdtr LABEL FWORD\r
- DW 0\r
- DQ 0\r
-\r
-SmmStartup PROC\r
- DB 66h, 0b8h\r
-gSmmCr3 DD ?\r
- mov cr3, eax\r
- DB 67h, 66h\r
- lgdt fword ptr cs:[ebp + (offset gcSmiInitGdtr - SmmStartup)]\r
- DB 66h, 0b8h\r
-gSmmCr4 DD ?\r
- mov cr4, eax\r
- DB 66h, 0b8h\r
-gSmmCr0 DD ?\r
- DB 0bfh, PROTECT_MODE_DS, 0 ; mov di, PROTECT_MODE_DS\r
- mov cr0, eax\r
- DB 66h, 0eah ; jmp far [ptr48]\r
-gSmmJmpAddr LABEL QWORD\r
- DD @32bit\r
- DW PROTECT_MODE_CS\r
-@32bit:\r
- mov ds, edi\r
- mov es, edi\r
- mov fs, edi\r
- mov gs, edi\r
- mov ss, edi\r
- DB 0bch ; mov esp, imm32\r
-gSmmInitStack DD ?\r
- call SmmInitHandler\r
- rsm\r
-SmmStartup ENDP\r
-\r
-gcSmmInitTemplate LABEL BYTE\r
-\r
-_SmmInitTemplate PROC\r
- DB 66h\r
- mov ebp, SmmStartup\r
- DB 66h, 81h, 0edh, 00h, 00h, 03h, 00 ; sub ebp, 30000h\r
- jmp bp ; jmp ebp actually\r
-_SmmInitTemplate ENDP\r
-\r
-gcSmmInitSize DW $ - gcSmmInitTemplate\r
-\r
-SmmRelocationSemaphoreComplete PROC\r
- push eax\r
- mov eax, mRebasedFlag\r
- mov byte ptr [eax], 1\r
- pop eax\r
- jmp [mSmmRelocationOriginalAddress]\r
-SmmRelocationSemaphoreComplete ENDP\r
- END\r
Ia32/SmmFuncsArch.c\r
Ia32/SmmProfileArch.c\r
Ia32/SmmProfileArch.h\r
- Ia32/SmmInit.asm\r
- Ia32/SmiEntry.asm\r
- Ia32/SmiException.asm\r
- Ia32/MpFuncs.asm\r
-\r
Ia32/SmmInit.nasm\r
Ia32/SmiEntry.nasm\r
Ia32/SmiException.nasm\r
Ia32/MpFuncs.nasm\r
\r
- Ia32/SmmInit.S\r
- Ia32/SmiEntry.S\r
- Ia32/SmiException.S\r
- Ia32/MpFuncs.S\r
-\r
[Sources.X64]\r
X64/Semaphore.c\r
X64/PageTbl.c\r
X64/SmmFuncsArch.c\r
X64/SmmProfileArch.c\r
X64/SmmProfileArch.h\r
- X64/SmmInit.asm\r
- X64/SmiEntry.asm\r
- X64/SmiException.asm\r
- X64/MpFuncs.asm\r
-\r
X64/SmmInit.nasm\r
X64/SmiEntry.nasm\r
X64/SmiException.nasm\r
X64/MpFuncs.nasm\r
\r
- X64/SmmInit.S\r
- X64/SmiEntry.S\r
- X64/SmiException.S\r
- X64/MpFuncs.S\r
-\r
[Packages]\r
MdePkg/MdePkg.dec\r
MdeModulePkg/MdeModulePkg.dec\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# MpFuncs.S\r
-#\r
-# Abstract:\r
-#\r
-# This is the assembly code for Multi-processor S3 support\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-.equ VacantFlag, 0x0\r
-.equ NotVacantFlag, 0xff\r
-\r
-.equ LockLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
-.equ StackStartAddressLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08\r
-.equ StackSizeLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10\r
-.equ CProcedureLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x18\r
-.equ GdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x20\r
-.equ IdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x2A\r
-.equ BufferStartLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x34\r
-.equ Cr3OffsetLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38\r
-\r
-#-------------------------------------------------------------------------------------\r
-#RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
-#procedure serializes all the AP processors through an Init sequence. It must be\r
-#noted that APs arrive here very raw...ie: real mode, no stack.\r
-#ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
-#IS IN MACHINE CODE.\r
-#-------------------------------------------------------------------------------------\r
-#RendezvousFunnelProc (&WakeUpBuffer,MemAddress);\r
-\r
-.code:\r
-\r
-ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)\r
-ASM_PFX(RendezvousFunnelProc):\r
-RendezvousFunnelProcStart:\r
-\r
-# At this point CS = 0x(vv00) and ip= 0x0.\r
-\r
- .byte 0x8c,0xc8 # mov ax, cs\r
- .byte 0x8e,0xd8 # mov ds, ax\r
- .byte 0x8e,0xc0 # mov es, ax\r
- .byte 0x8e,0xd0 # mov ss, ax\r
- .byte 0x33,0xc0 # xor ax, ax\r
- .byte 0x8e,0xe0 # mov fs, ax\r
- .byte 0x8e,0xe8 # mov gs, ax\r
-\r
-flat32Start:\r
-\r
- .byte 0xBE\r
- .word BufferStartLocation\r
- .byte 0x66,0x8B,0x14 # mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer\r
-\r
- .byte 0xBE\r
- .word Cr3OffsetLocation\r
- .byte 0x66,0x8B,0xC # mov ecx,dword ptr [si] ; ECX is keeping the value of CR3\r
-\r
- .byte 0xBE\r
- .word GdtrLocation\r
- .byte 0x66 # db 66h\r
- .byte 0x2E,0xF,0x1,0x14 # lgdt fword ptr cs:[si]\r
-\r
- .byte 0xBE\r
- .word IdtrLocation\r
- .byte 0x66 # db 66h\r
- .byte 0x2E,0xF,0x1,0x1C # lidt fword ptr cs:[si]\r
-\r
- .byte 0x33,0xC0 # xor ax, ax\r
- .byte 0x8E,0xD8 # mov ds, ax\r
-\r
- .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Get control register 0\r
- .byte 0x66,0x83,0xC8,0x1 # or eax, 000000001h ; Set PE bit (bit #0)\r
- .byte 0xF,0x22,0xC0 # mov cr0, eax\r
-\r
-FLAT32_JUMP:\r
-\r
- .byte 0x66,0x67,0xEA # far jump\r
- .long 0x0 # 32-bit offset\r
- .word 0x20 # 16-bit selector\r
-\r
-PMODE_ENTRY: # protected mode entry point\r
-\r
- .byte 0x66,0xB8,0x18,0x0 # mov ax, 18h\r
- .byte 0x66,0x8E,0xD8 # mov ds, ax\r
- .byte 0x66,0x8E,0xC0 # mov es, ax\r
- .byte 0x66,0x8E,0xE0 # mov fs, ax\r
- .byte 0x66,0x8E,0xE8 # mov gs, ax\r
- .byte 0x66,0x8E,0xD0 # mov ss, ax ; Flat mode setup.\r
-\r
- .byte 0xF,0x20,0xE0 # mov eax, cr4\r
- .byte 0xF,0xBA,0xE8,0x5 # bts eax, 5\r
- .byte 0xF,0x22,0xE0 # mov cr4, eax\r
-\r
- .byte 0xF,0x22,0xD9 # mov cr3, ecx\r
-\r
- .byte 0x8B,0xF2 # mov esi, edx ; Save wakeup buffer address\r
-\r
- .byte 0xB9\r
- .long 0xC0000080 # mov ecx, 0c0000080h ; EFER MSR number.\r
- .byte 0xF,0x32 # rdmsr ; Read EFER.\r
- .byte 0xF,0xBA,0xE8,0x8 # bts eax, 8 ; Set LME=1.\r
- .byte 0xF,0x30 # wrmsr ; Write EFER.\r
-\r
- .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Read CR0.\r
- .byte 0xF,0xBA,0xE8,0x1F # bts eax, 31 ; Set PG=1.\r
- .byte 0xF,0x22,0xC0 # mov cr0, eax ; Write CR0.\r
-\r
-LONG_JUMP:\r
-\r
- .byte 0x67,0xEA # far jump\r
- .long 0x0 # 32-bit offset\r
- .word 0x38 # 16-bit selector\r
-\r
-LongModeStart:\r
-\r
- movw $0x30,%ax\r
- .byte 0x66\r
- movw %ax,%ds\r
- .byte 0x66\r
- movw %ax,%es\r
- .byte 0x66\r
- movw %ax,%ss\r
-\r
- movl %esi,%edi\r
- addl $LockLocation, %edi\r
- movb $NotVacantFlag, %al\r
-TestLock:\r
- xchgb (%edi), %al\r
- cmpb $NotVacantFlag, %al\r
- jz TestLock\r
-\r
-ProgramStack:\r
-\r
- movl %esi,%edi\r
- addl $StackSizeLocation, %edi\r
- movq (%edi), %rax\r
- movl %esi,%edi\r
- addl $StackStartAddressLocation, %edi\r
- addq (%edi), %rax\r
- movq %rax, %rsp\r
- movq %rax, (%edi)\r
-\r
-Releaselock:\r
-\r
- movb $VacantFlag, %al\r
- movl %esi,%edi\r
- addl $LockLocation, %edi\r
- xchgb (%edi), %al\r
-\r
- #\r
- # Call assembly function to initialize FPU.\r
- #\r
- movabsq $ASM_PFX(InitializeFloatingPointUnits), %rax\r
- subq $0x20, %rsp\r
- call *%rax\r
- addq $0x20, %rsp\r
- #\r
- # Call C Function\r
- #\r
- movl %esi,%edi\r
- addl $CProcedureLocation, %edi\r
- movq (%edi), %rax\r
-\r
- testq %rax, %rax\r
- jz GoToSleep\r
-\r
- subq $0x20, %rsp\r
- call *%rax\r
- addq $0x20, %rsp\r
-\r
-GoToSleep:\r
- cli\r
- hlt\r
- jmp .-2\r
-\r
-RendezvousFunnelProcEnd:\r
-\r
-\r
-#-------------------------------------------------------------------------------------\r
-# AsmGetAddressMap (&AddressMap);\r
-#-------------------------------------------------------------------------------------\r
-# comments here for definition of address map\r
-ASM_GLOBAL ASM_PFX(AsmGetAddressMap)\r
-ASM_PFX(AsmGetAddressMap):\r
- movabsq $RendezvousFunnelProcStart, %rax\r
- movq %rax, (%rcx)\r
- movq $(PMODE_ENTRY - RendezvousFunnelProcStart), 0x08(%rcx)\r
- movq $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x10(%rcx)\r
- movq $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x18(%rcx)\r
- movq $(LongModeStart - RendezvousFunnelProcStart), 0x20(%rcx)\r
- movq $(LONG_JUMP - RendezvousFunnelProcStart), 0x28(%rcx)\r
- ret\r
-\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; MpFuncs.asm\r
-;\r
-; Abstract:\r
-;\r
-; This is the assembly code for Multi-processor S3 support\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
-EXTERN InitializeFloatingPointUnits:PROC\r
-\r
-VacantFlag Equ 00h\r
-NotVacantFlag Equ 0ffh\r
-\r
-LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
-StackStartAddressLocation equ LockLocation + 08h\r
-StackSizeLocation equ LockLocation + 10h\r
-CProcedureLocation equ LockLocation + 18h\r
-GdtrLocation equ LockLocation + 20h\r
-IdtrLocation equ LockLocation + 2Ah\r
-BufferStartLocation equ LockLocation + 34h\r
-Cr3OffsetLocation equ LockLocation + 38h\r
-\r
-;-------------------------------------------------------------------------------------\r
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
-;procedure serializes all the AP processors through an Init sequence. It must be\r
-;noted that APs arrive here very raw...ie: real mode, no stack.\r
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
-;IS IN MACHINE CODE.\r
-;-------------------------------------------------------------------------------------\r
-;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);\r
-\r
-;text SEGMENT\r
-.code\r
-\r
-RendezvousFunnelProc PROC\r
-RendezvousFunnelProcStart::\r
-\r
-; At this point CS = 0x(vv00) and ip= 0x0.\r
-\r
- db 8ch, 0c8h ; mov ax, cs\r
- db 8eh, 0d8h ; mov ds, ax\r
- db 8eh, 0c0h ; mov es, ax\r
- db 8eh, 0d0h ; mov ss, ax\r
- db 33h, 0c0h ; xor ax, ax\r
- db 8eh, 0e0h ; mov fs, ax\r
- db 8eh, 0e8h ; mov gs, ax\r
-\r
-flat32Start::\r
-\r
- db 0BEh\r
- dw BufferStartLocation ; mov si, BufferStartLocation\r
- db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer\r
-\r
- db 0BEh\r
- dw Cr3OffsetLocation ; mov si, Cr3Location\r
- db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3\r
-\r
- db 0BEh\r
- dw GdtrLocation ; mov si, GdtrProfile\r
- db 66h ; db 66h\r
- db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]\r
-\r
- db 0BEh\r
- dw IdtrLocation ; mov si, IdtrProfile\r
- db 66h ; db 66h\r
- db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]\r
-\r
- db 33h, 0C0h ; xor ax, ax\r
- db 8Eh, 0D8h ; mov ds, ax\r
-\r
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0\r
- db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)\r
- db 0Fh, 22h, 0C0h ; mov cr0, eax\r
-\r
-FLAT32_JUMP::\r
-\r
- db 66h, 67h, 0EAh ; far jump\r
- dd 0h ; 32-bit offset\r
- dw 20h ; 16-bit selector\r
-\r
-PMODE_ENTRY:: ; protected mode entry point\r
-\r
- db 66h, 0B8h, 18h, 00h ; mov ax, 18h\r
- db 66h, 8Eh, 0D8h ; mov ds, ax\r
- db 66h, 8Eh, 0C0h ; mov es, ax\r
- db 66h, 8Eh, 0E0h ; mov fs, ax\r
- db 66h, 8Eh, 0E8h ; mov gs, ax\r
- db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.\r
-\r
- db 0Fh, 20h, 0E0h ; mov eax, cr4\r
- db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5\r
- db 0Fh, 22h, 0E0h ; mov cr4, eax\r
-\r
- db 0Fh, 22h, 0D9h ; mov cr3, ecx\r
-\r
- db 8Bh, 0F2h ; mov esi, edx ; Save wakeup buffer address\r
-\r
- db 0B9h\r
- dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.\r
- db 0Fh, 32h ; rdmsr ; Read EFER.\r
- db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.\r
- db 0Fh, 30h ; wrmsr ; Write EFER.\r
-\r
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.\r
- db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.\r
- db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.\r
-\r
-LONG_JUMP::\r
-\r
- db 67h, 0EAh ; far jump\r
- dd 0h ; 32-bit offset\r
- dw 38h ; 16-bit selector\r
-\r
-LongModeStart::\r
-\r
- mov ax, 30h\r
- mov ds, ax\r
- mov es, ax\r
- mov ss, ax\r
-\r
- mov edi, esi\r
- add edi, LockLocation\r
- mov al, NotVacantFlag\r
-TestLock::\r
- xchg byte ptr [edi], al\r
- cmp al, NotVacantFlag\r
- jz TestLock\r
-\r
-ProgramStack::\r
-\r
- mov edi, esi\r
- add edi, StackSizeLocation\r
- mov rax, qword ptr [edi]\r
- mov edi, esi\r
- add edi, StackStartAddressLocation\r
- add rax, qword ptr [edi]\r
- mov rsp, rax\r
- mov qword ptr [edi], rax\r
-\r
-Releaselock::\r
-\r
- mov al, VacantFlag\r
- mov edi, esi\r
- add edi, LockLocation\r
- xchg byte ptr [edi], al\r
-\r
- ;\r
- ; Call assembly function to initialize FPU.\r
- ;\r
- mov rax, InitializeFloatingPointUnits\r
- sub rsp, 20h\r
- call rax\r
- add rsp, 20h\r
-\r
- ;\r
- ; Call C Function\r
- ;\r
- mov edi, esi\r
- add edi, CProcedureLocation\r
- mov rax, qword ptr [edi]\r
-\r
- test rax, rax\r
- jz GoToSleep\r
-\r
- sub rsp, 20h\r
- call rax\r
- add rsp, 20h\r
-\r
-GoToSleep::\r
- cli\r
- hlt\r
- jmp $-2\r
-\r
-RendezvousFunnelProcEnd::\r
-RendezvousFunnelProc ENDP\r
-\r
-\r
-;-------------------------------------------------------------------------------------\r
-; AsmGetAddressMap (&AddressMap);\r
-;-------------------------------------------------------------------------------------\r
-; comments here for definition of address map\r
-AsmGetAddressMap PROC\r
- mov rax, offset RendezvousFunnelProcStart\r
- mov qword ptr [rcx], rax\r
- mov qword ptr [rcx+8h], PMODE_ENTRY - RendezvousFunnelProcStart\r
- mov qword ptr [rcx+10h], FLAT32_JUMP - RendezvousFunnelProcStart\r
- mov qword ptr [rcx+18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
- mov qword ptr [rcx+20h], LongModeStart - RendezvousFunnelProcStart\r
- mov qword ptr [rcx+28h], LONG_JUMP - RendezvousFunnelProcStart\r
- ret\r
-\r
-AsmGetAddressMap ENDP\r
-\r
-END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# SmiEntry.S\r
-#\r
-# Abstract:\r
-#\r
-# Code template of the SMI handler for a particular processor\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)\r
-ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)\r
-ASM_GLOBAL ASM_PFX(gSmiCr3)\r
-ASM_GLOBAL ASM_PFX(gSmiStack)\r
-ASM_GLOBAL ASM_PFX(gSmbase)\r
-ASM_GLOBAL ASM_PFX(mXdSupported)\r
-ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)\r
-\r
-.equ MSR_IA32_MISC_ENABLE, 0x1A0\r
-.equ MSR_EFER, 0xc0000080\r
-.equ MSR_EFER_XD, 0x800\r
-\r
-#\r
-# Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
-#\r
-.equ DSC_OFFSET, 0xfb00\r
-.equ DSC_GDTPTR, 0x30\r
-.equ DSC_GDTSIZ, 0x38\r
-.equ DSC_CS, 14\r
-.equ DSC_DS, 16\r
-.equ DSC_SS, 18\r
-.equ DSC_OTHERSEG, 20\r
-#\r
-# Constants relating to CPU State Save Area\r
-#\r
-.equ SSM_DR6, 0xffd0\r
-.equ SSM_DR7, 0xffc8\r
-\r
-.equ PROTECT_MODE_CS, 0x08\r
-.equ PROTECT_MODE_DS, 0x20\r
-.equ LONG_MODE_CS, 0x38\r
-.equ TSS_SEGMENT, 0x40\r
-.equ GDT_SIZE, 0x50\r
-\r
- .text\r
-\r
-ASM_PFX(gcSmiHandlerTemplate):\r
-\r
-_SmiEntryPoint:\r
- #\r
- # The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-\r
- # bit addressing mode. And that coincidence has been used in the following\r
- # "64-bit like" 16-bit code. Be aware that once RDI is referenced as a\r
- # base address register, it is actually BX that is referenced.\r
- #\r
- .byte 0xbb # mov bx, imm16\r
- .word _GdtDesc - _SmiEntryPoint + 0x8000\r
- #\r
- # fix GDT descriptor\r
- #\r
- .byte 0x2e,0xa1 # mov ax, cs:[offset16]\r
- .word DSC_OFFSET + DSC_GDTSIZ\r
- .byte 0x48 # dec ax\r
- .byte 0x2e\r
- movl %eax, (%rdi) # mov cs:[bx], ax\r
- .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]\r
- .word DSC_OFFSET + DSC_GDTPTR\r
- .byte 0x2e\r
- movw %ax, 2(%rdi)\r
- .byte 0x66,0x2e\r
- lgdt (%rdi)\r
- #\r
- # Patch ProtectedMode Segment\r
- #\r
- .byte 0xb8\r
- .word PROTECT_MODE_CS\r
- .byte 0x2e\r
- movl %eax, -2(%rdi)\r
- #\r
- # Patch ProtectedMode entry\r
- #\r
- .byte 0x66, 0xbf # mov edi, SMBASE\r
-ASM_PFX(gSmbase): .space 4\r
- lea ((ProtectedMode - _SmiEntryPoint) + 0x8000)(%edi), %ax\r
- .byte 0x2e\r
- movw %ax, -6(%rdi)\r
- #\r
- # Switch into ProtectedMode\r
- #\r
- movq %cr0, %rbx\r
- .byte 0x66\r
- andl $0x9ffafff3, %ebx\r
- .byte 0x66\r
- orl $0x00000023, %ebx\r
-\r
- movq %rbx, %cr0\r
- .byte 0x66, 0xea\r
- .space 6\r
-\r
-_GdtDesc: .space 6\r
-\r
-ProtectedMode:\r
- movw $PROTECT_MODE_DS, %ax\r
- movl %eax, %ds\r
- movl %eax, %es\r
- movl %eax, %fs\r
- movl %eax, %gs\r
- movl %eax, %ss\r
- .byte 0xbc # mov esp, imm32\r
-ASM_PFX(gSmiStack): .space 4\r
- jmp ProtFlatMode\r
-\r
-ProtFlatMode:\r
- .byte 0xb8\r
-ASM_PFX(gSmiCr3): .space 4\r
- movq %rax, %cr3\r
- movl $0x668,%eax # as cr4.PGE is not set here, refresh cr3\r
- movq %rax, %cr4 # in PreModifyMtrrs() to flush TLB.\r
-# Load TSS\r
- subl $8, %esp # reserve room in stack\r
- sgdt (%rsp)\r
- movl 2(%rsp), %eax # eax = GDT base\r
- addl $8, %esp\r
- movb $0x89, %dl\r
- movb %dl, (TSS_SEGMENT + 5)(%rax) # clear busy flag\r
- movl $TSS_SEGMENT, %eax\r
- ltr %ax\r
-\r
-# enable NXE if supported\r
- .byte 0xb0 # mov al, imm8\r
-ASM_PFX(mXdSupported): .byte 1\r
- cmpb $0, %al\r
- jz SkipNxe\r
-#\r
-# Check XD disable bit\r
-#\r
- movl $MSR_IA32_MISC_ENABLE, %ecx\r
- rdmsr\r
- subl $4, %esp\r
- pushq %rdx # save MSR_IA32_MISC_ENABLE[63-32]\r
- testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34]\r
- jz L13\r
- andw $0x0FFFB, %dx # clear XD Disable bit if it is set\r
- wrmsr\r
-L13:\r
- movl $MSR_EFER, %ecx\r
- rdmsr\r
- orw $MSR_EFER_XD,%ax # enable NXE\r
- wrmsr\r
- jmp NxeDone\r
-SkipNxe:\r
- subl $8, %esp\r
-NxeDone:\r
-\r
- #\r
- # Switch to LongMode\r
- #\r
- pushq $LONG_MODE_CS # push cs hardcore here\r
- call Base # push return address for retf later\r
-Base:\r
- addl $(LongMode - Base), (%rsp) # offset for far retf, seg is the 1st arg\r
-\r
- movl $MSR_EFER, %ecx\r
- rdmsr\r
- orb $1,%ah # enable LME\r
- wrmsr\r
- movq %cr0, %rbx\r
- orl $0x080010023, %ebx # enable paging + WP + NE + MP + PE\r
- movq %rbx, %cr0\r
- retf\r
-LongMode: # long mode (64-bit code) starts here\r
- movabsq $ASM_PFX(gSmiHandlerIdtr), %rax\r
- lidt (%rax)\r
- lea (DSC_OFFSET)(%rdi), %ebx\r
- movw DSC_DS(%rbx), %ax\r
- movl %eax,%ds\r
- movw DSC_OTHERSEG(%rbx), %ax\r
- movl %eax,%es\r
- movl %eax,%fs\r
- movl %eax,%gs\r
- movw DSC_SS(%rbx), %ax\r
- movl %eax,%ss\r
-# jmp _SmiHandler ; instruction is not needed\r
-\r
-_SmiHandler:\r
- movq 8(%rsp), %rbx\r
- # Save FP registers\r
-\r
- subq $0x200, %rsp\r
- .byte 0x48 # FXSAVE64\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
- # Restore FP registers\r
- #\r
- .byte 0x48 # FXRSTOR64\r
- fxrstor (%rsp)\r
-\r
- addq $0x200, %rsp\r
-\r
- movabsq $ASM_PFX(mXdSupported), %rax\r
- movb (%rax), %al\r
- cmpb $0, %al\r
- jz L16\r
- popq %rdx # get saved MSR_IA32_MISC_ENABLE[63-32]\r
- testl $BIT2, %edx\r
- jz L16\r
- movl $MSR_IA32_MISC_ENABLE, %ecx\r
- rdmsr\r
- orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM\r
- wrmsr\r
-\r
-L16:\r
- rsm\r
-\r
-ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; SmiEntry.asm\r
-;\r
-; Abstract:\r
-;\r
-; Code template of the SMI handler for a particular processor\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
-;\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 mXdSupported:BYTE\r
-EXTERNDEF gSmiHandlerIdtr:FWORD\r
-\r
-MSR_IA32_MISC_ENABLE EQU 1A0h\r
-MSR_EFER EQU 0c0000080h\r
-MSR_EFER_XD EQU 0800h\r
-\r
-;\r
-; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
-;\r
-DSC_OFFSET EQU 0fb00h\r
-DSC_GDTPTR EQU 30h\r
-DSC_GDTSIZ EQU 38h\r
-DSC_CS EQU 14\r
-DSC_DS EQU 16\r
-DSC_SS EQU 18\r
-DSC_OTHERSEG EQU 20\r
-;\r
-; Constants relating to CPU State Save Area\r
-;\r
-SSM_DR6 EQU 0ffd0h\r
-SSM_DR7 EQU 0ffc8h\r
-\r
-PROTECT_MODE_CS EQU 08h\r
-PROTECT_MODE_DS EQU 20h\r
-LONG_MODE_CS EQU 38h\r
-TSS_SEGMENT EQU 40h\r
-GDT_SIZE EQU 50h\r
-\r
- .code\r
-\r
-gcSmiHandlerTemplate LABEL BYTE\r
-\r
-_SmiEntryPoint:\r
- ;\r
- ; The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-\r
- ; bit addressing mode. And that coincidence has been used in the following\r
- ; "64-bit like" 16-bit code. Be aware that once RDI is referenced as a\r
- ; base address register, it is actually BX that is referenced.\r
- ;\r
- DB 0bbh ; mov bx, imm16\r
- DW offset _GdtDesc - _SmiEntryPoint + 8000h ; bx = GdtDesc offset\r
-; fix GDT descriptor\r
- DB 2eh, 0a1h ; mov ax, cs:[offset16]\r
- DW DSC_OFFSET + DSC_GDTSIZ\r
- DB 48h ; dec ax\r
- DB 2eh\r
- mov [rdi], eax ; mov cs:[bx], ax\r
- DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]\r
- DW DSC_OFFSET + DSC_GDTPTR\r
- DB 2eh\r
- mov [rdi + 2], ax ; mov cs:[bx + 2], eax\r
- DB 66h, 2eh\r
- lgdt fword ptr [rdi] ; lgdt fword ptr cs:[bx]\r
-; Patch ProtectedMode Segment\r
- DB 0b8h ; mov ax, imm16\r
- DW PROTECT_MODE_CS ; set AX for segment directly\r
- DB 2eh\r
- mov [rdi - 2], eax ; mov cs:[bx - 2], ax\r
-; Patch ProtectedMode entry\r
- DB 66h, 0bfh ; mov edi, SMBASE\r
-gSmbase DD ?\r
- lea ax, [edi + (@ProtectedMode - _SmiEntryPoint) + 8000h]\r
- DB 2eh\r
- mov [rdi - 6], ax ; mov cs:[bx - 6], eax\r
-; Switch into @ProtectedMode\r
- mov rbx, cr0\r
- DB 66h\r
- and ebx, 9ffafff3h\r
- DB 66h\r
- or ebx, 00000023h\r
-\r
- mov cr0, rbx\r
- DB 66h, 0eah\r
- DD ?\r
- DW ?\r
-\r
-_GdtDesc FWORD ?\r
-@ProtectedMode:\r
- mov ax, PROTECT_MODE_DS\r
- mov ds, ax\r
- mov es, ax\r
- mov fs, ax\r
- mov gs, ax\r
- mov ss, ax\r
- DB 0bch ; mov esp, imm32\r
-gSmiStack DD ?\r
- jmp ProtFlatMode\r
-\r
-ProtFlatMode:\r
- DB 0b8h ; mov eax, offset gSmiCr3\r
-gSmiCr3 DD ?\r
- mov cr3, rax\r
- mov eax, 668h ; as cr4.PGE is not set here, refresh cr3\r
- mov cr4, rax ; in PreModifyMtrrs() to flush TLB.\r
-; Load TSS\r
- sub esp, 8 ; reserve room in stack\r
- sgdt fword ptr [rsp]\r
- mov eax, [rsp + 2] ; eax = GDT base\r
- add esp, 8\r
- mov dl, 89h\r
- mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
- mov eax, TSS_SEGMENT\r
- ltr ax\r
-\r
-; enable NXE if supported\r
- DB 0b0h ; mov al, imm8\r
-mXdSupported DB 1\r
- cmp al, 0\r
- jz @SkipXd\r
-;\r
-; Check XD disable bit\r
-;\r
- mov ecx, MSR_IA32_MISC_ENABLE\r
- rdmsr\r
- sub esp, 4\r
- push rdx ; save MSR_IA32_MISC_ENABLE[63-32]\r
- test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
- jz @f\r
- and dx, 0FFFBh ; clear XD Disable bit if it is set\r
- wrmsr\r
-@@:\r
- mov ecx, MSR_EFER\r
- rdmsr\r
- or ax, MSR_EFER_XD ; enable NXE\r
- wrmsr\r
- jmp @XdDone\r
-@SkipXd:\r
- sub esp, 8\r
-@XdDone:\r
-\r
-; Switch into @LongMode\r
- push LONG_MODE_CS ; push cs hardcore here\r
- call Base ; push return address for retf later\r
-Base:\r
- add dword ptr [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg\r
-\r
- mov ecx, MSR_EFER\r
- rdmsr\r
- or ah, 1 ; enable LME\r
- wrmsr\r
- mov rbx, cr0\r
- or ebx, 080010023h ; enable paging + WP + NE + MP + PE\r
- mov cr0, rbx\r
- retf\r
-@LongMode: ; long mode (64-bit code) starts here\r
- mov rax, offset gSmiHandlerIdtr\r
- lidt fword ptr [rax]\r
- lea ebx, [rdi + DSC_OFFSET]\r
- mov ax, [rbx + DSC_DS]\r
- mov ds, eax\r
- mov ax, [rbx + DSC_OTHERSEG]\r
- mov es, eax\r
- mov fs, eax\r
- mov gs, eax\r
- mov ax, [rbx + DSC_SS]\r
- mov ss, eax\r
-; jmp _SmiHandler ; instruction is not needed\r
-\r
-_SmiHandler:\r
- mov rbx, [rsp] ; rbx <- CpuIndex\r
-\r
- ;\r
- ; Save FP registers\r
- ;\r
- sub rsp, 200h\r
- DB 48h ; FXSAVE64\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
- ; Restore FP registers\r
- ;\r
- DB 48h ; FXRSTOR64\r
- fxrstor [rsp]\r
-\r
- add rsp, 200h\r
-\r
- mov rax, offset ASM_PFX(mXdSupported)\r
- mov al, [rax]\r
- cmp al, 0\r
- jz @f\r
- pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
- test edx, BIT2\r
- jz @f\r
- mov ecx, MSR_IA32_MISC_ENABLE\r
- rdmsr\r
- or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
- wrmsr\r
-\r
-@@:\r
- rsm\r
-\r
-gcSmiHandlerSize DW $ - _SmiEntryPoint\r
-\r
- END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# SmiException.S\r
-#\r
-# Abstract:\r
-#\r
-# Exception handlers used in SM mode\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(SmiPFHandler)\r
-ASM_GLOBAL ASM_PFX(gcSmiIdtr)\r
-ASM_GLOBAL ASM_PFX(gcSmiGdtr)\r
-ASM_GLOBAL ASM_PFX(gcPsd)\r
-\r
- .data\r
-\r
-NullSeg: .quad 0 # reserved by architecture\r
-CodeSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x9b\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-ProtModeCodeSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x9b\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-ProtModeSsSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x93\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-DataSeg32:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x93\r
- .byte 0xcf # LimitHigh\r
- .byte 0 # BaseHigh\r
-CodeSeg16:\r
- .word -1\r
- .word 0\r
- .byte 0\r
- .byte 0x9b\r
- .byte 0x8f\r
- .byte 0\r
-DataSeg16:\r
- .word -1\r
- .word 0\r
- .byte 0\r
- .byte 0x93\r
- .byte 0x8f\r
- .byte 0\r
-CodeSeg64:\r
- .word -1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x9b\r
- .byte 0xaf # LimitHigh\r
- .byte 0 # BaseHigh\r
-# TSS Segment for X64 specially\r
-TssSeg:\r
- .word TSS_DESC_SIZE - 1 # LimitLow\r
- .word 0 # BaseLow\r
- .byte 0 # BaseMid\r
- .byte 0x89\r
- .byte 0x00 # LimitHigh\r
- .byte 0 # BaseHigh\r
- .long 0 # BaseUpper\r
- .long 0 # Reserved\r
-.equ GDT_SIZE, .- NullSeg\r
-\r
-TssDescriptor:\r
- .space 104, 0\r
-.equ TSS_DESC_SIZE, .- TssDescriptor\r
-\r
-#\r
-# This structure serves as a template for all processors.\r
-#\r
-ASM_PFX(gcPsd):\r
- .ascii "PSDSIG "\r
- .word PSD_SIZE\r
- .word 2\r
- .word 1 << 2\r
- .word CODE_SEL\r
- .word DATA_SEL\r
- .word DATA_SEL\r
- .word DATA_SEL\r
- .word 0\r
- .quad 0\r
- .quad 0\r
- .quad 0 # fixed in InitializeMpServiceData()\r
- .quad NullSeg\r
- .long GDT_SIZE\r
- .long 0\r
- .space 24, 0\r
- .quad 0\r
-.equ PSD_SIZE, . - ASM_PFX(gcPsd)\r
-\r
-#\r
-# CODE & DATA segments for SMM runtime\r
-#\r
-.equ CODE_SEL, CodeSeg64 - NullSeg\r
-.equ DATA_SEL, DataSeg32 - NullSeg\r
-.equ CODE32_SEL, CodeSeg32 - NullSeg\r
-\r
-ASM_PFX(gcSmiGdtr):\r
- .word GDT_SIZE - 1\r
- .quad NullSeg\r
-\r
-ASM_PFX(gcSmiIdtr):\r
- .word 0\r
- .quad 0\r
-\r
- .text\r
-\r
-#------------------------------------------------------------------------------\r
-# _SmiExceptionEntryPoints is the collection of exception entry points followed\r
-# by a common exception handler.\r
-#\r
-# Stack frame would be as follows as specified in IA32 manuals:\r
-# +---------------------+ <-- 16-byte aligned ensured by processor\r
-# + Old SS +\r
-# +---------------------+\r
-# + Old RSP +\r
-# +---------------------+\r
-# + RFlags +\r
-# +---------------------+\r
-# + CS +\r
-# +---------------------+\r
-# + RIP +\r
-# +---------------------+\r
-# + Error Code +\r
-# +---------------------+\r
-# + Vector Number +\r
-# +---------------------+\r
-# + RBP +\r
-# +---------------------+ <-- RBP, 16-byte aligned\r
-#\r
-# RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT\r
-#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)\r
-ASM_PFX(PageFaultIdtHandlerSmmProfile):\r
- pushq $0x0e # Page Fault\r
- .byte 0x40, 0xf6, 0xc4, 0x08 #test spl, 8\r
- jnz L1\r
- pushq (%rsp)\r
- movq $0, 8(%rsp)\r
-L1:\r
- pushq %rbp\r
- movq %rsp, %rbp\r
-\r
- #\r
- # Since here the stack pointer is 16-byte aligned, so\r
- # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
- # is 16-byte aligned\r
- #\r
-\r
-## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pushq %r15\r
- pushq %r14\r
- pushq %r13\r
- pushq %r12\r
- pushq %r11\r
- pushq %r10\r
- pushq %r9\r
- pushq %r8\r
- pushq %rax\r
- pushq %rcx\r
- pushq %rdx\r
- pushq %rbx\r
- pushq 48(%rbp) # RSP\r
- pushq (%rbp) # RBP\r
- pushq %rsi\r
- pushq %rdi\r
-\r
-## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- movzwq 56(%rbp), %rax\r
- pushq %rax # for ss\r
- movzwq 32(%rbp), %rax\r
- pushq %rax # for cs\r
- movq %ds, %rax\r
- pushq %rax\r
- movq %es, %rax\r
- pushq %rax\r
- movq %fs, %rax\r
- pushq %rax\r
- movq %gs, %rax\r
- pushq %rax\r
-\r
-## UINT64 Rip;\r
- pushq 24(%rbp)\r
-\r
-## UINT64 Gdtr[2], Idtr[2];\r
- subq $16, %rsp\r
- sidt (%rsp)\r
- subq $16, %rsp\r
- sgdt (%rsp)\r
-\r
-## UINT64 Ldtr, Tr;\r
- xorq %rax, %rax\r
- strw %ax\r
- pushq %rax\r
- sldtw %ax\r
- pushq %rax\r
-\r
-## UINT64 RFlags;\r
- pushq 40(%rbp)\r
-\r
-## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- movq %cr8, %rax\r
- pushq %rax\r
- movq %cr4, %rax\r
- orq $0x208, %rax\r
- movq %rax, %cr4\r
- pushq %rax\r
- movq %cr3, %rax\r
- pushq %rax\r
- movq %cr2, %rax\r
- pushq %rax\r
- xorq %rax, %rax\r
- pushq %rax\r
- movq %cr0, %rax\r
- pushq %rax\r
-\r
-## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- movq %dr7, %rax\r
- pushq %rax\r
- movq %dr6, %rax\r
- pushq %rax\r
- movq %dr3, %rax\r
- pushq %rax\r
- movq %dr2, %rax\r
- pushq %rax\r
- movq %dr1, %rax\r
- pushq %rax\r
- movq %dr0, %rax\r
- pushq %rax\r
-\r
-## FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- subq $512, %rsp\r
- movq %rsp, %rdi\r
- .byte 0xf, 0xae, 0x7 # fxsave [rdi]\r
-\r
-# UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-## UINT32 ExceptionData;\r
- pushq 16(%rbp)\r
-\r
-## call into exception handler\r
- movq 8(%rbp), %rcx\r
- movabsq $ASM_PFX(SmiPFHandler), %rax\r
-\r
-## Prepare parameter and call\r
- movq %rsp, %rdx\r
- #\r
- # Per X64 calling convention, allocate maximum parameter stack space\r
- # and make sure RSP is 16-byte aligned\r
- #\r
- subq $4 * 8 + 8, %rsp\r
- call *%rax\r
- addq $4 * 8 + 8, %rsp\r
- jmp L5\r
-\r
-L5:\r
-## UINT64 ExceptionData;\r
- addq $8, %rsp\r
-\r
-## FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- movq %rsp, %rsi\r
- .byte 0xf, 0xae, 0xe # fxrstor [rsi]\r
- addq $512, %rsp\r
-\r
-## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-## Skip restoration of DRx registers to support debuggers\r
-## that set breakpoints in interrupt/exception context\r
- addq $8 * 6, %rsp\r
-\r
-## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- popq %rax\r
- movq %rax, %cr0\r
- addq $8, %rsp # not for Cr1\r
- popq %rax\r
- movq %rax, %cr2\r
- popq %rax\r
- movq %rax, %cr3\r
- popq %rax\r
- movq %rax, %cr4\r
- popq %rax\r
- movq %rax, %cr8\r
-\r
-## UINT64 RFlags;\r
- popq 40(%rbp)\r
-\r
-## UINT64 Ldtr, Tr;\r
-## UINT64 Gdtr[2], Idtr[2];\r
-## Best not let anyone mess with these particular registers...\r
- addq $48, %rsp\r
-\r
-## UINT64 Rip;\r
- popq 24(%rbp)\r
-\r
-## UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
- popq %rax\r
- # mov gs, rax ; not for gs\r
- popq %rax\r
- # mov fs, rax ; not for fs\r
- # (X64 will not use fs and gs, so we do not restore it)\r
- popq %rax\r
- movq %rax, %es\r
- popq %rax\r
- movq %rax, %ds\r
- popq 32(%rbp) # for cs\r
- popq 56(%rbp) # for ss\r
-\r
-## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- popq %rdi\r
- popq %rsi\r
- addq $8, %rsp # not for rbp\r
- popq 48(%rbp) # for rsp\r
- popq %rbx\r
- popq %rdx\r
- popq %rcx\r
- popq %rax\r
- popq %r8\r
- popq %r9\r
- popq %r10\r
- popq %r11\r
- popq %r12\r
- popq %r13\r
- popq %r14\r
- popq %r15\r
-\r
- movq %rbp, %rsp\r
-\r
-# Enable TF bit after page fault handler runs\r
- btsl $8, 40(%rsp) #RFLAGS\r
-\r
- popq %rbp\r
- addq $16, %rsp # skip INT# & ErrCode\r
- iretq\r
-\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; SmiException.asm\r
-;\r
-; Abstract:\r
-;\r
-; Exception handlers used in SM mode\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
-EXTERNDEF SmiPFHandler:PROC\r
-EXTERNDEF gcSmiIdtr:FWORD\r
-EXTERNDEF gcSmiGdtr:FWORD\r
-EXTERNDEF gcPsd:BYTE\r
-\r
- .const\r
-\r
-NullSeg DQ 0 ; reserved by architecture\r
-CodeSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 9bh\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-ProtModeCodeSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 9bh\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-ProtModeSsSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 93h\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-DataSeg32 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 93h\r
- DB 0cfh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-CodeSeg16 LABEL QWORD\r
- DW -1\r
- DW 0\r
- DB 0\r
- DB 9bh\r
- DB 8fh\r
- DB 0\r
-DataSeg16 LABEL QWORD\r
- DW -1\r
- DW 0\r
- DB 0\r
- DB 93h\r
- DB 8fh\r
- DB 0\r
-CodeSeg64 LABEL QWORD\r
- DW -1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 9bh\r
- DB 0afh ; LimitHigh\r
- DB 0 ; BaseHigh\r
-; TSS Segment for X64 specially\r
-TssSeg LABEL QWORD\r
- DW TSS_DESC_SIZE - 1 ; LimitLow\r
- DW 0 ; BaseLow\r
- DB 0 ; BaseMid\r
- DB 89h\r
- DB 00h ; LimitHigh\r
- DB 0 ; BaseHigh\r
- DD 0 ; BaseUpper\r
- DD 0 ; Reserved\r
-GDT_SIZE = $ - offset NullSeg\r
-\r
-; Create TSS Descriptor just after GDT\r
-TssDescriptor LABEL BYTE\r
- DD 0 ; Reserved\r
- DQ 0 ; RSP0\r
- DQ 0 ; RSP1\r
- DQ 0 ; RSP2\r
- DD 0 ; Reserved\r
- DD 0 ; Reserved\r
- DQ 0 ; IST1\r
- DQ 0 ; IST2\r
- DQ 0 ; IST3\r
- DQ 0 ; IST4\r
- DQ 0 ; IST5\r
- DQ 0 ; IST6\r
- DQ 0 ; IST7\r
- DD 0 ; Reserved\r
- DD 0 ; Reserved\r
- DW 0 ; Reserved\r
- DW 0 ; I/O Map Base Address\r
-TSS_DESC_SIZE = $ - offset TssDescriptor\r
-\r
-;\r
-; This structure serves as a template for all processors.\r
-;\r
-gcPsd LABEL BYTE\r
- DB 'PSDSIG '\r
- DW PSD_SIZE\r
- DW 2\r
- DW 1 SHL 2\r
- DW CODE_SEL\r
- DW DATA_SEL\r
- DW DATA_SEL\r
- DW DATA_SEL\r
- DW 0\r
- DQ 0\r
- DQ 0\r
- DQ 0 ; fixed in InitializeMpServiceData()\r
- DQ offset NullSeg\r
- DD GDT_SIZE\r
- DD 0\r
- DB 24 dup (0)\r
- DQ 0\r
-PSD_SIZE = $ - offset gcPsd\r
-\r
-;\r
-; CODE & DATA segments for SMM runtime\r
-;\r
-CODE_SEL = offset CodeSeg64 - offset NullSeg\r
-DATA_SEL = offset DataSeg32 - offset NullSeg\r
-CODE32_SEL = offset CodeSeg32 - offset NullSeg\r
-\r
-gcSmiGdtr LABEL FWORD\r
- DW GDT_SIZE - 1\r
- DQ offset NullSeg\r
-\r
-gcSmiIdtr LABEL FWORD\r
- DW 0\r
- DQ 0\r
-\r
- .code\r
-\r
-;------------------------------------------------------------------------------\r
-; _SmiExceptionEntryPoints is the collection of exception entry points followed\r
-; by a common exception handler.\r
-;\r
-; Stack frame would be as follows as specified in IA32 manuals:\r
-;\r
-; +---------------------+ <-- 16-byte aligned ensured by processor\r
-; + Old SS +\r
-; +---------------------+\r
-; + Old RSP +\r
-; +---------------------+\r
-; + RFlags +\r
-; +---------------------+\r
-; + CS +\r
-; +---------------------+\r
-; + RIP +\r
-; +---------------------+\r
-; + Error Code +\r
-; +---------------------+\r
-; + Vector Number +\r
-; +---------------------+\r
-; + RBP +\r
-; +---------------------+ <-- RBP, 16-byte aligned\r
-;\r
-; RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT\r
-;------------------------------------------------------------------------------\r
-PageFaultIdtHandlerSmmProfile PROC\r
- push 0eh ; Page Fault\r
- test spl, 8 ; odd multiple of 8 => ErrCode present\r
- jnz @F\r
- push [rsp] ; duplicate INT# if no ErrCode\r
- mov qword ptr [rsp + 8], 0\r
-@@:\r
- push rbp\r
- mov rbp, rsp\r
-\r
- ;\r
- ; Since here the stack pointer is 16-byte aligned, so\r
- ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
- ; is 16-byte aligned\r
- ;\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- push r15\r
- push r14\r
- push r13\r
- push r12\r
- push r11\r
- push r10\r
- push r9\r
- push r8\r
- push rax\r
- push rcx\r
- push rdx\r
- push rbx\r
- push qword ptr [rbp + 48] ; RSP\r
- push qword ptr [rbp] ; RBP\r
- push rsi\r
- push rdi\r
-\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- movzx rax, word ptr [rbp + 56]\r
- push rax ; for ss\r
- movzx rax, word ptr [rbp + 32]\r
- push rax ; for cs\r
- mov rax, ds\r
- push rax\r
- mov rax, es\r
- push rax\r
- mov rax, fs\r
- push rax\r
- mov rax, gs\r
- push rax\r
-\r
-;; UINT64 Rip;\r
- push qword ptr [rbp + 24]\r
-\r
-;; UINT64 Gdtr[2], Idtr[2];\r
- sub rsp, 16\r
- sidt fword ptr [rsp]\r
- sub rsp, 16\r
- sgdt fword ptr [rsp]\r
-\r
-;; UINT64 Ldtr, Tr;\r
- xor rax, rax\r
- str ax\r
- push rax\r
- sldt ax\r
- push rax\r
-\r
-;; UINT64 RFlags;\r
- push qword ptr [rbp + 40]\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- mov rax, cr8\r
- push rax\r
- mov rax, cr4\r
- or rax, 208h\r
- mov cr4, rax\r
- push rax\r
- mov rax, cr3\r
- push rax\r
- mov rax, cr2\r
- push rax\r
- xor rax, rax\r
- push rax\r
- mov rax, cr0\r
- push rax\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov rax, dr7\r
- push rax\r
- mov rax, dr6\r
- push rax\r
- mov rax, dr3\r
- push rax\r
- mov rax, dr2\r
- push rax\r
- mov rax, dr1\r
- push rax\r
- mov rax, dr0\r
- push rax\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- sub rsp, 512\r
- mov rdi, rsp\r
- db 0fh, 0aeh, 00000111y ;fxsave [rdi]\r
-\r
-; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-;; UINT32 ExceptionData;\r
- push qword ptr [rbp + 16]\r
-\r
-;; call into exception handler\r
- mov rcx, [rbp + 8]\r
- mov rax, SmiPFHandler\r
-\r
-;; Prepare parameter and call\r
- mov rdx, rsp\r
- ;\r
- ; Per X64 calling convention, allocate maximum parameter stack space\r
- ; and make sure RSP is 16-byte aligned\r
- ;\r
- sub rsp, 4 * 8 + 8\r
- call rax\r
- add rsp, 4 * 8 + 8\r
- jmp @F\r
-\r
-@@:\r
-;; UINT64 ExceptionData;\r
- add rsp, 8\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- mov rsi, rsp\r
- db 0fh, 0aeh, 00001110y ; fxrstor [rsi]\r
- add rsp, 512\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; Skip restoration of DRx registers to support debuggers\r
-;; that set breakpoints in interrupt/exception context\r
- add rsp, 8 * 6\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- pop rax\r
- mov cr0, rax\r
- add rsp, 8 ; not for Cr1\r
- pop rax\r
- mov cr2, rax\r
- pop rax\r
- mov cr3, rax\r
- pop rax\r
- mov cr4, rax\r
- pop rax\r
- mov cr8, rax\r
-\r
-;; UINT64 RFlags;\r
- pop qword ptr [rbp + 40]\r
-\r
-;; UINT64 Ldtr, Tr;\r
-;; UINT64 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add rsp, 48\r
-\r
-;; UINT64 Rip;\r
- pop qword ptr [rbp + 24]\r
-\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
- pop rax\r
- ; mov gs, rax ; not for gs\r
- pop rax\r
- ; mov fs, rax ; not for fs\r
- ; (X64 will not use fs and gs, so we do not restore it)\r
- pop rax\r
- mov es, rax\r
- pop rax\r
- mov ds, rax\r
- pop qword ptr [rbp + 32] ; for cs\r
- pop qword ptr [rbp + 56] ; for ss\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pop rdi\r
- pop rsi\r
- add rsp, 8 ; not for rbp\r
- pop qword ptr [rbp + 48] ; for rsp\r
- pop rbx\r
- pop rdx\r
- pop rcx\r
- pop rax\r
- pop r8\r
- pop r9\r
- pop r10\r
- pop r11\r
- pop r12\r
- pop r13\r
- pop r14\r
- pop r15\r
-\r
- mov rsp, rbp\r
-\r
-; Enable TF bit after page fault handler runs\r
- bts dword ptr [rsp + 40], 8 ;RFLAGS\r
-\r
- pop rbp\r
- add rsp, 16 ; skip INT# & ErrCode\r
- iretq\r
-PageFaultIdtHandlerSmmProfile ENDP\r
-\r
- END\r
+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# SmmInit.S\r
-#\r
-# Abstract:\r
-#\r
-# Functions for relocating SMBASE's for all processors\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(gSmmCr0)\r
-ASM_GLOBAL ASM_PFX(gSmmCr3)\r
-ASM_GLOBAL ASM_PFX(gSmmCr4)\r
-ASM_GLOBAL ASM_PFX(gSmmJmpAddr)\r
-ASM_GLOBAL ASM_PFX(gcSmmInitTemplate)\r
-ASM_GLOBAL ASM_PFX(gcSmmInitSize)\r
-ASM_GLOBAL ASM_PFX(mRebasedFlagAddr32)\r
-ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete)\r
-ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete32)\r
-ASM_GLOBAL ASM_PFX(mSmmRelocationOriginalAddressPtr32)\r
-ASM_GLOBAL ASM_PFX(gSmmInitStack)\r
-ASM_GLOBAL ASM_PFX(gcSmiInitGdtr)\r
-\r
-\r
- .text\r
-\r
-ASM_PFX(gcSmiInitGdtr):\r
- .word 0\r
- .quad 0\r
-\r
-SmmStartup:\r
- .byte 0x66,0xb8 # mov eax, imm32\r
-ASM_PFX(gSmmCr3): .space 4\r
- movq %rax, %cr3\r
- .byte 0x66,0x2e\r
- lgdt (ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp)\r
- .byte 0x66,0xb8 # mov eax, imm32\r
-ASM_PFX(gSmmCr4): .space 4\r
- orb $2, %ah # enable XMM registers access\r
- movq %rax, %cr4\r
- .byte 0x66\r
- movl $0xc0000080,%ecx # IA32_EFER MSR\r
- rdmsr\r
- orb $1,%ah # set LME bit\r
- wrmsr\r
- .byte 0x66,0xb8 # mov eax, imm32\r
-ASM_PFX(gSmmCr0): .space 4\r
- movq %rax, %cr0\r
- .byte 0x66,0xea # far jmp to long mode\r
-ASM_PFX(gSmmJmpAddr): .quad LongMode\r
-LongMode: # long-mode starts here\r
- .byte 0x48,0xbc # mov rsp, imm64\r
-ASM_PFX(gSmmInitStack): .space 8\r
- andw $0xfff0, %sp # make sure RSP is 16-byte aligned\r
- #\r
- # Accoring to X64 calling convention, XMM0~5 are volatile, we need to save\r
- # them before calling C-function.\r
- #\r
- subq $0x60, %rsp\r
- movdqa %xmm0, 0x0(%rsp)\r
- movdqa %xmm1, 0x10(%rsp)\r
- movdqa %xmm2, 0x20(%rsp)\r
- movdqa %xmm3, 0x30(%rsp)\r
- movdqa %xmm4, 0x40(%rsp)\r
- movdqa %xmm5, 0x50(%rsp)\r
-\r
-\r
- addq $-0x20, %rsp\r
- call ASM_PFX(SmmInitHandler)\r
- addq $0x20, %rsp\r
- #\r
- # Restore XMM0~5 after calling C-function.\r
- #\r
- movdqa 0x0(%rsp), %xmm0\r
- movdqa 0x10(%rsp), %xmm1\r
- movdqa 0x20(%rsp), %xmm2\r
- movdqa 0x30(%rsp), %xmm3\r
- movdqa 0x40(%rsp), %xmm4\r
- movdqa 0x50(%rsp), %xmm5\r
-\r
- rsm\r
-\r
-ASM_PFX(gcSmmInitTemplate):\r
-\r
-_SmmInitTemplate:\r
- .byte 0x66,0x2e,0x8b,0x2e # mov ebp, cs:[@F]\r
- .word L1 - _SmmInitTemplate + 0x8000\r
- .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000\r
- jmp *%bp # jmp ebp actually\r
-L1:\r
- .quad SmmStartup\r
-\r
-ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate)\r
-\r
-ASM_PFX(SmmRelocationSemaphoreComplete):\r
- # Create a simple stack frame to store RAX and the original RSM location\r
- pushq %rax # Used to store return address\r
- pushq %rax\r
-\r
- # Load the original RSM location onto stack\r
- movabsq $ASM_PFX(mSmmRelocationOriginalAddress), %rax\r
- movq (%rax), %rax\r
- movq %rax, 0x08(%rsp)\r
-\r
- # Update rebase flag\r
- movabsq $ASM_PFX(mRebasedFlag), %rax\r
- movq (%rax), %rax\r
- movb $1, (%rax)\r
-\r
- #restore RAX and return to original RSM location\r
- popq %rax\r
- retq\r
-\r
-#\r
-# Semaphore code running in 32-bit mode\r
-#\r
-ASM_PFX(SmmRelocationSemaphoreComplete32):\r
- #\r
- # movb $1, ()\r
- #\r
- .byte 0xc6, 0x05\r
-ASM_PFX(mRebasedFlagAddr32):\r
- .long 0\r
- .byte 1\r
- #\r
- # jmpd ()\r
- #\r
- .byte 0xff, 0x25\r
-ASM_PFX(mSmmRelocationOriginalAddressPtr32):\r
- .long 0\r
+++ /dev/null
-;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
-; This program and the accompanying materials\r
-; are licensed and made available under the terms and conditions of the BSD License\r
-; which accompanies this distribution. The full text of the license may be found at\r
-; http://opensource.org/licenses/bsd-license.php.\r
-;\r
-; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;\r
-; Module Name:\r
-;\r
-; SmmInit.Asm\r
-;\r
-; Abstract:\r
-;\r
-; Functions for relocating SMBASE's for all processors\r
-;\r
-;-------------------------------------------------------------------------------\r
-\r
-EXTERNDEF SmmInitHandler:PROC\r
-EXTERNDEF gSmmCr0:DWORD\r
-EXTERNDEF gSmmCr3:DWORD\r
-EXTERNDEF gSmmCr4:DWORD\r
-EXTERNDEF gSmmJmpAddr:QWORD\r
-EXTERNDEF gcSmmInitTemplate:BYTE\r
-EXTERNDEF gcSmmInitSize:WORD\r
-EXTERNDEF mRebasedFlag:PTR BYTE\r
-EXTERNDEF mSmmRelocationOriginalAddress:QWORD\r
-EXTERNDEF mRebasedFlagAddr32:DWORD\r
-EXTERNDEF mSmmRelocationOriginalAddressPtr32:DWORD\r
-EXTERNDEF gSmmInitStack:QWORD\r
-EXTERNDEF gcSmiInitGdtr:FWORD\r
-\r
- .code\r
-\r
-gcSmiInitGdtr LABEL FWORD\r
- DW 0\r
- DQ 0\r
-\r
-SmmStartup PROC\r
- DB 66h, 0b8h ; mov eax, imm32\r
-gSmmCr3 DD ?\r
- mov cr3, rax\r
- DB 66h, 2eh\r
- lgdt fword ptr [ebp + (offset gcSmiInitGdtr - SmmStartup)]\r
- DB 66h, 0b8h ; mov eax, imm32\r
-gSmmCr4 DD ?\r
- or ah, 2 ; enable XMM registers access\r
- mov cr4, rax\r
- DB 66h\r
- mov ecx, 0c0000080h ; IA32_EFER MSR\r
- rdmsr\r
- or ah, 1 ; set LME bit\r
- wrmsr\r
- DB 66h, 0b8h ; mov eax, imm32\r
-gSmmCr0 DD ?\r
- mov cr0, rax ; enable protected mode & paging\r
- DB 66h, 0eah ; far jmp to long mode\r
-gSmmJmpAddr DQ @LongMode\r
-@LongMode: ; long-mode starts here\r
- DB 48h, 0bch ; mov rsp, imm64\r
-gSmmInitStack DQ ?\r
- and sp, 0fff0h ; make sure RSP is 16-byte aligned\r
- ;\r
- ; Accoring to X64 calling convention, XMM0~5 are volatile, we need to save\r
- ; them before calling C-function.\r
- ;\r
- sub rsp, 60h\r
- movdqa [rsp], xmm0\r
- movdqa [rsp + 10h], xmm1\r
- movdqa [rsp + 20h], xmm2\r
- movdqa [rsp + 30h], xmm3\r
- movdqa [rsp + 40h], xmm4\r
- movdqa [rsp + 50h], xmm5\r
-\r
- add rsp, -20h\r
- call SmmInitHandler\r
- add rsp, 20h\r
-\r
- ;\r
- ; Restore XMM0~5 after calling C-function.\r
- ;\r
- movdqa xmm0, [rsp]\r
- movdqa xmm1, [rsp + 10h]\r
- movdqa xmm2, [rsp + 20h]\r
- movdqa xmm3, [rsp + 30h]\r
- movdqa xmm4, [rsp + 40h]\r
- movdqa xmm5, [rsp + 50h]\r
-\r
- rsm\r
-SmmStartup ENDP\r
-\r
-gcSmmInitTemplate LABEL BYTE\r
-\r
-_SmmInitTemplate PROC\r
- DB 66h, 2eh, 8bh, 2eh ; mov ebp, cs:[@F]\r
- DW @L1 - _SmmInitTemplate + 8000h\r
- DB 66h, 81h, 0edh, 00h, 00h, 03h, 00 ; sub ebp, 30000h\r
- jmp bp ; jmp ebp actually\r
-@L1:\r
- DQ SmmStartup\r
-_SmmInitTemplate ENDP\r
-\r
-gcSmmInitSize DW $ - gcSmmInitTemplate\r
-\r
-SmmRelocationSemaphoreComplete PROC\r
- push rax\r
- mov rax, mRebasedFlag\r
- mov byte ptr [rax], 1\r
- pop rax\r
- jmp [mSmmRelocationOriginalAddress]\r
-SmmRelocationSemaphoreComplete ENDP\r
-\r
-;\r
-; Semaphore code running in 32-bit mode\r
-;\r
-SmmRelocationSemaphoreComplete32 PROC\r
- ;\r
- ; mov byte ptr [], 1\r
- ;\r
- db 0c6h, 05h\r
-mRebasedFlagAddr32 dd 0\r
- db 1\r
- ;\r
- ; jmp dword ptr []\r
- ;\r
- db 0ffh, 25h\r
-mSmmRelocationOriginalAddressPtr32 dd 0\r
-SmmRelocationSemaphoreComplete32 ENDP\r
-\r
- END\r