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