summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/k_page_table_base.cpp32
-rw-r--r--src/core/memory.cpp8
-rw-r--r--src/core/memory.h6
3 files changed, 37 insertions, 9 deletions
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
index 47dc8fd35..dc6524146 100644
--- a/src/core/hle/kernel/k_page_table_base.cpp
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -88,6 +88,20 @@ Result FlushDataCache(AddressType addr, u64 size) {
88 R_SUCCEED(); 88 R_SUCCEED();
89} 89}
90 90
91constexpr Common::MemoryPermission ConvertToMemoryPermission(KMemoryPermission perm) {
92 Common::MemoryPermission perms{};
93 if (True(perm & KMemoryPermission::UserRead)) {
94 perms |= Common::MemoryPermission::Read;
95 }
96 if (True(perm & KMemoryPermission::UserWrite)) {
97 perms |= Common::MemoryPermission::Write;
98 }
99 if (True(perm & KMemoryPermission::UserExecute)) {
100 perms |= Common::MemoryPermission::Execute;
101 }
102 return perms;
103}
104
91} // namespace 105} // namespace
92 106
93void KPageTableBase::MemoryRange::Open() { 107void KPageTableBase::MemoryRange::Open() {
@@ -5643,7 +5657,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
5643 case OperationType::Map: { 5657 case OperationType::Map: {
5644 ASSERT(virt_addr != 0); 5658 ASSERT(virt_addr != 0);
5645 ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize)); 5659 ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
5646 m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr); 5660 m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr,
5661 ConvertToMemoryPermission(properties.perm));
5647 5662
5648 // Open references to pages, if we should. 5663 // Open references to pages, if we should.
5649 if (this->IsHeapPhysicalAddress(phys_addr)) { 5664 if (this->IsHeapPhysicalAddress(phys_addr)) {
@@ -5658,8 +5673,18 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
5658 } 5673 }
5659 case OperationType::ChangePermissions: 5674 case OperationType::ChangePermissions:
5660 case OperationType::ChangePermissionsAndRefresh: 5675 case OperationType::ChangePermissionsAndRefresh:
5661 case OperationType::ChangePermissionsAndRefreshAndFlush: 5676 case OperationType::ChangePermissionsAndRefreshAndFlush: {
5677 const bool read = True(properties.perm & Kernel::KMemoryPermission::UserRead);
5678 const bool write = True(properties.perm & Kernel::KMemoryPermission::UserWrite);
5679 // todo: this doesn't really belong here and should go into m_memory to handle rasterizer
5680 // access todo: ignore exec on non-direct-mapped case
5681 const bool exec = True(properties.perm & Kernel::KMemoryPermission::UserExecute);
5682 if (Settings::IsFastmemEnabled()) {
5683 m_system.DeviceMemory().buffer.Protect(GetInteger(virt_addr), num_pages * PageSize,
5684 read, write, exec);
5685 }
5662 R_SUCCEED(); 5686 R_SUCCEED();
5687 }
5663 default: 5688 default:
5664 UNREACHABLE(); 5689 UNREACHABLE();
5665 } 5690 }
@@ -5687,7 +5712,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
5687 const size_t size{node.GetNumPages() * PageSize}; 5712 const size_t size{node.GetNumPages() * PageSize};
5688 5713
5689 // Map the pages. 5714 // Map the pages.
5690 m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress()); 5715 m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(),
5716 ConvertToMemoryPermission(properties.perm));
5691 5717
5692 virt_addr += size; 5718 virt_addr += size;
5693 } 5719 }
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index a3431772a..14db64f9d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -53,7 +53,7 @@ struct Memory::Impl {
53 } 53 }
54 54
55 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, 55 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
56 Common::PhysicalAddress target) { 56 Common::PhysicalAddress target, Common::MemoryPermission perms) {
57 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size); 57 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
58 ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base)); 58 ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
59 ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", 59 ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}",
@@ -63,7 +63,7 @@ struct Memory::Impl {
63 63
64 if (Settings::IsFastmemEnabled()) { 64 if (Settings::IsFastmemEnabled()) {
65 system.DeviceMemory().buffer.Map(GetInteger(base), 65 system.DeviceMemory().buffer.Map(GetInteger(base),
66 GetInteger(target) - DramMemoryMap::Base, size); 66 GetInteger(target) - DramMemoryMap::Base, size, perms);
67 } 67 }
68 } 68 }
69 69
@@ -831,8 +831,8 @@ void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
831} 831}
832 832
833void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, 833void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
834 Common::PhysicalAddress target) { 834 Common::PhysicalAddress target, Common::MemoryPermission perms) {
835 impl->MapMemoryRegion(page_table, base, size, target); 835 impl->MapMemoryRegion(page_table, base, size, target, perms);
836} 836}
837 837
838void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) { 838void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) {
diff --git a/src/core/memory.h b/src/core/memory.h
index 13047a545..73195549f 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -15,8 +15,9 @@
15#include "core/hle/result.h" 15#include "core/hle/result.h"
16 16
17namespace Common { 17namespace Common {
18enum class MemoryPermission : u32;
18struct PageTable; 19struct PageTable;
19} 20} // namespace Common
20 21
21namespace Core { 22namespace Core {
22class System; 23class System;
@@ -82,9 +83,10 @@ public:
82 * @param size The amount of bytes to map. Must be page-aligned. 83 * @param size The amount of bytes to map. Must be page-aligned.
83 * @param target Buffer with the memory backing the mapping. Must be of length at least 84 * @param target Buffer with the memory backing the mapping. Must be of length at least
84 * `size`. 85 * `size`.
86 * @param perms The permissions to map the memory with.
85 */ 87 */
86 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, 88 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
87 Common::PhysicalAddress target); 89 Common::PhysicalAddress target, Common::MemoryPermission perms);
88 90
89 /** 91 /**
90 * Unmaps a region of the emulated process address space. 92 * Unmaps a region of the emulated process address space.