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