mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
kern: add infra (but not impl) for all DeviceAddressSpace svcs
This commit is contained in:
parent
863515a3b5
commit
0d3aa13f70
11 changed files with 303 additions and 13 deletions
|
@ -104,6 +104,18 @@ namespace ams::kern::arch::arm64 {
|
|||
return this->page_table.MakeAndOpenPageGroup(out, address, num_pages, state_mask, state, perm_mask, perm, attr_mask, attr);
|
||||
}
|
||||
|
||||
Result MakeAndOpenPageGroupContiguous(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) {
|
||||
return this->page_table.MakeAndOpenPageGroupContiguous(out, address, num_pages, state_mask, state, perm_mask, perm, attr_mask, attr);
|
||||
}
|
||||
|
||||
Result LockForDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned) {
|
||||
return this->page_table.LockForDeviceAddressSpace(out, address, size, perm, is_aligned);
|
||||
}
|
||||
|
||||
Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
|
||||
return this->page_table.UnlockForDeviceAddressSpace(address, size);
|
||||
}
|
||||
|
||||
Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) {
|
||||
return this->page_table.LockForIpcUserBuffer(out, address, size);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,9 @@ namespace ams::kern::board::nintendo::nx {
|
|||
|
||||
Result Attach(ams::svc::DeviceName device_name, u64 space_address, u64 space_size);
|
||||
Result Detach(ams::svc::DeviceName device_name);
|
||||
|
||||
Result Map(size_t *out_mapped_size, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings);
|
||||
Result Unmap(const KPageGroup &pg, KDeviceVirtualAddress device_address);
|
||||
public:
|
||||
static void Initialize();
|
||||
};
|
||||
|
|
|
@ -389,6 +389,30 @@ namespace ams::kern {
|
|||
this->num_pages -= block->num_pages;
|
||||
}
|
||||
|
||||
constexpr void ShareToDevice(KMemoryPermission new_perm) {
|
||||
/* We must either be shared or have a zero lock count. */
|
||||
MESOSPHERE_ASSERT((this->attribute & KMemoryAttribute_DeviceShared) == KMemoryAttribute_DeviceShared || this->device_use_count == 0);
|
||||
|
||||
/* Share. */
|
||||
const u16 new_count = ++this->device_use_count;
|
||||
MESOSPHERE_ABORT_UNLESS(new_count > 0);
|
||||
|
||||
this->attribute = static_cast<KMemoryAttribute>(this->attribute | KMemoryAttribute_DeviceShared);
|
||||
}
|
||||
|
||||
constexpr void UnshareToDevice(KMemoryPermission new_perm) {
|
||||
/* We must be shared. */
|
||||
MESOSPHERE_ASSERT((this->attribute & KMemoryAttribute_DeviceShared) == KMemoryAttribute_DeviceShared);
|
||||
|
||||
/* Unhare. */
|
||||
const u16 old_count = this->device_use_count--;
|
||||
MESOSPHERE_ABORT_UNLESS(old_count > 0);
|
||||
|
||||
if (old_count == 1) {
|
||||
this->attribute = static_cast<KMemoryAttribute>(this->attribute & ~KMemoryAttribute_DeviceShared);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void LockForIpc(KMemoryPermission new_perm) {
|
||||
/* We must either be locked or have a zero lock count. */
|
||||
MESOSPHERE_ASSERT((this->attribute & KMemoryAttribute_IpcLocked) == KMemoryAttribute_IpcLocked || this->ipc_lock_count == 0);
|
||||
|
|
|
@ -300,7 +300,10 @@ namespace ams::kern {
|
|||
Result UnmapPageGroup(KProcessAddress address, const KPageGroup &pg, KMemoryState state);
|
||||
|
||||
Result MakeAndOpenPageGroup(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr);
|
||||
Result MakeAndOpenPageGroupContiguous(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr);
|
||||
|
||||
Result LockForDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned);
|
||||
Result UnlockForDeviceAddressSpace(KProcessAddress address, size_t size);
|
||||
Result LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size);
|
||||
Result UnlockForIpcUserBuffer(KProcessAddress address, size_t size);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace ams::kern::svc {
|
|||
/* 105 */ using ::ams::svc::ResultOutOfHandles;
|
||||
/* 106 */ using ::ams::svc::ResultInvalidCurrentMemory;
|
||||
|
||||
/* 108 */ using ::ams::svc::ResultInvalidNewMemoryPermissions;
|
||||
/* 108 */ using ::ams::svc::ResultInvalidNewMemoryPermission;
|
||||
|
||||
/* 110 */ using ::ams::svc::ResultInvalidMemoryRegion;
|
||||
|
||||
|
|
|
@ -583,4 +583,12 @@ namespace ams::kern::board::nintendo::nx {
|
|||
MESOSPHERE_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
Result KDevicePageTable::Map(size_t *out_mapped_size, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
Result KDevicePageTable::Unmap(const KPageGroup &pg, KDeviceVirtualAddress device_address) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,15 +57,71 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
Result KDeviceAddressSpace::Detach(ams::svc::DeviceName device_name) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
/* Lock the address space. */
|
||||
KScopedLightLock lk(this->lock);
|
||||
|
||||
/* Detach. */
|
||||
return this->table.Detach(device_name);
|
||||
}
|
||||
|
||||
Result KDeviceAddressSpace::Map(size_t *out_mapped_size, KProcessPageTable *page_table, KProcessAddress process_address, size_t size, u64 device_address, ams::svc::MemoryPermission device_perm, bool is_aligned, bool refresh_mappings) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
/* Check that the address falls within the space. */
|
||||
R_UNLESS((this->space_address <= device_address && device_address + size - 1 <= this->space_address + this->space_size - 1), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Lock the address space. */
|
||||
KScopedLightLock lk(this->lock);
|
||||
|
||||
/* Lock the pages. */
|
||||
KPageGroup pg(page_table->GetBlockInfoManager());
|
||||
R_TRY(page_table->LockForDeviceAddressSpace(std::addressof(pg), process_address, size, ConvertToKMemoryPermission(device_perm), is_aligned));
|
||||
|
||||
/* Ensure that if we fail, we don't keep unmapped pages locked. */
|
||||
ON_SCOPE_EXIT {
|
||||
if (*out_mapped_size != size) {
|
||||
page_table->UnlockForDeviceAddressSpace(process_address + *out_mapped_size, size - *out_mapped_size);
|
||||
};
|
||||
};
|
||||
|
||||
/* Map the pages. */
|
||||
{
|
||||
/* Clear the output size to zero on failure. */
|
||||
auto map_guard = SCOPE_GUARD { *out_mapped_size = 0; };
|
||||
|
||||
/* Perform the mapping. */
|
||||
R_TRY(this->table.Map(out_mapped_size, pg, device_address, device_perm, refresh_mappings));
|
||||
|
||||
/* We succeeded, so cancel our guard. */
|
||||
map_guard.Cancel();
|
||||
}
|
||||
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KDeviceAddressSpace::Unmap(KProcessPageTable *page_table, KProcessAddress process_address, size_t size, u64 device_address) {
|
||||
MESOSPHERE_UNIMPLEMENTED();
|
||||
/* Check that the address falls within the space. */
|
||||
R_UNLESS((this->space_address <= device_address && device_address + size - 1 <= this->space_address + this->space_size - 1), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Lock the address space. */
|
||||
KScopedLightLock lk(this->lock);
|
||||
|
||||
/* Make and open a page group for the unmapped region. */
|
||||
KPageGroup pg(page_table->GetBlockInfoManager());
|
||||
R_TRY(page_table->MakeAndOpenPageGroupContiguous(std::addressof(pg), process_address, size / PageSize,
|
||||
KMemoryState_FlagCanDeviceMap, KMemoryState_FlagCanDeviceMap,
|
||||
KMemoryPermission_None, KMemoryPermission_None,
|
||||
KMemoryAttribute_AnyLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_Locked, KMemoryAttribute_DeviceShared));
|
||||
|
||||
/* Ensure the page group is closed on scope exit. */
|
||||
ON_SCOPE_EXIT { pg.Close(); };
|
||||
|
||||
/* Unmap. */
|
||||
R_TRY(this->table.Unmap(pg, device_address));
|
||||
|
||||
/* Unlock the pages. */
|
||||
R_TRY(page_table->UnlockForDeviceAddressSpace(process_address, size));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1370,6 +1370,85 @@ namespace ams::kern {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KPageTableBase::MakeAndOpenPageGroupContiguous(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) {
|
||||
/* Ensure that the page group isn't null. */
|
||||
MESOSPHERE_ASSERT(out != nullptr);
|
||||
|
||||
/* Make sure that the region we're mapping is valid for the table. */
|
||||
const size_t size = num_pages * PageSize;
|
||||
R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Lock the table. */
|
||||
KScopedLightLock lk(this->general_lock);
|
||||
|
||||
/* Check if state allows us to create the group. */
|
||||
R_TRY(this->CheckMemoryStateContiguous(address, size, state_mask | KMemoryState_FlagReferenceCounted, state | KMemoryState_FlagReferenceCounted, perm_mask, perm, attr_mask, attr));
|
||||
|
||||
/* Create a new page group for the region. */
|
||||
R_TRY(this->MakePageGroup(*out, address, num_pages));
|
||||
|
||||
/* Open a new reference to the pages in the group. */
|
||||
out->Open();
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KPageTableBase::LockForDeviceAddressSpace(KPageGroup *out, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned) {
|
||||
/* Lightly validate the range before doing anything else. */
|
||||
const size_t num_pages = size / PageSize;
|
||||
R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Lock the table. */
|
||||
KScopedLightLock lk(this->general_lock);
|
||||
|
||||
/* Check the memory state. */
|
||||
const u32 test_state = (is_aligned ? KMemoryState_FlagCanAlignedDeviceMap : KMemoryState_FlagCanDeviceMap);
|
||||
R_TRY(this->CheckMemoryState(address, size, test_state, test_state, perm, perm, KMemoryAttribute_AnyLocked | KMemoryAttribute_IpcLocked | KMemoryAttribute_Locked, 0, KMemoryAttribute_DeviceShared));
|
||||
|
||||
/* Make the page group, if we should. */
|
||||
if (out != nullptr) {
|
||||
R_TRY(this->MakePageGroup(*out, address, num_pages));
|
||||
}
|
||||
|
||||
/* Create an update allocator. */
|
||||
KMemoryBlockManagerUpdateAllocator allocator(this->memory_block_slab_manager);
|
||||
R_TRY(allocator.GetResult());
|
||||
|
||||
/* Update the memory blocks. */
|
||||
this->memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, &KMemoryBlock::ShareToDevice, KMemoryPermission_None);
|
||||
|
||||
/* Open the page group. */
|
||||
if (out != nullptr) {
|
||||
out->Open();
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KPageTableBase::UnlockForDeviceAddressSpace(KProcessAddress address, size_t size) {
|
||||
/* Lightly validate the range before doing anything else. */
|
||||
const size_t num_pages = size / PageSize;
|
||||
R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Lock the table. */
|
||||
KScopedLightLock lk(this->general_lock);
|
||||
|
||||
/* Check the memory state. */
|
||||
R_TRY(this->CheckMemoryStateContiguous(address, size,
|
||||
KMemoryState_FlagCanDeviceMap, KMemoryState_FlagCanDeviceMap,
|
||||
KMemoryPermission_None, KMemoryPermission_None,
|
||||
KMemoryAttribute_AnyLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_Locked, KMemoryAttribute_DeviceShared));
|
||||
|
||||
/* Create an update allocator. */
|
||||
KMemoryBlockManagerUpdateAllocator allocator(this->memory_block_slab_manager);
|
||||
R_TRY(allocator.GetResult());
|
||||
|
||||
/* Update the memory blocks. */
|
||||
this->memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, &KMemoryBlock::UnshareToDevice, KMemoryPermission_None);
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KPageTableBase::LockForIpcUserBuffer(KPhysicalAddress *out, KProcessAddress address, size_t size) {
|
||||
return this->LockMemoryAndOpen(nullptr, out, address, size,
|
||||
KMemoryState_FlagCanIpcUserBuffer, KMemoryState_FlagCanIpcUserBuffer,
|
||||
|
|
|
@ -21,6 +21,12 @@ namespace ams::kern::svc {
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr inline u64 DeviceAddressSpaceAlignMask = (1ul << 22) - 1;
|
||||
|
||||
constexpr bool IsProcessAndDeviceAligned(uint64_t process_address, uint64_t device_address) {
|
||||
return (process_address & DeviceAddressSpaceAlignMask) == (device_address & DeviceAddressSpaceAlignMask);
|
||||
}
|
||||
|
||||
Result CreateDeviceAddressSpace(ams::svc::Handle *out, uint64_t das_address, uint64_t das_size) {
|
||||
/* Validate input. */
|
||||
R_UNLESS(util::IsAligned(das_address, PageSize), svc::ResultInvalidMemoryRegion());
|
||||
|
@ -62,6 +68,97 @@ namespace ams::kern::svc {
|
|||
return das->Detach(device_name);
|
||||
}
|
||||
|
||||
constexpr bool IsValidDeviceMemoryPermission(ams::svc::MemoryPermission device_perm) {
|
||||
switch (device_perm) {
|
||||
case ams::svc::MemoryPermission_Read:
|
||||
case ams::svc::MemoryPermission_Write:
|
||||
case ams::svc::MemoryPermission_ReadWrite:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpace(size_t *out_mapped_size, ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings) {
|
||||
/* Validate input. */
|
||||
R_UNLESS(util::IsAligned(process_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(device_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||
R_UNLESS((process_address < process_address + size), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS((device_address < device_address + size), svc::ResultInvalidMemoryRegion());
|
||||
R_UNLESS((process_address == static_cast<uintptr_t>(process_address)), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS(IsValidDeviceMemoryPermission(device_perm), svc::ResultInvalidNewMemoryPermission());
|
||||
|
||||
/* Get the device address space. */
|
||||
KScopedAutoObject das = GetCurrentProcess().GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle);
|
||||
R_UNLESS(das.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Get the process. */
|
||||
KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Validate that the process address is within range. */
|
||||
auto &page_table = process->GetPageTable();
|
||||
R_UNLESS(page_table.Contains(process_address, size), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Map. */
|
||||
return das->Map(out_mapped_size, std::addressof(page_table), KProcessAddress(process_address), size, device_address, device_perm, refresh_mappings);
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpaceAligned(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
/* Validate input. */
|
||||
R_UNLESS(util::IsAligned(process_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(device_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(IsProcessAndDeviceAligned(process_address, device_address), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||
R_UNLESS((process_address < process_address + size), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS((device_address < device_address + size), svc::ResultInvalidMemoryRegion());
|
||||
R_UNLESS((process_address == static_cast<uintptr_t>(process_address)), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS(IsValidDeviceMemoryPermission(device_perm), svc::ResultInvalidNewMemoryPermission());
|
||||
|
||||
/* Get the device address space. */
|
||||
KScopedAutoObject das = GetCurrentProcess().GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle);
|
||||
R_UNLESS(das.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Get the process. */
|
||||
KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Validate that the process address is within range. */
|
||||
auto &page_table = process->GetPageTable();
|
||||
R_UNLESS(page_table.Contains(process_address, size), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Map. */
|
||||
return das->MapAligned(std::addressof(page_table), KProcessAddress(process_address), size, device_address, device_perm);
|
||||
}
|
||||
|
||||
Result UnmapDeviceAddressSpace(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, size_t size, uint64_t device_address) {
|
||||
/* Validate input. */
|
||||
R_UNLESS(util::IsAligned(process_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(device_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||
R_UNLESS((process_address < process_address + size), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS((device_address < device_address + size), svc::ResultInvalidMemoryRegion());
|
||||
R_UNLESS((process_address == static_cast<uintptr_t>(process_address)), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Get the device address space. */
|
||||
KScopedAutoObject das = GetCurrentProcess().GetHandleTable().GetObject<KDeviceAddressSpace>(das_handle);
|
||||
R_UNLESS(das.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Get the process. */
|
||||
KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject<KProcess>(process_handle);
|
||||
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
||||
|
||||
/* Validate that the process address is within range. */
|
||||
auto &page_table = process->GetPageTable();
|
||||
R_UNLESS(page_table.Contains(process_address, size), svc::ResultInvalidCurrentMemory());
|
||||
|
||||
return das->Unmap(std::addressof(page_table), KProcessAddress(process_address), size, device_address);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ============================= 64 ABI ============================= */
|
||||
|
@ -79,19 +176,21 @@ namespace ams::kern::svc {
|
|||
}
|
||||
|
||||
Result MapDeviceAddressSpaceByForce64(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcMapDeviceAddressSpaceByForce64 was called.");
|
||||
size_t dummy_map_size;
|
||||
return MapDeviceAddressSpace(std::addressof(dummy_map_size), das_handle, process_handle, process_address, size, device_address, device_perm, false);
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpaceAligned64(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcMapDeviceAddressSpaceAligned64 was called.");
|
||||
return MapDeviceAddressSpaceAligned(das_handle, process_handle, process_address, size, device_address, device_perm);
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpace64(ams::svc::Size *out_mapped_size, ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcMapDeviceAddressSpace64 was called.");
|
||||
static_assert(sizeof(*out_mapped_size) == sizeof(size_t));
|
||||
return MapDeviceAddressSpace(reinterpret_cast<size_t *>(out_mapped_size), das_handle, process_handle, process_address, size, device_address, device_perm, true);
|
||||
}
|
||||
|
||||
Result UnmapDeviceAddressSpace64(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcUnmapDeviceAddressSpace64 was called.");
|
||||
return UnmapDeviceAddressSpace(das_handle, process_handle, process_address, size, device_address);
|
||||
}
|
||||
|
||||
/* ============================= 64From32 ABI ============================= */
|
||||
|
@ -109,19 +208,21 @@ namespace ams::kern::svc {
|
|||
}
|
||||
|
||||
Result MapDeviceAddressSpaceByForce64From32(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcMapDeviceAddressSpaceByForce64From32 was called.");
|
||||
size_t dummy_map_size;
|
||||
return MapDeviceAddressSpace(std::addressof(dummy_map_size), das_handle, process_handle, process_address, size, device_address, device_perm, false);
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpaceAligned64From32(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcMapDeviceAddressSpaceAligned64From32 was called.");
|
||||
return MapDeviceAddressSpaceAligned(das_handle, process_handle, process_address, size, device_address, device_perm);
|
||||
}
|
||||
|
||||
Result MapDeviceAddressSpace64From32(ams::svc::Size *out_mapped_size, ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address, ams::svc::MemoryPermission device_perm) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcMapDeviceAddressSpace64From32 was called.");
|
||||
static_assert(sizeof(*out_mapped_size) == sizeof(size_t));
|
||||
return MapDeviceAddressSpace(reinterpret_cast<size_t *>(out_mapped_size), das_handle, process_handle, process_address, size, device_address, device_perm, true);
|
||||
}
|
||||
|
||||
Result UnmapDeviceAddressSpace64From32(ams::svc::Handle das_handle, ams::svc::Handle process_handle, uint64_t process_address, ams::svc::Size size, uint64_t device_address) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcUnmapDeviceAddressSpace64From32 was called.");
|
||||
return UnmapDeviceAddressSpace(das_handle, process_handle, process_address, size, device_address);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ namespace ams::kern::svc {
|
|||
namespace {
|
||||
|
||||
Result ReadWriteRegister(uint32_t *out, ams::svc::PhysicalAddress address, uint32_t mask, uint32_t value) {
|
||||
/* Clear the output unconditionally. */
|
||||
*out = 0;
|
||||
|
||||
/* Read/write the register. */
|
||||
return KSystemControl::ReadWriteRegister(out, address, mask, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ams::svc {
|
|||
R_DEFINE_ERROR_RESULT(OutOfHandles, 105);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCurrentMemory, 106);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidNewMemoryPermissions, 108);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNewMemoryPermission, 108);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidMemoryRegion, 110);
|
||||
|
||||
|
|
Loading…
Reference in a new issue