mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-16 12:09:07 +00:00
address translation
This commit is contained in:
parent
1c0617146c
commit
26900f9074
@ -650,8 +650,32 @@ struct AddressSpace::Impl {
|
|||||||
const int handle = phys_addr != -1 ? (fd == -1 ? backing_fd : fd) : -1;
|
const int handle = phys_addr != -1 ? (fd == -1 ? backing_fd : fd) : -1;
|
||||||
const off_t host_offset = phys_addr != -1 ? phys_addr : 0;
|
const off_t host_offset = phys_addr != -1 ? phys_addr : 0;
|
||||||
const int flag = phys_addr != -1 ? MAP_SHARED : (MAP_ANONYMOUS | MAP_PRIVATE);
|
const int flag = phys_addr != -1 ? MAP_SHARED : (MAP_ANONYMOUS | MAP_PRIVATE);
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(ARCH_ARM64)
|
||||||
|
// On ARM64 macOS, translate PS4 virtual addresses to host addresses
|
||||||
|
void* host_addr = nullptr;
|
||||||
|
if (virtual_addr >= SYSTEM_MANAGED_MIN && virtual_addr <= SYSTEM_MANAGED_MAX) {
|
||||||
|
// System managed region
|
||||||
|
u64 offset = virtual_addr - SYSTEM_MANAGED_MIN;
|
||||||
|
host_addr = system_managed_base + offset;
|
||||||
|
} else if (virtual_addr >= SYSTEM_RESERVED_MIN && virtual_addr <= SYSTEM_RESERVED_MAX) {
|
||||||
|
// System reserved region
|
||||||
|
u64 offset = virtual_addr - SYSTEM_RESERVED_MIN;
|
||||||
|
host_addr = system_reserved_base + offset;
|
||||||
|
} else if (virtual_addr >= USER_MIN && virtual_addr <= USER_MAX) {
|
||||||
|
// User region
|
||||||
|
u64 offset = virtual_addr - USER_MIN;
|
||||||
|
host_addr = user_base + offset;
|
||||||
|
} else {
|
||||||
|
LOG_CRITICAL(Kernel_Vmm, "Invalid virtual address for mapping: {:#x}", virtual_addr);
|
||||||
|
return MAP_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ret = mmap(host_addr, size, prot, MAP_FIXED | flag, handle, host_offset);
|
||||||
|
#else
|
||||||
void* ret = mmap(reinterpret_cast<void*>(virtual_addr), size, prot, MAP_FIXED | flag,
|
void* ret = mmap(reinterpret_cast<void*>(virtual_addr), size, prot, MAP_FIXED | flag,
|
||||||
handle, host_offset);
|
handle, host_offset);
|
||||||
|
#endif
|
||||||
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -671,9 +695,29 @@ struct AddressSpace::Impl {
|
|||||||
// Free the relevant region.
|
// Free the relevant region.
|
||||||
m_free_regions.insert({start_address, end_address});
|
m_free_regions.insert({start_address, end_address});
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(ARCH_ARM64)
|
||||||
|
// On ARM64 macOS, translate PS4 virtual addresses to host addresses
|
||||||
|
void* host_addr = nullptr;
|
||||||
|
if (start_address >= SYSTEM_MANAGED_MIN && start_address <= SYSTEM_MANAGED_MAX) {
|
||||||
|
u64 offset = start_address - SYSTEM_MANAGED_MIN;
|
||||||
|
host_addr = system_managed_base + offset;
|
||||||
|
} else if (start_address >= SYSTEM_RESERVED_MIN && start_address <= SYSTEM_RESERVED_MAX) {
|
||||||
|
u64 offset = start_address - SYSTEM_RESERVED_MIN;
|
||||||
|
host_addr = system_reserved_base + offset;
|
||||||
|
} else if (start_address >= USER_MIN && start_address <= USER_MAX) {
|
||||||
|
u64 offset = start_address - USER_MIN;
|
||||||
|
host_addr = user_base + offset;
|
||||||
|
} else {
|
||||||
|
LOG_CRITICAL(Kernel_Vmm, "Invalid virtual address for unmapping: {:#x}", start_address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void* ret = mmap(host_addr, end_address - start_address,
|
||||||
|
PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
||||||
|
#else
|
||||||
// Return the adjusted pointers.
|
// Return the adjusted pointers.
|
||||||
void* ret = mmap(reinterpret_cast<void*>(start_address), end_address - start_address,
|
void* ret = mmap(reinterpret_cast<void*>(start_address), end_address - start_address,
|
||||||
PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
||||||
|
#endif
|
||||||
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,7 +734,26 @@ struct AddressSpace::Impl {
|
|||||||
flags |= PROT_EXEC;
|
flags |= PROT_EXEC;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__APPLE__) && defined(ARCH_ARM64)
|
||||||
|
// On ARM64 macOS, translate PS4 virtual addresses to host addresses
|
||||||
|
void* host_addr = nullptr;
|
||||||
|
if (virtual_addr >= SYSTEM_MANAGED_MIN && virtual_addr <= SYSTEM_MANAGED_MAX) {
|
||||||
|
u64 offset = virtual_addr - SYSTEM_MANAGED_MIN;
|
||||||
|
host_addr = system_managed_base + offset;
|
||||||
|
} else if (virtual_addr >= SYSTEM_RESERVED_MIN && virtual_addr <= SYSTEM_RESERVED_MAX) {
|
||||||
|
u64 offset = virtual_addr - SYSTEM_RESERVED_MIN;
|
||||||
|
host_addr = system_reserved_base + offset;
|
||||||
|
} else if (virtual_addr >= USER_MIN && virtual_addr <= USER_MAX) {
|
||||||
|
u64 offset = virtual_addr - USER_MIN;
|
||||||
|
host_addr = user_base + offset;
|
||||||
|
} else {
|
||||||
|
LOG_CRITICAL(Kernel_Vmm, "Invalid virtual address for protection: {:#x}", virtual_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ret = mprotect(host_addr, size, flags);
|
||||||
|
#else
|
||||||
int ret = mprotect(reinterpret_cast<void*>(virtual_addr), size, flags);
|
int ret = mprotect(reinterpret_cast<void*>(virtual_addr), size, flags);
|
||||||
|
#endif
|
||||||
ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno));
|
ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user