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