| #------------------------------------------------------------------------------ | |
| # | |
| # Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> | |
| # This program and the accompanying materials | |
| # are licensed and made available under the terms and conditions of the BSD License | |
| # which accompanies this distribution. The full text of the license may be found at | |
| # http://opensource.org/licenses/bsd-license.php. | |
| # | |
| # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| # | |
| # 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 |