summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar liamwhite2022-12-25 12:51:16 -0500
committerGravatar GitHub2022-12-25 12:51:16 -0500
commitc6767704fbfe9c0ac1ae05d82222ce7d7926a4cd (patch)
tree0e539660fa1113501b8faeb539f8ef12d6c42b34 /src
parentMerge pull request #9487 from liamwhite/look-at-the-time (diff)
parentkernel: workaround static shared memory initialization (diff)
downloadyuzu-c6767704fbfe9c0ac1ae05d82222ce7d7926a4cd.tar.gz
yuzu-c6767704fbfe9c0ac1ae05d82222ce7d7926a4cd.tar.xz
yuzu-c6767704fbfe9c0ac1ae05d82222ce7d7926a4cd.zip
Merge pull request #9496 from liamwhite/shm3
kernel: workaround static shared memory initialization
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp69
-rw-r--r--src/core/hle/kernel/k_shared_memory.h8
-rw-r--r--src/core/hle/kernel/kernel.cpp43
3 files changed, 62 insertions, 58 deletions
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index 10cd4c43d..0aa68103c 100644
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -6,6 +6,7 @@
6#include "core/hle/kernel/k_page_table.h" 6#include "core/hle/kernel/k_page_table.h"
7#include "core/hle/kernel/k_scoped_resource_reservation.h" 7#include "core/hle/kernel/k_scoped_resource_reservation.h"
8#include "core/hle/kernel/k_shared_memory.h" 8#include "core/hle/kernel/k_shared_memory.h"
9#include "core/hle/kernel/k_system_resource.h"
9#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
10#include "core/hle/kernel/svc_results.h" 11#include "core/hle/kernel/svc_results.h"
11 12
@@ -18,19 +19,19 @@ KSharedMemory::~KSharedMemory() {
18} 19}
19 20
20Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, 21Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
21 KPageGroup&& page_list_, Svc::MemoryPermission owner_permission_, 22 Svc::MemoryPermission owner_permission_,
22 Svc::MemoryPermission user_permission_, PAddr physical_address_, 23 Svc::MemoryPermission user_permission_, std::size_t size_,
23 std::size_t size_, std::string name_) { 24 std::string name_) {
24 // Set members. 25 // Set members.
25 owner_process = owner_process_; 26 owner_process = owner_process_;
26 device_memory = &device_memory_; 27 device_memory = &device_memory_;
27 page_list = std::move(page_list_);
28 owner_permission = owner_permission_; 28 owner_permission = owner_permission_;
29 user_permission = user_permission_; 29 user_permission = user_permission_;
30 physical_address = physical_address_; 30 size = Common::AlignUp(size_, PageSize);
31 size = size_;
32 name = std::move(name_); 31 name = std::move(name_);
33 32
33 const size_t num_pages = Common::DivideUp(size, PageSize);
34
34 // Get the resource limit. 35 // Get the resource limit.
35 KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); 36 KResourceLimit* reslimit = kernel.GetSystemResourceLimit();
36 37
@@ -39,6 +40,17 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
39 size_); 40 size_);
40 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); 41 R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
41 42
43 // Allocate the memory.
44
45 //! HACK: Open continuous mapping from sysmodule pool.
46 auto option = KMemoryManager::EncodeOption(KMemoryManager::Pool::Secure,
47 KMemoryManager::Direction::FromBack);
48 physical_address = kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, option);
49 R_UNLESS(physical_address != 0, ResultOutOfMemory);
50
51 //! Insert the result into our page group.
52 page_group.emplace(physical_address, num_pages);
53
42 // Commit our reservation. 54 // Commit our reservation.
43 memory_reservation.Commit(); 55 memory_reservation.Commit();
44 56
@@ -50,12 +62,23 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
50 is_initialized = true; 62 is_initialized = true;
51 63
52 // Clear all pages in the memory. 64 // Clear all pages in the memory.
53 std::memset(device_memory_.GetPointer<void>(physical_address_), 0, size_); 65 for (const auto& block : page_group->Nodes()) {
66 std::memset(device_memory_.GetPointer<void>(block.GetAddress()), 0, block.GetSize());
67 }
54 68
55 return ResultSuccess; 69 return ResultSuccess;
56} 70}
57 71
58void KSharedMemory::Finalize() { 72void KSharedMemory::Finalize() {
73 // Close and finalize the page group.
74 // page_group->Close();
75 // page_group->Finalize();
76
77 //! HACK: Manually close.
78 for (const auto& block : page_group->Nodes()) {
79 kernel.MemoryManager().Close(block.GetAddress(), block.GetNumPages());
80 }
81
59 // Release the memory reservation. 82 // Release the memory reservation.
60 resource_limit->Release(LimitableResource::PhysicalMemoryMax, size); 83 resource_limit->Release(LimitableResource::PhysicalMemoryMax, size);
61 resource_limit->Close(); 84 resource_limit->Close();
@@ -65,32 +88,28 @@ void KSharedMemory::Finalize() {
65} 88}
66 89
67Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size, 90Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size,
68 Svc::MemoryPermission permissions) { 91 Svc::MemoryPermission map_perm) {
69 const u64 page_count{(map_size + PageSize - 1) / PageSize}; 92 // Validate the size.
70 93 R_UNLESS(size == map_size, ResultInvalidSize);
71 if (page_list.GetNumPages() != page_count) {
72 UNIMPLEMENTED_MSG("Page count does not match");
73 }
74 94
75 const Svc::MemoryPermission expected = 95 // Validate the permission.
96 const Svc::MemoryPermission test_perm =
76 &target_process == owner_process ? owner_permission : user_permission; 97 &target_process == owner_process ? owner_permission : user_permission;
77 98 if (test_perm == Svc::MemoryPermission::DontCare) {
78 if (permissions != expected) { 99 ASSERT(map_perm == Svc::MemoryPermission::Read || map_perm == Svc::MemoryPermission::Write);
79 UNIMPLEMENTED_MSG("Permission does not match"); 100 } else {
101 R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission);
80 } 102 }
81 103
82 return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared, 104 return target_process.PageTable().MapPages(address, *page_group, KMemoryState::Shared,
83 ConvertToKMemoryPermission(permissions)); 105 ConvertToKMemoryPermission(map_perm));
84} 106}
85 107
86Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { 108Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) {
87 const u64 page_count{(unmap_size + PageSize - 1) / PageSize}; 109 // Validate the size.
88 110 R_UNLESS(size == unmap_size, ResultInvalidSize);
89 if (page_list.GetNumPages() != page_count) {
90 UNIMPLEMENTED_MSG("Page count does not match");
91 }
92 111
93 return target_process.PageTable().UnmapPages(address, page_list, KMemoryState::Shared); 112 return target_process.PageTable().UnmapPages(address, *page_group, KMemoryState::Shared);
94} 113}
95 114
96} // namespace Kernel 115} // namespace Kernel
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h
index a96c55a3e..8b29f0b4a 100644
--- a/src/core/hle/kernel/k_shared_memory.h
+++ b/src/core/hle/kernel/k_shared_memory.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <optional>
6#include <string> 7#include <string>
7 8
8#include "common/common_types.h" 9#include "common/common_types.h"
@@ -26,9 +27,8 @@ public:
26 ~KSharedMemory() override; 27 ~KSharedMemory() override;
27 28
28 Result Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, 29 Result Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
29 KPageGroup&& page_list_, Svc::MemoryPermission owner_permission_, 30 Svc::MemoryPermission owner_permission_,
30 Svc::MemoryPermission user_permission_, PAddr physical_address_, 31 Svc::MemoryPermission user_permission_, std::size_t size_, std::string name_);
31 std::size_t size_, std::string name_);
32 32
33 /** 33 /**
34 * Maps a shared memory block to an address in the target process' address space 34 * Maps a shared memory block to an address in the target process' address space
@@ -76,7 +76,7 @@ public:
76private: 76private:
77 Core::DeviceMemory* device_memory{}; 77 Core::DeviceMemory* device_memory{};
78 KProcess* owner_process{}; 78 KProcess* owner_process{};
79 KPageGroup page_list; 79 std::optional<KPageGroup> page_group{};
80 Svc::MemoryPermission owner_permission{}; 80 Svc::MemoryPermission owner_permission{};
81 Svc::MemoryPermission user_permission{}; 81 Svc::MemoryPermission user_permission{};
82 PAddr physical_address{}; 82 PAddr physical_address{};
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b75bac5df..1fb25f221 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -94,6 +94,7 @@ struct KernelCore::Impl {
94 pt_heap_region.GetSize()); 94 pt_heap_region.GetSize());
95 } 95 }
96 96
97 InitializeHackSharedMemory();
97 RegisterHostThread(nullptr); 98 RegisterHostThread(nullptr);
98 99
99 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread"); 100 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");
@@ -726,14 +727,14 @@ struct KernelCore::Impl {
726 } 727 }
727 728
728 void InitializeMemoryLayout() { 729 void InitializeMemoryLayout() {
729 const auto system_pool = memory_layout->GetKernelSystemPoolRegionPhysicalExtents();
730
731 // Initialize the memory manager. 730 // Initialize the memory manager.
732 memory_manager = std::make_unique<KMemoryManager>(system); 731 memory_manager = std::make_unique<KMemoryManager>(system);
733 const auto& management_region = memory_layout->GetPoolManagementRegion(); 732 const auto& management_region = memory_layout->GetPoolManagementRegion();
734 ASSERT(management_region.GetEndAddress() != 0); 733 ASSERT(management_region.GetEndAddress() != 0);
735 memory_manager->Initialize(management_region.GetAddress(), management_region.GetSize()); 734 memory_manager->Initialize(management_region.GetAddress(), management_region.GetSize());
735 }
736 736
737 void InitializeHackSharedMemory() {
737 // Setup memory regions for emulated processes 738 // Setup memory regions for emulated processes
738 // TODO(bunnei): These should not be hardcoded regions initialized within the kernel 739 // TODO(bunnei): These should not be hardcoded regions initialized within the kernel
739 constexpr std::size_t hid_size{0x40000}; 740 constexpr std::size_t hid_size{0x40000};
@@ -742,39 +743,23 @@ struct KernelCore::Impl {
742 constexpr std::size_t time_size{0x1000}; 743 constexpr std::size_t time_size{0x1000};
743 constexpr std::size_t hidbus_size{0x1000}; 744 constexpr std::size_t hidbus_size{0x1000};
744 745
745 const PAddr hid_phys_addr{system_pool.GetAddress()};
746 const PAddr font_phys_addr{system_pool.GetAddress() + hid_size};
747 const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size};
748 const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size};
749 const PAddr hidbus_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size +
750 time_size};
751
752 hid_shared_mem = KSharedMemory::Create(system.Kernel()); 746 hid_shared_mem = KSharedMemory::Create(system.Kernel());
753 font_shared_mem = KSharedMemory::Create(system.Kernel()); 747 font_shared_mem = KSharedMemory::Create(system.Kernel());
754 irs_shared_mem = KSharedMemory::Create(system.Kernel()); 748 irs_shared_mem = KSharedMemory::Create(system.Kernel());
755 time_shared_mem = KSharedMemory::Create(system.Kernel()); 749 time_shared_mem = KSharedMemory::Create(system.Kernel());
756 hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); 750 hidbus_shared_mem = KSharedMemory::Create(system.Kernel());
757 751
758 hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, 752 hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
759 {hid_phys_addr, hid_size / PageSize}, 753 Svc::MemoryPermission::Read, hid_size, "HID:SharedMemory");
760 Svc::MemoryPermission::None, Svc::MemoryPermission::Read, 754 font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
761 hid_phys_addr, hid_size, "HID:SharedMemory"); 755 Svc::MemoryPermission::Read, font_size, "Font:SharedMemory");
762 font_shared_mem->Initialize(system.DeviceMemory(), nullptr, 756 irs_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
763 {font_phys_addr, font_size / PageSize}, 757 Svc::MemoryPermission::Read, irs_size, "IRS:SharedMemory");
764 Svc::MemoryPermission::None, Svc::MemoryPermission::Read, 758 time_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
765 font_phys_addr, font_size, "Font:SharedMemory"); 759 Svc::MemoryPermission::Read, time_size, "Time:SharedMemory");
766 irs_shared_mem->Initialize(system.DeviceMemory(), nullptr, 760 hidbus_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
767 {irs_phys_addr, irs_size / PageSize}, 761 Svc::MemoryPermission::Read, hidbus_size,
768 Svc::MemoryPermission::None, Svc::MemoryPermission::Read, 762 "HidBus:SharedMemory");
769 irs_phys_addr, irs_size, "IRS:SharedMemory");
770 time_shared_mem->Initialize(system.DeviceMemory(), nullptr,
771 {time_phys_addr, time_size / PageSize},
772 Svc::MemoryPermission::None, Svc::MemoryPermission::Read,
773 time_phys_addr, time_size, "Time:SharedMemory");
774 hidbus_shared_mem->Initialize(system.DeviceMemory(), nullptr,
775 {hidbus_phys_addr, hidbus_size / PageSize},
776 Svc::MemoryPermission::None, Svc::MemoryPermission::Read,
777 hidbus_phys_addr, hidbus_size, "HidBus:SharedMemory");
778 } 763 }
779 764
780 KClientPort* CreateNamedServicePort(std::string name) { 765 KClientPort* CreateNamedServicePort(std::string name) {