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