#------------------------------------------------------------------------------ # # Copyright (c) 2015, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # # Abstract: # # This is the code that goes from real-mode to protected mode. # It consumes the reset vector, configures the stack. # #------------------------------------------------------------------------------ # # Contrary to the name, this file contains 16 bit code as well. # .text #---------------------------------------------------------------------------- # # Procedure: _ModuleEntryPoint # # Input: None # # Output: None # # Destroys: Assume all registers # # Description: # # Transition to non-paged flat-model protected mode from a # hard-coded GDT that provides exactly two descriptors. # This is a bare bones transition to protected mode only # used for a while in PEI and possibly DXE. # # After enabling protected mode, a far jump is executed to # transfer to PEI using the newly loaded GDT. # # Return: None # #---------------------------------------------------------------------------- ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) ASM_PFX(_ModuleEntryPoint): # # Load the GDT table in GdtDesc # .byte 0x66,0xbe #movl $GdtDesc, %esi .long GdtDesc .byte 0x66,0x2e,0x0f,0x01,0x14 #lgdt %cs:(%si) # # Transition to 16 bit protected mode # .byte 0x0f,0x20,0xc0 #movl %cr0, %eax # Get control register 0 .byte 0x66,0x83,0xc8,0x03 #orl $0x0000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) .byte 0x0f,0x22,0xc0 #movl %eax, %cr0 # Activate protected mode # # Now we're in 16 bit protected mode # Set up the selectors for 32 bit protected mode entry # .byte 0xb8 #movw SYS_DATA_SEL, %ax .word SYS_DATA_SEL .byte 0x8e,0xd8 #movw %ax, %ds .byte 0x8e,0xc0 #movw %ax, %es .byte 0x8e,0xe0 #movw %ax, %fs .byte 0x8e,0xe8 #movw %ax, %gs .byte 0x8e,0xd0 #movw %ax, %ss # # Transition to Flat 32 bit protected mode # The jump to a far pointer causes the transition to 32 bit mode # .byte 0x66,0xbe #movl ProtectedModeEntryLinearAddress, %esi .long ProtectedModeEntryLinearAddress .byte 0x66,0x2e,0xff,0x2c #jmp %cs:(%esi) # # Protected mode portion initializes stack, configures cache, and calls C entry point # #---------------------------------------------------------------------------- # # Procedure: ProtectedModeEntryPoint # # Input: Executing in 32 Bit Protected (flat) mode # cs: 0-4GB # ds: 0-4GB # es: 0-4GB # fs: 0-4GB # gs: 0-4GB # ss: 0-4GB # # Output: This function never returns # # Destroys: # ecx # edi # esi # esp # # Description: # Perform any essential early platform initilaisation # Setup a stack # #---------------------------------------------------------------------------- ProtectedModeEntryPoint: # # Dummy function. Consume 2 API to make sure they can be linked. # movl ASM_PFX(TempRamInitApi), %eax movl ASM_PFX(FspInitApi), %eax # # Should never return # jmp . #'$' # # ROM-based Global-Descriptor Table for the PEI Phase # .align 16 # # GDT[0]: 000h: Null entry, never used. # .equ NULL_SEL, . - GDT_BASE # Selector [0] GDT_BASE: BootGdtTable: .long 0 .long 0 # # Linear code segment descriptor # .equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [08h] .word 0xFFFF # limit 0FFFFh .word 0 # base 0 .byte 0 .byte 0x9B # present, ring 0, data, expand-up, not-writable .byte 0xCF # page-granular, 32-bit .byte 0 # # System data segment descriptor # .equ SYS_DATA_SEL, . - GDT_BASE # Selector [010h] .word 0xFFFF # limit 0FFFFh .word 0 # base 0 .byte 0 .byte 0x93 # present, ring 0, data, expand-up, not-writable .byte 0xCF # page-granular, 32-bit .byte 0 .equ GDT_SIZE, . - BootGdtTable # Size, in bytes # # GDT Descriptor # GdtDesc: # GDT descriptor .word GDT_SIZE - 1 .long BootGdtTable ProtectedModeEntryLinearAddress: ProtectedModeEntryLinearOffset: .long ProtectedModeEntryPoint .word LINEAR_CODE_SEL