summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/kernel.cpp84
1 files changed, 43 insertions, 41 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index ac69367b8..71bd466cf 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -71,7 +71,7 @@ struct KernelCore::Impl {
71 // Derive the initial memory layout from the emulated board 71 // Derive the initial memory layout from the emulated board
72 Init::InitializeSlabResourceCounts(kernel); 72 Init::InitializeSlabResourceCounts(kernel);
73 DeriveInitialMemoryLayout(); 73 DeriveInitialMemoryLayout();
74 Init::InitializeSlabHeaps(system, memory_layout); 74 Init::InitializeSlabHeaps(system, *memory_layout);
75 75
76 // Initialize kernel memory and resources. 76 // Initialize kernel memory and resources.
77 InitializeSystemResourceLimit(kernel, system.CoreTiming()); 77 InitializeSystemResourceLimit(kernel, system.CoreTiming());
@@ -222,7 +222,7 @@ struct KernelCore::Impl {
222 system_resource_limit = KResourceLimit::Create(system.Kernel()); 222 system_resource_limit = KResourceLimit::Create(system.Kernel());
223 system_resource_limit->Initialize(&core_timing); 223 system_resource_limit->Initialize(&core_timing);
224 224
225 const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); 225 const auto [total_size, kernel_size] = memory_layout->GetTotalAndKernelMemorySizes();
226 226
227 // If setting the default system values fails, then something seriously wrong has occurred. 227 // If setting the default system values fails, then something seriously wrong has occurred.
228 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size) 228 ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size)
@@ -352,15 +352,17 @@ struct KernelCore::Impl {
352 } 352 }
353 353
354 void DeriveInitialMemoryLayout() { 354 void DeriveInitialMemoryLayout() {
355 memory_layout = std::make_unique<KMemoryLayout>();
356
355 // Insert the root region for the virtual memory tree, from which all other regions will 357 // Insert the root region for the virtual memory tree, from which all other regions will
356 // derive. 358 // derive.
357 memory_layout.GetVirtualMemoryRegionTree().InsertDirectly( 359 memory_layout->GetVirtualMemoryRegionTree().InsertDirectly(
358 KernelVirtualAddressSpaceBase, 360 KernelVirtualAddressSpaceBase,
359 KernelVirtualAddressSpaceBase + KernelVirtualAddressSpaceSize - 1); 361 KernelVirtualAddressSpaceBase + KernelVirtualAddressSpaceSize - 1);
360 362
361 // Insert the root region for the physical memory tree, from which all other regions will 363 // Insert the root region for the physical memory tree, from which all other regions will
362 // derive. 364 // derive.
363 memory_layout.GetPhysicalMemoryRegionTree().InsertDirectly( 365 memory_layout->GetPhysicalMemoryRegionTree().InsertDirectly(
364 KernelPhysicalAddressSpaceBase, 366 KernelPhysicalAddressSpaceBase,
365 KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1); 367 KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1);
366 368
@@ -377,7 +379,7 @@ struct KernelCore::Impl {
377 if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) { 379 if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) {
378 kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start; 380 kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start;
379 } 381 }
380 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 382 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
381 kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel)); 383 kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel));
382 384
383 // Setup the code region. 385 // Setup the code region.
@@ -386,11 +388,11 @@ struct KernelCore::Impl {
386 Common::AlignDown(code_start_virt_addr, CodeRegionAlign); 388 Common::AlignDown(code_start_virt_addr, CodeRegionAlign);
387 constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign); 389 constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign);
388 constexpr size_t code_region_size = code_region_end - code_region_start; 390 constexpr size_t code_region_size = code_region_end - code_region_start;
389 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 391 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
390 code_region_start, code_region_size, KMemoryRegionType_KernelCode)); 392 code_region_start, code_region_size, KMemoryRegionType_KernelCode));
391 393
392 // Setup board-specific device physical regions. 394 // Setup board-specific device physical regions.
393 Init::SetupDevicePhysicalMemoryRegions(memory_layout); 395 Init::SetupDevicePhysicalMemoryRegions(*memory_layout);
394 396
395 // Determine the amount of space needed for the misc region. 397 // Determine the amount of space needed for the misc region.
396 size_t misc_region_needed_size; 398 size_t misc_region_needed_size;
@@ -399,7 +401,7 @@ struct KernelCore::Impl {
399 misc_region_needed_size = Core::Hardware::NUM_CPU_CORES * (3 * (PageSize + PageSize)); 401 misc_region_needed_size = Core::Hardware::NUM_CPU_CORES * (3 * (PageSize + PageSize));
400 402
401 // Account for each auto-map device. 403 // Account for each auto-map device.
402 for (const auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { 404 for (const auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
403 if (region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) { 405 if (region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) {
404 // Check that the region is valid. 406 // Check that the region is valid.
405 ASSERT(region.GetEndAddress() != 0); 407 ASSERT(region.GetEndAddress() != 0);
@@ -424,22 +426,22 @@ struct KernelCore::Impl {
424 426
425 // Setup the misc region. 427 // Setup the misc region.
426 const VAddr misc_region_start = 428 const VAddr misc_region_start =
427 memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( 429 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
428 misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel); 430 misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel);
429 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 431 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
430 misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc)); 432 misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc));
431 433
432 // Setup the stack region. 434 // Setup the stack region.
433 constexpr size_t StackRegionSize = 14_MiB; 435 constexpr size_t StackRegionSize = 14_MiB;
434 constexpr size_t StackRegionAlign = KernelAslrAlignment; 436 constexpr size_t StackRegionAlign = KernelAslrAlignment;
435 const VAddr stack_region_start = 437 const VAddr stack_region_start =
436 memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( 438 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
437 StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel); 439 StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel);
438 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 440 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
439 stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack)); 441 stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack));
440 442
441 // Determine the size of the resource region. 443 // Determine the size of the resource region.
442 const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); 444 const size_t resource_region_size = memory_layout->GetResourceRegionSizeForInit();
443 445
444 // Determine the size of the slab region. 446 // Determine the size of the slab region.
445 const size_t slab_region_size = 447 const size_t slab_region_size =
@@ -456,23 +458,23 @@ struct KernelCore::Impl {
456 Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) - 458 Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) -
457 Common::AlignDown(code_end_phys_addr, SlabRegionAlign); 459 Common::AlignDown(code_end_phys_addr, SlabRegionAlign);
458 const VAddr slab_region_start = 460 const VAddr slab_region_start =
459 memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( 461 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
460 slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) + 462 slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) +
461 (code_end_phys_addr % SlabRegionAlign); 463 (code_end_phys_addr % SlabRegionAlign);
462 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 464 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
463 slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab)); 465 slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab));
464 466
465 // Setup the temp region. 467 // Setup the temp region.
466 constexpr size_t TempRegionSize = 128_MiB; 468 constexpr size_t TempRegionSize = 128_MiB;
467 constexpr size_t TempRegionAlign = KernelAslrAlignment; 469 constexpr size_t TempRegionAlign = KernelAslrAlignment;
468 const VAddr temp_region_start = 470 const VAddr temp_region_start =
469 memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion( 471 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
470 TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel); 472 TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel);
471 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize, 473 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize,
472 KMemoryRegionType_KernelTemp)); 474 KMemoryRegionType_KernelTemp));
473 475
474 // Automatically map in devices that have auto-map attributes. 476 // Automatically map in devices that have auto-map attributes.
475 for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { 477 for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
476 // We only care about kernel regions. 478 // We only care about kernel regions.
477 if (!region.IsDerivedFrom(KMemoryRegionType_Kernel)) { 479 if (!region.IsDerivedFrom(KMemoryRegionType_Kernel)) {
478 continue; 480 continue;
@@ -499,21 +501,21 @@ struct KernelCore::Impl {
499 const size_t map_size = 501 const size_t map_size =
500 Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr; 502 Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr;
501 const VAddr map_virt_addr = 503 const VAddr map_virt_addr =
502 memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard( 504 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
503 map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize); 505 map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize);
504 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 506 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
505 map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice)); 507 map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice));
506 region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr); 508 region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr);
507 } 509 }
508 510
509 Init::SetupDramPhysicalMemoryRegions(memory_layout); 511 Init::SetupDramPhysicalMemoryRegions(*memory_layout);
510 512
511 // Insert a physical region for the kernel code region. 513 // Insert a physical region for the kernel code region.
512 ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( 514 ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
513 code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode)); 515 code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode));
514 516
515 // Insert a physical region for the kernel slab region. 517 // Insert a physical region for the kernel slab region.
516 ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( 518 ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
517 slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab)); 519 slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab));
518 520
519 // Determine size available for kernel page table heaps, requiring > 8 MB. 521 // Determine size available for kernel page table heaps, requiring > 8 MB.
@@ -522,12 +524,12 @@ struct KernelCore::Impl {
522 ASSERT(page_table_heap_size / 4_MiB > 2); 524 ASSERT(page_table_heap_size / 4_MiB > 2);
523 525
524 // Insert a physical region for the kernel page table heap region 526 // Insert a physical region for the kernel page table heap region
525 ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( 527 ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
526 slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); 528 slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap));
527 529
528 // All DRAM regions that we haven't tagged by this point will be mapped under the linear 530 // All DRAM regions that we haven't tagged by this point will be mapped under the linear
529 // mapping. Tag them. 531 // mapping. Tag them.
530 for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { 532 for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
531 if (region.GetType() == KMemoryRegionType_Dram) { 533 if (region.GetType() == KMemoryRegionType_Dram) {
532 // Check that the region is valid. 534 // Check that the region is valid.
533 ASSERT(region.GetEndAddress() != 0); 535 ASSERT(region.GetEndAddress() != 0);
@@ -539,7 +541,7 @@ struct KernelCore::Impl {
539 541
540 // Get the linear region extents. 542 // Get the linear region extents.
541 const auto linear_extents = 543 const auto linear_extents =
542 memory_layout.GetPhysicalMemoryRegionTree().GetDerivedRegionExtents( 544 memory_layout->GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
543 KMemoryRegionAttr_LinearMapped); 545 KMemoryRegionAttr_LinearMapped);
544 ASSERT(linear_extents.GetEndAddress() != 0); 546 ASSERT(linear_extents.GetEndAddress() != 0);
545 547
@@ -551,7 +553,7 @@ struct KernelCore::Impl {
551 Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) - 553 Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) -
552 aligned_linear_phys_start; 554 aligned_linear_phys_start;
553 const VAddr linear_region_start = 555 const VAddr linear_region_start =
554 memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard( 556 memory_layout->GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
555 linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign); 557 linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign);
556 558
557 const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start; 559 const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start;
@@ -560,7 +562,7 @@ struct KernelCore::Impl {
560 { 562 {
561 PAddr cur_phys_addr = 0; 563 PAddr cur_phys_addr = 0;
562 u64 cur_size = 0; 564 u64 cur_size = 0;
563 for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { 565 for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
564 if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) { 566 if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
565 continue; 567 continue;
566 } 568 }
@@ -579,47 +581,47 @@ struct KernelCore::Impl {
579 581
580 const VAddr region_virt_addr = 582 const VAddr region_virt_addr =
581 region.GetAddress() + linear_region_phys_to_virt_diff; 583 region.GetAddress() + linear_region_phys_to_virt_diff;
582 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 584 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
583 region_virt_addr, region.GetSize(), 585 region_virt_addr, region.GetSize(),
584 GetTypeForVirtualLinearMapping(region.GetType()))); 586 GetTypeForVirtualLinearMapping(region.GetType())));
585 region.SetPairAddress(region_virt_addr); 587 region.SetPairAddress(region_virt_addr);
586 588
587 KMemoryRegion* virt_region = 589 KMemoryRegion* virt_region =
588 memory_layout.GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr); 590 memory_layout->GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr);
589 ASSERT(virt_region != nullptr); 591 ASSERT(virt_region != nullptr);
590 virt_region->SetPairAddress(region.GetAddress()); 592 virt_region->SetPairAddress(region.GetAddress());
591 } 593 }
592 } 594 }
593 595
594 // Insert regions for the initial page table region. 596 // Insert regions for the initial page table region.
595 ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert( 597 ASSERT(memory_layout->GetPhysicalMemoryRegionTree().Insert(
596 resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt)); 598 resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt));
597 ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert( 599 ASSERT(memory_layout->GetVirtualMemoryRegionTree().Insert(
598 resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize, 600 resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize,
599 KMemoryRegionType_VirtualDramKernelInitPt)); 601 KMemoryRegionType_VirtualDramKernelInitPt));
600 602
601 // All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to 603 // All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to
602 // some pool partition. Tag them. 604 // some pool partition. Tag them.
603 for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) { 605 for (auto& region : memory_layout->GetPhysicalMemoryRegionTree()) {
604 if (region.GetType() == (KMemoryRegionType_Dram | KMemoryRegionAttr_LinearMapped)) { 606 if (region.GetType() == (KMemoryRegionType_Dram | KMemoryRegionAttr_LinearMapped)) {
605 region.SetType(KMemoryRegionType_DramPoolPartition); 607 region.SetType(KMemoryRegionType_DramPoolPartition);
606 } 608 }
607 } 609 }
608 610
609 // Setup all other memory regions needed to arrange the pool partitions. 611 // Setup all other memory regions needed to arrange the pool partitions.
610 Init::SetupPoolPartitionMemoryRegions(memory_layout); 612 Init::SetupPoolPartitionMemoryRegions(*memory_layout);
611 613
612 // Cache all linear regions in their own trees for faster access, later. 614 // Cache all linear regions in their own trees for faster access, later.
613 memory_layout.InitializeLinearMemoryRegionTrees(aligned_linear_phys_start, 615 memory_layout->InitializeLinearMemoryRegionTrees(aligned_linear_phys_start,
614 linear_region_start); 616 linear_region_start);
615 } 617 }
616 618
617 void InitializeMemoryLayout() { 619 void InitializeMemoryLayout() {
618 const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents(); 620 const auto system_pool = memory_layout->GetKernelSystemPoolRegionPhysicalExtents();
619 621
620 // Initialize the memory manager. 622 // Initialize the memory manager.
621 memory_manager = std::make_unique<KMemoryManager>(system); 623 memory_manager = std::make_unique<KMemoryManager>(system);
622 const auto& management_region = memory_layout.GetPoolManagementRegion(); 624 const auto& management_region = memory_layout->GetPoolManagementRegion();
623 ASSERT(management_region.GetEndAddress() != 0); 625 ASSERT(management_region.GetEndAddress() != 0);
624 memory_manager->Initialize(management_region.GetAddress(), management_region.GetSize()); 626 memory_manager->Initialize(management_region.GetAddress(), management_region.GetSize());
625 627
@@ -763,7 +765,7 @@ struct KernelCore::Impl {
763 Kernel::KSharedMemory* time_shared_mem{}; 765 Kernel::KSharedMemory* time_shared_mem{};
764 766
765 // Memory layout 767 // Memory layout
766 KMemoryLayout memory_layout; 768 std::unique_ptr<KMemoryLayout> memory_layout;
767 769
768 // Threads used for services 770 // Threads used for services
769 std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; 771 std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads;
@@ -1131,7 +1133,7 @@ const KWorkerTaskManager& KernelCore::WorkerTaskManager() const {
1131} 1133}
1132 1134
1133const KMemoryLayout& KernelCore::MemoryLayout() const { 1135const KMemoryLayout& KernelCore::MemoryLayout() const {
1134 return impl->memory_layout; 1136 return *impl->memory_layout;
1135} 1137}
1136 1138
1137bool KernelCore::IsPhantomModeForSingleCore() const { 1139bool KernelCore::IsPhantomModeForSingleCore() const {