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