From 0b22af1206cf68a150f653329f46085a95f33bc6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 19 Oct 2019 17:42:53 -0700 Subject: [PATCH] libstrat: namespace remaining non-namespaced code. more new-ipc updates --- stratosphere/boot/source/boot_check_clock.cpp | 2 +- stratosphere/boot/source/boot_display.cpp | 14 +- stratosphere/boot/source/boot_main.cpp | 25 +- stratosphere/boot/source/boot_pmc_wrapper.cpp | 22 +- stratosphere/boot/source/boot_power_utils.cpp | 14 +- stratosphere/boot/source/boot_power_utils.hpp | 2 +- stratosphere/boot/source/gpio/gpio_utils.cpp | 2 +- .../source/i2c/driver/impl/i2c_registers.hpp | 4 +- .../boot/source/pinmux/pinmux_utils.cpp | 2 +- stratosphere/boot2/source/boot2_main.cpp | 18 +- stratosphere/creport/source/creport_main.cpp | 16 +- .../dmnt/source/cheat/impl/dmnt_cheat_api.cpp | 2 +- stratosphere/dmnt/source/dmnt_main.cpp | 15 +- .../dmnt/source/dmnt_service_debug.cpp | 2 +- stratosphere/eclct.stub/source/eclct_stub.cpp | 14 +- stratosphere/fatal/source/fatal_main.cpp | 17 +- .../fatal/source/fatal_task_error_report.cpp | 2 +- .../fatal/source/fatal_task_screen.cpp | 4 +- stratosphere/libstratosphere/Makefile | 2 +- .../libstratosphere/include/stratosphere.hpp | 9 +- .../include/stratosphere/ams.hpp | 5 +- .../{on_crash.hpp => ams/ams_emummc_api.hpp} | 18 +- .../ams_environment.hpp} | 13 +- .../stratosphere/ams/ams_exosphere_api.hpp | 61 ++ .../include/stratosphere/ams/ams_types.hpp | 65 ++ .../stratosphere/dd.hpp} | 8 +- .../stratosphere/dd/dd_io_mappings.hpp | 36 + .../include/stratosphere/defines.hpp | 1 + .../stratosphere/os/os_common_types.hpp | 12 +- .../include/stratosphere/services/bpc_ams.h | 66 -- .../include/stratosphere/sm.hpp | 1 + .../include/stratosphere/sm/sm_api.hpp | 13 + .../stratosphere/sm/sm_scoped_holder.hpp | 86 +++ .../include/stratosphere/sm/sm_types.hpp | 63 -- .../include/stratosphere/spl/smc/spl_smc.hpp | 18 + .../include/stratosphere/spl/spl_types.hpp | 13 + .../include/stratosphere/utilities.hpp | 128 ---- .../include/stratosphere/version_check.hpp | 75 -- .../libstratosphere/source/ams/ams_bpc.c | 46 ++ .../libstratosphere/source/ams/ams_bpc.h | 34 + .../source/ams/ams_environment.cpp | 153 +++++ .../source/ams/ams_exosphere_api.cpp | 75 ++ .../source/ams/ams_hos_version_api.cpp | 14 +- stratosphere/libstratosphere/source/bpc_ams.c | 76 -- .../source/dd/dd_io_mappings.cpp | 55 ++ .../libstratosphere/source/dmnt/dmntcht.c | 166 +++++ .../services => source/dmnt}/dmntcht.h | 7 +- stratosphere/libstratosphere/source/dmntcht.c | 650 ------------------ .../source/emummc_utilities.cpp | 141 ---- .../libstratosphere/source/ldr/ldr_ams.c | 41 +- .../libstratosphere/source/on_crash.cpp | 142 ---- .../libstratosphere/source/pm/pm_ams.c | 169 +---- .../libstratosphere/source/service_guard.h | 64 ++ .../libstratosphere/source/sm/sm_ams.c | 351 ++-------- .../libstratosphere/source/sm/sm_ams.h | 5 +- .../libstratosphere/source/sm/sm_api.cpp | 11 + .../libstratosphere/source/sm/smm_ams.c | 119 +--- .../source/spl/smc/spl_smc.cpp | 55 ++ .../source/updater/updater_api.cpp | 10 +- stratosphere/loader/source/ldr_main.cpp | 18 +- .../loader/source/ldr_process_creation.cpp | 5 +- stratosphere/pm/Makefile | 2 +- .../pm/source/impl/pm_process_manager.cpp | 3 +- stratosphere/pm/source/pm_main.cpp | 37 +- .../ro/source/impl/ro_service_impl.cpp | 5 +- stratosphere/ro/source/ro_main.cpp | 15 +- stratosphere/sm/source/sm_main.cpp | 15 +- stratosphere/spl/source/spl_main.cpp | 21 +- 68 files changed, 1257 insertions(+), 2118 deletions(-) rename stratosphere/libstratosphere/include/stratosphere/{on_crash.hpp => ams/ams_emummc_api.hpp} (68%) rename stratosphere/libstratosphere/include/stratosphere/{emummc_utilities.hpp => ams/ams_environment.hpp} (72%) create mode 100644 stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp rename stratosphere/libstratosphere/{source/utilities.cpp => include/stratosphere/dd.hpp} (80%) create mode 100644 stratosphere/libstratosphere/include/stratosphere/dd/dd_io_mappings.hpp delete mode 100644 stratosphere/libstratosphere/include/stratosphere/services/bpc_ams.h create mode 100644 stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp delete mode 100644 stratosphere/libstratosphere/include/stratosphere/utilities.hpp delete mode 100644 stratosphere/libstratosphere/include/stratosphere/version_check.hpp create mode 100644 stratosphere/libstratosphere/source/ams/ams_bpc.c create mode 100644 stratosphere/libstratosphere/source/ams/ams_bpc.h create mode 100644 stratosphere/libstratosphere/source/ams/ams_environment.cpp create mode 100644 stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp delete mode 100644 stratosphere/libstratosphere/source/bpc_ams.c create mode 100644 stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp create mode 100644 stratosphere/libstratosphere/source/dmnt/dmntcht.c rename stratosphere/libstratosphere/{include/stratosphere/services => source/dmnt}/dmntcht.h (96%) delete mode 100644 stratosphere/libstratosphere/source/dmntcht.c delete mode 100644 stratosphere/libstratosphere/source/emummc_utilities.cpp delete mode 100644 stratosphere/libstratosphere/source/on_crash.cpp create mode 100644 stratosphere/libstratosphere/source/service_guard.h diff --git a/stratosphere/boot/source/boot_check_clock.cpp b/stratosphere/boot/source/boot_check_clock.cpp index 1aae210d2..4884e1548 100644 --- a/stratosphere/boot/source/boot_check_clock.cpp +++ b/stratosphere/boot/source/boot_check_clock.cpp @@ -36,7 +36,7 @@ namespace sts::boot { /* Helpers. */ bool IsUsbClockValid() { - uintptr_t car_regs = GetIoMapping(0x60006000ul, 0x1000); + uintptr_t car_regs = dd::GetIoMapping(0x60006000ul, 0x1000); const u32 pllu = reg::Read(car_regs + 0xC0); const u32 utmip = reg::Read(car_regs + 0x480); diff --git a/stratosphere/boot/source/boot_display.cpp b/stratosphere/boot/source/boot_display.cpp index b608a6c9b..02ff79aa9 100644 --- a/stratosphere/boot/source/boot_display.cpp +++ b/stratosphere/boot/source/boot_display.cpp @@ -79,12 +79,12 @@ namespace sts::boot { /* Helper functions. */ void InitializeRegisterBaseAddresses() { - g_disp1_regs = GetIoMapping(Disp1Base, Disp1Size); - g_dsi_regs = GetIoMapping(DsiBase, DsiSize); - g_clk_rst_regs = GetIoMapping(ClkRstBase, ClkRstSize); - g_gpio_regs = GetIoMapping(GpioBase, GpioSize); - g_apb_misc_regs = GetIoMapping(ApbMiscBase, ApbMiscSize); - g_mipi_cal_regs = GetIoMapping(MipiCalBase, MipiCalSize); + g_disp1_regs = dd::GetIoMapping(Disp1Base, Disp1Size); + g_dsi_regs = dd::GetIoMapping(DsiBase, DsiSize); + g_clk_rst_regs = dd::GetIoMapping(ClkRstBase, ClkRstSize); + g_gpio_regs = dd::GetIoMapping(GpioBase, GpioSize); + g_apb_misc_regs = dd::GetIoMapping(ApbMiscBase, ApbMiscSize); + g_mipi_cal_regs = dd::GetIoMapping(MipiCalBase, MipiCalSize); } inline void DoRegisterWrites(uintptr_t base_address, const RegisterWrite *reg_writes, size_t num_writes) { @@ -418,7 +418,7 @@ namespace sts::boot { /* Nintendo waits 5 frames before continuing. */ { - const uintptr_t host1x_vaddr = GetIoMapping(0x500030a4, 4); + const uintptr_t host1x_vaddr = dd::GetIoMapping(0x500030a4, 4); const u32 start_val = reg::Read(host1x_vaddr); while (reg::Read(host1x_vaddr) < start_val + 5) { /* spinlock here. */ diff --git a/stratosphere/boot/source/boot_main.cpp b/stratosphere/boot/source/boot_main.cpp index 23111d5df..696416b39 100644 --- a/stratosphere/boot/source/boot_main.cpp +++ b/stratosphere/boot/source/boot_main.cpp @@ -59,18 +59,23 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Boot; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Boot; + + void ExceptionHandler(FatalErrorContext *ctx) { + /* We're boot sysmodule, so manually reboot to fatal error. */ + boot::RebootForFatalError(ctx); + } + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); -} - -void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) { - /* We're boot sysmodule, so manually reboot to fatal error. */ - boot::RebootForFatalError(ctx); + ams::CrashHandler(ctx); } void __libnx_initheap(void) { @@ -89,13 +94,13 @@ void __appInit(void) { hos::SetVersionForLibnx(); /* Initialize services we need (TODO: NCM) */ - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(fsInitialize()); R_ASSERT(splInitialize()); R_ASSERT(pmshellInitialize()); }); - CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); + ams::CheckApiVersion(); } void __appExit(void) { diff --git a/stratosphere/boot/source/boot_pmc_wrapper.cpp b/stratosphere/boot/source/boot_pmc_wrapper.cpp index 2cdb2a467..59a269f89 100644 --- a/stratosphere/boot/source/boot_pmc_wrapper.cpp +++ b/stratosphere/boot/source/boot_pmc_wrapper.cpp @@ -13,7 +13,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - +#include +#include #include "boot_pmc_wrapper.hpp" namespace sts::boot { @@ -31,29 +32,22 @@ namespace sts::boot { return (phys_addr & 3) == 0 && PmcPhysStart <= phys_addr && phys_addr <= PmcPhysEnd; } - inline u32 SmcAtmosphereReadWriteRegister(u32 phys_addr, u32 value, u32 mask) { - SecmonArgs args; - - args.X[0] = SmcFunctionId_AtmosphereReadWriteRegister; - args.X[1] = phys_addr; - args.X[2] = mask; - args.X[3] = value; - R_ASSERT(svcCallSecureMonitor(&args)); - STS_ASSERT(args.X[0] == 0); - - return static_cast(args.X[1]); + inline u32 ReadWriteRegisterImpl(uintptr_t phys_addr, u32 value, u32 mask) { + u32 out_value; + R_ASSERT(spl::smc::ConvertResult(spl::smc::AtmosphereReadWriteRegister(phys_addr, mask, value, &out_value))); + return out_value; } } u32 ReadPmcRegister(u32 phys_addr) { STS_ASSERT(IsValidPmcAddress(phys_addr)); - return SmcAtmosphereReadWriteRegister(phys_addr, 0, 0); + return ReadWriteRegisterImpl(phys_addr, 0, 0); } void WritePmcRegister(u32 phys_addr, u32 value, u32 mask) { STS_ASSERT(IsValidPmcAddress(phys_addr)); - SmcAtmosphereReadWriteRegister(phys_addr, value, mask); + ReadWriteRegisterImpl(phys_addr, value, mask); } } diff --git a/stratosphere/boot/source/boot_power_utils.cpp b/stratosphere/boot/source/boot_power_utils.cpp index 0e34cf9a2..0253d2af6 100644 --- a/stratosphere/boot/source/boot_power_utils.cpp +++ b/stratosphere/boot/source/boot_power_utils.cpp @@ -37,22 +37,22 @@ namespace sts::boot { /* Helpers. */ void ClearIram() { /* Make page FFs. */ - memset(g_work_page, 0xFF, sizeof(g_work_page)); + std::memset(g_work_page, 0xFF, sizeof(g_work_page)); /* Overwrite all of IRAM with FFs. */ for (size_t ofs = 0; ofs < IramSize; ofs += sizeof(g_work_page)) { - CopyToIram(IramBase + ofs, g_work_page, sizeof(g_work_page)); + ams::CopyToIram(IramBase + ofs, g_work_page, sizeof(g_work_page)); } } - void DoRebootToPayload(AtmosphereFatalErrorContext *ctx) { + void DoRebootToPayload(ams::FatalErrorContext *ctx) { /* Ensure clean IRAM state. */ ClearIram(); /* Copy in payload. */ for (size_t ofs = 0; ofs < fusee_primary_bin_size; ofs += 0x1000) { std::memcpy(g_work_page, &fusee_primary_bin[ofs], std::min(static_cast(fusee_primary_bin_size - ofs), size_t(0x1000))); - CopyToIram(IramPayloadBase + ofs, g_work_page, 0x1000); + ams::CopyToIram(IramPayloadBase + ofs, g_work_page, 0x1000); } @@ -60,10 +60,10 @@ namespace sts::boot { if (ctx != nullptr) { std::memset(g_work_page, 0xCC, sizeof(g_work_page)); std::memcpy(g_work_page, ctx, sizeof(*ctx)); - CopyToIram(IramPayloadBase + IramPayloadMaxSize, g_work_page, sizeof(g_work_page)); + ams::CopyToIram(IramPayloadBase + IramPayloadMaxSize, g_work_page, sizeof(g_work_page)); } - RebootToIramPayload(); + ams::ForceRebootToIramPayload(); } } @@ -72,7 +72,7 @@ namespace sts::boot { DoRebootToPayload(nullptr); } - void RebootForFatalError(AtmosphereFatalErrorContext *ctx) { + void RebootForFatalError(ams::FatalErrorContext *ctx) { DoRebootToPayload(ctx); } diff --git a/stratosphere/boot/source/boot_power_utils.hpp b/stratosphere/boot/source/boot_power_utils.hpp index 3a5386b12..6efe66190 100644 --- a/stratosphere/boot/source/boot_power_utils.hpp +++ b/stratosphere/boot/source/boot_power_utils.hpp @@ -25,6 +25,6 @@ namespace sts::boot { void ShutdownSystem(); /* Atmosphere power utilities. */ - void RebootForFatalError(AtmosphereFatalErrorContext *ctx); + void RebootForFatalError(ams::FatalErrorContext *ctx); } diff --git a/stratosphere/boot/source/gpio/gpio_utils.cpp b/stratosphere/boot/source/gpio/gpio_utils.cpp index f0ff57750..32ad05adc 100644 --- a/stratosphere/boot/source/gpio/gpio_utils.cpp +++ b/stratosphere/boot/source/gpio/gpio_utils.cpp @@ -39,7 +39,7 @@ namespace sts::gpio { uintptr_t GetBaseAddress() { if (!g_initialized_gpio_vaddr) { - g_gpio_vaddr = GetIoMapping(PhysicalBase, 0x1000); + g_gpio_vaddr = dd::GetIoMapping(PhysicalBase, 0x1000); g_initialized_gpio_vaddr = true; } return g_gpio_vaddr; diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp index 0d8c41a13..7cbd25e25 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_registers.hpp @@ -88,7 +88,7 @@ namespace sts::i2c::driver::impl { 12, 22, 3, 7, 15, 6 }; - const uintptr_t registers = GetIoMapping(0x60006000ul, 0x1000); + const uintptr_t registers = dd::GetIoMapping(0x60006000ul, 0x1000); const size_t idx = ConvertToIndex(bus); this->clk_src_reg = registers + s_clk_src_offsets[idx]; this->clk_en_reg = registers + s_clk_en_offsets[idx]; @@ -102,7 +102,7 @@ namespace sts::i2c::driver::impl { 0x0000, 0x0400, 0x0500, 0x0700, 0x1000, 0x1100 }; - const uintptr_t registers = GetIoMapping(0x7000c000ul, 0x2000) + s_offsets[ConvertToIndex(bus)]; + const uintptr_t registers = dd::GetIoMapping(0x7000c000ul, 0x2000) + s_offsets[ConvertToIndex(bus)]; return reinterpret_cast(registers); } diff --git a/stratosphere/boot/source/pinmux/pinmux_utils.cpp b/stratosphere/boot/source/pinmux/pinmux_utils.cpp index 2b2e17380..9000b520e 100644 --- a/stratosphere/boot/source/pinmux/pinmux_utils.cpp +++ b/stratosphere/boot/source/pinmux/pinmux_utils.cpp @@ -44,7 +44,7 @@ namespace sts::pinmux { uintptr_t GetBaseAddress() { if (!g_initialized_pinmux_vaddr) { - g_pinmux_vaddr = GetIoMapping(ApbMiscPhysicalBase, 0x4000); + g_pinmux_vaddr = dd::GetIoMapping(ApbMiscPhysicalBase, 0x4000); g_initialized_pinmux_vaddr = true; } return g_pinmux_vaddr; diff --git a/stratosphere/boot2/source/boot2_main.cpp b/stratosphere/boot2/source/boot2_main.cpp index 694659012..35fda6872 100644 --- a/stratosphere/boot2/source/boot2_main.cpp +++ b/stratosphere/boot2/source/boot2_main.cpp @@ -38,16 +38,20 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Boot2; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Boot2; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } - void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; @@ -60,13 +64,11 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); /* Initialize services we need. */ - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(fsInitialize()); R_ASSERT(pmbmInitialize()); R_ASSERT(pminfoInitialize()); @@ -77,7 +79,7 @@ void __appInit(void) { R_ASSERT(fsdevMountSdmc()); - CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); + ams::CheckApiVersion(); } void __appExit(void) { diff --git a/stratosphere/creport/source/creport_main.cpp b/stratosphere/creport/source/creport_main.cpp index 037fe520a..8de1a3c0e 100644 --- a/stratosphere/creport/source/creport_main.cpp +++ b/stratosphere/creport/source/creport_main.cpp @@ -44,16 +44,20 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Creport; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Creport; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } - void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; @@ -66,12 +70,10 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(fsInitialize()); }); diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index 4db3129b7..56700d6f0 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -157,7 +157,7 @@ namespace sts::dmnt::cheat::impl { /* Note: This function *MUST* be called only with the cheat lock held. */ os::ProcessId pid; bool has_cheat_process = this->cheat_process_debug_handle != INVALID_HANDLE; - has_cheat_process &= R_SUCCEEDED(os::GetProcessId(&pid, this->cheat_process_debug_handle)); + has_cheat_process &= R_SUCCEEDED(os::TryGetProcessId(&pid, this->cheat_process_debug_handle)); has_cheat_process &= R_SUCCEEDED(pm::dmnt::GetApplicationProcessId(&pid)); has_cheat_process &= (pid == this->cheat_process_metadata.process_id); diff --git a/stratosphere/dmnt/source/dmnt_main.cpp b/stratosphere/dmnt/source/dmnt_main.cpp index 4e643592d..1eec25cf0 100644 --- a/stratosphere/dmnt/source/dmnt_main.cpp +++ b/stratosphere/dmnt/source/dmnt_main.cpp @@ -43,8 +43,13 @@ extern "C" { void __appExit(void); } -/* Exception handling. */ -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Dmnt; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Dmnt; + +} + +using namespace sts; void __libnx_initheap(void) { void* addr = nx_inner_heap; @@ -58,12 +63,10 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(pmdmntInitialize()); R_ASSERT(pminfoInitialize()); R_ASSERT(ldrDmntInitialize()); @@ -81,7 +84,7 @@ void __appInit(void) { R_ASSERT(fsdevMountSdmc()); - CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); + ams::CheckApiVersion(); } void __appExit(void) { diff --git a/stratosphere/dmnt/source/dmnt_service_debug.cpp b/stratosphere/dmnt/source/dmnt_service_debug.cpp index 656a1e72f..ad049af2c 100644 --- a/stratosphere/dmnt/source/dmnt_service_debug.cpp +++ b/stratosphere/dmnt/source/dmnt_service_debug.cpp @@ -36,7 +36,7 @@ namespace sts::dmnt { Result DebugMonitorService::GetProcessId(sf::Out out_pid, Handle hnd) { /* Nintendo discards the output of this command, but we will return it. */ - return svcGetProcessId(reinterpret_cast(out_pid.GetPointer()), hnd); + return os::TryGetProcessId(out_pid.GetPointer(), hnd); } Result DebugMonitorService::GetProcessHandle(sf::Out out_hnd, os::ProcessId pid) { diff --git a/stratosphere/eclct.stub/source/eclct_stub.cpp b/stratosphere/eclct.stub/source/eclct_stub.cpp index 62b73d454..53cc76625 100644 --- a/stratosphere/eclct.stub/source/eclct_stub.cpp +++ b/stratosphere/eclct.stub/source/eclct_stub.cpp @@ -28,7 +28,7 @@ extern "C" { u32 __nx_applet_type = AppletType_None; - #define INNER_HEAP_SIZE 0x8000 + #define INNER_HEAP_SIZE 0x2000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -40,16 +40,20 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Eclct; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Eclct; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } - void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; diff --git a/stratosphere/fatal/source/fatal_main.cpp b/stratosphere/fatal/source/fatal_main.cpp index aa3d393c6..1fbb77572 100644 --- a/stratosphere/fatal/source/fatal_main.cpp +++ b/stratosphere/fatal/source/fatal_main.cpp @@ -49,13 +49,18 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Fatal; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Fatal; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } void __libnx_initheap(void) { @@ -70,12 +75,10 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(setInitialize()); R_ASSERT(setsysInitialize()); R_ASSERT(pminfoInitialize()); @@ -98,7 +101,7 @@ void __appInit(void) { R_ASSERT(fsdevMountSdmc()); - /* fatal cannot throw fatal, so don't do: CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); */ + /* fatal cannot throw fatal, so don't do: ams::CheckApiVersion(); */ } void __appExit(void) { diff --git a/stratosphere/fatal/source/fatal_task_error_report.cpp b/stratosphere/fatal/source/fatal_task_error_report.cpp index 4c55d5f1e..3a0d9b27d 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.cpp +++ b/stratosphere/fatal/source/fatal_task_error_report.cpp @@ -91,7 +91,7 @@ namespace sts::fatal::srv { if (strlen(this->context->proc_name)) { fprintf(f_report, "Process Name: %s\n", this->context->proc_name); } - fprintf(f_report, u8"Firmware: %s (Atmosphère %u.%u.%u-%s)\n", GetFatalConfig().GetFirmwareVersion().display_version, CURRENT_ATMOSPHERE_VERSION, GetAtmosphereGitRevision()); + fprintf(f_report, u8"Firmware: %s (Atmosphère %u.%u.%u-%s)\n", GetFatalConfig().GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision()); if (this->context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32) { fprintf(f_report, "General Purpose Registers:\n"); diff --git a/stratosphere/fatal/source/fatal_task_screen.cpp b/stratosphere/fatal/source/fatal_task_screen.cpp index 9dc638057..ac72778f5 100644 --- a/stratosphere/fatal/source/fatal_task_screen.cpp +++ b/stratosphere/fatal/source/fatal_task_screen.cpp @@ -189,7 +189,7 @@ namespace sts::fatal::srv { const FatalConfig &config = GetFatalConfig(); /* Prepare screen for drawing. */ - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(PrepareScreenForDrawing()); }); @@ -222,7 +222,7 @@ namespace sts::fatal::srv { font::AddSpacingLines(0.5f); font::PrintFormatLine("Title: %016lX", static_cast(this->context->title_id)); font::AddSpacingLines(0.5f); - font::PrintFormatLine(u8"Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, CURRENT_ATMOSPHERE_VERSION, GetAtmosphereGitRevision()); + font::PrintFormatLine(u8"Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision()); font::AddSpacingLines(1.5f); if (this->context->error_code != ResultAtmosphereVersionMismatch) { font::Print(config.GetErrorDescription()); diff --git a/stratosphere/libstratosphere/Makefile b/stratosphere/libstratosphere/Makefile index 0fd81506a..581691221 100644 --- a/stratosphere/libstratosphere/Makefile +++ b/stratosphere/libstratosphere/Makefile @@ -16,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules # INCLUDES is a list of directories containing header files #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) -SOURCES := source source/ams source/os source/os/impl source/sf source/sf/cmif source/sf/hipc source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb source/boot2 +SOURCES := source source/ams source/os source/os/impl source/dd source/sf source/sf/cmif source/sf/hipc source/dmnt source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb source/boot2 DATA := data INCLUDES := include diff --git a/stratosphere/libstratosphere/include/stratosphere.hpp b/stratosphere/libstratosphere/include/stratosphere.hpp index b1a36f453..58e7ffe74 100644 --- a/stratosphere/libstratosphere/include/stratosphere.hpp +++ b/stratosphere/libstratosphere/include/stratosphere.hpp @@ -17,20 +17,13 @@ #pragma once #include "stratosphere/defines.hpp" - -#include "stratosphere/utilities.hpp" -#include "stratosphere/emummc_utilities.hpp" - -#include "stratosphere/version_check.hpp" - #include "stratosphere/results.hpp" -#include "stratosphere/on_crash.hpp" - #include "stratosphere/util.hpp" #include "stratosphere/svc.hpp" #include "stratosphere/ams.hpp" #include "stratosphere/os.hpp" +#include "stratosphere/dd.hpp" #include "stratosphere/cfg.hpp" #include "stratosphere/fatal.hpp" #include "stratosphere/hid.hpp" diff --git a/stratosphere/libstratosphere/include/stratosphere/ams.hpp b/stratosphere/libstratosphere/include/stratosphere/ams.hpp index 9af4ad13d..666633bdb 100644 --- a/stratosphere/libstratosphere/include/stratosphere/ams.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ams.hpp @@ -17,4 +17,7 @@ #pragma once #include "ams/ams_types.hpp" -#include "ams/ams_hos_version_api.hpp" \ No newline at end of file +#include "ams/ams_hos_version_api.hpp" +#include "ams/ams_exosphere_api.hpp" +#include "ams/ams_emummc_api.hpp" +#include "ams/ams_environment.hpp" diff --git a/stratosphere/libstratosphere/include/stratosphere/on_crash.hpp b/stratosphere/libstratosphere/include/stratosphere/ams/ams_emummc_api.hpp similarity index 68% rename from stratosphere/libstratosphere/include/stratosphere/on_crash.hpp rename to stratosphere/libstratosphere/include/stratosphere/ams/ams_emummc_api.hpp index 2f66f60ee..5a6661403 100644 --- a/stratosphere/libstratosphere/include/stratosphere/on_crash.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ams/ams_emummc_api.hpp @@ -15,13 +15,17 @@ */ #pragma once -#include -#include -#include "services/bpc_ams.h" +#include "ams_types.hpp" -static constexpr size_t AtmosphereFatalErrorNumGprs = 29; +namespace sts::ams::emummc { -static constexpr u32 AtmosphereFatalErrorMagic = 0x31454641; /* "AFE1" */ + /* Get whether emummc is active. */ + bool IsActive(); -/* Will be called by libstratosphere on crash. */ -void StratosphereCrashHandler(ThreadExceptionDump *ctx); \ No newline at end of file + /* Get Nintendo redirection path. */ + const char *GetNintendoDirPath(); + + /* Get Emummc folderpath, NULL if not file-based. */ + const char *GetFilePath(); + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/emummc_utilities.hpp b/stratosphere/libstratosphere/include/stratosphere/ams/ams_environment.hpp similarity index 72% rename from stratosphere/libstratosphere/include/stratosphere/emummc_utilities.hpp rename to stratosphere/libstratosphere/include/stratosphere/ams/ams_environment.hpp index d2b52e043..55265ee3d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/emummc_utilities.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ams/ams_environment.hpp @@ -15,14 +15,11 @@ */ #pragma once -#include -#include +#include "ams_types.hpp" -/* Get whether emummc is active. */ -bool IsEmummc(); +namespace sts::ams { -/* Get Nintendo redirection path. */ -const char *GetEmummcNintendoDirPath(); + /* Will be called by libstratosphere on crash. */ + void CrashHandler(ThreadExceptionDump *ctx); -/* Get Emummc folderpath, NULL if not file-based. */ -const char *GetEmummcFilePath(); +} diff --git a/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp b/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp new file mode 100644 index 000000000..7dbcbedf4 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "ams_types.hpp" + +namespace sts::ams { + + ApiInfo GetApiInfo(); + + void ForceRebootToRcm(); + void ForceRebootToIramPayload(); + void ForceShutdown(); + + bool IsRcmBugPatched(); + + void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size); + void CopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size); + + /* Version checking utility. */ +#ifdef ATMOSPHERE_RELEASE_VERSION_MAJOR + +#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO + + inline void CheckApiVersion() { + const u32 runtime_version = GetApiInfo().GetVersion(); + const u32 build_version = GetVersion(ATMOSPHERE_RELEASE_VERSION); + + if (runtime_version < build_version) { + R_ASSERT(ResultAtmosphereVersionMismatch); + } + } + +#endif + +#ifdef ATMOSPHERE_GIT_BRANCH + NX_CONSTEXPR const char *GetGitBranch() { + return ATMOSPHERE_GIT_BRANCH; + } +#endif + +#ifdef ATMOSPHERE_GIT_REV + NX_CONSTEXPR const char *GetGitRevision() { + return ATMOSPHERE_GIT_REV; + } +#endif + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/ams/ams_types.hpp b/stratosphere/libstratosphere/include/stratosphere/ams/ams_types.hpp index 9c0e2436b..15e29808b 100644 --- a/stratosphere/libstratosphere/include/stratosphere/ams/ams_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/ams/ams_types.hpp @@ -17,6 +17,8 @@ #pragma once #include #include "../defines.hpp" +#include "../results.hpp" +#include "../sf/sf_buffer_tags.hpp" /* Define firmware version in global namespace, for convenience. */ namespace sts { @@ -59,4 +61,67 @@ namespace sts::ams { TargetFirmware_900 = 11, }; + constexpr inline u32 GetVersion(u32 major, u32 minor, u32 micro) { + return (major << 16) | (minor << 8) | (micro); + } + + struct ApiInfo { + u32 major_version; + u32 minor_version; + u32 micro_version; + TargetFirmware target_firmware; + u32 master_key_revision; + + constexpr u32 GetVersion() const { + return ::sts::ams::GetVersion(this->major_version, this->minor_version, this->micro_version); + } + + constexpr TargetFirmware GetTargetFirmware() const { + return this->target_firmware; + } + + constexpr u32 GetMasterKeyRevision() const { + return this->master_key_revision; + } + }; + + struct FatalErrorContext : sf::LargeData, sf::PrefersMapAliasTransferMode { + static constexpr size_t MaxStackTrace = 0x20; + static constexpr size_t MaxStackDumpSize = 0x100; + static constexpr size_t NumGprs = 29; + static constexpr uintptr_t StdAbortMagicAddress = 0x8; + static constexpr u64 StdAbortMagicValue = 0xA55AF00DDEADCAFEul; + static constexpr u32 StdAbortErrorDesc = 0xFFE; + static constexpr u32 DataAbortErrorDesc = 0x101; + static constexpr u32 Magic = 0x31454641; + + u32 magic; + u32 error_desc; + u64 title_id; + union { + u64 gprs[32]; + struct { + u64 _gprs[29]; + u64 fp; + u64 lr; + u64 sp; + }; + }; + u64 pc; + u64 module_base; + u32 pstate; + u32 afsr0; + u32 afsr1; + u32 esr; + u64 far; + u64 report_identifier; /* Normally just system tick. */ + u64 stack_trace_size; + u64 stack_dump_size; + u64 stack_trace[MaxStackTrace]; + u8 stack_dump[MaxStackDumpSize]; + }; + + static_assert(sizeof(FatalErrorContext) == 0x350, "sizeof(FatalErrorContext)"); + static_assert(std::is_pod::value, "FatalErrorContext"); + } diff --git a/stratosphere/libstratosphere/source/utilities.cpp b/stratosphere/libstratosphere/include/stratosphere/dd.hpp similarity index 80% rename from stratosphere/libstratosphere/source/utilities.cpp rename to stratosphere/libstratosphere/include/stratosphere/dd.hpp index af8d221d8..a4ba4aac0 100644 --- a/stratosphere/libstratosphere/source/utilities.cpp +++ b/stratosphere/libstratosphere/include/stratosphere/dd.hpp @@ -14,11 +14,7 @@ * along with this program. If not, see . */ +#pragma once #include -#include -static sts::os::RecursiveMutex g_sm_session_lock; - -sts::os::RecursiveMutex &GetSmSessionMutex() { - return g_sm_session_lock; -} +#include "dd/dd_io_mappings.hpp" diff --git a/stratosphere/libstratosphere/include/stratosphere/dd/dd_io_mappings.hpp b/stratosphere/libstratosphere/include/stratosphere/dd/dd_io_mappings.hpp new file mode 100644 index 000000000..a0ba2fd9a --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/dd/dd_io_mappings.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include "../defines.hpp" + +namespace sts::dd { + + uintptr_t QueryIoMapping(uintptr_t phys_addr, size_t size); + + u32 ReadRegister(uintptr_t phys_addr); + void WriteRegister(uintptr_t phys_addr, u32 value); + u32 ReadWriteRegister(uintptr_t phys_addr, u32 value, u32 mask); + + /* Convenience Helper. */ + + inline uintptr_t GetIoMapping(uintptr_t phys_addr, size_t size) { + const uintptr_t io_mapping = QueryIoMapping(phys_addr, size); + STS_ASSERT(io_mapping); + return io_mapping; + } +} diff --git a/stratosphere/libstratosphere/include/stratosphere/defines.hpp b/stratosphere/libstratosphere/include/stratosphere/defines.hpp index 3cd70b67a..2f381820b 100644 --- a/stratosphere/libstratosphere/include/stratosphere/defines.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/defines.hpp @@ -15,6 +15,7 @@ */ #pragma once +#include #include /* Any broadly useful language defines should go here. */ diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp index 8740faed1..9ed484058 100644 --- a/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_common_types.hpp @@ -46,14 +46,18 @@ namespace sts::os { inline constexpr const ProcessId InvalidProcessId = ProcessId::Invalid; - NX_INLINE Result GetProcessId(os::ProcessId *out, ::Handle process_handle) { + NX_INLINE Result TryGetProcessId(os::ProcessId *out, ::Handle process_handle) { return svcGetProcessId(&out->value, process_handle); } + NX_INLINE os::ProcessId GetProcessId(::Handle process_handle) { + os::ProcessId process_id; + R_ASSERT(TryGetProcessId(&process_id, process_handle)); + return process_id; + } + NX_INLINE ProcessId GetCurrentProcessId() { - os::ProcessId current_process_id; - R_ASSERT(GetProcessId(¤t_process_id, CUR_PROCESS_HANDLE)); - return current_process_id; + return GetProcessId(CUR_PROCESS_HANDLE); } inline constexpr bool operator==(const ProcessId &lhs, const ProcessId &rhs) { diff --git a/stratosphere/libstratosphere/include/stratosphere/services/bpc_ams.h b/stratosphere/libstratosphere/include/stratosphere/services/bpc_ams.h deleted file mode 100644 index c8e11a73f..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/services/bpc_ams.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define AMS_FATAL_ERROR_MAX_STACKTRACE 0x20 -#define AMS_FATAL_ERROR_MAX_STACKDUMP 0x100 - -#define STD_ABORT_ADDR_MAGIC (0x8) -#define STD_ABORT_VALUE_MAGIC (0xA55AF00DDEADCAFEul) -#define DATA_ABORT_ERROR_DESC (0x101) -#define STD_ABORT_ERROR_DESC (0xFFE) - -typedef struct { - u32 magic; - u32 error_desc; - u64 title_id; - union { - u64 gprs[32]; - struct { - u64 _gprs[29]; - u64 fp; - u64 lr; - u64 sp; - }; - }; - u64 pc; - u64 module_base; - u32 pstate; - u32 afsr0; - u32 afsr1; - u32 esr; - u64 far; - u64 report_identifier; /* Normally just system tick. */ - u64 stack_trace_size; - u64 stack_dump_size; - u64 stack_trace[AMS_FATAL_ERROR_MAX_STACKTRACE]; - u8 stack_dump[AMS_FATAL_ERROR_MAX_STACKDUMP]; -} AtmosphereFatalErrorContext; - -Result bpcAmsInitialize(void); -void bpcAmsExit(void); - -Result bpcAmsRebootToFatalError(AtmosphereFatalErrorContext *ctx); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/stratosphere/libstratosphere/include/stratosphere/sm.hpp b/stratosphere/libstratosphere/include/stratosphere/sm.hpp index a334419a1..5c6ac9f36 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sm.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sm.hpp @@ -20,3 +20,4 @@ #include "sm/sm_types.hpp" #include "sm/sm_api.hpp" #include "sm/sm_mitm_api.hpp" +#include "sm/sm_scoped_holder.hpp" diff --git a/stratosphere/libstratosphere/include/stratosphere/sm/sm_api.hpp b/stratosphere/libstratosphere/include/stratosphere/sm/sm_api.hpp index 80e12cb79..2fb4f9381 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sm/sm_api.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sm/sm_api.hpp @@ -29,4 +29,17 @@ namespace sts::sm { Result HasService(bool *out, ServiceName name); Result WaitService(ServiceName name); + /* Scoped session access. */ + namespace impl { + + void DoWithSessionImpl(void (*Invoker)(void *), void *Function); + + } + + template + NX_CONSTEXPR void DoWithSession(F f) { + auto invoker = +[](void *func) { (*(F *)func)(); }; + impl::DoWithSessionImpl(invoker, &f); + } + } diff --git a/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp b/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp new file mode 100644 index 000000000..a7ffb724e --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "sm_api.hpp" + +namespace sts::sm { + + /* Utility, for scoped access to libnx services. */ + template + class ScopedServiceHolder { + NON_COPYABLE(ScopedServiceHolder); + private: + Result result; + bool has_initialized; + public: + ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) { + if (initialize) { + this->Initialize(); + } + } + + ~ScopedServiceHolder() { + if (this->has_initialized) { + this->Finalize(); + } + } + + ScopedServiceHolder(ScopedServiceHolder&& rhs) { + this->result = rhs.result; + this->has_initialized = rhs.has_initialized; + rhs.result = ResultSuccess; + rhs.has_initialized = false; + } + + ScopedServiceHolder& operator=(ScopedServiceHolder&& rhs) { + rhs.Swap(*this); + return *this; + } + + void Swap(ScopedServiceHolder& rhs) { + std::swap(this->result, rhs.result); + std::swap(this->has_initialized, rhs.has_initialized); + } + + explicit operator bool() const { + return this->has_initialized; + } + + Result Initialize() { + STS_ASSERT(!this->has_initialized); + + sm::DoWithSession([&]() { + this->result = Initializer(); + }); + + this->has_initialized = R_SUCCEEDED(this->result); + return this->result; + } + + void Finalize() { + STS_ASSERT(this->has_initialized); + Finalizer(); + this->has_initialized = false; + } + + Result GetResult() const { + return this->result; + } + }; + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/sm/sm_types.hpp b/stratosphere/libstratosphere/include/stratosphere/sm/sm_types.hpp index 812cc2f71..30d97b3b3 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sm/sm_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sm/sm_types.hpp @@ -70,67 +70,4 @@ namespace sts::sm { }; static_assert(sizeof(ServiceRecord) == 0x30, "ServiceRecord definition!"); - /* Utility, for scoped access to libnx services. */ - template - class ScopedServiceHolder { - NON_COPYABLE(ScopedServiceHolder); - private: - Result result; - bool has_initialized; - public: - ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) { - if (initialize) { - this->Initialize(); - } - } - - ~ScopedServiceHolder() { - if (this->has_initialized) { - this->Finalize(); - } - } - - ScopedServiceHolder(ScopedServiceHolder&& rhs) { - this->result = rhs.result; - this->has_initialized = rhs.has_initialized; - rhs.result = ResultSuccess; - rhs.has_initialized = false; - } - - ScopedServiceHolder& operator=(ScopedServiceHolder&& rhs) { - rhs.Swap(*this); - return *this; - } - - void Swap(ScopedServiceHolder& rhs) { - std::swap(this->result, rhs.result); - std::swap(this->has_initialized, rhs.has_initialized); - } - - explicit operator bool() const { - return this->has_initialized; - } - - Result Initialize() { - STS_ASSERT(!this->has_initialized); - - DoWithSmSession([&]() { - this->result = Initializer(); - }); - - this->has_initialized = R_SUCCEEDED(this->result); - return this->result; - } - - void Finalize() { - STS_ASSERT(this->has_initialized); - Finalizer(); - this->has_initialized = false; - } - - Result GetResult() const { - return this->result; - } - }; - } diff --git a/stratosphere/libstratosphere/include/stratosphere/spl/smc/spl_smc.hpp b/stratosphere/libstratosphere/include/stratosphere/spl/smc/spl_smc.hpp index 46a011a38..fe39687bd 100644 --- a/stratosphere/libstratosphere/include/stratosphere/spl/smc/spl_smc.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/spl/smc/spl_smc.hpp @@ -16,6 +16,7 @@ #pragma once #include +#include #include "../spl_types.hpp" @@ -54,4 +55,21 @@ namespace sts::spl::smc { Result DecryptRsaPrivateKey(size_t *out_size, void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option); Result ImportSecureExpModKey(const void *data, size_t size, const AccessKey &access_key, const KeySource &source, u32 option); + /* Atmosphere functions. */ + Result AtmosphereCopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size); + Result AtmosphereCopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size); + Result AtmosphereReadWriteRegister(uint64_t address, uint32_t mask, uint32_t value, uint32_t *out_value); + Result AtmosphereWriteAddress(void *dst, const void *src, size_t size); + + /* Helpers. */ + inline Result SetConfig(SplConfigItem which, const u64 value) { + return SetConfig(which, &value, 1); + } + + template + inline Result AtmosphereWriteAddress(void *dst, const T value) { + static_assert(std::is_integral::value && sizeof(T) <= 8 && (sizeof(T) & (sizeof(T) - 1)) == 0, "AtmosphereWriteAddress requires integral type."); + return AtmosphereWriteAddress(dst, &value, sizeof(T)); + } + } diff --git a/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp b/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp index 56ce8fdd4..664811e2c 100644 --- a/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/spl/spl_types.hpp @@ -46,6 +46,12 @@ namespace sts::spl { ImportEsKey = 0xC300100C, DecryptRsaPrivateKey = 0xC300100D, ImportSecureExpModKey = 0xC300100E, + + /* Atmosphere functions. */ + AtmosphereIramCopy = 0xF0000201, + AtmosphereReadWriteRegister = 0xF0000002, + AtmosphereWriteAddress = 0xF0000003, + AtmosphereGetEmummcConfig = 0xF0000404, }; enum class Result { @@ -177,3 +183,10 @@ namespace sts::spl { #pragma pack(pop) } + +/* Extensions to libnx spl config item enum. */ +constexpr inline SplConfigItem SplConfigItem_ExosphereApiVersion = static_cast(65000); +constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsReboot = static_cast(65001); +constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsShutdown = static_cast(65002); +constexpr inline SplConfigItem SplConfigItem_ExosphereGitCommitHash = static_cast(65003); +constexpr inline SplConfigItem SplConfigItem_ExosphereHasRcmBugPatch = static_cast(65004); diff --git a/stratosphere/libstratosphere/include/stratosphere/utilities.hpp b/stratosphere/libstratosphere/include/stratosphere/utilities.hpp deleted file mode 100644 index 4de68dc18..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/utilities.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include "defines.hpp" -#include "results.hpp" -#include "os.hpp" - -static inline uintptr_t GetIoMapping(const u64 io_addr, const u64 io_size) { - u64 vaddr; - const u64 aligned_addr = (io_addr & ~0xFFFul); - const u64 aligned_size = io_size + (io_addr - aligned_addr); - R_ASSERT(svcQueryIoMapping(&vaddr, aligned_addr, aligned_size)); - return static_cast(vaddr + (io_addr - aligned_addr)); -} - -static inline void RebootToRcm() { - SecmonArgs args = {0}; - args.X[0] = 0xC3000401; /* smcSetConfig */ - args.X[1] = 65001; /* Exosphere reboot */ - args.X[3] = 1; /* Perform reboot to RCM. */ - svcCallSecureMonitor(&args); -} - -static inline void RebootToIramPayload() { - SecmonArgs args = {0}; - args.X[0] = 0xC3000401; /* smcSetConfig */ - args.X[1] = 65001; /* Exosphere reboot */ - args.X[3] = 2; /* Perform reboot to payload at 0x40010000 in IRAM. */ - svcCallSecureMonitor(&args); -} - -static inline void PerformShutdownSmc() { - SecmonArgs args = {0}; - args.X[0] = 0xC3000401; /* smcSetConfig */ - args.X[1] = 65002; /* Exosphere shutdown */ - args.X[3] = 1; /* Perform shutdown. */ - svcCallSecureMonitor(&args); -} - -static inline void CopyToIram(uintptr_t iram_addr, void *src_addr, size_t size) { - SecmonArgs args = {0}; - args.X[0] = 0xF0000201; /* smcAmsIramCopy */ - args.X[1] = (u64)src_addr; /* DRAM address */ - args.X[2] = (u64)iram_addr; /* IRAM address */ - args.X[3] = size; /* Amount to copy */ - args.X[4] = 1; /* 1 = Write */ - svcCallSecureMonitor(&args); -} - -static inline void CopyFromIram(void *dst_addr, uintptr_t iram_addr, size_t size) { - SecmonArgs args = {0}; - args.X[0] = 0xF0000201; /* smcAmsIramCopy */ - args.X[1] = (u64)dst_addr; /* DRAM address */ - args.X[2] = (u64)iram_addr; /* IRAM address */ - args.X[3] = size; /* Amount to copy */ - args.X[4] = 0; /* 0 = Read */ - svcCallSecureMonitor(&args); -} - -static inline Result SmcGetConfig(SplConfigItem config_item, u64 *out_config) { - SecmonArgs args = {0}; - args.X[0] = 0xC3000002; /* smcGetConfig */ - args.X[1] = (u64)config_item; /* config item */ - - R_TRY(svcCallSecureMonitor(&args)); - if (args.X[0] != 0) { - /* SPL result n = SMC result n */ - return MAKERESULT(26, args.X[0]); - } - - if (out_config) { - *out_config = args.X[1]; - } - return ResultSuccess; -} - -static inline Result GetRcmBugPatched(bool *out) { - u64 tmp = 0; - R_TRY(SmcGetConfig((SplConfigItem)65004, &tmp)); - *out = (tmp != 0); - return ResultSuccess; -} - -static inline bool IsRcmBugPatched() { - bool rcm_bug_patched; - R_ASSERT(GetRcmBugPatched(&rcm_bug_patched)); - return rcm_bug_patched; -} - -static inline Result GetShouldBlankProdInfo(bool *out) { - u64 tmp = 0; - R_TRY(SmcGetConfig((SplConfigItem)65005, &tmp)); - *out = (tmp != 0); - return ResultSuccess; -} - -static inline bool ShouldBlankProdInfo() { - bool should_blank_prodinfo; - R_ASSERT(GetShouldBlankProdInfo(&should_blank_prodinfo)); - return should_blank_prodinfo; -} - -sts::os::RecursiveMutex &GetSmSessionMutex(); - -template -static void DoWithSmSession(F f) { - std::scoped_lock lk(GetSmSessionMutex()); - { - R_ASSERT(smInitialize()); - f(); - smExit(); - } -} diff --git a/stratosphere/libstratosphere/include/stratosphere/version_check.hpp b/stratosphere/libstratosphere/include/stratosphere/version_check.hpp deleted file mode 100644 index f9f3dea11..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/version_check.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include - -#include "results.hpp" - -static inline void GetAtmosphereApiVersion(u32 *major, u32 *minor, u32 *micro, u32 *target_fw, u32 *mkey_rev) { - /* Check for exosphere API compatibility. */ - u64 exosphere_cfg; - if (R_FAILED(SmcGetConfig((SplConfigItem)65000, &exosphere_cfg))) { - fatalSimple(ResultAtmosphereExosphereNotPresent); - } - - if (mkey_rev) { - *mkey_rev = (u32)((exosphere_cfg >> 0x00) & 0xFF); - } - - if (target_fw) { - *target_fw = (u32)((exosphere_cfg >> 0x08) & 0xFF); - } - - if (micro) { - *micro = (u32)((exosphere_cfg >> 0x10) & 0xFF); - } - - if (minor) { - *minor = (u32)((exosphere_cfg >> 0x18) & 0xFF); - } - - if (major) { - *major = (u32)((exosphere_cfg >> 0x20) & 0xFF); - } -} - -static inline u32 MakeAtmosphereVersion(u32 major, u32 minor, u32 micro) { - return (major << 16) | (minor << 8) | micro; -} - -static inline void CheckAtmosphereVersion(u32 expected_major, u32 expected_minor, u32 expected_micro) { - u32 major, minor, micro; - GetAtmosphereApiVersion(&major, &minor, µ, nullptr, nullptr); - - if (MakeAtmosphereVersion(major, minor, micro) < MakeAtmosphereVersion(expected_major, expected_minor, expected_micro)) { - fatalSimple(ResultAtmosphereVersionMismatch); - } -} - -#define CURRENT_ATMOSPHERE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO - -#ifdef ATMOSPHERE_GIT_BRANCH -static inline const char *GetAtmosphereGitBranch() { - return ATMOSPHERE_GIT_BRANCH; -} -#endif - -#ifdef ATMOSPHERE_GIT_REV -static inline const char *GetAtmosphereGitRevision() { - return ATMOSPHERE_GIT_REV; -} -#endif diff --git a/stratosphere/libstratosphere/source/ams/ams_bpc.c b/stratosphere/libstratosphere/source/ams/ams_bpc.c new file mode 100644 index 000000000..84c1d4763 --- /dev/null +++ b/stratosphere/libstratosphere/source/ams/ams_bpc.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "../service_guard.h" +#include "ams_bpc.h" + +static Service g_amsBpcSrv; + +NX_GENERATE_SERVICE_GUARD(amsBpc); + +Result _amsBpcInitialize(void) { + Handle h; + Result rc = svcConnectToNamedPort(&h, "bpc:ams"); /* TODO: ams:bpc */ + if (R_SUCCEEDED(rc)) serviceCreate(&g_amsBpcSrv, h); + return rc; +} + +void _amsBpcCleanup(void) { + serviceClose(&g_amsBpcSrv); +} + +Service *amsBpcGetServiceSession(void) { + return &g_amsBpcSrv; +} + +Result amsBpcRebootToFatalError(void *ctx) { + /* Note: this takes in an sts::ams::FatalErrorContext. */ + /* static_assert(sizeof() == 0x350) is done at type definition. */ + return serviceDispatch(&g_amsBpcSrv, 65000, + .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize }, + .buffers = { { ctx, 0x350 } }, + ); +} diff --git a/stratosphere/libstratosphere/source/ams/ams_bpc.h b/stratosphere/libstratosphere/source/ams/ams_bpc.h new file mode 100644 index 000000000..91dfd1e41 --- /dev/null +++ b/stratosphere/libstratosphere/source/ams/ams_bpc.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +Result amsBpcInitialize(void); +void amsBpcExit(void); +Service *amsBpcGetServiceSession(void); + +Result amsBpcRebootToFatalError(void *ctx); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/ams/ams_environment.cpp b/stratosphere/libstratosphere/source/ams/ams_environment.cpp new file mode 100644 index 000000000..77d3d8e64 --- /dev/null +++ b/stratosphere/libstratosphere/source/ams/ams_environment.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "ams_bpc.h" + +namespace sts::ams { + + namespace { + + inline u64 GetPc() { + u64 pc; + __asm__ __volatile__ ("adr %[pc], ." : [pc]"=&r"(pc) :: ); + return pc; + } + + struct StackFrame { + u64 fp; + u64 lr; + }; + + } + + extern ncm::TitleId StratosphereTitleId; + + void WEAK ExceptionHandler(FatalErrorContext *ctx) { + R_ASSERT(amsBpcInitialize()); + R_ASSERT(amsBpcRebootToFatalError(ctx)); + while (1) { /* ... */ } + } + + void CrashHandler(ThreadExceptionDump *ctx) { + FatalErrorContext ams_ctx; + + /* Convert thread dump to atmosphere dump. */ + { + ams_ctx.magic = FatalErrorContext::Magic; + ams_ctx.error_desc = ctx->error_desc; + ams_ctx.title_id = static_cast(StratosphereTitleId); + for (size_t i = 0; i < FatalErrorContext::NumGprs; i++) { + ams_ctx.gprs[i] = ctx->cpu_gprs[i].x; + } + if (ams_ctx.error_desc == FatalErrorContext::DataAbortErrorDesc && + ams_ctx.gprs[27] == FatalErrorContext::StdAbortMagicAddress && + ams_ctx.gprs[28] == FatalErrorContext::StdAbortMagicValue) + { + /* Detect std::abort(). */ + ams_ctx.error_desc = FatalErrorContext::StdAbortErrorDesc; + } + + ams_ctx.fp = ctx->fp.x; + ams_ctx.lr = ctx->lr.x; + ams_ctx.sp = ctx->sp.x; + ams_ctx.pc = ctx->pc.x; + ams_ctx.pstate = ctx->pstate; + ams_ctx.afsr0 = ctx->afsr0; + ams_ctx.afsr1 = ctx->afsr1; + ams_ctx.far = ctx->far.x; + ams_ctx.report_identifier = armGetSystemTick(); + /* Grab module base. */ + { + MemoryInfo mem_info; + u32 page_info; + if (R_SUCCEEDED(svcQueryMemory(&mem_info, &page_info, GetPc()))) { + ams_ctx.module_base = mem_info.addr; + } else { + ams_ctx.module_base = 0; + } + } + ams_ctx.stack_trace_size = 0; + u64 cur_fp = ams_ctx.fp; + for (size_t i = 0; i < FatalErrorContext::MaxStackTrace; i++) { + /* Validate current frame. */ + if (cur_fp == 0 || (cur_fp & 0xF)) { + break; + } + + /* Read a new frame. */ + StackFrame cur_frame; + MemoryInfo mem_info; + u32 page_info; + if (R_SUCCEEDED(svcQueryMemory(&mem_info, &page_info, cur_fp)) && (mem_info.perm & Perm_R) == Perm_R) { + std::memcpy(&cur_frame, reinterpret_cast(cur_fp), sizeof(cur_frame)); + } else { + break; + } + + /* Advance to the next frame. */ + ams_ctx.stack_trace[ams_ctx.stack_trace_size++] = cur_frame.lr; + cur_fp = cur_frame.fp; + } + /* Clear unused parts of stack trace. */ + for (size_t i = ams_ctx.stack_trace_size; i < FatalErrorContext::MaxStackTrace; i++) { + ams_ctx.stack_trace[i] = 0; + } + + /* Grab up to 0x100 of stack. */ + { + MemoryInfo mem_info; + u32 page_info; + if (R_SUCCEEDED(svcQueryMemory(&mem_info, &page_info, ams_ctx.sp)) && (mem_info.perm & Perm_R) == Perm_R) { + size_t copy_size = std::min(FatalErrorContext::MaxStackDumpSize, static_cast(mem_info.addr + mem_info.size - ams_ctx.sp)); + ams_ctx.stack_dump_size = copy_size; + std::memcpy(ams_ctx.stack_dump, reinterpret_cast(ams_ctx.sp), copy_size); + } else { + ams_ctx.stack_dump_size = 0; + } + } + } + + /* Just call the user exception handler. */ + ::sts::ams::ExceptionHandler(&ams_ctx); + } + + inline __attribute((noreturn)) void AbortImpl() { + /* Just perform a data abort. */ + register u64 addr __asm__("x27") = FatalErrorContext::StdAbortMagicAddress; + register u64 val __asm__("x28") = FatalErrorContext::StdAbortMagicValue; + while (true) { + __asm__ __volatile__ ( + "str %[val], [%[addr]]" + : + : [val]"r"(val), [addr]"r"(addr) + ); + } + } + +} + +extern "C" { + + /* Redefine abort to trigger these handlers. */ + void abort(); + +} + +/* Custom abort handler, so that std::abort will trigger these. */ +void abort() { + sts::ams::AbortImpl(); +} \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp b/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp new file mode 100644 index 000000000..39c8f60af --- /dev/null +++ b/stratosphere/libstratosphere/source/ams/ams_exosphere_api.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +namespace sts::ams { + + ApiInfo GetApiInfo() { + u64 exosphere_cfg; + if (spl::smc::GetConfig(&exosphere_cfg, 1, SplConfigItem_ExosphereApiVersion) != spl::smc::Result::Success) { + R_ASSERT(ResultAtmosphereExosphereNotPresent); + } + + return ApiInfo{ + .major_version = static_cast((exosphere_cfg >> 0x20) & 0xFF), + .minor_version = static_cast((exosphere_cfg >> 0x18) & 0xFF), + .micro_version = static_cast((exosphere_cfg >> 0x10) & 0xFF), + .target_firmware = static_cast((exosphere_cfg >> 0x08) & 0xFF), + .master_key_revision = static_cast((exosphere_cfg >> 0x00) & 0xFF), + }; + } + + void ForceRebootToRcm() { + R_ASSERT(spl::smc::ConvertResult(spl::smc::SetConfig(SplConfigItem_ExosphereNeedsReboot, 1))); + } + + void ForceRebootToIramPayload() { + R_ASSERT(spl::smc::ConvertResult(spl::smc::SetConfig(SplConfigItem_ExosphereNeedsReboot, 2))); + } + + void ForceShutdown() { + R_ASSERT(spl::smc::ConvertResult(spl::smc::SetConfig(SplConfigItem_ExosphereNeedsShutdown, 1))); + } + + void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size) { + spl::smc::AtmosphereCopyToIram(iram_dst, dram_src, size); + } + + void CopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size) { + spl::smc::AtmosphereCopyFromIram(dram_dst, iram_src, size); + } + + namespace { + + inline Result GetRcmBugPatched(bool *out) { + u64 tmp; + R_TRY(spl::smc::ConvertResult(spl::smc::GetConfig(&tmp, 1, SplConfigItem_ExosphereHasRcmBugPatch))); + *out = (tmp != 0); + return ResultSuccess; + } + + } + + bool IsRcmBugPatched() { + bool rcm_bug_patched; + R_ASSERT(GetRcmBugPatched(&rcm_bug_patched)); + return rcm_bug_patched; + } + +} diff --git a/stratosphere/libstratosphere/source/ams/ams_hos_version_api.cpp b/stratosphere/libstratosphere/source/ams/ams_hos_version_api.cpp index 7a0404e0c..5f6ac7b35 100644 --- a/stratosphere/libstratosphere/source/ams/ams_hos_version_api.cpp +++ b/stratosphere/libstratosphere/source/ams/ams_hos_version_api.cpp @@ -35,19 +35,7 @@ namespace sts::hos { return; } - /* TODO: spl::smc:: */ - u32 target_fw = 0; - { - SecmonArgs args = {0}; - args.X[0] = 0xC3000002; /* smcGetConfig */ - args.X[1] = 65000; /* ConfigItem_ExosphereVersion */ - R_ASSERT(svcCallSecureMonitor(&args)); - STS_ASSERT(args.X[0] == 0); - - target_fw = (args.X[1] >> 0x08) & 0xFF; - } - - switch (static_cast(target_fw)) { + switch (ams::GetApiInfo().GetTargetFirmware()) { case ams::TargetFirmware_100: g_hos_version = hos::Version_100; break; diff --git a/stratosphere/libstratosphere/source/bpc_ams.c b/stratosphere/libstratosphere/source/bpc_ams.c deleted file mode 100644 index 0728e0911..000000000 --- a/stratosphere/libstratosphere/source/bpc_ams.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -static Service g_bpcAmsSrv; -static u64 g_bpcAmsAmsRefcnt; - -Result bpcAmsInitialize(void) { - atomicIncrement64(&g_bpcAmsAmsRefcnt); - - if (serviceIsActive(&g_bpcAmsSrv)) { - return 0; - } - - Handle h; - Result rc = svcConnectToNamedPort(&h, "bpc:ams"); - if (R_SUCCEEDED(rc)) { - serviceCreate(&g_bpcAmsSrv, h); - } - - return rc; -} - -void bpcAmsExit(void) { - if (atomicDecrement64(&g_bpcAmsAmsRefcnt) == 0) - serviceClose(&g_bpcAmsSrv); -} - -Result bpcAmsRebootToFatalError(AtmosphereFatalErrorContext *ctx) { - IpcCommand c; - ipcInitialize(&c); - ipcAddSendBuffer(&c, ctx, sizeof(*ctx), BufferType_Normal); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_bpcAmsSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - - Result rc = serviceIpcDispatch(&g_bpcAmsSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_bpcAmsSrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} diff --git a/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp b/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp new file mode 100644 index 000000000..5bb6b2ae6 --- /dev/null +++ b/stratosphere/libstratosphere/source/dd/dd_io_mappings.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +namespace sts::dd { + + uintptr_t QueryIoMapping(uintptr_t phys_addr, size_t size) { + u64 virtual_addr; + const u64 aligned_addr = util::AlignDown(phys_addr, 0x1000); + const size_t offset = phys_addr - aligned_addr; + const u64 aligned_size = size + offset; + R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) { + /* Official software handles this by returning 0. */ + R_CATCH(ResultKernelNotFound) { return 0; } + } R_END_TRY_CATCH_WITH_ASSERT; + + return static_cast(virtual_addr + offset); + } + + namespace { + + inline u32 ReadWriteRegisterImpl(uintptr_t phys_addr, u32 value, u32 mask) { + u32 out_value; + R_ASSERT(svcReadWriteRegister(&out_value, phys_addr, mask, value)); + return out_value; + } + + } + + u32 ReadRegister(uintptr_t phys_addr) { + return ReadWriteRegisterImpl(phys_addr, 0, 0); + } + + void WriteRegister(uintptr_t phys_addr, u32 value) { + ReadWriteRegisterImpl(phys_addr, value, ~u32()); + } + + u32 ReadWriteRegister(uintptr_t phys_addr, u32 value, u32 mask) { + return ReadWriteRegisterImpl(phys_addr, value, mask); + } + +} diff --git a/stratosphere/libstratosphere/source/dmnt/dmntcht.c b/stratosphere/libstratosphere/source/dmnt/dmntcht.c new file mode 100644 index 000000000..86ed9be2f --- /dev/null +++ b/stratosphere/libstratosphere/source/dmnt/dmntcht.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "../service_guard.h" +#include "dmntcht.h" + +static Service g_dmntchtSrv; + +NX_GENERATE_SERVICE_GUARD(dmntcht); + +Result _dmntchtInitialize(void) { + return smGetService(&g_dmntchtSrv, "dmnt:cht"); +} + +void _dmntchtCleanup(void) { + serviceClose(&g_dmntchtSrv); +} + +Service* dmntchtGetServiceSession(void) { + return &g_dmntchtSrv; +} + +Result dmntchtHasCheatProcess(bool *out) { + u8 tmp; + Result rc = serviceDispatchOut(&g_dmntchtSrv, 65000, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; +} + +Result dmntchtGetCheatProcessEvent(Event *event) { + Handle evt_handle; + Result rc = serviceDispatch(&g_dmntchtSrv, 65001, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &evt_handle, + ); + + if (R_SUCCEEDED(rc)) { + eventLoadRemote(&g_dmntchtSrv, evt_handle, true); + } + + return rc; +} + +Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata) { + return serviceDispatchOut(&g_dmntchtSrv, 65002, *out_metadata); +} + +Result dmntchtForceOpenCheatProcess(void) { + return serviceDispatch(&g_dmntchtSrv, 65003); +} + +static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) { + return serviceDispatchOut(&g_dmntchtSrv, cmd_id, *out_count); +} + +static Result _dmntchtGetEntries(void *buffer, u64 buffer_size, u64 offset, u64 *out_count, u32 cmd_id) { + return serviceDispatchInOut(&g_dmntchtSrv, cmd_id, offset, *out_count, + .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias }, + .buffers = { { buffer, buffer_size } }, + ); +} + +static Result _dmntchtCmdInU32NoOut(u32 in, u32 cmd_id) { + return serviceDispatchIn(&g_dmntchtSrv, cmd_id, in); +} + +Result dmntchtGetCheatProcessMappingCount(u64 *out_count) { + return _dmntchtGetCount(65100, out_count); +} + +Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count) { + return _dmntchtGetEntries(65101, buffer, sizeof(*buffer) * max_count, offset, out_count); +} + +Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size) { + const struct { + u64 address; + u64 size; + } in = { address, size }; + return serviceDispatchIn(&g_dmntchtSrv, 65102, in, + .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias }, + .buffers = { { buffer, size } }, + ); +} + +Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size) { + const struct { + u64 address; + u64 size; + } in = { address, size }; + return serviceDispatchIn(&g_dmntchtSrv, 65103, in, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, + .buffers = { { buffer, size } }, + ); +} + +Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address){ + return serviceDispatchInOut(&g_dmntchtSrv, 65104, address, *mem_info); +} + +Result dmntchtGetCheatCount(u64 *out_count) { + return _dmntchtGetCount(65200, out_count); +} + +Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { + return _dmntchtGetEntries(65201, buffer, sizeof(*buffer) * max_count, offset, out_count); +} + +Result dmntchtGetCheatById(DmntCheatEntry *out, u32 cheat_id) { + return serviceDispatchIn(&g_dmntchtSrv, 65202, cheat_id, + .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize }, + .buffers = { { out, sizeof(*out) } }, + ); +} + +Result dmntchtToggleCheat(u32 cheat_id) { + return _dmntchtCmdInU32NoOut(cheat_id, 65203); +} + +Result dmntchtAddCheat(DmntCheatDefinition *cheat_def, bool enabled, u32 *out_cheat_id) { + const u8 in = enabled != 0; + return serviceDispatchInOut(&g_dmntchtSrv, 65204, in, *out_cheat_id, + .buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize }, + .buffers = { { cheat_def, sizeof(*cheat_def) } }, + ); +} + +Result dmntchtRemoveCheat(u32 cheat_id) { + return _dmntchtCmdInU32NoOut(cheat_id, 65205); +} + +Result dmntchtGetFrozenAddressCount(u64 *out_count) { + return _dmntchtGetCount(65300, out_count); +} + +Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { + return _dmntchtGetEntries(65301, buffer, sizeof(*buffer) * max_count, offset, out_count); +} + +Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address) { + return serviceDispatchInOut(&g_dmntchtSrv, 65302, address, *out); +} + +Result dmntchtEnableFrozenAddress(u64 address, u64 width, u64 *out_value) { + const struct { + u64 address; + u64 width; + } in = { address, width }; + return serviceDispatchInOut(&g_dmntchtSrv, 65303, in, *out_value); +} + +Result dmntchtDisableFrozenAddress(u64 address) { + return serviceDispatchIn(&g_dmntchtSrv, 65304, address); +} diff --git a/stratosphere/libstratosphere/include/stratosphere/services/dmntcht.h b/stratosphere/libstratosphere/source/dmnt/dmntcht.h similarity index 96% rename from stratosphere/libstratosphere/include/stratosphere/services/dmntcht.h rename to stratosphere/libstratosphere/source/dmnt/dmntcht.h index 6f8d5ddc2..c1dc6f71a 100644 --- a/stratosphere/libstratosphere/include/stratosphere/services/dmntcht.h +++ b/stratosphere/libstratosphere/source/dmnt/dmntcht.h @@ -15,7 +15,9 @@ */ #pragma once -#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -86,7 +88,6 @@ Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address); Result dmntchtEnableFrozenAddress(u64 address, u64 width, u64 *out_value); Result dmntchtDisableFrozenAddress(u64 address); - #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/stratosphere/libstratosphere/source/dmntcht.c b/stratosphere/libstratosphere/source/dmntcht.c deleted file mode 100644 index eb6476f0d..000000000 --- a/stratosphere/libstratosphere/source/dmntcht.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -static Service g_dmntchtService; -static u64 g_refCnt; - -static Result _dmntchtGetCount(u64 cmd_id, u64 *out_count); -static Result _dmntchtGetEntries(u64 cmd_id, void *buffer, u64 buffer_size, u64 offset, u64 *out_count); - -Result dmntchtInitialize(void) { - atomicIncrement64(&g_refCnt); - - if (serviceIsActive(&g_dmntchtService)) { - return 0; - } - - return smGetService(&g_dmntchtService, "dmnt:cht"); -} - -void dmntchtExit(void) { - if (atomicIncrement64(&g_refCnt) == 0) { - serviceClose(&g_dmntchtService); - } -} - -Service* dmntchtGetServiceSession(void) { - return &g_dmntchtService; -} - -Result dmntchtHasCheatProcess(bool *out) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - bool out; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (out) *out = resp->out; - } - } - - return rc; -} - -Result dmntchtGetCheatProcessEvent(Event *event) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65001; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - eventLoadRemote(event, r.Handles[0], true); - } - } - - return rc; -} - -Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65002; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - DmntCheatProcessMetadata metadata; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (out_metadata) *out_metadata = resp->metadata; - } - } - - return rc; -} - -Result dmntchtForceOpenCheatProcess(void) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65003; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - -static Result _dmntchtGetCount(u64 cmd_id, u64 *out_count) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = cmd_id; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 count; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - *out_count = resp->count; - } - - return rc; -} - -static Result _dmntchtGetEntries(u64 cmd_id, void *buffer, u64 buffer_size, u64 offset, u64 *out_count) { - IpcCommand c; - ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, buffer_size, 0); - - struct { - u64 magic; - u64 cmd_id; - u64 offset; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = cmd_id; - raw->offset = offset; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 count; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (out_count) *out_count = resp->count; - } - } - - return rc; -} - -Result dmntchtGetCheatProcessMappingCount(u64 *out_count) { - return _dmntchtGetCount(65100, out_count); -} - -Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count) { - return _dmntchtGetEntries(65101, buffer, sizeof(*buffer) * max_count, offset, out_count); -} - -Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size) { - IpcCommand c; - ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, size, 0); - - struct { - u64 magic; - u64 cmd_id; - u64 address; - u64 size; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65102; - raw->address = address; - raw->size = size; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - -Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size) { - IpcCommand c; - ipcInitialize(&c); - ipcAddSendBuffer(&c, buffer, size, 0); - - struct { - u64 magic; - u64 cmd_id; - u64 address; - u64 size; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65103; - raw->address = address; - raw->size = size; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - -Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address){ - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 address; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65104; - raw->address = address; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - MemoryInfo mem_info; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (mem_info) *mem_info = resp->mem_info; - } - } - - return rc; -} - -Result dmntchtGetCheatCount(u64 *out_count) { - return _dmntchtGetCount(65200, out_count); -} - -Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { - return _dmntchtGetEntries(65201, buffer, sizeof(*buffer) * max_count, offset, out_count); -} - -Result dmntchtGetCheatById(DmntCheatEntry *buffer, u32 cheat_id) { - IpcCommand c; - ipcInitialize(&c); - ipcAddRecvBuffer(&c, buffer, sizeof(*buffer), 0); - - struct { - u64 magic; - u64 cmd_id; - u32 cheat_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65202; - raw->cheat_id = cheat_id; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - -Result dmntchtToggleCheat(u32 cheat_id) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 cheat_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65203; - raw->cheat_id = cheat_id; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - -Result dmntchtAddCheat(DmntCheatDefinition *buffer, bool enabled, u32 *out_cheat_id) { - IpcCommand c; - ipcInitialize(&c); - ipcAddSendBuffer(&c, buffer, sizeof(*buffer), 0); - - struct { - u64 magic; - u64 cmd_id; - u8 enabled; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65204; - raw->enabled = enabled; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u32 cheat_id; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (out_cheat_id) *out_cheat_id = resp->cheat_id; - } - } - - return rc; -} - -Result dmntchtRemoveCheat(u32 cheat_id) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 cheat_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65205; - raw->cheat_id = cheat_id; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} - - -Result dmntchtGetFrozenAddressCount(u64 *out_count) { - return _dmntchtGetCount(65300, out_count); -} - -Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { - return _dmntchtGetEntries(65301, buffer, sizeof(*buffer) * max_count, offset, out_count); -} - -Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 address; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65302; - raw->address = address; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - DmntFrozenAddressEntry entry; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (out) *out = resp->entry; - } - } - - return rc; -} - -Result dmntchtEnableFrozenAddress(u64 address, u64 width, u64 *out_value) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 address; - u64 width; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65303; - raw->address = address; - raw->width = width; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 value; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - if (out_value) *out_value = resp->value; - } - } - - return rc; -} - -Result dmntchtDisableFrozenAddress(u64 address) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 address; - } *raw; - - raw = serviceIpcPrepareHeader(&g_dmntchtService, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65304; - raw->address = address; - - Result rc = serviceIpcDispatch(&g_dmntchtService); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 value; - } *resp; - - serviceIpcParse(&g_dmntchtService, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; -} diff --git a/stratosphere/libstratosphere/source/emummc_utilities.cpp b/stratosphere/libstratosphere/source/emummc_utilities.cpp deleted file mode 100644 index 59c4267cd..000000000 --- a/stratosphere/libstratosphere/source/emummc_utilities.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -/* EFS0 */ -static constexpr u32 EmummcStorageMagic = 0x30534645; -static constexpr size_t EmummcMaxDirLength = 0x7F; - -struct EmummcBaseConfig { - u32 magic; - u32 type; - u32 id; - u32 fs_version; -}; - -struct EmummcPartitionConfig { - u64 start_sector; -}; - -struct EmummcFileConfig { - char path[EmummcMaxDirLength+1]; -}; - -struct ExoEmummcConfig { - EmummcBaseConfig base_cfg; - union { - EmummcPartitionConfig partition_cfg; - EmummcFileConfig file_cfg; - }; - char emu_dir_path[EmummcMaxDirLength+1]; -}; - -enum EmummcType { - EmummcType_Emmc = 0, - EmummcType_Sd, - EmummcType_SdFile, - - EmummcType_Max, -}; - -static bool g_IsEmummc = false; -static bool g_HasCached = false; -static Mutex g_Mutex; -static ExoEmummcConfig g_exo_emummc_config; - -static void _CacheValues(void) -{ - if (__atomic_load_n(&g_HasCached, __ATOMIC_SEQ_CST)) - return; - - mutexLock(&g_Mutex); - - if (g_HasCached) { - mutexUnlock(&g_Mutex); - return; - } - - static struct { - char file_path[EmummcMaxDirLength+1]; - char nintendo_path[EmummcMaxDirLength+1]; - } __attribute__((aligned(0x1000))) paths; - - { - SecmonArgs args = {0}; - args.X[0] = 0xF0000404; /* smcAmsGetEmunandConfig */ - args.X[1] = 0; /* NAND */ - args.X[2] = reinterpret_cast(&paths); /* path output */ - R_ASSERT(svcCallSecureMonitor(&args)); - STS_ASSERT(args.X[0] == 0); - std::memcpy(&g_exo_emummc_config, &args.X[1], sizeof(args) - sizeof(args.X[0])); - } - - const EmummcType emummc_type = static_cast(g_exo_emummc_config.base_cfg.type); - -/* Ignore format warnings. */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-truncation" - switch (emummc_type) { - case EmummcType_SdFile: - std::snprintf(g_exo_emummc_config.file_cfg.path, sizeof(g_exo_emummc_config.file_cfg.path), "/%s", paths.file_path); - break; - default: - break; - } - - std::snprintf(g_exo_emummc_config.emu_dir_path, sizeof(g_exo_emummc_config.emu_dir_path), "/%s", paths.nintendo_path); - - g_IsEmummc = g_exo_emummc_config.base_cfg.magic == EmummcStorageMagic && emummc_type != EmummcType_Emmc; - - /* Default Nintendo redirection path. */ - if (g_IsEmummc) { - if (std::strcmp(g_exo_emummc_config.emu_dir_path, "/") == 0) { - std::snprintf(g_exo_emummc_config.emu_dir_path, sizeof(g_exo_emummc_config.emu_dir_path), "/emummc/Nintendo_%04x", g_exo_emummc_config.base_cfg.id); - } - } -#pragma GCC diagnostic pop - - __atomic_store_n(&g_HasCached, true, __ATOMIC_SEQ_CST); - - mutexUnlock(&g_Mutex); -} - - -/* Get whether emummc is active. */ -bool IsEmummc() { - _CacheValues(); - return g_IsEmummc; -} - -/* Get Nintendo redirection path. */ -const char *GetEmummcNintendoDirPath() { - _CacheValues(); - if (!g_IsEmummc) { - return nullptr; - } - return g_exo_emummc_config.emu_dir_path; -} - -/* Get Emummc folderpath, NULL if not file-based. */ -const char *GetEmummcFilePath() { - _CacheValues(); - if (!g_IsEmummc || g_exo_emummc_config.base_cfg.type != EmummcType_SdFile) { - return nullptr; - } - return g_exo_emummc_config.file_cfg.path; -} diff --git a/stratosphere/libstratosphere/source/ldr/ldr_ams.c b/stratosphere/libstratosphere/source/ldr/ldr_ams.c index 94c042e12..59ec13245 100644 --- a/stratosphere/libstratosphere/source/ldr/ldr_ams.c +++ b/stratosphere/libstratosphere/source/ldr/ldr_ams.c @@ -18,44 +18,9 @@ #include "ldr_ams.h" static Result _ldrAtmosphereHasLaunchedTitle(Service *srv, bool *out, u64 tid) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 title_id; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - raw->title_id = tid; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 has_launched_title; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = resp->has_launched_title != 0; - } else { - rc = 0x666; - } - } else { - rc = 0x555; - } - + u8 tmp; + Result rc = serviceDispatchInOut(srv, 65000, tid, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } diff --git a/stratosphere/libstratosphere/source/on_crash.cpp b/stratosphere/libstratosphere/source/on_crash.cpp deleted file mode 100644 index 2621a51a4..000000000 --- a/stratosphere/libstratosphere/source/on_crash.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -WEAK sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Invalid; - -extern "C" { - void WEAK __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); - - /* Redefine abort, so that it triggers these handlers. */ - void abort(); -}; - -static inline u64 GetPc() { - u64 pc; - __asm__ __volatile__ ("adr %[pc], ." : [pc]"=&r"(pc) :: ); - return pc; -} - -struct StackFrame { - u64 fp; - u64 lr; -}; - -void StratosphereCrashHandler(ThreadExceptionDump *ctx) { - AtmosphereFatalErrorContext ams_ctx; - /* Convert thread dump to atmosphere dump. */ - { - ams_ctx.magic = AtmosphereFatalErrorMagic; - ams_ctx.error_desc = ctx->error_desc; - ams_ctx.title_id = static_cast(__stratosphere_title_id); - for (size_t i = 0; i < AtmosphereFatalErrorNumGprs; i++) { - ams_ctx.gprs[i] = ctx->cpu_gprs[i].x; - } - if (ams_ctx.error_desc == DATA_ABORT_ERROR_DESC && - ams_ctx.gprs[2] == STD_ABORT_ADDR_MAGIC && - ams_ctx.gprs[3] == STD_ABORT_VALUE_MAGIC) { - /* Detect std::abort(). */ - ams_ctx.error_desc = STD_ABORT_ERROR_DESC; - } - - ams_ctx.fp = ctx->fp.x; - ams_ctx.lr = ctx->lr.x; - ams_ctx.sp = ctx->sp.x; - ams_ctx.pc = ctx->pc.x; - ams_ctx.pstate = ctx->pstate; - ams_ctx.afsr0 = ctx->afsr0; - ams_ctx.afsr1 = ctx->afsr1; - ams_ctx.far = ctx->far.x; - ams_ctx.report_identifier = armGetSystemTick(); - /* Grab module base. */ - { - MemoryInfo mem_info; - u32 page_info; - if (R_SUCCEEDED(svcQueryMemory(&mem_info, &page_info, GetPc()))) { - ams_ctx.module_base = mem_info.addr; - } else { - ams_ctx.module_base = 0; - } - } - ams_ctx.stack_trace_size = 0; - u64 cur_fp = ams_ctx.fp; - for (size_t i = 0; i < AMS_FATAL_ERROR_MAX_STACKTRACE; i++) { - /* Validate current frame. */ - if (cur_fp == 0 || (cur_fp & 0xF)) { - break; - } - - /* Read a new frame. */ - StackFrame cur_frame; - MemoryInfo mem_info; - u32 page_info; - if (R_SUCCEEDED(svcQueryMemory(&mem_info, &page_info, cur_fp)) && (mem_info.perm & Perm_R) == Perm_R) { - std::memcpy(&cur_frame, reinterpret_cast(cur_fp), sizeof(cur_frame)); - } else { - break; - } - - /* Advance to the next frame. */ - ams_ctx.stack_trace[ams_ctx.stack_trace_size++] = cur_frame.lr; - cur_fp = cur_frame.fp; - } - /* Clear unused parts of stack trace. */ - for (size_t i = ams_ctx.stack_trace_size; i < AMS_FATAL_ERROR_MAX_STACKTRACE; i++) { - ams_ctx.stack_trace[i] = 0; - } - - /* Grab up to 0x100 of stack. */ - { - MemoryInfo mem_info; - u32 page_info; - if (R_SUCCEEDED(svcQueryMemory(&mem_info, &page_info, ams_ctx.sp)) && (mem_info.perm & Perm_R) == Perm_R) { - size_t copy_size = std::min(static_cast(AMS_FATAL_ERROR_MAX_STACKDUMP), static_cast(mem_info.addr + mem_info.size - ams_ctx.sp)); - ams_ctx.stack_dump_size = copy_size; - std::memcpy(ams_ctx.stack_dump, reinterpret_cast(ams_ctx.sp), copy_size); - } else { - ams_ctx.stack_dump_size = 0; - } - } - } - - /* Just call the user exception handler. */ - __libstratosphere_exception_handler(&ams_ctx); -} - -/* Default exception handler behavior. */ -void WEAK __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) { - R_ASSERT(bpcAmsInitialize()); - R_ASSERT(bpcAmsRebootToFatalError(ctx)); - bpcAmsExit(); - while (1) { } -} - -/* Custom abort handler, so that std::abort will trigger these. */ -void abort() { - /* Just perform a data abort. */ - register u64 addr __asm__("x2") = STD_ABORT_ADDR_MAGIC; - register u64 val __asm__("x3") = STD_ABORT_VALUE_MAGIC; - while (true) { - __asm__ __volatile__ ( - "str %[val], [%[addr]]" - : - : [val]"r"(val), [addr]"r"(addr) - ); - } -} \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/pm/pm_ams.c b/stratosphere/libstratosphere/source/pm/pm_ams.c index 2e1c19886..aeb6bf1cc 100644 --- a/stratosphere/libstratosphere/source/pm/pm_ams.c +++ b/stratosphere/libstratosphere/source/pm/pm_ams.c @@ -18,124 +18,35 @@ #include "pm_ams.h" Result pminfoAtmosphereGetProcessId(u64 *out_pid, u64 tid) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = pminfoGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 title_id; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - raw->title_id = tid; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 pid; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out_pid = resp->pid; - } - } - - return rc; + return serviceDispatchInOut(pminfoGetServiceSession(), 65000, tid, *out_pid); } Result pminfoAtmosphereHasLaunchedTitle(bool *out, u64 tid) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = pminfoGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 title_id; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65001; - raw->title_id = tid; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 has_launched_title; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = resp->has_launched_title != 0; - } - } - + u8 tmp; + Result rc = serviceDispatchInOut(pminfoGetServiceSession(), 65001, tid, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } -Result pmdmntAtmosphereGetProcessInfo(Handle* out, u64 *tid_out, u8 *sid_out, u64 pid) { - IpcCommand c; - ipcInitialize(&c); - Service *s = pmdmntGetServiceSession(); - +Result pmdmntAtmosphereGetProcessInfo(Handle* handle_out, u64 *tid_out, u8 *sid_out, u64 pid) { struct { - u64 magic; - u64 cmd_id; - u64 pid; - } *raw; + u64 title_id; + u8 storage_id; + } out; + Handle tmp_handle; - raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - raw->pid = pid; - - Result rc = serviceIpcDispatch(s); + Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65000, pid, out, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &tmp_handle, + ); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 title_id; - FsStorageId storage_id; - } *resp; - - serviceIpcParse(s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - if (out) { - *out = r.Handles[0]; - } else { - svcCloseHandle(r.Handles[0]); - } - if (tid_out) *tid_out = resp->title_id; - if (sid_out) *sid_out = resp->storage_id; + if (tid_out) *tid_out = out.title_id; + if (sid_out) *sid_out = out.storage_id; + if (handle_out) { + *handle_out = tmp_handle; + } else { + svcCloseHandle(tmp_handle); } } @@ -143,44 +54,20 @@ Result pmdmntAtmosphereGetProcessInfo(Handle* out, u64 *tid_out, u8 *sid_out, u6 } Result pmdmntAtmosphereGetCurrentLimitInfo(u64 *out_cur, u64 *out_lim, u32 group, u32 resource) { - IpcCommand c; - ipcInitialize(&c); - Service *s = pmdmntGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; + const struct { u32 group; u32 resource; - } *raw; + } in = { group, resource }; + struct { + u64 cur; + u64 lim; + } out; - raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65001; - raw->group = group; - raw->resource = resource; - - Result rc = serviceIpcDispatch(s); + Result rc = serviceDispatchInOut(pmdmntGetServiceSession(), 65001, in, out); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 cur_value; - u64 lim_value; - } *resp; - - serviceIpcParse(s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - if (out_cur) *out_cur = resp->cur_value; - if (out_lim) *out_lim = resp->lim_value; - } + if (out_cur) *out_cur = out.cur; + if (out_lim) *out_lim = out.lim; } return rc; diff --git a/stratosphere/libstratosphere/source/service_guard.h b/stratosphere/libstratosphere/source/service_guard.h new file mode 100644 index 000000000..588a0c995 --- /dev/null +++ b/stratosphere/libstratosphere/source/service_guard.h @@ -0,0 +1,64 @@ +#pragma once +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ServiceGuard { + Mutex mutex; + u32 refCount; +} ServiceGuard; + +NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g) +{ + mutexLock(&g->mutex); + return (g->refCount++) == 0; +} + +NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void)) +{ + if (R_FAILED(rc)) { + cleanupFunc(); + --g->refCount; + } + mutexUnlock(&g->mutex); + return rc; +} + +NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void)) +{ + mutexLock(&g->mutex); + if (g->refCount && (--g->refCount) == 0) + cleanupFunc(); + mutexUnlock(&g->mutex); +} + +#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \ +\ +static ServiceGuard g_##name##Guard; \ +NX_INLINE Result _##name##Initialize _paramdecl; \ +static void _##name##Cleanup(void); \ +\ +Result name##Initialize _paramdecl \ +{ \ + Result rc = 0; \ + if (serviceGuardBeginInit(&g_##name##Guard)) \ + rc = _##name##Initialize _parampass; \ + return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \ +} \ +\ +void name##Exit(void) \ +{ \ + serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \ +} + +#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ()) + +#ifdef __cplusplus +} +#endif diff --git a/stratosphere/libstratosphere/source/sm/sm_ams.c b/stratosphere/libstratosphere/source/sm/sm_ams.c index 628ff2fb8..b345e42a6 100644 --- a/stratosphere/libstratosphere/source/sm/sm_ams.c +++ b/stratosphere/libstratosphere/source/sm/sm_ams.c @@ -13,166 +13,42 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#include -#include +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "../service_guard.h" #include "sm_ams.h" -static Service g_smMitmSrv; -static u64 g_mitmRefCnt; +static Result _smAtmosphereCmdHas(bool *out, u64 service_name, u32 cmd_id) { + u8 tmp; + Result rc = serviceDispatchInOut(smGetServiceSession(), cmd_id, service_name, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; +} + +static Result _smAtmosphereCmdInServiceNameNoOut(u64 service_name, Service *srv, u32 cmd_id) { + return serviceDispatchIn(srv, cmd_id, service_name); +} Result smAtmosphereHasService(bool *out, const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = smGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65100; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 has_service; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = resp->has_service != 0; - } - } - - return rc; + return _smAtmosphereCmdHas(out, smEncodeName(name), 65100); } Result smAtmosphereWaitService(const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = smGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65101; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), smGetServiceSession(), 65101); } Result smAtmosphereHasMitm(bool *out, const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = smGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65004; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 has_mitm; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = resp->has_mitm != 0; - } - } - - return rc; + return _smAtmosphereCmdHas(out, smEncodeName(name), 65004); } Result smAtmosphereWaitMitm(const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = smGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65005; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; + return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), smGetServiceSession(), 65005); } -Result smAtmosphereMitmInitialize(void) { - atomicIncrement64(&g_mitmRefCnt); +static Service g_smAtmosphereMitmSrv; - if (serviceIsActive(&g_smMitmSrv)) - return 0; +NX_GENERATE_SERVICE_GUARD(smAtmosphereMitm); +Result _smAtmosphereMitmInitialize(void) { Handle sm_handle; Result rc = svcConnectToNamedPort(&sm_handle, "sm:"); while (R_VALUE(rc) == KERNELRESULT(NotFound)) { @@ -181,195 +57,64 @@ Result smAtmosphereMitmInitialize(void) { } if (R_SUCCEEDED(rc)) { - serviceCreate(&g_smMitmSrv, sm_handle); + serviceCreate(&g_smAtmosphereMitmSrv, sm_handle); } if (R_SUCCEEDED(rc)) { - IpcCommand c; - ipcInitialize(&c); - ipcSendPid(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 zero; - u64 reserved[2]; - } *raw; - - raw = serviceIpcPrepareHeader(&g_smMitmSrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; - raw->zero = 0; - - rc = serviceIpcDispatch(&g_smMitmSrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - - struct { - u64 magic; - u64 result; - } *resp; - serviceIpcParse(&g_smMitmSrv, &r, sizeof(*resp)); - - resp = r.Raw; - rc = resp->result; - } + const u64 pid_placeholder = 0; + rc = serviceDispatchIn(&g_smAtmosphereMitmSrv, 0, pid_placeholder, .in_send_pid = true); } - if (R_FAILED(rc)) - smAtmosphereMitmExit(); - return rc; } -void smAtmosphereMitmExit(void) { - if (atomicDecrement64(&g_mitmRefCnt) == 0) { - serviceClose(&g_smMitmSrv); - } +void _smAtmosphereMitmCleanup(void) { + serviceClose(&g_smAtmosphereMitmSrv); +} + +Service* smAtmosphereMitmGetServiceSession(void) { + return &g_smAtmosphereMitmSrv; } Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = &g_smMitmSrv; - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); + const u64 in = smEncodeName(name); + Handle tmp_handles[2]; + Result rc = serviceDispatchIn(&g_smAtmosphereMitmSrv, 65000, in, + .out_handle_attrs = { SfOutHandleAttr_HipcMove, SfOutHandleAttr_HipcMove }, + .out_handles = tmp_handles, + ); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *handle_out = r.Handles[0]; - *query_out = r.Handles[1]; - } + *handle_out = tmp_handles[0]; + *query_out = tmp_handles[1]; } return rc; } Result smAtmosphereMitmUninstall(const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = &g_smMitmSrv; - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65001; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - rc = resp->result; - } - - return rc; + return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), &g_smAtmosphereMitmSrv, 65001); } Result smAtmosphereMitmDeclareFuture(const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = &g_smMitmSrv; - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65006; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - rc = resp->result; - } - - return rc; + return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), &g_smAtmosphereMitmSrv, 65006); } Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, const char *name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = &g_smMitmSrv; - + const u64 in = smEncodeName(name); struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; + u64 pid; + u64 tid; + } out; - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65003; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); + Result rc = serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, in, out, + .out_num_objects = 1, + .out_objects = srv_out, + ); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u64 pid; - u64 tid; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc)) { - *pid_out = resp->pid; - *tid_out = resp->tid; - serviceCreate(srv_out, r.Handles[0]); - } + if (pid_out) *pid_out = out.pid; + if (tid_out) *tid_out = out.tid; } return rc; diff --git a/stratosphere/libstratosphere/source/sm/sm_ams.h b/stratosphere/libstratosphere/source/sm/sm_ams.h index 67c9b8894..7ab27f64a 100644 --- a/stratosphere/libstratosphere/source/sm/sm_ams.h +++ b/stratosphere/libstratosphere/source/sm/sm_ams.h @@ -5,7 +5,9 @@ * @copyright libnx Authors */ #pragma once -#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -18,6 +20,7 @@ Result smAtmosphereWaitMitm(const char *name); Result smAtmosphereMitmInitialize(void); void smAtmosphereMitmExit(void); +Service *smAtmosphereMitmGetServiceSession(); Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char *name); Result smAtmosphereMitmUninstall(const char *name); diff --git a/stratosphere/libstratosphere/source/sm/sm_api.cpp b/stratosphere/libstratosphere/source/sm/sm_api.cpp index a6b2be97a..c12806e36 100644 --- a/stratosphere/libstratosphere/source/sm/sm_api.cpp +++ b/stratosphere/libstratosphere/source/sm/sm_api.cpp @@ -55,4 +55,15 @@ namespace sts::sm { }); } + namespace impl { + + void DoWithSessionImpl(void (*Invoker)(void *), void *Function) { + impl::DoWithUserSession([&]() { + Invoker(Function); + return ResultSuccess; + }); + } + + } + } diff --git a/stratosphere/libstratosphere/source/sm/smm_ams.c b/stratosphere/libstratosphere/source/sm/smm_ams.c index f5ea65172..e9a1995eb 100644 --- a/stratosphere/libstratosphere/source/sm/smm_ams.c +++ b/stratosphere/libstratosphere/source/sm/smm_ams.c @@ -13,117 +13,36 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#include #include "smm_ams.h" Result smManagerAtmosphereEndInitialDefers(void) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = smManagerGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65000; - - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } - - return rc; - + return serviceDispatch(smManagerGetServiceSession(), 65000); } Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) { - IpcCommand c; - ipcInitialize(&c); - ipcAddSendBuffer(&c, acid_sac, acid_sac_size, BufferType_Normal); - ipcAddSendBuffer(&c, aci_sac, aci_sac_size, BufferType_Normal); - Service *srv = smManagerGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; + const struct { u64 pid; u64 tid; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65002; - raw->pid = pid; - raw->tid = tid; - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - } + } in = { pid, tid }; + return serviceDispatchIn(smManagerGetServiceSession(), 65002, in, + .buffer_attrs = { + SfBufferAttr_In | SfBufferAttr_HipcMapAlias, + SfBufferAttr_In | SfBufferAttr_HipcMapAlias, + }, + .buffers = { + { acid_sac, acid_sac_size }, + { aci_sac, aci_sac_size }, + }, + ); +} +static Result _smManagerAtmosphereCmdHas(bool *out, u64 service_name, u32 cmd_id) { + u8 tmp; + Result rc = serviceDispatchInOut(smManagerGetServiceSession(), cmd_id, service_name, tmp); + if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } Result smManagerAtmosphereHasMitm(bool *out, const char* name) { - IpcCommand c; - ipcInitialize(&c); - Service *srv = smManagerGetServiceSession(); - - struct { - u64 magic; - u64 cmd_id; - u64 service_name; - } *raw; - - raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw)); - raw->magic = SFCI_MAGIC; - raw->cmd_id = 65001; - raw->service_name = smEncodeName(name); - - Result rc = serviceIpcDispatch(srv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u8 has_mitm; - } *resp; - - serviceIpcParse(srv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - *out = resp->has_mitm != 0; - } - } - - return rc; + return _smManagerAtmosphereCmdHas(out, smEncodeName(name), 65001); } diff --git a/stratosphere/libstratosphere/source/spl/smc/spl_smc.cpp b/stratosphere/libstratosphere/source/spl/smc/spl_smc.cpp index 89e35067c..8b3c97339 100644 --- a/stratosphere/libstratosphere/source/spl/smc/spl_smc.cpp +++ b/stratosphere/libstratosphere/source/spl/smc/spl_smc.cpp @@ -309,4 +309,59 @@ namespace sts::spl::smc { return static_cast(args.X[0]); } + /* Atmosphere functions. */ + namespace { + + enum class IramCopyDirection { + FromIram = 0, + ToIram = 1, + }; + + inline Result AtmosphereIramCopy(uintptr_t dram_address, uintptr_t iram_address, size_t size, IramCopyDirection direction) { + SecmonArgs args; + args.X[0] = static_cast(FunctionId::AtmosphereIramCopy); + args.X[1] = dram_address; + args.X[2] = iram_address; + args.X[3] = size; + args.X[4] = static_cast(direction); + svcCallSecureMonitor(&args); + + return static_cast(args.X[0]); + } + + } + + Result AtmosphereCopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size) { + return AtmosphereIramCopy(reinterpret_cast(dram_src), iram_dst, size, IramCopyDirection::ToIram); + } + + Result AtmosphereCopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size) { + return AtmosphereIramCopy(reinterpret_cast(dram_dst), iram_src, size, IramCopyDirection::FromIram); + } + + Result AtmosphereReadWriteRegister(uint64_t address, uint32_t mask, uint32_t value, uint32_t *out_value) { + SecmonArgs args; + args.X[0] = static_cast(FunctionId::AtmosphereReadWriteRegister); + args.X[1] = address; + args.X[2] = mask; + args.X[3] = value; + svcCallSecureMonitor(&args); + + *out_value = static_cast(args.X[1]); + return static_cast(args.X[0]); + } + + Result AtmosphereWriteAddress(void *dst, const void *src, size_t size) { + STS_ASSERT(size <= sizeof(u64)); + + SecmonArgs args; + args.X[0] = static_cast(FunctionId::AtmosphereWriteAddress); + args.X[1] = reinterpret_cast(dst); + __builtin_memcpy(&args.X[1], src, size); + args.X[3] = size; + svcCallSecureMonitor(&args); + + return static_cast(args.X[0]); + } + } diff --git a/stratosphere/libstratosphere/source/updater/updater_api.cpp b/stratosphere/libstratosphere/source/updater/updater_api.cpp index f4f938520..ab619c107 100644 --- a/stratosphere/libstratosphere/source/updater/updater_api.cpp +++ b/stratosphere/libstratosphere/source/updater/updater_api.cpp @@ -346,7 +346,7 @@ namespace sts::updater { } /* Only preserve autorcm if on a unit with unpatched rcm bug. */ - if (HasAutoRcmPreserve(boot_image_update_type) && !IsRcmBugPatched()) { + if (HasAutoRcmPreserve(boot_image_update_type) && !ams::IsRcmBugPatched()) { R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctNormalSub)); R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctNormalSub)); R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctNormalMain)); @@ -407,7 +407,7 @@ namespace sts::updater { R_TRY(boot0_accessor.UpdateEks(bct, work)); } /* Only preserve autorcm if on a unit with unpatched rcm bug. */ - if (HasAutoRcmPreserve(boot_image_update_type) && !IsRcmBugPatched()) { + if (HasAutoRcmPreserve(boot_image_update_type) && !ams::IsRcmBugPatched()) { R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctSafeSub)); R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctSafeSub)); R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctSafeMain)); @@ -522,10 +522,8 @@ namespace sts::updater { } /* Get a session to ncm. */ - DoWithSmSession([&]() { - R_ASSERT(ncmInitialize()); - }); - ON_SCOPE_EXIT { ncmExit(); }; + sm::ScopedServiceHolder ncm_holder; + R_ASSERT(ncm_holder.GetResult()); /* Verify normal, verify safe as needed. */ if (verification_state.needs_verify_normal) { diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index 323866174..ebc612259 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -46,16 +46,20 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Loader; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Loader; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } - void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; @@ -68,19 +72,17 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); /* Initialize services we need. */ - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(fsInitialize()); R_ASSERT(lrInitialize()); R_ASSERT(fsldrInitialize()); }); - CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); + ams::CheckApiVersion(); } void __appExit(void) { diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 8eac3a8e2..d5edec87f 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -723,10 +723,9 @@ namespace sts::ldr { R_TRY(LoadNsosIntoProcessMemory(&info, loc.title_id, nso_headers, has_nso, arg_info)); /* Register NSOs with ro manager. */ - os::ProcessId process_id = os::InvalidProcessId; { - /* Nintendo doesn't validate this result, but we will. */ - R_ASSERT(svcGetProcessId(&process_id.value, info.process_handle.Get())); + /* Nintendo doesn't validate this get, but we do. */ + os::ProcessId process_id = os::GetProcessId(info.process_handle.Get()); /* Register new process. */ ldr::ro::RegisterProcess(pin_id, process_id, loc.title_id); diff --git a/stratosphere/pm/Makefile b/stratosphere/pm/Makefile index 57e73d8c8..09abb4c9a 100644 --- a/stratosphere/pm/Makefile +++ b/stratosphere/pm/Makefile @@ -41,7 +41,7 @@ ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE CFLAGS := -g -Wall -O2 -ffunction-sections \ $(ARCH) $(DEFINES) -CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_ENABLE_SMHAX +CFLAGS += $(INCLUDE) -D__SWITCH__ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 3eebce2c7..039776f56 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -310,8 +310,7 @@ namespace sts::pm::impl { }); /* Get the process id. */ - os::ProcessId process_id = os::InvalidProcessId; - R_ASSERT(svcGetProcessId(&process_id.value, process_handle)); + os::ProcessId process_id = os::GetProcessId(process_handle); /* Make new process info. */ void *process_info_storage = g_process_info_allocator.AllocateProcessInfoStorage(); diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index 93dbb0322..a7285c742 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -48,13 +48,18 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Pm; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Pm; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } void __libnx_initheap(void) { @@ -69,8 +74,6 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - namespace { constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000}; @@ -83,10 +86,8 @@ namespace { /* Check if we should return our title id. */ /* Doing this here works around a bug fixed in 6.0.0. */ /* Not doing so will cause svcDebugActiveProcess to deadlock on lower firmwares if called for it's own process. */ - os::ProcessId current_process_id = os::InvalidProcessId; - R_ASSERT(svcGetProcessId(¤t_process_id.value, CUR_PROCESS_HANDLE)); - if (current_process_id == process_id) { - return __stratosphere_title_id; + if (process_id == os::GetCurrentProcessId()) { + return ams::StratosphereTitleId; } /* Get a debug handle. */ @@ -97,8 +98,8 @@ namespace { svc::DebugEventInfo d; while (true) { R_ASSERT(svcGetDebugEvent(reinterpret_cast(&d), debug_handle.Get())); - if (d.type == sts::svc::DebugEventType::AttachProcess) { - return sts::ncm::TitleId{d.info.attach_process.title_id}; + if (d.type == svc::DebugEventType::AttachProcess) { + return ncm::TitleId{d.info.attach_process.title_id}; } } } @@ -109,14 +110,14 @@ namespace { void RegisterPrivilegedProcess(os::ProcessId process_id) { fsprUnregisterProgram(static_cast(process_id)); fsprRegisterProgram(static_cast(process_id), static_cast(process_id), FsStorageId_NandSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl)); - sts::sm::manager::UnregisterProcess(process_id); - sts::sm::manager::RegisterProcess(process_id, GetProcessTitleId(process_id), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl)); + sm::manager::UnregisterProcess(process_id); + sm::manager::RegisterProcess(process_id, GetProcessTitleId(process_id), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl)); } void RegisterPrivilegedProcesses() { /* Get privileged process range. */ os::ProcessId min_priv_process_id = os::InvalidProcessId, max_priv_process_id = os::InvalidProcessId; - sts::cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id); + cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id); /* Get list of processes, register all privileged ones. */ u32 num_pids; @@ -134,7 +135,7 @@ namespace { void __appInit(void) { hos::SetVersionForLibnx(); - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(fsprInitialize()); R_ASSERT(smManagerInitialize()); @@ -143,14 +144,14 @@ void __appInit(void) { RegisterPrivilegedProcesses(); /* Use AMS manager extension to tell SM that FS has been worked around. */ - R_ASSERT(sts::sm::manager::EndInitialDefers()); + R_ASSERT(sm::manager::EndInitialDefers()); R_ASSERT(lrInitialize()); R_ASSERT(ldrPmInitialize()); R_ASSERT(splInitialize()); }); - CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); + ams::CheckApiVersion(); } void __appExit(void) { @@ -191,7 +192,7 @@ namespace { int main(int argc, char **argv) { /* Initialize process manager implementation. */ - R_ASSERT(sts::pm::impl::InitializeProcessManager()); + R_ASSERT(pm::impl::InitializeProcessManager()); /* Create Services. */ /* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */ diff --git a/stratosphere/ro/source/impl/ro_service_impl.cpp b/stratosphere/ro/source/impl/ro_service_impl.cpp index cbcb080e3..3f3c478e2 100644 --- a/stratosphere/ro/source/impl/ro_service_impl.cpp +++ b/stratosphere/ro/source/impl/ro_service_impl.cpp @@ -93,8 +93,7 @@ namespace sts::ro::impl { R_ASSERT(svcGetInfo(&title_id.value, InfoType_TitleId, process_h, 0)); } else { /* 1.0.0-2.3.0: We're not inside loader, so ask pm. */ - os::ProcessId process_id = os::InvalidProcessId; - R_ASSERT(svcGetProcessId(&process_id.value, process_h)); + os::ProcessId process_id = os::GetProcessId(process_h); R_ASSERT(pminfoGetTitleId(&title_id.value, process_id.value)); } return title_id; @@ -335,7 +334,7 @@ namespace sts::ro::impl { os::ProcessId handle_pid = os::InvalidProcessId; /* Validate handle is a valid process handle. */ - if (R_FAILED(svcGetProcessId(&handle_pid.value, process_handle))) { + if (R_FAILED(os::TryGetProcessId(&handle_pid, process_handle))) { return ResultRoInvalidProcess; } diff --git a/stratosphere/ro/source/ro_main.cpp b/stratosphere/ro/source/ro_main.cpp index f3f156814..4d33a7d4a 100644 --- a/stratosphere/ro/source/ro_main.cpp +++ b/stratosphere/ro/source/ro_main.cpp @@ -44,8 +44,13 @@ extern "C" { void __appExit(void); } -/* Exception handling. */ -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Ro; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Ro; + +} + +using namespace sts; void __libnx_initheap(void) { void* addr = nx_inner_heap; @@ -59,12 +64,10 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); - DoWithSmSession([&]() { + sm::DoWithSession([&]() { R_ASSERT(setsysInitialize()); R_ASSERT(fsInitialize()); R_ASSERT(splInitialize()); @@ -75,7 +78,7 @@ void __appInit(void) { R_ASSERT(fsdevMountSdmc()); - CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); + ams::CheckApiVersion(); } void __appExit(void) { diff --git a/stratosphere/sm/source/sm_main.cpp b/stratosphere/sm/source/sm_main.cpp index 08f33d020..239c0c6af 100644 --- a/stratosphere/sm/source/sm_main.cpp +++ b/stratosphere/sm/source/sm_main.cpp @@ -45,13 +45,18 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Sm; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Sm; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } @@ -68,7 +73,7 @@ void __libnx_initheap(void) { } void __appInit(void) { - sts::hos::SetVersionForLibnx(); + hos::SetVersionForLibnx(); /* We must do no service setup here, because we are sm. */ } @@ -77,8 +82,6 @@ void __appExit(void) { /* Nothing to clean up, because we're sm. */ } -using namespace sts; - namespace { /* sm:m, sm:, sm:dmnt. */ diff --git a/stratosphere/spl/source/spl_main.cpp b/stratosphere/spl/source/spl_main.cpp index d372891ff..b3ea6a7ec 100644 --- a/stratosphere/spl/source/spl_main.cpp +++ b/stratosphere/spl/source/spl_main.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include "spl_api_impl.hpp" @@ -38,7 +39,7 @@ extern "C" { u32 __nx_applet_type = AppletType_None; - #define INNER_HEAP_SIZE 0x28000 + #define INNER_HEAP_SIZE 0x4000 size_t nx_inner_heap_size = INNER_HEAP_SIZE; char nx_inner_heap[INNER_HEAP_SIZE]; @@ -50,16 +51,20 @@ extern "C" { alignas(16) u8 __nx_exception_stack[0x1000]; u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); void __libnx_exception_handler(ThreadExceptionDump *ctx); - void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx); } -sts::ncm::TitleId __stratosphere_title_id = sts::ncm::TitleId::Spl; +namespace sts::ams { + + ncm::TitleId StratosphereTitleId = ncm::TitleId::Spl; + +} + +using namespace sts; void __libnx_exception_handler(ThreadExceptionDump *ctx) { - StratosphereCrashHandler(ctx); + ams::CrashHandler(ctx); } - void __libnx_initheap(void) { void* addr = nx_inner_heap; size_t size = nx_inner_heap_size; @@ -72,12 +77,12 @@ void __libnx_initheap(void) { fake_heap_end = (char*)addr + size; } -using namespace sts; - void __appInit(void) { hos::SetVersionForLibnx(); /* SPL doesn't really access any services... */ + + ams::CheckApiVersion(); } void __appExit(void) { @@ -149,4 +154,4 @@ int main(int argc, char **argv) g_server_manager.LoopProcess(); return 0; -} \ No newline at end of file +}