kern: allocate all TTBR0 pages during init, use procidx as asid
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
#include <mesosphere.hpp>
|
||||
|
||||
extern "C" void __rodata_start();
|
||||
extern "C" void __rodata_end();
|
||||
|
||||
extern "C" void __bin_start__();
|
||||
extern "C" void __bin_end__();
|
||||
|
||||
@@ -220,6 +223,31 @@ namespace ams::kern::init {
|
||||
};
|
||||
static_assert(kern::arch::arm64::init::IsInitialPageAllocator<KInitialPageAllocatorForFinalizeIdentityMapping>);
|
||||
|
||||
void SetupAllTtbr0Entries(KInitialPageTable &init_pt, KInitialPageAllocator &allocator) {
|
||||
/* Validate that the ttbr0 array is in rodata. */
|
||||
const uintptr_t rodata_start = reinterpret_cast<uintptr_t>(__rodata_start);
|
||||
const uintptr_t rodata_end = reinterpret_cast<uintptr_t>(__rodata_end);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(rodata_start < rodata_end);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(rodata_start <= reinterpret_cast<uintptr_t>(std::addressof(KPageTable::GetTtbr0Entry(0))));
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(reinterpret_cast<uintptr_t>(std::addressof(KPageTable::GetTtbr0Entry(KPageTable::NumTtbr0Entries))) < rodata_end);
|
||||
|
||||
/* Allocate pages for all ttbr0 entries. */
|
||||
for (size_t i = 0; i < KPageTable::NumTtbr0Entries; ++i) {
|
||||
/* Allocate a page. */
|
||||
KPhysicalAddress page = allocator.Allocate(PageSize);
|
||||
MESOSPHERE_INIT_ABORT_UNLESS(page != Null<KPhysicalAddress>);
|
||||
|
||||
/* Check that the page is allowed to be a ttbr0 entry. */
|
||||
MESOSPHERE_INIT_ABORT_UNLESS((GetInteger(page) & UINT64_C(0xFFFF000000000001)) == 0);
|
||||
|
||||
/* Get the physical address of the ttbr0 entry. */
|
||||
const auto ttbr0_phys_ptr = init_pt.GetPhysicalAddress(KVirtualAddress(std::addressof(KPageTable::GetTtbr0Entry(i))));
|
||||
|
||||
/* Set the entry to the newly allocated page. */
|
||||
*reinterpret_cast<volatile u64 *>(GetInteger(ttbr0_phys_ptr)) = (static_cast<u64>(i) << 48) | GetInteger(page);
|
||||
}
|
||||
}
|
||||
|
||||
void FinalizeIdentityMapping(KInitialPageTable &init_pt, KInitialPageAllocator &allocator, u64 phys_to_virt_offset) {
|
||||
/* Create an allocator for identity mapping finalization. */
|
||||
KInitialPageAllocatorForFinalizeIdentityMapping finalize_allocator(allocator, phys_to_virt_offset);
|
||||
@@ -591,6 +619,9 @@ namespace ams::kern::init {
|
||||
/* Create page table object for use during remaining initialization. */
|
||||
KInitialPageTable init_pt;
|
||||
|
||||
/* Setup all ttbr0 pages. */
|
||||
SetupAllTtbr0Entries(init_pt, g_initial_page_allocator);
|
||||
|
||||
/* Unmap the identity mapping. */
|
||||
FinalizeIdentityMapping(init_pt, g_initial_page_allocator, g_phase2_linear_region_phys_to_virt_diff);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user