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