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