mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-31 01:24:12 +02:00
There are a number of mostly older guests such as RHEL-7 which do not support 5-level paging. This patch adds support for switching from 5-level paging mode back to 4-level paging mode. This is done in PEI, after inspecting the address space needed (installed memory and reservations configured via fw_cfg). By default small guests (which need less than 1 TB) will use 4-level paging mode. There is a fw_cfg override though, so it is possible to force the one or the other this way: qemu-system-x86_64 -fw_cfg name=opt/org.tianocode/PagingLevel,string=5 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
77 lines
1.7 KiB
NASM
77 lines
1.7 KiB
NASM
;------------------------------------------------------------------------------
|
|
; @file
|
|
;
|
|
; Switch from 5-level paging mode to 4-level paging mode.
|
|
;
|
|
; This assumes everything (code, stack, page tables) is in 32-bit
|
|
; address space. Which is true for PEI phase even in X64 builds
|
|
; because low memory is used for early firmware setup.
|
|
;
|
|
; This also assumes the standard ResetVector GDT is active.
|
|
;
|
|
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
;------------------------------------------------------------------------------
|
|
|
|
SECTION .text
|
|
BITS 64
|
|
|
|
global ASM_PFX(Switch4Level)
|
|
ASM_PFX(Switch4Level):
|
|
|
|
; save regs
|
|
push rax
|
|
push rbx
|
|
push rcx
|
|
push rdx
|
|
|
|
; cs:ip for long mode
|
|
lea rax, [rel Switch4Level64]
|
|
mov rbx, 0x3800000000 ; LINEAR_CODE64_SEL << 32
|
|
or rax, rbx
|
|
push rax
|
|
|
|
; cs:ip for 32-bit mode
|
|
lea rax, [rel Switch4Level32]
|
|
mov rbx, 0x1000000000 ; LINEAR_CODE_SEL << 32
|
|
or rax, rbx
|
|
push rax
|
|
|
|
; enter 32-bit mode
|
|
retf
|
|
|
|
Switch4Level64:
|
|
; restore regs
|
|
pop rdx
|
|
pop rcx
|
|
pop rbx
|
|
pop rax
|
|
|
|
ret
|
|
|
|
BITS 32
|
|
|
|
Switch4Level32:
|
|
; disable paging
|
|
mov eax, cr0
|
|
btc eax, 31 ; clear PG
|
|
mov cr0, eax
|
|
|
|
; disable 5-level paging
|
|
mov eax, cr4
|
|
btc eax, 12 ; clear la57
|
|
mov cr4, eax
|
|
|
|
; fixup cr3 (dereference 5th level)
|
|
mov eax, cr3
|
|
mov eax, [ eax ]
|
|
and eax, 0xfffff000
|
|
mov cr3, eax
|
|
|
|
; enable paging
|
|
mov eax, cr0
|
|
bts eax, 31 ; set PG
|
|
mov cr0, eax
|
|
|
|
; back to long mode
|
|
retf
|