summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/acc/acc.cpp14
-rw-r--r--src/core/hle/service/am/am.cpp57
-rw-r--r--src/core/hle/service/am/am.h5
-rw-r--r--src/core/hle/service/am/applet_ae.h6
-rw-r--r--src/core/hle/service/am/applet_oe.h6
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp19
-rw-r--r--src/core/hle/service/aoc/aoc_u.h5
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp8
-rw-r--r--src/core/hle/service/btdrv/btdrv.h6
-rw-r--r--src/core/hle/service/btm/btm.cpp14
-rw-r--r--src/core/hle/service/btm/btm.h6
-rw-r--r--src/core/hle/service/fatal/fatal.cpp29
-rw-r--r--src/core/hle/service/fatal/fatal.h9
-rw-r--r--src/core/hle/service/fatal/fatal_p.cpp4
-rw-r--r--src/core/hle/service/fatal/fatal_p.h2
-rw-r--r--src/core/hle/service/fatal/fatal_u.cpp3
-rw-r--r--src/core/hle/service/fatal/fatal_u.h2
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp329
-rw-r--r--src/core/hle/service/filesystem/filesystem.h116
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp80
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h4
-rw-r--r--src/core/hle/service/friend/friend.cpp31
-rw-r--r--src/core/hle/service/friend/friend.h9
-rw-r--r--src/core/hle/service/friend/interface.cpp4
-rw-r--r--src/core/hle/service/friend/interface.h2
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h8
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h3
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h3
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h3
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h3
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp26
-rw-r--r--src/core/hle/service/hid/controllers/npad.h8
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.h3
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h3
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h3
-rw-r--r--src/core/hle/service/hid/hid.cpp25
-rw-r--r--src/core/hle/service/hid/hid.h10
-rw-r--r--src/core/hle/service/hid/irs.cpp6
-rw-r--r--src/core/hle/service/hid/irs.h3
-rw-r--r--src/core/hle/service/ldr/ldr.cpp11
-rw-r--r--src/core/hle/service/ldr/ldr.h2
-rw-r--r--src/core/hle/service/nfp/nfp.cpp19
-rw-r--r--src/core/hle/service/nfp/nfp.h5
-rw-r--r--src/core/hle/service/nfp/nfp_user.cpp4
-rw-r--r--src/core/hle/service/nfp/nfp_user.h2
-rw-r--r--src/core/hle/service/nifm/nifm.cpp30
-rw-r--r--src/core/hle/service/nifm/nifm.h6
-rw-r--r--src/core/hle/service/nim/nim.cpp13
-rw-r--r--src/core/hle/service/nim/nim.h6
-rw-r--r--src/core/hle/service/ns/ns.cpp5
-rw-r--r--src/core/hle/service/ns/ns.h13
-rw-r--r--src/core/hle/service/ns/pl_u.cpp11
-rw-r--r--src/core/hle/service/ns/pl_u.h15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp18
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp28
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h5
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp75
-rw-r--r--src/core/hle/service/nvdrv/interface.h3
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h6
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp7
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h5
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp38
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h5
-rw-r--r--src/core/hle/service/prepo/prepo.cpp105
-rw-r--r--src/core/hle/service/prepo/prepo.h6
-rw-r--r--src/core/hle/service/service.cpp27
-rw-r--r--src/core/hle/service/service.h8
-rw-r--r--src/core/hle/service/time/interface.cpp4
-rw-r--r--src/core/hle/service/time/interface.h2
-rw-r--r--src/core/hle/service/time/time.cpp25
-rw-r--r--src/core/hle/service/time/time.h4
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp4
-rw-r--r--src/core/hle/service/vi/display/vi_display.h2
97 files changed, 1066 insertions, 438 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index a7c55e116..0c0f7ed6e 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -70,7 +70,7 @@ public:
protected:
void Get(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_ACC, "called user_id={}", user_id.Format());
+ LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
ProfileBase profile_base{};
ProfileData data{};
if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) {
@@ -89,7 +89,7 @@ protected:
}
void GetBase(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_ACC, "called user_id={}", user_id.Format());
+ LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
ProfileBase profile_base{};
if (profile_manager.GetProfileBase(user_id, profile_base)) {
IPC::ResponseBuilder rb{ctx, 16};
@@ -263,7 +263,7 @@ private:
};
void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_ACC, "called");
+ LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount()));
@@ -272,7 +272,7 @@ void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
Common::UUID user_id = rp.PopRaw<Common::UUID>();
- LOG_INFO(Service_ACC, "called user_id={}", user_id.Format());
+ LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
@@ -280,21 +280,21 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
}
void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_ACC, "called");
+ LOG_DEBUG(Service_ACC, "called");
ctx.WriteBuffer(profile_manager->GetAllUsers());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_ACC, "called");
+ LOG_DEBUG(Service_ACC, "called");
ctx.WriteBuffer(profile_manager->GetOpenUsers());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_ACC, "called");
+ LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser());
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index aa2c83937..797c9a06f 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -232,12 +232,12 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
IDebugFunctions::~IDebugFunctions() = default;
-ISelfController::ISelfController(Core::System& system_,
- std::shared_ptr<NVFlinger::NVFlinger> nvflinger_)
- : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger_)) {
+ISelfController::ISelfController(Core::System& system,
+ std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
+ : ServiceFramework("ISelfController"), system(system), nvflinger(std::move(nvflinger)) {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Exit"},
+ {0, &ISelfController::Exit, "Exit"},
{1, &ISelfController::LockExit, "LockExit"},
{2, &ISelfController::UnlockExit, "UnlockExit"},
{3, &ISelfController::EnterFatalSection, "EnterFatalSection"},
@@ -282,7 +282,7 @@ ISelfController::ISelfController(Core::System& system_,
RegisterHandlers(functions);
- auto& kernel = system_.Kernel();
+ auto& kernel = system.Kernel();
launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
"ISelfController:LaunchableEvent");
@@ -298,15 +298,28 @@ ISelfController::ISelfController(Core::System& system_,
ISelfController::~ISelfController() = default;
+void ISelfController::Exit(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_AM, "called");
+
+ system.Shutdown();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
+
+ system.SetExitLock(true);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
+
+ system.SetExitLock(false);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -550,6 +563,10 @@ void AppletMessageQueue::OperationModeChanged() {
on_operation_mode_changed.writable->Signal();
}
+void AppletMessageQueue::RequestExit() {
+ PushMessage(AppletMessage::ExitRequested);
+}
+
ICommonStateGetter::ICommonStateGetter(Core::System& system,
std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("ICommonStateGetter"), system(system), msg_queue(std::move(msg_queue)) {
@@ -1066,7 +1083,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Manual, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
}
@@ -1143,13 +1160,21 @@ void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- u128 uid = rp.PopRaw<u128>(); // What does this do?
- LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
+ u128 user_id = rp.PopRaw<u128>();
+
+ LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]);
+
+ FileSys::SaveDataDescriptor descriptor{};
+ descriptor.title_id = Core::CurrentProcess()->GetTitleID();
+ descriptor.user_id = user_id;
+ descriptor.type = FileSys::SaveDataType::SaveData;
+ const auto res = system.GetFileSystemController().CreateSaveData(
+ FileSys::SaveDataSpaceId::NandUser, descriptor);
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(RESULT_SUCCESS);
+ rb.Push(res.Code());
rb.Push<u64>(0);
-} // namespace Service::AM
+}
void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
// Takes an input u32 Result, no output.
@@ -1261,8 +1286,8 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
"new_journal={:016X}",
static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size);
- const auto title_id = system.CurrentProcess()->GetTitleID();
- FileSystem::WriteSaveDataSize(type, title_id, user_id, {new_normal_size, new_journal_size});
+ system.GetFileSystemController().WriteSaveDataSize(
+ type, system.CurrentProcess()->GetTitleID(), user_id, {new_normal_size, new_journal_size});
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
@@ -1281,8 +1306,8 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast<u8>(type),
user_id[1], user_id[0]);
- const auto title_id = system.CurrentProcess()->GetTitleID();
- const auto size = FileSystem::ReadSaveDataSize(type, title_id, user_id);
+ const auto size = system.GetFileSystemController().ReadSaveDataSize(
+ type, system.CurrentProcess()->GetTitleID(), user_id);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 28f870302..a3baeb673 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -45,6 +45,7 @@ class AppletMessageQueue {
public:
enum class AppletMessage : u32 {
NoMessage = 0,
+ ExitRequested = 4,
FocusStateChanged = 15,
OperationModeChanged = 30,
PerformanceModeChanged = 31,
@@ -59,6 +60,7 @@ public:
AppletMessage PopMessage();
std::size_t GetMessageCount() const;
void OperationModeChanged();
+ void RequestExit();
private:
std::queue<AppletMessage> messages;
@@ -123,6 +125,7 @@ public:
~ISelfController() override;
private:
+ void Exit(Kernel::HLERequestContext& ctx);
void LockExit(Kernel::HLERequestContext& ctx);
void UnlockExit(Kernel::HLERequestContext& ctx);
void EnterFatalSection(Kernel::HLERequestContext& ctx);
@@ -151,6 +154,8 @@ private:
u32 idle_time_detection_extension = 0;
u64 num_fatal_sections_entered = 0;
bool is_auto_sleep_disabled = false;
+
+ Core::System& system;
};
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
index 9e006cd9d..2e3e45915 100644
--- a/src/core/hle/service/am/applet_ae.h
+++ b/src/core/hle/service/am/applet_ae.h
@@ -9,12 +9,18 @@
#include "core/hle/service/service.h"
namespace Service {
+namespace FileSystem {
+class FileSystemController;
+}
+
namespace NVFlinger {
class NVFlinger;
}
namespace AM {
+class AppletMessageQueue;
+
class AppletAE final : public ServiceFramework<AppletAE> {
public:
explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 22c05419d..758da792d 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -9,12 +9,18 @@
#include "core/hle/service/service.h"
namespace Service {
+namespace FileSystem {
+class FileSystemController;
+}
+
namespace NVFlinger {
class NVFlinger;
}
namespace AM {
+class AppletMessageQueue;
+
class AppletOE final : public ServiceFramework<AppletOE> {
public:
explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index d3e97776b..e9cf1e840 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -29,9 +29,9 @@ static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) {
return (title_id & DLC_BASE_TITLE_ID_MASK) == base;
}
-static std::vector<u64> AccumulateAOCTitleIDs() {
+static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
std::vector<u64> add_on_content;
- const auto& rcu = Core::System::GetInstance().GetContentProvider();
+ const auto& rcu = system.GetContentProvider();
const auto list =
rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
std::transform(list.begin(), list.end(), std::back_inserter(add_on_content),
@@ -47,7 +47,8 @@ static std::vector<u64> AccumulateAOCTitleIDs() {
return add_on_content;
}
-AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs()) {
+AOC_U::AOC_U(Core::System& system)
+ : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs(system)), system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CountAddOnContentByApplicationId"},
@@ -65,7 +66,7 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
"GetAddOnContentListChanged:Event");
}
@@ -86,7 +87,7 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- const auto current = Core::System::GetInstance().CurrentProcess()->GetTitleID();
+ const auto current = system.CurrentProcess()->GetTitleID();
const auto& disabled = Settings::values.disabled_addons[current];
if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) {
@@ -113,7 +114,7 @@ void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count,
process_id);
- const auto current = Core::System::GetInstance().CurrentProcess()->GetTitleID();
+ const auto current = system.CurrentProcess()->GetTitleID();
std::vector<u32> out;
const auto& disabled = Settings::values.disabled_addons[current];
@@ -159,7 +160,7 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- const auto title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
+ const auto title_id = system.CurrentProcess()->GetTitleID();
FileSys::PatchManager pm{title_id};
const auto res = pm.GetControlMetadata();
@@ -196,8 +197,8 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
rb.PushCopyObjects(aoc_change_event.readable);
}
-void InstallInterfaces(SM::ServiceManager& service_manager) {
- std::make_shared<AOC_U>()->InstallAsService(service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
+ std::make_shared<AOC_U>(system)->InstallAsService(service_manager);
}
} // namespace Service::AOC
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index 5effea730..848b2f416 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -14,7 +14,7 @@ namespace Service::AOC {
class AOC_U final : public ServiceFramework<AOC_U> {
public:
- AOC_U();
+ explicit AOC_U(Core::System& system);
~AOC_U() override;
private:
@@ -26,9 +26,10 @@ private:
std::vector<u64> add_on_content;
Kernel::EventPair aoc_change_event;
+ Core::System& system;
};
/// Registers all AOC services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::AOC
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index 3c7ca2c44..afce581e5 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -16,7 +16,7 @@ namespace Service::BtDrv {
class Bt final : public ServiceFramework<Bt> {
public:
- explicit Bt() : ServiceFramework{"bt"} {
+ explicit Bt(Core::System& system) : ServiceFramework{"bt"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "LeClientReadCharacteristic"},
@@ -33,7 +33,7 @@ public:
// clang-format on
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
register_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic, "BT:RegisterEvent");
}
@@ -163,9 +163,9 @@ public:
}
};
-void InstallInterfaces(SM::ServiceManager& sm) {
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
std::make_shared<BtDrv>()->InstallAsService(sm);
- std::make_shared<Bt>()->InstallAsService(sm);
+ std::make_shared<Bt>(system)->InstallAsService(sm);
}
} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h
index 164e56f43..191410dbc 100644
--- a/src/core/hle/service/btdrv/btdrv.h
+++ b/src/core/hle/service/btdrv/btdrv.h
@@ -8,9 +8,13 @@ namespace Service::SM {
class ServiceManager;
}
+namespace Core {
+class System;
+}
+
namespace Service::BtDrv {
/// Registers all BtDrv services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& sm);
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index b439ee7ec..920fc6ff7 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -17,7 +17,7 @@ namespace Service::BTM {
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
public:
- explicit IBtmUserCore() : ServiceFramework{"IBtmUserCore"} {
+ explicit IBtmUserCore(Core::System& system) : ServiceFramework{"IBtmUserCore"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
@@ -56,7 +56,7 @@ public:
// clang-format on
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
"IBtmUserCore:ScanEvent");
connection_event = Kernel::WritableEvent::CreateEventPair(
@@ -108,7 +108,7 @@ private:
class BTM_USR final : public ServiceFramework<BTM_USR> {
public:
- explicit BTM_USR() : ServiceFramework{"btm:u"} {
+ explicit BTM_USR(Core::System& system) : ServiceFramework{"btm:u"}, system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BTM_USR::GetCore, "GetCore"},
@@ -123,8 +123,10 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IBtmUserCore>();
+ rb.PushIpcInterface<IBtmUserCore>(system);
}
+
+ Core::System& system;
};
class BTM final : public ServiceFramework<BTM> {
@@ -268,11 +270,11 @@ private:
}
};
-void InstallInterfaces(SM::ServiceManager& sm) {
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
std::make_shared<BTM>()->InstallAsService(sm);
std::make_shared<BTM_DBG>()->InstallAsService(sm);
std::make_shared<BTM_SYS>()->InstallAsService(sm);
- std::make_shared<BTM_USR>()->InstallAsService(sm);
+ std::make_shared<BTM_USR>(system)->InstallAsService(sm);
}
} // namespace Service::BTM
diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h
index e6425a7e3..c6b878043 100644
--- a/src/core/hle/service/btm/btm.h
+++ b/src/core/hle/service/btm/btm.h
@@ -8,8 +8,12 @@ namespace Service::SM {
class ServiceManager;
}
+namespace Core {
+class System;
+};
+
namespace Service::BTM {
-void InstallInterfaces(SM::ServiceManager& sm);
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
} // namespace Service::BTM
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index 01fa06ad3..b2ebf6240 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -20,8 +20,8 @@
namespace Service::Fatal {
-Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
- : ServiceFramework(name), module(std::move(module)) {}
+Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
+ : ServiceFramework(name), module(std::move(module)), system(system) {}
Module::Interface::~Interface() = default;
@@ -64,7 +64,8 @@ enum class FatalType : u32 {
ErrorScreen = 2,
};
-static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) {
+static void GenerateErrorReport(Core::System& system, ResultCode error_code,
+ const FatalInfo& info) {
const auto title_id = Core::CurrentProcess()->GetTitleID();
std::string crash_report = fmt::format(
"Yuzu {}-{} crash report\n"
@@ -101,18 +102,19 @@ static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) {
LOG_ERROR(Service_Fatal, "{}", crash_report);
- Core::System::GetInstance().GetReporter().SaveCrashReport(
+ system.GetReporter().SaveCrashReport(
title_id, error_code, info.set_flags, info.program_entry_point, info.sp, info.pc,
info.pstate, info.afsr0, info.afsr1, info.esr, info.far, info.registers, info.backtrace,
info.backtrace_size, info.ArchAsString(), info.unk10);
}
-static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) {
+static void ThrowFatalError(Core::System& system, ResultCode error_code, FatalType fatal_type,
+ const FatalInfo& info) {
LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}",
static_cast<u32>(fatal_type), error_code.raw);
switch (fatal_type) {
case FatalType::ErrorReportAndScreen:
- GenerateErrorReport(error_code, info);
+ GenerateErrorReport(system, error_code, info);
[[fallthrough]];
case FatalType::ErrorScreen:
// Since we have no fatal:u error screen. We should just kill execution instead
@@ -120,7 +122,7 @@ static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const F
break;
// Should not throw a fatal screen but should generate an error report
case FatalType::ErrorReport:
- GenerateErrorReport(error_code, info);
+ GenerateErrorReport(system, error_code, info);
break;
}
}
@@ -130,7 +132,7 @@ void Module::Interface::ThrowFatal(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto error_code = rp.Pop<ResultCode>();
- ThrowFatalError(error_code, FatalType::ErrorScreen, {});
+ ThrowFatalError(system, error_code, FatalType::ErrorScreen, {});
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -141,7 +143,8 @@ void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) {
const auto error_code = rp.Pop<ResultCode>();
const auto fatal_type = rp.PopEnum<FatalType>();
- ThrowFatalError(error_code, fatal_type, {}); // No info is passed with ThrowFatalWithPolicy
+ ThrowFatalError(system, error_code, fatal_type,
+ {}); // No info is passed with ThrowFatalWithPolicy
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -157,15 +160,15 @@ void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx)
ASSERT_MSG(fatal_info.size() == sizeof(FatalInfo), "Invalid fatal info buffer size!");
std::memcpy(&info, fatal_info.data(), sizeof(FatalInfo));
- ThrowFatalError(error_code, fatal_type, info);
+ ThrowFatalError(system, error_code, fatal_type, info);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
auto module = std::make_shared<Module>();
- std::make_shared<Fatal_P>(module)->InstallAsService(service_manager);
- std::make_shared<Fatal_U>(module)->InstallAsService(service_manager);
+ std::make_shared<Fatal_P>(module, system)->InstallAsService(service_manager);
+ std::make_shared<Fatal_U>(module, system)->InstallAsService(service_manager);
}
} // namespace Service::Fatal
diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h
index 09371ff7f..bd9339dfc 100644
--- a/src/core/hle/service/fatal/fatal.h
+++ b/src/core/hle/service/fatal/fatal.h
@@ -6,13 +6,17 @@
#include "core/hle/service/service.h"
+namespace Core {
+class System;
+}
+
namespace Service::Fatal {
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
- explicit Interface(std::shared_ptr<Module> module, const char* name);
+ explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name);
~Interface() override;
void ThrowFatal(Kernel::HLERequestContext& ctx);
@@ -21,9 +25,10 @@ public:
protected:
std::shared_ptr<Module> module;
+ Core::System& system;
};
};
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::Fatal
diff --git a/src/core/hle/service/fatal/fatal_p.cpp b/src/core/hle/service/fatal/fatal_p.cpp
index 9e5f872ff..066ccf6b0 100644
--- a/src/core/hle/service/fatal/fatal_p.cpp
+++ b/src/core/hle/service/fatal/fatal_p.cpp
@@ -6,8 +6,8 @@
namespace Service::Fatal {
-Fatal_P::Fatal_P(std::shared_ptr<Module> module)
- : Module::Interface(std::move(module), "fatal:p") {}
+Fatal_P::Fatal_P(std::shared_ptr<Module> module, Core::System& system)
+ : Module::Interface(std::move(module), system, "fatal:p") {}
Fatal_P::~Fatal_P() = default;
diff --git a/src/core/hle/service/fatal/fatal_p.h b/src/core/hle/service/fatal/fatal_p.h
index 6e9c5979f..c6d953cb5 100644
--- a/src/core/hle/service/fatal/fatal_p.h
+++ b/src/core/hle/service/fatal/fatal_p.h
@@ -10,7 +10,7 @@ namespace Service::Fatal {
class Fatal_P final : public Module::Interface {
public:
- explicit Fatal_P(std::shared_ptr<Module> module);
+ explicit Fatal_P(std::shared_ptr<Module> module, Core::System& system);
~Fatal_P() override;
};
diff --git a/src/core/hle/service/fatal/fatal_u.cpp b/src/core/hle/service/fatal/fatal_u.cpp
index 1572a2051..8d72ed485 100644
--- a/src/core/hle/service/fatal/fatal_u.cpp
+++ b/src/core/hle/service/fatal/fatal_u.cpp
@@ -6,7 +6,8 @@
namespace Service::Fatal {
-Fatal_U::Fatal_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "fatal:u") {
+Fatal_U::Fatal_U(std::shared_ptr<Module> module, Core::System& system)
+ : Module::Interface(std::move(module), system, "fatal:u") {
static const FunctionInfo functions[] = {
{0, &Fatal_U::ThrowFatal, "ThrowFatal"},
{1, &Fatal_U::ThrowFatalWithPolicy, "ThrowFatalWithPolicy"},
diff --git a/src/core/hle/service/fatal/fatal_u.h b/src/core/hle/service/fatal/fatal_u.h
index 72cb6d076..34c5c7f95 100644
--- a/src/core/hle/service/fatal/fatal_u.h
+++ b/src/core/hle/service/fatal/fatal_u.h
@@ -10,7 +10,7 @@ namespace Service::Fatal {
class Fatal_U final : public Module::Interface {
public:
- explicit Fatal_U(std::shared_ptr<Module> module);
+ explicit Fatal_U(std::shared_ptr<Module> module, Core::System& system);
~Fatal_U() override;
};
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 8ce110dd1..14cd0e322 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -8,6 +8,7 @@
#include "common/file_util.h"
#include "core/core.h"
#include "core/file_sys/bis_factory.h"
+#include "core/file_sys/card_image.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/mode.h"
@@ -25,14 +26,10 @@
#include "core/hle/service/filesystem/fsp_pr.h"
#include "core/hle/service/filesystem/fsp_srv.h"
#include "core/loader/loader.h"
+#include "core/settings.h"
namespace Service::FileSystem {
-// Size of emulated sd card free space, reported in bytes.
-// Just using 32GB because thats reasonable
-// TODO(DarkLordZach): Eventually make this configurable in settings.
-constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000;
-
// A default size for normal/journal save data size if application control metadata cannot be found.
// This should be large enough to satisfy even the most extreme requirements (~4.2GB)
constexpr u64 SUFFICIENT_SAVE_DATA_SIZE = 0xF0000000;
@@ -226,13 +223,6 @@ ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const s
return MakeResult(dir);
}
-u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const {
- if (backing->IsWritable())
- return EMULATED_SD_REPORTED_SIZE;
-
- return 0;
-}
-
ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
@@ -251,44 +241,39 @@ ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
return FileSys::ERROR_PATH_NOT_FOUND;
}
-/**
- * Map of registered file systems, identified by type. Once an file system is registered here, it
- * is never removed until UnregisterFileSystems is called.
- */
-static std::unique_ptr<FileSys::RomFSFactory> romfs_factory;
-static std::unique_ptr<FileSys::SaveDataFactory> save_data_factory;
-static std::unique_ptr<FileSys::SDMCFactory> sdmc_factory;
-static std::unique_ptr<FileSys::BISFactory> bis_factory;
+FileSystemController::FileSystemController() = default;
+
+FileSystemController::~FileSystemController() = default;
-ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) {
- ASSERT_MSG(romfs_factory == nullptr, "Tried to register a second RomFS");
+ResultCode FileSystemController::RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) {
romfs_factory = std::move(factory);
LOG_DEBUG(Service_FS, "Registered RomFS");
return RESULT_SUCCESS;
}
-ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory) {
- ASSERT_MSG(romfs_factory == nullptr, "Tried to register a second save data");
+ResultCode FileSystemController::RegisterSaveData(
+ std::unique_ptr<FileSys::SaveDataFactory>&& factory) {
+ ASSERT_MSG(save_data_factory == nullptr, "Tried to register a second save data");
save_data_factory = std::move(factory);
LOG_DEBUG(Service_FS, "Registered save data");
return RESULT_SUCCESS;
}
-ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) {
+ResultCode FileSystemController::RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) {
ASSERT_MSG(sdmc_factory == nullptr, "Tried to register a second SDMC");
sdmc_factory = std::move(factory);
LOG_DEBUG(Service_FS, "Registered SDMC");
return RESULT_SUCCESS;
}
-ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) {
+ResultCode FileSystemController::RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) {
ASSERT_MSG(bis_factory == nullptr, "Tried to register a second BIS");
bis_factory = std::move(factory);
LOG_DEBUG(Service_FS, "Registered BIS");
return RESULT_SUCCESS;
}
-void SetPackedUpdate(FileSys::VirtualFile update_raw) {
+void FileSystemController::SetPackedUpdate(FileSys::VirtualFile update_raw) {
LOG_TRACE(Service_FS, "Setting packed update for romfs");
if (romfs_factory == nullptr)
@@ -297,7 +282,7 @@ void SetPackedUpdate(FileSys::VirtualFile update_raw) {
romfs_factory->SetPackedUpdate(std::move(update_raw));
}
-ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() {
+ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFSCurrentProcess() const {
LOG_TRACE(Service_FS, "Opening RomFS for current process");
if (romfs_factory == nullptr) {
@@ -308,8 +293,8 @@ ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() {
return romfs_factory->OpenCurrentProcess();
}
-ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
- FileSys::ContentRecordType type) {
+ResultVal<FileSys::VirtualFile> FileSystemController::OpenRomFS(
+ u64 title_id, FileSys::StorageId storage_id, FileSys::ContentRecordType type) const {
LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}, storage_id={:02X}, type={:02X}",
title_id, static_cast<u8>(storage_id), static_cast<u8>(type));
@@ -321,8 +306,20 @@ ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId stora
return romfs_factory->Open(title_id, storage_id, type);
}
-ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
- const FileSys::SaveDataDescriptor& descriptor) {
+ResultVal<FileSys::VirtualDir> FileSystemController::CreateSaveData(
+ FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& save_struct) const {
+ LOG_TRACE(Service_FS, "Creating Save Data for space_id={:01X}, save_struct={}",
+ static_cast<u8>(space), save_struct.DebugInfo());
+
+ if (save_data_factory == nullptr) {
+ return FileSys::ERROR_ENTITY_NOT_FOUND;
+ }
+
+ return save_data_factory->Create(space, save_struct);
+}
+
+ResultVal<FileSys::VirtualDir> FileSystemController::OpenSaveData(
+ FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& descriptor) const {
LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}",
static_cast<u8>(space), descriptor.DebugInfo());
@@ -333,7 +330,8 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
return save_data_factory->Open(space, descriptor);
}
-ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space) {
+ResultVal<FileSys::VirtualDir> FileSystemController::OpenSaveDataSpace(
+ FileSys::SaveDataSpaceId space) const {
LOG_TRACE(Service_FS, "Opening Save Data Space for space_id={:01X}", static_cast<u8>(space));
if (save_data_factory == nullptr) {
@@ -343,7 +341,7 @@ ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space)
return MakeResult(save_data_factory->GetSaveDataSpaceDirectory(space));
}
-ResultVal<FileSys::VirtualDir> OpenSDMC() {
+ResultVal<FileSys::VirtualDir> FileSystemController::OpenSDMC() const {
LOG_TRACE(Service_FS, "Opening SDMC");
if (sdmc_factory == nullptr) {
@@ -353,7 +351,92 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() {
return sdmc_factory->Open();
}
-FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id) {
+ResultVal<FileSys::VirtualDir> FileSystemController::OpenBISPartition(
+ FileSys::BisPartitionId id) const {
+ LOG_TRACE(Service_FS, "Opening BIS Partition with id={:08X}", static_cast<u32>(id));
+
+ if (bis_factory == nullptr) {
+ return FileSys::ERROR_ENTITY_NOT_FOUND;
+ }
+
+ auto part = bis_factory->OpenPartition(id);
+ if (part == nullptr) {
+ return FileSys::ERROR_INVALID_ARGUMENT;
+ }
+
+ return MakeResult<FileSys::VirtualDir>(std::move(part));
+}
+
+ResultVal<FileSys::VirtualFile> FileSystemController::OpenBISPartitionStorage(
+ FileSys::BisPartitionId id) const {
+ LOG_TRACE(Service_FS, "Opening BIS Partition Storage with id={:08X}", static_cast<u32>(id));
+
+ if (bis_factory == nullptr) {
+ return FileSys::ERROR_ENTITY_NOT_FOUND;
+ }
+
+ auto part = bis_factory->OpenPartitionStorage(id);
+ if (part == nullptr) {
+ return FileSys::ERROR_INVALID_ARGUMENT;
+ }
+
+ return MakeResult<FileSys::VirtualFile>(std::move(part));
+}
+
+u64 FileSystemController::GetFreeSpaceSize(FileSys::StorageId id) const {
+ switch (id) {
+ case FileSys::StorageId::None:
+ case FileSys::StorageId::GameCard:
+ return 0;
+ case FileSys::StorageId::SdCard:
+ if (sdmc_factory == nullptr)
+ return 0;
+ return sdmc_factory->GetSDMCFreeSpace();
+ case FileSys::StorageId::Host:
+ if (bis_factory == nullptr)
+ return 0;
+ return bis_factory->GetSystemNANDFreeSpace() + bis_factory->GetUserNANDFreeSpace();
+ case FileSys::StorageId::NandSystem:
+ if (bis_factory == nullptr)
+ return 0;
+ return bis_factory->GetSystemNANDFreeSpace();
+ case FileSys::StorageId::NandUser:
+ if (bis_factory == nullptr)
+ return 0;
+ return bis_factory->GetUserNANDFreeSpace();
+ }
+
+ return 0;
+}
+
+u64 FileSystemController::GetTotalSpaceSize(FileSys::StorageId id) const {
+ switch (id) {
+ case FileSys::StorageId::None:
+ case FileSys::StorageId::GameCard:
+ return 0;
+ case FileSys::StorageId::SdCard:
+ if (sdmc_factory == nullptr)
+ return 0;
+ return sdmc_factory->GetSDMCTotalSpace();
+ case FileSys::StorageId::Host:
+ if (bis_factory == nullptr)
+ return 0;
+ return bis_factory->GetFullNANDTotalSpace();
+ case FileSys::StorageId::NandSystem:
+ if (bis_factory == nullptr)
+ return 0;
+ return bis_factory->GetSystemNANDTotalSpace();
+ case FileSys::StorageId::NandUser:
+ if (bis_factory == nullptr)
+ return 0;
+ return bis_factory->GetUserNANDTotalSpace();
+ }
+
+ return 0;
+}
+
+FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataType type,
+ u64 title_id, u128 user_id) const {
if (save_data_factory == nullptr) {
return {0, 0};
}
@@ -385,13 +468,32 @@ FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id,
return value;
}
-void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
- FileSys::SaveDataSize new_value) {
+void FileSystemController::WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
+ FileSys::SaveDataSize new_value) const {
if (save_data_factory != nullptr)
save_data_factory->WriteSaveDataSize(type, title_id, user_id, new_value);
}
-FileSys::RegisteredCache* GetSystemNANDContents() {
+void FileSystemController::SetGameCard(FileSys::VirtualFile file) {
+ gamecard = std::make_unique<FileSys::XCI>(file);
+ const auto dir = gamecard->ConcatenatedPseudoDirectory();
+ gamecard_registered = std::make_unique<FileSys::RegisteredCache>(dir);
+ gamecard_placeholder = std::make_unique<FileSys::PlaceholderCache>(dir);
+}
+
+FileSys::XCI* FileSystemController::GetGameCard() const {
+ return gamecard.get();
+}
+
+FileSys::RegisteredCache* FileSystemController::GetGameCardContents() const {
+ return gamecard_registered.get();
+}
+
+FileSys::PlaceholderCache* FileSystemController::GetGameCardPlaceholder() const {
+ return gamecard_placeholder.get();
+}
+
+FileSys::RegisteredCache* FileSystemController::GetSystemNANDContents() const {
LOG_TRACE(Service_FS, "Opening System NAND Contents");
if (bis_factory == nullptr)
@@ -400,7 +502,7 @@ FileSys::RegisteredCache* GetSystemNANDContents() {
return bis_factory->GetSystemNANDContents();
}
-FileSys::RegisteredCache* GetUserNANDContents() {
+FileSys::RegisteredCache* FileSystemController::GetUserNANDContents() const {
LOG_TRACE(Service_FS, "Opening User NAND Contents");
if (bis_factory == nullptr)
@@ -409,7 +511,7 @@ FileSys::RegisteredCache* GetUserNANDContents() {
return bis_factory->GetUserNANDContents();
}
-FileSys::RegisteredCache* GetSDMCContents() {
+FileSys::RegisteredCache* FileSystemController::GetSDMCContents() const {
LOG_TRACE(Service_FS, "Opening SDMC Contents");
if (sdmc_factory == nullptr)
@@ -418,7 +520,143 @@ FileSys::RegisteredCache* GetSDMCContents() {
return sdmc_factory->GetSDMCContents();
}
-FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) {
+FileSys::PlaceholderCache* FileSystemController::GetSystemNANDPlaceholder() const {
+ LOG_TRACE(Service_FS, "Opening System NAND Placeholder");
+
+ if (bis_factory == nullptr)
+ return nullptr;
+
+ return bis_factory->GetSystemNANDPlaceholder();
+}
+
+FileSys::PlaceholderCache* FileSystemController::GetUserNANDPlaceholder() const {
+ LOG_TRACE(Service_FS, "Opening User NAND Placeholder");
+
+ if (bis_factory == nullptr)
+ return nullptr;
+
+ return bis_factory->GetUserNANDPlaceholder();
+}
+
+FileSys::PlaceholderCache* FileSystemController::GetSDMCPlaceholder() const {
+ LOG_TRACE(Service_FS, "Opening SDMC Placeholder");
+
+ if (sdmc_factory == nullptr)
+ return nullptr;
+
+ return sdmc_factory->GetSDMCPlaceholder();
+}
+
+FileSys::RegisteredCache* FileSystemController::GetRegisteredCacheForStorage(
+ FileSys::StorageId id) const {
+ switch (id) {
+ case FileSys::StorageId::None:
+ case FileSys::StorageId::Host:
+ UNIMPLEMENTED();
+ return nullptr;
+ case FileSys::StorageId::GameCard:
+ return GetGameCardContents();
+ case FileSys::StorageId::NandSystem:
+ return GetSystemNANDContents();
+ case FileSys::StorageId::NandUser:
+ return GetUserNANDContents();
+ case FileSys::StorageId::SdCard:
+ return GetSDMCContents();
+ }
+
+ return nullptr;
+}
+
+FileSys::PlaceholderCache* FileSystemController::GetPlaceholderCacheForStorage(
+ FileSys::StorageId id) const {
+ switch (id) {
+ case FileSys::StorageId::None:
+ case FileSys::StorageId::Host:
+ UNIMPLEMENTED();
+ return nullptr;
+ case FileSys::StorageId::GameCard:
+ return GetGameCardPlaceholder();
+ case FileSys::StorageId::NandSystem:
+ return GetSystemNANDPlaceholder();
+ case FileSys::StorageId::NandUser:
+ return GetUserNANDPlaceholder();
+ case FileSys::StorageId::SdCard:
+ return GetSDMCPlaceholder();
+ }
+
+ return nullptr;
+}
+
+FileSys::VirtualDir FileSystemController::GetSystemNANDContentDirectory() const {
+ LOG_TRACE(Service_FS, "Opening system NAND content directory");
+
+ if (bis_factory == nullptr)
+ return nullptr;
+
+ return bis_factory->GetSystemNANDContentDirectory();
+}
+
+FileSys::VirtualDir FileSystemController::GetUserNANDContentDirectory() const {
+ LOG_TRACE(Service_FS, "Opening user NAND content directory");
+
+ if (bis_factory == nullptr)
+ return nullptr;
+
+ return bis_factory->GetUserNANDContentDirectory();
+}
+
+FileSys::VirtualDir FileSystemController::GetSDMCContentDirectory() const {
+ LOG_TRACE(Service_FS, "Opening SDMC content directory");
+
+ if (sdmc_factory == nullptr)
+ return nullptr;
+
+ return sdmc_factory->GetSDMCContentDirectory();
+}
+
+FileSys::VirtualDir FileSystemController::GetNANDImageDirectory() const {
+ LOG_TRACE(Service_FS, "Opening NAND image directory");
+
+ if (bis_factory == nullptr)
+ return nullptr;
+
+ return bis_factory->GetImageDirectory();
+}
+
+FileSys::VirtualDir FileSystemController::GetSDMCImageDirectory() const {
+ LOG_TRACE(Service_FS, "Opening SDMC image directory");
+
+ if (sdmc_factory == nullptr)
+ return nullptr;
+
+ return sdmc_factory->GetImageDirectory();
+}
+
+FileSys::VirtualDir FileSystemController::GetContentDirectory(ContentStorageId id) const {
+ switch (id) {
+ case ContentStorageId::System:
+ return GetSystemNANDContentDirectory();
+ case ContentStorageId::User:
+ return GetUserNANDContentDirectory();
+ case ContentStorageId::SdCard:
+ return GetSDMCContentDirectory();
+ }
+
+ return nullptr;
+}
+
+FileSys::VirtualDir FileSystemController::GetImageDirectory(ImageDirectoryId id) const {
+ switch (id) {
+ case ImageDirectoryId::NAND:
+ return GetNANDImageDirectory();
+ case ImageDirectoryId::SdCard:
+ return GetSDMCImageDirectory();
+ }
+
+ return nullptr;
+}
+
+FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id) const {
LOG_TRACE(Service_FS, "Opening mod load root for tid={:016X}", title_id);
if (bis_factory == nullptr)
@@ -427,7 +665,7 @@ FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) {
return bis_factory->GetModificationLoadRoot(title_id);
}
-FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) {
+FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const {
LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id);
if (bis_factory == nullptr)
@@ -436,7 +674,7 @@ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) {
return bis_factory->GetModificationDumpRoot(title_id);
}
-void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {
+void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {
if (overwrite) {
bis_factory = nullptr;
save_data_factory = nullptr;
@@ -473,11 +711,10 @@ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {
}
void InstallInterfaces(Core::System& system) {
- romfs_factory = nullptr;
- CreateFactories(*system.GetFilesystem(), false);
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
- std::make_shared<FSP_SRV>(system.GetReporter())->InstallAsService(system.ServiceManager());
+ std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetReporter())
+ ->InstallAsService(system.ServiceManager());
}
} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 3849dd89e..3e0c03ec0 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -14,10 +14,13 @@ namespace FileSys {
class BISFactory;
class RegisteredCache;
class RegisteredCacheUnion;
+class PlaceholderCache;
class RomFSFactory;
class SaveDataFactory;
class SDMCFactory;
+class XCI;
+enum class BisPartitionId : u32;
enum class ContentRecordType : u8;
enum class Mode : u32;
enum class SaveDataSpaceId : u8;
@@ -36,34 +39,91 @@ class ServiceManager;
namespace FileSystem {
-ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory);
-ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory);
-ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory);
-ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory);
-
-void SetPackedUpdate(FileSys::VirtualFile update_raw);
-ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess();
-ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
- FileSys::ContentRecordType type);
-ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space,
- const FileSys::SaveDataDescriptor& descriptor);
-ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space);
-ResultVal<FileSys::VirtualDir> OpenSDMC();
-
-FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id);
-void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
- FileSys::SaveDataSize new_value);
+enum class ContentStorageId : u32 {
+ System,
+ User,
+ SdCard,
+};
-FileSys::RegisteredCache* GetSystemNANDContents();
-FileSys::RegisteredCache* GetUserNANDContents();
-FileSys::RegisteredCache* GetSDMCContents();
+enum class ImageDirectoryId : u32 {
+ NAND,
+ SdCard,
+};
-FileSys::VirtualDir GetModificationLoadRoot(u64 title_id);
-FileSys::VirtualDir GetModificationDumpRoot(u64 title_id);
+class FileSystemController {
+public:
+ FileSystemController();
+ ~FileSystemController();
+
+ ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory);
+ ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory);
+ ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory);
+ ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory);
+
+ void SetPackedUpdate(FileSys::VirtualFile update_raw);
+ ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() const;
+ ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
+ FileSys::ContentRecordType type) const;
+ ResultVal<FileSys::VirtualDir> CreateSaveData(
+ FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& save_struct) const;
+ ResultVal<FileSys::VirtualDir> OpenSaveData(
+ FileSys::SaveDataSpaceId space, const FileSys::SaveDataDescriptor& save_struct) const;
+ ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space) const;
+ ResultVal<FileSys::VirtualDir> OpenSDMC() const;
+ ResultVal<FileSys::VirtualDir> OpenBISPartition(FileSys::BisPartitionId id) const;
+ ResultVal<FileSys::VirtualFile> OpenBISPartitionStorage(FileSys::BisPartitionId id) const;
+
+ u64 GetFreeSpaceSize(FileSys::StorageId id) const;
+ u64 GetTotalSpaceSize(FileSys::StorageId id) const;
+
+ FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id,
+ u128 user_id) const;
+ void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
+ FileSys::SaveDataSize new_value) const;
+
+ void SetGameCard(FileSys::VirtualFile file);
+ FileSys::XCI* GetGameCard() const;
+
+ FileSys::RegisteredCache* GetSystemNANDContents() const;
+ FileSys::RegisteredCache* GetUserNANDContents() const;
+ FileSys::RegisteredCache* GetSDMCContents() const;
+ FileSys::RegisteredCache* GetGameCardContents() const;
+
+ FileSys::PlaceholderCache* GetSystemNANDPlaceholder() const;
+ FileSys::PlaceholderCache* GetUserNANDPlaceholder() const;
+ FileSys::PlaceholderCache* GetSDMCPlaceholder() const;
+ FileSys::PlaceholderCache* GetGameCardPlaceholder() const;
+
+ FileSys::RegisteredCache* GetRegisteredCacheForStorage(FileSys::StorageId id) const;
+ FileSys::PlaceholderCache* GetPlaceholderCacheForStorage(FileSys::StorageId id) const;
+
+ FileSys::VirtualDir GetSystemNANDContentDirectory() const;
+ FileSys::VirtualDir GetUserNANDContentDirectory() const;
+ FileSys::VirtualDir GetSDMCContentDirectory() const;
+
+ FileSys::VirtualDir GetNANDImageDirectory() const;
+ FileSys::VirtualDir GetSDMCImageDirectory() const;
+
+ FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
+ FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
+
+ FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
+ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;
+
+ // Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function
+ // above is called.
+ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
-// Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function
-// above is called.
-void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
+private:
+ std::unique_ptr<FileSys::RomFSFactory> romfs_factory;
+ std::unique_ptr<FileSys::SaveDataFactory> save_data_factory;
+ std::unique_ptr<FileSys::SDMCFactory> sdmc_factory;
+ std::unique_ptr<FileSys::BISFactory> bis_factory;
+
+ std::unique_ptr<FileSys::XCI> gamecard;
+ std::unique_ptr<FileSys::RegisteredCache> gamecard_registered;
+ std::unique_ptr<FileSys::PlaceholderCache> gamecard_placeholder;
+};
void InstallInterfaces(Core::System& system);
@@ -160,12 +220,6 @@ public:
ResultVal<FileSys::VirtualDir> OpenDirectory(const std::string& path);
/**
- * Get the free space
- * @return The number of free bytes in the archive
- */
- u64 GetFreeSpaceSize() const;
-
- /**
* Get the type of the specified path
* @return The type of the specified path or error code
*/
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index d3cd46a9b..eb982ad49 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -19,6 +19,7 @@
#include "core/file_sys/mode.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/patch_manager.h"
+#include "core/file_sys/romfs_factory.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/system_archive/system_archive.h"
#include "core/file_sys/vfs.h"
@@ -30,6 +31,18 @@
namespace Service::FileSystem {
+struct SizeGetter {
+ std::function<u64()> get_free_size;
+ std::function<u64()> get_total_size;
+
+ static SizeGetter FromStorageId(const FileSystemController& fsc, FileSys::StorageId id) {
+ return {
+ [&fsc, id] { return fsc.GetFreeSpaceSize(id); },
+ [&fsc, id] { return fsc.GetTotalSpaceSize(id); },
+ };
+ }
+};
+
enum class FileSystemType : u8 {
Invalid0 = 0,
Invalid1 = 1,
@@ -289,8 +302,8 @@ private:
class IFileSystem final : public ServiceFramework<IFileSystem> {
public:
- explicit IFileSystem(FileSys::VirtualDir backend)
- : ServiceFramework("IFileSystem"), backend(std::move(backend)) {
+ explicit IFileSystem(FileSys::VirtualDir backend, SizeGetter size)
+ : ServiceFramework("IFileSystem"), backend(std::move(backend)), size(std::move(size)) {
static const FunctionInfo functions[] = {
{0, &IFileSystem::CreateFile, "CreateFile"},
{1, &IFileSystem::DeleteFile, "DeleteFile"},
@@ -467,14 +480,31 @@ public:
rb.Push(RESULT_SUCCESS);
}
+ void GetFreeSpaceSize(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_FS, "called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(size.get_free_size());
+ }
+
+ void GetTotalSpaceSize(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_FS, "called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(size.get_total_size());
+ }
+
private:
VfsDirectoryServiceWrapper backend;
+ SizeGetter size;
};
class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
public:
- explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space)
- : ServiceFramework("ISaveDataInfoReader") {
+ explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space, FileSystemController& fsc)
+ : ServiceFramework("ISaveDataInfoReader"), fsc(fsc) {
static const FunctionInfo functions[] = {
{0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
};
@@ -520,8 +550,13 @@ private:
}
void FindAllSaves(FileSys::SaveDataSpaceId space) {
- const auto save_root = OpenSaveDataSpace(space);
- ASSERT(save_root.Succeeded());
+ const auto save_root = fsc.OpenSaveDataSpace(space);
+
+ if (save_root.Failed() || *save_root == nullptr) {
+ LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!",
+ static_cast<u8>(space));
+ return;
+ }
for (const auto& type : (*save_root)->GetSubdirectories()) {
if (type->GetName() == "save") {
@@ -610,11 +645,13 @@ private:
};
static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size.");
+ FileSystemController& fsc;
std::vector<SaveDataInfo> info;
u64 next_entry_index = 0;
};
-FSP_SRV::FSP_SRV(const Core::Reporter& reporter) : ServiceFramework("fsp-srv"), reporter(reporter) {
+FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
+ : ServiceFramework("fsp-srv"), fsc(fsc), reporter(reporter) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "OpenFileSystem"},
@@ -754,7 +791,8 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
- IFileSystem filesystem(OpenSDMC().Unwrap());
+ IFileSystem filesystem(fsc.OpenSDMC().Unwrap(),
+ SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard));
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -768,8 +806,10 @@ void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
u128 uid = rp.PopRaw<u128>();
- LOG_WARNING(Service_FS, "(STUBBED) called save_struct = {}, uid = {:016X}{:016X}",
- save_struct.DebugInfo(), uid[1], uid[0]);
+ LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(),
+ uid[1], uid[0]);
+
+ fsc.CreateSaveData(FileSys::SaveDataSpaceId::NandUser, save_struct);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -786,14 +826,24 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto parameters = rp.PopRaw<Parameters>();
- auto dir = OpenSaveData(parameters.save_data_space_id, parameters.descriptor);
+ auto dir = fsc.OpenSaveData(parameters.save_data_space_id, parameters.descriptor);
if (dir.Failed()) {
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
return;
}
- IFileSystem filesystem(std::move(dir.Unwrap()));
+ FileSys::StorageId id;
+ if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::NandUser) {
+ id = FileSys::StorageId::NandUser;
+ } else if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardSystem ||
+ parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardUser) {
+ id = FileSys::StorageId::SdCard;
+ } else {
+ id = FileSys::StorageId::NandSystem;
+ }
+
+ IFileSystem filesystem(std::move(dir.Unwrap()), SizeGetter::FromStorageId(fsc, id));
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
@@ -812,7 +862,7 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space));
+ rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space, fsc));
}
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
@@ -836,7 +886,7 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
- auto romfs = OpenRomFSCurrentProcess();
+ auto romfs = fsc.OpenRomFSCurrentProcess();
if (romfs.Failed()) {
// TODO (bunnei): Find the right error code to use here
LOG_CRITICAL(Service_FS, "no file system interface available!");
@@ -861,7 +911,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}",
static_cast<u8>(storage_id), unknown, title_id);
- auto data = OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data);
+ auto data = fsc.OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data);
if (data.Failed()) {
const auto archive = FileSys::SystemArchive::SynthesizeSystemArchive(title_id);
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index b5486a193..d52b55999 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -32,7 +32,7 @@ enum class LogMode : u32 {
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
public:
- explicit FSP_SRV(const Core::Reporter& reporter);
+ explicit FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter);
~FSP_SRV() override;
private:
@@ -51,6 +51,8 @@ private:
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
+ FileSystemController& fsc;
+
FileSys::VirtualFile romfs;
u64 current_process_id = 0;
u32 access_log_program_index = 0;
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index d1ec12ef9..42b4ee861 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -149,7 +149,8 @@ private:
class INotificationService final : public ServiceFramework<INotificationService> {
public:
- INotificationService(Common::UUID uuid) : ServiceFramework("INotificationService"), uuid(uuid) {
+ INotificationService(Common::UUID uuid, Core::System& system)
+ : ServiceFramework("INotificationService"), uuid(uuid) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &INotificationService::GetEvent, "GetEvent"},
@@ -159,6 +160,9 @@ public:
// clang-format on
RegisterHandlers(functions);
+
+ notification_event = Kernel::WritableEvent::CreateEventPair(
+ system.Kernel(), Kernel::ResetType::Manual, "INotificationService:NotifyEvent");
}
private:
@@ -167,13 +171,6 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
-
- if (!is_event_created) {
- auto& kernel = Core::System::GetInstance().Kernel();
- notification_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, "INotificationService:NotifyEvent");
- is_event_created = true;
- }
rb.PushCopyObjects(notification_event.readable);
}
@@ -261,21 +258,21 @@ void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<INotificationService>(uuid);
+ rb.PushIpcInterface<INotificationService>(uuid, system);
}
-Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
- : ServiceFramework(name), module(std::move(module)) {}
+Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
+ : ServiceFramework(name), module(std::move(module)), system(system) {}
Module::Interface::~Interface() = default;
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
auto module = std::make_shared<Module>();
- std::make_shared<Friend>(module, "friend:a")->InstallAsService(service_manager);
- std::make_shared<Friend>(module, "friend:m")->InstallAsService(service_manager);
- std::make_shared<Friend>(module, "friend:s")->InstallAsService(service_manager);
- std::make_shared<Friend>(module, "friend:u")->InstallAsService(service_manager);
- std::make_shared<Friend>(module, "friend:v")->InstallAsService(service_manager);
+ std::make_shared<Friend>(module, system, "friend:a")->InstallAsService(service_manager);
+ std::make_shared<Friend>(module, system, "friend:m")->InstallAsService(service_manager);
+ std::make_shared<Friend>(module, system, "friend:s")->InstallAsService(service_manager);
+ std::make_shared<Friend>(module, system, "friend:u")->InstallAsService(service_manager);
+ std::make_shared<Friend>(module, system, "friend:v")->InstallAsService(service_manager);
}
} // namespace Service::Friend
diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h
index 38d05fa8e..24f3fc969 100644
--- a/src/core/hle/service/friend/friend.h
+++ b/src/core/hle/service/friend/friend.h
@@ -6,13 +6,17 @@
#include "core/hle/service/service.h"
+namespace Core {
+class System;
+}
+
namespace Service::Friend {
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
- explicit Interface(std::shared_ptr<Module> module, const char* name);
+ explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name);
~Interface() override;
void CreateFriendService(Kernel::HLERequestContext& ctx);
@@ -20,10 +24,11 @@ public:
protected:
std::shared_ptr<Module> module;
+ Core::System& system;
};
};
/// Registers all Friend services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::Friend
diff --git a/src/core/hle/service/friend/interface.cpp b/src/core/hle/service/friend/interface.cpp
index 5b384f733..58155f652 100644
--- a/src/core/hle/service/friend/interface.cpp
+++ b/src/core/hle/service/friend/interface.cpp
@@ -6,8 +6,8 @@
namespace Service::Friend {
-Friend::Friend(std::shared_ptr<Module> module, const char* name)
- : Interface(std::move(module), name) {
+Friend::Friend(std::shared_ptr<Module> module, Core::System& system, const char* name)
+ : Interface(std::move(module), system, name) {
static const FunctionInfo functions[] = {
{0, &Friend::CreateFriendService, "CreateFriendService"},
{1, &Friend::CreateNotificationService, "CreateNotificationService"},
diff --git a/src/core/hle/service/friend/interface.h b/src/core/hle/service/friend/interface.h
index 1963def39..465a35770 100644
--- a/src/core/hle/service/friend/interface.h
+++ b/src/core/hle/service/friend/interface.h
@@ -10,7 +10,7 @@ namespace Service::Friend {
class Friend final : public Module::Interface {
public:
- explicit Friend(std::shared_ptr<Module> module, const char* name);
+ explicit Friend(std::shared_ptr<Module> module, Core::System& system, const char* name);
~Friend() override;
};
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp
index 0993a7815..8091db9d7 100644
--- a/src/core/hle/service/hid/controllers/controller_base.cpp
+++ b/src/core/hle/service/hid/controllers/controller_base.cpp
@@ -6,7 +6,7 @@
namespace Service::HID {
-ControllerBase::ControllerBase() = default;
+ControllerBase::ControllerBase(Core::System& system) : system(system) {}
ControllerBase::~ControllerBase() = default;
void ControllerBase::ActivateController() {
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index 5e5097a03..8bc69c372 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -11,10 +11,14 @@ namespace Core::Timing {
class CoreTiming;
}
+namespace Core {
+class System;
+}
+
namespace Service::HID {
class ControllerBase {
public:
- ControllerBase();
+ explicit ControllerBase(Core::System& system);
virtual ~ControllerBase();
// Called when the controller is initialized
@@ -46,5 +50,7 @@ protected:
s64_le entry_count;
};
static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
+
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index c5c2e032a..8e8263f5b 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -14,7 +14,8 @@ constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
constexpr s32 HID_JOYSTICK_MIN = -0x7fff;
enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right };
-Controller_DebugPad::Controller_DebugPad() = default;
+Controller_DebugPad::Controller_DebugPad(Core::System& system)
+ : ControllerBase(system), system(system) {}
Controller_DebugPad::~Controller_DebugPad() = default;
void Controller_DebugPad::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index e584b92ec..6c4de817e 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -16,7 +16,7 @@
namespace Service::HID {
class Controller_DebugPad final : public ControllerBase {
public:
- Controller_DebugPad();
+ explicit Controller_DebugPad(Core::System& system);
~Controller_DebugPad() override;
// Called when the controller is initialized
@@ -89,5 +89,6 @@ private:
buttons;
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>
analogs;
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index a179252e3..80da0a0d3 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -10,7 +10,8 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
-Controller_Gesture::Controller_Gesture() = default;
+Controller_Gesture::Controller_Gesture(Core::System& system)
+ : ControllerBase(system), system(system) {}
Controller_Gesture::~Controller_Gesture() = default;
void Controller_Gesture::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index f305fe90f..396897527 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -12,7 +12,7 @@
namespace Service::HID {
class Controller_Gesture final : public ControllerBase {
public:
- Controller_Gesture();
+ explicit Controller_Gesture(Core::System& system);
~Controller_Gesture() override;
// Called when the controller is initialized
@@ -59,5 +59,6 @@ private:
std::array<GestureState, 17> gesture_states;
};
SharedMemory shared_memory{};
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 92d7bfb52..e587b2e15 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -12,7 +12,8 @@ namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
constexpr u8 KEYS_PER_BYTE = 8;
-Controller_Keyboard::Controller_Keyboard() = default;
+Controller_Keyboard::Controller_Keyboard(Core::System& system)
+ : ControllerBase(system), system(system) {}
Controller_Keyboard::~Controller_Keyboard() = default;
void Controller_Keyboard::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index 73cd2c7bb..ef586f7eb 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -15,7 +15,7 @@
namespace Service::HID {
class Controller_Keyboard final : public ControllerBase {
public:
- Controller_Keyboard();
+ explicit Controller_Keyboard(Core::System& system);
~Controller_Keyboard() override;
// Called when the controller is initialized
@@ -53,5 +53,6 @@ private:
keyboard_keys;
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeKeyboard::NumKeyboardMods>
keyboard_mods;
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 11ab096d9..88f2ca4c1 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -11,7 +11,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
-Controller_Mouse::Controller_Mouse() = default;
+Controller_Mouse::Controller_Mouse(Core::System& system) : ControllerBase(system), system(system) {}
Controller_Mouse::~Controller_Mouse() = default;
void Controller_Mouse::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 9d46eecbe..df2da6ae3 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -14,7 +14,7 @@
namespace Service::HID {
class Controller_Mouse final : public ControllerBase {
public:
- Controller_Mouse();
+ explicit Controller_Mouse(Core::System& system);
~Controller_Mouse() override;
// Called when the controller is initialized
@@ -53,5 +53,6 @@ private:
std::unique_ptr<Input::MouseDevice> mouse_device;
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeMouseButton::NumMouseButtons>
mouse_button_devices;
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index e47fe8188..44b668fbf 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -93,7 +93,7 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
};
}
-Controller_NPad::Controller_NPad() = default;
+Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
Controller_NPad::~Controller_NPad() = default;
void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
@@ -168,9 +168,11 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
}
void Controller_NPad::OnInit() {
- auto& kernel = Core::System::GetInstance().Kernel();
- styleset_changed_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "npad:NpadStyleSetChanged");
+ auto& kernel = system.Kernel();
+ for (std::size_t i = 0; i < styleset_changed_events.size(); i++) {
+ styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair(
+ kernel, Kernel::ResetType::Automatic, fmt::format("npad:NpadStyleSetChanged_{}", i));
+ }
if (!IsControllerActivated()) {
return;
@@ -453,7 +455,7 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) {
had_controller_update = true;
}
if (had_controller_update) {
- styleset_changed_event.writable->Signal();
+ styleset_changed_events[i].writable->Signal();
}
}
}
@@ -468,7 +470,6 @@ std::size_t Controller_NPad::GetSupportedNPadIdTypesSize() const {
}
void Controller_NPad::SetHoldType(NpadHoldType joy_hold_type) {
- styleset_changed_event.writable->Signal();
hold_type = joy_hold_type;
}
@@ -479,7 +480,10 @@ Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const {
void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) {
const std::size_t npad_index = NPadIdToIndex(npad_id);
ASSERT(npad_index < shared_memory_entries.size());
- shared_memory_entries[npad_index].pad_assignment = assignment_mode;
+ if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) {
+ styleset_changed_events[npad_index].writable->Signal();
+ shared_memory_entries[npad_index].pad_assignment = assignment_mode;
+ }
}
void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
@@ -498,11 +502,13 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
last_processed_vibration = vibrations.back();
}
-Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent() const {
+Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(
+ u32 npad_id) const {
// TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
// be signalled at least once, and signaled after a new controller is connected?
- styleset_changed_event.writable->Signal();
- return styleset_changed_event.readable;
+ const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)];
+ styleset_event.writable->Signal();
+ return styleset_event.readable;
}
Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index f28b36806..1bc3d55d6 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -20,7 +20,7 @@ constexpr u32 NPAD_UNKNOWN = 16; // TODO(ogniK): What is this?
class Controller_NPad final : public ControllerBase {
public:
- Controller_NPad();
+ explicit Controller_NPad(Core::System& system);
~Controller_NPad() override;
// Called when the controller is initialized
@@ -109,7 +109,7 @@ public:
void VibrateController(const std::vector<u32>& controller_ids,
const std::vector<Vibration>& vibrations);
- Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent() const;
+ Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
Vibration GetLastVibration() const;
void AddNewController(NPadControllerType controller);
@@ -315,7 +315,8 @@ private:
sticks;
std::vector<u32> supported_npad_id_types{};
NpadHoldType hold_type{NpadHoldType::Vertical};
- Kernel::EventPair styleset_changed_event;
+ // Each controller should have their own styleset changed event
+ std::array<Kernel::EventPair, 10> styleset_changed_events;
Vibration last_processed_vibration{};
std::array<ControllerHolder, 10> connected_controllers{};
bool can_controllers_vibrate{true};
@@ -327,5 +328,6 @@ private:
std::array<ControllerPad, 10> npad_pad_states{};
bool IsControllerSupported(NPadControllerType controller);
bool is_in_lr_assignment_mode{false};
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
index 946948f5e..9b829341e 100644
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ b/src/core/hle/service/hid/controllers/stubbed.cpp
@@ -9,7 +9,8 @@
namespace Service::HID {
-Controller_Stubbed::Controller_Stubbed() = default;
+Controller_Stubbed::Controller_Stubbed(Core::System& system)
+ : ControllerBase(system), system(system) {}
Controller_Stubbed::~Controller_Stubbed() = default;
void Controller_Stubbed::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h
index 24469f03e..37d7d8538 100644
--- a/src/core/hle/service/hid/controllers/stubbed.h
+++ b/src/core/hle/service/hid/controllers/stubbed.h
@@ -10,7 +10,7 @@
namespace Service::HID {
class Controller_Stubbed final : public ControllerBase {
public:
- Controller_Stubbed();
+ explicit Controller_Stubbed(Core::System& system);
~Controller_Stubbed() override;
// Called when the controller is initialized
@@ -30,5 +30,6 @@ public:
private:
bool smart_update{};
std::size_t common_offset{};
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 1a8445a43..25912fd69 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -13,7 +13,8 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
-Controller_Touchscreen::Controller_Touchscreen() = default;
+Controller_Touchscreen::Controller_Touchscreen(Core::System& system)
+ : ControllerBase(system), system(system) {}
Controller_Touchscreen::~Controller_Touchscreen() = default;
void Controller_Touchscreen::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index 76fc340e9..3429c84db 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -14,7 +14,7 @@
namespace Service::HID {
class Controller_Touchscreen final : public ControllerBase {
public:
- Controller_Touchscreen();
+ explicit Controller_Touchscreen(Core::System& system);
~Controller_Touchscreen() override;
// Called when the controller is initialized
@@ -69,5 +69,6 @@ private:
TouchScreenSharedMemory shared_memory{};
std::unique_ptr<Input::TouchDevice> touch_device;
s64_le last_touch{};
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
index 1a9da9576..1bce044b4 100644
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ b/src/core/hle/service/hid/controllers/xpad.cpp
@@ -10,7 +10,7 @@
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
-Controller_XPad::Controller_XPad() = default;
+Controller_XPad::Controller_XPad(Core::System& system) : ControllerBase(system), system(system) {}
Controller_XPad::~Controller_XPad() = default;
void Controller_XPad::OnInit() {}
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h
index 2864e6617..c445ebec0 100644
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ b/src/core/hle/service/hid/controllers/xpad.h
@@ -12,7 +12,7 @@
namespace Service::HID {
class Controller_XPad final : public ControllerBase {
public:
- Controller_XPad();
+ explicit Controller_XPad(Core::System& system);
~Controller_XPad() override;
// Called when the controller is initialized
@@ -56,5 +56,6 @@ private:
};
static_assert(sizeof(SharedMemory) == 0x1000, "SharedMemory is an invalid size");
SharedMemory shared_memory{};
+ Core::System& system;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index f8b1ca816..8d76ba746 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -42,13 +42,14 @@ constexpr s64 accelerometer_update_ticks = static_cast<s64>(Core::Timing::BASE_C
constexpr s64 gyroscope_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100);
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
-IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
+IAppletResource::IAppletResource(Core::System& system)
+ : ServiceFramework("IAppletResource"), system(system) {
static const FunctionInfo functions[] = {
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
};
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
shared_mem = Kernel::SharedMemory::Create(
kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
@@ -74,7 +75,7 @@ IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
// Register update callbacks
- auto& core_timing = Core::System::GetInstance().CoreTiming();
+ auto& core_timing = system.CoreTiming();
pad_update_event =
core_timing.RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 cycles_late) {
UpdateControllers(userdata, cycles_late);
@@ -96,7 +97,7 @@ void IAppletResource::DeactivateController(HidController controller) {
}
IAppletResource ::~IAppletResource() {
- Core::System::GetInstance().CoreTiming().UnscheduleEvent(pad_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
}
void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
@@ -108,7 +109,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
}
void IAppletResource::UpdateControllers(u64 userdata, s64 cycles_late) {
- auto& core_timing = Core::System::GetInstance().CoreTiming();
+ auto& core_timing = system.CoreTiming();
const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);
for (const auto& controller : controllers) {
@@ -141,13 +142,13 @@ private:
std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
if (applet_resource == nullptr) {
- applet_resource = std::make_shared<IAppletResource>();
+ applet_resource = std::make_shared<IAppletResource>(system);
}
return applet_resource;
}
-Hid::Hid() : ServiceFramework("hid") {
+Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &Hid::CreateAppletResource, "CreateAppletResource"},
@@ -286,7 +287,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
if (applet_resource == nullptr) {
- applet_resource = std::make_shared<IAppletResource>();
+ applet_resource = std::make_shared<IAppletResource>(system);
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -479,7 +480,7 @@ void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetStyleSetChangedEvent());
+ .GetStyleSetChangedEvent(npad_id));
}
void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
@@ -1053,14 +1054,14 @@ void ReloadInputDevices() {
Settings::values.is_device_reload_pending.store(true);
}
-void InstallInterfaces(SM::ServiceManager& service_manager) {
- std::make_shared<Hid>()->InstallAsService(service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
+ std::make_shared<Hid>(system)->InstallAsService(service_manager);
std::make_shared<HidBus>()->InstallAsService(service_manager);
std::make_shared<HidDbg>()->InstallAsService(service_manager);
std::make_shared<HidSys>()->InstallAsService(service_manager);
std::make_shared<HidTmp>()->InstallAsService(service_manager);
- std::make_shared<IRS>()->InstallAsService(service_manager);
+ std::make_shared<IRS>(system)->InstallAsService(service_manager);
std::make_shared<IRS_SYS>()->InstallAsService(service_manager);
std::make_shared<XCD_SYS>()->InstallAsService(service_manager);
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 2fd6d9fc7..35b663679 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -42,7 +42,7 @@ enum class HidController : std::size_t {
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
- IAppletResource();
+ explicit IAppletResource(Core::System& system);
~IAppletResource() override;
void ActivateController(HidController controller);
@@ -61,7 +61,7 @@ public:
private:
template <typename T>
void MakeController(HidController controller) {
- controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>();
+ controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system);
}
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
@@ -70,6 +70,7 @@ private:
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
Core::Timing::EventType* pad_update_event;
+ Core::System& system;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
controllers{};
@@ -77,7 +78,7 @@ private:
class Hid final : public ServiceFramework<Hid> {
public:
- Hid();
+ explicit Hid(Core::System& system);
~Hid() override;
std::shared_ptr<IAppletResource> GetAppletResource();
@@ -126,12 +127,13 @@ private:
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
std::shared_ptr<IAppletResource> applet_resource;
+ Core::System& system;
};
/// Reload input devices. Used when input configuration changed
void ReloadInputDevices();
/// Registers all HID services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 2c4625c99..5e79e2c1a 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -11,7 +11,7 @@
namespace Service::HID {
-IRS::IRS() : ServiceFramework{"irs"} {
+IRS::IRS(Core::System& system) : ServiceFramework{"irs"}, system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{302, &IRS::ActivateIrsensor, "ActivateIrsensor"},
@@ -37,7 +37,7 @@ IRS::IRS() : ServiceFramework{"irs"} {
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
shared_mem = Kernel::SharedMemory::Create(
kernel, nullptr, 0x8000, Kernel::MemoryPermission::ReadWrite,
Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "IRS:SharedMemory");
@@ -98,7 +98,7 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 5};
rb.Push(RESULT_SUCCESS);
- rb.PushRaw<u64>(Core::System::GetInstance().CoreTiming().GetTicks());
+ rb.PushRaw<u64>(system.CoreTiming().GetTicks());
rb.PushRaw<u32>(0);
}
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index 12de6bfb3..eb4e898dd 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -15,7 +15,7 @@ namespace Service::HID {
class IRS final : public ServiceFramework<IRS> {
public:
- explicit IRS();
+ explicit IRS(Core::System& system);
~IRS() override;
private:
@@ -39,6 +39,7 @@ private:
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
const u32 device_handle{0xABCD};
+ Core::System& system;
};
class IRS_SYS final : public ServiceFramework<IRS_SYS> {
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 8ddad8682..3164ca26e 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -78,7 +78,7 @@ public:
class RelocatableObject final : public ServiceFramework<RelocatableObject> {
public:
- explicit RelocatableObject() : ServiceFramework{"ldr:ro"} {
+ explicit RelocatableObject(Core::System& system) : ServiceFramework{"ldr:ro"}, system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &RelocatableObject::LoadNro, "LoadNro"},
@@ -364,7 +364,7 @@ public:
vm_manager.ReprotectRange(*map_address + header.rw_offset, header.rw_size,
Kernel::VMAPermission::ReadWrite);
- Core::System::GetInstance().InvalidateCpuInstructionCaches();
+ system.InvalidateCpuInstructionCaches();
nro.insert_or_assign(*map_address,
NROInfo{hash, nro_address, nro_size, bss_address, bss_size});
@@ -430,7 +430,7 @@ public:
.IsSuccess());
}
- Core::System::GetInstance().InvalidateCpuInstructionCaches();
+ system.InvalidateCpuInstructionCaches();
nro.erase(iter);
IPC::ResponseBuilder rb{ctx, 2};
@@ -516,13 +516,14 @@ private:
Common::Is4KBAligned(header.text_size) && Common::Is4KBAligned(header.ro_size) &&
Common::Is4KBAligned(header.rw_size);
}
+ Core::System& system;
};
-void InstallInterfaces(SM::ServiceManager& sm) {
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
std::make_shared<DebugMonitor>()->InstallAsService(sm);
std::make_shared<ProcessManager>()->InstallAsService(sm);
std::make_shared<Shell>()->InstallAsService(sm);
- std::make_shared<RelocatableObject>()->InstallAsService(sm);
+ std::make_shared<RelocatableObject>(system)->InstallAsService(sm);
}
} // namespace Service::LDR
diff --git a/src/core/hle/service/ldr/ldr.h b/src/core/hle/service/ldr/ldr.h
index 412410c4f..7ac8c0b65 100644
--- a/src/core/hle/service/ldr/ldr.h
+++ b/src/core/hle/service/ldr/ldr.h
@@ -11,6 +11,6 @@ class ServiceManager;
namespace Service::LDR {
/// Registers all LDR services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& sm);
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
} // namespace Service::LDR
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index a5cb06f8a..a42c22d44 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -23,9 +23,9 @@ constexpr ResultCode ERR_TAG_FAILED(ErrorModule::NFP,
constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
} // namespace ErrCodes
-Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
- : ServiceFramework(name), module(std::move(module)) {
- auto& kernel = Core::System::GetInstance().Kernel();
+Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
+ : ServiceFramework(name), module(std::move(module)), system(system) {
+ auto& kernel = system.Kernel();
nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
"IUser:NFCTagDetected");
}
@@ -34,8 +34,8 @@ Module::Interface::~Interface() = default;
class IUser final : public ServiceFramework<IUser> {
public:
- IUser(Module::Interface& nfp_interface)
- : ServiceFramework("NFP::IUser"), nfp_interface(nfp_interface) {
+ IUser(Module::Interface& nfp_interface, Core::System& system)
+ : ServiceFramework("NFP::IUser"), nfp_interface(nfp_interface), system(system) {
static const FunctionInfo functions[] = {
{0, &IUser::Initialize, "Initialize"},
{1, &IUser::Finalize, "Finalize"},
@@ -65,7 +65,7 @@ public:
};
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
deactivate_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic, "IUser:DeactivateEvent");
availability_change_event = Kernel::WritableEvent::CreateEventPair(
@@ -324,6 +324,7 @@ private:
Kernel::EventPair deactivate_event;
Kernel::EventPair availability_change_event;
const Module::Interface& nfp_interface;
+ Core::System& system;
};
void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
@@ -331,7 +332,7 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IUser>(*this);
+ rb.PushIpcInterface<IUser>(*this, system);
}
bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
@@ -353,9 +354,9 @@ const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const
return amiibo;
}
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
auto module = std::make_shared<Module>();
- std::make_shared<NFP_User>(module)->InstallAsService(service_manager);
+ std::make_shared<NFP_User>(module, system)->InstallAsService(service_manager);
}
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index a1817e991..9718ef745 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -16,7 +16,7 @@ class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
- explicit Interface(std::shared_ptr<Module> module, const char* name);
+ explicit Interface(std::shared_ptr<Module> module, Core::System& system, const char* name);
~Interface() override;
struct ModelInfo {
@@ -43,9 +43,10 @@ public:
protected:
std::shared_ptr<Module> module;
+ Core::System& system;
};
};
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp
index 784a87c1b..298184f17 100644
--- a/src/core/hle/service/nfp/nfp_user.cpp
+++ b/src/core/hle/service/nfp/nfp_user.cpp
@@ -6,8 +6,8 @@
namespace Service::NFP {
-NFP_User::NFP_User(std::shared_ptr<Module> module)
- : Module::Interface(std::move(module), "nfp:user") {
+NFP_User::NFP_User(std::shared_ptr<Module> module, Core::System& system)
+ : Module::Interface(std::move(module), system, "nfp:user") {
static const FunctionInfo functions[] = {
{0, &NFP_User::CreateUserInterface, "CreateUserInterface"},
};
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h
index 65d9aaf48..1686ebf20 100644
--- a/src/core/hle/service/nfp/nfp_user.h
+++ b/src/core/hle/service/nfp/nfp_user.h
@@ -10,7 +10,7 @@ namespace Service::NFP {
class NFP_User final : public Module::Interface {
public:
- explicit NFP_User(std::shared_ptr<Module> module);
+ explicit NFP_User(std::shared_ptr<Module> module, Core::System& system);
~NFP_User() override;
};
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 76b12b482..24d1813a7 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -31,7 +31,7 @@ public:
class IRequest final : public ServiceFramework<IRequest> {
public:
- explicit IRequest() : ServiceFramework("IRequest") {
+ explicit IRequest(Core::System& system) : ServiceFramework("IRequest") {
static const FunctionInfo functions[] = {
{0, &IRequest::GetRequestState, "GetRequestState"},
{1, &IRequest::GetResult, "GetResult"},
@@ -61,7 +61,7 @@ public:
};
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
"IRequest:Event1");
event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
@@ -130,7 +130,7 @@ public:
class IGeneralService final : public ServiceFramework<IGeneralService> {
public:
- IGeneralService();
+ IGeneralService(Core::System& system);
private:
void GetClientId(Kernel::HLERequestContext& ctx) {
@@ -155,7 +155,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IRequest>();
+ rb.PushIpcInterface<IRequest>(system);
}
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NIFM, "(STUBBED) called");
@@ -198,9 +198,11 @@ private:
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(0);
}
+ Core::System& system;
};
-IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
+IGeneralService::IGeneralService(Core::System& system)
+ : ServiceFramework("IGeneralService"), system(system) {
static const FunctionInfo functions[] = {
{1, &IGeneralService::GetClientId, "GetClientId"},
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
@@ -245,7 +247,8 @@ IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
class NetworkInterface final : public ServiceFramework<NetworkInterface> {
public:
- explicit NetworkInterface(const char* name) : ServiceFramework{name} {
+ explicit NetworkInterface(const char* name, Core::System& system)
+ : ServiceFramework{name}, system(system) {
static const FunctionInfo functions[] = {
{4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"},
@@ -258,7 +261,7 @@ public:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IGeneralService>();
+ rb.PushIpcInterface<IGeneralService>(system);
}
void CreateGeneralService(Kernel::HLERequestContext& ctx) {
@@ -266,14 +269,17 @@ public:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IGeneralService>();
+ rb.PushIpcInterface<IGeneralService>(system);
}
+
+private:
+ Core::System& system;
};
-void InstallInterfaces(SM::ServiceManager& service_manager) {
- std::make_shared<NetworkInterface>("nifm:a")->InstallAsService(service_manager);
- std::make_shared<NetworkInterface>("nifm:s")->InstallAsService(service_manager);
- std::make_shared<NetworkInterface>("nifm:u")->InstallAsService(service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
+ std::make_shared<NetworkInterface>("nifm:a", system)->InstallAsService(service_manager);
+ std::make_shared<NetworkInterface>("nifm:s", system)->InstallAsService(service_manager);
+ std::make_shared<NetworkInterface>("nifm:u", system)->InstallAsService(service_manager);
}
} // namespace Service::NIFM
diff --git a/src/core/hle/service/nifm/nifm.h b/src/core/hle/service/nifm/nifm.h
index 4616b3b48..6857e18f9 100644
--- a/src/core/hle/service/nifm/nifm.h
+++ b/src/core/hle/service/nifm/nifm.h
@@ -8,9 +8,13 @@ namespace Service::SM {
class ServiceManager;
}
+namespace Core {
+class System;
+}
+
namespace Service::NIFM {
/// Registers all NIFM services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::NIFM
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index f319a3ca1..75d414952 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -126,7 +126,7 @@ public:
class IEnsureNetworkClockAvailabilityService final
: public ServiceFramework<IEnsureNetworkClockAvailabilityService> {
public:
- IEnsureNetworkClockAvailabilityService()
+ explicit IEnsureNetworkClockAvailabilityService(Core::System& system)
: ServiceFramework("IEnsureNetworkClockAvailabilityService") {
static const FunctionInfo functions[] = {
{0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"},
@@ -139,7 +139,7 @@ public:
};
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
finished_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic,
"IEnsureNetworkClockAvailabilityService:FinishEvent");
@@ -200,7 +200,7 @@ private:
class NTC final : public ServiceFramework<NTC> {
public:
- explicit NTC() : ServiceFramework{"ntc"} {
+ explicit NTC(Core::System& system) : ServiceFramework{"ntc"}, system(system) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"},
@@ -218,7 +218,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>();
+ rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>(system);
}
// TODO(ogniK): Do we need these?
@@ -235,13 +235,14 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
+ Core::System& system;
};
-void InstallInterfaces(SM::ServiceManager& sm) {
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
std::make_shared<NIM>()->InstallAsService(sm);
std::make_shared<NIM_ECA>()->InstallAsService(sm);
std::make_shared<NIM_SHP>()->InstallAsService(sm);
- std::make_shared<NTC>()->InstallAsService(sm);
+ std::make_shared<NTC>(system)->InstallAsService(sm);
}
} // namespace Service::NIM
diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h
index 2a2a92df0..dbe25dc01 100644
--- a/src/core/hle/service/nim/nim.h
+++ b/src/core/hle/service/nim/nim.h
@@ -8,8 +8,12 @@ namespace Service::SM {
class ServiceManager;
}
+namespace Core {
+class System;
+}
+
namespace Service::NIM {
-void InstallInterfaces(SM::ServiceManager& sm);
+void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
} // namespace Service::NIM
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index ce88a2941..15c156ce1 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -617,7 +617,8 @@ public:
}
};
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
+
std::make_shared<NS>("ns:am2")->InstallAsService(service_manager);
std::make_shared<NS>("ns:ec")->InstallAsService(service_manager);
std::make_shared<NS>("ns:rid")->InstallAsService(service_manager);
@@ -628,7 +629,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<NS_SU>()->InstallAsService(service_manager);
std::make_shared<NS_VM>()->InstallAsService(service_manager);
- std::make_shared<PL_U>()->InstallAsService(service_manager);
+ std::make_shared<PL_U>(system)->InstallAsService(service_manager);
}
} // namespace Service::NS
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index 0e8256cb4..13a64ad88 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -6,7 +6,13 @@
#include "core/hle/service/service.h"
-namespace Service::NS {
+namespace Service {
+
+namespace FileSystem {
+class FileSystemController;
+} // namespace FileSystem
+
+namespace NS {
class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
public:
@@ -91,6 +97,7 @@ private:
};
/// Registers all NS services with the specified service manager.
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
-} // namespace Service::NS
+} // namespace NS
+} // namespace Service
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 2a522136d..7dcdb4a07 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -150,7 +150,9 @@ struct PL_U::Impl {
std::vector<FontRegion> shared_font_regions;
};
-PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} {
+PL_U::PL_U(Core::System& system)
+ : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()}, system(system) {
+
static const FunctionInfo functions[] = {
{0, &PL_U::RequestLoad, "RequestLoad"},
{1, &PL_U::GetLoadState, "GetLoadState"},
@@ -160,8 +162,11 @@ PL_U::PL_U() : ServiceFramework("pl:u"), impl{std::make_unique<Impl>()} {
{5, &PL_U::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"},
};
RegisterHandlers(functions);
+
+ auto& fsc = system.GetFileSystemController();
+
// Attempt to load shared font data from disk
- const auto* nand = FileSystem::GetSystemNANDContents();
+ const auto* nand = fsc.GetSystemNANDContents();
std::size_t offset = 0;
// Rebuild shared fonts from data ncas
if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
@@ -324,7 +329,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
Kernel::MemoryState::Shared);
// Create shared font memory object
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system.Kernel();
impl->shared_font_mem = Kernel::SharedMemory::Create(
kernel, Core::CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
diff --git a/src/core/hle/service/ns/pl_u.h b/src/core/hle/service/ns/pl_u.h
index 253f26a2a..1063f4204 100644
--- a/src/core/hle/service/ns/pl_u.h
+++ b/src/core/hle/service/ns/pl_u.h
@@ -7,11 +7,17 @@
#include <memory>
#include "core/hle/service/service.h"
-namespace Service::NS {
+namespace Service {
+
+namespace FileSystem {
+class FileSystemController;
+} // namespace FileSystem
+
+namespace NS {
class PL_U final : public ServiceFramework<PL_U> {
public:
- PL_U();
+ explicit PL_U(Core::System& system);
~PL_U() override;
private:
@@ -24,6 +30,9 @@ private:
struct Impl;
std::unique_ptr<Impl> impl;
+ Core::System& system;
};
-} // namespace Service::NS
+} // namespace NS
+
+} // namespace Service
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index 5b8248433..1b52511a5 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -9,6 +9,7 @@
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/service/nvdrv/nvdata.h"
+#include "core/hle/service/service.h"
namespace Core {
class System;
@@ -38,8 +39,9 @@ public:
* @param output A buffer where the output data will be written to.
* @returns The result code of the ioctl.
*/
- virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) = 0;
+ virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) = 0;
protected:
Core::System& system;
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 926a1285d..f764388bc 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -17,8 +17,9 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
nvdisp_disp0 ::~nvdisp_disp0() = default;
-u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
UNIMPLEMENTED_MSG("Unimplemented ioctl");
return 0;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index e79e490ff..6fcdeee84 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -20,8 +20,9 @@ public:
explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvdisp_disp0() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
/// Performs a screen flip, drawing the buffer pointed to by the handle.
void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
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 24ab3f2e9..6bc053f27 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -26,8 +26,9 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
nvhost_as_gpu::~nvhost_as_gpu() = default;
-u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
index 30ca5f4c3..169fb8f0e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -20,8 +20,9 @@ public:
explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvhost_as_gpu() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 9a66a5f88..ff6b1abae 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -19,8 +19,9 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface)
: nvdevice(system), events_interface{events_interface} {}
nvhost_ctrl::~nvhost_ctrl() = default;
-u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 14e6e7e57..9898623de 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -17,8 +17,9 @@ public:
explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface);
~nvhost_ctrl() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
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 988effd90..389ace76f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -15,14 +15,15 @@ namespace Service::Nvidia::Devices {
nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
-u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input,
+ const std::vector<u8>& input2, std::vector<u8>& output,
+ std::vector<u8>& output2, IoctlCtrl& ctrl, IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::IocGetCharacteristicsCommand:
- return GetCharacteristics(input, output);
+ return GetCharacteristics(input, output, output2, version);
case IoctlCommand::IocGetTPCMasksCommand:
return GetTPCMasks(input, output);
case IoctlCommand::IocGetActiveSlotMaskCommand:
@@ -44,7 +45,8 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec
return 0;
}
-u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) {
+u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output,
+ std::vector<u8>& output2, IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called");
IoctlCharacteristics params{};
std::memcpy(&params, input.data(), input.size());
@@ -85,7 +87,13 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto
params.gc.gr_compbit_store_base_hw = 0x0;
params.gpu_characteristics_buf_size = 0xA0;
params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED)
- std::memcpy(output.data(), &params, output.size());
+
+ if (version == IoctlVersion::Version3) {
+ std::memcpy(output.data(), input.data(), output.size());
+ std::memcpy(output2.data(), &params.gc, output2.size());
+ } else {
+ std::memcpy(output.data(), &params, output.size());
+ }
return 0;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index 2b035ae3f..642b0a2cb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -16,8 +16,9 @@ public:
explicit nvhost_ctrl_gpu(Core::System& system);
~nvhost_ctrl_gpu() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
@@ -162,7 +163,8 @@ private:
};
static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size");
- u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output);
+ u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output,
+ std::vector<u8>& output2, IoctlVersion version);
u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output);
u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 241dac881..2b8d1bef6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -17,8 +17,9 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev)
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
nvhost_gpu::~nvhost_gpu() = default;
-u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
@@ -50,7 +51,7 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u
return SubmitGPFIFO(input, output);
}
if (command.cmd == NVGPU_IOCTL_CHANNEL_KICKOFF_PB) {
- return KickoffPB(input, output);
+ return KickoffPB(input, output, input2, version);
}
}
@@ -146,8 +147,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
}
IoctlSubmitGpfifo params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
- params.address, params.num_entries, params.flags.raw);
+ LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address,
+ params.num_entries, params.flags.raw);
ASSERT_MSG(input.size() == sizeof(IoctlSubmitGpfifo) +
params.num_entries * sizeof(Tegra::CommandListHeader),
@@ -173,19 +174,24 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
return 0;
}
-u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) {
+u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output,
+ const std::vector<u8>& input2, IoctlVersion version) {
if (input.size() < sizeof(IoctlSubmitGpfifo)) {
UNIMPLEMENTED();
}
IoctlSubmitGpfifo params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmitGpfifo));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
- params.address, params.num_entries, params.flags.raw);
+ LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address,
+ params.num_entries, params.flags.raw);
Tegra::CommandList entries(params.num_entries);
- Memory::ReadBlock(params.address, entries.data(),
- params.num_entries * sizeof(Tegra::CommandListHeader));
-
+ if (version == IoctlVersion::Version2) {
+ std::memcpy(entries.data(), input2.data(),
+ params.num_entries * sizeof(Tegra::CommandListHeader));
+ } else {
+ Memory::ReadBlock(params.address, entries.data(),
+ params.num_entries * sizeof(Tegra::CommandListHeader));
+ }
UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0);
UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index d2e8fbae9..d056dd046 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -24,8 +24,9 @@ public:
explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvhost_gpu() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
@@ -183,7 +184,8 @@ private:
u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output);
u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output);
u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output);
- u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output);
+ u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output,
+ const std::vector<u8>& input2, IoctlVersion version);
u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index f572ad30f..bdae8b887 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices {
nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {}
nvhost_nvdec::~nvhost_nvdec() = default;
-u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 2710f0511..cbdac8069 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -16,8 +16,9 @@ public:
explicit nvhost_nvdec(Core::System& system);
~nvhost_nvdec() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index 38282956f..96e7b7dab 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices {
nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
nvhost_nvjpg::~nvhost_nvjpg() = default;
-u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 379766693..98dcac52f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -16,8 +16,9 @@ public:
explicit nvhost_nvjpg(Core::System& system);
~nvhost_nvjpg() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index 70e8091db..c695b8863 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices {
nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {}
nvhost_vic::~nvhost_vic() = default;
-u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
command.raw, input.size(), output.size());
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index 7d111977e..bec32bea1 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -16,8 +16,9 @@ public:
explicit nvhost_vic(Core::System& system);
~nvhost_vic() override;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
private:
enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 223b496b7..8c742316c 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -28,8 +28,9 @@ VAddr nvmap::GetObjectAddress(u32 handle) const {
return object->addr;
}
-u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::Create:
return IocCreate(input, output);
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index bf4a101c2..73c2e8809 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -22,8 +22,9 @@ public:
/// Returns the allocated address of an nvmap object given its handle.
VAddr GetObjectAddress(u32 handle) const;
- u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) override;
+ u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) override;
/// Represents an nvmap object.
struct Object {
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index d5be64ed2..5e0c23602 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -33,42 +33,77 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
rb.Push<u32>(0);
}
-void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_NVDRV, "called");
-
+void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) {
IPC::RequestParser rp{ctx};
u32 fd = rp.Pop<u32>();
u32 command = rp.Pop<u32>();
- std::vector<u8> output(ctx.GetWriteBufferSize());
+ /// Ioctl 3 has 2 outputs, first in the input params, second is the result
+ std::vector<u8> output(ctx.GetWriteBufferSize(0));
+ std::vector<u8> output2;
+ if (version == IoctlVersion::Version3) {
+ output2.resize((ctx.GetWriteBufferSize(1)));
+ }
+
+ /// Ioctl2 has 2 inputs. It's used to pass data directly instead of providing a pointer.
+ /// KickOfPB uses this
+ auto input = ctx.ReadBuffer(0);
+
+ std::vector<u8> input2;
+ if (version == IoctlVersion::Version2) {
+ input2 = ctx.ReadBuffer(1);
+ }
IoctlCtrl ctrl{};
- u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl);
+ u32 result = nvdrv->Ioctl(fd, command, input, input2, output, output2, ctrl, version);
if (ctrl.must_delay) {
ctrl.fresh_call = false;
- ctx.SleepClientThread(
- "NVServices::DelayedResponse", ctrl.timeout,
- [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
- Kernel::ThreadWakeupReason reason) {
- IoctlCtrl ctrl2{ctrl};
- std::vector<u8> output2 = output;
- u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output2, ctrl2);
- ctx.WriteBuffer(output2);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(result);
- },
- nvdrv->GetEventWriteable(ctrl.event_id));
+ ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout,
+ [=](Kernel::SharedPtr<Kernel::Thread> thread,
+ Kernel::HLERequestContext& ctx,
+ Kernel::ThreadWakeupReason reason) {
+ IoctlCtrl ctrl2{ctrl};
+ std::vector<u8> tmp_output = output;
+ std::vector<u8> tmp_output2 = output2;
+ u32 result = nvdrv->Ioctl(fd, command, input, input2, tmp_output,
+ tmp_output2, ctrl2, version);
+ ctx.WriteBuffer(tmp_output, 0);
+ if (version == IoctlVersion::Version3) {
+ ctx.WriteBuffer(tmp_output2, 1);
+ }
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(result);
+ },
+ nvdrv->GetEventWriteable(ctrl.event_id));
} else {
ctx.WriteBuffer(output);
+ if (version == IoctlVersion::Version3) {
+ ctx.WriteBuffer(output2, 1);
+ }
}
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(result);
}
+void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NVDRV, "called");
+ IoctlBase(ctx, IoctlVersion::Version1);
+}
+
+void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NVDRV, "called");
+ IoctlBase(ctx, IoctlVersion::Version2);
+}
+
+void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NVDRV, "called");
+ IoctlBase(ctx, IoctlVersion::Version3);
+}
+
void NVDRV::Close(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NVDRV, "called");
@@ -154,8 +189,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
{8, &NVDRV::SetClientPID, "SetClientPID"},
{9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"},
{10, nullptr, "InitializeDevtools"},
- {11, &NVDRV::Ioctl, "Ioctl2"},
- {12, nullptr, "Ioctl3"},
+ {11, &NVDRV::Ioctl2, "Ioctl2"},
+ {12, &NVDRV::Ioctl3, "Ioctl3"},
{13, &NVDRV::FinishInitialize, "FinishInitialize"},
};
RegisterHandlers(functions);
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index 10a0ecd52..9269ce00c 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -24,6 +24,8 @@ public:
private:
void Open(Kernel::HLERequestContext& ctx);
void Ioctl(Kernel::HLERequestContext& ctx);
+ void Ioctl2(Kernel::HLERequestContext& ctx);
+ void Ioctl3(Kernel::HLERequestContext& ctx);
void Close(Kernel::HLERequestContext& ctx);
void Initialize(Kernel::HLERequestContext& ctx);
void QueryEvent(Kernel::HLERequestContext& ctx);
@@ -31,6 +33,7 @@ private:
void FinishInitialize(Kernel::HLERequestContext& ctx);
void GetStatus(Kernel::HLERequestContext& ctx);
void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx);
+ void IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version);
std::shared_ptr<Module> nvdrv;
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
index ac03cbc23..529b03471 100644
--- a/src/core/hle/service/nvdrv/nvdata.h
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -34,6 +34,12 @@ enum class EventState {
Busy = 3,
};
+enum class IoctlVersion : u32 {
+ Version1,
+ Version2,
+ Version3,
+};
+
struct IoctlCtrl {
// First call done to the servioce for services that call itself again after a call.
bool fresh_call{true};
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 2011a226a..307a7e928 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -71,13 +71,14 @@ u32 Module::Open(const std::string& device_name) {
return fd;
}
-u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl) {
+u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version) {
auto itr = open_files.find(fd);
ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
auto& device = itr->second;
- return device->ioctl({command}, input, output, ctrl);
+ return device->ioctl({command}, input, input2, output, output2, ctrl, version);
}
ResultCode Module::Close(u32 fd) {
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index a339ab672..f8bb28969 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -106,8 +106,9 @@ public:
/// Opens a device node and returns a file descriptor to it.
u32 Open(const std::string& device_name);
/// Sends an ioctl command to the specified file descriptor.
- u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output,
- IoctlCtrl& ctrl);
+ u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2,
+ std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
+ IoctlVersion version);
/// Closes a device file descriptor and returns operation success.
ResultCode Close(u32 fd);
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index f9db79370..2e4d707b9 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -29,26 +29,28 @@ namespace Service::NVFlinger {
constexpr s64 frame_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60);
constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 30);
-NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_timing} {
- displays.emplace_back(0, "Default");
- displays.emplace_back(1, "External");
- displays.emplace_back(2, "Edid");
- displays.emplace_back(3, "Internal");
- displays.emplace_back(4, "Null");
+NVFlinger::NVFlinger(Core::System& system) : system(system) {
+ displays.emplace_back(0, "Default", system);
+ displays.emplace_back(1, "External", system);
+ displays.emplace_back(2, "Edid", system);
+ displays.emplace_back(3, "Internal", system);
+ displays.emplace_back(4, "Null", system);
// Schedule the screen composition events
- composition_event = core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata,
- s64 cycles_late) {
- Compose();
- const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks();
- this->core_timing.ScheduleEvent(std::max<s64>(0LL, ticks - cycles_late), composition_event);
- });
-
- core_timing.ScheduleEvent(frame_ticks, composition_event);
+ composition_event = system.CoreTiming().RegisterEvent(
+ "ScreenComposition", [this](u64 userdata, s64 cycles_late) {
+ Compose();
+ const auto ticks =
+ Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks();
+ this->system.CoreTiming().ScheduleEvent(std::max<s64>(0LL, ticks - cycles_late),
+ composition_event);
+ });
+
+ system.CoreTiming().ScheduleEvent(frame_ticks, composition_event);
}
NVFlinger::~NVFlinger() {
- core_timing.UnscheduleEvent(composition_event, 0);
+ system.CoreTiming().UnscheduleEvent(composition_event, 0);
}
void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
@@ -185,11 +187,9 @@ void NVFlinger::Compose() {
MicroProfileFlip();
if (!buffer) {
- auto& system_instance = Core::System::GetInstance();
-
// There was no queued buffer to draw, render previous frame
- system_instance.GetPerfStats().EndGameFrame();
- system_instance.GPU().SwapBuffers({});
+ system.GetPerfStats().EndGameFrame();
+ system.GPU().SwapBuffers({});
continue;
}
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 988be8726..5d7e3bfb8 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -38,7 +38,7 @@ class BufferQueue;
class NVFlinger final {
public:
- explicit NVFlinger(Core::Timing::CoreTiming& core_timing);
+ explicit NVFlinger(Core::System& system);
~NVFlinger();
/// Sets the NVDrv module instance to use to send buffers to the GPU.
@@ -105,8 +105,7 @@ private:
/// Event that handles screen composition.
Core::Timing::EventType* composition_event;
- /// Core timing instance for registering/unregistering the composition event.
- Core::Timing::CoreTiming& core_timing;
+ Core::System& system;
};
} // namespace Service::NVFlinger
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 7e134f5c1..18d895263 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -2,34 +2,31 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <json.hpp>
-#include "common/file_util.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
-#include "common/scm_rev.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/prepo/prepo.h"
#include "core/hle/service/service.h"
#include "core/reporter.h"
-#include "core/settings.h"
namespace Service::PlayReport {
class PlayReport final : public ServiceFramework<PlayReport> {
public:
- explicit PlayReport(const char* name) : ServiceFramework{name} {
+ explicit PlayReport(const char* name, Core::System& system)
+ : ServiceFramework{name}, system(system) {
// clang-format off
static const FunctionInfo functions[] = {
- {10100, nullptr, "SaveReportOld"},
- {10101, &PlayReport::SaveReportWithUserOld, "SaveReportWithUserOld"},
- {10102, nullptr, "SaveReport"},
- {10103, nullptr, "SaveReportWithUser"},
+ {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"},
+ {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"},
+ {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"},
+ {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"},
{10200, nullptr, "RequestImmediateTransmission"},
{10300, nullptr, "GetTransmissionStatus"},
- {20100, nullptr, "SaveSystemReport"},
- {20101, nullptr, "SaveSystemReportWithUser"},
+ {20100, &PlayReport::SaveSystemReport, "SaveSystemReport"},
+ {20101, &PlayReport::SaveSystemReportWithUser, "SaveSystemReportWithUser"},
{20200, nullptr, "SetOperationMode"},
{30100, nullptr, "ClearStorage"},
{30200, nullptr, "ClearStatistics"},
@@ -47,7 +44,28 @@ public:
}
private:
- void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) {
+ template <Core::Reporter::PlayReportType Type>
+ void SaveReport(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto process_id = rp.PopRaw<u64>();
+
+ const auto data1 = ctx.ReadBuffer(0);
+ const auto data2 = ctx.ReadBuffer(1);
+
+ LOG_DEBUG(Service_PREPO,
+ "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}",
+ static_cast<u8>(Type), process_id, data1.size(), data2.size());
+
+ const auto& reporter{system.GetReporter()};
+ reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
+ process_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ template <Core::Reporter::PlayReportType Type>
+ void SaveReportWithUser(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto user_id = rp.PopRaw<u128>();
const auto process_id = rp.PopRaw<u64>();
@@ -57,24 +75,65 @@ private:
LOG_DEBUG(
Service_PREPO,
- "called, user_id={:016X}{:016X}, unk1={:016X}, data1_size={:016X}, data2_size={:016X}",
- user_id[1], user_id[0], process_id, data1.size(), data2.size());
+ "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}, "
+ "data2_size={:016X}",
+ static_cast<u8>(Type), user_id[1], user_id[0], process_id, data1.size(), data2.size());
+
+ const auto& reporter{system.GetReporter()};
+ reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), {data1, data2},
+ process_id, user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ void SaveSystemReport(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto title_id = rp.PopRaw<u64>();
+
+ const auto data1 = ctx.ReadBuffer(0);
+ const auto data2 = ctx.ReadBuffer(1);
+
+ LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}",
+ title_id, data1.size(), data2.size());
+
+ const auto& reporter{system.GetReporter()};
+ reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2});
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
- const auto& reporter{Core::System::GetInstance().GetReporter()};
- reporter.SavePlayReport(Core::CurrentProcess()->GetTitleID(), process_id, {data1, data2},
- user_id);
+ void SaveSystemReportWithUser(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto user_id = rp.PopRaw<u128>();
+ const auto title_id = rp.PopRaw<u64>();
+
+ const auto data1 = ctx.ReadBuffer(0);
+ const auto data2 = ctx.ReadBuffer(1);
+
+ LOG_DEBUG(Service_PREPO,
+ "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, "
+ "data2_size={:016X}",
+ user_id[1], user_id[0], title_id, data1.size(), data2.size());
+
+ const auto& reporter{system.GetReporter()};
+ reporter.SavePlayReport(Core::Reporter::PlayReportType::System, title_id, {data1, data2},
+ std::nullopt, user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
+
+ Core::System& system;
};
-void InstallInterfaces(SM::ServiceManager& service_manager) {
- std::make_shared<PlayReport>("prepo:a")->InstallAsService(service_manager);
- std::make_shared<PlayReport>("prepo:a2")->InstallAsService(service_manager);
- std::make_shared<PlayReport>("prepo:m")->InstallAsService(service_manager);
- std::make_shared<PlayReport>("prepo:s")->InstallAsService(service_manager);
- std::make_shared<PlayReport>("prepo:u")->InstallAsService(service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
+ std::make_shared<PlayReport>("prepo:a", system)->InstallAsService(service_manager);
+ std::make_shared<PlayReport>("prepo:a2", system)->InstallAsService(service_manager);
+ std::make_shared<PlayReport>("prepo:m", system)->InstallAsService(service_manager);
+ std::make_shared<PlayReport>("prepo:s", system)->InstallAsService(service_manager);
+ std::make_shared<PlayReport>("prepo:u", system)->InstallAsService(service_manager);
}
} // namespace Service::PlayReport
diff --git a/src/core/hle/service/prepo/prepo.h b/src/core/hle/service/prepo/prepo.h
index 0e7b01331..a5682ee26 100644
--- a/src/core/hle/service/prepo/prepo.h
+++ b/src/core/hle/service/prepo/prepo.h
@@ -8,8 +8,12 @@ namespace Service::SM {
class ServiceManager;
}
+namespace Core {
+class System;
+}
+
namespace Service::PlayReport {
-void InstallInterfaces(SM::ServiceManager& service_manager);
+void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace Service::PlayReport
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 3a0f8c3f6..831a427de 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -198,49 +198,50 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
// here and pass it into the respective InstallInterfaces functions.
- auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system.CoreTiming());
+ auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system);
+ system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
SM::ServiceManager::InstallInterfaces(sm);
Account::InstallInterfaces(system);
AM::InstallInterfaces(*sm, nv_flinger, system);
- AOC::InstallInterfaces(*sm);
+ AOC::InstallInterfaces(*sm, system);
APM::InstallInterfaces(system);
Audio::InstallInterfaces(*sm, system);
BCAT::InstallInterfaces(*sm);
BPC::InstallInterfaces(*sm);
- BtDrv::InstallInterfaces(*sm);
- BTM::InstallInterfaces(*sm);
+ BtDrv::InstallInterfaces(*sm, system);
+ BTM::InstallInterfaces(*sm, system);
Capture::InstallInterfaces(*sm);
ERPT::InstallInterfaces(*sm);
ES::InstallInterfaces(*sm);
EUPLD::InstallInterfaces(*sm);
- Fatal::InstallInterfaces(*sm);
+ Fatal::InstallInterfaces(*sm, system);
FGM::InstallInterfaces(*sm);
FileSystem::InstallInterfaces(system);
- Friend::InstallInterfaces(*sm);
+ Friend::InstallInterfaces(*sm, system);
Glue::InstallInterfaces(system);
GRC::InstallInterfaces(*sm);
- HID::InstallInterfaces(*sm);
+ HID::InstallInterfaces(*sm, system);
LBL::InstallInterfaces(*sm);
LDN::InstallInterfaces(*sm);
- LDR::InstallInterfaces(*sm);
+ LDR::InstallInterfaces(*sm, system);
LM::InstallInterfaces(*sm);
Migration::InstallInterfaces(*sm);
Mii::InstallInterfaces(*sm);
MM::InstallInterfaces(*sm);
NCM::InstallInterfaces(*sm);
NFC::InstallInterfaces(*sm);
- NFP::InstallInterfaces(*sm);
- NIFM::InstallInterfaces(*sm);
- NIM::InstallInterfaces(*sm);
+ NFP::InstallInterfaces(*sm, system);
+ NIFM::InstallInterfaces(*sm, system);
+ NIM::InstallInterfaces(*sm, system);
NPNS::InstallInterfaces(*sm);
- NS::InstallInterfaces(*sm);
+ NS::InstallInterfaces(*sm, system);
Nvidia::InstallInterfaces(*sm, *nv_flinger, system);
PCIe::InstallInterfaces(*sm);
PCTL::InstallInterfaces(*sm);
PCV::InstallInterfaces(*sm);
- PlayReport::InstallInterfaces(*sm);
+ PlayReport::InstallInterfaces(*sm, system);
PM::InstallInterfaces(system);
PSC::InstallInterfaces(*sm);
PSM::InstallInterfaces(*sm);
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index c6c4bdae5..aef964861 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -18,10 +18,6 @@ namespace Core {
class System;
}
-namespace FileSys {
-class VfsFilesystem;
-}
-
namespace Kernel {
class ClientPort;
class ServerPort;
@@ -31,6 +27,10 @@ class HLERequestContext;
namespace Service {
+namespace FileSystem {
+class FileSystemController;
+} // namespace FileSystem
+
namespace SM {
class ServiceManager;
}
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp
index 1030185e0..9565e7de5 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/interface.cpp
@@ -7,8 +7,8 @@
namespace Service::Time {
Time::Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory,
- const char* name)
- : Module::Interface(std::move(time), std::move(shared_memory), name) {
+ Core::System& system, const char* name)
+ : Module::Interface(std::move(time), std::move(shared_memory), system, name) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"},
diff --git a/src/core/hle/service/time/interface.h b/src/core/hle/service/time/interface.h
index bdf0883e2..5c63a07f4 100644
--- a/src/core/hle/service/time/interface.h
+++ b/src/core/hle/service/time/interface.h
@@ -13,7 +13,7 @@ class SharedMemory;
class Time final : public Module::Interface {
public:
explicit Time(std::shared_ptr<Module> time, std::shared_ptr<SharedMemory> shared_memory,
- const char* name);
+ Core::System& system, const char* name);
~Time() override;
};
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index ae6446204..1b9ab8401 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -126,8 +126,8 @@ private:
class ISteadyClock final : public ServiceFramework<ISteadyClock> {
public:
- ISteadyClock(std::shared_ptr<SharedMemory> shared_memory)
- : ServiceFramework("ISteadyClock"), shared_memory(shared_memory) {
+ ISteadyClock(std::shared_ptr<SharedMemory> shared_memory, Core::System& system)
+ : ServiceFramework("ISteadyClock"), shared_memory(shared_memory), system(system) {
static const FunctionInfo functions[] = {
{0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"},
};
@@ -150,12 +150,13 @@ private:
}
SteadyClockTimePoint GetCurrentTimePoint() const {
- const auto& core_timing = Core::System::GetInstance().CoreTiming();
+ const auto& core_timing = system.CoreTiming();
const auto ms = Core::Timing::CyclesToMs(core_timing.GetTicks());
return {static_cast<u64_le>(ms.count() / 1000), {}};
}
std::shared_ptr<SharedMemory> shared_memory;
+ Core::System& system;
};
class ITimeZoneService final : public ServiceFramework<ITimeZoneService> {
@@ -290,7 +291,7 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ISteadyClock>(shared_memory);
+ rb.PushIpcInterface<ISteadyClock>(shared_memory, system);
}
void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
@@ -325,7 +326,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
return;
}
- const auto& core_timing = Core::System::GetInstance().CoreTiming();
+ const auto& core_timing = system.CoreTiming();
const auto ms = Core::Timing::CyclesToMs(core_timing.GetTicks());
const SteadyClockTimePoint steady_clock_time_point{static_cast<u64_le>(ms.count() / 1000), {}};
@@ -407,8 +408,10 @@ void Module::Interface::SetStandardUserSystemClockAutomaticCorrectionEnabled(
}
Module::Interface::Interface(std::shared_ptr<Module> time,
- std::shared_ptr<SharedMemory> shared_memory, const char* name)
- : ServiceFramework(name), time(std::move(time)), shared_memory(std::move(shared_memory)) {}
+ std::shared_ptr<SharedMemory> shared_memory, Core::System& system,
+ const char* name)
+ : ServiceFramework(name), time(std::move(time)), shared_memory(std::move(shared_memory)),
+ system(system) {}
Module::Interface::~Interface() = default;
@@ -416,9 +419,11 @@ void InstallInterfaces(Core::System& system) {
auto time = std::make_shared<Module>();
auto shared_mem = std::make_shared<SharedMemory>(system);
- std::make_shared<Time>(time, shared_mem, "time:a")->InstallAsService(system.ServiceManager());
- std::make_shared<Time>(time, shared_mem, "time:s")->InstallAsService(system.ServiceManager());
- std::make_shared<Time>(std::move(time), shared_mem, "time:u")
+ std::make_shared<Time>(time, shared_mem, system, "time:a")
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<Time>(time, shared_mem, system, "time:s")
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<Time>(std::move(time), shared_mem, system, "time:u")
->InstallAsService(system.ServiceManager());
}
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index e0708f856..c32d32860 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -80,7 +80,8 @@ public:
class Interface : public ServiceFramework<Interface> {
public:
explicit Interface(std::shared_ptr<Module> time,
- std::shared_ptr<SharedMemory> shared_memory, const char* name);
+ std::shared_ptr<SharedMemory> shared_memory, Core::System& system,
+ const char* name);
~Interface() override;
void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
@@ -97,6 +98,7 @@ public:
protected:
std::shared_ptr<Module> time;
std::shared_ptr<SharedMemory> shared_memory;
+ Core::System& system;
};
};
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index a8d088305..006a6d9ff 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -15,8 +15,8 @@
namespace Service::VI {
-Display::Display(u64 id, std::string name) : id{id}, name{std::move(name)} {
- auto& kernel = Core::System::GetInstance().Kernel();
+Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} {
+ auto& kernel = system.Kernel();
vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
fmt::format("Display VSync Event {}", id));
}
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h
index 2acd46ff8..f56b5badc 100644
--- a/src/core/hle/service/vi/display/vi_display.h
+++ b/src/core/hle/service/vi/display/vi_display.h
@@ -26,7 +26,7 @@ public:
/// @param id The unique ID for this display.
/// @param name The name for this display.
///
- Display(u64 id, std::string name);
+ Display(u64 id, std::string name, Core::System& system);
~Display();
Display(const Display&) = delete;