mirror of https://github.com/acidanthera/audk.git
172 lines
5.3 KiB
ArmAsm
172 lines
5.3 KiB
ArmAsm
#------------------------------------------------------------------------------
|
|
#
|
|
# 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
|