1 ;------------------------------------------------------------------------------
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.
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.
18 ; This is the code that goes from real-mode to protected mode.
19 ; It consumes the reset vector, calls two basic APIs from FSP binary.
21 ;------------------------------------------------------------------------------
28 EXTRN CallPeiCoreEntryPoint:NEAR
29 EXTRN TempRamInitParams:FAR
32 EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
33 EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD
35 _TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
36 ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
38 ;----------------------------------------------------------------------------
40 ; Procedure: _ModuleEntryPoint
46 ; Destroys: Assume all registers
50 ; Transition to non-paged flat-model protected mode from a
51 ; hard-coded GDT that provides exactly two descriptors.
52 ; This is a bare bones transition to protected mode only
53 ; used for a while in PEI and possibly DXE.
55 ; After enabling protected mode, a far jump is executed to
56 ; transfer to PEI using the newly loaded GDT.
62 ; MM5 = Save time-stamp counter value high32bit
63 ; MM6 = Save time-stamp counter value low32bit.
65 ;----------------------------------------------------------------------------
68 _ModuleEntryPoint PROC NEAR C PUBLIC
69 fninit ; clear any pending Floating point exceptions
71 ; Store the BIST value in mm0
76 ; Save time-stamp counter value
77 ; rdtsc load 64bit time-stamp counter to EDX:EAX
84 ; Load the GDT table in GdtDesc
86 mov esi, OFFSET GdtDesc
88 lgdt fword ptr cs:[si]
91 ; Transition to 16 bit protected mode
93 mov eax, cr0 ; Get control register 0
94 or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
95 mov cr0, eax ; Activate protected mode
97 mov eax, cr4 ; Get control register 4
98 or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
102 ; Now we're in 16 bit protected mode
103 ; Set up the selectors for 32 bit protected mode entry
113 ; Transition to Flat 32 bit protected mode
114 ; The jump to a far pointer causes the transition to 32 bit mode
116 mov esi, offset ProtectedModeEntryLinearAddress
117 jmp fword ptr cs:[si]
119 _ModuleEntryPoint ENDP
122 _TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
123 ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
125 ;----------------------------------------------------------------------------
127 ; Procedure: ProtectedModeEntryPoint
133 ; Destroys: Assume all registers
137 ; This function handles:
138 ; Call two basic APIs from FSP binary
139 ; Initializes stack with some early data (BIST, PEI entry, etc)
143 ;----------------------------------------------------------------------------
146 ProtectedModeEntryPoint PROC NEAR PUBLIC
148 ; Find the fsp info header
149 mov edi, PcdGet32 (PcdFlashFvFspBase)
150 mov ecx, PcdGet32 (PcdFlashFvFspSize)
152 mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
153 cmp eax, FVH_SIGINATURE_VALID_VALUE
154 jnz FspHeaderNotFound
157 mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
159 jnz FspFvExtHeaderExist
162 mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
164 jmp FspCheckFfsHeader
168 mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
171 ; Round up to 8 byte alignment
181 mov eax, dword ptr [edi]
182 cmp eax, FSP_HEADER_GUID_DWORD1
183 jnz FspHeaderNotFound
185 mov eax, dword ptr [edi + 4]
186 cmp eax, FSP_HEADER_GUID_DWORD2
187 jnz FspHeaderNotFound
189 mov eax, dword ptr [edi + 8]
190 cmp eax, FSP_HEADER_GUID_DWORD3
191 jnz FspHeaderNotFound
193 mov eax, dword ptr [edi + 0Ch]
194 cmp eax, FSP_HEADER_GUID_DWORD4
195 jnz FspHeaderNotFound
197 add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
199 ; Check the section type as raw section
200 mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
202 jnz FspHeaderNotFound
204 add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
211 ; Get the fsp TempRamInit Api address
212 mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]
213 add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
215 ; Setup the hardcode stack
216 mov esp, OFFSET TempRamInitStack
218 ; Call the fsp TempRamInit Api
225 ; ECX: start of range
230 push eax ; zero - no hob list yet
231 call CallPeiCoreEntryPoint
238 DD OFFSET TempRamInitDone
239 DD OFFSET TempRamInitParams
241 ProtectedModeEntryPoint ENDP
244 ; ROM-based Global-Descriptor Table for the Tiano PEI Phase
250 ; GDT[0]: 0x00: Null entry, never used.
252 NULL_SEL EQU $ - GDT_BASE ; Selector [0]
257 ; Linear data segment descriptor
259 LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
260 DW 0FFFFh ; limit 0xFFFFF
263 DB 092h ; present, ring 0, data, expand-up, writable
264 DB 0CFh ; page-granular, 32-bit
267 ; Linear code segment descriptor
269 LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
270 DW 0FFFFh ; limit 0xFFFFF
273 DB 09Bh ; present, ring 0, data, expand-up, not-writable
274 DB 0CFh ; page-granular, 32-bit
277 ; System data segment descriptor
279 SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]
280 DW 0FFFFh ; limit 0xFFFFF
283 DB 093h ; present, ring 0, data, expand-up, not-writable
284 DB 0CFh ; page-granular, 32-bit
288 ; System code segment descriptor
290 SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
291 DW 0FFFFh ; limit 0xFFFFF
294 DB 09Ah ; present, ring 0, data, expand-up, writable
295 DB 0CFh ; page-granular, 32-bit
298 ; Spare segment descriptor
300 SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
301 DW 0FFFFh ; limit 0xFFFFF
303 DB 0Eh ; Changed from F000 to E000.
304 DB 09Bh ; present, ring 0, code, expand-up, writable
305 DB 00h ; byte-granular, 16-bit
308 ; Spare segment descriptor
310 SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
311 DW 0FFFFh ; limit 0xFFFF
314 DB 093h ; present, ring 0, data, expand-up, not-writable
315 DB 00h ; byte-granular, 16-bit
319 ; Spare segment descriptor
321 SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
325 DB 0 ; present, ring 0, data, expand-up, writable
326 DB 0 ; page-granular, 32-bit
328 GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes
333 GdtDesc: ; GDT descriptor
334 DW GDT_SIZE - 1 ; GDT limit
335 DD OFFSET BootGdtTable ; GDT base address
338 ProtectedModeEntryLinearAddress LABEL FWORD
339 ProtectedModeEntryLinearOffset LABEL DWORD
340 DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
343 _TEXT_PROTECTED_MODE ENDS