summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp2
-rw-r--r--src/core/core.cpp5
-rw-r--r--src/core/core.h11
-rw-r--r--src/core/gdbstub/gdbstub.cpp10
-rw-r--r--src/core/hle/kernel/client_port.cpp12
-rw-r--r--src/core/hle/kernel/client_port.h14
-rw-r--r--src/core/hle/kernel/server_session.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h1
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp2
-rw-r--r--src/core/hle/service/nvdrv/interface.h1
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp2
-rw-r--r--src/core/hle/service/nvdrv/nvmemp.cpp2
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp5
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h8
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp4
-rw-r--r--src/core/hle/service/usb/usb.cpp238
-rw-r--r--src/core/hle/service/usb/usb.h15
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp11
-rw-r--r--src/core/loader/deconstructed_rom_directory.h4
-rw-r--r--src/core/loader/nca.cpp44
-rw-r--r--src/core/loader/nca.h2
31 files changed, 358 insertions, 67 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index c11f017da..0abf7edc1 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -315,6 +315,8 @@ add_library(core STATIC
hle/service/time/interface.h
hle/service/time/time.cpp
hle/service/time/time.h
+ hle/service/usb/usb.cpp
+ hle/service/usb/usb.h
hle/service/vi/vi.cpp
hle/service/vi/vi.h
hle/service/vi/vi_m.cpp
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 4c11f35a4..6bc349460 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -203,7 +203,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
}
Kernel::Thread* thread = Kernel::GetCurrentThread();
SaveContext(thread->context);
- if (last_bkpt_hit || (num_instructions == 1)) {
+ if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) {
last_bkpt_hit = false;
GDBStub::Break();
GDBStub::SendTrap(thread, 5);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index e01c45cdd..085ba68d0 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -62,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
// execute. Otherwise, get out of the loop function.
if (GDBStub::GetCpuHaltFlag()) {
if (GDBStub::GetCpuStepFlag()) {
- GDBStub::SetCpuStepFlag(false);
tight_loop = false;
} else {
return ResultStatus::Success;
@@ -78,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
}
}
+ if (GDBStub::IsServerEnabled()) {
+ GDBStub::SetCpuStepFlag(false);
+ }
+
return status;
}
diff --git a/src/core/core.h b/src/core/core.h
index a3be88aa8..c8ca4b247 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -82,6 +82,17 @@ public:
*/
ResultStatus SingleStep();
+ /**
+ * Invalidate the CPU instruction caches
+ * This function should only be used by GDB Stub to support breakpoints, memory updates and
+ * step/continue commands.
+ */
+ void InvalidateCpuInstructionCaches() {
+ for (auto& cpu : cpu_cores) {
+ cpu->ArmInterface().ClearInstructionCache();
+ }
+ }
+
/// Shutdown the emulated system.
void Shutdown();
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 884e64e99..332e5c3d0 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -173,6 +173,7 @@ struct Breakpoint {
bool active;
VAddr addr;
u64 len;
+ std::array<u8, 4> inst;
};
using BreakpointMap = std::map<VAddr, Breakpoint>;
@@ -453,6 +454,8 @@ static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
bp->second.len, bp->second.addr, static_cast<int>(type));
+ Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size());
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
p.erase(addr);
}
@@ -937,6 +940,7 @@ static void WriteMemory() {
GdbHexToMem(data.data(), len_pos + 1, len);
Memory::WriteBlock(addr, data.data(), len);
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
SendReply("OK");
}
@@ -956,6 +960,7 @@ static void Step() {
step_loop = true;
halt_loop = true;
send_trap = true;
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
}
/// Tell the CPU if we hit a memory breakpoint.
@@ -972,6 +977,7 @@ static void Continue() {
memory_break = false;
step_loop = false;
halt_loop = false;
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
}
/**
@@ -988,6 +994,10 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
breakpoint.active = true;
breakpoint.addr = addr;
breakpoint.len = len;
+ Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
+ static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}};
+ Memory::WriteBlock(addr, btrap.data(), btrap.size());
+ Core::System::GetInstance().InvalidateCpuInstructionCaches();
p.insert({addr, breakpoint});
LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
index 7933c105c..134e41ebc 100644
--- a/src/core/hle/kernel/client_port.cpp
+++ b/src/core/hle/kernel/client_port.cpp
@@ -14,8 +14,8 @@
namespace Kernel {
-ClientPort::ClientPort() {}
-ClientPort::~ClientPort() {}
+ClientPort::ClientPort() = default;
+ClientPort::~ClientPort() = default;
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
// Note: Threads do not wait for the server endpoint to call
@@ -40,4 +40,12 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
return MakeResult(std::get<SharedPtr<ClientSession>>(sessions));
}
+void ClientPort::ConnectionClosed() {
+ if (active_sessions == 0) {
+ return;
+ }
+
+ --active_sessions;
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index b42c94bde..b1269ea5c 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -37,14 +37,20 @@ public:
*/
ResultVal<SharedPtr<ClientSession>> Connect();
- SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
- u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have
- u32 active_sessions; ///< Number of currently open sessions to this port
- std::string name; ///< Name of client port (optional)
+ /**
+ * Signifies that a previously active connection has been closed,
+ * decreasing the total number of active connections to this port.
+ */
+ void ConnectionClosed();
private:
ClientPort();
~ClientPort() override;
+
+ SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
+ u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
+ u32 active_sessions = 0; ///< Number of currently open sessions to this port
+ std::string name; ///< Name of client port (optional)
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 60370e9ec..93560152f 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -27,7 +27,7 @@ ServerSession::~ServerSession() {
// Decrease the port's connection count.
if (parent->port)
- parent->port->active_sessions--;
+ parent->port->ConnectionClosed();
// TODO(Subv): Wake up all the ClientSession's waiting threads and set
// the SendSyncRequest result to 0xC920181A.
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 2b74e6a33..8bc49935a 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -7,8 +7,8 @@
#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
+#include "video_core/gpu.h"
#include "video_core/renderer_base.h"
-#include "video_core/video_core.h"
namespace Service::Nvidia::Devices {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 4b601781f..be2b79256 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -2,14 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cinttypes>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
+#include "video_core/memory_manager.h"
+#include "video_core/rasterizer_interface.h"
#include "video_core/renderer_base.h"
-#include "video_core/video_core.h"
namespace Service::Nvidia::Devices {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 671b092e1..5685eb2be 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cstdlib>
+#include <cstring>
+
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 090261a60..6b496e9fe 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -5,8 +5,6 @@
#pragma once
#include <array>
-#include <cstdlib>
-#include <cstring>
#include <vector>
#include "common/common_types.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 010072a5b..ae421247d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cinttypes>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 5a1123ad2..116dabedb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -2,12 +2,14 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cinttypes>
-#include <map>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
+#include "core/memory.h"
+#include "video_core/gpu.h"
+#include "video_core/memory_manager.h"
namespace Service::Nvidia::Devices {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index aa8df2e6e..650ed8fbc 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -6,6 +6,7 @@
#include <memory>
#include <vector>
+#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index b51c73ee8..364619e67 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cstring>
+
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 0192aecdd..6ad74421b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -4,11 +4,9 @@
#pragma once
-#include <array>
-#include <cstdlib>
-#include <cstring>
#include <vector>
#include "common/common_types.h"
+#include "common/swap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
namespace Service::Nvidia::Devices {
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 724eeb139..e9305bfb3 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -3,7 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
-#include <cinttypes>
+#include <cstring>
#include "common/assert.h"
#include "common/logging/log.h"
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index 959b5ba29..1c3529bb6 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -5,7 +5,6 @@
#pragma once
#include <memory>
-#include <string>
#include "core/hle/kernel/event.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/service.h"
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 1555ea806..e8b30921a 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -54,7 +54,7 @@ u32 Module::Open(const std::string& device_name) {
return fd;
}
-u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vector<u8>& output) {
+u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) {
auto itr = open_files.find(fd);
ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp
index 9ca6e5512..0e8e21bad 100644
--- a/src/core/hle/service/nvdrv/nvmemp.cpp
+++ b/src/core/hle/service/nvdrv/nvmemp.cpp
@@ -4,8 +4,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
-#include "core/hle/ipc_helpers.h"
-#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvdrv/nvmemp.h"
namespace Service::Nvidia {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 0bf51062c..1e287ab62 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -3,8 +3,11 @@
// Refer to the license.txt file included.
#include <algorithm>
+#include <boost/optional.hpp>
#include "common/alignment.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "core/core.h"
@@ -43,7 +46,7 @@ NVFlinger::~NVFlinger() {
CoreTiming::UnscheduleEvent(composition_event, 0);
}
-u64 NVFlinger::OpenDisplay(const std::string& name) {
+u64 NVFlinger::OpenDisplay(std::string_view name) {
LOG_WARNING(Service, "Opening display {}", name);
// TODO(Subv): Currently we only support the Default display.
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 2c908297b..5374df175 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -5,7 +5,11 @@
#pragma once
#include <memory>
-#include <boost/optional.hpp>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "common/common_types.h"
#include "core/hle/kernel/event.h"
namespace CoreTiming {
@@ -41,7 +45,7 @@ public:
~NVFlinger();
/// Opens the specified display and returns the id.
- u64 OpenDisplay(const std::string& name);
+ u64 OpenDisplay(std::string_view name);
/// Creates a layer on the specified display and returns the layer id.
u64 CreateLayer(u64 display_id);
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 31ea79773..889cdd41a 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -63,6 +63,7 @@
#include "core/hle/service/spl/module.h"
#include "core/hle/service/ssl/ssl.h"
#include "core/hle/service/time/time.h"
+#include "core/hle/service/usb/usb.h"
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/wlan/wlan.h"
@@ -249,6 +250,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
SPL::InstallInterfaces(*sm);
SSL::InstallInterfaces(*sm);
Time::InstallInterfaces(*sm);
+ USB::InstallInterfaces(*sm);
VI::InstallInterfaces(*sm, nv_flinger);
WLAN::InstallInterfaces(*sm);
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 37b58bb77..2172c681b 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -80,8 +80,8 @@ public:
{5, nullptr, "GetTimeZoneRuleVersion"},
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
- {200, nullptr, "ToPosixTime"},
- {201, nullptr, "ToPosixTimeWithMyRule"},
+ {201, nullptr, "ToPosixTime"},
+ {202, nullptr, "ToPosixTimeWithMyRule"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
new file mode 100644
index 000000000..e7fb5a419
--- /dev/null
+++ b/src/core/hle/service/usb/usb.cpp
@@ -0,0 +1,238 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/sm/sm.h"
+#include "core/hle/service/usb/usb.h"
+
+namespace Service::USB {
+
+class IDsInterface final : public ServiceFramework<IDsInterface> {
+public:
+ explicit IDsInterface() : ServiceFramework{"IDsInterface"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetDsEndpoint"},
+ {1, nullptr, "GetSetupEvent"},
+ {2, nullptr, "Unknown"},
+ {3, nullptr, "EnableInterface"},
+ {4, nullptr, "DisableInterface"},
+ {5, nullptr, "CtrlInPostBufferAsync"},
+ {6, nullptr, "CtrlOutPostBufferAsync"},
+ {7, nullptr, "GetCtrlInCompletionEvent"},
+ {8, nullptr, "GetCtrlInReportData"},
+ {9, nullptr, "GetCtrlOutCompletionEvent"},
+ {10, nullptr, "GetCtrlOutReportData"},
+ {11, nullptr, "StallCtrl"},
+ {12, nullptr, "AppendConfigurationData"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_DS final : public ServiceFramework<USB_DS> {
+public:
+ explicit USB_DS() : ServiceFramework{"usb:ds"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "BindDevice"},
+ {1, nullptr, "BindClientProcess"},
+ {2, nullptr, "GetDsInterface"},
+ {3, nullptr, "GetStateChangeEvent"},
+ {4, nullptr, "GetState"},
+ {5, nullptr, "ClearDeviceData"},
+ {6, nullptr, "AddUsbStringDescriptor"},
+ {7, nullptr, "DeleteUsbStringDescriptor"},
+ {8, nullptr, "SetUsbDeviceDescriptor"},
+ {9, nullptr, "SetBinaryObjectStore"},
+ {10, nullptr, "Enable"},
+ {11, nullptr, "Disable"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IClientEpSession final : public ServiceFramework<IClientEpSession> {
+public:
+ explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "PostBufferAsync"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "Unknown7"},
+ {8, nullptr, "Unknown8"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IClientIfSession final : public ServiceFramework<IClientIfSession> {
+public:
+ explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "CtrlXferAsync"},
+ {6, nullptr, "Unknown6"},
+ {7, nullptr, "GetCtrlXferReport"},
+ {8, nullptr, "Unknown7"},
+ {9, nullptr, "GetClientEpSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_HS final : public ServiceFramework<USB_HS> {
+public:
+ explicit USB_HS() : ServiceFramework{"usb:hs"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "BindClientProcess"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "Unknown2"},
+ {3, nullptr, "Unknown3"},
+ {4, nullptr, "Unknown4"},
+ {5, nullptr, "Unknown5"},
+ {6, nullptr, "GetInterfaceStateChangeEvent"},
+ {7, nullptr, "GetClientIfSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class IPdSession final : public ServiceFramework<IPdSession> {
+public:
+ explicit IPdSession() : ServiceFramework{"IPdSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "BindNoticeEvent"},
+ {1, nullptr, "Unknown1"},
+ {2, nullptr, "GetStatus"},
+ {3, nullptr, "GetNotice"},
+ {4, nullptr, "Unknown2"},
+ {5, nullptr, "Unknown3"},
+ {6, nullptr, "ReplyPowerRequest"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_PD final : public ServiceFramework<USB_PD> {
+public:
+ explicit USB_PD() : ServiceFramework{"usb:pd"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &USB_PD::GetPdSession, "GetPdSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetPdSession(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IPdSession>();
+
+ LOG_DEBUG(Service_USB, "called");
+ }
+};
+
+class IPdCradleSession final : public ServiceFramework<IPdCradleSession> {
+public:
+ explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "VdmUserWrite"},
+ {1, nullptr, "VdmUserRead"},
+ {2, nullptr, "Vdm20Init"},
+ {3, nullptr, "GetFwType"},
+ {4, nullptr, "GetFwRevision"},
+ {5, nullptr, "GetManufacturerId"},
+ {6, nullptr, "GetDeviceId"},
+ {7, nullptr, "Unknown1"},
+ {8, nullptr, "Unknown2"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+class USB_PD_C final : public ServiceFramework<USB_PD_C> {
+public:
+ explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void GetPdCradleSession(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IPdCradleSession>();
+
+ LOG_DEBUG(Service_USB, "called");
+ }
+};
+
+class USB_PM final : public ServiceFramework<USB_PM> {
+public:
+ explicit USB_PM() : ServiceFramework{"usb:pm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Unknown1"},
+ {1, nullptr, "Unknown2"},
+ {2, nullptr, "Unknown3"},
+ {3, nullptr, "Unknown4"},
+ {4, nullptr, "Unknown5"},
+ {5, nullptr, "Unknown6"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+};
+
+void InstallInterfaces(SM::ServiceManager& sm) {
+ std::make_shared<USB_DS>()->InstallAsService(sm);
+ std::make_shared<USB_HS>()->InstallAsService(sm);
+ std::make_shared<USB_PD>()->InstallAsService(sm);
+ std::make_shared<USB_PD_C>()->InstallAsService(sm);
+ std::make_shared<USB_PM>()->InstallAsService(sm);
+}
+
+} // namespace Service::USB
diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h
new file mode 100644
index 000000000..970a11fe8
--- /dev/null
+++ b/src/core/hle/service/usb/usb.h
@@ -0,0 +1,15 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+namespace Service::SM {
+class ServiceManager;
+}
+
+namespace Service::USB {
+
+void InstallInterfaces(SM::ServiceManager& sm);
+
+} // namespace Service::USB
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index b0277a875..9a8cdd0ff 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -20,6 +20,10 @@ namespace Loader {
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file)
: AppLoader(std::move(file)) {}
+AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
+ FileSys::VirtualDir directory)
+ : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {}
+
FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
return FileType::DeconstructedRomDirectory;
@@ -34,7 +38,12 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
return ResultStatus::ErrorAlreadyLoaded;
}
- const FileSys::VirtualDir dir = file->GetContainingDirectory();
+ if (dir == nullptr) {
+ if (file == nullptr)
+ return ResultStatus::ErrorInvalidFormat;
+ dir = file->GetContainingDirectory();
+ }
+
const FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
if (npdm == nullptr)
return ResultStatus::ErrorInvalidFormat;
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h
index 7319ba6ea..7d5433563 100644
--- a/src/core/loader/deconstructed_rom_directory.h
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -22,6 +22,9 @@ class AppLoader_DeconstructedRomDirectory final : public AppLoader {
public:
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file);
+ // Overload to accept exefs directory. Must contain 'main' and 'main.npdm'
+ explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory);
+
/**
* Returns the type of the file
* @param file std::shared_ptr<VfsFile> open file
@@ -40,6 +43,7 @@ public:
private:
FileSys::ProgramMetadata metadata;
FileSys::VirtualFile romfs;
+ FileSys::VirtualDir dir;
};
} // namespace Loader
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index a1f8235d1..dbc67c0b5 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -22,7 +22,8 @@
namespace Loader {
-AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {}
+AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_)
+ : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {}
FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) {
FileSys::NCA nca(file);
@@ -39,8 +40,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
return ResultStatus::ErrorAlreadyLoaded;
}
- nca = std::make_unique<FileSys::NCA>(file);
- ResultStatus result = nca->GetStatus();
+ const auto result = nca->GetStatus();
if (result != ResultStatus::Success) {
return result;
}
@@ -48,44 +48,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
if (nca->GetType() != FileSys::NCAContentType::Program)
return ResultStatus::ErrorInvalidFormat;
- auto exefs = nca->GetExeFS();
+ const auto exefs = nca->GetExeFS();
if (exefs == nullptr)
return ResultStatus::ErrorInvalidFormat;
- result = metadata.Load(exefs->GetFile("main.npdm"));
- if (result != ResultStatus::Success) {
- return result;
- }
- metadata.Print();
-
- const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
- if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
- return ResultStatus::ErrorUnsupportedArch;
- }
-
- VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
- for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
- "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) {
- const VAddr load_addr = next_load_addr;
-
- next_load_addr = AppLoader_NSO::LoadModule(exefs->GetFile(module), load_addr);
- if (next_load_addr) {
- LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
- // Register module with GDBStub
- GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
- } else {
- next_load_addr = load_addr;
- }
- }
+ directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs);
- process->program_id = metadata.GetTitleID();
- process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
- process->resource_limit =
- Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
- metadata.GetMainThreadStackSize());
+ const auto load_result = directory_loader->Load(process);
+ if (load_result != ResultStatus::Success)
+ return load_result;
if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0)
Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this));
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index e14d618b3..0fd2d0417 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -10,6 +10,7 @@
#include "core/file_sys/program_metadata.h"
#include "core/hle/kernel/object.h"
#include "core/loader/loader.h"
+#include "deconstructed_rom_directory.h"
namespace Loader {
@@ -41,6 +42,7 @@ private:
FileSys::ProgramMetadata metadata;
std::unique_ptr<FileSys::NCA> nca;
+ std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
};
} // namespace Loader