• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#------------------------------------------------------------------------------
2#
3# Copyright (c) 2009 - 2016, 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
22ASM_GLOBAL  ASM_PFX(gcStmSmiHandlerTemplate)
23ASM_GLOBAL  ASM_PFX(gcStmSmiHandlerSize)
24ASM_GLOBAL  ASM_PFX(gcStmSmiHandlerOffset)
25ASM_GLOBAL  ASM_PFX(gStmSmiCr3)
26ASM_GLOBAL  ASM_PFX(gStmSmiStack)
27ASM_GLOBAL  ASM_PFX(gStmSmbase)
28ASM_GLOBAL  ASM_PFX(gStmXdSupported)
29ASM_GLOBAL  ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
30ASM_GLOBAL  ASM_PFX(gStmSmiHandlerIdtr)
31
32.equ            MSR_IA32_MISC_ENABLE, 0x1A0
33.equ            MSR_EFER, 0xc0000080
34.equ            MSR_EFER_XD, 0x800
35
36#
37# Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
38#
39.equ            DSC_OFFSET, 0xfb00
40.equ            DSC_GDTPTR, 0x48
41.equ            DSC_GDTSIZ, 0x50
42.equ            DSC_CS, 0x14
43.equ            DSC_DS, 0x16
44.equ            DSC_SS, 0x18
45.equ            DSC_OTHERSEG, 0x1A
46
47.equ            PROTECT_MODE_CS, 0x08
48.equ            PROTECT_MODE_DS, 0x20
49.equ            TSS_SEGMENT,     0x40
50
51    .text
52ASM_PFX(gcStmSmiHandlerTemplate):
53
54_StmSmiEntryPoint:
55    .byte 0xbb                          # mov bx, imm16
56    .word _StmGdtDesc - _StmSmiEntryPoint + 0x8000
57    .byte 0x2e,0xa1                     # mov ax, cs:[offset16]
58    .word DSC_OFFSET + DSC_GDTSIZ
59    decl    %eax
60    movl    %eax, %cs:(%edi)            # mov cs:[bx], ax
61    .byte 0x66,0x2e,0xa1                # mov eax, cs:[offset16]
62    .word   DSC_OFFSET + DSC_GDTPTR
63    movw    %ax, %cs:2(%edi)
64    movw    %ax, %bp                    # ebp = GDT base
65    .byte 0x66
66    lgdt    %cs:(%edi)
67# Patch ProtectedMode Segment
68    .byte   0xb8                        # mov ax, imm16
69    .word   PROTECT_MODE_CS             # set AX for segment directly
70    movl    %eax, %cs:-2(%edi)          # mov cs:[bx - 2], ax
71# Patch ProtectedMode entry
72    .byte 0x66, 0xbf                    # mov edi, SMBASE
73ASM_PFX(gStmSmbase): .space 4
74    .byte 0x67
75    lea     ((Start32bit - _StmSmiEntryPoint) + 0x8000)(%edi), %ax
76    movw     %ax, %cs:-6(%edi)
77    movl    %cr0, %ebx
78    .byte 0x66
79    andl    $0x9ffafff3, %ebx
80    .byte 0x66
81    orl     $0x23, %ebx
82    movl    %ebx, %cr0
83    .byte 0x66,0xea
84    .space  4
85    .space  2
86_StmGdtDesc:   .space 4
87            .space 2
88
89Start32bit:
90    movw    $PROTECT_MODE_DS, %ax
91    movl    %eax,%ds
92    movl    %eax,%es
93    movl    %eax,%fs
94    movl    %eax,%gs
95    movl    %eax,%ss
96    .byte   0xbc                          # mov esp, imm32
97ASM_PFX(gStmSmiStack): .space 4
98    movl    $ASM_PFX(gStmSmiHandlerIdtr), %eax
99    lidt    (%eax)
100    jmp     ProtFlatMode
101
102ProtFlatMode:
103    .byte   0xb8                           # mov eax, imm32
104ASM_PFX(gStmSmiCr3): .space 4
105    movl    %eax, %cr3
106#
107# Need to test for CR4 specific bit support
108#
109    movl    $1, %eax
110    cpuid                                  # use CPUID to determine if specific CR4 bits are supported
111    xorl    %eax, %eax                     # Clear EAX
112    testl   $BIT2, %edx                    # Check for DE capabilities
113    jz      L8
114    orl     $BIT3, %eax
115L8:
116    testl   $BIT6, %edx                    # Check for PAE capabilities
117    jz      L9
118    orl     $BIT5, %eax
119L9:
120    testl   $BIT7, %edx                    # Check for MCE capabilities
121    jz      L10
122    orl     $BIT6, %eax
123L10:
124    testl   $BIT24, %edx                   # Check for FXSR capabilities
125    jz      L11
126    orl     $BIT9, %eax
127L11:
128    testl   $BIT25, %edx                   # Check for SSE capabilities
129    jz      L12
130    orl     $BIT10, %eax
131L12:                                       # as cr4.PGE is not set here, refresh cr3
132    movl    %eax, %cr4                     # in PreModifyMtrrs() to flush TLB.
133
134    cmpb    $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
135    jz      L5
136# Load TSS
137    movb    $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
138    movl    $TSS_SEGMENT, %eax
139    ltrw    %ax
140L5:
141
142# enable NXE if supported
143    .byte   0xb0                           # mov al, imm8
144ASM_PFX(gStmXdSupported): .byte 1
145    cmpb    $0, %al
146    jz      SkipXd
147#
148# Check XD disable bit
149#
150    movl    $MSR_IA32_MISC_ENABLE, %ecx
151    rdmsr
152    pushl   %edx                           # save MSR_IA32_MISC_ENABLE[63-32]
153    testl   $BIT2, %edx                    # MSR_IA32_MISC_ENABLE[34]
154    jz      L13
155    andw    $0x0FFFB, %dx                  # clear XD Disable bit if it is set
156    wrmsr
157L13:
158    movl    $MSR_EFER, %ecx
159    rdmsr
160    orw     $MSR_EFER_XD,%ax               # enable NXE
161    wrmsr
162    jmp     XdDone
163SkipXd:
164    subl    $4, %esp
165XdDone:
166
167    movl    %cr0, %ebx
168    orl     $0x080010023, %ebx             # enable paging + WP + NE + MP + PE
169    movl    %ebx, %cr0
170    leal    DSC_OFFSET(%edi),%ebx
171    movw    DSC_DS(%ebx),%ax
172    movl    %eax, %ds
173    movw    DSC_OTHERSEG(%ebx),%ax
174    movl    %eax, %es
175    movl    %eax, %fs
176    movl    %eax, %gs
177    movw    DSC_SS(%ebx),%ax
178    movl    %eax, %ss
179
180CommonHandler:
181    movl    4(%esp), %ebx
182
183    pushl   %ebx
184    movl    $ASM_PFX(CpuSmmDebugEntry), %eax
185    call    *%eax
186    addl    $4, %esp
187
188    pushl   %ebx
189    movl    $ASM_PFX(SmiRendezvous), %eax
190    call    *%eax
191    addl    $4, %esp
192
193    pushl   %ebx
194    movl    $ASM_PFX(CpuSmmDebugExit), %eax
195    call    *%eax
196    addl    $4, %esp
197
198    movl    $ASM_PFX(gStmXdSupported), %eax
199    movb    (%eax), %al
200    cmpb    $0, %al
201    jz      L16
202    popl    %edx                        # get saved MSR_IA32_MISC_ENABLE[63-32]
203    testl   $BIT2, %edx
204    jz      L16
205    movl    $MSR_IA32_MISC_ENABLE, %ecx
206    rdmsr
207    orw     $BIT2, %dx                  # set XD Disable bit if it was set before entering into SMM
208    wrmsr
209
210L16:
211    rsm
212
213_StmSmiHandler:
214#
215# Check XD disable bit
216#
217    xorl    %esi, %esi
218    movl    $ASM_PFX(gStmXdSupported), %eax
219    movb    (%eax), %al
220    cmpb    $0, %al
221    jz      StmXdDone
222    movl    $MSR_IA32_MISC_ENABLE, %ecx
223    rdmsr
224    movl    %edx, %esi                     # save MSR_IA32_MISC_ENABLE[63-32]
225    testl   $BIT2, %edx                    # MSR_IA32_MISC_ENABLE[34]
226    jz      L14
227    andw    $0x0FFFB, %dx                  # clear XD Disable bit if it is set
228    wrmsr
229L14:
230    movl    $MSR_EFER, %ecx
231    rdmsr
232    orw     $MSR_EFER_XD,%ax               # enable NXE
233    wrmsr
234StmXdDone:
235    push    %esi
236
237    # below step is needed, because STM does not run above code.
238    # we have to run below code to set IDT/CR0/CR4
239    movl    $ASM_PFX(gStmSmiHandlerIdtr), %eax
240    lidt    (%eax)
241
242    movl    %cr0, %eax
243    orl     $0x80010023, %eax           # enable paging + WP + NE + MP + PE
244    movl    %eax, %cr0
245#
246# Need to test for CR4 specific bit support
247#
248    movl    $1, %eax
249    cpuid                               # use CPUID to determine if specific CR4 bits are supported
250    movl    %cr4, %eax                  # init EAX
251    testl   $BIT2, %edx                 # Check for DE capabilities
252    jz      L28
253    orl     $BIT3, %eax
254L28:
255    testl   $BIT6, %edx                 # Check for PAE capabilities
256    jz      L29
257    orl     $BIT5, %eax
258L29:
259    testl   $BIT7, %edx                 # Check for MCE capabilities
260    jz      L30
261    orl     $BIT6, %eax
262L30:
263    testl   $BIT24, %edx                # Check for FXSR capabilities
264    jz      L31
265    orl     $BIT9, %eax
266L31:
267    testl   $BIT25, %edx                # Check for SSE capabilities
268    jz      L32
269    orl     $BIT10, %eax
270L32:                                    # as cr4.PGE is not set here, refresh cr3
271    movl    %eax, %cr4                  # in PreModifyMtrrs() to flush TLB.
272    # STM init finish
273    jmp     CommonHandler
274
275
276ASM_PFX(gcStmSmiHandlerSize)  :  .word      . - _StmSmiEntryPoint
277ASM_PFX(gcStmSmiHandlerOffset):  .word      _StmSmiHandler - _StmSmiEntryPoint
278
279