arm64: Disable Cache & MMU before reconfiguring MMU while being in EL1
* Final clean up of Exception Level Handling * Enable legacy console Change-Id: If19134a237fd0373c427b82a69f1ce61abe82f4d Reviewed-on: https://review.haiku-os.org/c/haiku/+/5176 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]> Reviewed-by: David Karoly <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]>
This commit is contained in:
committed by
Fredrik Holmqvist
parent
0ff09cb7ef
commit
955acf7e19
@@ -109,10 +109,7 @@ arch_mmu_dump_present_tables()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void arch_mmu_setup_EL1() {
|
void arch_mmu_setup_EL1(uint64 tcr) {
|
||||||
|
|
||||||
// Inherit TCR from EL2
|
|
||||||
uint64 tcr = READ_SPECIALREG(TCR_EL2);
|
|
||||||
|
|
||||||
// Enable TTBR1
|
// Enable TTBR1
|
||||||
tcr &= ~TCR_EPD1_DISABLE;
|
tcr &= ~TCR_EPD1_DISABLE;
|
||||||
@@ -380,7 +377,7 @@ arch_mmu_post_efi_setup(size_t memory_map_size,
|
|||||||
// Switch EFI to virtual mode, using the kernel pmap.
|
// Switch EFI to virtual mode, using the kernel pmap.
|
||||||
kRuntimeServices->SetVirtualAddressMap(memory_map_size, descriptor_size,
|
kRuntimeServices->SetVirtualAddressMap(memory_map_size, descriptor_size,
|
||||||
descriptor_version, memory_map);
|
descriptor_version, memory_map);
|
||||||
#ifdef DUMP_RANGES_AFTER_EXIT_SERIVCES
|
|
||||||
TRACE(("phys memory ranges:\n"));
|
TRACE(("phys memory ranges:\n"));
|
||||||
for (uint32_t i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) {
|
for (uint32_t i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) {
|
||||||
uint32_t start = (uint32_t)gKernelArgs.physical_memory_range[i].start;
|
uint32_t start = (uint32_t)gKernelArgs.physical_memory_range[i].start;
|
||||||
@@ -404,7 +401,7 @@ arch_mmu_post_efi_setup(size_t memory_map_size,
|
|||||||
TRACE((" 0x%08x-0x%08x, length 0x%08x\n",
|
TRACE((" 0x%08x-0x%08x, length 0x%08x\n",
|
||||||
start, start + size, size));
|
start, start + size, size));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <boot/stdio.h>
|
#include <boot/stdio.h>
|
||||||
|
|
||||||
#include "efi_platform.h"
|
#include "efi_platform.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
#include "aarch64.h"
|
#include "aarch64.h"
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ extern void arch_mmu_post_efi_setup(size_t memory_map_size,
|
|||||||
efi_memory_descriptor *memory_map, size_t descriptor_size,
|
efi_memory_descriptor *memory_map, size_t descriptor_size,
|
||||||
uint32_t descriptor_version);
|
uint32_t descriptor_version);
|
||||||
|
|
||||||
extern void arch_mmu_setup_EL1();
|
extern void arch_mmu_setup_EL1(uint64 tcr);
|
||||||
|
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
@@ -130,11 +131,6 @@ arch_start_kernel(addr_t kernelEntry)
|
|||||||
// offset for properly align symbols
|
// offset for properly align symbols
|
||||||
dprintf("Efi loader symbols offset: 0x%0lx:\n", loaderCode);
|
dprintf("Efi loader symbols offset: 0x%0lx:\n", loaderCode);
|
||||||
|
|
||||||
// Generate page tables for use after ExitBootServices.
|
|
||||||
arch_mmu_generate_post_efi_page_tables(
|
|
||||||
memory_map_size, memory_map, descriptor_size, descriptor_version);
|
|
||||||
|
|
||||||
bool el2toel1 = false;
|
|
||||||
/*
|
/*
|
||||||
* "The AArch64 exception model is made up of a number of exception levels
|
* "The AArch64 exception model is made up of a number of exception levels
|
||||||
* (EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
|
* (EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
|
||||||
@@ -150,7 +146,8 @@ arch_start_kernel(addr_t kernelEntry)
|
|||||||
* On AArch64 UEFI shall execute as 64-bit code at either EL1 or EL2,
|
* On AArch64 UEFI shall execute as 64-bit code at either EL1 or EL2,
|
||||||
* depending on whether or not virtualization is available at OS load time."
|
* depending on whether or not virtualization is available at OS load time."
|
||||||
*/
|
*/
|
||||||
dprintf("Current Exception Level EL%1lx\n", arch_exception_level());
|
uint64 el = arch_exception_level();
|
||||||
|
dprintf("Current Exception Level EL%1lx\n", el);
|
||||||
dprintf("TTBR0: %" B_PRIx64 " TTBRx: %" B_PRIx64 " SCTLR: %" B_PRIx64 " TCR: %" B_PRIx64 "\n",
|
dprintf("TTBR0: %" B_PRIx64 " TTBRx: %" B_PRIx64 " SCTLR: %" B_PRIx64 " TCR: %" B_PRIx64 "\n",
|
||||||
arch_mmu_base_register(),
|
arch_mmu_base_register(),
|
||||||
arch_mmu_base_register(true),
|
arch_mmu_base_register(true),
|
||||||
@@ -167,25 +164,16 @@ arch_start_kernel(addr_t kernelEntry)
|
|||||||
arch_mmu_read_access(kernelEntry));
|
arch_mmu_read_access(kernelEntry));
|
||||||
|
|
||||||
arch_mmu_dump_present_tables();
|
arch_mmu_dump_present_tables();
|
||||||
|
|
||||||
|
if (el == 1) {
|
||||||
|
// Disable CACHE & MMU before dealing with TTBRx
|
||||||
|
arch_cache_disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (arch_exception_level()) {
|
// Generate page tables for use after ExitBootServices.
|
||||||
case 1:
|
arch_mmu_generate_post_efi_page_tables(
|
||||||
/* arch_cache_disable(); */
|
memory_map_size, memory_map, descriptor_size, descriptor_version);
|
||||||
/* arch_mmu_generate_post_efi_page_tables */
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
|
|
||||||
el2toel1 = true; // we want to print before exit services
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic("Unexpected Exception Level\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Attempt to fetch the memory map and exit boot services.
|
// Attempt to fetch the memory map and exit boot services.
|
||||||
// This needs to be done in a loop, as ExitBootServices can change the
|
// This needs to be done in a loop, as ExitBootServices can change the
|
||||||
@@ -205,6 +193,8 @@ arch_start_kernel(addr_t kernelEntry)
|
|||||||
stderr = NULL;
|
stderr = NULL;
|
||||||
// Can we adjust gKernelArgs.platform_args.serial_base_ports[0]
|
// Can we adjust gKernelArgs.platform_args.serial_base_ports[0]
|
||||||
// to something fixed in qemu for debugging?
|
// to something fixed in qemu for debugging?
|
||||||
|
serial_switch_to_legacy();
|
||||||
|
dprintf("Switched to legacy serial output\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,21 +206,24 @@ arch_start_kernel(addr_t kernelEntry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update EFI, generate final kernel physical memory map, etc.
|
// Update EFI, generate final kernel physical memory map, etc.
|
||||||
//arch_mmu_post_efi_setup(memory_map_size, memory_map,
|
// arch_mmu_post_efi_setup(memory_map_size, memory_map, descriptor_size, descriptor_version);
|
||||||
// descriptor_size, descriptor_version);
|
|
||||||
|
|
||||||
if (el2toel1) {
|
switch (el) {
|
||||||
arch_mmu_setup_EL1();
|
case 1:
|
||||||
arch_cache_disable();
|
arch_mmu_setup_EL1(READ_SPECIALREG(TCR_EL1));
|
||||||
|
break;
|
||||||
_arch_transition_EL2_EL1();
|
case 2:
|
||||||
|
arch_mmu_setup_EL1(READ_SPECIALREG(TCR_EL2));
|
||||||
arch_cache_enable();
|
arch_cache_disable();
|
||||||
} else {
|
_arch_transition_EL2_EL1();
|
||||||
|
break;
|
||||||
arch_cache_enable();
|
default:
|
||||||
|
panic("Unexpected Exception Level\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arch_cache_enable();
|
||||||
|
|
||||||
//smp_boot_other_cpus(final_pml4, kernelEntry, (addr_t)&gKernelArgs);
|
//smp_boot_other_cpus(final_pml4, kernelEntry, (addr_t)&gKernelArgs);
|
||||||
|
|
||||||
if (arch_mmu_read_access(kernelEntry) && arch_mmu_read_access(gKernelArgs.cpu_kstack[0].start)) {
|
if (arch_mmu_read_access(kernelEntry) && arch_mmu_read_access(gKernelArgs.cpu_kstack[0].start)) {
|
||||||
@@ -238,6 +231,7 @@ arch_start_kernel(addr_t kernelEntry)
|
|||||||
arch_enter_kernel(&gKernelArgs, kernelEntry,
|
arch_enter_kernel(&gKernelArgs, kernelEntry,
|
||||||
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size - 8);
|
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size - 8);
|
||||||
} else {
|
} else {
|
||||||
_arch_exception_panic("Kernel or Stack memory not accessible\n", __LINE__);
|
// _arch_exception_panic("Kernel or Stack memory not accessible\n", __LINE__);
|
||||||
|
panic("Kernel or Stack memory not accessible\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user