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