diff --git a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 78a25185..48af48ef 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -604,6 +604,15 @@ namespace ams::kern::arch::arm64::init { this->state.free_bitmap = ~uintptr_t(); } + ALWAYS_INLINE void InitializeFromState(uintptr_t state_val) { + if (kern::GetTargetFirmware() >= kern::TargetFirmware_10_0_0) { + this->state = *reinterpret_cast(state_val); + } else { + this->state.next_address = state_val; + this->state.free_bitmap = 0; + } + } + ALWAYS_INLINE void GetFinalState(State *out) { *out = this->state; this->state = {}; diff --git a/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp b/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp index e519c475..56b7f827 100644 --- a/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp +++ b/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp @@ -318,8 +318,12 @@ namespace ams::svc::aarch64::lp64 { return ::svcQueryPhysicalAddress(reinterpret_cast<::PhysicalMemoryInfo *>(out_info), address); } - ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { - return ::svcQueryIoMapping(reinterpret_cast(out_address), physical_address, size); + ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { + return ::svcQueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size); + } + + ALWAYS_INLINE Result LegacyQueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { + return ::svcLegacyQueryIoMapping(reinterpret_cast(out_address), physical_address, size); } ALWAYS_INLINE Result CreateDeviceAddressSpace(::ams::svc::Handle *out_handle, uint64_t das_address, uint64_t das_size) { diff --git a/libstratosphere/source/dd/dd_io_mappings.cpp b/libstratosphere/source/dd/dd_io_mappings.cpp index e71f9821..7966defa 100644 --- a/libstratosphere/source/dd/dd_io_mappings.cpp +++ b/libstratosphere/source/dd/dd_io_mappings.cpp @@ -22,10 +22,19 @@ namespace ams::dd { const u64 aligned_addr = util::AlignDown(phys_addr, os::MemoryPageSize); const size_t offset = phys_addr - aligned_addr; const u64 aligned_size = size + offset; - R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) { - /* Official software handles this by returning 0. */ - R_CATCH(svc::ResultNotFound) { return 0; } - } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + if (hos::GetVersion() >= hos::Version_10_0_0) { + u64 region_size; + R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, ®ion_size, aligned_addr, aligned_size)) { + /* Official software handles this by returning 0. */ + R_CATCH(svc::ResultNotFound) { exosphere::ForceRebootToRcm(); return 0; } + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + AMS_ASSERT(region_size >= aligned_size); + } else { + R_TRY_CATCH(svcLegacyQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) { + /* Official software handles this by returning 0. */ + R_CATCH(svc::ResultNotFound) { return 0; } + } R_END_TRY_CATCH_WITH_ABORT_UNLESS; + } return static_cast(virtual_addr + offset); }