]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
Always set WP in CR0.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiEntry.S
1 #------------------------------------------------------------------------------
2 #
3 # Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
4 # This program and the accompanying materials
5 # are licensed and made available under the terms and conditions of the BSD License
6 # which accompanies this distribution. The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php.
8 #
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 #
12 # Module Name:
13 #
14 # SmiEntry.S
15 #
16 # Abstract:
17 #
18 # Code template of the SMI handler for a particular processor
19 #
20 #------------------------------------------------------------------------------
21
22 ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)
23 ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
24 ASM_GLOBAL ASM_PFX(gSmiCr3)
25 ASM_GLOBAL ASM_PFX(gSmiStack)
26 ASM_GLOBAL ASM_PFX(gSmbase)
27 ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
28 ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
29
30 .equ DSC_OFFSET, 0xfb00
31 .equ DSC_GDTPTR, 0x30
32 .equ DSC_GDTSIZ, 0x38
33 .equ DSC_CS, 14
34 .equ DSC_DS, 16
35 .equ DSC_SS, 18
36 .equ DSC_OTHERSEG, 20
37
38 .equ PROTECT_MODE_CS, 0x08
39 .equ PROTECT_MODE_DS, 0x20
40 .equ TSS_SEGMENT, 0x40
41
42 .text
43
44 ASM_PFX(gcSmiHandlerTemplate):
45
46 _SmiEntryPoint:
47 .byte 0xbb # mov bx, imm16
48 .word _GdtDesc - _SmiEntryPoint + 0x8000
49 .byte 0x2e,0xa1 # mov ax, cs:[offset16]
50 .word DSC_OFFSET + DSC_GDTSIZ
51 decl %eax
52 movl %eax, %cs:(%edi) # mov cs:[bx], ax
53 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
54 .word DSC_OFFSET + DSC_GDTPTR
55 movw %ax, %cs:2(%edi)
56 movw %ax, %bp # ebp = GDT base
57 .byte 0x66
58 lgdt %cs:(%edi)
59 # Patch ProtectedMode Segment
60 .byte 0xb8 # mov ax, imm16
61 .word PROTECT_MODE_CS # set AX for segment directly
62 movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax
63 # Patch ProtectedMode entry
64 .byte 0x66, 0xbf # mov edi, SMBASE
65 ASM_PFX(gSmbase): .space 4
66 .byte 0x67
67 lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax
68 movw %ax, %cs:-6(%edi)
69 movl %cr0, %ebx
70 .byte 0x66
71 andl $0x9ffafff3, %ebx
72 .byte 0x66
73 orl $0x23, %ebx
74 movl %ebx, %cr0
75 .byte 0x66,0xea
76 .space 4
77 .space 2
78 _GdtDesc: .space 4
79 .space 2
80
81 Start32bit:
82 movw $PROTECT_MODE_DS, %ax
83 movl %eax,%ds
84 movl %eax,%es
85 movl %eax,%fs
86 movl %eax,%gs
87 movl %eax,%ss
88 .byte 0xbc # mov esp, imm32
89 ASM_PFX(gSmiStack): .space 4
90 movl $ASM_PFX(gSmiHandlerIdtr), %eax
91 lidt (%eax)
92 jmp ProtFlatMode
93
94 ProtFlatMode:
95 .byte 0xb8 # mov eax, imm32
96 ASM_PFX(gSmiCr3): .space 4
97 movl %eax, %cr3
98 #
99 # Need to test for CR4 specific bit support
100 #
101 movl $1, %eax
102 cpuid # use CPUID to determine if specific CR4 bits are supported
103 xorl %eax, %eax # Clear EAX
104 testl $BIT2, %edx # Check for DE capabilities
105 jz L8
106 orl $BIT3, %eax
107 L8:
108 testl $BIT6, %edx # Check for PAE capabilities
109 jz L9
110 orl $BIT5, %eax
111 L9:
112 testl $BIT7, %edx # Check for MCE capabilities
113 jz L10
114 orl $BIT6, %eax
115 L10:
116 testl $BIT24, %edx # Check for FXSR capabilities
117 jz L11
118 orl $BIT9, %eax
119 L11:
120 testl $BIT25, %edx # Check for SSE capabilities
121 jz L12
122 orl $BIT10, %eax
123 L12: # as cr4.PGE is not set here, refresh cr3
124 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.
125 movl %cr0, %ebx
126 orl $0x080010000, %ebx # enable paging + WP
127 movl %ebx, %cr0
128 leal DSC_OFFSET(%edi),%ebx
129 movw DSC_DS(%ebx),%ax
130 movl %eax, %ds
131 movw DSC_OTHERSEG(%ebx),%ax
132 movl %eax, %es
133 movl %eax, %fs
134 movl %eax, %gs
135 movw DSC_SS(%ebx),%ax
136 movl %eax, %ss
137
138 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
139 jz L5
140
141 # Load TSS
142 movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
143 movl $TSS_SEGMENT, %eax
144 ltrw %ax
145 L5:
146
147 # jmp _SmiHandler # instruction is not needed
148
149 _SmiHandler:
150 movl (%esp), %ebx
151
152 pushl %ebx
153 movl $ASM_PFX(CpuSmmDebugEntry), %eax
154 call *%eax
155 popl %ecx
156
157 pushl %ebx
158 movl $ASM_PFX(SmiRendezvous), %eax
159 call *%eax
160 popl %ecx
161
162 pushl %ebx
163 movl $ASM_PFX(CpuSmmDebugExit), %eax
164 call *%eax
165 popl %ecx
166
167 rsm
168
169 ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint