diff options
Diffstat (limited to 'src/core')
87 files changed, 1499 insertions, 412 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c59107102..2ace866ee 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -88,6 +88,10 @@ add_library(core STATIC | |||
| 88 | file_sys/vfs_vector.h | 88 | file_sys/vfs_vector.h |
| 89 | file_sys/xts_archive.cpp | 89 | file_sys/xts_archive.cpp |
| 90 | file_sys/xts_archive.h | 90 | file_sys/xts_archive.h |
| 91 | frontend/applets/error.cpp | ||
| 92 | frontend/applets/error.h | ||
| 93 | frontend/applets/general_frontend.cpp | ||
| 94 | frontend/applets/general_frontend.h | ||
| 91 | frontend/applets/profile_select.cpp | 95 | frontend/applets/profile_select.cpp |
| 92 | frontend/applets/profile_select.h | 96 | frontend/applets/profile_select.h |
| 93 | frontend/applets/software_keyboard.cpp | 97 | frontend/applets/software_keyboard.cpp |
| @@ -177,12 +181,14 @@ add_library(core STATIC | |||
| 177 | hle/service/am/applet_oe.h | 181 | hle/service/am/applet_oe.h |
| 178 | hle/service/am/applets/applets.cpp | 182 | hle/service/am/applets/applets.cpp |
| 179 | hle/service/am/applets/applets.h | 183 | hle/service/am/applets/applets.h |
| 184 | hle/service/am/applets/error.cpp | ||
| 185 | hle/service/am/applets/error.h | ||
| 186 | hle/service/am/applets/general_backend.cpp | ||
| 187 | hle/service/am/applets/general_backend.h | ||
| 180 | hle/service/am/applets/profile_select.cpp | 188 | hle/service/am/applets/profile_select.cpp |
| 181 | hle/service/am/applets/profile_select.h | 189 | hle/service/am/applets/profile_select.h |
| 182 | hle/service/am/applets/software_keyboard.cpp | 190 | hle/service/am/applets/software_keyboard.cpp |
| 183 | hle/service/am/applets/software_keyboard.h | 191 | hle/service/am/applets/software_keyboard.h |
| 184 | hle/service/am/applets/stub_applet.cpp | ||
| 185 | hle/service/am/applets/stub_applet.h | ||
| 186 | hle/service/am/applets/web_browser.cpp | 192 | hle/service/am/applets/web_browser.cpp |
| 187 | hle/service/am/applets/web_browser.h | 193 | hle/service/am/applets/web_browser.h |
| 188 | hle/service/am/idle.cpp | 194 | hle/service/am/idle.cpp |
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 4dfd41b43..978b1518f 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -7,6 +7,10 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | namespace Common { | ||
| 11 | struct PageTable; | ||
| 12 | } | ||
| 13 | |||
| 10 | namespace Kernel { | 14 | namespace Kernel { |
| 11 | enum class VMAPermission : u8; | 15 | enum class VMAPermission : u8; |
| 12 | } | 16 | } |
| @@ -49,8 +53,14 @@ public: | |||
| 49 | /// Clear all instruction cache | 53 | /// Clear all instruction cache |
| 50 | virtual void ClearInstructionCache() = 0; | 54 | virtual void ClearInstructionCache() = 0; |
| 51 | 55 | ||
| 52 | /// Notify CPU emulation that page tables have changed | 56 | /// Notifies CPU emulation that the current page table has changed. |
| 53 | virtual void PageTableChanged() = 0; | 57 | /// |
| 58 | /// @param new_page_table The new page table. | ||
| 59 | /// @param new_address_space_size_in_bits The new usable size of the address space in bits. | ||
| 60 | /// This can be either 32, 36, or 39 on official software. | ||
| 61 | /// | ||
| 62 | virtual void PageTableChanged(Common::PageTable& new_page_table, | ||
| 63 | std::size_t new_address_space_size_in_bits) = 0; | ||
| 54 | 64 | ||
| 55 | /** | 65 | /** |
| 56 | * Set the Program Counter to an address | 66 | * Set the Program Counter to an address |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index dc96e35d5..44307fa19 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include "core/core_timing.h" | 14 | #include "core/core_timing.h" |
| 15 | #include "core/core_timing_util.h" | 15 | #include "core/core_timing_util.h" |
| 16 | #include "core/gdbstub/gdbstub.h" | 16 | #include "core/gdbstub/gdbstub.h" |
| 17 | #include "core/hle/kernel/kernel.h" | ||
| 18 | #include "core/hle/kernel/process.h" | 17 | #include "core/hle/kernel/process.h" |
| 19 | #include "core/hle/kernel/svc.h" | 18 | #include "core/hle/kernel/svc.h" |
| 20 | #include "core/hle/kernel/vm_manager.h" | 19 | #include "core/hle/kernel/vm_manager.h" |
| @@ -129,18 +128,16 @@ public: | |||
| 129 | u64 tpidr_el0 = 0; | 128 | u64 tpidr_el0 = 0; |
| 130 | }; | 129 | }; |
| 131 | 130 | ||
| 132 | std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { | 131 | std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit(Common::PageTable& page_table, |
| 133 | auto* current_process = system.Kernel().CurrentProcess(); | 132 | std::size_t address_space_bits) const { |
| 134 | auto** const page_table = current_process->VMManager().page_table.pointers.data(); | ||
| 135 | |||
| 136 | Dynarmic::A64::UserConfig config; | 133 | Dynarmic::A64::UserConfig config; |
| 137 | 134 | ||
| 138 | // Callbacks | 135 | // Callbacks |
| 139 | config.callbacks = cb.get(); | 136 | config.callbacks = cb.get(); |
| 140 | 137 | ||
| 141 | // Memory | 138 | // Memory |
| 142 | config.page_table = reinterpret_cast<void**>(page_table); | 139 | config.page_table = reinterpret_cast<void**>(page_table.pointers.data()); |
| 143 | config.page_table_address_space_bits = current_process->VMManager().GetAddressSpaceWidth(); | 140 | config.page_table_address_space_bits = address_space_bits; |
| 144 | config.silently_mirror_page_table = false; | 141 | config.silently_mirror_page_table = false; |
| 145 | 142 | ||
| 146 | // Multi-process state | 143 | // Multi-process state |
| @@ -176,12 +173,7 @@ ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor, | |||
| 176 | std::size_t core_index) | 173 | std::size_t core_index) |
| 177 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system}, | 174 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system}, |
| 178 | core_index{core_index}, system{system}, | 175 | core_index{core_index}, system{system}, |
| 179 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} { | 176 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} |
| 180 | ThreadContext ctx{}; | ||
| 181 | inner_unicorn.SaveContext(ctx); | ||
| 182 | PageTableChanged(); | ||
| 183 | LoadContext(ctx); | ||
| 184 | } | ||
| 185 | 177 | ||
| 186 | ARM_Dynarmic::~ARM_Dynarmic() = default; | 178 | ARM_Dynarmic::~ARM_Dynarmic() = default; |
| 187 | 179 | ||
| @@ -276,8 +268,9 @@ void ARM_Dynarmic::ClearExclusiveState() { | |||
| 276 | jit->ClearExclusiveState(); | 268 | jit->ClearExclusiveState(); |
| 277 | } | 269 | } |
| 278 | 270 | ||
| 279 | void ARM_Dynarmic::PageTableChanged() { | 271 | void ARM_Dynarmic::PageTableChanged(Common::PageTable& page_table, |
| 280 | jit = MakeJit(); | 272 | std::size_t new_address_space_size_in_bits) { |
| 273 | jit = MakeJit(page_table, new_address_space_size_in_bits); | ||
| 281 | } | 274 | } |
| 282 | 275 | ||
| 283 | DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(std::size_t core_count) : monitor(core_count) {} | 276 | DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(std::size_t core_count) : monitor(core_count) {} |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index c1db254e8..b701e97a3 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -48,10 +48,12 @@ public: | |||
| 48 | void ClearExclusiveState() override; | 48 | void ClearExclusiveState() override; |
| 49 | 49 | ||
| 50 | void ClearInstructionCache() override; | 50 | void ClearInstructionCache() override; |
| 51 | void PageTableChanged() override; | 51 | void PageTableChanged(Common::PageTable& new_page_table, |
| 52 | std::size_t new_address_space_size_in_bits) override; | ||
| 52 | 53 | ||
| 53 | private: | 54 | private: |
| 54 | std::unique_ptr<Dynarmic::A64::Jit> MakeJit() const; | 55 | std::unique_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable& page_table, |
| 56 | std::size_t address_space_bits) const; | ||
| 55 | 57 | ||
| 56 | friend class ARM_Dynarmic_Callbacks; | 58 | friend class ARM_Dynarmic_Callbacks; |
| 57 | std::unique_ptr<ARM_Dynarmic_Callbacks> cb; | 59 | std::unique_ptr<ARM_Dynarmic_Callbacks> cb; |
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index 209fc16ad..34e974b4d 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h | |||
| @@ -41,7 +41,7 @@ public: | |||
| 41 | void Run() override; | 41 | void Run() override; |
| 42 | void Step() override; | 42 | void Step() override; |
| 43 | void ClearInstructionCache() override; | 43 | void ClearInstructionCache() override; |
| 44 | void PageTableChanged() override{}; | 44 | void PageTableChanged(Common::PageTable&, std::size_t) override {} |
| 45 | void RecordBreak(GDBStub::BreakpointAddress bkpt); | 45 | void RecordBreak(GDBStub::BreakpointAddress bkpt); |
| 46 | 46 | ||
| 47 | private: | 47 | private: |
diff --git a/src/core/core.cpp b/src/core/core.cpp index bc9e887b6..7106151bd 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -3,9 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <map> | ||
| 7 | #include <memory> | 6 | #include <memory> |
| 8 | #include <thread> | ||
| 9 | #include <utility> | 7 | #include <utility> |
| 10 | 8 | ||
| 11 | #include "common/file_util.h" | 9 | #include "common/file_util.h" |
| @@ -20,13 +18,18 @@ | |||
| 20 | #include "core/file_sys/registered_cache.h" | 18 | #include "core/file_sys/registered_cache.h" |
| 21 | #include "core/file_sys/vfs_concat.h" | 19 | #include "core/file_sys/vfs_concat.h" |
| 22 | #include "core/file_sys/vfs_real.h" | 20 | #include "core/file_sys/vfs_real.h" |
| 21 | #include "core/frontend/applets/error.h" | ||
| 22 | #include "core/frontend/applets/general_frontend.h" | ||
| 23 | #include "core/frontend/applets/profile_select.h" | ||
| 24 | #include "core/frontend/applets/software_keyboard.h" | ||
| 25 | #include "core/frontend/applets/web_browser.h" | ||
| 23 | #include "core/gdbstub/gdbstub.h" | 26 | #include "core/gdbstub/gdbstub.h" |
| 24 | #include "core/hle/kernel/client_port.h" | 27 | #include "core/hle/kernel/client_port.h" |
| 25 | #include "core/hle/kernel/kernel.h" | 28 | #include "core/hle/kernel/kernel.h" |
| 26 | #include "core/hle/kernel/process.h" | 29 | #include "core/hle/kernel/process.h" |
| 27 | #include "core/hle/kernel/scheduler.h" | 30 | #include "core/hle/kernel/scheduler.h" |
| 28 | #include "core/hle/kernel/thread.h" | 31 | #include "core/hle/kernel/thread.h" |
| 29 | #include "core/hle/service/am/applets/software_keyboard.h" | 32 | #include "core/hle/service/am/applets/applets.h" |
| 30 | #include "core/hle/service/service.h" | 33 | #include "core/hle/service/service.h" |
| 31 | #include "core/hle/service/sm/sm.h" | 34 | #include "core/hle/service/sm/sm.h" |
| 32 | #include "core/loader/loader.h" | 35 | #include "core/loader/loader.h" |
| @@ -38,8 +41,6 @@ | |||
| 38 | #include "frontend/applets/software_keyboard.h" | 41 | #include "frontend/applets/software_keyboard.h" |
| 39 | #include "frontend/applets/web_browser.h" | 42 | #include "frontend/applets/web_browser.h" |
| 40 | #include "video_core/debug_utils/debug_utils.h" | 43 | #include "video_core/debug_utils/debug_utils.h" |
| 41 | #include "video_core/gpu_asynch.h" | ||
| 42 | #include "video_core/gpu_synch.h" | ||
| 43 | #include "video_core/renderer_base.h" | 44 | #include "video_core/renderer_base.h" |
| 44 | #include "video_core/video_core.h" | 45 | #include "video_core/video_core.h" |
| 45 | 46 | ||
| @@ -81,7 +82,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | |||
| 81 | return vfs->OpenFile(path, FileSys::Mode::Read); | 82 | return vfs->OpenFile(path, FileSys::Mode::Read); |
| 82 | } | 83 | } |
| 83 | struct System::Impl { | 84 | struct System::Impl { |
| 84 | explicit Impl(System& system) : kernel{system} {} | 85 | explicit Impl(System& system) : kernel{system}, cpu_core_manager{system} {} |
| 85 | 86 | ||
| 86 | Cpu& CurrentCpuCore() { | 87 | Cpu& CurrentCpuCore() { |
| 87 | return cpu_core_manager.GetCurrentCore(); | 88 | return cpu_core_manager.GetCurrentCore(); |
| @@ -99,6 +100,7 @@ struct System::Impl { | |||
| 99 | LOG_DEBUG(HW_Memory, "initialized OK"); | 100 | LOG_DEBUG(HW_Memory, "initialized OK"); |
| 100 | 101 | ||
| 101 | core_timing.Initialize(); | 102 | core_timing.Initialize(); |
| 103 | cpu_core_manager.Initialize(); | ||
| 102 | kernel.Initialize(); | 104 | kernel.Initialize(); |
| 103 | 105 | ||
| 104 | const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( | 106 | const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( |
| @@ -113,15 +115,7 @@ struct System::Impl { | |||
| 113 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); | 115 | content_provider = std::make_unique<FileSys::ContentProviderUnion>(); |
| 114 | 116 | ||
| 115 | /// Create default implementations of applets if one is not provided. | 117 | /// Create default implementations of applets if one is not provided. |
| 116 | if (profile_selector == nullptr) | 118 | applet_manager.SetDefaultAppletsIfMissing(); |
| 117 | profile_selector = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); | ||
| 118 | if (software_keyboard == nullptr) | ||
| 119 | software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); | ||
| 120 | if (web_browser == nullptr) | ||
| 121 | web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); | ||
| 122 | |||
| 123 | auto main_process = Kernel::Process::Create(system, "main"); | ||
| 124 | kernel.MakeCurrentProcess(main_process.get()); | ||
| 125 | 119 | ||
| 126 | telemetry_session = std::make_unique<Core::TelemetrySession>(); | 120 | telemetry_session = std::make_unique<Core::TelemetrySession>(); |
| 127 | service_manager = std::make_shared<Service::SM::ServiceManager>(); | 121 | service_manager = std::make_shared<Service::SM::ServiceManager>(); |
| @@ -134,15 +128,9 @@ struct System::Impl { | |||
| 134 | return ResultStatus::ErrorVideoCore; | 128 | return ResultStatus::ErrorVideoCore; |
| 135 | } | 129 | } |
| 136 | 130 | ||
| 137 | is_powered_on = true; | 131 | gpu_core = VideoCore::CreateGPU(system); |
| 138 | 132 | ||
| 139 | if (Settings::values.use_asynchronous_gpu_emulation) { | 133 | is_powered_on = true; |
| 140 | gpu_core = std::make_unique<VideoCommon::GPUAsynch>(system, *renderer); | ||
| 141 | } else { | ||
| 142 | gpu_core = std::make_unique<VideoCommon::GPUSynch>(system, *renderer); | ||
| 143 | } | ||
| 144 | |||
| 145 | cpu_core_manager.Initialize(system); | ||
| 146 | 134 | ||
| 147 | LOG_DEBUG(Core, "Initialized OK"); | 135 | LOG_DEBUG(Core, "Initialized OK"); |
| 148 | 136 | ||
| @@ -179,7 +167,8 @@ struct System::Impl { | |||
| 179 | return init_result; | 167 | return init_result; |
| 180 | } | 168 | } |
| 181 | 169 | ||
| 182 | const Loader::ResultStatus load_result{app_loader->Load(*kernel.CurrentProcess())}; | 170 | auto main_process = Kernel::Process::Create(system, "main"); |
| 171 | const auto [load_result, load_parameters] = app_loader->Load(*main_process); | ||
| 183 | if (load_result != Loader::ResultStatus::Success) { | 172 | if (load_result != Loader::ResultStatus::Success) { |
| 184 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); | 173 | LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); |
| 185 | Shutdown(); | 174 | Shutdown(); |
| @@ -187,6 +176,16 @@ struct System::Impl { | |||
| 187 | return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + | 176 | return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + |
| 188 | static_cast<u32>(load_result)); | 177 | static_cast<u32>(load_result)); |
| 189 | } | 178 | } |
| 179 | kernel.MakeCurrentProcess(main_process.get()); | ||
| 180 | |||
| 181 | // Main process has been loaded and been made current. | ||
| 182 | // Begin GPU and CPU execution. | ||
| 183 | gpu_core->Start(); | ||
| 184 | cpu_core_manager.StartThreads(); | ||
| 185 | |||
| 186 | // All threads are started, begin main process execution, now that we're in the clear. | ||
| 187 | main_process->Run(load_parameters->main_thread_priority, | ||
| 188 | load_parameters->main_thread_stack_size); | ||
| 190 | 189 | ||
| 191 | status = ResultStatus::Success; | 190 | status = ResultStatus::Success; |
| 192 | return status; | 191 | return status; |
| @@ -224,9 +223,7 @@ struct System::Impl { | |||
| 224 | app_loader.reset(); | 223 | app_loader.reset(); |
| 225 | 224 | ||
| 226 | // Clear all applets | 225 | // Clear all applets |
| 227 | profile_selector.reset(); | 226 | applet_manager.ClearAll(); |
| 228 | software_keyboard.reset(); | ||
| 229 | web_browser.reset(); | ||
| 230 | 227 | ||
| 231 | LOG_DEBUG(Core, "Shutdown OK"); | 228 | LOG_DEBUG(Core, "Shutdown OK"); |
| 232 | } | 229 | } |
| @@ -265,9 +262,7 @@ struct System::Impl { | |||
| 265 | std::unique_ptr<FileSys::CheatEngine> cheat_engine; | 262 | std::unique_ptr<FileSys::CheatEngine> cheat_engine; |
| 266 | 263 | ||
| 267 | /// Frontend applets | 264 | /// Frontend applets |
| 268 | std::unique_ptr<Core::Frontend::ProfileSelectApplet> profile_selector; | 265 | Service::AM::Applets::AppletManager applet_manager; |
| 269 | std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard; | ||
| 270 | std::unique_ptr<Core::Frontend::WebBrowserApplet> web_browser; | ||
| 271 | 266 | ||
| 272 | /// Service manager | 267 | /// Service manager |
| 273 | std::shared_ptr<Service::SM::ServiceManager> service_manager; | 268 | std::shared_ptr<Service::SM::ServiceManager> service_manager; |
| @@ -477,20 +472,20 @@ std::shared_ptr<FileSys::VfsFilesystem> System::GetFilesystem() const { | |||
| 477 | return impl->virtual_filesystem; | 472 | return impl->virtual_filesystem; |
| 478 | } | 473 | } |
| 479 | 474 | ||
| 480 | void System::SetProfileSelector(std::unique_ptr<Frontend::ProfileSelectApplet> applet) { | 475 | void System::SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set) { |
| 481 | impl->profile_selector = std::move(applet); | 476 | impl->applet_manager.SetAppletFrontendSet(std::move(set)); |
| 482 | } | 477 | } |
| 483 | 478 | ||
| 484 | const Frontend::ProfileSelectApplet& System::GetProfileSelector() const { | 479 | void System::SetDefaultAppletFrontendSet() { |
| 485 | return *impl->profile_selector; | 480 | impl->applet_manager.SetDefaultAppletFrontendSet(); |
| 486 | } | 481 | } |
| 487 | 482 | ||
| 488 | void System::SetSoftwareKeyboard(std::unique_ptr<Frontend::SoftwareKeyboardApplet> applet) { | 483 | Service::AM::Applets::AppletManager& System::GetAppletManager() { |
| 489 | impl->software_keyboard = std::move(applet); | 484 | return impl->applet_manager; |
| 490 | } | 485 | } |
| 491 | 486 | ||
| 492 | const Frontend::SoftwareKeyboardApplet& System::GetSoftwareKeyboard() const { | 487 | const Service::AM::Applets::AppletManager& System::GetAppletManager() const { |
| 493 | return *impl->software_keyboard; | 488 | return impl->applet_manager; |
| 494 | } | 489 | } |
| 495 | 490 | ||
| 496 | void System::SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider) { | 491 | void System::SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider) { |
| @@ -514,18 +509,6 @@ void System::ClearContentProvider(FileSys::ContentProviderUnionSlot slot) { | |||
| 514 | impl->content_provider->ClearSlot(slot); | 509 | impl->content_provider->ClearSlot(slot); |
| 515 | } | 510 | } |
| 516 | 511 | ||
| 517 | void System::SetWebBrowser(std::unique_ptr<Frontend::WebBrowserApplet> applet) { | ||
| 518 | impl->web_browser = std::move(applet); | ||
| 519 | } | ||
| 520 | |||
| 521 | Frontend::WebBrowserApplet& System::GetWebBrowser() { | ||
| 522 | return *impl->web_browser; | ||
| 523 | } | ||
| 524 | |||
| 525 | const Frontend::WebBrowserApplet& System::GetWebBrowser() const { | ||
| 526 | return *impl->web_browser; | ||
| 527 | } | ||
| 528 | |||
| 529 | System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { | 512 | System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { |
| 530 | return impl->Init(*this, emu_window); | 513 | return impl->Init(*this, emu_window); |
| 531 | } | 514 | } |
diff --git a/src/core/core.h b/src/core/core.h index 82b2e087e..a9a756a4c 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -14,9 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | namespace Core::Frontend { | 15 | namespace Core::Frontend { |
| 16 | class EmuWindow; | 16 | class EmuWindow; |
| 17 | class ProfileSelectApplet; | ||
| 18 | class SoftwareKeyboardApplet; | ||
| 19 | class WebBrowserApplet; | ||
| 20 | } // namespace Core::Frontend | 17 | } // namespace Core::Frontend |
| 21 | 18 | ||
| 22 | namespace FileSys { | 19 | namespace FileSys { |
| @@ -38,9 +35,18 @@ class AppLoader; | |||
| 38 | enum class ResultStatus : u16; | 35 | enum class ResultStatus : u16; |
| 39 | } // namespace Loader | 36 | } // namespace Loader |
| 40 | 37 | ||
| 41 | namespace Service::SM { | 38 | namespace Service { |
| 39 | |||
| 40 | namespace AM::Applets { | ||
| 41 | struct AppletFrontendSet; | ||
| 42 | class AppletManager; | ||
| 43 | } // namespace AM::Applets | ||
| 44 | |||
| 45 | namespace SM { | ||
| 42 | class ServiceManager; | 46 | class ServiceManager; |
| 43 | } // namespace Service::SM | 47 | } // namespace SM |
| 48 | |||
| 49 | } // namespace Service | ||
| 44 | 50 | ||
| 45 | namespace Tegra { | 51 | namespace Tegra { |
| 46 | class DebugContext; | 52 | class DebugContext; |
| @@ -260,18 +266,13 @@ public: | |||
| 260 | void RegisterCheatList(const std::vector<FileSys::CheatList>& list, const std::string& build_id, | 266 | void RegisterCheatList(const std::vector<FileSys::CheatList>& list, const std::string& build_id, |
| 261 | VAddr code_region_start, VAddr code_region_end); | 267 | VAddr code_region_start, VAddr code_region_end); |
| 262 | 268 | ||
| 263 | void SetProfileSelector(std::unique_ptr<Frontend::ProfileSelectApplet> applet); | 269 | void SetAppletFrontendSet(Service::AM::Applets::AppletFrontendSet&& set); |
| 264 | |||
| 265 | const Frontend::ProfileSelectApplet& GetProfileSelector() const; | ||
| 266 | |||
| 267 | void SetSoftwareKeyboard(std::unique_ptr<Frontend::SoftwareKeyboardApplet> applet); | ||
| 268 | 270 | ||
| 269 | const Frontend::SoftwareKeyboardApplet& GetSoftwareKeyboard() const; | 271 | void SetDefaultAppletFrontendSet(); |
| 270 | 272 | ||
| 271 | void SetWebBrowser(std::unique_ptr<Frontend::WebBrowserApplet> applet); | 273 | Service::AM::Applets::AppletManager& GetAppletManager(); |
| 272 | 274 | ||
| 273 | Frontend::WebBrowserApplet& GetWebBrowser(); | 275 | const Service::AM::Applets::AppletManager& GetAppletManager() const; |
| 274 | const Frontend::WebBrowserApplet& GetWebBrowser() const; | ||
| 275 | 276 | ||
| 276 | void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider); | 277 | void SetContentProvider(std::unique_ptr<FileSys::ContentProviderUnion> provider); |
| 277 | 278 | ||
diff --git a/src/core/cpu_core_manager.cpp b/src/core/cpu_core_manager.cpp index 93bc5619c..8fcb4eeb1 100644 --- a/src/core/cpu_core_manager.cpp +++ b/src/core/cpu_core_manager.cpp | |||
| @@ -19,17 +19,19 @@ void RunCpuCore(const System& system, Cpu& cpu_state) { | |||
| 19 | } | 19 | } |
| 20 | } // Anonymous namespace | 20 | } // Anonymous namespace |
| 21 | 21 | ||
| 22 | CpuCoreManager::CpuCoreManager() = default; | 22 | CpuCoreManager::CpuCoreManager(System& system) : system{system} {} |
| 23 | CpuCoreManager::~CpuCoreManager() = default; | 23 | CpuCoreManager::~CpuCoreManager() = default; |
| 24 | 24 | ||
| 25 | void CpuCoreManager::Initialize(System& system) { | 25 | void CpuCoreManager::Initialize() { |
| 26 | barrier = std::make_unique<CpuBarrier>(); | 26 | barrier = std::make_unique<CpuBarrier>(); |
| 27 | exclusive_monitor = Cpu::MakeExclusiveMonitor(cores.size()); | 27 | exclusive_monitor = Cpu::MakeExclusiveMonitor(cores.size()); |
| 28 | 28 | ||
| 29 | for (std::size_t index = 0; index < cores.size(); ++index) { | 29 | for (std::size_t index = 0; index < cores.size(); ++index) { |
| 30 | cores[index] = std::make_unique<Cpu>(system, *exclusive_monitor, *barrier, index); | 30 | cores[index] = std::make_unique<Cpu>(system, *exclusive_monitor, *barrier, index); |
| 31 | } | 31 | } |
| 32 | } | ||
| 32 | 33 | ||
| 34 | void CpuCoreManager::StartThreads() { | ||
| 33 | // Create threads for CPU cores 1-3, and build thread_to_cpu map | 35 | // Create threads for CPU cores 1-3, and build thread_to_cpu map |
| 34 | // CPU core 0 is run on the main thread | 36 | // CPU core 0 is run on the main thread |
| 35 | thread_to_cpu[std::this_thread::get_id()] = cores[0].get(); | 37 | thread_to_cpu[std::this_thread::get_id()] = cores[0].get(); |
diff --git a/src/core/cpu_core_manager.h b/src/core/cpu_core_manager.h index a4d70ec56..2cbbf8216 100644 --- a/src/core/cpu_core_manager.h +++ b/src/core/cpu_core_manager.h | |||
| @@ -18,7 +18,7 @@ class System; | |||
| 18 | 18 | ||
| 19 | class CpuCoreManager { | 19 | class CpuCoreManager { |
| 20 | public: | 20 | public: |
| 21 | CpuCoreManager(); | 21 | explicit CpuCoreManager(System& system); |
| 22 | CpuCoreManager(const CpuCoreManager&) = delete; | 22 | CpuCoreManager(const CpuCoreManager&) = delete; |
| 23 | CpuCoreManager(CpuCoreManager&&) = delete; | 23 | CpuCoreManager(CpuCoreManager&&) = delete; |
| 24 | 24 | ||
| @@ -27,7 +27,8 @@ public: | |||
| 27 | CpuCoreManager& operator=(const CpuCoreManager&) = delete; | 27 | CpuCoreManager& operator=(const CpuCoreManager&) = delete; |
| 28 | CpuCoreManager& operator=(CpuCoreManager&&) = delete; | 28 | CpuCoreManager& operator=(CpuCoreManager&&) = delete; |
| 29 | 29 | ||
| 30 | void Initialize(System& system); | 30 | void Initialize(); |
| 31 | void StartThreads(); | ||
| 31 | void Shutdown(); | 32 | void Shutdown(); |
| 32 | 33 | ||
| 33 | Cpu& GetCore(std::size_t index); | 34 | Cpu& GetCore(std::size_t index); |
| @@ -54,6 +55,8 @@ private: | |||
| 54 | 55 | ||
| 55 | /// Map of guest threads to CPU cores | 56 | /// Map of guest threads to CPU cores |
| 56 | std::map<std::thread::id, Cpu*> thread_to_cpu; | 57 | std::map<std::thread::id, Cpu*> thread_to_cpu; |
| 58 | |||
| 59 | System& system; | ||
| 57 | }; | 60 | }; |
| 58 | 61 | ||
| 59 | } // namespace Core | 62 | } // namespace Core |
diff --git a/src/core/frontend/applets/error.cpp b/src/core/frontend/applets/error.cpp new file mode 100644 index 000000000..4002a9211 --- /dev/null +++ b/src/core/frontend/applets/error.cpp | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/frontend/applets/error.h" | ||
| 6 | |||
| 7 | namespace Core::Frontend { | ||
| 8 | |||
| 9 | ErrorApplet::~ErrorApplet() = default; | ||
| 10 | |||
| 11 | void DefaultErrorApplet::ShowError(ResultCode error, std::function<void()> finished) const { | ||
| 12 | LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", | ||
| 13 | static_cast<u32>(error.module.Value()), error.description.Value(), error.raw); | ||
| 14 | } | ||
| 15 | |||
| 16 | void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 17 | std::function<void()> finished) const { | ||
| 18 | LOG_CRITICAL( | ||
| 19 | Service_Fatal, | ||
| 20 | "Application requested error display: {:04X}-{:04X} (raw={:08X}) with timestamp={:016X}", | ||
| 21 | static_cast<u32>(error.module.Value()), error.description.Value(), error.raw, time.count()); | ||
| 22 | } | ||
| 23 | |||
| 24 | void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_text, | ||
| 25 | std::string detail_text, | ||
| 26 | std::function<void()> finished) const { | ||
| 27 | LOG_CRITICAL(Service_Fatal, | ||
| 28 | "Application requested custom error with error_code={:04X}-{:04X} (raw={:08X})", | ||
| 29 | static_cast<u32>(error.module.Value()), error.description.Value(), error.raw); | ||
| 30 | LOG_CRITICAL(Service_Fatal, " Main Text: {}", main_text); | ||
| 31 | LOG_CRITICAL(Service_Fatal, " Detail Text: {}", detail_text); | ||
| 32 | } | ||
| 33 | |||
| 34 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/error.h b/src/core/frontend/applets/error.h new file mode 100644 index 000000000..699df940d --- /dev/null +++ b/src/core/frontend/applets/error.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <chrono> | ||
| 8 | #include <functional> | ||
| 9 | |||
| 10 | #include "core/hle/result.h" | ||
| 11 | |||
| 12 | namespace Core::Frontend { | ||
| 13 | |||
| 14 | class ErrorApplet { | ||
| 15 | public: | ||
| 16 | virtual ~ErrorApplet(); | ||
| 17 | |||
| 18 | virtual void ShowError(ResultCode error, std::function<void()> finished) const = 0; | ||
| 19 | |||
| 20 | virtual void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 21 | std::function<void()> finished) const = 0; | ||
| 22 | |||
| 23 | virtual void ShowCustomErrorText(ResultCode error, std::string dialog_text, | ||
| 24 | std::string fullscreen_text, | ||
| 25 | std::function<void()> finished) const = 0; | ||
| 26 | }; | ||
| 27 | |||
| 28 | class DefaultErrorApplet final : public ErrorApplet { | ||
| 29 | public: | ||
| 30 | void ShowError(ResultCode error, std::function<void()> finished) const override; | ||
| 31 | void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, | ||
| 32 | std::function<void()> finished) const override; | ||
| 33 | void ShowCustomErrorText(ResultCode error, std::string main_text, std::string detail_text, | ||
| 34 | std::function<void()> finished) const override; | ||
| 35 | }; | ||
| 36 | |||
| 37 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/general_frontend.cpp b/src/core/frontend/applets/general_frontend.cpp new file mode 100644 index 000000000..b974f2289 --- /dev/null +++ b/src/core/frontend/applets/general_frontend.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/frontend/applets/general_frontend.h" | ||
| 7 | |||
| 8 | namespace Core::Frontend { | ||
| 9 | |||
| 10 | PhotoViewerApplet::~PhotoViewerApplet() = default; | ||
| 11 | |||
| 12 | DefaultPhotoViewerApplet::~DefaultPhotoViewerApplet() {} | ||
| 13 | |||
| 14 | void DefaultPhotoViewerApplet::ShowPhotosForApplication(u64 title_id, | ||
| 15 | std::function<void()> finished) const { | ||
| 16 | LOG_INFO(Service_AM, | ||
| 17 | "Application requested frontend to display stored photos for title_id={:016X}", | ||
| 18 | title_id); | ||
| 19 | finished(); | ||
| 20 | } | ||
| 21 | |||
| 22 | void DefaultPhotoViewerApplet::ShowAllPhotos(std::function<void()> finished) const { | ||
| 23 | LOG_INFO(Service_AM, "Application requested frontend to display all stored photos."); | ||
| 24 | finished(); | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace Core::Frontend | ||
diff --git a/src/core/frontend/applets/general_frontend.h b/src/core/frontend/applets/general_frontend.h new file mode 100644 index 000000000..d4506c999 --- /dev/null +++ b/src/core/frontend/applets/general_frontend.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <functional> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | namespace Core::Frontend { | ||
| 11 | |||
| 12 | class PhotoViewerApplet { | ||
| 13 | public: | ||
| 14 | virtual ~PhotoViewerApplet(); | ||
| 15 | |||
| 16 | virtual void ShowPhotosForApplication(u64 title_id, std::function<void()> finished) const = 0; | ||
| 17 | virtual void ShowAllPhotos(std::function<void()> finished) const = 0; | ||
| 18 | }; | ||
| 19 | |||
| 20 | class DefaultPhotoViewerApplet final : public PhotoViewerApplet { | ||
| 21 | public: | ||
| 22 | ~DefaultPhotoViewerApplet() override; | ||
| 23 | |||
| 24 | void ShowPhotosForApplication(u64 title_id, std::function<void()> finished) const override; | ||
| 25 | void ShowAllPhotos(std::function<void()> finished) const override; | ||
| 26 | }; | ||
| 27 | |||
| 28 | } // namespace Core::Frontend | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 4d58e7c69..757e5f21f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -46,8 +46,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | |||
| 46 | 46 | ||
| 47 | bool resume = true; | 47 | bool resume = true; |
| 48 | 48 | ||
| 49 | if (thread->GetStatus() == ThreadStatus::WaitSynchAny || | 49 | if (thread->GetStatus() == ThreadStatus::WaitSynch || |
| 50 | thread->GetStatus() == ThreadStatus::WaitSynchAll || | ||
| 51 | thread->GetStatus() == ThreadStatus::WaitHLEEvent) { | 50 | thread->GetStatus() == ThreadStatus::WaitHLEEvent) { |
| 52 | // Remove the thread from each of its waiting objects' waitlists | 51 | // Remove the thread from each of its waiting objects' waitlists |
| 53 | for (const auto& object : thread->GetWaitObjects()) { | 52 | for (const auto& object : thread->GetWaitObjects()) { |
| @@ -182,7 +181,12 @@ void KernelCore::AppendNewProcess(SharedPtr<Process> process) { | |||
| 182 | 181 | ||
| 183 | void KernelCore::MakeCurrentProcess(Process* process) { | 182 | void KernelCore::MakeCurrentProcess(Process* process) { |
| 184 | impl->current_process = process; | 183 | impl->current_process = process; |
| 185 | Memory::SetCurrentPageTable(&process->VMManager().page_table); | 184 | |
| 185 | if (process == nullptr) { | ||
| 186 | return; | ||
| 187 | } | ||
| 188 | |||
| 189 | Memory::SetCurrentPageTable(*process); | ||
| 186 | } | 190 | } |
| 187 | 191 | ||
| 188 | Process* KernelCore::CurrentProcess() { | 192 | Process* KernelCore::CurrentProcess() { |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 4e94048da..20d01fc88 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -28,21 +28,20 @@ namespace { | |||
| 28 | * | 28 | * |
| 29 | * @param owner_process The parent process for the main thread | 29 | * @param owner_process The parent process for the main thread |
| 30 | * @param kernel The kernel instance to create the main thread under. | 30 | * @param kernel The kernel instance to create the main thread under. |
| 31 | * @param entry_point The address at which the thread should start execution | ||
| 32 | * @param priority The priority to give the main thread | 31 | * @param priority The priority to give the main thread |
| 33 | */ | 32 | */ |
| 34 | void SetupMainThread(Process& owner_process, KernelCore& kernel, VAddr entry_point, u32 priority) { | 33 | void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) { |
| 35 | // Initialize new "main" thread | 34 | const auto& vm_manager = owner_process.VMManager(); |
| 36 | const VAddr stack_top = owner_process.VMManager().GetTLSIORegionEndAddress(); | 35 | const VAddr entry_point = vm_manager.GetCodeRegionBaseAddress(); |
| 36 | const VAddr stack_top = vm_manager.GetTLSIORegionEndAddress(); | ||
| 37 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, | 37 | auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, |
| 38 | owner_process.GetIdealCore(), stack_top, owner_process); | 38 | owner_process.GetIdealCore(), stack_top, owner_process); |
| 39 | 39 | ||
| 40 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); | 40 | SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); |
| 41 | 41 | ||
| 42 | // Register 1 must be a handle to the main thread | 42 | // Register 1 must be a handle to the main thread |
| 43 | const Handle guest_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); | 43 | const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap(); |
| 44 | thread->SetGuestHandle(guest_handle); | 44 | thread->GetContext().cpu_registers[1] = thread_handle; |
| 45 | thread->GetContext().cpu_registers[1] = guest_handle; | ||
| 46 | 45 | ||
| 47 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires | 46 | // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires |
| 48 | thread->ResumeFromWait(); | 47 | thread->ResumeFromWait(); |
| @@ -106,8 +105,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | |||
| 106 | is_64bit_process = metadata.Is64BitProgram(); | 105 | is_64bit_process = metadata.Is64BitProgram(); |
| 107 | 106 | ||
| 108 | vm_manager.Reset(metadata.GetAddressSpaceType()); | 107 | vm_manager.Reset(metadata.GetAddressSpaceType()); |
| 109 | // Ensure that the potentially resized page table is seen by CPU backends. | ||
| 110 | Memory::SetCurrentPageTable(&vm_manager.page_table); | ||
| 111 | 108 | ||
| 112 | const auto& caps = metadata.GetKernelCapabilities(); | 109 | const auto& caps = metadata.GetKernelCapabilities(); |
| 113 | const auto capability_init_result = | 110 | const auto capability_init_result = |
| @@ -119,7 +116,7 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | |||
| 119 | return handle_table.SetSize(capabilities.GetHandleTableSize()); | 116 | return handle_table.SetSize(capabilities.GetHandleTableSize()); |
| 120 | } | 117 | } |
| 121 | 118 | ||
| 122 | void Process::Run(VAddr entry_point, s32 main_thread_priority, u64 stack_size) { | 119 | void Process::Run(s32 main_thread_priority, u64 stack_size) { |
| 123 | // The kernel always ensures that the given stack size is page aligned. | 120 | // The kernel always ensures that the given stack size is page aligned. |
| 124 | main_thread_stack_size = Common::AlignUp(stack_size, Memory::PAGE_SIZE); | 121 | main_thread_stack_size = Common::AlignUp(stack_size, Memory::PAGE_SIZE); |
| 125 | 122 | ||
| @@ -135,7 +132,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u64 stack_size) { | |||
| 135 | vm_manager.LogLayout(); | 132 | vm_manager.LogLayout(); |
| 136 | ChangeStatus(ProcessStatus::Running); | 133 | ChangeStatus(ProcessStatus::Running); |
| 137 | 134 | ||
| 138 | SetupMainThread(*this, kernel, entry_point, main_thread_priority); | 135 | SetupMainThread(*this, kernel, main_thread_priority); |
| 139 | } | 136 | } |
| 140 | 137 | ||
| 141 | void Process::PrepareForTermination() { | 138 | void Process::PrepareForTermination() { |
| @@ -150,8 +147,7 @@ void Process::PrepareForTermination() { | |||
| 150 | continue; | 147 | continue; |
| 151 | 148 | ||
| 152 | // TODO(Subv): When are the other running/ready threads terminated? | 149 | // TODO(Subv): When are the other running/ready threads terminated? |
| 153 | ASSERT_MSG(thread->GetStatus() == ThreadStatus::WaitSynchAny || | 150 | ASSERT_MSG(thread->GetStatus() == ThreadStatus::WaitSynch, |
| 154 | thread->GetStatus() == ThreadStatus::WaitSynchAll, | ||
| 155 | "Exiting processes with non-waiting threads is currently unimplemented"); | 151 | "Exiting processes with non-waiting threads is currently unimplemented"); |
| 156 | 152 | ||
| 157 | thread->Stop(); | 153 | thread->Stop(); |
| @@ -242,9 +238,6 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) { | |||
| 242 | MapSegment(module_.DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeData); | 238 | MapSegment(module_.DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeData); |
| 243 | 239 | ||
| 244 | code_memory_size += module_.memory.size(); | 240 | code_memory_size += module_.memory.size(); |
| 245 | |||
| 246 | // Clear instruction cache in CPU JIT | ||
| 247 | system.InvalidateCpuInstructionCaches(); | ||
| 248 | } | 241 | } |
| 249 | 242 | ||
| 250 | Process::Process(Core::System& system) | 243 | Process::Process(Core::System& system) |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index dda52f4c0..bf3b7eef3 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -225,9 +225,12 @@ public: | |||
| 225 | ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata); | 225 | ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata); |
| 226 | 226 | ||
| 227 | /** | 227 | /** |
| 228 | * Applies address space changes and launches the process main thread. | 228 | * Starts the main application thread for this process. |
| 229 | * | ||
| 230 | * @param main_thread_priority The priority for the main thread. | ||
| 231 | * @param stack_size The stack size for the main thread in bytes. | ||
| 229 | */ | 232 | */ |
| 230 | void Run(VAddr entry_point, s32 main_thread_priority, u64 stack_size); | 233 | void Run(s32 main_thread_priority, u64 stack_size); |
| 231 | 234 | ||
| 232 | /** | 235 | /** |
| 233 | * Prepares a process for termination by stopping all of its threads | 236 | * Prepares a process for termination by stopping all of its threads |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e5d4d6b55..2dcf174c5 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -424,7 +424,7 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han | |||
| 424 | /// Default thread wakeup callback for WaitSynchronization | 424 | /// Default thread wakeup callback for WaitSynchronization |
| 425 | static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, | 425 | static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, |
| 426 | SharedPtr<WaitObject> object, std::size_t index) { | 426 | SharedPtr<WaitObject> object, std::size_t index) { |
| 427 | ASSERT(thread->GetStatus() == ThreadStatus::WaitSynchAny); | 427 | ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch); |
| 428 | 428 | ||
| 429 | if (reason == ThreadWakeupReason::Timeout) { | 429 | if (reason == ThreadWakeupReason::Timeout) { |
| 430 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | 430 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); |
| @@ -502,7 +502,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | |||
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | thread->SetWaitObjects(std::move(objects)); | 504 | thread->SetWaitObjects(std::move(objects)); |
| 505 | thread->SetStatus(ThreadStatus::WaitSynchAny); | 505 | thread->SetStatus(ThreadStatus::WaitSynch); |
| 506 | 506 | ||
| 507 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 507 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 508 | thread->WakeAfterDelay(nano_seconds); | 508 | thread->WakeAfterDelay(nano_seconds); |
| @@ -518,16 +518,14 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand | |||
| 518 | LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); | 518 | LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); |
| 519 | 519 | ||
| 520 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 520 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 521 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 521 | SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 522 | if (!thread) { | 522 | if (!thread) { |
| 523 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | 523 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", |
| 524 | thread_handle); | 524 | thread_handle); |
| 525 | return ERR_INVALID_HANDLE; | 525 | return ERR_INVALID_HANDLE; |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | ASSERT(thread->GetStatus() == ThreadStatus::WaitSynchAny); | 528 | thread->CancelWait(); |
| 529 | thread->SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED); | ||
| 530 | thread->ResumeFromWait(); | ||
| 531 | return RESULT_SUCCESS; | 529 | return RESULT_SUCCESS; |
| 532 | } | 530 | } |
| 533 | 531 | ||
| @@ -1189,6 +1187,142 @@ static ResultCode QueryMemory(Core::System& system, VAddr memory_info_address, | |||
| 1189 | query_address); | 1187 | query_address); |
| 1190 | } | 1188 | } |
| 1191 | 1189 | ||
| 1190 | static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, | ||
| 1191 | u64 src_address, u64 size) { | ||
| 1192 | LOG_DEBUG(Kernel_SVC, | ||
| 1193 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, " | ||
| 1194 | "src_address=0x{:016X}, size=0x{:016X}", | ||
| 1195 | process_handle, dst_address, src_address, size); | ||
| 1196 | |||
| 1197 | if (!Common::Is4KBAligned(src_address)) { | ||
| 1198 | LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", | ||
| 1199 | src_address); | ||
| 1200 | return ERR_INVALID_ADDRESS; | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | if (!Common::Is4KBAligned(dst_address)) { | ||
| 1204 | LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", | ||
| 1205 | dst_address); | ||
| 1206 | return ERR_INVALID_ADDRESS; | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | if (size == 0 || !Common::Is4KBAligned(size)) { | ||
| 1210 | LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X})", size); | ||
| 1211 | return ERR_INVALID_SIZE; | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | if (!IsValidAddressRange(dst_address, size)) { | ||
| 1215 | LOG_ERROR(Kernel_SVC, | ||
| 1216 | "Destination address range overflows the address space (dst_address=0x{:016X}, " | ||
| 1217 | "size=0x{:016X}).", | ||
| 1218 | dst_address, size); | ||
| 1219 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | if (!IsValidAddressRange(src_address, size)) { | ||
| 1223 | LOG_ERROR(Kernel_SVC, | ||
| 1224 | "Source address range overflows the address space (src_address=0x{:016X}, " | ||
| 1225 | "size=0x{:016X}).", | ||
| 1226 | src_address, size); | ||
| 1227 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||
| 1231 | auto process = handle_table.Get<Process>(process_handle); | ||
| 1232 | if (!process) { | ||
| 1233 | LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", | ||
| 1234 | process_handle); | ||
| 1235 | return ERR_INVALID_HANDLE; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | auto& vm_manager = process->VMManager(); | ||
| 1239 | if (!vm_manager.IsWithinAddressSpace(src_address, size)) { | ||
| 1240 | LOG_ERROR(Kernel_SVC, | ||
| 1241 | "Source address range is not within the address space (src_address=0x{:016X}, " | ||
| 1242 | "size=0x{:016X}).", | ||
| 1243 | src_address, size); | ||
| 1244 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | if (!vm_manager.IsWithinASLRRegion(dst_address, size)) { | ||
| 1248 | LOG_ERROR(Kernel_SVC, | ||
| 1249 | "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||
| 1250 | "size=0x{:016X}).", | ||
| 1251 | dst_address, size); | ||
| 1252 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | return vm_manager.MapCodeMemory(dst_address, src_address, size); | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, | ||
| 1259 | u64 src_address, u64 size) { | ||
| 1260 | LOG_DEBUG(Kernel_SVC, | ||
| 1261 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " | ||
| 1262 | "size=0x{:016X}", | ||
| 1263 | process_handle, dst_address, src_address, size); | ||
| 1264 | |||
| 1265 | if (!Common::Is4KBAligned(dst_address)) { | ||
| 1266 | LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", | ||
| 1267 | dst_address); | ||
| 1268 | return ERR_INVALID_ADDRESS; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | if (!Common::Is4KBAligned(src_address)) { | ||
| 1272 | LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", | ||
| 1273 | src_address); | ||
| 1274 | return ERR_INVALID_ADDRESS; | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | if (size == 0 || Common::Is4KBAligned(size)) { | ||
| 1278 | LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X}).", size); | ||
| 1279 | return ERR_INVALID_SIZE; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | if (!IsValidAddressRange(dst_address, size)) { | ||
| 1283 | LOG_ERROR(Kernel_SVC, | ||
| 1284 | "Destination address range overflows the address space (dst_address=0x{:016X}, " | ||
| 1285 | "size=0x{:016X}).", | ||
| 1286 | dst_address, size); | ||
| 1287 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | if (!IsValidAddressRange(src_address, size)) { | ||
| 1291 | LOG_ERROR(Kernel_SVC, | ||
| 1292 | "Source address range overflows the address space (src_address=0x{:016X}, " | ||
| 1293 | "size=0x{:016X}).", | ||
| 1294 | src_address, size); | ||
| 1295 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||
| 1299 | auto process = handle_table.Get<Process>(process_handle); | ||
| 1300 | if (!process) { | ||
| 1301 | LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", | ||
| 1302 | process_handle); | ||
| 1303 | return ERR_INVALID_HANDLE; | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | auto& vm_manager = process->VMManager(); | ||
| 1307 | if (!vm_manager.IsWithinAddressSpace(src_address, size)) { | ||
| 1308 | LOG_ERROR(Kernel_SVC, | ||
| 1309 | "Source address range is not within the address space (src_address=0x{:016X}, " | ||
| 1310 | "size=0x{:016X}).", | ||
| 1311 | src_address, size); | ||
| 1312 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | if (!vm_manager.IsWithinASLRRegion(dst_address, size)) { | ||
| 1316 | LOG_ERROR(Kernel_SVC, | ||
| 1317 | "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||
| 1318 | "size=0x{:016X}).", | ||
| 1319 | dst_address, size); | ||
| 1320 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | return vm_manager.UnmapCodeMemory(dst_address, src_address, size); | ||
| 1324 | } | ||
| 1325 | |||
| 1192 | /// Exits the current process | 1326 | /// Exits the current process |
| 1193 | static void ExitProcess(Core::System& system) { | 1327 | static void ExitProcess(Core::System& system) { |
| 1194 | auto* current_process = system.Kernel().CurrentProcess(); | 1328 | auto* current_process = system.Kernel().CurrentProcess(); |
| @@ -1244,20 +1378,22 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1244 | return ERR_INVALID_THREAD_PRIORITY; | 1378 | return ERR_INVALID_THREAD_PRIORITY; |
| 1245 | } | 1379 | } |
| 1246 | 1380 | ||
| 1247 | const std::string name = fmt::format("thread-{:X}", entry_point); | ||
| 1248 | auto& kernel = system.Kernel(); | 1381 | auto& kernel = system.Kernel(); |
| 1249 | CASCADE_RESULT(SharedPtr<Thread> thread, | 1382 | CASCADE_RESULT(SharedPtr<Thread> thread, |
| 1250 | Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top, | 1383 | Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top, |
| 1251 | *current_process)); | 1384 | *current_process)); |
| 1252 | 1385 | ||
| 1253 | const auto new_guest_handle = current_process->GetHandleTable().Create(thread); | 1386 | const auto new_thread_handle = current_process->GetHandleTable().Create(thread); |
| 1254 | if (new_guest_handle.Failed()) { | 1387 | if (new_thread_handle.Failed()) { |
| 1255 | LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", | 1388 | LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", |
| 1256 | new_guest_handle.Code().raw); | 1389 | new_thread_handle.Code().raw); |
| 1257 | return new_guest_handle.Code(); | 1390 | return new_thread_handle.Code(); |
| 1258 | } | 1391 | } |
| 1259 | thread->SetGuestHandle(*new_guest_handle); | 1392 | *out_handle = *new_thread_handle; |
| 1260 | *out_handle = *new_guest_handle; | 1393 | |
| 1394 | // Set the thread name for debugging purposes. | ||
| 1395 | thread->SetName( | ||
| 1396 | fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); | ||
| 1261 | 1397 | ||
| 1262 | system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); | 1398 | system.CpuCore(thread->GetProcessorID()).PrepareReschedule(); |
| 1263 | 1399 | ||
| @@ -2152,7 +2288,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 2152 | {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"}, | 2288 | {0x33, SvcWrap<GetThreadContext>, "GetThreadContext"}, |
| 2153 | {0x34, SvcWrap<WaitForAddress>, "WaitForAddress"}, | 2289 | {0x34, SvcWrap<WaitForAddress>, "WaitForAddress"}, |
| 2154 | {0x35, SvcWrap<SignalToAddress>, "SignalToAddress"}, | 2290 | {0x35, SvcWrap<SignalToAddress>, "SignalToAddress"}, |
| 2155 | {0x36, nullptr, "Unknown"}, | 2291 | {0x36, nullptr, "SynchronizePreemptionState"}, |
| 2156 | {0x37, nullptr, "Unknown"}, | 2292 | {0x37, nullptr, "Unknown"}, |
| 2157 | {0x38, nullptr, "Unknown"}, | 2293 | {0x38, nullptr, "Unknown"}, |
| 2158 | {0x39, nullptr, "Unknown"}, | 2294 | {0x39, nullptr, "Unknown"}, |
| @@ -2217,8 +2353,8 @@ static const FunctionDef SVC_Table[] = { | |||
| 2217 | {0x74, nullptr, "MapProcessMemory"}, | 2353 | {0x74, nullptr, "MapProcessMemory"}, |
| 2218 | {0x75, nullptr, "UnmapProcessMemory"}, | 2354 | {0x75, nullptr, "UnmapProcessMemory"}, |
| 2219 | {0x76, SvcWrap<QueryProcessMemory>, "QueryProcessMemory"}, | 2355 | {0x76, SvcWrap<QueryProcessMemory>, "QueryProcessMemory"}, |
| 2220 | {0x77, nullptr, "MapProcessCodeMemory"}, | 2356 | {0x77, SvcWrap<MapProcessCodeMemory>, "MapProcessCodeMemory"}, |
| 2221 | {0x78, nullptr, "UnmapProcessCodeMemory"}, | 2357 | {0x78, SvcWrap<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, |
| 2222 | {0x79, nullptr, "CreateProcess"}, | 2358 | {0x79, nullptr, "CreateProcess"}, |
| 2223 | {0x7A, nullptr, "StartProcess"}, | 2359 | {0x7A, nullptr, "StartProcess"}, |
| 2224 | {0x7B, nullptr, "TerminateProcess"}, | 2360 | {0x7B, nullptr, "TerminateProcess"}, |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index b3690b5f3..865473c6f 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -44,6 +44,13 @@ void SvcWrap(Core::System& system) { | |||
| 44 | func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw); | 44 | func(system, static_cast<u32>(Param(system, 0)), static_cast<u32>(Param(system, 1))).raw); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | template <ResultCode func(Core::System&, u32, u64, u64, u64)> | ||
| 48 | void SvcWrap(Core::System& system) { | ||
| 49 | FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1), | ||
| 50 | Param(system, 2), Param(system, 3)) | ||
| 51 | .raw); | ||
| 52 | } | ||
| 53 | |||
| 47 | template <ResultCode func(Core::System&, u32*)> | 54 | template <ResultCode func(Core::System&, u32*)> |
| 48 | void SvcWrap(Core::System& system) { | 55 | void SvcWrap(Core::System& system) { |
| 49 | u32 param = 0; | 56 | u32 param = 0; |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 1b891f632..2abf9efca 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -101,8 +101,7 @@ void Thread::ResumeFromWait() { | |||
| 101 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); | 101 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); |
| 102 | 102 | ||
| 103 | switch (status) { | 103 | switch (status) { |
| 104 | case ThreadStatus::WaitSynchAll: | 104 | case ThreadStatus::WaitSynch: |
| 105 | case ThreadStatus::WaitSynchAny: | ||
| 106 | case ThreadStatus::WaitHLEEvent: | 105 | case ThreadStatus::WaitHLEEvent: |
| 107 | case ThreadStatus::WaitSleep: | 106 | case ThreadStatus::WaitSleep: |
| 108 | case ThreadStatus::WaitIPC: | 107 | case ThreadStatus::WaitIPC: |
| @@ -142,6 +141,12 @@ void Thread::ResumeFromWait() { | |||
| 142 | ChangeScheduler(); | 141 | ChangeScheduler(); |
| 143 | } | 142 | } |
| 144 | 143 | ||
| 144 | void Thread::CancelWait() { | ||
| 145 | ASSERT(GetStatus() == ThreadStatus::WaitSynch); | ||
| 146 | SetWaitSynchronizationResult(ERR_SYNCHRONIZATION_CANCELED); | ||
| 147 | ResumeFromWait(); | ||
| 148 | } | ||
| 149 | |||
| 145 | /** | 150 | /** |
| 146 | * Resets a thread context, making it ready to be scheduled and run by the CPU | 151 | * Resets a thread context, making it ready to be scheduled and run by the CPU |
| 147 | * @param context Thread context to reset | 152 | * @param context Thread context to reset |
| @@ -220,11 +225,6 @@ void Thread::SetPriority(u32 priority) { | |||
| 220 | UpdatePriority(); | 225 | UpdatePriority(); |
| 221 | } | 226 | } |
| 222 | 227 | ||
| 223 | void Thread::BoostPriority(u32 priority) { | ||
| 224 | scheduler->SetThreadPriority(this, priority); | ||
| 225 | current_priority = priority; | ||
| 226 | } | ||
| 227 | |||
| 228 | void Thread::SetWaitSynchronizationResult(ResultCode result) { | 228 | void Thread::SetWaitSynchronizationResult(ResultCode result) { |
| 229 | context.cpu_registers[0] = result.raw; | 229 | context.cpu_registers[0] = result.raw; |
| 230 | } | 230 | } |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 83c83e45a..f07332f02 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -49,8 +49,7 @@ enum class ThreadStatus { | |||
| 49 | WaitHLEEvent, ///< Waiting for hle event to finish | 49 | WaitHLEEvent, ///< Waiting for hle event to finish |
| 50 | WaitSleep, ///< Waiting due to a SleepThread SVC | 50 | WaitSleep, ///< Waiting due to a SleepThread SVC |
| 51 | WaitIPC, ///< Waiting for the reply from an IPC request | 51 | WaitIPC, ///< Waiting for the reply from an IPC request |
| 52 | WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false | 52 | WaitSynch, ///< Waiting due to WaitSynchronization |
| 53 | WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true | ||
| 54 | WaitMutex, ///< Waiting due to an ArbitrateLock svc | 53 | WaitMutex, ///< Waiting due to an ArbitrateLock svc |
| 55 | WaitCondVar, ///< Waiting due to an WaitProcessWideKey svc | 54 | WaitCondVar, ///< Waiting due to an WaitProcessWideKey svc |
| 56 | WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc | 55 | WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc |
| @@ -102,6 +101,11 @@ public: | |||
| 102 | std::string GetName() const override { | 101 | std::string GetName() const override { |
| 103 | return name; | 102 | return name; |
| 104 | } | 103 | } |
| 104 | |||
| 105 | void SetName(std::string new_name) { | ||
| 106 | name = std::move(new_name); | ||
| 107 | } | ||
| 108 | |||
| 105 | std::string GetTypeName() const override { | 109 | std::string GetTypeName() const override { |
| 106 | return "Thread"; | 110 | return "Thread"; |
| 107 | } | 111 | } |
| @@ -136,12 +140,6 @@ public: | |||
| 136 | */ | 140 | */ |
| 137 | void SetPriority(u32 priority); | 141 | void SetPriority(u32 priority); |
| 138 | 142 | ||
| 139 | /** | ||
| 140 | * Temporarily boosts the thread's priority until the next time it is scheduled | ||
| 141 | * @param priority The new priority | ||
| 142 | */ | ||
| 143 | void BoostPriority(u32 priority); | ||
| 144 | |||
| 145 | /// Adds a thread to the list of threads that are waiting for a lock held by this thread. | 143 | /// Adds a thread to the list of threads that are waiting for a lock held by this thread. |
| 146 | void AddMutexWaiter(SharedPtr<Thread> thread); | 144 | void AddMutexWaiter(SharedPtr<Thread> thread); |
| 147 | 145 | ||
| @@ -170,11 +168,17 @@ public: | |||
| 170 | return tls_memory; | 168 | return tls_memory; |
| 171 | } | 169 | } |
| 172 | 170 | ||
| 173 | /** | 171 | /// Resumes a thread from waiting |
| 174 | * Resumes a thread from waiting | ||
| 175 | */ | ||
| 176 | void ResumeFromWait(); | 172 | void ResumeFromWait(); |
| 177 | 173 | ||
| 174 | /// Cancels a waiting operation that this thread may or may not be within. | ||
| 175 | /// | ||
| 176 | /// When the thread is within a waiting state, this will set the thread's | ||
| 177 | /// waiting result to signal a canceled wait. The function will then resume | ||
| 178 | /// this thread. | ||
| 179 | /// | ||
| 180 | void CancelWait(); | ||
| 181 | |||
| 178 | /** | 182 | /** |
| 179 | * Schedules an event to wake up the specified thread after the specified delay | 183 | * Schedules an event to wake up the specified thread after the specified delay |
| 180 | * @param nanoseconds The time this thread will be allowed to sleep for | 184 | * @param nanoseconds The time this thread will be allowed to sleep for |
| @@ -185,24 +189,27 @@ public: | |||
| 185 | void CancelWakeupTimer(); | 189 | void CancelWakeupTimer(); |
| 186 | 190 | ||
| 187 | /** | 191 | /** |
| 188 | * Sets the result after the thread awakens (from either WaitSynchronization SVC) | 192 | * Sets the result after the thread awakens (from svcWaitSynchronization) |
| 189 | * @param result Value to set to the returned result | 193 | * @param result Value to set to the returned result |
| 190 | */ | 194 | */ |
| 191 | void SetWaitSynchronizationResult(ResultCode result); | 195 | void SetWaitSynchronizationResult(ResultCode result); |
| 192 | 196 | ||
| 193 | /** | 197 | /** |
| 194 | * Sets the output parameter value after the thread awakens (from WaitSynchronizationN SVC only) | 198 | * Sets the output parameter value after the thread awakens (from svcWaitSynchronization) |
| 195 | * @param output Value to set to the output parameter | 199 | * @param output Value to set to the output parameter |
| 196 | */ | 200 | */ |
| 197 | void SetWaitSynchronizationOutput(s32 output); | 201 | void SetWaitSynchronizationOutput(s32 output); |
| 198 | 202 | ||
| 199 | /** | 203 | /** |
| 200 | * Retrieves the index that this particular object occupies in the list of objects | 204 | * Retrieves the index that this particular object occupies in the list of objects |
| 201 | * that the thread passed to WaitSynchronizationN, starting the search from the last element. | 205 | * that the thread passed to WaitSynchronization, starting the search from the last element. |
| 202 | * It is used to set the output value of WaitSynchronizationN when the thread is awakened. | 206 | * |
| 207 | * It is used to set the output index of WaitSynchronization when the thread is awakened. | ||
| 208 | * | ||
| 203 | * When a thread wakes up due to an object signal, the kernel will use the index of the last | 209 | * When a thread wakes up due to an object signal, the kernel will use the index of the last |
| 204 | * matching object in the wait objects list in case of having multiple instances of the same | 210 | * matching object in the wait objects list in case of having multiple instances of the same |
| 205 | * object in the list. | 211 | * object in the list. |
| 212 | * | ||
| 206 | * @param object Object to query the index of. | 213 | * @param object Object to query the index of. |
| 207 | */ | 214 | */ |
| 208 | s32 GetWaitObjectIndex(const WaitObject* object) const; | 215 | s32 GetWaitObjectIndex(const WaitObject* object) const; |
| @@ -239,13 +246,9 @@ public: | |||
| 239 | */ | 246 | */ |
| 240 | VAddr GetCommandBufferAddress() const; | 247 | VAddr GetCommandBufferAddress() const; |
| 241 | 248 | ||
| 242 | /** | 249 | /// Returns whether this thread is waiting on objects from a WaitSynchronization call. |
| 243 | * Returns whether this thread is waiting for all the objects in | 250 | bool IsSleepingOnWait() const { |
| 244 | * its wait list to become ready, as a result of a WaitSynchronizationN call | 251 | return status == ThreadStatus::WaitSynch; |
| 245 | * with wait_all = true. | ||
| 246 | */ | ||
| 247 | bool IsSleepingOnWaitAll() const { | ||
| 248 | return status == ThreadStatus::WaitSynchAll; | ||
| 249 | } | 252 | } |
| 250 | 253 | ||
| 251 | ThreadContext& GetContext() { | 254 | ThreadContext& GetContext() { |
| @@ -345,10 +348,6 @@ public: | |||
| 345 | arb_wait_address = address; | 348 | arb_wait_address = address; |
| 346 | } | 349 | } |
| 347 | 350 | ||
| 348 | void SetGuestHandle(Handle handle) { | ||
| 349 | guest_handle = handle; | ||
| 350 | } | ||
| 351 | |||
| 352 | bool HasWakeupCallback() const { | 351 | bool HasWakeupCallback() const { |
| 353 | return wakeup_callback != nullptr; | 352 | return wakeup_callback != nullptr; |
| 354 | } | 353 | } |
| @@ -423,7 +422,7 @@ private: | |||
| 423 | Process* owner_process; | 422 | Process* owner_process; |
| 424 | 423 | ||
| 425 | /// Objects that the thread is waiting on, in the same order as they were | 424 | /// Objects that the thread is waiting on, in the same order as they were |
| 426 | /// passed to WaitSynchronization1/N. | 425 | /// passed to WaitSynchronization. |
| 427 | ThreadWaitObjects wait_objects; | 426 | ThreadWaitObjects wait_objects; |
| 428 | 427 | ||
| 429 | /// List of threads that are waiting for a mutex that is held by this thread. | 428 | /// List of threads that are waiting for a mutex that is held by this thread. |
| @@ -442,14 +441,11 @@ private: | |||
| 442 | /// If waiting for an AddressArbiter, this is the address being waited on. | 441 | /// If waiting for an AddressArbiter, this is the address being waited on. |
| 443 | VAddr arb_wait_address{0}; | 442 | VAddr arb_wait_address{0}; |
| 444 | 443 | ||
| 445 | /// Handle used by guest emulated application to access this thread | ||
| 446 | Handle guest_handle = 0; | ||
| 447 | |||
| 448 | /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. | 444 | /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. |
| 449 | Handle callback_handle = 0; | 445 | Handle callback_handle = 0; |
| 450 | 446 | ||
| 451 | /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread | 447 | /// Callback that will be invoked when the thread is resumed from a waiting state. If the thread |
| 452 | /// was waiting via WaitSynchronizationN then the object will be the last object that became | 448 | /// was waiting via WaitSynchronization then the object will be the last object that became |
| 453 | /// available. In case of a timeout, the object will be nullptr. | 449 | /// available. In case of a timeout, the object will be nullptr. |
| 454 | WakeupCallback wakeup_callback; | 450 | WakeupCallback wakeup_callback; |
| 455 | 451 | ||
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index ec0a480ce..f0c0c12fc 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -302,6 +302,86 @@ ResultVal<VAddr> VMManager::SetHeapSize(u64 size) { | |||
| 302 | return MakeResult<VAddr>(heap_region_base); | 302 | return MakeResult<VAddr>(heap_region_base); |
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | ResultCode VMManager::MapCodeMemory(VAddr dst_address, VAddr src_address, u64 size) { | ||
| 306 | constexpr auto ignore_attribute = MemoryAttribute::LockedForIPC | MemoryAttribute::DeviceMapped; | ||
| 307 | const auto src_check_result = CheckRangeState( | ||
| 308 | src_address, size, MemoryState::All, MemoryState::Heap, VMAPermission::All, | ||
| 309 | VMAPermission::ReadWrite, MemoryAttribute::Mask, MemoryAttribute::None, ignore_attribute); | ||
| 310 | |||
| 311 | if (src_check_result.Failed()) { | ||
| 312 | return src_check_result.Code(); | ||
| 313 | } | ||
| 314 | |||
| 315 | const auto mirror_result = | ||
| 316 | MirrorMemory(dst_address, src_address, size, MemoryState::ModuleCode); | ||
| 317 | if (mirror_result.IsError()) { | ||
| 318 | return mirror_result; | ||
| 319 | } | ||
| 320 | |||
| 321 | // Ensure we lock the source memory region. | ||
| 322 | const auto src_vma_result = CarveVMARange(src_address, size); | ||
| 323 | if (src_vma_result.Failed()) { | ||
| 324 | return src_vma_result.Code(); | ||
| 325 | } | ||
| 326 | auto src_vma_iter = *src_vma_result; | ||
| 327 | src_vma_iter->second.attribute = MemoryAttribute::Locked; | ||
| 328 | Reprotect(src_vma_iter, VMAPermission::Read); | ||
| 329 | |||
| 330 | // The destination memory region is fine as is, however we need to make it read-only. | ||
| 331 | return ReprotectRange(dst_address, size, VMAPermission::Read); | ||
| 332 | } | ||
| 333 | |||
| 334 | ResultCode VMManager::UnmapCodeMemory(VAddr dst_address, VAddr src_address, u64 size) { | ||
| 335 | constexpr auto ignore_attribute = MemoryAttribute::LockedForIPC | MemoryAttribute::DeviceMapped; | ||
| 336 | const auto src_check_result = CheckRangeState( | ||
| 337 | src_address, size, MemoryState::All, MemoryState::Heap, VMAPermission::None, | ||
| 338 | VMAPermission::None, MemoryAttribute::Mask, MemoryAttribute::Locked, ignore_attribute); | ||
| 339 | |||
| 340 | if (src_check_result.Failed()) { | ||
| 341 | return src_check_result.Code(); | ||
| 342 | } | ||
| 343 | |||
| 344 | // Yes, the kernel only checks the first page of the region. | ||
| 345 | const auto dst_check_result = | ||
| 346 | CheckRangeState(dst_address, Memory::PAGE_SIZE, MemoryState::FlagModule, | ||
| 347 | MemoryState::FlagModule, VMAPermission::None, VMAPermission::None, | ||
| 348 | MemoryAttribute::Mask, MemoryAttribute::None, ignore_attribute); | ||
| 349 | |||
| 350 | if (dst_check_result.Failed()) { | ||
| 351 | return dst_check_result.Code(); | ||
| 352 | } | ||
| 353 | |||
| 354 | const auto dst_memory_state = std::get<MemoryState>(*dst_check_result); | ||
| 355 | const auto dst_contiguous_check_result = CheckRangeState( | ||
| 356 | dst_address, size, MemoryState::All, dst_memory_state, VMAPermission::None, | ||
| 357 | VMAPermission::None, MemoryAttribute::Mask, MemoryAttribute::None, ignore_attribute); | ||
| 358 | |||
| 359 | if (dst_contiguous_check_result.Failed()) { | ||
| 360 | return dst_contiguous_check_result.Code(); | ||
| 361 | } | ||
| 362 | |||
| 363 | const auto unmap_result = UnmapRange(dst_address, size); | ||
| 364 | if (unmap_result.IsError()) { | ||
| 365 | return unmap_result; | ||
| 366 | } | ||
| 367 | |||
| 368 | // With the mirrored portion unmapped, restore the original region's traits. | ||
| 369 | const auto src_vma_result = CarveVMARange(src_address, size); | ||
| 370 | if (src_vma_result.Failed()) { | ||
| 371 | return src_vma_result.Code(); | ||
| 372 | } | ||
| 373 | auto src_vma_iter = *src_vma_result; | ||
| 374 | src_vma_iter->second.state = MemoryState::Heap; | ||
| 375 | src_vma_iter->second.attribute = MemoryAttribute::None; | ||
| 376 | Reprotect(src_vma_iter, VMAPermission::ReadWrite); | ||
| 377 | |||
| 378 | if (dst_memory_state == MemoryState::ModuleCode) { | ||
| 379 | Core::System::GetInstance().InvalidateCpuInstructionCaches(); | ||
| 380 | } | ||
| 381 | |||
| 382 | return unmap_result; | ||
| 383 | } | ||
| 384 | |||
| 305 | MemoryInfo VMManager::QueryMemory(VAddr address) const { | 385 | MemoryInfo VMManager::QueryMemory(VAddr address) const { |
| 306 | const auto vma = FindVMA(address); | 386 | const auto vma = FindVMA(address); |
| 307 | MemoryInfo memory_info{}; | 387 | MemoryInfo memory_info{}; |
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 6f484b7bf..288eb9450 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h | |||
| @@ -43,6 +43,9 @@ enum class VMAPermission : u8 { | |||
| 43 | ReadExecute = Read | Execute, | 43 | ReadExecute = Read | Execute, |
| 44 | WriteExecute = Write | Execute, | 44 | WriteExecute = Write | Execute, |
| 45 | ReadWriteExecute = Read | Write | Execute, | 45 | ReadWriteExecute = Read | Write | Execute, |
| 46 | |||
| 47 | // Used as a wildcard when checking permissions across memory ranges | ||
| 48 | All = 0xFF, | ||
| 46 | }; | 49 | }; |
| 47 | 50 | ||
| 48 | constexpr VMAPermission operator|(VMAPermission lhs, VMAPermission rhs) { | 51 | constexpr VMAPermission operator|(VMAPermission lhs, VMAPermission rhs) { |
| @@ -152,6 +155,9 @@ enum class MemoryState : u32 { | |||
| 152 | FlagUncached = 1U << 24, | 155 | FlagUncached = 1U << 24, |
| 153 | FlagCodeMemory = 1U << 25, | 156 | FlagCodeMemory = 1U << 25, |
| 154 | 157 | ||
| 158 | // Wildcard used in range checking to indicate all states. | ||
| 159 | All = 0xFFFFFFFF, | ||
| 160 | |||
| 155 | // Convenience flag sets to reduce repetition | 161 | // Convenience flag sets to reduce repetition |
| 156 | IPCFlags = FlagIPC0 | FlagIPC3 | FlagIPC1, | 162 | IPCFlags = FlagIPC0 | FlagIPC3 | FlagIPC1, |
| 157 | 163 | ||
| @@ -415,6 +421,49 @@ public: | |||
| 415 | /// | 421 | /// |
| 416 | ResultVal<VAddr> SetHeapSize(u64 size); | 422 | ResultVal<VAddr> SetHeapSize(u64 size); |
| 417 | 423 | ||
| 424 | /// Maps a region of memory as code memory. | ||
| 425 | /// | ||
| 426 | /// @param dst_address The base address of the region to create the aliasing memory region. | ||
| 427 | /// @param src_address The base address of the region to be aliased. | ||
| 428 | /// @param size The total amount of memory to map in bytes. | ||
| 429 | /// | ||
| 430 | /// @pre Both memory regions lie within the actual addressable address space. | ||
| 431 | /// | ||
| 432 | /// @post After this function finishes execution, assuming success, then the address range | ||
| 433 | /// [dst_address, dst_address+size) will alias the memory region, | ||
| 434 | /// [src_address, src_address+size). | ||
| 435 | /// <p> | ||
| 436 | /// What this also entails is as follows: | ||
| 437 | /// 1. The aliased region gains the Locked memory attribute. | ||
| 438 | /// 2. The aliased region becomes read-only. | ||
| 439 | /// 3. The aliasing region becomes read-only. | ||
| 440 | /// 4. The aliasing region is created with a memory state of MemoryState::CodeModule. | ||
| 441 | /// | ||
| 442 | ResultCode MapCodeMemory(VAddr dst_address, VAddr src_address, u64 size); | ||
| 443 | |||
| 444 | /// Unmaps a region of memory designated as code module memory. | ||
| 445 | /// | ||
| 446 | /// @param dst_address The base address of the memory region aliasing the source memory region. | ||
| 447 | /// @param src_address The base address of the memory region being aliased. | ||
| 448 | /// @param size The size of the memory region to unmap in bytes. | ||
| 449 | /// | ||
| 450 | /// @pre Both memory ranges lie within the actual addressable address space. | ||
| 451 | /// | ||
| 452 | /// @pre The memory region being unmapped has been previously been mapped | ||
| 453 | /// by a call to MapCodeMemory. | ||
| 454 | /// | ||
| 455 | /// @post After execution of the function, if successful. the aliasing memory region | ||
| 456 | /// will be unmapped and the aliased region will have various traits about it | ||
| 457 | /// restored to what they were prior to the original mapping call preceding | ||
| 458 | /// this function call. | ||
| 459 | /// <p> | ||
| 460 | /// What this also entails is as follows: | ||
| 461 | /// 1. The state of the memory region will now indicate a general heap region. | ||
| 462 | /// 2. All memory attributes for the memory region are cleared. | ||
| 463 | /// 3. Memory permissions for the region are restored to user read/write. | ||
| 464 | /// | ||
| 465 | ResultCode UnmapCodeMemory(VAddr dst_address, VAddr src_address, u64 size); | ||
| 466 | |||
| 418 | /// Queries the memory manager for information about the given address. | 467 | /// Queries the memory manager for information about the given address. |
| 419 | /// | 468 | /// |
| 420 | /// @param address The address to query the memory manager about for information. | 469 | /// @param address The address to query the memory manager about for information. |
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 90580ed93..0e96ba872 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp | |||
| @@ -30,7 +30,7 @@ void WaitObject::RemoveWaitingThread(Thread* thread) { | |||
| 30 | waiting_threads.erase(itr); | 30 | waiting_threads.erase(itr); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | 33 | SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const { |
| 34 | Thread* candidate = nullptr; | 34 | Thread* candidate = nullptr; |
| 35 | u32 candidate_priority = THREADPRIO_LOWEST + 1; | 35 | u32 candidate_priority = THREADPRIO_LOWEST + 1; |
| 36 | 36 | ||
| @@ -38,8 +38,7 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 38 | const ThreadStatus thread_status = thread->GetStatus(); | 38 | const ThreadStatus thread_status = thread->GetStatus(); |
| 39 | 39 | ||
| 40 | // The list of waiting threads must not contain threads that are not waiting to be awakened. | 40 | // The list of waiting threads must not contain threads that are not waiting to be awakened. |
| 41 | ASSERT_MSG(thread_status == ThreadStatus::WaitSynchAny || | 41 | ASSERT_MSG(thread_status == ThreadStatus::WaitSynch || |
| 42 | thread_status == ThreadStatus::WaitSynchAll || | ||
| 43 | thread_status == ThreadStatus::WaitHLEEvent, | 42 | thread_status == ThreadStatus::WaitHLEEvent, |
| 44 | "Inconsistent thread statuses in waiting_threads"); | 43 | "Inconsistent thread statuses in waiting_threads"); |
| 45 | 44 | ||
| @@ -49,10 +48,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 49 | if (ShouldWait(thread.get())) | 48 | if (ShouldWait(thread.get())) |
| 50 | continue; | 49 | continue; |
| 51 | 50 | ||
| 52 | // A thread is ready to run if it's either in ThreadStatus::WaitSynchAny or | 51 | // A thread is ready to run if it's either in ThreadStatus::WaitSynch |
| 53 | // in ThreadStatus::WaitSynchAll and the rest of the objects it is waiting on are ready. | 52 | // and the rest of the objects it is waiting on are ready. |
| 54 | bool ready_to_run = true; | 53 | bool ready_to_run = true; |
| 55 | if (thread_status == ThreadStatus::WaitSynchAll) { | 54 | if (thread_status == ThreadStatus::WaitSynch) { |
| 56 | ready_to_run = thread->AllWaitObjectsReady(); | 55 | ready_to_run = thread->AllWaitObjectsReady(); |
| 57 | } | 56 | } |
| 58 | 57 | ||
| @@ -68,33 +67,35 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 68 | void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { | 67 | void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) { |
| 69 | ASSERT(!ShouldWait(thread.get())); | 68 | ASSERT(!ShouldWait(thread.get())); |
| 70 | 69 | ||
| 71 | if (!thread) | 70 | if (!thread) { |
| 72 | return; | 71 | return; |
| 72 | } | ||
| 73 | 73 | ||
| 74 | if (!thread->IsSleepingOnWaitAll()) { | 74 | if (thread->IsSleepingOnWait()) { |
| 75 | Acquire(thread.get()); | ||
| 76 | } else { | ||
| 77 | for (const auto& object : thread->GetWaitObjects()) { | 75 | for (const auto& object : thread->GetWaitObjects()) { |
| 78 | ASSERT(!object->ShouldWait(thread.get())); | 76 | ASSERT(!object->ShouldWait(thread.get())); |
| 79 | object->Acquire(thread.get()); | 77 | object->Acquire(thread.get()); |
| 80 | } | 78 | } |
| 79 | } else { | ||
| 80 | Acquire(thread.get()); | ||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | const std::size_t index = thread->GetWaitObjectIndex(this); | 83 | const std::size_t index = thread->GetWaitObjectIndex(this); |
| 84 | 84 | ||
| 85 | for (const auto& object : thread->GetWaitObjects()) | 85 | for (const auto& object : thread->GetWaitObjects()) { |
| 86 | object->RemoveWaitingThread(thread.get()); | 86 | object->RemoveWaitingThread(thread.get()); |
| 87 | } | ||
| 87 | thread->ClearWaitObjects(); | 88 | thread->ClearWaitObjects(); |
| 88 | 89 | ||
| 89 | thread->CancelWakeupTimer(); | 90 | thread->CancelWakeupTimer(); |
| 90 | 91 | ||
| 91 | bool resume = true; | 92 | bool resume = true; |
| 92 | 93 | if (thread->HasWakeupCallback()) { | |
| 93 | if (thread->HasWakeupCallback()) | ||
| 94 | resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index); | 94 | resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index); |
| 95 | 95 | } | |
| 96 | if (resume) | 96 | if (resume) { |
| 97 | thread->ResumeFromWait(); | 97 | thread->ResumeFromWait(); |
| 98 | } | ||
| 98 | } | 99 | } |
| 99 | 100 | ||
| 100 | void WaitObject::WakeupAllWaitingThreads() { | 101 | void WaitObject::WakeupAllWaitingThreads() { |
diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index 04464a51a..3271a30a7 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h | |||
| @@ -54,7 +54,7 @@ public: | |||
| 54 | void WakeupWaitingThread(SharedPtr<Thread> thread); | 54 | void WakeupWaitingThread(SharedPtr<Thread> thread); |
| 55 | 55 | ||
| 56 | /// Obtains the highest priority thread that is ready to run from this object's waiting list. | 56 | /// Obtains the highest priority thread that is ready to run from this object's waiting list. |
| 57 | SharedPtr<Thread> GetHighestPriorityReadyThread(); | 57 | SharedPtr<Thread> GetHighestPriorityReadyThread() const; |
| 58 | 58 | ||
| 59 | /// Get a const reference to the waiting threads list for debug use | 59 | /// Get a const reference to the waiting threads list for debug use |
| 60 | const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const; | 60 | const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const; |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 1f8ed265e..ba7d7acbd 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -137,6 +137,7 @@ private: | |||
| 137 | class IManagerForApplication final : public ServiceFramework<IManagerForApplication> { | 137 | class IManagerForApplication final : public ServiceFramework<IManagerForApplication> { |
| 138 | public: | 138 | public: |
| 139 | IManagerForApplication() : ServiceFramework("IManagerForApplication") { | 139 | IManagerForApplication() : ServiceFramework("IManagerForApplication") { |
| 140 | // clang-format off | ||
| 140 | static const FunctionInfo functions[] = { | 141 | static const FunctionInfo functions[] = { |
| 141 | {0, &IManagerForApplication::CheckAvailability, "CheckAvailability"}, | 142 | {0, &IManagerForApplication::CheckAvailability, "CheckAvailability"}, |
| 142 | {1, &IManagerForApplication::GetAccountId, "GetAccountId"}, | 143 | {1, &IManagerForApplication::GetAccountId, "GetAccountId"}, |
| @@ -145,7 +146,10 @@ public: | |||
| 145 | {130, nullptr, "GetNintendoAccountUserResourceCacheForApplication"}, | 146 | {130, nullptr, "GetNintendoAccountUserResourceCacheForApplication"}, |
| 146 | {150, nullptr, "CreateAuthorizationRequest"}, | 147 | {150, nullptr, "CreateAuthorizationRequest"}, |
| 147 | {160, nullptr, "StoreOpenContext"}, | 148 | {160, nullptr, "StoreOpenContext"}, |
| 149 | {170, nullptr, "LoadNetworkServiceLicenseKindAsync"}, | ||
| 148 | }; | 150 | }; |
| 151 | // clang-format on | ||
| 152 | |||
| 149 | RegisterHandlers(functions); | 153 | RegisterHandlers(functions); |
| 150 | } | 154 | } |
| 151 | 155 | ||
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 5e2030355..d66233cad 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp | |||
| @@ -8,6 +8,7 @@ namespace Service::Account { | |||
| 8 | 8 | ||
| 9 | ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager) | 9 | ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager) |
| 10 | : Module::Interface(std::move(module), std::move(profile_manager), "acc:su") { | 10 | : Module::Interface(std::move(module), std::move(profile_manager), "acc:su") { |
| 11 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | 12 | static const FunctionInfo functions[] = { |
| 12 | {0, &ACC_SU::GetUserCount, "GetUserCount"}, | 13 | {0, &ACC_SU::GetUserCount, "GetUserCount"}, |
| 13 | {1, &ACC_SU::GetUserExistence, "GetUserExistence"}, | 14 | {1, &ACC_SU::GetUserExistence, "GetUserExistence"}, |
| @@ -19,6 +20,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 19 | {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, | 20 | {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, |
| 20 | {51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, | 21 | {51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, |
| 21 | {60, nullptr, "ListOpenContextStoredUsers"}, | 22 | {60, nullptr, "ListOpenContextStoredUsers"}, |
| 23 | {99, nullptr, "DebugActivateOpenContextRetention"}, | ||
| 22 | {100, nullptr, "GetUserRegistrationNotifier"}, | 24 | {100, nullptr, "GetUserRegistrationNotifier"}, |
| 23 | {101, nullptr, "GetUserStateChangeNotifier"}, | 25 | {101, nullptr, "GetUserStateChangeNotifier"}, |
| 24 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, | 26 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, |
| @@ -29,6 +31,8 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 29 | {111, nullptr, "ClearSaveDataThumbnail"}, | 31 | {111, nullptr, "ClearSaveDataThumbnail"}, |
| 30 | {112, nullptr, "LoadSaveDataThumbnail"}, | 32 | {112, nullptr, "LoadSaveDataThumbnail"}, |
| 31 | {113, nullptr, "GetSaveDataThumbnailExistence"}, | 33 | {113, nullptr, "GetSaveDataThumbnailExistence"}, |
| 34 | {130, nullptr, "ActivateOpenContextRetention"}, | ||
| 35 | {140, nullptr, "ListQualifiedUsers"}, | ||
| 32 | {190, nullptr, "GetUserLastOpenedApplication"}, | 36 | {190, nullptr, "GetUserLastOpenedApplication"}, |
| 33 | {191, nullptr, "ActivateOpenContextHolder"}, | 37 | {191, nullptr, "ActivateOpenContextHolder"}, |
| 34 | {200, nullptr, "BeginUserRegistration"}, | 38 | {200, nullptr, "BeginUserRegistration"}, |
| @@ -48,6 +52,8 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 48 | {998, nullptr, "DebugSetUserStateClose"}, | 52 | {998, nullptr, "DebugSetUserStateClose"}, |
| 49 | {999, nullptr, "DebugSetUserStateOpen"}, | 53 | {999, nullptr, "DebugSetUserStateOpen"}, |
| 50 | }; | 54 | }; |
| 55 | // clang-format on | ||
| 56 | |||
| 51 | RegisterHandlers(functions); | 57 | RegisterHandlers(functions); |
| 52 | } | 58 | } |
| 53 | 59 | ||
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index a4d705b45..182f7c7e5 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp | |||
| @@ -8,6 +8,7 @@ namespace Service::Account { | |||
| 8 | 8 | ||
| 9 | ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager) | 9 | ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager) |
| 10 | : Module::Interface(std::move(module), std::move(profile_manager), "acc:u0") { | 10 | : Module::Interface(std::move(module), std::move(profile_manager), "acc:u0") { |
| 11 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | 12 | static const FunctionInfo functions[] = { |
| 12 | {0, &ACC_U0::GetUserCount, "GetUserCount"}, | 13 | {0, &ACC_U0::GetUserCount, "GetUserCount"}, |
| 13 | {1, &ACC_U0::GetUserExistence, "GetUserExistence"}, | 14 | {1, &ACC_U0::GetUserExistence, "GetUserExistence"}, |
| @@ -19,6 +20,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 19 | {50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, | 20 | {50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, |
| 20 | {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, | 21 | {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, |
| 21 | {60, nullptr, "ListOpenContextStoredUsers"}, | 22 | {60, nullptr, "ListOpenContextStoredUsers"}, |
| 23 | {99, nullptr, "DebugActivateOpenContextRetention"}, | ||
| 22 | {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"}, | 24 | {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"}, |
| 23 | {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"}, | 25 | {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"}, |
| 24 | {102, nullptr, "AuthenticateApplicationAsync"}, | 26 | {102, nullptr, "AuthenticateApplicationAsync"}, |
| @@ -27,7 +29,13 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 27 | {111, nullptr, "ClearSaveDataThumbnail"}, | 29 | {111, nullptr, "ClearSaveDataThumbnail"}, |
| 28 | {120, nullptr, "CreateGuestLoginRequest"}, | 30 | {120, nullptr, "CreateGuestLoginRequest"}, |
| 29 | {130, nullptr, "LoadOpenContext"}, | 31 | {130, nullptr, "LoadOpenContext"}, |
| 32 | {131, nullptr, "ListOpenContextStoredUsers"}, | ||
| 33 | {140, nullptr, "InitializeApplicationInfo"}, | ||
| 34 | {141, nullptr, "ListQualifiedUsers"}, | ||
| 35 | {150, nullptr, "IsUserAccountSwitchLocked"}, | ||
| 30 | }; | 36 | }; |
| 37 | // clang-format on | ||
| 38 | |||
| 31 | RegisterHandlers(functions); | 39 | RegisterHandlers(functions); |
| 32 | } | 40 | } |
| 33 | 41 | ||
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 8fffc93b5..2dd17d935 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp | |||
| @@ -8,6 +8,7 @@ namespace Service::Account { | |||
| 8 | 8 | ||
| 9 | ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager) | 9 | ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> profile_manager) |
| 10 | : Module::Interface(std::move(module), std::move(profile_manager), "acc:u1") { | 10 | : Module::Interface(std::move(module), std::move(profile_manager), "acc:u1") { |
| 11 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | 12 | static const FunctionInfo functions[] = { |
| 12 | {0, &ACC_U1::GetUserCount, "GetUserCount"}, | 13 | {0, &ACC_U1::GetUserCount, "GetUserCount"}, |
| 13 | {1, &ACC_U1::GetUserExistence, "GetUserExistence"}, | 14 | {1, &ACC_U1::GetUserExistence, "GetUserExistence"}, |
| @@ -19,6 +20,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 19 | {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, | 20 | {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, |
| 20 | {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, | 21 | {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, |
| 21 | {60, nullptr, "ListOpenContextStoredUsers"}, | 22 | {60, nullptr, "ListOpenContextStoredUsers"}, |
| 23 | {99, nullptr, "DebugActivateOpenContextRetention"}, | ||
| 22 | {100, nullptr, "GetUserRegistrationNotifier"}, | 24 | {100, nullptr, "GetUserRegistrationNotifier"}, |
| 23 | {101, nullptr, "GetUserStateChangeNotifier"}, | 25 | {101, nullptr, "GetUserStateChangeNotifier"}, |
| 24 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, | 26 | {102, nullptr, "GetBaasAccountManagerForSystemService"}, |
| @@ -29,12 +31,16 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p | |||
| 29 | {111, nullptr, "ClearSaveDataThumbnail"}, | 31 | {111, nullptr, "ClearSaveDataThumbnail"}, |
| 30 | {112, nullptr, "LoadSaveDataThumbnail"}, | 32 | {112, nullptr, "LoadSaveDataThumbnail"}, |
| 31 | {113, nullptr, "GetSaveDataThumbnailExistence"}, | 33 | {113, nullptr, "GetSaveDataThumbnailExistence"}, |
| 34 | {130, nullptr, "ActivateOpenContextRetention"}, | ||
| 35 | {140, nullptr, "ListQualifiedUsers"}, | ||
| 32 | {190, nullptr, "GetUserLastOpenedApplication"}, | 36 | {190, nullptr, "GetUserLastOpenedApplication"}, |
| 33 | {191, nullptr, "ActivateOpenContextHolder"}, | 37 | {191, nullptr, "ActivateOpenContextHolder"}, |
| 34 | {997, nullptr, "DebugInvalidateTokenCacheForUser"}, | 38 | {997, nullptr, "DebugInvalidateTokenCacheForUser"}, |
| 35 | {998, nullptr, "DebugSetUserStateClose"}, | 39 | {998, nullptr, "DebugSetUserStateClose"}, |
| 36 | {999, nullptr, "DebugSetUserStateOpen"}, | 40 | {999, nullptr, "DebugSetUserStateOpen"}, |
| 37 | }; | 41 | }; |
| 42 | // clang-format on | ||
| 43 | |||
| 38 | RegisterHandlers(functions); | 44 | RegisterHandlers(functions); |
| 39 | } | 45 | } |
| 40 | 46 | ||
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 85271d418..26a665bfd 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include "core/hle/service/am/applets/applets.h" | 22 | #include "core/hle/service/am/applets/applets.h" |
| 23 | #include "core/hle/service/am/applets/profile_select.h" | 23 | #include "core/hle/service/am/applets/profile_select.h" |
| 24 | #include "core/hle/service/am/applets/software_keyboard.h" | 24 | #include "core/hle/service/am/applets/software_keyboard.h" |
| 25 | #include "core/hle/service/am/applets/stub_applet.h" | ||
| 26 | #include "core/hle/service/am/applets/web_browser.h" | 25 | #include "core/hle/service/am/applets/web_browser.h" |
| 27 | #include "core/hle/service/am/idle.h" | 26 | #include "core/hle/service/am/idle.h" |
| 28 | #include "core/hle/service/am/omm.h" | 27 | #include "core/hle/service/am/omm.h" |
| @@ -42,12 +41,6 @@ constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2}; | |||
| 42 | constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3}; | 41 | constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3}; |
| 43 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; | 42 | constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; |
| 44 | 43 | ||
| 45 | enum class AppletId : u32 { | ||
| 46 | ProfileSelect = 0x10, | ||
| 47 | SoftwareKeyboard = 0x11, | ||
| 48 | LibAppletOff = 0x17, | ||
| 49 | }; | ||
| 50 | |||
| 51 | constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA; | 44 | constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA; |
| 52 | 45 | ||
| 53 | struct LaunchParameters { | 46 | struct LaunchParameters { |
| @@ -224,6 +217,7 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} { | |||
| 224 | {20, nullptr, "InvalidateTransitionLayer"}, | 217 | {20, nullptr, "InvalidateTransitionLayer"}, |
| 225 | {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, | 218 | {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, |
| 226 | {40, nullptr, "GetAppletResourceUsageInfo"}, | 219 | {40, nullptr, "GetAppletResourceUsageInfo"}, |
| 220 | {41, nullptr, "SetCpuBoostModeForApplet"}, | ||
| 227 | }; | 221 | }; |
| 228 | // clang-format on | 222 | // clang-format on |
| 229 | 223 | ||
| @@ -256,6 +250,7 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger | |||
| 256 | {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"}, | 250 | {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"}, |
| 257 | {41, nullptr, "IsSystemBufferSharingEnabled"}, | 251 | {41, nullptr, "IsSystemBufferSharingEnabled"}, |
| 258 | {42, nullptr, "GetSystemSharedLayerHandle"}, | 252 | {42, nullptr, "GetSystemSharedLayerHandle"}, |
| 253 | {43, nullptr, "GetSystemSharedBufferHandle"}, | ||
| 259 | {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, | 254 | {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, |
| 260 | {51, nullptr, "ApproveToDisplay"}, | 255 | {51, nullptr, "ApproveToDisplay"}, |
| 261 | {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, | 256 | {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, |
| @@ -269,9 +264,11 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger | |||
| 269 | {68, nullptr, "SetAutoSleepDisabled"}, | 264 | {68, nullptr, "SetAutoSleepDisabled"}, |
| 270 | {69, nullptr, "IsAutoSleepDisabled"}, | 265 | {69, nullptr, "IsAutoSleepDisabled"}, |
| 271 | {70, nullptr, "ReportMultimediaError"}, | 266 | {70, nullptr, "ReportMultimediaError"}, |
| 267 | {71, nullptr, "GetCurrentIlluminanceEx"}, | ||
| 272 | {80, nullptr, "SetWirelessPriorityMode"}, | 268 | {80, nullptr, "SetWirelessPriorityMode"}, |
| 273 | {90, nullptr, "GetAccumulatedSuspendedTickValue"}, | 269 | {90, nullptr, "GetAccumulatedSuspendedTickValue"}, |
| 274 | {91, nullptr, "GetAccumulatedSuspendedTickChangedEvent"}, | 270 | {91, nullptr, "GetAccumulatedSuspendedTickChangedEvent"}, |
| 271 | {100, nullptr, "SetAlbumImageTakenNotificationEnabled"}, | ||
| 275 | {1000, nullptr, "GetDebugStorageChannel"}, | 272 | {1000, nullptr, "GetDebugStorageChannel"}, |
| 276 | }; | 273 | }; |
| 277 | // clang-format on | 274 | // clang-format on |
| @@ -516,11 +513,20 @@ ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_q | |||
| 516 | {50, nullptr, "IsVrModeEnabled"}, | 513 | {50, nullptr, "IsVrModeEnabled"}, |
| 517 | {51, nullptr, "SetVrModeEnabled"}, | 514 | {51, nullptr, "SetVrModeEnabled"}, |
| 518 | {52, nullptr, "SwitchLcdBacklight"}, | 515 | {52, nullptr, "SwitchLcdBacklight"}, |
| 516 | {53, nullptr, "BeginVrModeEx"}, | ||
| 517 | {54, nullptr, "EndVrModeEx"}, | ||
| 519 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, | 518 | {55, nullptr, "IsInControllerFirmwareUpdateSection"}, |
| 520 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, | 519 | {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"}, |
| 521 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, | 520 | {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"}, |
| 522 | {62, nullptr, "GetHdcpAuthenticationState"}, | 521 | {62, nullptr, "GetHdcpAuthenticationState"}, |
| 523 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, | 522 | {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"}, |
| 523 | {64, nullptr, "SetTvPowerStateMatchingMode"}, | ||
| 524 | {65, nullptr, "GetApplicationIdByContentActionName"}, | ||
| 525 | {66, nullptr, "SetCpuBoostMode"}, | ||
| 526 | {80, nullptr, "PerformSystemButtonPressingIfInFocus"}, | ||
| 527 | {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, | ||
| 528 | {91, nullptr, "GetCurrentPerformanceConfiguration"}, | ||
| 529 | {200, nullptr, "GetOperationModeSystemInfo"}, | ||
| 524 | }; | 530 | }; |
| 525 | // clang-format on | 531 | // clang-format on |
| 526 | 532 | ||
| @@ -873,30 +879,16 @@ ILibraryAppletCreator::ILibraryAppletCreator() : ServiceFramework("ILibraryApple | |||
| 873 | 879 | ||
| 874 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; | 880 | ILibraryAppletCreator::~ILibraryAppletCreator() = default; |
| 875 | 881 | ||
| 876 | static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) { | ||
| 877 | switch (id) { | ||
| 878 | case AppletId::ProfileSelect: | ||
| 879 | return std::make_shared<Applets::ProfileSelect>(); | ||
| 880 | case AppletId::SoftwareKeyboard: | ||
| 881 | return std::make_shared<Applets::SoftwareKeyboard>(); | ||
| 882 | case AppletId::LibAppletOff: | ||
| 883 | return std::make_shared<Applets::WebBrowser>(); | ||
| 884 | default: | ||
| 885 | LOG_ERROR(Service_AM, "Unimplemented AppletId [{:08X}]! -- Falling back to stub!", | ||
| 886 | static_cast<u32>(id)); | ||
| 887 | return std::make_shared<Applets::StubApplet>(); | ||
| 888 | } | ||
| 889 | } | ||
| 890 | |||
| 891 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { | 882 | void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { |
| 892 | IPC::RequestParser rp{ctx}; | 883 | IPC::RequestParser rp{ctx}; |
| 893 | const auto applet_id = rp.PopRaw<AppletId>(); | 884 | const auto applet_id = rp.PopRaw<Applets::AppletId>(); |
| 894 | const auto applet_mode = rp.PopRaw<u32>(); | 885 | const auto applet_mode = rp.PopRaw<u32>(); |
| 895 | 886 | ||
| 896 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", | 887 | LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", |
| 897 | static_cast<u32>(applet_id), applet_mode); | 888 | static_cast<u32>(applet_id), applet_mode); |
| 898 | 889 | ||
| 899 | const auto applet = GetAppletFromId(applet_id); | 890 | const auto& applet_manager{Core::System::GetInstance().GetAppletManager()}; |
| 891 | const auto applet = applet_manager.GetApplet(applet_id); | ||
| 900 | 892 | ||
| 901 | if (applet == nullptr) { | 893 | if (applet == nullptr) { |
| 902 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id)); | 894 | LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id)); |
| @@ -960,6 +952,8 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF | |||
| 960 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, | 952 | {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"}, |
| 961 | {12, nullptr, "CreateApplicationAndRequestToStart"}, | 953 | {12, nullptr, "CreateApplicationAndRequestToStart"}, |
| 962 | {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"}, | 954 | {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"}, |
| 955 | {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"}, | ||
| 956 | {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"}, | ||
| 963 | {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"}, | 957 | {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"}, |
| 964 | {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"}, | 958 | {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"}, |
| 965 | {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"}, | 959 | {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"}, |
| @@ -1233,6 +1227,7 @@ IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStat | |||
| 1233 | {2, nullptr, "StartSleepSequence"}, | 1227 | {2, nullptr, "StartSleepSequence"}, |
| 1234 | {3, nullptr, "StartShutdownSequence"}, | 1228 | {3, nullptr, "StartShutdownSequence"}, |
| 1235 | {4, nullptr, "StartRebootSequence"}, | 1229 | {4, nullptr, "StartRebootSequence"}, |
| 1230 | {9, nullptr, "IsAutoPowerDownRequested"}, | ||
| 1236 | {10, nullptr, "LoadAndApplyIdlePolicySettings"}, | 1231 | {10, nullptr, "LoadAndApplyIdlePolicySettings"}, |
| 1237 | {11, nullptr, "NotifyCecSettingsChanged"}, | 1232 | {11, nullptr, "NotifyCecSettingsChanged"}, |
| 1238 | {12, nullptr, "SetDefaultHomeButtonLongPressTime"}, | 1233 | {12, nullptr, "SetDefaultHomeButtonLongPressTime"}, |
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index b888f861d..488add8e7 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp | |||
| @@ -16,6 +16,7 @@ public: | |||
| 16 | std::shared_ptr<AppletMessageQueue> msg_queue) | 16 | std::shared_ptr<AppletMessageQueue> msg_queue) |
| 17 | : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)), | 17 | : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)), |
| 18 | msg_queue(std::move(msg_queue)) { | 18 | msg_queue(std::move(msg_queue)) { |
| 19 | // clang-format off | ||
| 19 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
| 20 | {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | 21 | {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, |
| 21 | {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"}, | 22 | {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"}, |
| @@ -25,8 +26,11 @@ public: | |||
| 25 | {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"}, | 26 | {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"}, |
| 26 | {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, | 27 | {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, |
| 27 | {20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"}, | 28 | {20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"}, |
| 29 | {21, nullptr, "GetAppletCommonFunctions"}, | ||
| 28 | {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, | 30 | {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, |
| 29 | }; | 31 | }; |
| 32 | // clang-format on | ||
| 33 | |||
| 30 | RegisterHandlers(functions); | 34 | RegisterHandlers(functions); |
| 31 | } | 35 | } |
| 32 | 36 | ||
| @@ -113,6 +117,7 @@ public: | |||
| 113 | std::shared_ptr<AppletMessageQueue> msg_queue) | 117 | std::shared_ptr<AppletMessageQueue> msg_queue) |
| 114 | : ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)), | 118 | : ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)), |
| 115 | msg_queue(std::move(msg_queue)) { | 119 | msg_queue(std::move(msg_queue)) { |
| 120 | // clang-format off | ||
| 116 | static const FunctionInfo functions[] = { | 121 | static const FunctionInfo functions[] = { |
| 117 | {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, | 122 | {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, |
| 118 | {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"}, | 123 | {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"}, |
| @@ -124,8 +129,11 @@ public: | |||
| 124 | {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, | 129 | {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, |
| 125 | {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, | 130 | {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, |
| 126 | {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"}, | 131 | {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"}, |
| 132 | {23, nullptr, "GetAppletCommonFunctions"}, | ||
| 127 | {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, | 133 | {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, |
| 128 | }; | 134 | }; |
| 135 | // clang-format on | ||
| 136 | |||
| 129 | RegisterHandlers(functions); | 137 | RegisterHandlers(functions); |
| 130 | } | 138 | } |
| 131 | 139 | ||
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index a6064c63f..7f70b10df 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -5,11 +5,21 @@ | |||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/frontend/applets/error.h" | ||
| 9 | #include "core/frontend/applets/general_frontend.h" | ||
| 10 | #include "core/frontend/applets/profile_select.h" | ||
| 11 | #include "core/frontend/applets/software_keyboard.h" | ||
| 12 | #include "core/frontend/applets/web_browser.h" | ||
| 8 | #include "core/hle/kernel/readable_event.h" | 13 | #include "core/hle/kernel/readable_event.h" |
| 9 | #include "core/hle/kernel/server_session.h" | 14 | #include "core/hle/kernel/server_session.h" |
| 10 | #include "core/hle/kernel/writable_event.h" | 15 | #include "core/hle/kernel/writable_event.h" |
| 11 | #include "core/hle/service/am/am.h" | 16 | #include "core/hle/service/am/am.h" |
| 12 | #include "core/hle/service/am/applets/applets.h" | 17 | #include "core/hle/service/am/applets/applets.h" |
| 18 | #include "core/hle/service/am/applets/error.h" | ||
| 19 | #include "core/hle/service/am/applets/general_backend.h" | ||
| 20 | #include "core/hle/service/am/applets/profile_select.h" | ||
| 21 | #include "core/hle/service/am/applets/software_keyboard.h" | ||
| 22 | #include "core/hle/service/am/applets/web_browser.h" | ||
| 13 | 23 | ||
| 14 | namespace Service::AM::Applets { | 24 | namespace Service::AM::Applets { |
| 15 | 25 | ||
| @@ -111,4 +121,76 @@ void Applet::Initialize() { | |||
| 111 | initialized = true; | 121 | initialized = true; |
| 112 | } | 122 | } |
| 113 | 123 | ||
| 124 | AppletManager::AppletManager() = default; | ||
| 125 | |||
| 126 | AppletManager::~AppletManager() = default; | ||
| 127 | |||
| 128 | void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { | ||
| 129 | if (set.error != nullptr) | ||
| 130 | frontend.error = std::move(set.error); | ||
| 131 | if (set.photo_viewer != nullptr) | ||
| 132 | frontend.photo_viewer = std::move(set.photo_viewer); | ||
| 133 | if (set.profile_select != nullptr) | ||
| 134 | frontend.profile_select = std::move(set.profile_select); | ||
| 135 | if (set.software_keyboard != nullptr) | ||
| 136 | frontend.software_keyboard = std::move(set.software_keyboard); | ||
| 137 | if (set.web_browser != nullptr) | ||
| 138 | frontend.web_browser = std::move(set.web_browser); | ||
| 139 | } | ||
| 140 | |||
| 141 | void AppletManager::SetDefaultAppletFrontendSet() { | ||
| 142 | frontend.error = std::make_unique<Core::Frontend::DefaultErrorApplet>(); | ||
| 143 | frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>(); | ||
| 144 | frontend.profile_select = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); | ||
| 145 | frontend.software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); | ||
| 146 | frontend.web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); | ||
| 147 | } | ||
| 148 | |||
| 149 | void AppletManager::SetDefaultAppletsIfMissing() { | ||
| 150 | if (frontend.error == nullptr) { | ||
| 151 | frontend.error = std::make_unique<Core::Frontend::DefaultErrorApplet>(); | ||
| 152 | } | ||
| 153 | |||
| 154 | if (frontend.photo_viewer == nullptr) { | ||
| 155 | frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>(); | ||
| 156 | } | ||
| 157 | |||
| 158 | if (frontend.profile_select == nullptr) { | ||
| 159 | frontend.profile_select = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); | ||
| 160 | } | ||
| 161 | |||
| 162 | if (frontend.software_keyboard == nullptr) { | ||
| 163 | frontend.software_keyboard = | ||
| 164 | std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); | ||
| 165 | } | ||
| 166 | |||
| 167 | if (frontend.web_browser == nullptr) { | ||
| 168 | frontend.web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | void AppletManager::ClearAll() { | ||
| 173 | frontend = {}; | ||
| 174 | } | ||
| 175 | |||
| 176 | std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const { | ||
| 177 | switch (id) { | ||
| 178 | case AppletId::Error: | ||
| 179 | return std::make_shared<Error>(*frontend.error); | ||
| 180 | case AppletId::ProfileSelect: | ||
| 181 | return std::make_shared<ProfileSelect>(*frontend.profile_select); | ||
| 182 | case AppletId::SoftwareKeyboard: | ||
| 183 | return std::make_shared<SoftwareKeyboard>(*frontend.software_keyboard); | ||
| 184 | case AppletId::PhotoViewer: | ||
| 185 | return std::make_shared<PhotoViewer>(*frontend.photo_viewer); | ||
| 186 | case AppletId::LibAppletOff: | ||
| 187 | return std::make_shared<WebBrowser>(*frontend.web_browser); | ||
| 188 | default: | ||
| 189 | UNIMPLEMENTED_MSG( | ||
| 190 | "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", | ||
| 191 | static_cast<u8>(id)); | ||
| 192 | return std::make_shared<StubApplet>(); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 114 | } // namespace Service::AM::Applets | 196 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 37424c379..7f932672c 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -12,12 +12,43 @@ | |||
| 12 | 12 | ||
| 13 | union ResultCode; | 13 | union ResultCode; |
| 14 | 14 | ||
| 15 | namespace Core::Frontend { | ||
| 16 | class ErrorApplet; | ||
| 17 | class PhotoViewerApplet; | ||
| 18 | class ProfileSelectApplet; | ||
| 19 | class SoftwareKeyboardApplet; | ||
| 20 | class WebBrowserApplet; | ||
| 21 | } // namespace Core::Frontend | ||
| 22 | |||
| 15 | namespace Service::AM { | 23 | namespace Service::AM { |
| 16 | 24 | ||
| 17 | class IStorage; | 25 | class IStorage; |
| 18 | 26 | ||
| 19 | namespace Applets { | 27 | namespace Applets { |
| 20 | 28 | ||
| 29 | enum class AppletId : u32 { | ||
| 30 | OverlayDisplay = 0x02, | ||
| 31 | QLaunch = 0x03, | ||
| 32 | Starter = 0x04, | ||
| 33 | Auth = 0x0A, | ||
| 34 | Cabinet = 0x0B, | ||
| 35 | Controller = 0x0C, | ||
| 36 | DataErase = 0x0D, | ||
| 37 | Error = 0x0E, | ||
| 38 | NetConnect = 0x0F, | ||
| 39 | ProfileSelect = 0x10, | ||
| 40 | SoftwareKeyboard = 0x11, | ||
| 41 | MiiEdit = 0x12, | ||
| 42 | LibAppletWeb = 0x13, | ||
| 43 | LibAppletShop = 0x14, | ||
| 44 | PhotoViewer = 0x15, | ||
| 45 | Settings = 0x16, | ||
| 46 | LibAppletOff = 0x17, | ||
| 47 | LibAppletWhitelisted = 0x18, | ||
| 48 | LibAppletAuth = 0x19, | ||
| 49 | MyPage = 0x1A, | ||
| 50 | }; | ||
| 51 | |||
| 21 | class AppletDataBroker final { | 52 | class AppletDataBroker final { |
| 22 | public: | 53 | public: |
| 23 | AppletDataBroker(); | 54 | AppletDataBroker(); |
| @@ -105,5 +136,29 @@ protected: | |||
| 105 | bool initialized = false; | 136 | bool initialized = false; |
| 106 | }; | 137 | }; |
| 107 | 138 | ||
| 139 | struct AppletFrontendSet { | ||
| 140 | std::unique_ptr<Core::Frontend::ErrorApplet> error; | ||
| 141 | std::unique_ptr<Core::Frontend::PhotoViewerApplet> photo_viewer; | ||
| 142 | std::unique_ptr<Core::Frontend::ProfileSelectApplet> profile_select; | ||
| 143 | std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard; | ||
| 144 | std::unique_ptr<Core::Frontend::WebBrowserApplet> web_browser; | ||
| 145 | }; | ||
| 146 | |||
| 147 | class AppletManager { | ||
| 148 | public: | ||
| 149 | AppletManager(); | ||
| 150 | ~AppletManager(); | ||
| 151 | |||
| 152 | void SetAppletFrontendSet(AppletFrontendSet set); | ||
| 153 | void SetDefaultAppletFrontendSet(); | ||
| 154 | void SetDefaultAppletsIfMissing(); | ||
| 155 | void ClearAll(); | ||
| 156 | |||
| 157 | std::shared_ptr<Applet> GetApplet(AppletId id) const; | ||
| 158 | |||
| 159 | private: | ||
| 160 | AppletFrontendSet frontend; | ||
| 161 | }; | ||
| 162 | |||
| 108 | } // namespace Applets | 163 | } // namespace Applets |
| 109 | } // namespace Service::AM | 164 | } // namespace Service::AM |
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp new file mode 100644 index 000000000..04774bedc --- /dev/null +++ b/src/core/hle/service/am/applets/error.cpp | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <cstring> | ||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "common/string_util.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/frontend/applets/error.h" | ||
| 12 | #include "core/hle/service/am/am.h" | ||
| 13 | #include "core/hle/service/am/applets/error.h" | ||
| 14 | |||
| 15 | namespace Service::AM::Applets { | ||
| 16 | |||
| 17 | #pragma pack(push, 4) | ||
| 18 | struct ShowError { | ||
| 19 | u8 mode; | ||
| 20 | bool jump; | ||
| 21 | INSERT_PADDING_BYTES(4); | ||
| 22 | bool use_64bit_error_code; | ||
| 23 | INSERT_PADDING_BYTES(1); | ||
| 24 | u64 error_code_64; | ||
| 25 | u32 error_code_32; | ||
| 26 | }; | ||
| 27 | static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size."); | ||
| 28 | #pragma pack(pop) | ||
| 29 | |||
| 30 | struct ShowErrorRecord { | ||
| 31 | u8 mode; | ||
| 32 | bool jump; | ||
| 33 | INSERT_PADDING_BYTES(6); | ||
| 34 | u64 error_code_64; | ||
| 35 | u64 posix_time; | ||
| 36 | }; | ||
| 37 | static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect size."); | ||
| 38 | |||
| 39 | struct SystemErrorArg { | ||
| 40 | u8 mode; | ||
| 41 | bool jump; | ||
| 42 | INSERT_PADDING_BYTES(6); | ||
| 43 | u64 error_code_64; | ||
| 44 | std::array<char, 8> language_code; | ||
| 45 | std::array<char, 0x800> main_text; | ||
| 46 | std::array<char, 0x800> detail_text; | ||
| 47 | }; | ||
| 48 | static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect size."); | ||
| 49 | |||
| 50 | struct ApplicationErrorArg { | ||
| 51 | u8 mode; | ||
| 52 | bool jump; | ||
| 53 | INSERT_PADDING_BYTES(6); | ||
| 54 | u32 error_code; | ||
| 55 | std::array<char, 8> language_code; | ||
| 56 | std::array<char, 0x800> main_text; | ||
| 57 | std::array<char, 0x800> detail_text; | ||
| 58 | }; | ||
| 59 | static_assert(sizeof(ApplicationErrorArg) == 0x1014, "ApplicationErrorArg has incorrect size."); | ||
| 60 | |||
| 61 | union Error::ErrorArguments { | ||
| 62 | ShowError error; | ||
| 63 | ShowErrorRecord error_record; | ||
| 64 | SystemErrorArg system_error; | ||
| 65 | ApplicationErrorArg application_error; | ||
| 66 | }; | ||
| 67 | |||
| 68 | namespace { | ||
| 69 | template <typename T> | ||
| 70 | void CopyArgumentData(const std::vector<u8>& data, T& variable) { | ||
| 71 | ASSERT(data.size() >= sizeof(T)); | ||
| 72 | std::memcpy(&variable, data.data(), sizeof(T)); | ||
| 73 | } | ||
| 74 | |||
| 75 | ResultCode Decode64BitError(u64 error) { | ||
| 76 | const auto description = (error >> 32) & 0x1FFF; | ||
| 77 | auto module = error & 0x3FF; | ||
| 78 | if (module >= 2000) | ||
| 79 | module -= 2000; | ||
| 80 | module &= 0x1FF; | ||
| 81 | return {static_cast<ErrorModule>(module), static_cast<u32>(description)}; | ||
| 82 | } | ||
| 83 | |||
| 84 | } // Anonymous namespace | ||
| 85 | |||
| 86 | Error::Error(const Core::Frontend::ErrorApplet& frontend) : frontend(frontend) {} | ||
| 87 | |||
| 88 | Error::~Error() = default; | ||
| 89 | |||
| 90 | void Error::Initialize() { | ||
| 91 | Applet::Initialize(); | ||
| 92 | args = std::make_unique<ErrorArguments>(); | ||
| 93 | complete = false; | ||
| 94 | |||
| 95 | const auto storage = broker.PopNormalDataToApplet(); | ||
| 96 | ASSERT(storage != nullptr); | ||
| 97 | const auto data = storage->GetData(); | ||
| 98 | |||
| 99 | ASSERT(!data.empty()); | ||
| 100 | std::memcpy(&mode, data.data(), sizeof(ErrorAppletMode)); | ||
| 101 | |||
| 102 | switch (mode) { | ||
| 103 | case ErrorAppletMode::ShowError: | ||
| 104 | CopyArgumentData(data, args->error); | ||
| 105 | if (args->error.use_64bit_error_code) { | ||
| 106 | error_code = Decode64BitError(args->error.error_code_64); | ||
| 107 | } else { | ||
| 108 | error_code = ResultCode(args->error.error_code_32); | ||
| 109 | } | ||
| 110 | break; | ||
| 111 | case ErrorAppletMode::ShowSystemError: | ||
| 112 | CopyArgumentData(data, args->system_error); | ||
| 113 | error_code = ResultCode(Decode64BitError(args->system_error.error_code_64)); | ||
| 114 | break; | ||
| 115 | case ErrorAppletMode::ShowApplicationError: | ||
| 116 | CopyArgumentData(data, args->application_error); | ||
| 117 | error_code = ResultCode(args->application_error.error_code); | ||
| 118 | break; | ||
| 119 | case ErrorAppletMode::ShowErrorRecord: | ||
| 120 | CopyArgumentData(data, args->error_record); | ||
| 121 | error_code = Decode64BitError(args->error_record.error_code_64); | ||
| 122 | break; | ||
| 123 | default: | ||
| 124 | UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast<u8>(mode)); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | bool Error::TransactionComplete() const { | ||
| 129 | return complete; | ||
| 130 | } | ||
| 131 | |||
| 132 | ResultCode Error::GetStatus() const { | ||
| 133 | return RESULT_SUCCESS; | ||
| 134 | } | ||
| 135 | |||
| 136 | void Error::ExecuteInteractive() { | ||
| 137 | UNREACHABLE_MSG("Unexpected interactive applet data!"); | ||
| 138 | } | ||
| 139 | |||
| 140 | void Error::Execute() { | ||
| 141 | if (complete) { | ||
| 142 | return; | ||
| 143 | } | ||
| 144 | |||
| 145 | const auto callback = [this] { DisplayCompleted(); }; | ||
| 146 | |||
| 147 | switch (mode) { | ||
| 148 | case ErrorAppletMode::ShowError: | ||
| 149 | frontend.ShowError(error_code, callback); | ||
| 150 | break; | ||
| 151 | case ErrorAppletMode::ShowSystemError: | ||
| 152 | case ErrorAppletMode::ShowApplicationError: { | ||
| 153 | const auto system = mode == ErrorAppletMode::ShowSystemError; | ||
| 154 | const auto& main_text = | ||
| 155 | system ? args->system_error.main_text : args->application_error.main_text; | ||
| 156 | const auto& detail_text = | ||
| 157 | system ? args->system_error.detail_text : args->application_error.detail_text; | ||
| 158 | |||
| 159 | frontend.ShowCustomErrorText( | ||
| 160 | error_code, | ||
| 161 | Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()), | ||
| 162 | Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()), | ||
| 163 | callback); | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | case ErrorAppletMode::ShowErrorRecord: | ||
| 167 | frontend.ShowErrorWithTimestamp( | ||
| 168 | error_code, std::chrono::seconds{args->error_record.posix_time}, callback); | ||
| 169 | break; | ||
| 170 | default: | ||
| 171 | UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast<u8>(mode)); | ||
| 172 | DisplayCompleted(); | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | void Error::DisplayCompleted() { | ||
| 177 | complete = true; | ||
| 178 | broker.PushNormalDataFromApplet(IStorage{{}}); | ||
| 179 | broker.SignalStateChanged(); | ||
| 180 | } | ||
| 181 | |||
| 182 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/error.h new file mode 100644 index 000000000..a3590d181 --- /dev/null +++ b/src/core/hle/service/am/applets/error.h | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/result.h" | ||
| 8 | #include "core/hle/service/am/applets/applets.h" | ||
| 9 | |||
| 10 | namespace Service::AM::Applets { | ||
| 11 | |||
| 12 | enum class ErrorAppletMode : u8 { | ||
| 13 | ShowError = 0, | ||
| 14 | ShowSystemError = 1, | ||
| 15 | ShowApplicationError = 2, | ||
| 16 | ShowEula = 3, | ||
| 17 | ShowErrorPctl = 4, | ||
| 18 | ShowErrorRecord = 5, | ||
| 19 | ShowUpdateEula = 8, | ||
| 20 | }; | ||
| 21 | |||
| 22 | class Error final : public Applet { | ||
| 23 | public: | ||
| 24 | explicit Error(const Core::Frontend::ErrorApplet& frontend); | ||
| 25 | ~Error() override; | ||
| 26 | |||
| 27 | void Initialize() override; | ||
| 28 | |||
| 29 | bool TransactionComplete() const override; | ||
| 30 | ResultCode GetStatus() const override; | ||
| 31 | void ExecuteInteractive() override; | ||
| 32 | void Execute() override; | ||
| 33 | |||
| 34 | void DisplayCompleted(); | ||
| 35 | |||
| 36 | private: | ||
| 37 | union ErrorArguments; | ||
| 38 | |||
| 39 | const Core::Frontend::ErrorApplet& frontend; | ||
| 40 | ResultCode error_code = RESULT_SUCCESS; | ||
| 41 | ErrorAppletMode mode = ErrorAppletMode::ShowError; | ||
| 42 | std::unique_ptr<ErrorArguments> args; | ||
| 43 | |||
| 44 | bool complete = false; | ||
| 45 | }; | ||
| 46 | |||
| 47 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/stub_applet.cpp b/src/core/hle/service/am/applets/general_backend.cpp index ed166b87d..c591b9ac2 100644 --- a/src/core/hle/service/am/applets/stub_applet.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp | |||
| @@ -4,11 +4,15 @@ | |||
| 4 | 4 | ||
| 5 | #include <string> | 5 | #include <string> |
| 6 | 6 | ||
| 7 | #include "common/assert.h" | ||
| 7 | #include "common/hex_util.h" | 8 | #include "common/hex_util.h" |
| 8 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "core/core.h" | ||
| 11 | #include "core/frontend/applets/general_frontend.h" | ||
| 12 | #include "core/hle/kernel/process.h" | ||
| 9 | #include "core/hle/result.h" | 13 | #include "core/hle/result.h" |
| 10 | #include "core/hle/service/am/am.h" | 14 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applets/stub_applet.h" | 15 | #include "core/hle/service/am/applets/general_backend.h" |
| 12 | 16 | ||
| 13 | namespace Service::AM::Applets { | 17 | namespace Service::AM::Applets { |
| 14 | 18 | ||
| @@ -30,6 +34,55 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string prefix) { | |||
| 30 | } | 34 | } |
| 31 | } | 35 | } |
| 32 | 36 | ||
| 37 | PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {} | ||
| 38 | |||
| 39 | PhotoViewer::~PhotoViewer() = default; | ||
| 40 | |||
| 41 | void PhotoViewer::Initialize() { | ||
| 42 | Applet::Initialize(); | ||
| 43 | complete = false; | ||
| 44 | |||
| 45 | const auto storage = broker.PopNormalDataToApplet(); | ||
| 46 | ASSERT(storage != nullptr); | ||
| 47 | const auto data = storage->GetData(); | ||
| 48 | ASSERT(!data.empty()); | ||
| 49 | mode = static_cast<PhotoViewerAppletMode>(data[0]); | ||
| 50 | } | ||
| 51 | |||
| 52 | bool PhotoViewer::TransactionComplete() const { | ||
| 53 | return complete; | ||
| 54 | } | ||
| 55 | |||
| 56 | ResultCode PhotoViewer::GetStatus() const { | ||
| 57 | return RESULT_SUCCESS; | ||
| 58 | } | ||
| 59 | |||
| 60 | void PhotoViewer::ExecuteInteractive() { | ||
| 61 | UNREACHABLE_MSG("Unexpected interactive applet data."); | ||
| 62 | } | ||
| 63 | |||
| 64 | void PhotoViewer::Execute() { | ||
| 65 | if (complete) | ||
| 66 | return; | ||
| 67 | |||
| 68 | const auto callback = [this] { ViewFinished(); }; | ||
| 69 | switch (mode) { | ||
| 70 | case PhotoViewerAppletMode::CurrentApp: | ||
| 71 | frontend.ShowPhotosForApplication(Core::CurrentProcess()->GetTitleID(), callback); | ||
| 72 | break; | ||
| 73 | case PhotoViewerAppletMode::AllApps: | ||
| 74 | frontend.ShowAllPhotos(callback); | ||
| 75 | break; | ||
| 76 | default: | ||
| 77 | UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", static_cast<u8>(mode)); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | void PhotoViewer::ViewFinished() { | ||
| 82 | broker.PushNormalDataFromApplet(IStorage{{}}); | ||
| 83 | broker.SignalStateChanged(); | ||
| 84 | } | ||
| 85 | |||
| 33 | StubApplet::StubApplet() = default; | 86 | StubApplet::StubApplet() = default; |
| 34 | 87 | ||
| 35 | StubApplet::~StubApplet() = default; | 88 | StubApplet::~StubApplet() = default; |
| @@ -67,4 +120,5 @@ void StubApplet::Execute() { | |||
| 67 | broker.PushInteractiveDataFromApplet(IStorage{std::vector<u8>(0x1000)}); | 120 | broker.PushInteractiveDataFromApplet(IStorage{std::vector<u8>(0x1000)}); |
| 68 | broker.SignalStateChanged(); | 121 | broker.SignalStateChanged(); |
| 69 | } | 122 | } |
| 123 | |||
| 70 | } // namespace Service::AM::Applets | 124 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h new file mode 100644 index 000000000..2dd255d7c --- /dev/null +++ b/src/core/hle/service/am/applets/general_backend.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/am/applets/applets.h" | ||
| 8 | |||
| 9 | namespace Service::AM::Applets { | ||
| 10 | |||
| 11 | enum class PhotoViewerAppletMode : u8 { | ||
| 12 | CurrentApp = 0, | ||
| 13 | AllApps = 1, | ||
| 14 | }; | ||
| 15 | |||
| 16 | class PhotoViewer final : public Applet { | ||
| 17 | public: | ||
| 18 | explicit PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend); | ||
| 19 | ~PhotoViewer() override; | ||
| 20 | |||
| 21 | void Initialize() override; | ||
| 22 | bool TransactionComplete() const override; | ||
| 23 | ResultCode GetStatus() const override; | ||
| 24 | void ExecuteInteractive() override; | ||
| 25 | void Execute() override; | ||
| 26 | |||
| 27 | void ViewFinished(); | ||
| 28 | |||
| 29 | private: | ||
| 30 | const Core::Frontend::PhotoViewerApplet& frontend; | ||
| 31 | bool complete = false; | ||
| 32 | PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp; | ||
| 33 | }; | ||
| 34 | |||
| 35 | class StubApplet final : public Applet { | ||
| 36 | public: | ||
| 37 | StubApplet(); | ||
| 38 | ~StubApplet() override; | ||
| 39 | |||
| 40 | void Initialize() override; | ||
| 41 | |||
| 42 | bool TransactionComplete() const override; | ||
| 43 | ResultCode GetStatus() const override; | ||
| 44 | void ExecuteInteractive() override; | ||
| 45 | void Execute() override; | ||
| 46 | }; | ||
| 47 | |||
| 48 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp index 14e2a1fee..d113bd2eb 100644 --- a/src/core/hle/service/am/applets/profile_select.cpp +++ b/src/core/hle/service/am/applets/profile_select.cpp | |||
| @@ -15,7 +15,9 @@ namespace Service::AM::Applets { | |||
| 15 | 15 | ||
| 16 | constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; | 16 | constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; |
| 17 | 17 | ||
| 18 | ProfileSelect::ProfileSelect() = default; | 18 | ProfileSelect::ProfileSelect(const Core::Frontend::ProfileSelectApplet& frontend) |
| 19 | : frontend(frontend) {} | ||
| 20 | |||
| 19 | ProfileSelect::~ProfileSelect() = default; | 21 | ProfileSelect::~ProfileSelect() = default; |
| 20 | 22 | ||
| 21 | void ProfileSelect::Initialize() { | 23 | void ProfileSelect::Initialize() { |
| @@ -51,8 +53,6 @@ void ProfileSelect::Execute() { | |||
| 51 | return; | 53 | return; |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | const auto& frontend{Core::System::GetInstance().GetProfileSelector()}; | ||
| 55 | |||
| 56 | frontend.SelectProfile([this](std::optional<Account::UUID> uuid) { SelectionComplete(uuid); }); | 56 | frontend.SelectProfile([this](std::optional<Account::UUID> uuid) { SelectionComplete(uuid); }); |
| 57 | } | 57 | } |
| 58 | 58 | ||
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h index 787485f22..a2ac6cf50 100644 --- a/src/core/hle/service/am/applets/profile_select.h +++ b/src/core/hle/service/am/applets/profile_select.h | |||
| @@ -28,7 +28,7 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco | |||
| 28 | 28 | ||
| 29 | class ProfileSelect final : public Applet { | 29 | class ProfileSelect final : public Applet { |
| 30 | public: | 30 | public: |
| 31 | ProfileSelect(); | 31 | explicit ProfileSelect(const Core::Frontend::ProfileSelectApplet& frontend); |
| 32 | ~ProfileSelect() override; | 32 | ~ProfileSelect() override; |
| 33 | 33 | ||
| 34 | void Initialize() override; | 34 | void Initialize() override; |
| @@ -41,6 +41,8 @@ public: | |||
| 41 | void SelectionComplete(std::optional<Account::UUID> uuid); | 41 | void SelectionComplete(std::optional<Account::UUID> uuid); |
| 42 | 42 | ||
| 43 | private: | 43 | private: |
| 44 | const Core::Frontend::ProfileSelectApplet& frontend; | ||
| 45 | |||
| 44 | UserSelectionConfig config; | 46 | UserSelectionConfig config; |
| 45 | bool complete = false; | 47 | bool complete = false; |
| 46 | ResultCode status = RESULT_SUCCESS; | 48 | ResultCode status = RESULT_SUCCESS; |
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 8c5bd6059..e197990f7 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp | |||
| @@ -39,7 +39,8 @@ static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters( | |||
| 39 | return params; | 39 | return params; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | SoftwareKeyboard::SoftwareKeyboard() = default; | 42 | SoftwareKeyboard::SoftwareKeyboard(const Core::Frontend::SoftwareKeyboardApplet& frontend) |
| 43 | : frontend(frontend) {} | ||
| 43 | 44 | ||
| 44 | SoftwareKeyboard::~SoftwareKeyboard() = default; | 45 | SoftwareKeyboard::~SoftwareKeyboard() = default; |
| 45 | 46 | ||
| @@ -90,8 +91,6 @@ void SoftwareKeyboard::ExecuteInteractive() { | |||
| 90 | if (status == INTERACTIVE_STATUS_OK) { | 91 | if (status == INTERACTIVE_STATUS_OK) { |
| 91 | complete = true; | 92 | complete = true; |
| 92 | } else { | 93 | } else { |
| 93 | const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()}; | ||
| 94 | |||
| 95 | std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; | 94 | std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; |
| 96 | std::memcpy(string.data(), data.data() + 4, string.size() * 2); | 95 | std::memcpy(string.data(), data.data() + 4, string.size() * 2); |
| 97 | frontend.SendTextCheckDialog( | 96 | frontend.SendTextCheckDialog( |
| @@ -106,8 +105,6 @@ void SoftwareKeyboard::Execute() { | |||
| 106 | return; | 105 | return; |
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()}; | ||
| 110 | |||
| 111 | const auto parameters = ConvertToFrontendParameters(config, initial_text); | 108 | const auto parameters = ConvertToFrontendParameters(config, initial_text); |
| 112 | 109 | ||
| 113 | frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, | 110 | frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, |
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h index b93a30d28..0fbc43e51 100644 --- a/src/core/hle/service/am/applets/software_keyboard.h +++ b/src/core/hle/service/am/applets/software_keyboard.h | |||
| @@ -55,7 +55,7 @@ static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect siz | |||
| 55 | 55 | ||
| 56 | class SoftwareKeyboard final : public Applet { | 56 | class SoftwareKeyboard final : public Applet { |
| 57 | public: | 57 | public: |
| 58 | SoftwareKeyboard(); | 58 | explicit SoftwareKeyboard(const Core::Frontend::SoftwareKeyboardApplet& frontend); |
| 59 | ~SoftwareKeyboard() override; | 59 | ~SoftwareKeyboard() override; |
| 60 | 60 | ||
| 61 | void Initialize() override; | 61 | void Initialize() override; |
| @@ -68,6 +68,8 @@ public: | |||
| 68 | void WriteText(std::optional<std::u16string> text); | 68 | void WriteText(std::optional<std::u16string> text); |
| 69 | 69 | ||
| 70 | private: | 70 | private: |
| 71 | const Core::Frontend::SoftwareKeyboardApplet& frontend; | ||
| 72 | |||
| 71 | KeyboardConfig config; | 73 | KeyboardConfig config; |
| 72 | std::u16string initial_text; | 74 | std::u16string initial_text; |
| 73 | bool complete = false; | 75 | bool complete = false; |
diff --git a/src/core/hle/service/am/applets/stub_applet.h b/src/core/hle/service/am/applets/stub_applet.h deleted file mode 100644 index 7d8dc968d..000000000 --- a/src/core/hle/service/am/applets/stub_applet.h +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/am/applets/applets.h" | ||
| 8 | |||
| 9 | namespace Service::AM::Applets { | ||
| 10 | |||
| 11 | class StubApplet final : public Applet { | ||
| 12 | public: | ||
| 13 | StubApplet(); | ||
| 14 | ~StubApplet() override; | ||
| 15 | |||
| 16 | void Initialize() override; | ||
| 17 | |||
| 18 | bool TransactionComplete() const override; | ||
| 19 | ResultCode GetStatus() const override; | ||
| 20 | void ExecuteInteractive() override; | ||
| 21 | void Execute() override; | ||
| 22 | }; | ||
| 23 | |||
| 24 | } // namespace Service::AM::Applets | ||
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 7e17df98a..7878f5136 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp | |||
| @@ -95,7 +95,7 @@ static FileSys::VirtualFile GetManualRomFS() { | |||
| 95 | return nullptr; | 95 | return nullptr; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | WebBrowser::WebBrowser() = default; | 98 | WebBrowser::WebBrowser(Core::Frontend::WebBrowserApplet& frontend) : frontend(frontend) {} |
| 99 | 99 | ||
| 100 | WebBrowser::~WebBrowser() = default; | 100 | WebBrowser::~WebBrowser() = default; |
| 101 | 101 | ||
| @@ -152,8 +152,6 @@ void WebBrowser::Execute() { | |||
| 152 | return; | 152 | return; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | auto& frontend{Core::System::GetInstance().GetWebBrowser()}; | ||
| 156 | |||
| 157 | frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); }); | 155 | frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); }); |
| 158 | } | 156 | } |
| 159 | 157 | ||
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h index b9e228fac..7e0f34c7d 100644 --- a/src/core/hle/service/am/applets/web_browser.h +++ b/src/core/hle/service/am/applets/web_browser.h | |||
| @@ -12,7 +12,7 @@ namespace Service::AM::Applets { | |||
| 12 | 12 | ||
| 13 | class WebBrowser final : public Applet { | 13 | class WebBrowser final : public Applet { |
| 14 | public: | 14 | public: |
| 15 | WebBrowser(); | 15 | WebBrowser(Core::Frontend::WebBrowserApplet& frontend); |
| 16 | ~WebBrowser() override; | 16 | ~WebBrowser() override; |
| 17 | 17 | ||
| 18 | void Initialize() override; | 18 | void Initialize() override; |
| @@ -32,6 +32,8 @@ public: | |||
| 32 | void Finalize(); | 32 | void Finalize(); |
| 33 | 33 | ||
| 34 | private: | 34 | private: |
| 35 | Core::Frontend::WebBrowserApplet& frontend; | ||
| 36 | |||
| 35 | bool complete = false; | 37 | bool complete = false; |
| 36 | bool unpacked = false; | 38 | bool unpacked = false; |
| 37 | ResultCode status = RESULT_SUCCESS; | 39 | ResultCode status = RESULT_SUCCESS; |
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 2d768d9fc..51d8c26b4 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -50,6 +50,7 @@ static std::vector<u64> AccumulateAOCTitleIDs() { | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs()) { | 52 | AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs()) { |
| 53 | // clang-format off | ||
| 53 | static const FunctionInfo functions[] = { | 54 | static const FunctionInfo functions[] = { |
| 54 | {0, nullptr, "CountAddOnContentByApplicationId"}, | 55 | {0, nullptr, "CountAddOnContentByApplicationId"}, |
| 55 | {1, nullptr, "ListAddOnContentByApplicationId"}, | 56 | {1, nullptr, "ListAddOnContentByApplicationId"}, |
| @@ -60,7 +61,10 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs | |||
| 60 | {6, nullptr, "PrepareAddOnContentByApplicationId"}, | 61 | {6, nullptr, "PrepareAddOnContentByApplicationId"}, |
| 61 | {7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"}, | 62 | {7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"}, |
| 62 | {8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"}, | 63 | {8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"}, |
| 64 | {100, nullptr, "CreateEcPurchasedEventManager"}, | ||
| 63 | }; | 65 | }; |
| 66 | // clang-format on | ||
| 67 | |||
| 64 | RegisterHandlers(functions); | 68 | RegisterHandlers(functions); |
| 65 | 69 | ||
| 66 | auto& kernel = Core::System::GetInstance().Kernel(); | 70 | auto& kernel = Core::System::GetInstance().Kernel(); |
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index fcacbab72..d058c0245 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp | |||
| @@ -87,6 +87,8 @@ APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} { | |||
| 87 | {3, nullptr, "GetLastThrottlingState"}, | 87 | {3, nullptr, "GetLastThrottlingState"}, |
| 88 | {4, nullptr, "ClearLastThrottlingState"}, | 88 | {4, nullptr, "ClearLastThrottlingState"}, |
| 89 | {5, nullptr, "LoadAndApplySettings"}, | 89 | {5, nullptr, "LoadAndApplySettings"}, |
| 90 | {6, nullptr, "SetCpuBoostMode"}, | ||
| 91 | {7, nullptr, "GetCurrentPerformanceConfiguration"}, | ||
| 90 | }; | 92 | }; |
| 91 | // clang-format on | 93 | // clang-format on |
| 92 | 94 | ||
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp index b6b71f966..f43e512e9 100644 --- a/src/core/hle/service/audio/audctl.cpp +++ b/src/core/hle/service/audio/audctl.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/hle/ipc_helpers.h" | ||
| 5 | #include "core/hle/service/audio/audctl.h" | 7 | #include "core/hle/service/audio/audctl.h" |
| 6 | 8 | ||
| 7 | namespace Service::Audio { | 9 | namespace Service::Audio { |
| @@ -11,8 +13,8 @@ AudCtl::AudCtl() : ServiceFramework{"audctl"} { | |||
| 11 | static const FunctionInfo functions[] = { | 13 | static const FunctionInfo functions[] = { |
| 12 | {0, nullptr, "GetTargetVolume"}, | 14 | {0, nullptr, "GetTargetVolume"}, |
| 13 | {1, nullptr, "SetTargetVolume"}, | 15 | {1, nullptr, "SetTargetVolume"}, |
| 14 | {2, nullptr, "GetTargetVolumeMin"}, | 16 | {2, &AudCtl::GetTargetVolumeMin, "GetTargetVolumeMin"}, |
| 15 | {3, nullptr, "GetTargetVolumeMax"}, | 17 | {3, &AudCtl::GetTargetVolumeMax, "GetTargetVolumeMax"}, |
| 16 | {4, nullptr, "IsTargetMute"}, | 18 | {4, nullptr, "IsTargetMute"}, |
| 17 | {5, nullptr, "SetTargetMute"}, | 19 | {5, nullptr, "SetTargetMute"}, |
| 18 | {6, nullptr, "IsTargetConnected"}, | 20 | {6, nullptr, "IsTargetConnected"}, |
| @@ -44,4 +46,28 @@ AudCtl::AudCtl() : ServiceFramework{"audctl"} { | |||
| 44 | 46 | ||
| 45 | AudCtl::~AudCtl() = default; | 47 | AudCtl::~AudCtl() = default; |
| 46 | 48 | ||
| 49 | void AudCtl::GetTargetVolumeMin(Kernel::HLERequestContext& ctx) { | ||
| 50 | LOG_DEBUG(Audio, "called."); | ||
| 51 | |||
| 52 | // This service function is currently hardcoded on the | ||
| 53 | // actual console to this value (as of 6.0.0). | ||
| 54 | constexpr s32 target_min_volume = 0; | ||
| 55 | |||
| 56 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 57 | rb.Push(RESULT_SUCCESS); | ||
| 58 | rb.Push(target_min_volume); | ||
| 59 | } | ||
| 60 | |||
| 61 | void AudCtl::GetTargetVolumeMax(Kernel::HLERequestContext& ctx) { | ||
| 62 | LOG_DEBUG(Audio, "called."); | ||
| 63 | |||
| 64 | // This service function is currently hardcoded on the | ||
| 65 | // actual console to this value (as of 6.0.0). | ||
| 66 | constexpr s32 target_max_volume = 15; | ||
| 67 | |||
| 68 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 69 | rb.Push(RESULT_SUCCESS); | ||
| 70 | rb.Push(target_max_volume); | ||
| 71 | } | ||
| 72 | |||
| 47 | } // namespace Service::Audio | 73 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h index 9d2d9e83b..c7fafc02e 100644 --- a/src/core/hle/service/audio/audctl.h +++ b/src/core/hle/service/audio/audctl.h | |||
| @@ -12,6 +12,10 @@ class AudCtl final : public ServiceFramework<AudCtl> { | |||
| 12 | public: | 12 | public: |
| 13 | explicit AudCtl(); | 13 | explicit AudCtl(); |
| 14 | ~AudCtl() override; | 14 | ~AudCtl() override; |
| 15 | |||
| 16 | private: | ||
| 17 | void GetTargetVolumeMin(Kernel::HLERequestContext& ctx); | ||
| 18 | void GetTargetVolumeMax(Kernel::HLERequestContext& ctx); | ||
| 15 | }; | 19 | }; |
| 16 | 20 | ||
| 17 | } // namespace Service::Audio | 21 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index e5daefdde..d7f1d348d 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp | |||
| @@ -25,6 +25,7 @@ public: | |||
| 25 | {11, nullptr, "GetAudioInBufferCount"}, | 25 | {11, nullptr, "GetAudioInBufferCount"}, |
| 26 | {12, nullptr, "SetAudioInDeviceGain"}, | 26 | {12, nullptr, "SetAudioInDeviceGain"}, |
| 27 | {13, nullptr, "GetAudioInDeviceGain"}, | 27 | {13, nullptr, "GetAudioInDeviceGain"}, |
| 28 | {14, nullptr, "FlushAudioInBuffers"}, | ||
| 28 | }; | 29 | }; |
| 29 | // clang-format on | 30 | // clang-format on |
| 30 | 31 | ||
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 39acb7b23..12875fb42 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -44,7 +44,7 @@ public: | |||
| 44 | std::string&& unique_name) | 44 | std::string&& unique_name) |
| 45 | : ServiceFramework("IAudioOut"), audio_core(audio_core), | 45 | : ServiceFramework("IAudioOut"), audio_core(audio_core), |
| 46 | device_name(std::move(device_name)), audio_params(audio_params) { | 46 | device_name(std::move(device_name)), audio_params(audio_params) { |
| 47 | 47 | // clang-format off | |
| 48 | static const FunctionInfo functions[] = { | 48 | static const FunctionInfo functions[] = { |
| 49 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, | 49 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, |
| 50 | {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, | 50 | {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, |
| @@ -58,7 +58,10 @@ public: | |||
| 58 | {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, | 58 | {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, |
| 59 | {10, nullptr, "GetAudioOutPlayedSampleCount"}, | 59 | {10, nullptr, "GetAudioOutPlayedSampleCount"}, |
| 60 | {11, nullptr, "FlushAudioOutBuffers"}, | 60 | {11, nullptr, "FlushAudioOutBuffers"}, |
| 61 | {12, nullptr, "SetAudioOutVolume"}, | ||
| 62 | {13, nullptr, "GetAudioOutVolume"}, | ||
| 61 | }; | 63 | }; |
| 64 | // clang-format on | ||
| 62 | RegisterHandlers(functions); | 65 | RegisterHandlers(functions); |
| 63 | 66 | ||
| 64 | // This is the event handle used to check if the audio buffer was released | 67 | // This is the event handle used to check if the audio buffer was released |
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 59ef603e1..974ff8e1a 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -154,7 +154,8 @@ public: | |||
| 154 | {96, nullptr, "GetLeHidEventInfo"}, | 154 | {96, nullptr, "GetLeHidEventInfo"}, |
| 155 | {97, nullptr, "RegisterBleHidEvent"}, | 155 | {97, nullptr, "RegisterBleHidEvent"}, |
| 156 | {98, nullptr, "SetLeScanParameter"}, | 156 | {98, nullptr, "SetLeScanParameter"}, |
| 157 | {256, nullptr, "GetIsManufacturingMode"} | 157 | {256, nullptr, "GetIsManufacturingMode"}, |
| 158 | {257, nullptr, "EmulateBluetoothCrash"}, | ||
| 158 | }; | 159 | }; |
| 159 | // clang-format on | 160 | // clang-format on |
| 160 | 161 | ||
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp index ae7b0720b..907f464ab 100644 --- a/src/core/hle/service/caps/caps.cpp +++ b/src/core/hle/service/caps/caps.cpp | |||
| @@ -15,32 +15,41 @@ public: | |||
| 15 | explicit CAPS_A() : ServiceFramework{"caps:a"} { | 15 | explicit CAPS_A() : ServiceFramework{"caps:a"} { |
| 16 | // clang-format off | 16 | // clang-format off |
| 17 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 18 | {0, nullptr, "Unknown1"}, | 18 | {0, nullptr, "GetAlbumFileCount"}, |
| 19 | {1, nullptr, "Unknown2"}, | 19 | {1, nullptr, "GetAlbumFileList"}, |
| 20 | {2, nullptr, "Unknown3"}, | 20 | {2, nullptr, "LoadAlbumFile"}, |
| 21 | {3, nullptr, "Unknown4"}, | 21 | {3, nullptr, "DeleteAlbumFile"}, |
| 22 | {4, nullptr, "Unknown5"}, | 22 | {4, nullptr, "StorageCopyAlbumFile"}, |
| 23 | {5, nullptr, "Unknown6"}, | 23 | {5, nullptr, "IsAlbumMounted"}, |
| 24 | {6, nullptr, "Unknown7"}, | 24 | {6, nullptr, "GetAlbumUsage"}, |
| 25 | {7, nullptr, "Unknown8"}, | 25 | {7, nullptr, "GetAlbumFileSize"}, |
| 26 | {8, nullptr, "Unknown9"}, | 26 | {8, nullptr, "LoadAlbumFileThumbnail"}, |
| 27 | {9, nullptr, "Unknown10"}, | 27 | {9, nullptr, "LoadAlbumScreenShotImage"}, |
| 28 | {10, nullptr, "Unknown11"}, | 28 | {10, nullptr, "LoadAlbumScreenShotThumbnailImage"}, |
| 29 | {11, nullptr, "Unknown12"}, | 29 | {11, nullptr, "GetAlbumEntryFromApplicationAlbumEntry"}, |
| 30 | {12, nullptr, "Unknown13"}, | 30 | {12, nullptr, "Unknown12"}, |
| 31 | {13, nullptr, "Unknown14"}, | 31 | {13, nullptr, "Unknown13"}, |
| 32 | {14, nullptr, "Unknown15"}, | 32 | {14, nullptr, "Unknown14"}, |
| 33 | {301, nullptr, "Unknown16"}, | 33 | {15, nullptr, "Unknown15"}, |
| 34 | {401, nullptr, "Unknown17"}, | 34 | {16, nullptr, "Unknown16"}, |
| 35 | {501, nullptr, "Unknown18"}, | 35 | {17, nullptr, "Unknown17"}, |
| 36 | {1001, nullptr, "Unknown19"}, | 36 | {18, nullptr, "Unknown18"}, |
| 37 | {1002, nullptr, "Unknown20"}, | 37 | {202, nullptr, "SaveEditedScreenShot"}, |
| 38 | {8001, nullptr, "Unknown21"}, | 38 | {301, nullptr, "GetLastThumbnail"}, |
| 39 | {8002, nullptr, "Unknown22"}, | 39 | {401, nullptr, "GetAutoSavingStorage"}, |
| 40 | {8011, nullptr, "Unknown23"}, | 40 | {501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"}, |
| 41 | {8012, nullptr, "Unknown24"}, | 41 | {1001, nullptr, "Unknown1001"}, |
| 42 | {8021, nullptr, "Unknown25"}, | 42 | {1002, nullptr, "Unknown1002"}, |
| 43 | {10011, nullptr, "Unknown26"}, | 43 | {1003, nullptr, "Unknown1003"}, |
| 44 | {8001, nullptr, "ForceAlbumUnmounted"}, | ||
| 45 | {8002, nullptr, "ResetAlbumMountStatus"}, | ||
| 46 | {8011, nullptr, "RefreshAlbumCache"}, | ||
| 47 | {8012, nullptr, "GetAlbumCache"}, | ||
| 48 | {8013, nullptr, "Unknown8013"}, | ||
| 49 | {8021, nullptr, "GetAlbumEntryFromApplicationAlbumEntryAruid"}, | ||
| 50 | {10011, nullptr, "SetInternalErrorConversionEnabled"}, | ||
| 51 | {50000, nullptr, "Unknown50000"}, | ||
| 52 | {60002, nullptr, "Unknown60002"}, | ||
| 44 | }; | 53 | }; |
| 45 | // clang-format on | 54 | // clang-format on |
| 46 | 55 | ||
| @@ -53,16 +62,17 @@ public: | |||
| 53 | explicit CAPS_C() : ServiceFramework{"caps:c"} { | 62 | explicit CAPS_C() : ServiceFramework{"caps:c"} { |
| 54 | // clang-format off | 63 | // clang-format off |
| 55 | static const FunctionInfo functions[] = { | 64 | static const FunctionInfo functions[] = { |
| 56 | {2001, nullptr, "Unknown1"}, | 65 | {33, nullptr, "Unknown33"}, |
| 57 | {2002, nullptr, "Unknown2"}, | 66 | {2001, nullptr, "Unknown2001"}, |
| 58 | {2011, nullptr, "Unknown3"}, | 67 | {2002, nullptr, "Unknown2002"}, |
| 59 | {2012, nullptr, "Unknown4"}, | 68 | {2011, nullptr, "Unknown2011"}, |
| 60 | {2013, nullptr, "Unknown5"}, | 69 | {2012, nullptr, "Unknown2012"}, |
| 61 | {2014, nullptr, "Unknown6"}, | 70 | {2013, nullptr, "Unknown2013"}, |
| 62 | {2101, nullptr, "Unknown7"}, | 71 | {2014, nullptr, "Unknown2014"}, |
| 63 | {2102, nullptr, "Unknown8"}, | 72 | {2101, nullptr, "Unknown2101"}, |
| 64 | {2201, nullptr, "Unknown9"}, | 73 | {2102, nullptr, "Unknown2102"}, |
| 65 | {2301, nullptr, "Unknown10"}, | 74 | {2201, nullptr, "Unknown2201"}, |
| 75 | {2301, nullptr, "Unknown2301"}, | ||
| 66 | }; | 76 | }; |
| 67 | // clang-format on | 77 | // clang-format on |
| 68 | 78 | ||
| @@ -127,11 +137,18 @@ public: | |||
| 127 | explicit CAPS_U() : ServiceFramework{"caps:u"} { | 137 | explicit CAPS_U() : ServiceFramework{"caps:u"} { |
| 128 | // clang-format off | 138 | // clang-format off |
| 129 | static const FunctionInfo functions[] = { | 139 | static const FunctionInfo functions[] = { |
| 140 | {32, nullptr, "SetShimLibraryVersion"}, | ||
| 130 | {102, nullptr, "GetAlbumFileListByAruid"}, | 141 | {102, nullptr, "GetAlbumFileListByAruid"}, |
| 131 | {103, nullptr, "DeleteAlbumFileByAruid"}, | 142 | {103, nullptr, "DeleteAlbumFileByAruid"}, |
| 132 | {104, nullptr, "GetAlbumFileSizeByAruid"}, | 143 | {104, nullptr, "GetAlbumFileSizeByAruid"}, |
| 144 | {105, nullptr, "DeleteAlbumFileByAruidForDebug"}, | ||
| 133 | {110, nullptr, "LoadAlbumScreenShotImageByAruid"}, | 145 | {110, nullptr, "LoadAlbumScreenShotImageByAruid"}, |
| 134 | {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"}, | 146 | {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"}, |
| 147 | {130, nullptr, "PrecheckToCreateContentsByAruid"}, | ||
| 148 | {140, nullptr, "GetAlbumFileList1AafeAruidDeprecated"}, | ||
| 149 | {141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"}, | ||
| 150 | {142, nullptr, "GetAlbumFileList3AaeAruid"}, | ||
| 151 | {143, nullptr, "GetAlbumFileList4AaeUidAruid"}, | ||
| 135 | {60002, nullptr, "OpenAccessorSessionForApplication"}, | 152 | {60002, nullptr, "OpenAccessorSessionForApplication"}, |
| 136 | }; | 153 | }; |
| 137 | // clang-format on | 154 | // clang-format on |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 0249b6992..e7df8fd98 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -664,10 +664,13 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||
| 664 | {100, nullptr, "OpenImageDirectoryFileSystem"}, | 664 | {100, nullptr, "OpenImageDirectoryFileSystem"}, |
| 665 | {110, nullptr, "OpenContentStorageFileSystem"}, | 665 | {110, nullptr, "OpenContentStorageFileSystem"}, |
| 666 | {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, | 666 | {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, |
| 667 | {130, nullptr, "OpenCustomStorageFileSystem"}, | ||
| 667 | {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, | 668 | {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, |
| 668 | {201, nullptr, "OpenDataStorageByProgramId"}, | 669 | {201, nullptr, "OpenDataStorageByProgramId"}, |
| 669 | {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"}, | 670 | {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"}, |
| 670 | {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"}, | 671 | {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"}, |
| 672 | {204, nullptr, "OpenDataFileSystemByProgramIndex"}, | ||
| 673 | {205, nullptr, "OpenDataStorageByProgramIndex"}, | ||
| 671 | {400, nullptr, "OpenDeviceOperator"}, | 674 | {400, nullptr, "OpenDeviceOperator"}, |
| 672 | {500, nullptr, "OpenSdCardDetectionEventNotifier"}, | 675 | {500, nullptr, "OpenSdCardDetectionEventNotifier"}, |
| 673 | {501, nullptr, "OpenGameCardDetectionEventNotifier"}, | 676 | {501, nullptr, "OpenGameCardDetectionEventNotifier"}, |
| @@ -691,6 +694,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||
| 691 | {614, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId"}, | 694 | {614, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId"}, |
| 692 | {615, nullptr, "QuerySaveDataInternalStorageTotalSize"}, | 695 | {615, nullptr, "QuerySaveDataInternalStorageTotalSize"}, |
| 693 | {616, nullptr, "GetSaveDataCommitId"}, | 696 | {616, nullptr, "GetSaveDataCommitId"}, |
| 697 | {617, nullptr, "UnregisterExternalKey"}, | ||
| 694 | {620, nullptr, "SetSdCardEncryptionSeed"}, | 698 | {620, nullptr, "SetSdCardEncryptionSeed"}, |
| 695 | {630, nullptr, "SetSdCardAccessibility"}, | 699 | {630, nullptr, "SetSdCardAccessibility"}, |
| 696 | {631, nullptr, "IsSdCardAccessible"}, | 700 | {631, nullptr, "IsSdCardAccessible"}, |
| @@ -701,6 +705,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||
| 701 | {710, nullptr, "ResolveAccessFailure"}, | 705 | {710, nullptr, "ResolveAccessFailure"}, |
| 702 | {720, nullptr, "AbandonAccessFailure"}, | 706 | {720, nullptr, "AbandonAccessFailure"}, |
| 703 | {800, nullptr, "GetAndClearFileSystemProxyErrorInfo"}, | 707 | {800, nullptr, "GetAndClearFileSystemProxyErrorInfo"}, |
| 708 | {810, nullptr, "RegisterProgramIndexMapInfo"}, | ||
| 704 | {1000, nullptr, "SetBisRootForHost"}, | 709 | {1000, nullptr, "SetBisRootForHost"}, |
| 705 | {1001, nullptr, "SetSaveDataSize"}, | 710 | {1001, nullptr, "SetSaveDataSize"}, |
| 706 | {1002, nullptr, "SetSaveDataRootPath"}, | 711 | {1002, nullptr, "SetSaveDataRootPath"}, |
| @@ -711,6 +716,8 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||
| 711 | {1007, nullptr, "RegisterUpdatePartition"}, | 716 | {1007, nullptr, "RegisterUpdatePartition"}, |
| 712 | {1008, nullptr, "OpenRegisteredUpdatePartition"}, | 717 | {1008, nullptr, "OpenRegisteredUpdatePartition"}, |
| 713 | {1009, nullptr, "GetAndClearMemoryReportInfo"}, | 718 | {1009, nullptr, "GetAndClearMemoryReportInfo"}, |
| 719 | {1010, nullptr, "SetDataStorageRedirectTarget"}, | ||
| 720 | {1011, nullptr, "OutputAccessLogToSdCard2"}, | ||
| 714 | {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, | 721 | {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, |
| 715 | {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, | 722 | {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, |
| 716 | {1200, nullptr, "OpenMultiCommitManager"}, | 723 | {1200, nullptr, "OpenMultiCommitManager"}, |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index d9225d624..5100e376c 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -12,6 +12,7 @@ namespace Service::Friend { | |||
| 12 | class IFriendService final : public ServiceFramework<IFriendService> { | 12 | class IFriendService final : public ServiceFramework<IFriendService> { |
| 13 | public: | 13 | public: |
| 14 | IFriendService() : ServiceFramework("IFriendService") { | 14 | IFriendService() : ServiceFramework("IFriendService") { |
| 15 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 16 | {0, nullptr, "GetCompletionEvent"}, | 17 | {0, nullptr, "GetCompletionEvent"}, |
| 17 | {1, nullptr, "Cancel"}, | 18 | {1, nullptr, "Cancel"}, |
| @@ -24,8 +25,7 @@ public: | |||
| 24 | {10400, nullptr, "GetBlockedUserListIds"}, | 25 | {10400, nullptr, "GetBlockedUserListIds"}, |
| 25 | {10500, nullptr, "GetProfileList"}, | 26 | {10500, nullptr, "GetProfileList"}, |
| 26 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, | 27 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, |
| 27 | {10601, &IFriendService::DeclareCloseOnlinePlaySession, | 28 | {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"}, |
| 28 | "DeclareCloseOnlinePlaySession"}, | ||
| 29 | {10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"}, | 29 | {10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"}, |
| 30 | {10700, nullptr, "GetPlayHistoryRegistrationKey"}, | 30 | {10700, nullptr, "GetPlayHistoryRegistrationKey"}, |
| 31 | {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, | 31 | {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, |
| @@ -88,6 +88,7 @@ public: | |||
| 88 | {30830, nullptr, "ClearPlayLog"}, | 88 | {30830, nullptr, "ClearPlayLog"}, |
| 89 | {49900, nullptr, "DeleteNetworkServiceAccountCache"}, | 89 | {49900, nullptr, "DeleteNetworkServiceAccountCache"}, |
| 90 | }; | 90 | }; |
| 91 | // clang-format on | ||
| 91 | 92 | ||
| 92 | RegisterHandlers(functions); | 93 | RegisterHandlers(functions); |
| 93 | } | 94 | } |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 63b55758b..a4ad95d96 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -210,6 +210,7 @@ Hid::Hid() : ServiceFramework("hid") { | |||
| 210 | {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, | 210 | {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, |
| 211 | {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, | 211 | {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, |
| 212 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, | 212 | {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"}, |
| 213 | {134, nullptr, "SetNpadAnalogStickUseCenterClamp"}, | ||
| 213 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, | 214 | {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, |
| 214 | {201, &Hid::SendVibrationValue, "SendVibrationValue"}, | 215 | {201, &Hid::SendVibrationValue, "SendVibrationValue"}, |
| 215 | {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, | 216 | {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, |
| @@ -221,6 +222,7 @@ Hid::Hid() : ServiceFramework("hid") { | |||
| 221 | {208, nullptr, "GetActualVibrationGcErmCommand"}, | 222 | {208, nullptr, "GetActualVibrationGcErmCommand"}, |
| 222 | {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, | 223 | {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"}, |
| 223 | {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"}, | 224 | {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"}, |
| 225 | {211, nullptr, "IsVibrationDeviceMounted"}, | ||
| 224 | {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, | 226 | {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"}, |
| 225 | {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, | 227 | {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"}, |
| 226 | {302, nullptr, "StopConsoleSixAxisSensor"}, | 228 | {302, nullptr, "StopConsoleSixAxisSensor"}, |
| @@ -265,6 +267,7 @@ Hid::Hid() : ServiceFramework("hid") { | |||
| 265 | {523, nullptr, "SetIsPalmaPairedConnectable"}, | 267 | {523, nullptr, "SetIsPalmaPairedConnectable"}, |
| 266 | {524, nullptr, "PairPalma"}, | 268 | {524, nullptr, "PairPalma"}, |
| 267 | {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"}, | 269 | {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"}, |
| 270 | {526, nullptr, "CancelWritePalmaWaveEntry"}, | ||
| 268 | {1000, nullptr, "SetNpadCommunicationMode"}, | 271 | {1000, nullptr, "SetNpadCommunicationMode"}, |
| 269 | {1001, nullptr, "GetNpadCommunicationMode"}, | 272 | {1001, nullptr, "GetNpadCommunicationMode"}, |
| 270 | }; | 273 | }; |
| @@ -797,12 +800,22 @@ public: | |||
| 797 | {232, nullptr, "EnableShipmentMode"}, | 800 | {232, nullptr, "EnableShipmentMode"}, |
| 798 | {233, nullptr, "ClearPairingInfo"}, | 801 | {233, nullptr, "ClearPairingInfo"}, |
| 799 | {234, nullptr, "GetUniquePadDeviceTypeSetInternal"}, | 802 | {234, nullptr, "GetUniquePadDeviceTypeSetInternal"}, |
| 803 | {235, nullptr, "EnableAnalogStickPower"}, | ||
| 800 | {301, nullptr, "GetAbstractedPadHandles"}, | 804 | {301, nullptr, "GetAbstractedPadHandles"}, |
| 801 | {302, nullptr, "GetAbstractedPadState"}, | 805 | {302, nullptr, "GetAbstractedPadState"}, |
| 802 | {303, nullptr, "GetAbstractedPadsState"}, | 806 | {303, nullptr, "GetAbstractedPadsState"}, |
| 803 | {321, nullptr, "SetAutoPilotVirtualPadState"}, | 807 | {321, nullptr, "SetAutoPilotVirtualPadState"}, |
| 804 | {322, nullptr, "UnsetAutoPilotVirtualPadState"}, | 808 | {322, nullptr, "UnsetAutoPilotVirtualPadState"}, |
| 805 | {323, nullptr, "UnsetAllAutoPilotVirtualPadState"}, | 809 | {323, nullptr, "UnsetAllAutoPilotVirtualPadState"}, |
| 810 | {324, nullptr, "AttachHdlsWorkBuffer"}, | ||
| 811 | {325, nullptr, "ReleaseHdlsWorkBuffer"}, | ||
| 812 | {326, nullptr, "DumpHdlsNpadAssignmentState"}, | ||
| 813 | {327, nullptr, "DumpHdlsStates"}, | ||
| 814 | {328, nullptr, "ApplyHdlsNpadAssignmentState"}, | ||
| 815 | {329, nullptr, "ApplyHdlsStateList"}, | ||
| 816 | {330, nullptr, "AttachHdlsVirtualDevice"}, | ||
| 817 | {331, nullptr, "DetachHdlsVirtualDevice"}, | ||
| 818 | {332, nullptr, "SetHdlsState"}, | ||
| 806 | {350, nullptr, "AddRegisteredDevice"}, | 819 | {350, nullptr, "AddRegisteredDevice"}, |
| 807 | {400, nullptr, "DisableExternalMcuOnNxDevice"}, | 820 | {400, nullptr, "DisableExternalMcuOnNxDevice"}, |
| 808 | {401, nullptr, "DisableRailDeviceFiltering"}, | 821 | {401, nullptr, "DisableRailDeviceFiltering"}, |
| @@ -825,6 +838,7 @@ public: | |||
| 825 | {131, nullptr, "ActivateSleepButton"}, | 838 | {131, nullptr, "ActivateSleepButton"}, |
| 826 | {141, nullptr, "AcquireCaptureButtonEventHandle"}, | 839 | {141, nullptr, "AcquireCaptureButtonEventHandle"}, |
| 827 | {151, nullptr, "ActivateCaptureButton"}, | 840 | {151, nullptr, "ActivateCaptureButton"}, |
| 841 | {161, nullptr, "GetPlatformConfig"}, | ||
| 828 | {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"}, | 842 | {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"}, |
| 829 | {211, nullptr, "GetNpadsWithNfc"}, | 843 | {211, nullptr, "GetNpadsWithNfc"}, |
| 830 | {212, nullptr, "AcquireNfcActivateEventHandle"}, | 844 | {212, nullptr, "AcquireNfcActivateEventHandle"}, |
| @@ -894,6 +908,7 @@ public: | |||
| 894 | {827, nullptr, "IsAnalogStickButtonPressed"}, | 908 | {827, nullptr, "IsAnalogStickButtonPressed"}, |
| 895 | {828, nullptr, "IsAnalogStickInReleasePosition"}, | 909 | {828, nullptr, "IsAnalogStickInReleasePosition"}, |
| 896 | {829, nullptr, "IsAnalogStickInCircumference"}, | 910 | {829, nullptr, "IsAnalogStickInCircumference"}, |
| 911 | {830, nullptr, "SetNotificationLedPattern"}, | ||
| 897 | {850, nullptr, "IsUsbFullKeyControllerEnabled"}, | 912 | {850, nullptr, "IsUsbFullKeyControllerEnabled"}, |
| 898 | {851, nullptr, "EnableUsbFullKeyController"}, | 913 | {851, nullptr, "EnableUsbFullKeyController"}, |
| 899 | {852, nullptr, "IsUsbConnected"}, | 914 | {852, nullptr, "IsUsbConnected"}, |
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index e250595e3..ed5059047 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp | |||
| @@ -52,9 +52,11 @@ public: | |||
| 52 | } | 52 | } |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | class ILocalCommunicationService final : public ServiceFramework<ILocalCommunicationService> { | 55 | class ISystemLocalCommunicationService final |
| 56 | : public ServiceFramework<ISystemLocalCommunicationService> { | ||
| 56 | public: | 57 | public: |
| 57 | explicit ILocalCommunicationService(const char* name) : ServiceFramework{name} { | 58 | explicit ISystemLocalCommunicationService() |
| 59 | : ServiceFramework{"ISystemLocalCommunicationService"} { | ||
| 58 | // clang-format off | 60 | // clang-format off |
| 59 | static const FunctionInfo functions[] = { | 61 | static const FunctionInfo functions[] = { |
| 60 | {0, nullptr, "GetState"}, | 62 | {0, nullptr, "GetState"}, |
| @@ -84,6 +86,50 @@ public: | |||
| 84 | {304, nullptr, "Disconnect"}, | 86 | {304, nullptr, "Disconnect"}, |
| 85 | {400, nullptr, "InitializeSystem"}, | 87 | {400, nullptr, "InitializeSystem"}, |
| 86 | {401, nullptr, "FinalizeSystem"}, | 88 | {401, nullptr, "FinalizeSystem"}, |
| 89 | {402, nullptr, "SetOperationMode"}, | ||
| 90 | {403, nullptr, "InitializeSystem2"}, | ||
| 91 | }; | ||
| 92 | // clang-format on | ||
| 93 | |||
| 94 | RegisterHandlers(functions); | ||
| 95 | } | ||
| 96 | }; | ||
| 97 | |||
| 98 | class IUserLocalCommunicationService final | ||
| 99 | : public ServiceFramework<IUserLocalCommunicationService> { | ||
| 100 | public: | ||
| 101 | explicit IUserLocalCommunicationService() : ServiceFramework{"IUserLocalCommunicationService"} { | ||
| 102 | // clang-format off | ||
| 103 | static const FunctionInfo functions[] = { | ||
| 104 | {0, nullptr, "GetState"}, | ||
| 105 | {1, nullptr, "GetNetworkInfo"}, | ||
| 106 | {2, nullptr, "GetIpv4Address"}, | ||
| 107 | {3, nullptr, "GetDisconnectReason"}, | ||
| 108 | {4, nullptr, "GetSecurityParameter"}, | ||
| 109 | {5, nullptr, "GetNetworkConfig"}, | ||
| 110 | {100, nullptr, "AttachStateChangeEvent"}, | ||
| 111 | {101, nullptr, "GetNetworkInfoLatestUpdate"}, | ||
| 112 | {102, nullptr, "Scan"}, | ||
| 113 | {103, nullptr, "ScanPrivate"}, | ||
| 114 | {104, nullptr, "SetWirelessControllerRestriction"}, | ||
| 115 | {200, nullptr, "OpenAccessPoint"}, | ||
| 116 | {201, nullptr, "CloseAccessPoint"}, | ||
| 117 | {202, nullptr, "CreateNetwork"}, | ||
| 118 | {203, nullptr, "CreateNetworkPrivate"}, | ||
| 119 | {204, nullptr, "DestroyNetwork"}, | ||
| 120 | {205, nullptr, "Reject"}, | ||
| 121 | {206, nullptr, "SetAdvertiseData"}, | ||
| 122 | {207, nullptr, "SetStationAcceptPolicy"}, | ||
| 123 | {208, nullptr, "AddAcceptFilterEntry"}, | ||
| 124 | {209, nullptr, "ClearAcceptFilter"}, | ||
| 125 | {300, nullptr, "OpenStation"}, | ||
| 126 | {301, nullptr, "CloseStation"}, | ||
| 127 | {302, nullptr, "Connect"}, | ||
| 128 | {303, nullptr, "ConnectPrivate"}, | ||
| 129 | {304, nullptr, "Disconnect"}, | ||
| 130 | {400, nullptr, "Initialize"}, | ||
| 131 | {401, nullptr, "Finalize"}, | ||
| 132 | {402, nullptr, "SetOperationMode"}, | ||
| 87 | }; | 133 | }; |
| 88 | // clang-format on | 134 | // clang-format on |
| 89 | 135 | ||
| @@ -108,7 +154,7 @@ public: | |||
| 108 | 154 | ||
| 109 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 155 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 110 | rb.Push(RESULT_SUCCESS); | 156 | rb.Push(RESULT_SUCCESS); |
| 111 | rb.PushIpcInterface<ILocalCommunicationService>("ISystemLocalCommunicationService"); | 157 | rb.PushIpcInterface<ISystemLocalCommunicationService>(); |
| 112 | } | 158 | } |
| 113 | }; | 159 | }; |
| 114 | 160 | ||
| @@ -129,7 +175,7 @@ public: | |||
| 129 | 175 | ||
| 130 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 176 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 131 | rb.Push(RESULT_SUCCESS); | 177 | rb.Push(RESULT_SUCCESS); |
| 132 | rb.PushIpcInterface<ILocalCommunicationService>("IUserLocalCommunicationService"); | 178 | rb.PushIpcInterface<IUserLocalCommunicationService>(); |
| 133 | } | 179 | } |
| 134 | }; | 180 | }; |
| 135 | 181 | ||
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 609102f2c..5af925515 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp | |||
| @@ -86,6 +86,7 @@ public: | |||
| 86 | {2, &RelocatableObject::LoadNrr, "LoadNrr"}, | 86 | {2, &RelocatableObject::LoadNrr, "LoadNrr"}, |
| 87 | {3, &RelocatableObject::UnloadNrr, "UnloadNrr"}, | 87 | {3, &RelocatableObject::UnloadNrr, "UnloadNrr"}, |
| 88 | {4, &RelocatableObject::Initialize, "Initialize"}, | 88 | {4, &RelocatableObject::Initialize, "Initialize"}, |
| 89 | {10, nullptr, "LoadNrrEx"}, | ||
| 89 | }; | 90 | }; |
| 90 | // clang-format on | 91 | // clang-format on |
| 91 | 92 | ||
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 60479bb45..f92571008 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp | |||
| @@ -15,12 +15,16 @@ namespace Service::NIFM { | |||
| 15 | class IScanRequest final : public ServiceFramework<IScanRequest> { | 15 | class IScanRequest final : public ServiceFramework<IScanRequest> { |
| 16 | public: | 16 | public: |
| 17 | explicit IScanRequest() : ServiceFramework("IScanRequest") { | 17 | explicit IScanRequest() : ServiceFramework("IScanRequest") { |
| 18 | // clang-format off | ||
| 18 | static const FunctionInfo functions[] = { | 19 | static const FunctionInfo functions[] = { |
| 19 | {0, nullptr, "Submit"}, | 20 | {0, nullptr, "Submit"}, |
| 20 | {1, nullptr, "IsProcessing"}, | 21 | {1, nullptr, "IsProcessing"}, |
| 21 | {2, nullptr, "GetResult"}, | 22 | {2, nullptr, "GetResult"}, |
| 22 | {3, nullptr, "GetSystemEventReadableHandle"}, | 23 | {3, nullptr, "GetSystemEventReadableHandle"}, |
| 24 | {4, nullptr, "SetChannels"}, | ||
| 23 | }; | 25 | }; |
| 26 | // clang-format on | ||
| 27 | |||
| 24 | RegisterHandlers(functions); | 28 | RegisterHandlers(functions); |
| 25 | } | 29 | } |
| 26 | }; | 30 | }; |
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp index ccb6f9da9..8751522ca 100644 --- a/src/core/hle/service/npns/npns.cpp +++ b/src/core/hle/service/npns/npns.cpp | |||
| @@ -45,7 +45,7 @@ public: | |||
| 45 | {114, nullptr, "AttachJid"}, | 45 | {114, nullptr, "AttachJid"}, |
| 46 | {115, nullptr, "DetachJid"}, | 46 | {115, nullptr, "DetachJid"}, |
| 47 | {201, nullptr, "RequestChangeStateForceTimed"}, | 47 | {201, nullptr, "RequestChangeStateForceTimed"}, |
| 48 | {102, nullptr, "RequestChangeStateForceAsync"}, | 48 | {202, nullptr, "RequestChangeStateForceAsync"}, |
| 49 | }; | 49 | }; |
| 50 | // clang-format on | 50 | // clang-format on |
| 51 | 51 | ||
| @@ -73,6 +73,7 @@ public: | |||
| 73 | {103, nullptr, "GetState"}, | 73 | {103, nullptr, "GetState"}, |
| 74 | {104, nullptr, "GetStatistics"}, | 74 | {104, nullptr, "GetStatistics"}, |
| 75 | {111, nullptr, "GetJid"}, | 75 | {111, nullptr, "GetJid"}, |
| 76 | {120, nullptr, "CreateNotificationReceiver"}, | ||
| 76 | }; | 77 | }; |
| 77 | // clang-format on | 78 | // clang-format on |
| 78 | 79 | ||
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp index 6081f41e1..c75b4ee34 100644 --- a/src/core/hle/service/pctl/module.cpp +++ b/src/core/hle/service/pctl/module.cpp | |||
| @@ -12,10 +12,10 @@ namespace Service::PCTL { | |||
| 12 | class IParentalControlService final : public ServiceFramework<IParentalControlService> { | 12 | class IParentalControlService final : public ServiceFramework<IParentalControlService> { |
| 13 | public: | 13 | public: |
| 14 | IParentalControlService() : ServiceFramework("IParentalControlService") { | 14 | IParentalControlService() : ServiceFramework("IParentalControlService") { |
| 15 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 16 | {1, &IParentalControlService::Initialize, "Initialize"}, | 17 | {1, &IParentalControlService::Initialize, "Initialize"}, |
| 17 | {1001, &IParentalControlService::CheckFreeCommunicationPermission, | 18 | {1001, &IParentalControlService::CheckFreeCommunicationPermission, "CheckFreeCommunicationPermission"}, |
| 18 | "CheckFreeCommunicationPermission"}, | ||
| 19 | {1002, nullptr, "ConfirmLaunchApplicationPermission"}, | 19 | {1002, nullptr, "ConfirmLaunchApplicationPermission"}, |
| 20 | {1003, nullptr, "ConfirmResumeApplicationPermission"}, | 20 | {1003, nullptr, "ConfirmResumeApplicationPermission"}, |
| 21 | {1004, nullptr, "ConfirmSnsPostPermission"}, | 21 | {1004, nullptr, "ConfirmSnsPostPermission"}, |
| @@ -30,6 +30,7 @@ public: | |||
| 30 | {1013, nullptr, "ConfirmStereoVisionPermission"}, | 30 | {1013, nullptr, "ConfirmStereoVisionPermission"}, |
| 31 | {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, | 31 | {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, |
| 32 | {1015, nullptr, "ConfirmPlayableApplicationVideo"}, | 32 | {1015, nullptr, "ConfirmPlayableApplicationVideo"}, |
| 33 | {1016, nullptr, "ConfirmShowNewsPermission"}, | ||
| 33 | {1031, nullptr, "IsRestrictionEnabled"}, | 34 | {1031, nullptr, "IsRestrictionEnabled"}, |
| 34 | {1032, nullptr, "GetSafetyLevel"}, | 35 | {1032, nullptr, "GetSafetyLevel"}, |
| 35 | {1033, nullptr, "SetSafetyLevel"}, | 36 | {1033, nullptr, "SetSafetyLevel"}, |
| @@ -45,6 +46,7 @@ public: | |||
| 45 | {1045, nullptr, "UpdateFreeCommunicationApplicationList"}, | 46 | {1045, nullptr, "UpdateFreeCommunicationApplicationList"}, |
| 46 | {1046, nullptr, "DisableFeaturesForReset"}, | 47 | {1046, nullptr, "DisableFeaturesForReset"}, |
| 47 | {1047, nullptr, "NotifyApplicationDownloadStarted"}, | 48 | {1047, nullptr, "NotifyApplicationDownloadStarted"}, |
| 49 | {1048, nullptr, "NotifyNetworkProfileCreated"}, | ||
| 48 | {1061, nullptr, "ConfirmStereoVisionRestrictionConfigurable"}, | 50 | {1061, nullptr, "ConfirmStereoVisionRestrictionConfigurable"}, |
| 49 | {1062, nullptr, "GetStereoVisionRestriction"}, | 51 | {1062, nullptr, "GetStereoVisionRestriction"}, |
| 50 | {1063, nullptr, "SetStereoVisionRestriction"}, | 52 | {1063, nullptr, "SetStereoVisionRestriction"}, |
| @@ -63,6 +65,7 @@ public: | |||
| 63 | {1411, nullptr, "GetPairingAccountInfo"}, | 65 | {1411, nullptr, "GetPairingAccountInfo"}, |
| 64 | {1421, nullptr, "GetAccountNickname"}, | 66 | {1421, nullptr, "GetAccountNickname"}, |
| 65 | {1424, nullptr, "GetAccountState"}, | 67 | {1424, nullptr, "GetAccountState"}, |
| 68 | {1425, nullptr, "RequestPostEvents"}, | ||
| 66 | {1432, nullptr, "GetSynchronizationEvent"}, | 69 | {1432, nullptr, "GetSynchronizationEvent"}, |
| 67 | {1451, nullptr, "StartPlayTimer"}, | 70 | {1451, nullptr, "StartPlayTimer"}, |
| 68 | {1452, nullptr, "StopPlayTimer"}, | 71 | {1452, nullptr, "StopPlayTimer"}, |
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index 6b27dc4a3..ebcc41a43 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp | |||
| @@ -42,15 +42,18 @@ private: | |||
| 42 | class DebugMonitor final : public ServiceFramework<DebugMonitor> { | 42 | class DebugMonitor final : public ServiceFramework<DebugMonitor> { |
| 43 | public: | 43 | public: |
| 44 | explicit DebugMonitor() : ServiceFramework{"pm:dmnt"} { | 44 | explicit DebugMonitor() : ServiceFramework{"pm:dmnt"} { |
| 45 | // clang-format off | ||
| 45 | static const FunctionInfo functions[] = { | 46 | static const FunctionInfo functions[] = { |
| 46 | {0, nullptr, "IsDebugMode"}, | 47 | {0, nullptr, "GetDebugProcesses"}, |
| 47 | {1, nullptr, "GetDebugProcesses"}, | 48 | {1, nullptr, "StartDebugProcess"}, |
| 48 | {2, nullptr, "StartDebugProcess"}, | 49 | {2, nullptr, "GetTitlePid"}, |
| 49 | {3, nullptr, "GetTitlePid"}, | 50 | {3, nullptr, "EnableDebugForTitleId"}, |
| 50 | {4, nullptr, "EnableDebugForTitleId"}, | 51 | {4, nullptr, "GetApplicationPid"}, |
| 51 | {5, nullptr, "GetApplicationPid"}, | 52 | {5, nullptr, "EnableDebugForApplication"}, |
| 52 | {6, nullptr, "EnableDebugForApplication"}, | 53 | {6, nullptr, "DisableDebug"}, |
| 53 | }; | 54 | }; |
| 55 | // clang-format on | ||
| 56 | |||
| 54 | RegisterHandlers(functions); | 57 | RegisterHandlers(functions); |
| 55 | } | 58 | } |
| 56 | }; | 59 | }; |
| @@ -68,6 +71,7 @@ public: | |||
| 68 | class Shell final : public ServiceFramework<Shell> { | 71 | class Shell final : public ServiceFramework<Shell> { |
| 69 | public: | 72 | public: |
| 70 | explicit Shell() : ServiceFramework{"pm:shell"} { | 73 | explicit Shell() : ServiceFramework{"pm:shell"} { |
| 74 | // clang-format off | ||
| 71 | static const FunctionInfo functions[] = { | 75 | static const FunctionInfo functions[] = { |
| 72 | {0, nullptr, "LaunchProcess"}, | 76 | {0, nullptr, "LaunchProcess"}, |
| 73 | {1, nullptr, "TerminateProcessByPid"}, | 77 | {1, nullptr, "TerminateProcessByPid"}, |
| @@ -77,7 +81,10 @@ public: | |||
| 77 | {5, nullptr, "NotifyBootFinished"}, | 81 | {5, nullptr, "NotifyBootFinished"}, |
| 78 | {6, nullptr, "GetApplicationPid"}, | 82 | {6, nullptr, "GetApplicationPid"}, |
| 79 | {7, nullptr, "BoostSystemMemoryResourceLimit"}, | 83 | {7, nullptr, "BoostSystemMemoryResourceLimit"}, |
| 84 | {8, nullptr, "EnableAdditionalSystemThreads"}, | ||
| 80 | }; | 85 | }; |
| 86 | // clang-format on | ||
| 87 | |||
| 81 | RegisterHandlers(functions); | 88 | RegisterHandlers(functions); |
| 82 | } | 89 | } |
| 83 | }; | 90 | }; |
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 1afc43f75..4ecb6bcef 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -116,6 +116,7 @@ void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | SET::SET() : ServiceFramework("set") { | 118 | SET::SET() : ServiceFramework("set") { |
| 119 | // clang-format off | ||
| 119 | static const FunctionInfo functions[] = { | 120 | static const FunctionInfo functions[] = { |
| 120 | {0, &SET::GetLanguageCode, "GetLanguageCode"}, | 121 | {0, &SET::GetLanguageCode, "GetLanguageCode"}, |
| 121 | {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, | 122 | {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, |
| @@ -126,7 +127,10 @@ SET::SET() : ServiceFramework("set") { | |||
| 126 | {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, | 127 | {6, &SET::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, |
| 127 | {7, nullptr, "GetKeyCodeMap"}, | 128 | {7, nullptr, "GetKeyCodeMap"}, |
| 128 | {8, nullptr, "GetQuestFlag"}, | 129 | {8, nullptr, "GetQuestFlag"}, |
| 130 | {9, nullptr, "GetKeyCodeMap2"}, | ||
| 129 | }; | 131 | }; |
| 132 | // clang-format on | ||
| 133 | |||
| 130 | RegisterHandlers(functions); | 134 | RegisterHandlers(functions); |
| 131 | } | 135 | } |
| 132 | 136 | ||
diff --git a/src/core/hle/service/set/set_cal.cpp b/src/core/hle/service/set/set_cal.cpp index 34654bb07..5981c575c 100644 --- a/src/core/hle/service/set/set_cal.cpp +++ b/src/core/hle/service/set/set_cal.cpp | |||
| @@ -40,7 +40,7 @@ SET_CAL::SET_CAL() : ServiceFramework("set:cal") { | |||
| 40 | {30, nullptr, "GetAmiiboEcqvBlsCertificate"}, | 40 | {30, nullptr, "GetAmiiboEcqvBlsCertificate"}, |
| 41 | {31, nullptr, "GetAmiiboEcqvBlsRootCertificate"}, | 41 | {31, nullptr, "GetAmiiboEcqvBlsRootCertificate"}, |
| 42 | {32, nullptr, "GetUsbTypeCPowerSourceCircuitVersion"}, | 42 | {32, nullptr, "GetUsbTypeCPowerSourceCircuitVersion"}, |
| 43 | {33, nullptr, "GetBatteryVersion"}, | 43 | {41, nullptr, "GetBatteryVersion"}, |
| 44 | }; | 44 | }; |
| 45 | RegisterHandlers(functions); | 45 | RegisterHandlers(functions); |
| 46 | } | 46 | } |
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index ecee554bf..98d0cfdfd 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp | |||
| @@ -104,6 +104,7 @@ void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) { | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | SET_SYS::SET_SYS() : ServiceFramework("set:sys") { | 106 | SET_SYS::SET_SYS() : ServiceFramework("set:sys") { |
| 107 | // clang-format off | ||
| 107 | static const FunctionInfo functions[] = { | 108 | static const FunctionInfo functions[] = { |
| 108 | {0, nullptr, "SetLanguageCode"}, | 109 | {0, nullptr, "SetLanguageCode"}, |
| 109 | {1, nullptr, "SetNetworkSettings"}, | 110 | {1, nullptr, "SetNetworkSettings"}, |
| @@ -252,7 +253,33 @@ SET_SYS::SET_SYS() : ServiceFramework("set:sys") { | |||
| 252 | {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, | 253 | {147, nullptr, "GetConsoleSixAxisSensorAngularAcceleration"}, |
| 253 | {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, | 254 | {148, nullptr, "SetConsoleSixAxisSensorAngularAcceleration"}, |
| 254 | {149, nullptr, "GetRebootlessSystemUpdateVersion"}, | 255 | {149, nullptr, "GetRebootlessSystemUpdateVersion"}, |
| 256 | {150, nullptr, "GetDeviceTimeZoneLocationUpdatedTime"}, | ||
| 257 | {151, nullptr, "SetDeviceTimeZoneLocationUpdatedTime"}, | ||
| 258 | {152, nullptr, "GetUserSystemClockAutomaticCorrectionUpdatedTime"}, | ||
| 259 | {153, nullptr, "SetUserSystemClockAutomaticCorrectionUpdatedTime"}, | ||
| 260 | {154, nullptr, "GetAccountOnlineStorageSettings"}, | ||
| 261 | {155, nullptr, "SetAccountOnlineStorageSettings"}, | ||
| 262 | {156, nullptr, "GetPctlReadyFlag"}, | ||
| 263 | {157, nullptr, "SetPctlReadyFlag"}, | ||
| 264 | {162, nullptr, "GetPtmBatteryVersion"}, | ||
| 265 | {163, nullptr, "SetPtmBatteryVersion"}, | ||
| 266 | {164, nullptr, "GetUsb30HostEnableFlag"}, | ||
| 267 | {165, nullptr, "SetUsb30HostEnableFlag"}, | ||
| 268 | {166, nullptr, "GetUsb30DeviceEnableFlag"}, | ||
| 269 | {167, nullptr, "SetUsb30DeviceEnableFlag"}, | ||
| 270 | {168, nullptr, "GetThemeId"}, | ||
| 271 | {169, nullptr, "SetThemeId"}, | ||
| 272 | {170, nullptr, "GetChineseTraditionalInputMethod"}, | ||
| 273 | {171, nullptr, "SetChineseTraditionalInputMethod"}, | ||
| 274 | {172, nullptr, "GetPtmCycleCountReliability"}, | ||
| 275 | {173, nullptr, "SetPtmCycleCountReliability"}, | ||
| 276 | {175, nullptr, "GetThemeSettings"}, | ||
| 277 | {176, nullptr, "SetThemeSettings"}, | ||
| 278 | {177, nullptr, "GetThemeKey"}, | ||
| 279 | {178, nullptr, "SetThemeKey"}, | ||
| 255 | }; | 280 | }; |
| 281 | // clang-format on | ||
| 282 | |||
| 256 | RegisterHandlers(functions); | 283 | RegisterHandlers(functions); |
| 257 | } | 284 | } |
| 258 | 285 | ||
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 4342f3b2d..884ad173b 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp | |||
| @@ -73,6 +73,7 @@ void BSD::Close(Kernel::HLERequestContext& ctx) { | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | BSD::BSD(const char* name) : ServiceFramework(name) { | 75 | BSD::BSD(const char* name) : ServiceFramework(name) { |
| 76 | // clang-format off | ||
| 76 | static const FunctionInfo functions[] = { | 77 | static const FunctionInfo functions[] = { |
| 77 | {0, &BSD::RegisterClient, "RegisterClient"}, | 78 | {0, &BSD::RegisterClient, "RegisterClient"}, |
| 78 | {1, &BSD::StartMonitoring, "StartMonitoring"}, | 79 | {1, &BSD::StartMonitoring, "StartMonitoring"}, |
| @@ -105,7 +106,11 @@ BSD::BSD(const char* name) : ServiceFramework(name) { | |||
| 105 | {28, nullptr, "GetResourceStatistics"}, | 106 | {28, nullptr, "GetResourceStatistics"}, |
| 106 | {29, nullptr, "RecvMMsg"}, | 107 | {29, nullptr, "RecvMMsg"}, |
| 107 | {30, nullptr, "SendMMsg"}, | 108 | {30, nullptr, "SendMMsg"}, |
| 109 | {31, nullptr, "EventFd"}, | ||
| 110 | {32, nullptr, "RegisterResourceStatisticsName"}, | ||
| 108 | }; | 111 | }; |
| 112 | // clang-format on | ||
| 113 | |||
| 109 | RegisterHandlers(functions); | 114 | RegisterHandlers(functions); |
| 110 | } | 115 | } |
| 111 | 116 | ||
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index f7f87a958..65040c077 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp | |||
| @@ -103,6 +103,8 @@ public: | |||
| 103 | {4, nullptr, "DebugIoctl"}, | 103 | {4, nullptr, "DebugIoctl"}, |
| 104 | {5, &SSL::SetInterfaceVersion, "SetInterfaceVersion"}, | 104 | {5, &SSL::SetInterfaceVersion, "SetInterfaceVersion"}, |
| 105 | {6, nullptr, "FlushSessionCache"}, | 105 | {6, nullptr, "FlushSessionCache"}, |
| 106 | {7, nullptr, "SetDebugOption"}, | ||
| 107 | {8, nullptr, "GetDebugOption"}, | ||
| 106 | }; | 108 | }; |
| 107 | // clang-format on | 109 | // clang-format on |
| 108 | 110 | ||
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index b3a196f65..8d122ae33 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp | |||
| @@ -8,6 +8,7 @@ namespace Service::Time { | |||
| 8 | 8 | ||
| 9 | Time::Time(std::shared_ptr<Module> time, const char* name) | 9 | Time::Time(std::shared_ptr<Module> time, const char* name) |
| 10 | : Module::Interface(std::move(time), name) { | 10 | : Module::Interface(std::move(time), name) { |
| 11 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | 12 | static const FunctionInfo functions[] = { |
| 12 | {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, | 13 | {0, &Time::GetStandardUserSystemClock, "GetStandardUserSystemClock"}, |
| 13 | {1, &Time::GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, | 14 | {1, &Time::GetStandardNetworkSystemClock, "GetStandardNetworkSystemClock"}, |
| @@ -15,18 +16,23 @@ Time::Time(std::shared_ptr<Module> time, const char* name) | |||
| 15 | {3, &Time::GetTimeZoneService, "GetTimeZoneService"}, | 16 | {3, &Time::GetTimeZoneService, "GetTimeZoneService"}, |
| 16 | {4, &Time::GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, | 17 | {4, &Time::GetStandardLocalSystemClock, "GetStandardLocalSystemClock"}, |
| 17 | {5, nullptr, "GetEphemeralNetworkSystemClock"}, | 18 | {5, nullptr, "GetEphemeralNetworkSystemClock"}, |
| 19 | {20, nullptr, "GetSharedMemoryNativeHandle"}, | ||
| 20 | {30, nullptr, "GetStandardNetworkClockOperationEventReadableHandle"}, | ||
| 21 | {31, nullptr, "GetEphemeralNetworkClockOperationEventReadableHandle"}, | ||
| 18 | {50, nullptr, "SetStandardSteadyClockInternalOffset"}, | 22 | {50, nullptr, "SetStandardSteadyClockInternalOffset"}, |
| 19 | {100, nullptr, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, | 23 | {100, nullptr, "IsStandardUserSystemClockAutomaticCorrectionEnabled"}, |
| 20 | {101, nullptr, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, | 24 | {101, nullptr, "SetStandardUserSystemClockAutomaticCorrectionEnabled"}, |
| 21 | {102, nullptr, "GetStandardUserSystemClockInitialYear"}, | 25 | {102, nullptr, "GetStandardUserSystemClockInitialYear"}, |
| 22 | {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, | 26 | {200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"}, |
| 27 | {201, nullptr, "GetStandardUserSystemClockAutomaticCorrectionUpdatedTime"}, | ||
| 23 | {300, nullptr, "CalculateMonotonicSystemClockBaseTimePoint"}, | 28 | {300, nullptr, "CalculateMonotonicSystemClockBaseTimePoint"}, |
| 24 | {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, | 29 | {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, |
| 25 | {401, nullptr, "GetClockSnapshotFromSystemClockContext"}, | 30 | {401, nullptr, "GetClockSnapshotFromSystemClockContext"}, |
| 26 | {500, &Time::CalculateStandardUserSystemClockDifferenceByUser, | 31 | {500, &Time::CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, |
| 27 | "CalculateStandardUserSystemClockDifferenceByUser"}, | ||
| 28 | {501, nullptr, "CalculateSpanBetween"}, | 32 | {501, nullptr, "CalculateSpanBetween"}, |
| 29 | }; | 33 | }; |
| 34 | // clang-format on | ||
| 35 | |||
| 30 | RegisterHandlers(functions); | 36 | RegisterHandlers(functions); |
| 31 | } | 37 | } |
| 32 | 38 | ||
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 07aa7a1cd..10b13fb1d 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -86,25 +86,29 @@ FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::Virtua | |||
| 86 | return FileType::Error; | 86 | return FileType::Error; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) { | 89 | AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirectory::Load( |
| 90 | Kernel::Process& process) { | ||
| 90 | if (is_loaded) { | 91 | if (is_loaded) { |
| 91 | return ResultStatus::ErrorAlreadyLoaded; | 92 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | if (dir == nullptr) { | 95 | if (dir == nullptr) { |
| 95 | if (file == nullptr) | 96 | if (file == nullptr) { |
| 96 | return ResultStatus::ErrorNullFile; | 97 | return {ResultStatus::ErrorNullFile, {}}; |
| 98 | } | ||
| 99 | |||
| 97 | dir = file->GetContainingDirectory(); | 100 | dir = file->GetContainingDirectory(); |
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | // Read meta to determine title ID | 103 | // Read meta to determine title ID |
| 101 | FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); | 104 | FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); |
| 102 | if (npdm == nullptr) | 105 | if (npdm == nullptr) { |
| 103 | return ResultStatus::ErrorMissingNPDM; | 106 | return {ResultStatus::ErrorMissingNPDM, {}}; |
| 107 | } | ||
| 104 | 108 | ||
| 105 | ResultStatus result = metadata.Load(npdm); | 109 | const ResultStatus result = metadata.Load(npdm); |
| 106 | if (result != ResultStatus::Success) { | 110 | if (result != ResultStatus::Success) { |
| 107 | return result; | 111 | return {result, {}}; |
| 108 | } | 112 | } |
| 109 | 113 | ||
| 110 | if (override_update) { | 114 | if (override_update) { |
| @@ -114,23 +118,24 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 114 | 118 | ||
| 115 | // Reread in case PatchExeFS affected the main.npdm | 119 | // Reread in case PatchExeFS affected the main.npdm |
| 116 | npdm = dir->GetFile("main.npdm"); | 120 | npdm = dir->GetFile("main.npdm"); |
| 117 | if (npdm == nullptr) | 121 | if (npdm == nullptr) { |
| 118 | return ResultStatus::ErrorMissingNPDM; | 122 | return {ResultStatus::ErrorMissingNPDM, {}}; |
| 123 | } | ||
| 119 | 124 | ||
| 120 | ResultStatus result2 = metadata.Load(npdm); | 125 | const ResultStatus result2 = metadata.Load(npdm); |
| 121 | if (result2 != ResultStatus::Success) { | 126 | if (result2 != ResultStatus::Success) { |
| 122 | return result2; | 127 | return {result2, {}}; |
| 123 | } | 128 | } |
| 124 | metadata.Print(); | 129 | metadata.Print(); |
| 125 | 130 | ||
| 126 | const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; | 131 | const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; |
| 127 | if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit || | 132 | if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit || |
| 128 | arch_bits == FileSys::ProgramAddressSpaceType::Is32BitNoMap) { | 133 | arch_bits == FileSys::ProgramAddressSpaceType::Is32BitNoMap) { |
| 129 | return ResultStatus::Error32BitISA; | 134 | return {ResultStatus::Error32BitISA, {}}; |
| 130 | } | 135 | } |
| 131 | 136 | ||
| 132 | if (process.LoadFromMetadata(metadata).IsError()) { | 137 | if (process.LoadFromMetadata(metadata).IsError()) { |
| 133 | return ResultStatus::ErrorUnableToParseKernelMetadata; | 138 | return {ResultStatus::ErrorUnableToParseKernelMetadata, {}}; |
| 134 | } | 139 | } |
| 135 | 140 | ||
| 136 | const FileSys::PatchManager pm(metadata.GetTitleID()); | 141 | const FileSys::PatchManager pm(metadata.GetTitleID()); |
| @@ -150,7 +155,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 150 | const auto tentative_next_load_addr = | 155 | const auto tentative_next_load_addr = |
| 151 | AppLoader_NSO::LoadModule(process, *module_file, load_addr, should_pass_arguments, pm); | 156 | AppLoader_NSO::LoadModule(process, *module_file, load_addr, should_pass_arguments, pm); |
| 152 | if (!tentative_next_load_addr) { | 157 | if (!tentative_next_load_addr) { |
| 153 | return ResultStatus::ErrorLoadingNSO; | 158 | return {ResultStatus::ErrorLoadingNSO, {}}; |
| 154 | } | 159 | } |
| 155 | 160 | ||
| 156 | next_load_addr = *tentative_next_load_addr; | 161 | next_load_addr = *tentative_next_load_addr; |
| @@ -159,8 +164,6 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 159 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); | 164 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); |
| 160 | } | 165 | } |
| 161 | 166 | ||
| 162 | process.Run(base_address, metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()); | ||
| 163 | |||
| 164 | // Find the RomFS by searching for a ".romfs" file in this directory | 167 | // Find the RomFS by searching for a ".romfs" file in this directory |
| 165 | const auto& files = dir->GetFiles(); | 168 | const auto& files = dir->GetFiles(); |
| 166 | const auto romfs_iter = | 169 | const auto romfs_iter = |
| @@ -175,7 +178,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(Kernel::Process& process) | |||
| 175 | } | 178 | } |
| 176 | 179 | ||
| 177 | is_loaded = true; | 180 | is_loaded = true; |
| 178 | return ResultStatus::Success; | 181 | return {ResultStatus::Success, |
| 182 | LoadParameters{metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()}}; | ||
| 179 | } | 183 | } |
| 180 | 184 | ||
| 181 | ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { | 185 | ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { |
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 1615cb5a8..1a65c16a4 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h | |||
| @@ -37,7 +37,7 @@ public: | |||
| 37 | return IdentifyType(file); | 37 | return IdentifyType(file); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | ResultStatus Load(Kernel::Process& process) override; | 40 | LoadResult Load(Kernel::Process& process) override; |
| 41 | 41 | ||
| 42 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 42 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 43 | ResultStatus ReadIcon(std::vector<u8>& buffer) override; | 43 | ResultStatus ReadIcon(std::vector<u8>& buffer) override; |
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 46ac372f6..6d4b02375 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -382,13 +382,15 @@ FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& file) { | |||
| 382 | return FileType::Error; | 382 | return FileType::Error; |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | ResultStatus AppLoader_ELF::Load(Kernel::Process& process) { | 385 | AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::Process& process) { |
| 386 | if (is_loaded) | 386 | if (is_loaded) { |
| 387 | return ResultStatus::ErrorAlreadyLoaded; | 387 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 388 | } | ||
| 388 | 389 | ||
| 389 | std::vector<u8> buffer = file->ReadAllBytes(); | 390 | std::vector<u8> buffer = file->ReadAllBytes(); |
| 390 | if (buffer.size() != file->GetSize()) | 391 | if (buffer.size() != file->GetSize()) { |
| 391 | return ResultStatus::ErrorIncorrectELFFileSize; | 392 | return {ResultStatus::ErrorIncorrectELFFileSize, {}}; |
| 393 | } | ||
| 392 | 394 | ||
| 393 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | 395 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); |
| 394 | ElfReader elf_reader(&buffer[0]); | 396 | ElfReader elf_reader(&buffer[0]); |
| @@ -396,10 +398,9 @@ ResultStatus AppLoader_ELF::Load(Kernel::Process& process) { | |||
| 396 | const VAddr entry_point = codeset.entrypoint; | 398 | const VAddr entry_point = codeset.entrypoint; |
| 397 | 399 | ||
| 398 | process.LoadModule(std::move(codeset), entry_point); | 400 | process.LoadModule(std::move(codeset), entry_point); |
| 399 | process.Run(entry_point, 48, Memory::DEFAULT_STACK_SIZE); | ||
| 400 | 401 | ||
| 401 | is_loaded = true; | 402 | is_loaded = true; |
| 402 | return ResultStatus::Success; | 403 | return {ResultStatus::Success, LoadParameters{48, Memory::DEFAULT_STACK_SIZE}}; |
| 403 | } | 404 | } |
| 404 | 405 | ||
| 405 | } // namespace Loader | 406 | } // namespace Loader |
diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index a2d33021c..7ef7770a6 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h | |||
| @@ -26,7 +26,7 @@ public: | |||
| 26 | return IdentifyType(file); | 26 | return IdentifyType(file); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | ResultStatus Load(Kernel::Process& process) override; | 29 | LoadResult Load(Kernel::Process& process) override; |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | } // namespace Loader | 32 | } // namespace Loader |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index bb925f4a6..f7846db52 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -131,6 +131,12 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status); | |||
| 131 | /// Interface for loading an application | 131 | /// Interface for loading an application |
| 132 | class AppLoader : NonCopyable { | 132 | class AppLoader : NonCopyable { |
| 133 | public: | 133 | public: |
| 134 | struct LoadParameters { | ||
| 135 | s32 main_thread_priority; | ||
| 136 | u64 main_thread_stack_size; | ||
| 137 | }; | ||
| 138 | using LoadResult = std::pair<ResultStatus, std::optional<LoadParameters>>; | ||
| 139 | |||
| 134 | explicit AppLoader(FileSys::VirtualFile file); | 140 | explicit AppLoader(FileSys::VirtualFile file); |
| 135 | virtual ~AppLoader(); | 141 | virtual ~AppLoader(); |
| 136 | 142 | ||
| @@ -145,7 +151,7 @@ public: | |||
| 145 | * @param process The newly created process. | 151 | * @param process The newly created process. |
| 146 | * @return The status result of the operation. | 152 | * @return The status result of the operation. |
| 147 | */ | 153 | */ |
| 148 | virtual ResultStatus Load(Kernel::Process& process) = 0; | 154 | virtual LoadResult Load(Kernel::Process& process) = 0; |
| 149 | 155 | ||
| 150 | /** | 156 | /** |
| 151 | * Loads the system mode that this application needs. | 157 | * Loads the system mode that this application needs. |
diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index 93a970d10..34efef09a 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp | |||
| @@ -41,31 +41,37 @@ FileType AppLoader_NAX::GetFileType() const { | |||
| 41 | return IdentifyTypeImpl(*nax); | 41 | return IdentifyTypeImpl(*nax); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | ResultStatus AppLoader_NAX::Load(Kernel::Process& process) { | 44 | AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process) { |
| 45 | if (is_loaded) { | 45 | if (is_loaded) { |
| 46 | return ResultStatus::ErrorAlreadyLoaded; | 46 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | if (nax->GetStatus() != ResultStatus::Success) | 49 | const auto nax_status = nax->GetStatus(); |
| 50 | return nax->GetStatus(); | 50 | if (nax_status != ResultStatus::Success) { |
| 51 | return {nax_status, {}}; | ||
| 52 | } | ||
| 51 | 53 | ||
| 52 | const auto nca = nax->AsNCA(); | 54 | const auto nca = nax->AsNCA(); |
| 53 | if (nca == nullptr) { | 55 | if (nca == nullptr) { |
| 54 | if (!Core::Crypto::KeyManager::KeyFileExists(false)) | 56 | if (!Core::Crypto::KeyManager::KeyFileExists(false)) { |
| 55 | return ResultStatus::ErrorMissingProductionKeyFile; | 57 | return {ResultStatus::ErrorMissingProductionKeyFile, {}}; |
| 56 | return ResultStatus::ErrorNAXInconvertibleToNCA; | 58 | } |
| 59 | |||
| 60 | return {ResultStatus::ErrorNAXInconvertibleToNCA, {}}; | ||
| 57 | } | 61 | } |
| 58 | 62 | ||
| 59 | if (nca->GetStatus() != ResultStatus::Success) | 63 | const auto nca_status = nca->GetStatus(); |
| 60 | return nca->GetStatus(); | 64 | if (nca_status != ResultStatus::Success) { |
| 65 | return {nca_status, {}}; | ||
| 66 | } | ||
| 61 | 67 | ||
| 62 | const auto result = nca_loader->Load(process); | 68 | const auto result = nca_loader->Load(process); |
| 63 | if (result != ResultStatus::Success) | 69 | if (result.first != ResultStatus::Success) { |
| 64 | return result; | 70 | return result; |
| 71 | } | ||
| 65 | 72 | ||
| 66 | is_loaded = true; | 73 | is_loaded = true; |
| 67 | 74 | return result; | |
| 68 | return ResultStatus::Success; | ||
| 69 | } | 75 | } |
| 70 | 76 | ||
| 71 | ResultStatus AppLoader_NAX::ReadRomFS(FileSys::VirtualFile& dir) { | 77 | ResultStatus AppLoader_NAX::ReadRomFS(FileSys::VirtualFile& dir) { |
diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index f40079574..00f1659c1 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h | |||
| @@ -33,7 +33,7 @@ public: | |||
| 33 | 33 | ||
| 34 | FileType GetFileType() const override; | 34 | FileType GetFileType() const override; |
| 35 | 35 | ||
| 36 | ResultStatus Load(Kernel::Process& process) override; | 36 | LoadResult Load(Kernel::Process& process) override; |
| 37 | 37 | ||
| 38 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 38 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 39 | u64 ReadRomFSIVFCOffset() const override; | 39 | u64 ReadRomFSIVFCOffset() const override; |
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index ce8196fcf..b3f8f1083 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp | |||
| @@ -30,36 +30,38 @@ FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { | |||
| 30 | return FileType::Error; | 30 | return FileType::Error; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | ResultStatus AppLoader_NCA::Load(Kernel::Process& process) { | 33 | AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::Process& process) { |
| 34 | if (is_loaded) { | 34 | if (is_loaded) { |
| 35 | return ResultStatus::ErrorAlreadyLoaded; | 35 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | const auto result = nca->GetStatus(); | 38 | const auto result = nca->GetStatus(); |
| 39 | if (result != ResultStatus::Success) { | 39 | if (result != ResultStatus::Success) { |
| 40 | return result; | 40 | return {result, {}}; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | if (nca->GetType() != FileSys::NCAContentType::Program) | 43 | if (nca->GetType() != FileSys::NCAContentType::Program) { |
| 44 | return ResultStatus::ErrorNCANotProgram; | 44 | return {ResultStatus::ErrorNCANotProgram, {}}; |
| 45 | } | ||
| 45 | 46 | ||
| 46 | const auto exefs = nca->GetExeFS(); | 47 | const auto exefs = nca->GetExeFS(); |
| 47 | 48 | if (exefs == nullptr) { | |
| 48 | if (exefs == nullptr) | 49 | return {ResultStatus::ErrorNoExeFS, {}}; |
| 49 | return ResultStatus::ErrorNoExeFS; | 50 | } |
| 50 | 51 | ||
| 51 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs, true); | 52 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs, true); |
| 52 | 53 | ||
| 53 | const auto load_result = directory_loader->Load(process); | 54 | const auto load_result = directory_loader->Load(process); |
| 54 | if (load_result != ResultStatus::Success) | 55 | if (load_result.first != ResultStatus::Success) { |
| 55 | return load_result; | 56 | return load_result; |
| 57 | } | ||
| 56 | 58 | ||
| 57 | if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) | 59 | if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) { |
| 58 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); | 60 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); |
| 61 | } | ||
| 59 | 62 | ||
| 60 | is_loaded = true; | 63 | is_loaded = true; |
| 61 | 64 | return load_result; | |
| 62 | return ResultStatus::Success; | ||
| 63 | } | 65 | } |
| 64 | 66 | ||
| 65 | ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { | 67 | ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { |
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index b9f077468..94f0ed677 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h | |||
| @@ -33,7 +33,7 @@ public: | |||
| 33 | return IdentifyType(file); | 33 | return IdentifyType(file); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | ResultStatus Load(Kernel::Process& process) override; | 36 | LoadResult Load(Kernel::Process& process) override; |
| 37 | 37 | ||
| 38 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 38 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 39 | u64 ReadRomFSIVFCOffset() const override; | 39 | u64 ReadRomFSIVFCOffset() const override; |
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 31e4a0c84..6a0ca389b 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp | |||
| @@ -201,25 +201,25 @@ bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& fi | |||
| 201 | return LoadNroImpl(process, file.ReadAllBytes(), file.GetName(), load_base); | 201 | return LoadNroImpl(process, file.ReadAllBytes(), file.GetName(), load_base); |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | ResultStatus AppLoader_NRO::Load(Kernel::Process& process) { | 204 | AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process) { |
| 205 | if (is_loaded) { | 205 | if (is_loaded) { |
| 206 | return ResultStatus::ErrorAlreadyLoaded; | 206 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | // Load NRO | 209 | // Load NRO |
| 210 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | 210 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); |
| 211 | 211 | ||
| 212 | if (!LoadNro(process, *file, base_address)) { | 212 | if (!LoadNro(process, *file, base_address)) { |
| 213 | return ResultStatus::ErrorLoadingNRO; | 213 | return {ResultStatus::ErrorLoadingNRO, {}}; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | if (romfs != nullptr) | 216 | if (romfs != nullptr) { |
| 217 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); | 217 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); |
| 218 | 218 | } | |
| 219 | process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); | ||
| 220 | 219 | ||
| 221 | is_loaded = true; | 220 | is_loaded = true; |
| 222 | return ResultStatus::Success; | 221 | return {ResultStatus::Success, |
| 222 | LoadParameters{Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE}}; | ||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) { | 225 | ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) { |
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index 85b0ed644..1ffdae805 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h | |||
| @@ -37,7 +37,7 @@ public: | |||
| 37 | return IdentifyType(file); | 37 | return IdentifyType(file); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | ResultStatus Load(Kernel::Process& process) override; | 40 | LoadResult Load(Kernel::Process& process) override; |
| 41 | 41 | ||
| 42 | ResultStatus ReadIcon(std::vector<u8>& buffer) override; | 42 | ResultStatus ReadIcon(std::vector<u8>& buffer) override; |
| 43 | ResultStatus ReadProgramId(u64& out_program_id) override; | 43 | ResultStatus ReadProgramId(u64& out_program_id) override; |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index d7c47c197..a86653204 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -169,22 +169,21 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, | |||
| 169 | return load_base + image_size; | 169 | return load_base + image_size; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | ResultStatus AppLoader_NSO::Load(Kernel::Process& process) { | 172 | AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process) { |
| 173 | if (is_loaded) { | 173 | if (is_loaded) { |
| 174 | return ResultStatus::ErrorAlreadyLoaded; | 174 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | // Load module | 177 | // Load module |
| 178 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); | 178 | const VAddr base_address = process.VMManager().GetCodeRegionBaseAddress(); |
| 179 | if (!LoadModule(process, *file, base_address, true)) { | 179 | if (!LoadModule(process, *file, base_address, true)) { |
| 180 | return ResultStatus::ErrorLoadingNSO; | 180 | return {ResultStatus::ErrorLoadingNSO, {}}; |
| 181 | } | 181 | } |
| 182 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); | 182 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), base_address); |
| 183 | 183 | ||
| 184 | process.Run(base_address, Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); | ||
| 185 | |||
| 186 | is_loaded = true; | 184 | is_loaded = true; |
| 187 | return ResultStatus::Success; | 185 | return {ResultStatus::Success, |
| 186 | LoadParameters{Kernel::THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE}}; | ||
| 188 | } | 187 | } |
| 189 | 188 | ||
| 190 | } // namespace Loader | 189 | } // namespace Loader |
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 4674c3724..fdce9191c 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h | |||
| @@ -84,7 +84,7 @@ public: | |||
| 84 | VAddr load_base, bool should_pass_arguments, | 84 | VAddr load_base, bool should_pass_arguments, |
| 85 | std::optional<FileSys::PatchManager> pm = {}); | 85 | std::optional<FileSys::PatchManager> pm = {}); |
| 86 | 86 | ||
| 87 | ResultStatus Load(Kernel::Process& process) override; | 87 | LoadResult Load(Kernel::Process& process) override; |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | } // namespace Loader | 90 | } // namespace Loader |
diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 7da1f8960..ad56bbb38 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp | |||
| @@ -72,37 +72,45 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& file) { | |||
| 72 | return FileType::Error; | 72 | return FileType::Error; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | ResultStatus AppLoader_NSP::Load(Kernel::Process& process) { | 75 | AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process) { |
| 76 | if (is_loaded) { | 76 | if (is_loaded) { |
| 77 | return ResultStatus::ErrorAlreadyLoaded; | 77 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | if (title_id == 0) | 80 | if (title_id == 0) { |
| 81 | return ResultStatus::ErrorNSPMissingProgramNCA; | 81 | return {ResultStatus::ErrorNSPMissingProgramNCA, {}}; |
| 82 | } | ||
| 82 | 83 | ||
| 83 | if (nsp->GetStatus() != ResultStatus::Success) | 84 | const auto nsp_status = nsp->GetStatus(); |
| 84 | return nsp->GetStatus(); | 85 | if (nsp_status != ResultStatus::Success) { |
| 86 | return {nsp_status, {}}; | ||
| 87 | } | ||
| 85 | 88 | ||
| 86 | if (nsp->GetProgramStatus(title_id) != ResultStatus::Success) | 89 | const auto nsp_program_status = nsp->GetProgramStatus(title_id); |
| 87 | return nsp->GetProgramStatus(title_id); | 90 | if (nsp_program_status != ResultStatus::Success) { |
| 91 | return {nsp_program_status, {}}; | ||
| 92 | } | ||
| 88 | 93 | ||
| 89 | if (nsp->GetNCA(title_id, FileSys::ContentRecordType::Program) == nullptr) { | 94 | if (nsp->GetNCA(title_id, FileSys::ContentRecordType::Program) == nullptr) { |
| 90 | if (!Core::Crypto::KeyManager::KeyFileExists(false)) | 95 | if (!Core::Crypto::KeyManager::KeyFileExists(false)) { |
| 91 | return ResultStatus::ErrorMissingProductionKeyFile; | 96 | return {ResultStatus::ErrorMissingProductionKeyFile, {}}; |
| 92 | return ResultStatus::ErrorNSPMissingProgramNCA; | 97 | } |
| 98 | |||
| 99 | return {ResultStatus::ErrorNSPMissingProgramNCA, {}}; | ||
| 93 | } | 100 | } |
| 94 | 101 | ||
| 95 | const auto result = secondary_loader->Load(process); | 102 | const auto result = secondary_loader->Load(process); |
| 96 | if (result != ResultStatus::Success) | 103 | if (result.first != ResultStatus::Success) { |
| 97 | return result; | 104 | return result; |
| 105 | } | ||
| 98 | 106 | ||
| 99 | FileSys::VirtualFile update_raw; | 107 | FileSys::VirtualFile update_raw; |
| 100 | if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) | 108 | if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) { |
| 101 | Service::FileSystem::SetPackedUpdate(std::move(update_raw)); | 109 | Service::FileSystem::SetPackedUpdate(std::move(update_raw)); |
| 110 | } | ||
| 102 | 111 | ||
| 103 | is_loaded = true; | 112 | is_loaded = true; |
| 104 | 113 | return result; | |
| 105 | return ResultStatus::Success; | ||
| 106 | } | 114 | } |
| 107 | 115 | ||
| 108 | ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& file) { | 116 | ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& file) { |
diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 953a1b508..85e870bdf 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h | |||
| @@ -35,7 +35,7 @@ public: | |||
| 35 | return IdentifyType(file); | 35 | return IdentifyType(file); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | ResultStatus Load(Kernel::Process& process) override; | 38 | LoadResult Load(Kernel::Process& process) override; |
| 39 | 39 | ||
| 40 | ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; | 40 | ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; |
| 41 | u64 ReadRomFSIVFCOffset() const override; | 41 | u64 ReadRomFSIVFCOffset() const override; |
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 89f7bbf77..1e285a053 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp | |||
| @@ -48,31 +48,35 @@ FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) { | |||
| 48 | return FileType::Error; | 48 | return FileType::Error; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | ResultStatus AppLoader_XCI::Load(Kernel::Process& process) { | 51 | AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::Process& process) { |
| 52 | if (is_loaded) { | 52 | if (is_loaded) { |
| 53 | return ResultStatus::ErrorAlreadyLoaded; | 53 | return {ResultStatus::ErrorAlreadyLoaded, {}}; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | if (xci->GetStatus() != ResultStatus::Success) | 56 | if (xci->GetStatus() != ResultStatus::Success) { |
| 57 | return xci->GetStatus(); | 57 | return {xci->GetStatus(), {}}; |
| 58 | } | ||
| 58 | 59 | ||
| 59 | if (xci->GetProgramNCAStatus() != ResultStatus::Success) | 60 | if (xci->GetProgramNCAStatus() != ResultStatus::Success) { |
| 60 | return xci->GetProgramNCAStatus(); | 61 | return {xci->GetProgramNCAStatus(), {}}; |
| 62 | } | ||
| 61 | 63 | ||
| 62 | if (!xci->HasProgramNCA() && !Core::Crypto::KeyManager::KeyFileExists(false)) | 64 | if (!xci->HasProgramNCA() && !Core::Crypto::KeyManager::KeyFileExists(false)) { |
| 63 | return ResultStatus::ErrorMissingProductionKeyFile; | 65 | return {ResultStatus::ErrorMissingProductionKeyFile, {}}; |
| 66 | } | ||
| 64 | 67 | ||
| 65 | const auto result = nca_loader->Load(process); | 68 | const auto result = nca_loader->Load(process); |
| 66 | if (result != ResultStatus::Success) | 69 | if (result.first != ResultStatus::Success) { |
| 67 | return result; | 70 | return result; |
| 71 | } | ||
| 68 | 72 | ||
| 69 | FileSys::VirtualFile update_raw; | 73 | FileSys::VirtualFile update_raw; |
| 70 | if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) | 74 | if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) { |
| 71 | Service::FileSystem::SetPackedUpdate(std::move(update_raw)); | 75 | Service::FileSystem::SetPackedUpdate(std::move(update_raw)); |
| 76 | } | ||
| 72 | 77 | ||
| 73 | is_loaded = true; | 78 | is_loaded = true; |
| 74 | 79 | return result; | |
| 75 | return ResultStatus::Success; | ||
| 76 | } | 80 | } |
| 77 | 81 | ||
| 78 | ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& file) { | 82 | ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& file) { |
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 436f7387c..ae7145b14 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h | |||
| @@ -35,7 +35,7 @@ public: | |||
| 35 | return IdentifyType(file); | 35 | return IdentifyType(file); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | ResultStatus Load(Kernel::Process& process) override; | 38 | LoadResult Load(Kernel::Process& process) override; |
| 39 | 39 | ||
| 40 | ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; | 40 | ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; |
| 41 | u64 ReadRomFSIVFCOffset() const override; | 41 | u64 ReadRomFSIVFCOffset() const override; |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4e0538bc2..f18f6226b 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -26,16 +26,16 @@ namespace Memory { | |||
| 26 | 26 | ||
| 27 | static Common::PageTable* current_page_table = nullptr; | 27 | static Common::PageTable* current_page_table = nullptr; |
| 28 | 28 | ||
| 29 | void SetCurrentPageTable(Common::PageTable* page_table) { | 29 | void SetCurrentPageTable(Kernel::Process& process) { |
| 30 | current_page_table = page_table; | 30 | current_page_table = &process.VMManager().page_table; |
| 31 | |||
| 32 | const std::size_t address_space_width = process.VMManager().GetAddressSpaceWidth(); | ||
| 31 | 33 | ||
| 32 | auto& system = Core::System::GetInstance(); | 34 | auto& system = Core::System::GetInstance(); |
| 33 | if (system.IsPoweredOn()) { | 35 | system.ArmInterface(0).PageTableChanged(*current_page_table, address_space_width); |
| 34 | system.ArmInterface(0).PageTableChanged(); | 36 | system.ArmInterface(1).PageTableChanged(*current_page_table, address_space_width); |
| 35 | system.ArmInterface(1).PageTableChanged(); | 37 | system.ArmInterface(2).PageTableChanged(*current_page_table, address_space_width); |
| 36 | system.ArmInterface(2).PageTableChanged(); | 38 | system.ArmInterface(3).PageTableChanged(*current_page_table, address_space_width); |
| 37 | system.ArmInterface(3).PageTableChanged(); | ||
| 38 | } | ||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static void MapPages(Common::PageTable& page_table, VAddr base, u64 size, u8* memory, | 41 | static void MapPages(Common::PageTable& page_table, VAddr base, u64 size, u8* memory, |
diff --git a/src/core/memory.h b/src/core/memory.h index 6845f5fe1..b9fa18b1d 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -40,8 +40,9 @@ enum : VAddr { | |||
| 40 | KERNEL_REGION_END = KERNEL_REGION_VADDR + KERNEL_REGION_SIZE, | 40 | KERNEL_REGION_END = KERNEL_REGION_VADDR + KERNEL_REGION_SIZE, |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | /// Changes the currently active page table. | 43 | /// Changes the currently active page table to that of |
| 44 | void SetCurrentPageTable(Common::PageTable* page_table); | 44 | /// the given process instance. |
| 45 | void SetCurrentPageTable(Kernel::Process& process); | ||
| 45 | 46 | ||
| 46 | /// Determines if the given VAddr is valid for the specified process. | 47 | /// Determines if the given VAddr is valid for the specified process. |
| 47 | bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); | 48 | bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 6d32ebea3..c1365879b 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -90,6 +90,7 @@ void LogSettings() { | |||
| 90 | LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); | 90 | LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); |
| 91 | LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); | 91 | LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); |
| 92 | LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); | 92 | LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); |
| 93 | LogSetting("Renderer_UseCompatibilityProfile", Settings::values.use_compatibility_profile); | ||
| 93 | LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); | 94 | LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); |
| 94 | LogSetting("Renderer_UseAccurateGpuEmulation", Settings::values.use_accurate_gpu_emulation); | 95 | LogSetting("Renderer_UseAccurateGpuEmulation", Settings::values.use_accurate_gpu_emulation); |
| 95 | LogSetting("Renderer_UseAsynchronousGpuEmulation", | 96 | LogSetting("Renderer_UseAsynchronousGpuEmulation", |
diff --git a/src/core/settings.h b/src/core/settings.h index b84390745..5ff3634aa 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -390,6 +390,7 @@ struct Values { | |||
| 390 | float resolution_factor; | 390 | float resolution_factor; |
| 391 | bool use_frame_limit; | 391 | bool use_frame_limit; |
| 392 | u16 frame_limit; | 392 | u16 frame_limit; |
| 393 | bool use_compatibility_profile; | ||
| 393 | bool use_disk_shader_cache; | 394 | bool use_disk_shader_cache; |
| 394 | bool use_accurate_gpu_emulation; | 395 | bool use_accurate_gpu_emulation; |
| 395 | bool use_asynchronous_gpu_emulation; | 396 | bool use_asynchronous_gpu_emulation; |