kern: revamp KMemoryRegionType to better encode derivation hierarchies

This commit is contained in:
Michael Scire 2020-08-23 13:19:45 -07:00 committed by SciresM
parent d50c7c5c79
commit 1983f86875
17 changed files with 746 additions and 426 deletions

View file

@ -39,8 +39,8 @@ namespace ams::kern::arch::arm {
void KInterruptController::Initialize(s32 core_id) {
/* Setup pointers to ARM mmio. */
this->gicd = GetPointer<volatile GicDistributor>(KMemoryLayout::GetInterruptDistributorAddress());
this->gicc = GetPointer<volatile GicCpuInterface>(KMemoryLayout::GetInterruptCpuInterfaceAddress());
this->gicd = GetPointer<volatile GicDistributor >(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_InterruptDistributor));
this->gicc = GetPointer<volatile GicCpuInterface>(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_InterruptCpuInterface));
/* Clear CTLRs. */
this->gicc->ctlr = 0;

View file

@ -405,7 +405,7 @@ namespace ams::kern::board::nintendo::nx {
void KDevicePageTable::Initialize() {
/* Set the memory controller register address. */
g_memory_controller_address = KMemoryLayout::GetMemoryControllerRegion().GetAddress();
g_memory_controller_address = KMemoryLayout::GetDevicePhysicalAddress(KMemoryRegionType_MemoryController);
/* Allocate a page to use as a reserved/no device table. */
const KVirtualAddress table_virt_addr = Kernel::GetPageTableManager().Allocate();

View file

@ -181,7 +181,7 @@ namespace ams::kern::board::nintendo::nx {
/* Find the region for the address. */
const KMemoryRegion *region = KMemoryLayout::Find(KPhysicalAddress(address));
if (AMS_LIKELY(region != nullptr)) {
if (AMS_LIKELY(region->IsDerivedFrom(KMemoryRegionAttr_NoUserMap | KMemoryRegionType_MemoryController))) {
if (AMS_LIKELY(region->IsDerivedFrom(KMemoryRegionType_MemoryController))) {
/* Get the offset within the region. */
const size_t offset = address - region->GetAddress();
MESOSPHERE_ABORT_UNLESS(offset < region->GetSize());
@ -206,9 +206,9 @@ namespace ams::kern::board::nintendo::nx {
}
/* Memory controller is allowed if the register is whitelisted. */
if (region->IsDerivedFrom(KMemoryRegionAttr_NoUserMap | KMemoryRegionType_MemoryController ) ||
region->IsDerivedFrom(KMemoryRegionAttr_NoUserMap | KMemoryRegionType_MemoryController0) ||
region->IsDerivedFrom(KMemoryRegionAttr_NoUserMap | KMemoryRegionType_MemoryController1))
if (region->IsDerivedFrom(KMemoryRegionType_MemoryController ) ||
region->IsDerivedFrom(KMemoryRegionType_MemoryController0) ||
region->IsDerivedFrom(KMemoryRegionType_MemoryController1))
{
/* Get the offset within the region. */
const size_t offset = address - region->GetAddress();

View file

@ -50,7 +50,7 @@ namespace ams::kern {
bool KDebugLogImpl::Initialize() {
/* Set the uart register base address. */
g_uart_address = KMemoryLayout::GetUartAddress();
g_uart_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_Uart);
/* Parameters for uart. */
constexpr u32 BaudRate = 115200;

View file

@ -27,9 +27,9 @@ namespace ams::kern {
ALWAYS_INLINE bool SetupUartPhysicalMemoryRegion() {
#if defined(MESOSPHERE_DEBUG_LOG_USE_UART_A)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_B)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_C)
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap);
#elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_D)
@ -41,10 +41,10 @@ namespace ams::kern {
ALWAYS_INLINE bool SetupPowerManagementControllerMemoryRegion() {
/* For backwards compatibility, the PMC must remain mappable on < 2.0.0. */
const auto pmc_type = GetTargetFirmware() >= TargetFirmware_2_0_0 ? (KMemoryRegionType_PowerManagementController | KMemoryRegionAttr_NoUserMap) : KMemoryRegionType_PowerManagementController;
const auto restrict_attr = GetTargetFirmware() >= TargetFirmware_2_0_0 ? KMemoryRegionAttr_NoUserMap : static_cast<KMemoryRegionAttr>(0);
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E000, 0x400, KMemoryRegionType_None | KMemoryRegionAttr_NoUserMap) &&
KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E400, 0xC00, pmc_type);
return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E000, 0x400, KMemoryRegionType_None | restrict_attr) &&
KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x7000E400, 0xC00, KMemoryRegionType_PowerManagementController | restrict_attr);
}
void InsertPoolPartitionRegionIntoBothTrees(size_t start, size_t size, KMemoryRegionType phys_type, KMemoryRegionType virt_type, u32 &cur_attr) {
@ -95,7 +95,7 @@ namespace ams::kern {
const size_t unsafe_system_pool_min_size = KSystemControl::Init::GetMinimumNonSecureSystemPoolSize();
/* Find the start of the kernel DRAM region. */
const KMemoryRegion *kernel_dram_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DramKernel);
const KMemoryRegion *kernel_dram_region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DramKernelBase);
MESOSPHERE_INIT_ABORT_UNLESS(kernel_dram_region != nullptr);
const uintptr_t kernel_dram_start = kernel_dram_region->GetAddress();
@ -141,7 +141,7 @@ namespace ams::kern {
const uintptr_t metadata_pool_start = unsafe_system_pool_start - total_overhead_size;
const size_t metadata_pool_size = total_overhead_size;
u32 metadata_pool_attr = 0;
InsertPoolPartitionRegionIntoBothTrees(metadata_pool_start, metadata_pool_size, KMemoryRegionType_DramMetadataPool, KMemoryRegionType_VirtualDramMetadataPool, metadata_pool_attr);
InsertPoolPartitionRegionIntoBothTrees(metadata_pool_start, metadata_pool_size, KMemoryRegionType_DramPoolManagement, KMemoryRegionType_VirtualDramPoolManagement, metadata_pool_attr);
/* Insert the system pool. */
const uintptr_t system_pool_size = metadata_pool_start - pool_partitions_start;

View file

@ -234,7 +234,7 @@ namespace ams::kern {
/* 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_CoreLocal));
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] = {};

View file

@ -42,7 +42,7 @@ namespace ams::kern {
const KMemoryRegion *region = nullptr;
for (const auto &it : KMemoryLayout::GetVirtualMemoryRegionTree()) {
/* We only care about regions that we need to create managers for. */
if (!it.IsDerivedFrom(KMemoryRegionType_VirtualDramManagedPool)) {
if (!it.IsDerivedFrom(KMemoryRegionType_VirtualDramUserPool)) {
continue;
}
@ -64,7 +64,7 @@ namespace ams::kern {
MESOSPHERE_ASSERT(region->GetAddress() != Null<decltype(region->GetAddress())>);
MESOSPHERE_ASSERT(region->GetSize() > 0);
MESOSPHERE_ASSERT(region->GetEndAddress() >= region->GetAddress());
MESOSPHERE_ASSERT(region->IsDerivedFrom(KMemoryRegionType_VirtualDramManagedPool));
MESOSPHERE_ASSERT(region->IsDerivedFrom(KMemoryRegionType_VirtualDramUserPool));
MESOSPHERE_ASSERT(region->GetAttributes() == this->num_managers);
/* Initialize a new manager for the region. */

View file

@ -153,7 +153,7 @@ namespace ams::kern {
PrintMemoryRegion(" InitPageTable", KMemoryLayout::GetKernelInitPageTableRegionPhysicalExtents());
PrintMemoryRegion(" MemoryPoolRegion", KMemoryLayout::GetKernelPoolPartitionRegionPhysicalExtents());
PrintMemoryRegion(" System", KMemoryLayout::GetKernelSystemPoolRegionPhysicalExtents());
PrintMemoryRegion(" Internal", KMemoryLayout::GetKernelMetadataPoolRegionPhysicalExtents());
PrintMemoryRegion(" Management", KMemoryLayout::GetKernelPoolManagementRegionPhysicalExtents());
PrintMemoryRegion(" SystemUnsafe", KMemoryLayout::GetKernelSystemNonSecurePoolRegionPhysicalExtents());
PrintMemoryRegion(" Applet", KMemoryLayout::GetKernelAppletPoolRegionPhysicalExtents());
PrintMemoryRegion(" Application", KMemoryLayout::GetKernelApplicationPoolRegionPhysicalExtents());

View file

@ -51,8 +51,8 @@ namespace ams::kern {
/* Initialize the memory manager and the KPageBuffer slabheap. */
{
const auto &metadata_region = KMemoryLayout::GetMetadataPoolRegion();
Kernel::GetMemoryManager().Initialize(metadata_region.GetAddress(), metadata_region.GetSize());
const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize());
init::InitializeKPageBufferSlabHeap();
}