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