]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S
Do not deadloop if Microcode not found in FspTempRamInit.
[mirror_edk2.git] / IntelFspWrapperPkg / Library / SecPeiFspPlatformSecLibSample / Ia32 / SecEntry.S
CommitLineData
a33a2f62
JY
1#------------------------------------------------------------------------------\r
2#\r
3# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
4# This program and the accompanying materials\r
5# are licensed and made available under the terms and conditions of the BSD License\r
6# which accompanies this distribution. The full text of the license may be found at\r
7# http://opensource.org/licenses/bsd-license.php.\r
8#\r
9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11#\r
12# Module Name:\r
13#\r
14# SecEntry.S\r
15#\r
16# Abstract:\r
17#\r
18# This is the code that goes from real-mode to protected mode.\r
19# It consumes the reset vector, calls TempRamInit API from FSP binary.\r
20#\r
21#------------------------------------------------------------------------------\r
22\r
23#include "Fsp.h"\r
24\r
a81fcd30
JY
25ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase)\r
26ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize)\r
27\r
a33a2f62
JY
28ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)\r
29ASM_PFX(_TEXT_REALMODE):\r
30#----------------------------------------------------------------------------\r
31#\r
32# Procedure: _ModuleEntryPoint\r
33#\r
34# Input: None\r
35#\r
36# Output: None\r
37#\r
38# Destroys: Assume all registers\r
39#\r
40# Description:\r
41#\r
42# Transition to non-paged flat-model protected mode from a\r
43# hard-coded GDT that provides exactly two descriptors.\r
44# This is a bare bones transition to protected mode only\r
45# used for a while in PEI and possibly DXE.\r
46#\r
47# After enabling protected mode, a far jump is executed to\r
48# transfer to PEI using the newly loaded GDT.\r
49#\r
50# Return: None\r
51#\r
52# MMX Usage:\r
53# MM0 = BIST State\r
54# MM5 = Save time-stamp counter value high32bit\r
55# MM6 = Save time-stamp counter value low32bit.\r
56#\r
57#----------------------------------------------------------------------------\r
58\r
59.align 4\r
60ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)\r
61ASM_PFX(_ModuleEntryPoint):\r
62 fninit # clear any pending Floating point exceptions\r
63 #\r
64 # Store the BIST value in mm0\r
65 #\r
66 movd %eax, %mm0\r
67\r
68 #\r
69 # Save time-stamp counter value\r
70 # rdtsc load 64bit time-stamp counter to EDX:EAX\r
71 #\r
72 rdtsc\r
73 movd %edx, %mm5\r
74 movd %ecx, %mm6\r
75\r
76 #\r
77 # Load the GDT table in GdtDesc\r
78 #\r
79 movl $GdtDesc, %esi\r
80 .byte 0x66\r
81 lgdt %cs:(%si)\r
82\r
83 #\r
84 # Transition to 16 bit protected mode\r
85 #\r
86 movl %cr0, %eax # Get control register 0\r
87 orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)\r
88 movl %eax, %cr0 # Activate protected mode\r
89\r
90 movl %cr4, %eax # Get control register 4\r
91 orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
92 movl %eax, %cr4\r
93\r
94 #\r
95 # Now we're in 16 bit protected mode\r
96 # Set up the selectors for 32 bit protected mode entry\r
97 #\r
98 movw SYS_DATA_SEL, %ax\r
99 movw %ax, %ds\r
100 movw %ax, %es\r
101 movw %ax, %fs\r
102 movw %ax, %gs\r
103 movw %ax, %ss\r
104\r
105 #\r
106 # Transition to Flat 32 bit protected mode\r
107 # The jump to a far pointer causes the transition to 32 bit mode\r
108 #\r
a81fcd30 109 movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi\r
a33a2f62
JY
110 jmp *%cs:(%si)\r
111\r
112ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)\r
113ASM_PFX(_TEXT_PROTECTED_MODE):\r
114\r
115#----------------------------------------------------------------------------\r
116#\r
117# Procedure: ProtectedModeEntryPoint\r
118#\r
119# Input: None\r
120#\r
121# Output: None\r
122#\r
123# Destroys: Assume all registers\r
124#\r
125# Description:\r
126#\r
127# This function handles:\r
128# Call two basic APIs from FSP binary\r
129# Initializes stack with some early data (BIST, PEI entry, etc)\r
130#\r
131# Return: None\r
132#\r
133#----------------------------------------------------------------------------\r
134\r
135.align 4\r
136ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)\r
137ASM_PFX(ProtectedModeEntryPoint):\r
138\r
139 # Find the fsp info header\r
a81fcd30
JY
140 movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi\r
141 movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx\r
a33a2f62
JY
142\r
143 movl FVH_SIGINATURE_OFFSET(%edi), %eax\r
144 cmp $FVH_SIGINATURE_VALID_VALUE, %eax\r
145 jnz FspHeaderNotFound\r
146\r
147 xorl %eax, %eax\r
148 movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax\r
149 cmp %ax, 0\r
150 jnz FspFvExtHeaderExist\r
151\r
152 xorl %eax, %eax\r
153 movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header\r
154 addl %eax, %edi\r
155 jmp FspCheckFfsHeader\r
156\r
157FspFvExtHeaderExist:\r
158 addl %eax, %edi\r
159 movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header\r
160 addl %eax, %edi\r
161\r
162 # Round up to 8 byte alignment\r
163 movl %edi, %eax\r
164 andb $0x07, %al\r
165 jz FspCheckFfsHeader\r
166\r
167 and $0xFFFFFFF8, %edi\r
168 add $0x08, %edi\r
169\r
170FspCheckFfsHeader:\r
171 # Check the ffs guid\r
172 movl (%edi), %eax\r
173 cmp $FSP_HEADER_GUID_DWORD1, %eax\r
174 jnz FspHeaderNotFound\r
175\r
176 movl 0x4(%edi), %eax\r
177 cmp $FSP_HEADER_GUID_DWORD2, %eax\r
178 jnz FspHeaderNotFound\r
179\r
180 movl 0x08(%edi), %eax\r
181 cmp $FSP_HEADER_GUID_DWORD3, %eax\r
182 jnz FspHeaderNotFound\r
183\r
184 movl 0x0c(%edi), %eax\r
185 cmp $FSP_HEADER_GUID_DWORD4, %eax\r
186 jnz FspHeaderNotFound\r
187\r
188 add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header\r
189\r
190 # Check the section type as raw section\r
191 movb SECTION_HEADER_TYPE_OFFSET(%edi), %al\r
192 cmp $0x19, %al\r
193 jnz FspHeaderNotFound\r
194\r
195 addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header\r
196 jmp FspHeaderFound\r
197\r
198FspHeaderNotFound:\r
199 jmp .\r
200\r
201FspHeaderFound:\r
202 # Get the fsp TempRamInit Api address\r
203 movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax\r
204 addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax\r
205\r
206 # Setup the hardcode stack\r
207 movl $TempRamInitStack, %esp\r
208\r
209 # Call the fsp TempRamInit Api\r
210 jmp *%eax\r
211\r
212TempRamInitDone:\r
e620b729
JY
213 cmp $0x8000000E, %eax #Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.\r
214 je CallSecFspInit #If microcode not found, don't hang, but continue.\r
215\r
a33a2f62
JY
216 cmp $0x0, %eax\r
217 jnz FspApiFailed\r
218\r
219 # ECX: start of range\r
220 # EDX: end of range\r
e620b729
JY
221CallSecFspInit:\r
222 xorl %eax, %eax\r
a33a2f62 223 movl %edx, %esp\r
e620b729
JY
224\r
225 # Align the stack at DWORD\r
226 addl $3, %esp\r
227 andl $0xFFFFFFFC, %esp\r
228\r
a33a2f62
JY
229 pushl %edx\r
230 pushl %ecx\r
231 pushl %eax # zero - no hob list yet\r
232 call ASM_PFX(CallPeiCoreEntryPoint)\r
233\r
234FspApiFailed:\r
235 jmp .\r
236\r
237.align 0x10\r
238TempRamInitStack:\r
239 .long TempRamInitDone\r
a81fcd30 240 .long ASM_PFX(TempRamInitParams)\r
a33a2f62
JY
241\r
242#\r
243# ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
244#\r
245.align 16\r
246\r
247#\r
248# GDT[0]: 0x00: Null entry, never used.\r
249#\r
250.equ NULL_SEL, . - GDT_BASE # Selector [0]\r
251GDT_BASE:\r
252BootGdtTable: .long 0\r
253 .long 0\r
254#\r
255# Linear data segment descriptor\r
256#\r
257.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]\r
258 .word 0xFFFF # limit 0xFFFFF\r
259 .word 0 # base 0\r
260 .byte 0\r
261 .byte 0x92 # present, ring 0, data, expand-up, writable\r
262 .byte 0xCF # page-granular, 32-bit\r
263 .byte 0\r
264#\r
265# Linear code segment descriptor\r
266#\r
267.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]\r
268 .word 0xFFFF # limit 0xFFFFF\r
269 .word 0 # base 0\r
270 .byte 0\r
271 .byte 0x9B # present, ring 0, data, expand-up, not-writable\r
272 .byte 0xCF # page-granular, 32-bit\r
273 .byte 0\r
274#\r
275# System data segment descriptor\r
276#\r
277.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]\r
278 .word 0xFFFF # limit 0xFFFFF\r
279 .word 0 # base 0\r
280 .byte 0\r
281 .byte 0x93 # present, ring 0, data, expand-up, not-writable\r
282 .byte 0xCF # page-granular, 32-bit\r
283 .byte 0\r
284\r
285#\r
286# System code segment descriptor\r
287#\r
288.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20]\r
289 .word 0xFFFF # limit 0xFFFFF\r
290 .word 0 # base 0\r
291 .byte 0\r
292 .byte 0x9A # present, ring 0, data, expand-up, writable\r
293 .byte 0xCF # page-granular, 32-bit\r
294 .byte 0\r
295#\r
296# Spare segment descriptor\r
297#\r
298.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28]\r
299 .word 0xFFFF # limit 0xFFFFF\r
300 .word 0 # base 0\r
301 .byte 0x0E # Changed from F000 to E000.\r
302 .byte 0x9B # present, ring 0, code, expand-up, writable\r
303 .byte 0x00 # byte-granular, 16-bit\r
304 .byte 0\r
305#\r
306# Spare segment descriptor\r
307#\r
308.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30]\r
309 .word 0xFFFF # limit 0xFFFF\r
310 .word 0 # base 0\r
311 .byte 0\r
312 .byte 0x93 # present, ring 0, data, expand-up, not-writable\r
313 .byte 0x00 # byte-granular, 16-bit\r
314 .byte 0\r
315\r
316#\r
317# Spare segment descriptor\r
318#\r
319.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38]\r
320 .word 0 # limit 0\r
321 .word 0 # base 0\r
322 .byte 0\r
323 .byte 0 # present, ring 0, data, expand-up, writable\r
324 .byte 0 # page-granular, 32-bit\r
325 .byte 0\r
326.equ GDT_SIZE, . - BootGdtTable # Size, in bytes\r
327\r
328#\r
329# GDT Descriptor\r
330#\r
331GdtDesc: # GDT descriptor\r
332 .word GDT_SIZE - 1 # GDT limit\r
333 .long BootGdtTable # GDT base address\r
334\r
335ASM_PFX(ProtectedModeEntryLinearAddress):\r
336ProtectedModeEntryLinearOffset:\r
a81fcd30 337 .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code\r
a33a2f62 338 .word LINEAR_CODE_SEL\r