• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1;------------------------------------------------------------------------------ ;
2; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
3; This program and the accompanying materials
4; are licensed and made available under the terms and conditions of the BSD License
5; which accompanies this distribution.  The full text of the license may be found at
6; http://opensource.org/licenses/bsd-license.php.
7;
8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10;
11; Module Name:
12;
13;   SmiException.asm
14;
15; Abstract:
16;
17;   Exception handlers used in SM mode
18;
19;-------------------------------------------------------------------------------
20
21EXTERNDEF   SmiPFHandler:PROC
22EXTERNDEF   gcSmiIdtr:FWORD
23EXTERNDEF   gcSmiGdtr:FWORD
24EXTERNDEF   gcPsd:BYTE
25
26    .const
27
28NullSeg     DQ      0                   ; reserved by architecture
29CodeSeg32   LABEL   QWORD
30            DW      -1                  ; LimitLow
31            DW      0                   ; BaseLow
32            DB      0                   ; BaseMid
33            DB      9bh
34            DB      0cfh                ; LimitHigh
35            DB      0                   ; BaseHigh
36ProtModeCodeSeg32   LABEL   QWORD
37            DW      -1                  ; LimitLow
38            DW      0                   ; BaseLow
39            DB      0                   ; BaseMid
40            DB      9bh
41            DB      0cfh                ; LimitHigh
42            DB      0                   ; BaseHigh
43ProtModeSsSeg32     LABEL   QWORD
44            DW      -1                  ; LimitLow
45            DW      0                   ; BaseLow
46            DB      0                   ; BaseMid
47            DB      93h
48            DB      0cfh                ; LimitHigh
49            DB      0                   ; BaseHigh
50DataSeg32   LABEL   QWORD
51            DW      -1                  ; LimitLow
52            DW      0                   ; BaseLow
53            DB      0                   ; BaseMid
54            DB      93h
55            DB      0cfh                ; LimitHigh
56            DB      0                   ; BaseHigh
57CodeSeg16   LABEL   QWORD
58            DW      -1
59            DW      0
60            DB      0
61            DB      9bh
62            DB      8fh
63            DB      0
64DataSeg16   LABEL   QWORD
65            DW      -1
66            DW      0
67            DB      0
68            DB      93h
69            DB      8fh
70            DB      0
71CodeSeg64   LABEL   QWORD
72            DW      -1                  ; LimitLow
73            DW      0                   ; BaseLow
74            DB      0                   ; BaseMid
75            DB      9bh
76            DB      0afh                ; LimitHigh
77            DB      0                   ; BaseHigh
78; TSS Segment for X64 specially
79TssSeg      LABEL   QWORD
80            DW      TSS_DESC_SIZE - 1   ; LimitLow
81            DW      0                   ; BaseLow
82            DB      0                   ; BaseMid
83            DB      89h
84            DB      00h                 ; LimitHigh
85            DB      0                   ; BaseHigh
86            DD      0                   ; BaseUpper
87            DD      0                   ; Reserved
88GDT_SIZE = $ - offset NullSeg
89
90; Create TSS Descriptor just after GDT
91TssDescriptor LABEL BYTE
92            DD      0                   ; Reserved
93            DQ      0                   ; RSP0
94            DQ      0                   ; RSP1
95            DQ      0                   ; RSP2
96            DD      0                   ; Reserved
97            DD      0                   ; Reserved
98            DQ      0                   ; IST1
99            DQ      0                   ; IST2
100            DQ      0                   ; IST3
101            DQ      0                   ; IST4
102            DQ      0                   ; IST5
103            DQ      0                   ; IST6
104            DQ      0                   ; IST7
105            DD      0                   ; Reserved
106            DD      0                   ; Reserved
107            DW      0                   ; Reserved
108            DW      0                   ; I/O Map Base Address
109TSS_DESC_SIZE = $ - offset TssDescriptor
110
111;
112; This structure serves as a template for all processors.
113;
114gcPsd     LABEL   BYTE
115            DB      'PSDSIG  '
116            DW      PSD_SIZE
117            DW      2
118            DW      1 SHL 2
119            DW      CODE_SEL
120            DW      DATA_SEL
121            DW      DATA_SEL
122            DW      DATA_SEL
123            DW      0
124            DQ      0
125            DQ      0
126            DQ      0                   ; fixed in InitializeMpServiceData()
127            DQ      offset NullSeg
128            DD      GDT_SIZE
129            DD      0
130            DB      24 dup (0)
131            DQ      0
132PSD_SIZE  = $ - offset gcPsd
133
134;
135; CODE & DATA segments for SMM runtime
136;
137CODE_SEL    = offset CodeSeg64 - offset NullSeg
138DATA_SEL    = offset DataSeg32 - offset NullSeg
139CODE32_SEL  = offset CodeSeg32 - offset NullSeg
140
141gcSmiGdtr   LABEL   FWORD
142    DW      GDT_SIZE - 1
143    DQ      offset NullSeg
144
145gcSmiIdtr   LABEL   FWORD
146    DW      0
147    DQ      0
148
149    .code
150
151;------------------------------------------------------------------------------
152; _SmiExceptionEntryPoints is the collection of exception entry points followed
153; by a common exception handler.
154;
155; Stack frame would be as follows as specified in IA32 manuals:
156;
157; +---------------------+ <-- 16-byte aligned ensured by processor
158; +    Old SS           +
159; +---------------------+
160; +    Old RSP          +
161; +---------------------+
162; +    RFlags           +
163; +---------------------+
164; +    CS               +
165; +---------------------+
166; +    RIP              +
167; +---------------------+
168; +    Error Code       +
169; +---------------------+
170; +   Vector Number     +
171; +---------------------+
172; +    RBP              +
173; +---------------------+ <-- RBP, 16-byte aligned
174;
175; RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
176;------------------------------------------------------------------------------
177PageFaultIdtHandlerSmmProfile    PROC
178    push    0eh                         ; Page Fault
179    test    spl, 8                      ; odd multiple of 8 => ErrCode present
180    jnz     @F
181    push    [rsp]                       ; duplicate INT# if no ErrCode
182    mov     qword ptr [rsp + 8], 0
183@@:
184    push    rbp
185    mov     rbp, rsp
186
187    ;
188    ; Since here the stack pointer is 16-byte aligned, so
189    ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
190    ; is 16-byte aligned
191    ;
192
193;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
194;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
195    push    r15
196    push    r14
197    push    r13
198    push    r12
199    push    r11
200    push    r10
201    push    r9
202    push    r8
203    push    rax
204    push    rcx
205    push    rdx
206    push    rbx
207    push    qword ptr [rbp + 48]  ; RSP
208    push    qword ptr [rbp]       ; RBP
209    push    rsi
210    push    rdi
211
212;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero
213    movzx   rax, word ptr [rbp + 56]
214    push    rax                      ; for ss
215    movzx   rax, word ptr [rbp + 32]
216    push    rax                      ; for cs
217    mov     rax, ds
218    push    rax
219    mov     rax, es
220    push    rax
221    mov     rax, fs
222    push    rax
223    mov     rax, gs
224    push    rax
225
226;; UINT64  Rip;
227    push    qword ptr [rbp + 24]
228
229;; UINT64  Gdtr[2], Idtr[2];
230    sub     rsp, 16
231    sidt    fword ptr [rsp]
232    sub     rsp, 16
233    sgdt    fword ptr [rsp]
234
235;; UINT64  Ldtr, Tr;
236    xor     rax, rax
237    str     ax
238    push    rax
239    sldt    ax
240    push    rax
241
242;; UINT64  RFlags;
243    push    qword ptr [rbp + 40]
244
245;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
246    mov     rax, cr8
247    push    rax
248    mov     rax, cr4
249    or      rax, 208h
250    mov     cr4, rax
251    push    rax
252    mov     rax, cr3
253    push    rax
254    mov     rax, cr2
255    push    rax
256    xor     rax, rax
257    push    rax
258    mov     rax, cr0
259    push    rax
260
261;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
262    mov     rax, dr7
263    push    rax
264    mov     rax, dr6
265    push    rax
266    mov     rax, dr3
267    push    rax
268    mov     rax, dr2
269    push    rax
270    mov     rax, dr1
271    push    rax
272    mov     rax, dr0
273    push    rax
274
275;; FX_SAVE_STATE_X64 FxSaveState;
276
277    sub rsp, 512
278    mov rdi, rsp
279    db 0fh, 0aeh, 00000111y ;fxsave [rdi]
280
281; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
282    cld
283
284;; UINT32  ExceptionData;
285    push    qword ptr [rbp + 16]
286
287;; call into exception handler
288    mov     rcx, [rbp + 8]
289    mov     rax, SmiPFHandler
290
291;; Prepare parameter and call
292    mov     rdx, rsp
293    ;
294    ; Per X64 calling convention, allocate maximum parameter stack space
295    ; and make sure RSP is 16-byte aligned
296    ;
297    sub     rsp, 4 * 8 + 8
298    call    rax
299    add     rsp, 4 * 8 + 8
300    jmp     @F
301
302@@:
303;; UINT64  ExceptionData;
304    add     rsp, 8
305
306;; FX_SAVE_STATE_X64 FxSaveState;
307
308    mov rsi, rsp
309    db 0fh, 0aeh, 00001110y ; fxrstor [rsi]
310    add rsp, 512
311
312;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
313;; Skip restoration of DRx registers to support debuggers
314;; that set breakpoints in interrupt/exception context
315  add     rsp, 8 * 6
316
317;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
318    pop     rax
319    mov     cr0, rax
320    add     rsp, 8   ; not for Cr1
321    pop     rax
322    mov     cr2, rax
323    pop     rax
324    mov     cr3, rax
325    pop     rax
326    mov     cr4, rax
327    pop     rax
328    mov     cr8, rax
329
330;; UINT64  RFlags;
331    pop     qword ptr [rbp + 40]
332
333;; UINT64  Ldtr, Tr;
334;; UINT64  Gdtr[2], Idtr[2];
335;; Best not let anyone mess with these particular registers...
336    add     rsp, 48
337
338;; UINT64  Rip;
339    pop     qword ptr [rbp + 24]
340
341;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;
342    pop     rax
343    ; mov     gs, rax ; not for gs
344    pop     rax
345    ; mov     fs, rax ; not for fs
346    ; (X64 will not use fs and gs, so we do not restore it)
347    pop     rax
348    mov     es, rax
349    pop     rax
350    mov     ds, rax
351    pop     qword ptr [rbp + 32]  ; for cs
352    pop     qword ptr [rbp + 56]  ; for ss
353
354;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
355;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
356    pop     rdi
357    pop     rsi
358    add     rsp, 8               ; not for rbp
359    pop     qword ptr [rbp + 48] ; for rsp
360    pop     rbx
361    pop     rdx
362    pop     rcx
363    pop     rax
364    pop     r8
365    pop     r9
366    pop     r10
367    pop     r11
368    pop     r12
369    pop     r13
370    pop     r14
371    pop     r15
372
373    mov     rsp, rbp
374
375; Enable TF bit after page fault handler runs
376    bts     dword ptr [rsp + 40], 8  ;RFLAGS
377
378    pop     rbp
379    add     rsp, 16           ; skip INT# & ErrCode
380    iretq
381PageFaultIdtHandlerSmmProfile ENDP
382
383    END
384