diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_shared_memory.cpp | 69 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_shared_memory.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 43 |
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 | ||
| 20 | Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, | 21 | Result 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 | ||
| 58 | void KSharedMemory::Finalize() { | 72 | void 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 | ||
| 67 | Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size, | 90 | Result 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 | ||
| 86 | Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { | 108 | Result 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: | |||
| 76 | private: | 76 | private: |
| 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) { |