1;------------------------------------------------------------------------------ 2; 3; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR> 4; SPDX-License-Identifier: BSD-2-Clause-Patent 5; 6; Module Name: 7; 8; SecEntry.asm 9; 10; Abstract: 11; 12; This is the code that goes from real-mode to protected mode. 13; It consumes the reset vector, calls TempRamInit API from FSP binary. 14; 15;------------------------------------------------------------------------------ 16 17#include "Fsp.h" 18 19.686p 20.xmm 21.model small, c 22 23EXTRN CallPeiCoreEntryPoint:NEAR 24EXTRN TempRamInitParams:FAR 25 26; Pcds 27EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD 28EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD 29 30_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' 31 ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE 32 33;---------------------------------------------------------------------------- 34; 35; Procedure: _ModuleEntryPoint 36; 37; Input: None 38; 39; Output: None 40; 41; Destroys: Assume all registers 42; 43; Description: 44; 45; Transition to non-paged flat-model protected mode from a 46; hard-coded GDT that provides exactly two descriptors. 47; This is a bare bones transition to protected mode only 48; used for a while in PEI and possibly DXE. 49; 50; After enabling protected mode, a far jump is executed to 51; transfer to PEI using the newly loaded GDT. 52; 53; Return: None 54; 55; MMX Usage: 56; MM0 = BIST State 57; MM5 = Save time-stamp counter value high32bit 58; MM6 = Save time-stamp counter value low32bit. 59; 60;---------------------------------------------------------------------------- 61 62align 4 63_ModuleEntryPoint PROC NEAR C PUBLIC 64 fninit ; clear any pending Floating point exceptions 65 ; 66 ; Store the BIST value in mm0 67 ; 68 movd mm0, eax 69 70 ; 71 ; Save time-stamp counter value 72 ; rdtsc load 64bit time-stamp counter to EDX:EAX 73 ; 74 rdtsc 75 movd mm5, edx 76 movd mm6, eax 77 78 ; 79 ; Load the GDT table in GdtDesc 80 ; 81 mov esi, OFFSET GdtDesc 82 DB 66h 83 lgdt fword ptr cs:[si] 84 85 ; 86 ; Transition to 16 bit protected mode 87 ; 88 mov eax, cr0 ; Get control register 0 89 or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) 90 mov cr0, eax ; Activate protected mode 91 92 mov eax, cr4 ; Get control register 4 93 or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) 94 mov cr4, eax 95 96 ; 97 ; Now we're in 16 bit protected mode 98 ; Set up the selectors for 32 bit protected mode entry 99 ; 100 mov ax, SYS_DATA_SEL 101 mov ds, ax 102 mov es, ax 103 mov fs, ax 104 mov gs, ax 105 mov ss, ax 106 107 ; 108 ; Transition to Flat 32 bit protected mode 109 ; The jump to a far pointer causes the transition to 32 bit mode 110 ; 111 mov esi, offset ProtectedModeEntryLinearAddress 112 jmp fword ptr cs:[si] 113 114_ModuleEntryPoint ENDP 115_TEXT_REALMODE ENDS 116 117_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE' 118 ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE 119 120;---------------------------------------------------------------------------- 121; 122; Procedure: ProtectedModeEntryPoint 123; 124; Input: None 125; 126; Output: None 127; 128; Destroys: Assume all registers 129; 130; Description: 131; 132; This function handles: 133; Call two basic APIs from FSP binary 134; Initializes stack with some early data (BIST, PEI entry, etc) 135; 136; Return: None 137; 138;---------------------------------------------------------------------------- 139 140align 4 141ProtectedModeEntryPoint PROC NEAR PUBLIC 142 143 ; Find the fsp info header 144 mov edi, PcdGet32 (PcdFlashFvFspBase) 145 mov ecx, PcdGet32 (PcdFlashFvFspSize) 146 147 mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET] 148 cmp eax, FVH_SIGINATURE_VALID_VALUE 149 jnz FspHeaderNotFound 150 151 xor eax, eax 152 mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET] 153 cmp ax, 0 154 jnz FspFvExtHeaderExist 155 156 xor eax, eax 157 mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header 158 add edi, eax 159 jmp FspCheckFfsHeader 160 161FspFvExtHeaderExist: 162 add edi, eax 163 mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header 164 add edi, eax 165 166 ; Round up to 8 byte alignment 167 mov eax, edi 168 and al, 07h 169 jz FspCheckFfsHeader 170 171 and edi, 0FFFFFFF8h 172 add edi, 08h 173 174FspCheckFfsHeader: 175 ; Check the ffs guid 176 mov eax, dword ptr [edi] 177 cmp eax, FSP_HEADER_GUID_DWORD1 178 jnz FspHeaderNotFound 179 180 mov eax, dword ptr [edi + 4] 181 cmp eax, FSP_HEADER_GUID_DWORD2 182 jnz FspHeaderNotFound 183 184 mov eax, dword ptr [edi + 8] 185 cmp eax, FSP_HEADER_GUID_DWORD3 186 jnz FspHeaderNotFound 187 188 mov eax, dword ptr [edi + 0Ch] 189 cmp eax, FSP_HEADER_GUID_DWORD4 190 jnz FspHeaderNotFound 191 192 add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header 193 194 ; Check the section type as raw section 195 mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET] 196 cmp al, 019h 197 jnz FspHeaderNotFound 198 199 add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header 200 jmp FspHeaderFound 201 202FspHeaderNotFound: 203 jmp $ 204 205FspHeaderFound: 206 ; Get the fsp TempRamInit Api address 207 mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET] 208 add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET] 209 210 ; Setup the hardcode stack 211 mov esp, OFFSET TempRamInitStack 212 213 ; Call the fsp TempRamInit Api 214 jmp eax 215 216TempRamInitDone: 217 cmp eax, 8000000Eh ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found. 218 je CallSecFspInit ;If microcode not found, don't hang, but continue. 219 220 cmp eax, 0 ;Check if EFI_SUCCESS retuned. 221 jnz FspApiFailed 222 223 ; ECX: start of range 224 ; EDX: end of range 225CallSecFspInit: 226 xor eax, eax 227 mov esp, edx 228 229 ; Align the stack at DWORD 230 add esp, 3 231 and esp, 0FFFFFFFCh 232 233 push edx 234 push ecx 235 push eax ; zero - no hob list yet 236 call CallPeiCoreEntryPoint 237 238FspApiFailed: 239 jmp $ 240 241align 10h 242TempRamInitStack: 243 DD OFFSET TempRamInitDone 244 DD OFFSET TempRamInitParams 245 246ProtectedModeEntryPoint ENDP 247 248; 249; ROM-based Global-Descriptor Table for the Tiano PEI Phase 250; 251align 16 252PUBLIC BootGdtTable 253 254; 255; GDT[0]: 0x00: Null entry, never used. 256; 257NULL_SEL EQU $ - GDT_BASE ; Selector [0] 258GDT_BASE: 259BootGdtTable DD 0 260 DD 0 261; 262; Linear data segment descriptor 263; 264LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8] 265 DW 0FFFFh ; limit 0xFFFFF 266 DW 0 ; base 0 267 DB 0 268 DB 092h ; present, ring 0, data, expand-up, writable 269 DB 0CFh ; page-granular, 32-bit 270 DB 0 271; 272; Linear code segment descriptor 273; 274LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10] 275 DW 0FFFFh ; limit 0xFFFFF 276 DW 0 ; base 0 277 DB 0 278 DB 09Bh ; present, ring 0, data, expand-up, not-writable 279 DB 0CFh ; page-granular, 32-bit 280 DB 0 281; 282; System data segment descriptor 283; 284SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18] 285 DW 0FFFFh ; limit 0xFFFFF 286 DW 0 ; base 0 287 DB 0 288 DB 093h ; present, ring 0, data, expand-up, not-writable 289 DB 0CFh ; page-granular, 32-bit 290 DB 0 291 292; 293; System code segment descriptor 294; 295SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20] 296 DW 0FFFFh ; limit 0xFFFFF 297 DW 0 ; base 0 298 DB 0 299 DB 09Ah ; present, ring 0, data, expand-up, writable 300 DB 0CFh ; page-granular, 32-bit 301 DB 0 302; 303; Spare segment descriptor 304; 305SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28] 306 DW 0FFFFh ; limit 0xFFFFF 307 DW 0 ; base 0 308 DB 0Eh ; Changed from F000 to E000. 309 DB 09Bh ; present, ring 0, code, expand-up, writable 310 DB 00h ; byte-granular, 16-bit 311 DB 0 312; 313; Spare segment descriptor 314; 315SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30] 316 DW 0FFFFh ; limit 0xFFFF 317 DW 0 ; base 0 318 DB 0 319 DB 093h ; present, ring 0, data, expand-up, not-writable 320 DB 00h ; byte-granular, 16-bit 321 DB 0 322 323; 324; Spare segment descriptor 325; 326SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38] 327 DW 0 ; limit 0 328 DW 0 ; base 0 329 DB 0 330 DB 0 ; present, ring 0, data, expand-up, writable 331 DB 0 ; page-granular, 32-bit 332 DB 0 333GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes 334 335; 336; GDT Descriptor 337; 338GdtDesc: ; GDT descriptor 339 DW GDT_SIZE - 1 ; GDT limit 340 DD OFFSET BootGdtTable ; GDT base address 341 342 343ProtectedModeEntryLinearAddress LABEL FWORD 344ProtectedModeEntryLinearOffset LABEL DWORD 345 DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code 346 DW LINEAR_CODE_SEL 347 348_TEXT_PROTECTED_MODE ENDS 349END 350