kern: Kill KCoreLocalRegion

This commit is contained in:
Michael Scire 2020-12-01 13:41:37 -08:00 committed by SciresM
parent 24d545701c
commit b0debd72a7
24 changed files with 165 additions and 334 deletions

View file

@ -181,89 +181,4 @@ namespace ams::kern {
return resource_region_size;
}
namespace init {
namespace {
constexpr PageTableEntry KernelRwDataAttribute(PageTableEntry::Permission_KernelRW, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped);
constexpr size_t CoreLocalRegionAlign = PageSize;
constexpr size_t CoreLocalRegionSize = PageSize * (1 + cpu::NumCores);
constexpr size_t CoreLocalRegionSizeWithGuards = CoreLocalRegionSize + 2 * PageSize;
constexpr size_t CoreLocalRegionBoundsAlign = 1_GB;
static_assert(CoreLocalRegionSize == sizeof(KCoreLocalRegion));
KVirtualAddress GetCoreLocalRegionVirtualAddress() {
while (true) {
const uintptr_t candidate_start = GetInteger(KMemoryLayout::GetVirtualMemoryRegionTree().GetRandomAlignedRegion(CoreLocalRegionSizeWithGuards, CoreLocalRegionAlign, KMemoryRegionType_None));
const uintptr_t candidate_end = candidate_start + CoreLocalRegionSizeWithGuards;
const uintptr_t candidate_last = candidate_end - 1;
const auto &containing_region = *KMemoryLayout::GetVirtualMemoryRegionTree().Find(candidate_start);
if (candidate_last > containing_region.GetLastAddress()) {
continue;
}
if (containing_region.GetType() != KMemoryRegionType_None) {
continue;
}
if (util::AlignDown(candidate_start, CoreLocalRegionBoundsAlign) != util::AlignDown(candidate_last, CoreLocalRegionBoundsAlign)) {
continue;
}
if (containing_region.GetAddress() > util::AlignDown(candidate_start, CoreLocalRegionBoundsAlign)) {
continue;
}
if (util::AlignUp(candidate_last, CoreLocalRegionBoundsAlign) - 1 > containing_region.GetLastAddress()) {
continue;
}
return candidate_start + PageSize;
}
}
}
void SetupCoreLocalRegionMemoryRegions(KInitialPageTable &page_table, KInitialPageAllocator &page_allocator) {
/* NOTE: Nintendo passes page table here to use num_l1_entries; we don't use this at present. */
MESOSPHERE_UNUSED(page_table);
/* Get the virtual address of the core local reigon. */
const KVirtualAddress core_local_virt_start = GetCoreLocalRegionVirtualAddress();
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetVirtualMemoryRegionTree().Insert(GetInteger(core_local_virt_start), CoreLocalRegionSize, KMemoryRegionType_CoreLocalRegion));
/* Allocate a page for each core. */
KPhysicalAddress core_local_region_start_phys[cpu::NumCores] = {};
for (size_t i = 0; i < cpu::NumCores; i++) {
core_local_region_start_phys[i] = page_allocator.Allocate();
}
/* Allocate an l1 page table for each core. */
KPhysicalAddress core_l1_ttbr1_phys[cpu::NumCores] = {};
core_l1_ttbr1_phys[0] = util::AlignDown(cpu::GetTtbr1El1(), PageSize);
for (size_t i = 1; i < cpu::NumCores; i++) {
core_l1_ttbr1_phys[i] = page_allocator.Allocate();
std::memcpy(reinterpret_cast<void *>(GetInteger(core_l1_ttbr1_phys[i])), reinterpret_cast<void *>(GetInteger(core_l1_ttbr1_phys[0])), PageSize);
}
/* Use the l1 page table for each core to map the core local region for each core. */
for (size_t i = 0; i < cpu::NumCores; i++) {
KInitialPageTable temp_pt(core_l1_ttbr1_phys[i], KInitialPageTable::NoClear{});
temp_pt.Map(core_local_virt_start, PageSize, core_local_region_start_phys[i], KernelRwDataAttribute, page_allocator);
for (size_t j = 0; j < cpu::NumCores; j++) {
temp_pt.Map(core_local_virt_start + (j + 1) * PageSize, PageSize, core_local_region_start_phys[j], KernelRwDataAttribute, page_allocator);
}
/* Setup the InitArguments. */
SetInitArguments(static_cast<s32>(i), core_local_region_start_phys[i], GetInteger(core_l1_ttbr1_phys[i]));
}
}
}
}