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 25ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase) 26ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize) 27 28ASM_GLOBAL ASM_PFX(_TEXT_REALMODE) 29ASM_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 60ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) 61ASM_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 112ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE) 113ASM_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 136ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint) 137ASM_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 157FspFvExtHeaderExist: 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 170FspCheckFfsHeader: 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 198FspHeaderNotFound: 199 jmp . 200 201FspHeaderFound: 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 212TempRamInitDone: 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 221CallSecFspInit: 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 234FspApiFailed: 235 jmp . 236 237.align 0x10 238TempRamInitStack: 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] 251GDT_BASE: 252BootGdtTable: .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# 331GdtDesc: # GDT descriptor 332 .word GDT_SIZE - 1 # GDT limit 333 .long BootGdtTable # GDT base address 334 335ASM_PFX(ProtectedModeEntryLinearAddress): 336ProtectedModeEntryLinearOffset: 337 .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code 338 .word LINEAR_CODE_SEL 339