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 TempRamInit API from FSP binary.
21 ;------------------------------------------------------------------------------
29 EXTRN CallPeiCoreEntryPoint:NEAR
30 EXTRN TempRamInitParams:FAR
33 EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
34 EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD
36 _TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
37 ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
39 ;----------------------------------------------------------------------------
41 ; Procedure: _ModuleEntryPoint
47 ; Destroys: Assume all registers
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.
56 ; After enabling protected mode, a far jump is executed to
57 ; transfer to PEI using the newly loaded GDT.
63 ; MM5 = Save time-stamp counter value high32bit
64 ; MM6 = Save time-stamp counter value low32bit.
66 ;----------------------------------------------------------------------------
69 _ModuleEntryPoint PROC NEAR C PUBLIC
70 fninit ; clear any pending Floating point exceptions
72 ; Store the BIST value in mm0
77 ; Save time-stamp counter value
78 ; rdtsc load 64bit time-stamp counter to EDX:EAX
85 ; Load the GDT table in GdtDesc
87 mov esi, OFFSET GdtDesc
89 lgdt fword ptr cs:[si]
92 ; Transition to 16 bit protected mode
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
98 mov eax, cr4 ; Get control register 4
99 or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
103 ; Now we're in 16 bit protected mode
104 ; Set up the selectors for 32 bit protected mode entry
114 ; Transition to Flat 32 bit protected mode
115 ; The jump to a far pointer causes the transition to 32 bit mode
117 mov esi, offset ProtectedModeEntryLinearAddress
118 jmp fword ptr cs:[si]
120 _ModuleEntryPoint ENDP
123 _TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
124 ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
126 ;----------------------------------------------------------------------------
128 ; Procedure: ProtectedModeEntryPoint
134 ; Destroys: Assume all registers
138 ; This function handles:
139 ; Call two basic APIs from FSP binary
140 ; Initializes stack with some early data (BIST, PEI entry, etc)
144 ;----------------------------------------------------------------------------
147 ProtectedModeEntryPoint PROC NEAR PUBLIC
149 ; Find the fsp info header
150 mov edi, PcdGet32 (PcdFlashFvFspBase)
151 mov ecx, PcdGet32 (PcdFlashFvFspSize)
153 mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
154 cmp eax, FVH_SIGINATURE_VALID_VALUE
155 jnz FspHeaderNotFound
158 mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
160 jnz FspFvExtHeaderExist
163 mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
165 jmp FspCheckFfsHeader
169 mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
172 ; Round up to 8 byte alignment
182 mov eax, dword ptr [edi]
183 cmp eax, FSP_HEADER_GUID_DWORD1
184 jnz FspHeaderNotFound
186 mov eax, dword ptr [edi + 4]
187 cmp eax, FSP_HEADER_GUID_DWORD2
188 jnz FspHeaderNotFound
190 mov eax, dword ptr [edi + 8]
191 cmp eax, FSP_HEADER_GUID_DWORD3
192 jnz FspHeaderNotFound
194 mov eax, dword ptr [edi + 0Ch]
195 cmp eax, FSP_HEADER_GUID_DWORD4
196 jnz FspHeaderNotFound
198 add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
200 ; Check the section type as raw section
201 mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
203 jnz FspHeaderNotFound
205 add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
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]
216 ; Setup the hardcode stack
217 mov esp, OFFSET TempRamInitStack
219 ; Call the fsp TempRamInit Api
226 ; ECX: start of range
231 push eax ; zero - no hob list yet
232 call CallPeiCoreEntryPoint
239 DD OFFSET TempRamInitDone
240 DD OFFSET TempRamInitParams
242 ProtectedModeEntryPoint ENDP
245 ; ROM-based Global-Descriptor Table for the Tiano PEI Phase
251 ; GDT[0]: 0x00: Null entry, never used.
253 NULL_SEL EQU $ - GDT_BASE ; Selector [0]
258 ; Linear data segment descriptor
260 LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
261 DW 0FFFFh ; limit 0xFFFFF
264 DB 092h ; present, ring 0, data, expand-up, writable
265 DB 0CFh ; page-granular, 32-bit
268 ; Linear code segment descriptor
270 LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
271 DW 0FFFFh ; limit 0xFFFFF
274 DB 09Bh ; present, ring 0, data, expand-up, not-writable
275 DB 0CFh ; page-granular, 32-bit
278 ; System data segment descriptor
280 SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]
281 DW 0FFFFh ; limit 0xFFFFF
284 DB 093h ; present, ring 0, data, expand-up, not-writable
285 DB 0CFh ; page-granular, 32-bit
289 ; System code segment descriptor
291 SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
292 DW 0FFFFh ; limit 0xFFFFF
295 DB 09Ah ; present, ring 0, data, expand-up, writable
296 DB 0CFh ; page-granular, 32-bit
299 ; Spare segment descriptor
301 SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
302 DW 0FFFFh ; limit 0xFFFFF
304 DB 0Eh ; Changed from F000 to E000.
305 DB 09Bh ; present, ring 0, code, expand-up, writable
306 DB 00h ; byte-granular, 16-bit
309 ; Spare segment descriptor
311 SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
312 DW 0FFFFh ; limit 0xFFFF
315 DB 093h ; present, ring 0, data, expand-up, not-writable
316 DB 00h ; byte-granular, 16-bit
320 ; Spare segment descriptor
322 SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
326 DB 0 ; present, ring 0, data, expand-up, writable
327 DB 0 ; page-granular, 32-bit
329 GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes
334 GdtDesc: ; GDT descriptor
335 DW GDT_SIZE - 1 ; GDT limit
336 DD OFFSET BootGdtTable ; GDT base address
339 ProtectedModeEntryLinearAddress LABEL FWORD
340 ProtectedModeEntryLinearOffset LABEL DWORD
341 DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
344 _TEXT_PROTECTED_MODE ENDS