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