summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorGPUCode <geoster3d@gmail.com>2023-11-17 20:43:15 +0100
committert895 <clombardo169@gmail.com>2023-11-25 06:46:15 +0100
commit5938a9582a238d7679eb15f9812f8a85bfdb1cc3 (patch)
tree935356a1cc03fea528e349d5027f2d885537272a /src/core
parenthost_memory: Switch to FreeRegionManager (diff)
downloadyuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar
yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.gz
yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.bz2
yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.lz
yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.xz
yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.tar.zst
yuzu-5938a9582a238d7679eb15f9812f8a85bfdb1cc3.zip
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) {
R_SUCCEED();
}
+constexpr Common::MemoryPermission ConvertToMemoryPermission(KMemoryPermission perm) {
+ Common::MemoryPermission perms{};
+ if (True(perm & KMemoryPermission::UserRead)) {
+ perms |= Common::MemoryPermission::Read;
+ }
+ if (True(perm & KMemoryPermission::UserWrite)) {
+ perms |= Common::MemoryPermission::Write;
+ }
+ if (True(perm & KMemoryPermission::UserExecute)) {
+ perms |= Common::MemoryPermission::Execute;
+ }
+ return perms;
+}
+
} // namespace
void KPageTableBase::MemoryRange::Open() {
@@ -5643,7 +5657,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
case OperationType::Map: {
ASSERT(virt_addr != 0);
ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
- m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr);
+ m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr,
+ ConvertToMemoryPermission(properties.perm));
// Open references to pages, if we should.
if (this->IsHeapPhysicalAddress(phys_addr)) {
@@ -5658,8 +5673,18 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
}
case OperationType::ChangePermissions:
case OperationType::ChangePermissionsAndRefresh:
- case OperationType::ChangePermissionsAndRefreshAndFlush:
+ case OperationType::ChangePermissionsAndRefreshAndFlush: {
+ const bool read = True(properties.perm & Kernel::KMemoryPermission::UserRead);
+ const bool write = True(properties.perm & Kernel::KMemoryPermission::UserWrite);
+ // todo: this doesn't really belong here and should go into m_memory to handle rasterizer
+ // access todo: ignore exec on non-direct-mapped case
+ const bool exec = True(properties.perm & Kernel::KMemoryPermission::UserExecute);
+ if (Settings::IsFastmemEnabled()) {
+ m_system.DeviceMemory().buffer.Protect(GetInteger(virt_addr), num_pages * PageSize,
+ read, write, exec);
+ }
R_SUCCEED();
+ }
default:
UNREACHABLE();
}
@@ -5687,7 +5712,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
const size_t size{node.GetNumPages() * PageSize};
// Map the pages.
- m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress());
+ m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(),
+ ConvertToMemoryPermission(properties.perm));
virt_addr += size;
}
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 {
}
void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
- Common::PhysicalAddress target) {
+ Common::PhysicalAddress target, Common::MemoryPermission perms) {
ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}",
@@ -63,7 +63,7 @@ struct Memory::Impl {
if (Settings::IsFastmemEnabled()) {
system.DeviceMemory().buffer.Map(GetInteger(base),
- GetInteger(target) - DramMemoryMap::Base, size);
+ GetInteger(target) - DramMemoryMap::Base, size, perms);
}
}
@@ -831,8 +831,8 @@ void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
}
void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
- Common::PhysicalAddress target) {
- impl->MapMemoryRegion(page_table, base, size, target);
+ Common::PhysicalAddress target, Common::MemoryPermission perms) {
+ impl->MapMemoryRegion(page_table, base, size, target, perms);
}
void 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 @@
#include "core/hle/result.h"
namespace Common {
+enum class MemoryPermission : u32;
struct PageTable;
-}
+} // namespace Common
namespace Core {
class System;
@@ -82,9 +83,10 @@ public:
* @param size The amount of bytes to map. Must be page-aligned.
* @param target Buffer with the memory backing the mapping. Must be of length at least
* `size`.
+ * @param perms The permissions to map the memory with.
*/
void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
- Common::PhysicalAddress target);
+ Common::PhysicalAddress target, Common::MemoryPermission perms);
/**
* Unmaps a region of the emulated process address space.