mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-16 12:09:07 +00:00
flexible address in mmap
This commit is contained in:
parent
513bc203df
commit
1c0617146c
@ -532,56 +532,41 @@ struct AddressSpace::Impl {
|
|||||||
user_base = reinterpret_cast<u8*>(
|
user_base = reinterpret_cast<u8*>(
|
||||||
mmap(reinterpret_cast<void*>(USER_MIN), user_size, protection_flags, map_flags, -1, 0));
|
mmap(reinterpret_cast<void*>(USER_MIN), user_size, protection_flags, map_flags, -1, 0));
|
||||||
#elif defined(ARCH_ARM64)
|
#elif defined(ARCH_ARM64)
|
||||||
// On ARM64 macOS, MAP_FIXED may not work at these addresses due to system restrictions.
|
// On ARM64 macOS, MAP_FIXED doesn't work at low addresses (0x400000) due to system restrictions.
|
||||||
// We need these exact addresses for the PS4 memory layout, so we try multiple approaches.
|
// Map memory wherever possible and use offset calculations. This is a temporary solution
|
||||||
int map_flags_fixed = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED;
|
// until proper address translation is implemented for ARM64.
|
||||||
|
// Note: This means the PS4 virtual addresses won't match host addresses, so instruction
|
||||||
|
// translation/JIT will need to handle the offset.
|
||||||
|
constexpr int map_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
|
||||||
|
|
||||||
|
// Map the three regions separately, but let the system choose addresses
|
||||||
system_managed_base =
|
system_managed_base =
|
||||||
reinterpret_cast<u8*>(mmap(reinterpret_cast<void*>(SYSTEM_MANAGED_MIN),
|
reinterpret_cast<u8*>(mmap(nullptr, system_managed_size, protection_flags, map_flags, -1, 0));
|
||||||
system_managed_size, protection_flags, map_flags_fixed, -1, 0));
|
|
||||||
if (system_managed_base == MAP_FAILED) {
|
if (system_managed_base == MAP_FAILED) {
|
||||||
// Try without MAP_NORESERVE
|
LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_managed_base: {}", strerror(errno));
|
||||||
int map_flags_noreserve = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
|
throw std::bad_alloc{};
|
||||||
system_managed_base =
|
|
||||||
reinterpret_cast<u8*>(mmap(reinterpret_cast<void*>(SYSTEM_MANAGED_MIN),
|
|
||||||
system_managed_size, protection_flags, map_flags_noreserve, -1, 0));
|
|
||||||
if (system_managed_base == MAP_FAILED) {
|
|
||||||
LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_managed_base at {}: {}. "
|
|
||||||
"ARM64 macOS does not allow mapping at address 0x400000. "
|
|
||||||
"The PS4 memory layout requires exact addresses. "
|
|
||||||
"Consider using x86_64 mode or implementing address translation for ARM64.",
|
|
||||||
fmt::ptr(reinterpret_cast<void*>(SYSTEM_MANAGED_MIN)), strerror(errno));
|
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
system_reserved_base =
|
system_reserved_base =
|
||||||
reinterpret_cast<u8*>(mmap(reinterpret_cast<void*>(SYSTEM_RESERVED_MIN),
|
reinterpret_cast<u8*>(mmap(nullptr, system_reserved_size, protection_flags, map_flags, -1, 0));
|
||||||
system_reserved_size, protection_flags, map_flags_fixed, -1, 0));
|
|
||||||
if (system_reserved_base == MAP_FAILED) {
|
if (system_reserved_base == MAP_FAILED) {
|
||||||
int map_flags_noreserve = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
|
LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_reserved_base: {}", strerror(errno));
|
||||||
system_reserved_base =
|
throw std::bad_alloc{};
|
||||||
reinterpret_cast<u8*>(mmap(reinterpret_cast<void*>(SYSTEM_RESERVED_MIN),
|
|
||||||
system_reserved_size, protection_flags, map_flags_noreserve, -1, 0));
|
|
||||||
if (system_reserved_base == MAP_FAILED) {
|
|
||||||
LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_reserved_base at {}: {}",
|
|
||||||
fmt::ptr(reinterpret_cast<void*>(SYSTEM_RESERVED_MIN)), strerror(errno));
|
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user_base = reinterpret_cast<u8*>(
|
user_base = reinterpret_cast<u8*>(
|
||||||
mmap(reinterpret_cast<void*>(USER_MIN), user_size, protection_flags, map_flags_fixed, -1, 0));
|
mmap(nullptr, user_size, protection_flags, map_flags, -1, 0));
|
||||||
if (user_base == MAP_FAILED) {
|
if (user_base == MAP_FAILED) {
|
||||||
int map_flags_noreserve = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
|
LOG_CRITICAL(Kernel_Vmm, "mmap failed for user_base: {}", strerror(errno));
|
||||||
user_base = reinterpret_cast<u8*>(
|
throw std::bad_alloc{};
|
||||||
mmap(reinterpret_cast<void*>(USER_MIN), user_size, protection_flags, map_flags_noreserve, -1, 0));
|
|
||||||
if (user_base == MAP_FAILED) {
|
|
||||||
LOG_CRITICAL(Kernel_Vmm, "mmap failed for user_base at {}: {}",
|
|
||||||
fmt::ptr(reinterpret_cast<void*>(USER_MIN)), strerror(errno));
|
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_WARNING(Kernel_Vmm, "ARM64 macOS: Using flexible memory layout. "
|
||||||
|
"PS4 addresses will be offset from host addresses. "
|
||||||
|
"system_managed: {} (expected {}), system_reserved: {} (expected {}), user: {} (expected {})",
|
||||||
|
fmt::ptr(system_managed_base), fmt::ptr(reinterpret_cast<void*>(SYSTEM_MANAGED_MIN)),
|
||||||
|
fmt::ptr(system_reserved_base), fmt::ptr(reinterpret_cast<void*>(SYSTEM_RESERVED_MIN)),
|
||||||
|
fmt::ptr(user_base), fmt::ptr(reinterpret_cast<void*>(USER_MIN)));
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
const auto virtual_size = system_managed_size + system_reserved_size + user_size;
|
const auto virtual_size = system_managed_size + system_reserved_size + user_size;
|
||||||
@ -618,7 +603,7 @@ struct AddressSpace::Impl {
|
|||||||
fmt::ptr(user_base + user_size - 1));
|
fmt::ptr(user_base + user_size - 1));
|
||||||
|
|
||||||
const VAddr system_managed_addr = reinterpret_cast<VAddr>(system_managed_base);
|
const VAddr system_managed_addr = reinterpret_cast<VAddr>(system_managed_base);
|
||||||
const VAddr system_reserved_addr = reinterpret_cast<VAddr>(system_managed_base);
|
const VAddr system_reserved_addr = reinterpret_cast<VAddr>(system_reserved_base);
|
||||||
const VAddr user_addr = reinterpret_cast<VAddr>(user_base);
|
const VAddr user_addr = reinterpret_cast<VAddr>(user_base);
|
||||||
m_free_regions.insert({system_managed_addr, system_managed_addr + system_managed_size});
|
m_free_regions.insert({system_managed_addr, system_managed_addr + system_managed_size});
|
||||||
m_free_regions.insert({system_reserved_addr, system_reserved_addr + system_reserved_size});
|
m_free_regions.insert({system_reserved_addr, system_reserved_addr + system_reserved_size});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user