]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2WrapperPkg / Library / SecFspWrapperPlatformSecLibSample / Ia32 / SecEntry.nasm
CommitLineData
2d24f4e7
LG
1;------------------------------------------------------------------------------\r
2;\r
3; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
512e23a3 4; SPDX-License-Identifier: BSD-2-Clause-Patent\r
2d24f4e7
LG
5;\r
6; Module Name:\r
7;\r
8; SecEntry.asm\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
19SECTION .text\r
20\r
21extern ASM_PFX(CallPeiCoreEntryPoint)\r
22extern ASM_PFX(FsptUpdDataPtr)\r
23\r
24; Pcds\r
25extern ASM_PFX(PcdGet32 (PcdFsptBaseAddress))\r
26\r
27;----------------------------------------------------------------------------\r
28;\r
29; Procedure: _ModuleEntryPoint\r
30;\r
31; Input: None\r
32;\r
33; Output: None\r
34;\r
35; Destroys: Assume all registers\r
36;\r
37; Description:\r
38;\r
39; Transition to non-paged flat-model protected mode from a\r
40; hard-coded GDT that provides exactly two descriptors.\r
41; This is a bare bones transition to protected mode only\r
42; used for a while in PEI and possibly DXE.\r
43;\r
44; After enabling protected mode, a far jump is executed to\r
45; transfer to PEI using the newly loaded GDT.\r
46;\r
47; Return: None\r
48;\r
49; MMX Usage:\r
50; MM0 = BIST State\r
51; MM5 = Save time-stamp counter value high32bit\r
52; MM6 = Save time-stamp counter value low32bit.\r
53;\r
54;----------------------------------------------------------------------------\r
55\r
56BITS 16\r
57align 4\r
58global ASM_PFX(ModuleEntryPoint)\r
59ASM_PFX(ModuleEntryPoint):\r
60 fninit ; clear any pending Floating point exceptions\r
61 ;\r
62 ; Store the BIST value in mm0\r
63 ;\r
64 movd mm0, eax\r
65\r
66 ;\r
67 ; Save time-stamp counter value\r
68 ; rdtsc load 64bit time-stamp counter to EDX:EAX\r
69 ;\r
70 rdtsc\r
71 movd mm5, edx\r
72 movd mm6, eax\r
73\r
74 ;\r
75 ; Load the GDT table in GdtDesc\r
76 ;\r
77 mov esi, GdtDesc\r
78 DB 66h\r
79 lgdt [cs:si]\r
80\r
81 ;\r
82 ; Transition to 16 bit protected mode\r
83 ;\r
84 mov eax, cr0 ; Get control register 0\r
85 or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)\r
86 mov cr0, eax ; Activate protected mode\r
87\r
88 mov eax, cr4 ; Get control register 4\r
89 or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
90 mov cr4, eax\r
91\r
92 ;\r
93 ; Now we're in 16 bit protected mode\r
94 ; Set up the selectors for 32 bit protected mode entry\r
95 ;\r
96 mov ax, SYS_DATA_SEL\r
97 mov ds, ax\r
98 mov es, ax\r
99 mov fs, ax\r
100 mov gs, ax\r
101 mov ss, ax\r
102\r
103 ;\r
104 ; Transition to Flat 32 bit protected mode\r
105 ; The jump to a far pointer causes the transition to 32 bit mode\r
106 ;\r
107 mov esi, ProtectedModeEntryLinearAddress\r
108 jmp dword far [cs:si]\r
109\r
110;----------------------------------------------------------------------------\r
111;\r
112; Procedure: ProtectedModeEntryPoint\r
113;\r
114; Input: None\r
115;\r
116; Output: None\r
117;\r
118; Destroys: Assume all registers\r
119;\r
120; Description:\r
121;\r
122; This function handles:\r
123; Call two basic APIs from FSP binary\r
124; Initializes stack with some early data (BIST, PEI entry, etc)\r
125;\r
126; Return: None\r
127;\r
128;----------------------------------------------------------------------------\r
129\r
130BITS 32\r
131align 4\r
132ProtectedModeEntryPoint:\r
133\r
134 ; Find the fsp info header\r
135 mov edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]\r
136\r
137 mov eax, dword [edi + FVH_SIGINATURE_OFFSET]\r
138 cmp eax, FVH_SIGINATURE_VALID_VALUE\r
139 jnz FspHeaderNotFound\r
140\r
141 xor eax, eax\r
142 mov ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]\r
143 cmp ax, 0\r
144 jnz FspFvExtHeaderExist\r
145\r
146 xor eax, eax\r
147 mov ax, word [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header\r
148 add edi, eax\r
149 jmp FspCheckFfsHeader\r
150\r
151FspFvExtHeaderExist:\r
152 add edi, eax\r
153 mov eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header\r
154 add edi, eax\r
155\r
156 ; Round up to 8 byte alignment\r
157 mov eax, edi\r
158 and al, 07h\r
159 jz FspCheckFfsHeader\r
160\r
161 and edi, 0FFFFFFF8h\r
162 add edi, 08h\r
163\r
164FspCheckFfsHeader:\r
165 ; Check the ffs guid\r
166 mov eax, dword [edi]\r
167 cmp eax, FSP_HEADER_GUID_DWORD1\r
168 jnz FspHeaderNotFound\r
169\r
170 mov eax, dword [edi + 4]\r
171 cmp eax, FSP_HEADER_GUID_DWORD2\r
172 jnz FspHeaderNotFound\r
173\r
174 mov eax, dword [edi + 8]\r
175 cmp eax, FSP_HEADER_GUID_DWORD3\r
176 jnz FspHeaderNotFound\r
177\r
178 mov eax, dword [edi + 0Ch]\r
179 cmp eax, FSP_HEADER_GUID_DWORD4\r
180 jnz FspHeaderNotFound\r
181\r
182 add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header\r
183\r
184 ; Check the section type as raw section\r
185 mov al, byte [edi + SECTION_HEADER_TYPE_OFFSET]\r
186 cmp al, 019h\r
187 jnz FspHeaderNotFound\r
188\r
189 add edi, RAW_SECTION_HEADER_SIZE_VALUE ; 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 mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]\r
198 add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]\r
199\r
200 ; Setup the hardcode stack\r
201 mov esp, TempRamInitStack\r
202\r
203 ; Call the fsp TempRamInit Api\r
204 jmp eax\r
205\r
206TempRamInitDone:\r
207 cmp eax, 8000000Eh ;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
97eedf5d 210 cmp eax, 0 ;Check if EFI_SUCCESS returned.\r
2d24f4e7
LG
211 jnz FspApiFailed\r
212\r
213 ; ECX: start of range\r
214 ; EDX: end of range\r
215CallSecFspInit:\r
216 xor eax, eax\r
217 mov esp, edx\r
218\r
219 ; Align the stack at DWORD\r
220 add esp, 3\r
221 and esp, 0FFFFFFFCh\r
222\r
223 push edx\r
224 push ecx\r
225 push eax ; zero - no hob list yet\r
226 call ASM_PFX(CallPeiCoreEntryPoint)\r
227\r
228FspApiFailed:\r
229 jmp $\r
230\r
231align 10h\r
232TempRamInitStack:\r
233 DD TempRamInitDone\r
234 DD ASM_PFX(FsptUpdDataPtr); TempRamInitParams\r
235\r
236;\r
237; ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
238;\r
239align 16\r
240global ASM_PFX(BootGdtTable)\r
241\r
242;\r
243; GDT[0]: 0x00: Null entry, never used.\r
244;\r
245NULL_SEL EQU $ - GDT_BASE ; Selector [0]\r
246GDT_BASE:\r
247ASM_PFX(BootGdtTable):\r
248 DD 0\r
249 DD 0\r
250;\r
251; Linear data segment descriptor\r
252;\r
253LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]\r
254 DW 0FFFFh ; limit 0xFFFFF\r
255 DW 0 ; base 0\r
256 DB 0\r
257 DB 092h ; present, ring 0, data, expand-up, writable\r
258 DB 0CFh ; page-granular, 32-bit\r
259 DB 0\r
260;\r
261; Linear code segment descriptor\r
262;\r
263LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]\r
264 DW 0FFFFh ; limit 0xFFFFF\r
265 DW 0 ; base 0\r
266 DB 0\r
267 DB 09Bh ; present, ring 0, data, expand-up, not-writable\r
268 DB 0CFh ; page-granular, 32-bit\r
269 DB 0\r
270;\r
271; System data segment descriptor\r
272;\r
273SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]\r
274 DW 0FFFFh ; limit 0xFFFFF\r
275 DW 0 ; base 0\r
276 DB 0\r
277 DB 093h ; present, ring 0, data, expand-up, not-writable\r
278 DB 0CFh ; page-granular, 32-bit\r
279 DB 0\r
280\r
281;\r
282; System code segment descriptor\r
283;\r
284SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]\r
285 DW 0FFFFh ; limit 0xFFFFF\r
286 DW 0 ; base 0\r
287 DB 0\r
288 DB 09Ah ; present, ring 0, data, expand-up, writable\r
289 DB 0CFh ; page-granular, 32-bit\r
290 DB 0\r
291;\r
292; Spare segment descriptor\r
293;\r
294SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]\r
295 DW 0FFFFh ; limit 0xFFFFF\r
296 DW 0 ; base 0\r
297 DB 0Eh ; Changed from F000 to E000.\r
298 DB 09Bh ; present, ring 0, code, expand-up, writable\r
299 DB 00h ; byte-granular, 16-bit\r
300 DB 0\r
301;\r
302; Spare segment descriptor\r
303;\r
304SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]\r
305 DW 0FFFFh ; limit 0xFFFF\r
306 DW 0 ; base 0\r
307 DB 0\r
308 DB 093h ; present, ring 0, data, expand-up, not-writable\r
309 DB 00h ; byte-granular, 16-bit\r
310 DB 0\r
311\r
312;\r
313; Spare segment descriptor\r
314;\r
315SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]\r
316 DW 0 ; limit 0\r
317 DW 0 ; base 0\r
318 DB 0\r
319 DB 0 ; present, ring 0, data, expand-up, writable\r
320 DB 0 ; page-granular, 32-bit\r
321 DB 0\r
322GDT_SIZE EQU $ - GDT_BASE ; Size, in bytes\r
323\r
324;\r
325; GDT Descriptor\r
326;\r
327GdtDesc: ; GDT descriptor\r
328 DW GDT_SIZE - 1 ; GDT limit\r
329 DD GDT_BASE ; GDT base address\r
330\r
331\r
332ProtectedModeEntryLinearAddress:\r
333ProtectedModeEntryLinear:\r
334 DD ProtectedModeEntryPoint ; Offset of our 32 bit code\r
335 DW LINEAR_CODE_SEL\r