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