summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2019-03-24 16:00:23 -0400
committerGravatar GitHub2019-03-24 16:00:23 -0400
commit3f74518e19331f1344960ae522c7439446febcd0 (patch)
treeabe0a23c3aa974ca3ada91c384b9c757f102c9a6 /src/core/hle/kernel/svc.cpp
parentMerge pull request #2221 from DarkLordZach/firmware-version (diff)
parentcore/hle/kernel/svc: Implement svcUnmapTransferMemory (diff)
downloadyuzu-3f74518e19331f1344960ae522c7439446febcd0.tar.gz
yuzu-3f74518e19331f1344960ae522c7439446febcd0.tar.xz
yuzu-3f74518e19331f1344960ae522c7439446febcd0.zip
Merge pull request #2232 from lioncash/transfer-memory
core/hle/kernel: Split transfer memory handling out into its own class
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp120
1 files changed, 114 insertions, 6 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index a6a17efe7..e5e7f99e1 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -32,6 +32,7 @@
32#include "core/hle/kernel/svc.h" 32#include "core/hle/kernel/svc.h"
33#include "core/hle/kernel/svc_wrap.h" 33#include "core/hle/kernel/svc_wrap.h"
34#include "core/hle/kernel/thread.h" 34#include "core/hle/kernel/thread.h"
35#include "core/hle/kernel/transfer_memory.h"
35#include "core/hle/kernel/writable_event.h" 36#include "core/hle/kernel/writable_event.h"
36#include "core/hle/lock.h" 37#include "core/hle/lock.h"
37#include "core/hle/result.h" 38#include "core/hle/result.h"
@@ -1586,14 +1587,121 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1586 } 1587 }
1587 1588
1588 auto& kernel = Core::System::GetInstance().Kernel(); 1589 auto& kernel = Core::System::GetInstance().Kernel();
1589 auto process = kernel.CurrentProcess(); 1590 auto transfer_mem_handle = TransferMemory::Create(kernel, addr, size, perms);
1590 auto& handle_table = process->GetHandleTable();
1591 const auto shared_mem_handle = SharedMemory::Create(kernel, process, size, perms, perms, addr);
1592 1591
1593 CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle)); 1592 auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
1593 const auto result = handle_table.Create(std::move(transfer_mem_handle));
1594 if (result.Failed()) {
1595 return result.Code();
1596 }
1597
1598 *handle = *result;
1594 return RESULT_SUCCESS; 1599 return RESULT_SUCCESS;
1595} 1600}
1596 1601
1602static ResultCode MapTransferMemory(Handle handle, VAddr address, u64 size, u32 permission_raw) {
1603 LOG_DEBUG(Kernel_SVC,
1604 "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}, permissions=0x{:08X}",
1605 handle, address, size, permission_raw);
1606
1607 if (!Common::Is4KBAligned(address)) {
1608 LOG_ERROR(Kernel_SVC, "Transfer memory addresses must be 4KB aligned (size=0x{:016X}).",
1609 address);
1610 return ERR_INVALID_ADDRESS;
1611 }
1612
1613 if (size == 0 || !Common::Is4KBAligned(size)) {
1614 LOG_ERROR(Kernel_SVC,
1615 "Transfer memory sizes must be 4KB aligned and not be zero (size=0x{:016X}).",
1616 size);
1617 return ERR_INVALID_SIZE;
1618 }
1619
1620 if (!IsValidAddressRange(address, size)) {
1621 LOG_ERROR(Kernel_SVC,
1622 "Given address and size overflows the 64-bit range (address=0x{:016X}, "
1623 "size=0x{:016X}).",
1624 address, size);
1625 return ERR_INVALID_ADDRESS_STATE;
1626 }
1627
1628 const auto permissions = static_cast<MemoryPermission>(permission_raw);
1629 if (permissions != MemoryPermission::None && permissions != MemoryPermission::Read &&
1630 permissions != MemoryPermission::ReadWrite) {
1631 LOG_ERROR(Kernel_SVC, "Invalid transfer memory permissions given (permissions=0x{:08X}).",
1632 permission_raw);
1633 return ERR_INVALID_STATE;
1634 }
1635
1636 const auto& kernel = Core::System::GetInstance().Kernel();
1637 const auto* const current_process = kernel.CurrentProcess();
1638 const auto& handle_table = current_process->GetHandleTable();
1639
1640 auto transfer_memory = handle_table.Get<TransferMemory>(handle);
1641 if (!transfer_memory) {
1642 LOG_ERROR(Kernel_SVC, "Nonexistent transfer memory handle given (handle=0x{:08X}).",
1643 handle);
1644 return ERR_INVALID_HANDLE;
1645 }
1646
1647 if (!current_process->VMManager().IsWithinASLRRegion(address, size)) {
1648 LOG_ERROR(Kernel_SVC,
1649 "Given address and size don't fully fit within the ASLR region "
1650 "(address=0x{:016X}, size=0x{:016X}).",
1651 address, size);
1652 return ERR_INVALID_MEMORY_RANGE;
1653 }
1654
1655 return transfer_memory->MapMemory(address, size, permissions);
1656}
1657
1658static ResultCode UnmapTransferMemory(Handle handle, VAddr address, u64 size) {
1659 LOG_DEBUG(Kernel_SVC, "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}", handle,
1660 address, size);
1661
1662 if (!Common::Is4KBAligned(address)) {
1663 LOG_ERROR(Kernel_SVC, "Transfer memory addresses must be 4KB aligned (size=0x{:016X}).",
1664 address);
1665 return ERR_INVALID_ADDRESS;
1666 }
1667
1668 if (size == 0 || !Common::Is4KBAligned(size)) {
1669 LOG_ERROR(Kernel_SVC,
1670 "Transfer memory sizes must be 4KB aligned and not be zero (size=0x{:016X}).",
1671 size);
1672 return ERR_INVALID_SIZE;
1673 }
1674
1675 if (!IsValidAddressRange(address, size)) {
1676 LOG_ERROR(Kernel_SVC,
1677 "Given address and size overflows the 64-bit range (address=0x{:016X}, "
1678 "size=0x{:016X}).",
1679 address, size);
1680 return ERR_INVALID_ADDRESS_STATE;
1681 }
1682
1683 const auto& kernel = Core::System::GetInstance().Kernel();
1684 const auto* const current_process = kernel.CurrentProcess();
1685 const auto& handle_table = current_process->GetHandleTable();
1686
1687 auto transfer_memory = handle_table.Get<TransferMemory>(handle);
1688 if (!transfer_memory) {
1689 LOG_ERROR(Kernel_SVC, "Nonexistent transfer memory handle given (handle=0x{:08X}).",
1690 handle);
1691 return ERR_INVALID_HANDLE;
1692 }
1693
1694 if (!current_process->VMManager().IsWithinASLRRegion(address, size)) {
1695 LOG_ERROR(Kernel_SVC,
1696 "Given address and size don't fully fit within the ASLR region "
1697 "(address=0x{:016X}, size=0x{:016X}).",
1698 address, size);
1699 return ERR_INVALID_MEMORY_RANGE;
1700 }
1701
1702 return transfer_memory->UnmapMemory(address, size);
1703}
1704
1597static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { 1705static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) {
1598 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); 1706 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
1599 1707
@@ -1969,8 +2077,8 @@ static const FunctionDef SVC_Table[] = {
1969 {0x4E, nullptr, "ReadWriteRegister"}, 2077 {0x4E, nullptr, "ReadWriteRegister"},
1970 {0x4F, nullptr, "SetProcessActivity"}, 2078 {0x4F, nullptr, "SetProcessActivity"},
1971 {0x50, SvcWrap<CreateSharedMemory>, "CreateSharedMemory"}, 2079 {0x50, SvcWrap<CreateSharedMemory>, "CreateSharedMemory"},
1972 {0x51, nullptr, "MapTransferMemory"}, 2080 {0x51, SvcWrap<MapTransferMemory>, "MapTransferMemory"},
1973 {0x52, nullptr, "UnmapTransferMemory"}, 2081 {0x52, SvcWrap<UnmapTransferMemory>, "UnmapTransferMemory"},
1974 {0x53, nullptr, "CreateInterruptEvent"}, 2082 {0x53, nullptr, "CreateInterruptEvent"},
1975 {0x54, nullptr, "QueryPhysicalAddress"}, 2083 {0x54, nullptr, "QueryPhysicalAddress"},
1976 {0x55, nullptr, "QueryIoMapping"}, 2084 {0x55, nullptr, "QueryIoMapping"},