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 #------------------------------------------------------------------------------
19 ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase)
20 ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize)
22 ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)
23 ASM_PFX(_TEXT_REALMODE):
24 #----------------------------------------------------------------------------
26 # Procedure: _ModuleEntryPoint
32 # Destroys: Assume all registers
36 # Transition to non-paged flat-model protected mode from a
37 # hard-coded GDT that provides exactly two descriptors.
38 # This is a bare bones transition to protected mode only
39 # used for a while in PEI and possibly DXE.
41 # After enabling protected mode, a far jump is executed to
42 # transfer to PEI using the newly loaded GDT.
48 # MM5 = Save time-stamp counter value high32bit
49 # MM6 = Save time-stamp counter value low32bit.
51 #----------------------------------------------------------------------------
54 ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
55 ASM_PFX(_ModuleEntryPoint):
56 fninit # clear any pending Floating point exceptions
58 # Store the BIST value in mm0
63 # Save time-stamp counter value
64 # rdtsc load 64bit time-stamp counter to EDX:EAX
71 # Load the GDT table in GdtDesc
78 # Transition to 16 bit protected mode
80 movl %cr0, %eax # Get control register 0
81 orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)
82 movl %eax, %cr0 # Activate protected mode
84 movl %cr4, %eax # Get control register 4
85 orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
89 # Now we're in 16 bit protected mode
90 # Set up the selectors for 32 bit protected mode entry
92 movw SYS_DATA_SEL, %ax
100 # Transition to Flat 32 bit protected mode
101 # The jump to a far pointer causes the transition to 32 bit mode
103 movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi
106 ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)
107 ASM_PFX(_TEXT_PROTECTED_MODE):
109 #----------------------------------------------------------------------------
111 # Procedure: ProtectedModeEntryPoint
117 # Destroys: Assume all registers
121 # This function handles:
122 # Call two basic APIs from FSP binary
123 # Initializes stack with some early data (BIST, PEI entry, etc)
127 #----------------------------------------------------------------------------
130 ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)
131 ASM_PFX(ProtectedModeEntryPoint):
133 # Find the fsp info header
134 movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi
135 movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx
137 movl FVH_SIGINATURE_OFFSET(%edi), %eax
138 cmp $FVH_SIGINATURE_VALID_VALUE, %eax
139 jnz FspHeaderNotFound
142 movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax
144 jnz FspFvExtHeaderExist
147 movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header
149 jmp FspCheckFfsHeader
153 movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header
156 # Round up to 8 byte alignment
161 and $0xFFFFFFF8, %edi
167 cmp $FSP_HEADER_GUID_DWORD1, %eax
168 jnz FspHeaderNotFound
171 cmp $FSP_HEADER_GUID_DWORD2, %eax
172 jnz FspHeaderNotFound
174 movl 0x08(%edi), %eax
175 cmp $FSP_HEADER_GUID_DWORD3, %eax
176 jnz FspHeaderNotFound
178 movl 0x0c(%edi), %eax
179 cmp $FSP_HEADER_GUID_DWORD4, %eax
180 jnz FspHeaderNotFound
182 add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header
184 # Check the section type as raw section
185 movb SECTION_HEADER_TYPE_OFFSET(%edi), %al
187 jnz FspHeaderNotFound
189 addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header
196 # Get the fsp TempRamInit Api address
197 movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax
198 addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax
200 # Setup the hardcode stack
201 movl $TempRamInitStack, %esp
203 # Call the fsp TempRamInit Api
207 cmp $0x8000000E, %eax #Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.
208 je CallSecFspInit #If microcode not found, don't hang, but continue.
213 # ECX: start of range
219 # Align the stack at DWORD
221 andl $0xFFFFFFFC, %esp
225 pushl %eax # zero - no hob list yet
226 call ASM_PFX(CallPeiCoreEntryPoint)
233 .long TempRamInitDone
234 .long ASM_PFX(TempRamInitParams)
237 # ROM-based Global-Descriptor Table for the Tiano PEI Phase
242 # GDT[0]: 0x00: Null entry, never used.
244 .equ NULL_SEL, . - GDT_BASE # Selector [0]
246 BootGdtTable: .long 0
249 # Linear data segment descriptor
251 .equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]
252 .word 0xFFFF # limit 0xFFFFF
255 .byte 0x92 # present, ring 0, data, expand-up, writable
256 .byte 0xCF # page-granular, 32-bit
259 # Linear code segment descriptor
261 .equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
262 .word 0xFFFF # limit 0xFFFFF
265 .byte 0x9B # present, ring 0, data, expand-up, not-writable
266 .byte 0xCF # page-granular, 32-bit
269 # System data segment descriptor
271 .equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]
272 .word 0xFFFF # limit 0xFFFFF
275 .byte 0x93 # present, ring 0, data, expand-up, not-writable
276 .byte 0xCF # page-granular, 32-bit
280 # System code segment descriptor
282 .equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20]
283 .word 0xFFFF # limit 0xFFFFF
286 .byte 0x9A # present, ring 0, data, expand-up, writable
287 .byte 0xCF # page-granular, 32-bit
290 # Spare segment descriptor
292 .equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28]
293 .word 0xFFFF # limit 0xFFFFF
295 .byte 0x0E # Changed from F000 to E000.
296 .byte 0x9B # present, ring 0, code, expand-up, writable
297 .byte 0x00 # byte-granular, 16-bit
300 # Spare segment descriptor
302 .equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30]
303 .word 0xFFFF # limit 0xFFFF
306 .byte 0x93 # present, ring 0, data, expand-up, not-writable
307 .byte 0x00 # byte-granular, 16-bit
311 # Spare segment descriptor
313 .equ SPARE5_SEL, . - GDT_BASE # Selector [0x38]
317 .byte 0 # present, ring 0, data, expand-up, writable
318 .byte 0 # page-granular, 32-bit
320 .equ GDT_SIZE, . - BootGdtTable # Size, in bytes
325 GdtDesc: # GDT descriptor
326 .word GDT_SIZE - 1 # GDT limit
327 .long BootGdtTable # GDT base address
329 ASM_PFX(ProtectedModeEntryLinearAddress):
330 ProtectedModeEntryLinearOffset:
331 .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code
332 .word LINEAR_CODE_SEL