1 ;------------------------------------------------------------------------------
3 ; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
4 ; SPDX-License-Identifier: BSD-2-Clause-Patent
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.
15 ;------------------------------------------------------------------------------
23 EXTRN CallPeiCoreEntryPoint:NEAR
24 EXTRN TempRamInitParams:FAR
27 EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
28 EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD
30 _TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
31 ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
33 ;----------------------------------------------------------------------------
35 ; Procedure: _ModuleEntryPoint
41 ; Destroys: Assume all registers
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.
50 ; After enabling protected mode, a far jump is executed to
51 ; transfer to PEI using the newly loaded GDT.
57 ; MM5 = Save time-stamp counter value high32bit
58 ; MM6 = Save time-stamp counter value low32bit.
60 ;----------------------------------------------------------------------------
63 _ModuleEntryPoint PROC NEAR C PUBLIC
64 fninit ; clear any pending Floating point exceptions
66 ; Store the BIST value in mm0
71 ; Save time-stamp counter value
72 ; rdtsc load 64bit time-stamp counter to EDX:EAX
79 ; Load the GDT table in GdtDesc
81 mov esi, OFFSET GdtDesc
83 lgdt fword ptr cs:[si]
86 ; Transition to 16 bit protected mode
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
92 mov eax, cr4 ; Get control register 4
93 or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
97 ; Now we're in 16 bit protected mode
98 ; Set up the selectors for 32 bit protected mode entry
108 ; Transition to Flat 32 bit protected mode
109 ; The jump to a far pointer causes the transition to 32 bit mode
111 mov esi, offset ProtectedModeEntryLinearAddress
112 jmp fword ptr cs:[si]
114 _ModuleEntryPoint ENDP
117 _TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
118 ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
120 ;----------------------------------------------------------------------------
122 ; Procedure: ProtectedModeEntryPoint
128 ; Destroys: Assume all registers
132 ; This function handles:
133 ; Call two basic APIs from FSP binary
134 ; Initializes stack with some early data (BIST, PEI entry, etc)
138 ;----------------------------------------------------------------------------
141 ProtectedModeEntryPoint PROC NEAR PUBLIC
143 ; Find the fsp info header
144 mov edi, PcdGet32 (PcdFlashFvFspBase)
145 mov ecx, PcdGet32 (PcdFlashFvFspSize)
147 mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
148 cmp eax, FVH_SIGINATURE_VALID_VALUE
149 jnz FspHeaderNotFound
152 mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
154 jnz FspFvExtHeaderExist
157 mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
159 jmp FspCheckFfsHeader
163 mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
166 ; Round up to 8 byte alignment
176 mov eax, dword ptr [edi]
177 cmp eax, FSP_HEADER_GUID_DWORD1
178 jnz FspHeaderNotFound
180 mov eax, dword ptr [edi + 4]
181 cmp eax, FSP_HEADER_GUID_DWORD2
182 jnz FspHeaderNotFound
184 mov eax, dword ptr [edi + 8]
185 cmp eax, FSP_HEADER_GUID_DWORD3
186 jnz FspHeaderNotFound
188 mov eax, dword ptr [edi + 0Ch]
189 cmp eax, FSP_HEADER_GUID_DWORD4
190 jnz FspHeaderNotFound
192 add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
194 ; Check the section type as raw section
195 mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
197 jnz FspHeaderNotFound
199 add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
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]
210 ; Setup the hardcode stack
211 mov esp, OFFSET TempRamInitStack
213 ; Call the fsp TempRamInit Api
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.
220 cmp eax, 0 ;Check if EFI_SUCCESS retuned.
223 ; ECX: start of range
229 ; Align the stack at DWORD
235 push eax ; zero - no hob list yet
236 call CallPeiCoreEntryPoint
243 DD OFFSET TempRamInitDone
244 DD OFFSET TempRamInitParams
246 ProtectedModeEntryPoint ENDP
249 ; ROM-based Global-Descriptor Table for the Tiano PEI Phase
255 ; GDT[0]: 0x00: Null entry, never used.
257 NULL_SEL EQU $ - GDT_BASE ; Selector [0]
262 ; Linear data segment descriptor
264 LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
265 DW 0FFFFh ; limit 0xFFFFF
268 DB 092h ; present, ring 0, data, expand-up, writable
269 DB 0CFh ; page-granular, 32-bit
272 ; Linear code segment descriptor
274 LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
275 DW 0FFFFh ; limit 0xFFFFF
278 DB 09Bh ; present, ring 0, data, expand-up, not-writable
279 DB 0CFh ; page-granular, 32-bit
282 ; System data segment descriptor
284 SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]
285 DW 0FFFFh ; limit 0xFFFFF
288 DB 093h ; present, ring 0, data, expand-up, not-writable
289 DB 0CFh ; page-granular, 32-bit
293 ; System code segment descriptor
295 SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
296 DW 0FFFFh ; limit 0xFFFFF
299 DB 09Ah ; present, ring 0, data, expand-up, writable
300 DB 0CFh ; page-granular, 32-bit
303 ; Spare segment descriptor
305 SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
306 DW 0FFFFh ; limit 0xFFFFF
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
313 ; Spare segment descriptor
315 SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
316 DW 0FFFFh ; limit 0xFFFF
319 DB 093h ; present, ring 0, data, expand-up, not-writable
320 DB 00h ; byte-granular, 16-bit
324 ; Spare segment descriptor
326 SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
330 DB 0 ; present, ring 0, data, expand-up, writable
331 DB 0 ; page-granular, 32-bit
333 GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes
338 GdtDesc: ; GDT descriptor
339 DW GDT_SIZE - 1 ; GDT limit
340 DD OFFSET BootGdtTable ; GDT base address
343 ProtectedModeEntryLinearAddress LABEL FWORD
344 ProtectedModeEntryLinearOffset LABEL DWORD
345 DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
348 _TEXT_PROTECTED_MODE ENDS