diff --git a/stratosphere/fatal/source/ams_logo.hpp b/stratosphere/fatal/source/ams_logo.hpp index 71d965cc5..b7e76b355 100644 --- a/stratosphere/fatal/source/ams_logo.hpp +++ b/stratosphere/fatal/source/ams_logo.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #define AMS_LOGO_WIDTH 0xA0 #define AMS_LOGO_HEIGHT 0x80 diff --git a/stratosphere/fatal/source/fatal_config.cpp b/stratosphere/fatal/source/fatal_config.cpp index 0bd7b2930..adb997008 100644 --- a/stratosphere/fatal/source/fatal_config.cpp +++ b/stratosphere/fatal/source/fatal_config.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_types.hpp" #include "fatal_config.hpp" @@ -38,22 +38,22 @@ IEvent *GetFatalSettingsEvent() { } g_fatal_settings_event = LoadReadOnlySystemEvent(evt.revent, [](u64 timeout) { u64 flags_0, flags_1; - if (R_SUCCEEDED(setsysGetFatalDirtyFlags(&flags_0, &flags_1)) && (flags_0 & 1)) { + if (R_SUCCEEDED(setsysGetFatalDirtyFlags(&flags_0, &flags_1)) && (flags_0 & 1)) { UpdateLanguageCode(); } return ResultSuccess; }, true); } - + return g_fatal_settings_event; } static void SetupConfigLanguages() { FatalConfig *config = GetFatalConfig(); - + /* Defaults. */ config->error_msg = u8"Error Code: 2%03d-%04d (0x%x)\n"; - + if (config->quest_flag) { config->error_desc = u8"Please call 1-800-875-1852 for service.\n"; } else { @@ -64,7 +64,7 @@ static void SetupConfigLanguages() { u8"If the problem persists, refer to the Nintendo Support Website.\n" u8"support.nintendo.com/switch/error\n"; } - + /* TODO: Try to load dynamically. */ /* FsStorage message_storage; */ /* TODO: if (R_SUCCEEDED(fsOpenDataStorageByDataId(0x010000000000081D, "fatal_msg"))) { ... } */ @@ -72,18 +72,18 @@ static void SetupConfigLanguages() { void InitializeFatalConfig() { FatalConfig *config = GetFatalConfig(); - + memset(config, 0, sizeof(*config)); setsysGetSerialNumber(config->serial_number); setsysGetFirmwareVersion(&config->firmware_version); UpdateLanguageCode(); - + setsysGetSettingsItemValue("fatal", "transition_to_fatal", &config->transition_to_fatal, sizeof(config->transition_to_fatal)); setsysGetSettingsItemValue("fatal", "show_extra_info", &config->show_extra_info, sizeof(config->show_extra_info)); setsysGetSettingsItemValue("fatal", "quest_reboot_interval_second", &config->quest_reboot_interval_second, sizeof(config->quest_reboot_interval_second)); - + setsysGetFlag(SetSysFlag_Quest, &config->quest_flag); - + config->is_auto_reboot_enabled = R_SUCCEEDED(setsysGetSettingsItemValue("atmosphere", "fatal_auto_reboot_interval", &config->fatal_auto_reboot_interval, sizeof(config->fatal_auto_reboot_interval))); config->is_auto_reboot_enabled &= (config->fatal_auto_reboot_interval != 0); diff --git a/stratosphere/fatal/source/fatal_config.hpp b/stratosphere/fatal/source/fatal_config.hpp index 6e4c1db7c..2a4eba2d6 100644 --- a/stratosphere/fatal/source/fatal_config.hpp +++ b/stratosphere/fatal/source/fatal_config.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_debug.cpp b/stratosphere/fatal/source/fatal_debug.cpp index 3105549df..d8666a92b 100644 --- a/stratosphere/fatal/source/fatal_debug.cpp +++ b/stratosphere/fatal/source/fatal_debug.cpp @@ -21,20 +21,20 @@ static bool IsAddressReadable(Handle debug_handle, u64 address, u64 size, MemoryInfo *o_mi) { MemoryInfo mi; u32 pi; - + if (o_mi == NULL) { o_mi = &mi; } - + if (R_FAILED(svcQueryDebugProcessMemory(o_mi, &pi, debug_handle, address))) { return false; } - + /* Must be readable */ if ((o_mi->perm & Perm_R) != Perm_R) { return false; } - + /* Must have space for both userdata address and userdata size. */ if (address < o_mi->addr || o_mi->addr + o_mi->size < address + size) { return false; @@ -51,83 +51,83 @@ static bool CheckThreadIsFatalCaller(FatalThrowContext *ctx, u64 debug_handle, u if (R_FAILED(svcGetDebugThreadParam(&_, &thread_state, debug_handle, thread_id, DebugThreadParam_State))) { return false; } - + if (thread_state > 1) { return false; } } - + /* Get the thread context. */ if (R_FAILED(svcGetDebugThreadContext(thread_ctx, debug_handle, thread_id, 0xF))) { return false; } - + /* Check if PC is readable. */ if (!IsAddressReadable(debug_handle, thread_ctx->pc.x, sizeof(u32), NULL)) { return false; } - + /* Try to read the current instruction. */ u32 insn; if (R_FAILED(svcReadDebugProcessMemory(&insn, debug_handle, thread_ctx->pc.x, sizeof(insn)))) { return false; } - + /* If the instruction isn't svcSendSyncRequest, it's not the fatal caller. */ if (insn != 0xD4000421) { return false; } - + /* The fatal caller will have readable tls. */ if (!IsAddressReadable(debug_handle, thread_tls_addr, 0x100, NULL)) { return false; } - + /* Read in the fatal caller's tls. */ u8 thread_tls[0x100]; if (R_FAILED(svcReadDebugProcessMemory(thread_tls, debug_handle, thread_tls_addr, sizeof(thread_tls)))) { return false; } - + /* Replace our tls with the fatal caller's. */ std::memcpy(armGetTls(), thread_tls, sizeof(thread_tls)); - + /* Parse the command that the thread sent. */ { IpcParsedCommand r; if (R_FAILED(ipcParse(&r))) { return false; } - + /* Fatal command takes in a PID, only one buffer max. */ if (!r.HasPid || r.NumStatics || r.NumStaticsOut || r.NumHandles) { return false; } - + struct { u32 magic; u32 version; u64 cmd_id; u32 err_code; } *raw = (decltype(raw))(r.Raw); - + if (raw->magic != SFCI_MAGIC) { return false; } - + if (raw->cmd_id > 2) { return false; } - + if (raw->cmd_id != 2 && r.NumBuffers) { return false; } - + if (raw->err_code != ctx->error_code) { return false; } } - + /* We found our caller. */ return true; } @@ -137,7 +137,7 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { if (R_SUCCEEDED(svcDebugActiveProcess(&debug_handle, pid))) { /* Ensure we close the debugged process. */ ON_SCOPE_EXIT { svcCloseHandle(debug_handle); }; - + /* First things first, check if process is 64 bits, and get list of thread infos. */ std::unordered_map thread_id_to_tls; { @@ -152,17 +152,17 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { thread_id_to_tls[d.info.attach_thread.thread_id] = d.info.attach_thread.tls_address; } } - + if (!got_attach_process) { return; } } - + /* TODO: Try to collect information on 32-bit fatals. This shouldn't really matter for any real use case. */ if (ctx->cpu_ctx.is_aarch32) { return; } - + /* Welcome to hell. */ bool found_fatal_caller = false; u64 thread_id = 0; @@ -174,14 +174,14 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { if (R_FAILED(svcGetThreadList(&thread_count, thread_ids, 0x60, debug_handle))) { return; } - + /* We need to locate the thread that's called fatal. */ for (u32 i = 0; i < thread_count; i++) { const u64 cur_thread_id = thread_ids[i]; if (thread_id_to_tls.find(cur_thread_id) == thread_id_to_tls.end()) { continue; } - + if (CheckThreadIsFatalCaller(ctx, debug_handle, cur_thread_id, thread_id_to_tls[cur_thread_id], &thread_ctx)) { thread_id = cur_thread_id; found_fatal_caller = true; @@ -195,7 +195,7 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { if (R_FAILED(svcGetDebugThreadContext(&thread_ctx, debug_handle, thread_id, 0xF))) { return; } - + /* So we found our caller. */ for (u32 i = 0; i < 29; i++) { /* GetDebugThreadContext won't give us any of these registers, because thread is in SVC :( */ @@ -208,7 +208,7 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { ctx->cpu_ctx.aarch64_ctx.lr = thread_ctx.lr; ctx->cpu_ctx.aarch64_ctx.sp = thread_ctx.sp; ctx->cpu_ctx.aarch64_ctx.pc = thread_ctx.pc.x; - + /* Parse a stack trace. */ u64 cur_fp = thread_ctx.fp; @@ -217,18 +217,18 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { if (cur_fp == 0 || (cur_fp & 0xF)) { break; } - + /* Read a new frame. */ StackFrame cur_frame; if (R_FAILED(svcReadDebugProcessMemory(&cur_frame, debug_handle, cur_fp, sizeof(StackFrame)))) { break; } - + /* Advance to the next frame. */ ctx->cpu_ctx.aarch64_ctx.stack_trace[ctx->cpu_ctx.aarch64_ctx.stack_trace_size++] = cur_frame.lr; cur_fp = cur_frame.fp; } - + /* Try to read up to 0x100 of stack. */ for (size_t sz = 0x100; sz > 0; sz -= 0x10) { if (IsAddressReadable(debug_handle, ctx->cpu_ctx.aarch64_ctx.sp, sz, nullptr)) { @@ -246,25 +246,25 @@ void TryCollectDebugInformation(FatalThrowContext *ctx, u64 pid) { if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess)) || mi.perm != Perm_Rx) { return false; } - + /* Iterate backwards until we find the memory before the code region. */ while (mi.addr > 0) { if (R_FAILED(svcQueryDebugProcessMemory(&mi, &pi, debug_handle, guess))) { return false; } - + if (mi.type == MemType_Unmapped) { /* Code region will be at the end of the unmapped region preceding it. */ ctx->cpu_ctx.aarch64_ctx.start_address = mi.addr + mi.size; return true; } - + guess -= 4; } return false; }; - + /* Parse the starting address. */ { if (TryGuessStartAddress(thread_ctx.pc.x)) { diff --git a/stratosphere/fatal/source/fatal_debug.hpp b/stratosphere/fatal/source/fatal_debug.hpp index 66202fb2e..4166aa178 100644 --- a/stratosphere/fatal/source/fatal_debug.hpp +++ b/stratosphere/fatal/source/fatal_debug.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_event_manager.cpp b/stratosphere/fatal/source/fatal_event_manager.cpp index 4906a4403..1003ef115 100644 --- a/stratosphere/fatal/source/fatal_event_manager.cpp +++ b/stratosphere/fatal/source/fatal_event_manager.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_types.hpp" #include "fatal_event_manager.hpp" @@ -35,12 +35,12 @@ FatalEventManager::FatalEventManager() { Result FatalEventManager::GetEvent(Handle *out) { std::scoped_lock lk{this->lock}; - + /* Only allow GetEvent to succeed NumFatalEvents times. */ if (this->events_gotten >= FatalEventManager::NumFatalEvents) { return ResultFatalTooManyEvents; } - + *out = this->events[this->events_gotten++].revent; return ResultSuccess; } diff --git a/stratosphere/fatal/source/fatal_event_manager.hpp b/stratosphere/fatal/source/fatal_event_manager.hpp index 20448ae8c..6d12ac1f1 100644 --- a/stratosphere/fatal/source/fatal_event_manager.hpp +++ b/stratosphere/fatal/source/fatal_event_manager.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include @@ -21,7 +21,7 @@ class FatalEventManager { private: static constexpr size_t NumFatalEvents = 3; - + HosMutex lock; size_t events_gotten = 0; Event events[NumFatalEvents]; diff --git a/stratosphere/fatal/source/fatal_font.cpp b/stratosphere/fatal/source/fatal_font.cpp index 676def64a..3ad9b538b 100644 --- a/stratosphere/fatal/source/fatal_font.cpp +++ b/stratosphere/fatal/source/fatal_font.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_types.hpp" @@ -49,11 +49,11 @@ static u16 Blend(u16 color, u16 bg, u8 alpha) { const u32 b_r = RGB565_GET_R8(bg); const u32 b_g = RGB565_GET_G8(bg); const u32 b_b = RGB565_GET_B8(bg); - + const u32 r = ((alpha * c_r) + ((0xFF - alpha) * b_r)) / 0xFF; const u32 g = ((alpha * c_g) + ((0xFF - alpha) * b_g)) / 0xFF; const u32 b = ((alpha * c_b) + ((0xFF - alpha) * b_b)) / 0xFF; - + return RGB888_TO_RGB565(r, g, b); } @@ -61,7 +61,7 @@ static void DrawGlyph(FT_Bitmap *bitmap, u32 x, u32 y) { u8* imageptr = bitmap->buffer; if (bitmap->pixel_mode!=FT_PIXEL_MODE_GRAY) return; - + for (u32 tmpy = 0; tmpy < bitmap->rows; tmpy++) { for (u32 tmpx = 0; tmpx < bitmap->width; tmpx++) { /* Implement very simple blending, as the bitmap value is an alpha value. */ @@ -75,47 +75,47 @@ static void DrawGlyph(FT_Bitmap *bitmap, u32 x, u32 y) { static void DrawString(const char *str, bool add_line, bool mono = false) { FT_UInt glyph_index; FT_GlyphSlot slot = g_face->glyph; - + const size_t len = strlen(str); - + u32 cur_x = g_cur_x, cur_y = g_cur_y; - ON_SCOPE_EXIT { + ON_SCOPE_EXIT { if (add_line) { /* Advance to next line. */ g_cur_x = g_line_x; - g_cur_y = cur_y + (g_face->size->metrics.height >> 6); + g_cur_y = cur_y + (g_face->size->metrics.height >> 6); } else { g_cur_x = cur_x; g_cur_y = cur_y; } }; - + for (u32 i = 0; i < len; ) { u32 cur_char; ssize_t unit_count = decode_utf8(&cur_char, reinterpret_cast(&str[i])); if (unit_count <= 0) break; i += unit_count; - + if (cur_char == '\n') { cur_x = g_line_x; cur_y += g_face->size->metrics.height >> 6; continue; } - + glyph_index = FT_Get_Char_Index(g_face, cur_char); - + g_ft_err = FT_Load_Glyph(g_face, glyph_index, FT_LOAD_DEFAULT); - + if (g_ft_err == 0) { g_ft_err = FT_Render_Glyph(g_face->glyph, FT_RENDER_MODE_NORMAL); } - + if (g_ft_err) { return; } - + DrawGlyph(&slot->bitmap, cur_x + slot->bitmap_left + ((mono && g_mono_adv > slot->advance.x) ? ((g_mono_adv - slot->advance.x) >> 7) : 0), cur_y - slot->bitmap_top); - + cur_x += (mono ? g_mono_adv : slot->advance.x) >> 6; cur_y += slot->advance.y >> 6; } @@ -151,17 +151,17 @@ void FontManager::PrintFormat(const char *format, ...) { Print(char_buf); } -void FontManager::PrintMonospaceU64(u64 x) { +void FontManager::PrintMonospaceU64(u64 x) { char char_buf[0x400]; snprintf(char_buf, sizeof(char_buf), "%016lX", x); - + DrawString(char_buf, false, true); } -void FontManager::PrintMonospaceU32(u32 x) { +void FontManager::PrintMonospaceU32(u32 x) { char char_buf[0x400]; snprintf(char_buf, sizeof(char_buf), "%08X", x); - + DrawString(char_buf, false, true); } @@ -170,7 +170,7 @@ void FontManager::PrintMonospaceBlank(u32 width) { for (size_t i = 0; i < width && i < sizeof(char_buf); i++) { char_buf[i] = ' '; } - + DrawString(char_buf, false, true); } @@ -195,9 +195,9 @@ u32 FontManager::GetY() { void FontManager::SetFontSize(float fsz) { g_font_sz = fsz; g_ft_err = FT_Set_Char_Size(g_face, 0, static_cast(g_font_sz * 64.0f), 96, 96); - + g_ft_err = FT_Load_Glyph(g_face, FT_Get_Char_Index(g_face, 'A'), FT_LOAD_DEFAULT); - + if (g_ft_err == 0) { g_ft_err = FT_Render_Glyph(g_face->glyph, FT_RENDER_MODE_NORMAL); } @@ -217,23 +217,17 @@ void FontManager::ConfigureFontFramebuffer(u16 *fb, u32 (*unswizzle_func)(u32, u } Result FontManager::InitializeSharedFont() { - Result rc; size_t total_fonts = 0; - - if (R_FAILED((rc = plGetSharedFont(GetFatalConfig()->language_code, g_fonts, PlSharedFontType_Total, &total_fonts)))) { - return rc; - } - if (R_FAILED((rc = plGetSharedFontByType(&g_font, PlSharedFontType_Standard)))) { - return rc; - } - + R_TRY(plGetSharedFont(GetFatalConfig()->language_code, g_fonts, PlSharedFontType_Total, &total_fonts)); + R_TRY(plGetSharedFontByType(&g_font, PlSharedFontType_Standard)); + g_ft_err = FT_Init_FreeType(&g_library); if (g_ft_err) return g_ft_err; - + g_ft_err = FT_New_Memory_Face(g_library, reinterpret_cast(g_font.address), g_font.size, 0, &g_face); if (g_ft_err) return g_ft_err; - + SetFontSize(g_font_sz); return g_ft_err; } \ No newline at end of file diff --git a/stratosphere/fatal/source/fatal_font.hpp b/stratosphere/fatal/source/fatal_font.hpp index b3fc666b3..e8b89b89e 100644 --- a/stratosphere/fatal/source/fatal_font.hpp +++ b/stratosphere/fatal/source/fatal_font.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include @@ -24,7 +24,7 @@ #define RGB565_GET_G8(c) ((((c >> 5) & 0x3F) << 2) | ((c >> 9) & 3)) #define RGB565_GET_B8(c) ((((c >> 0) & 0x1F) << 3) | ((c >> 2) & 7)) -class FontManager { +class FontManager { public: static Result InitializeSharedFont(); static void ConfigureFontFramebuffer(u16 *fb, u32 (*unswizzle_func)(u32, u32)); diff --git a/stratosphere/fatal/source/fatal_private.cpp b/stratosphere/fatal/source/fatal_private.cpp index 785c909dc..c33518100 100644 --- a/stratosphere/fatal/source/fatal_private.cpp +++ b/stratosphere/fatal/source/fatal_private.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_private.hpp" #include "fatal_event_manager.hpp" diff --git a/stratosphere/fatal/source/fatal_private.hpp b/stratosphere/fatal/source/fatal_private.hpp index 428e331d5..143e10c15 100644 --- a/stratosphere/fatal/source/fatal_private.hpp +++ b/stratosphere/fatal/source/fatal_private.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_repair.cpp b/stratosphere/fatal/source/fatal_repair.cpp index 02bf336bd..3fd738d3e 100644 --- a/stratosphere/fatal/source/fatal_repair.cpp +++ b/stratosphere/fatal/source/fatal_repair.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include "fatal_types.hpp" @@ -24,21 +24,21 @@ static bool InRepairWithoutVolHeld() { if (GetRuntimeFirmwareVersion() < FirmwareVersion_300) { return false; } - + bool in_repair; if (R_FAILED(setsysGetFlag(SetSysFlag_InRepairProcessEnable, &in_repair)) || !in_repair) { return false; } - + { GpioPadSession vol_btn; if (R_FAILED(gpioOpenSession(&vol_btn, GpioPadName_ButtonVolUp))) { return true; } - + /* Ensure we close even on early return. */ ON_SCOPE_EXIT { gpioPadClose(&vol_btn); }; - + /* Set direction input. */ gpioPadSetDirection(&vol_btn, GpioDirection_Input); @@ -49,12 +49,12 @@ static bool InRepairWithoutVolHeld() { if (R_FAILED(gpioPadGetValue(&vol_btn, &val)) || val != GpioValue_Low) { return true; } - + /* Sleep for 100 ms. */ svcSleepThread(100000000UL); } } - + return false; } @@ -62,12 +62,12 @@ static bool InRepairWithoutTimeReviserCartridge() { if (GetRuntimeFirmwareVersion() < FirmwareVersion_500) { return false; } - + bool requires_time_reviser; if (R_FAILED(setsysGetFlag(SetSysFlag_RequiresRunRepairTimeReviser, &requires_time_reviser)) || !requires_time_reviser) { return false; } - + FsGameCardHandle gc_hnd; u8 gc_attr; { @@ -75,22 +75,22 @@ static bool InRepairWithoutTimeReviserCartridge() { if (R_FAILED(fsOpenDeviceOperator(&devop))) { return true; } - + /* Ensure we close even on early return. */ ON_SCOPE_EXIT { fsDeviceOperatorClose(&devop); }; - + /* Check that a gamecard is inserted. */ bool inserted; if (R_FAILED(fsDeviceOperatorIsGameCardInserted(&devop, &inserted)) || !inserted) { return true; } - + /* Check that we can retrieve the gamecard's attributes. */ if (R_FAILED(fsDeviceOperatorGetGameCardHandle(&devop, &gc_hnd)) || R_FAILED(fsDeviceOperatorGetGameCardAttribute(&devop, &gc_hnd, &gc_attr))) { return true; } } - + /* Check that the gamecard is a repair tool. */ return (gc_attr & FsGameCardAttribute_Repair) == FsGameCardAttribute_Repair; } @@ -99,7 +99,7 @@ void CheckRepairStatus() { if (InRepairWithoutVolHeld()) { ThrowFatalForSelf(ResultFatalInRepairWithoutVolHeld); } - + if (InRepairWithoutTimeReviserCartridge()) { ThrowFatalForSelf(ResultFatalInRepairWithoutTimeReviserCartridge); } diff --git a/stratosphere/fatal/source/fatal_repair.hpp b/stratosphere/fatal/source/fatal_repair.hpp index 792e3ae63..47f068348 100644 --- a/stratosphere/fatal/source/fatal_repair.hpp +++ b/stratosphere/fatal/source/fatal_repair.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_task.cpp b/stratosphere/fatal/source/fatal_task.cpp index 7fbe17617..dd3cf9b36 100644 --- a/stratosphere/fatal/source/fatal_task.cpp +++ b/stratosphere/fatal/source/fatal_task.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_types.hpp" #include "fatal_task.hpp" @@ -32,22 +32,22 @@ static size_t g_num_threads = 0; static void RunTaskThreadFunc(void *arg) { IFatalTask *task = reinterpret_cast(arg); - + Result rc = task->Run(); if (R_FAILED(rc)) { /* TODO: Log task failure, somehow? */ } - + /* Finish. */ } -static void RunTask(IFatalTask *task, u32 stack_size = 0x4000) { +static void RunTask(IFatalTask *task, u32 stack_size = 0x4000) { if (g_num_threads >= MaxTasks) { std::abort(); } - + HosThread *cur_thread = &g_task_threads[g_num_threads++]; - + cur_thread->Initialize(&RunTaskThreadFunc, task, stack_size, 15); cur_thread->Start(); } diff --git a/stratosphere/fatal/source/fatal_task.hpp b/stratosphere/fatal/source/fatal_task.hpp index 31c3ce8d0..407e78e82 100644 --- a/stratosphere/fatal/source/fatal_task.hpp +++ b/stratosphere/fatal/source/fatal_task.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_task_clock.cpp b/stratosphere/fatal/source/fatal_task_clock.cpp index 6fe9a849f..ba345e6b5 100644 --- a/stratosphere/fatal/source/fatal_task_clock.cpp +++ b/stratosphere/fatal/source/fatal_task_clock.cpp @@ -13,34 +13,27 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_task_clock.hpp" Result AdjustClockTask::AdjustClockForModule(PcvModule module, u32 hz) { - Result rc; - if (GetRuntimeFirmwareVersion() >= FirmwareVersion_800) { /* On 8.0.0+, convert to module id + use clkrst API. */ PcvModuleId module_id; - if (R_FAILED((rc = pcvGetModuleId(&module_id, module)))) { - return rc; - } + R_TRY(pcvGetModuleId(&module_id, module)); ClkrstSession session; - Result rc = clkrstOpenSession(&session, module_id, 3); - if (R_FAILED(rc)) { - return rc; - } + R_TRY(clkrstOpenSession(&session, module_id, 3)); ON_SCOPE_EXIT { clkrstCloseSession(&session); }; - rc = clkrstSetClockRate(&session, hz); + R_TRY(clkrstSetClockRate(&session, hz)); } else { /* On 1.0.0-7.0.1, use pcv API. */ - rc = pcvSetClockRate(module, hz); + R_TRY(pcvSetClockRate(module, hz)); } - return rc; + return ResultSuccess; } Result AdjustClockTask::AdjustClock() { @@ -48,23 +41,14 @@ Result AdjustClockTask::AdjustClock() { constexpr u32 CPU_CLOCK_1020MHZ = 0x3CCBF700L; constexpr u32 GPU_CLOCK_307MHZ = 0x124F8000L; constexpr u32 EMC_CLOCK_1331MHZ = 0x4F588000L; - Result rc = ResultSuccess; - if (R_FAILED((rc = AdjustClockForModule(PcvModule_CpuBus, CPU_CLOCK_1020MHZ)))) { - return rc; - } + R_TRY(AdjustClockForModule(PcvModule_CpuBus, CPU_CLOCK_1020MHZ)); + R_TRY(AdjustClockForModule(PcvModule_GPU, GPU_CLOCK_307MHZ)); + R_TRY(AdjustClockForModule(PcvModule_EMC, EMC_CLOCK_1331MHZ)); - if (R_FAILED((rc = AdjustClockForModule(PcvModule_GPU, GPU_CLOCK_307MHZ)))) { - return rc; - } - - if (R_FAILED((rc = AdjustClockForModule(PcvModule_EMC, EMC_CLOCK_1331MHZ)))) { - return rc; - } - - return rc; + return ResultSuccess; } Result AdjustClockTask::Run() { return AdjustClock(); -} \ No newline at end of file +} diff --git a/stratosphere/fatal/source/fatal_task_clock.hpp b/stratosphere/fatal/source/fatal_task_clock.hpp index 942196cad..573cd8739 100644 --- a/stratosphere/fatal/source/fatal_task_clock.hpp +++ b/stratosphere/fatal/source/fatal_task_clock.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_task_error_report.cpp b/stratosphere/fatal/source/fatal_task_error_report.cpp index 9efcb3e12..01f232e4a 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.cpp +++ b/stratosphere/fatal/source/fatal_task_error_report.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include @@ -24,7 +24,7 @@ #include "fatal_config.hpp" void ErrorReportTask::EnsureReportDirectories() { - char path[FS_MAX_PATH]; + char path[FS_MAX_PATH]; strcpy(path, "sdmc:/atmosphere"); mkdir(path, S_IRWXU); strcat(path, "/fatal_reports"); @@ -35,7 +35,7 @@ void ErrorReportTask::EnsureReportDirectories() { bool ErrorReportTask::GetCurrentTime(u64 *out) { *out = 0; - + /* Verify that pcv isn't dead. */ { bool has_time_service; @@ -52,7 +52,7 @@ bool ErrorReportTask::GetCurrentTime(u64 *out) { return false; } } - + /* Try to get the current time. */ bool success = true; DoWithSmSession([&]() { @@ -67,22 +67,22 @@ bool ErrorReportTask::GetCurrentTime(u64 *out) { void ErrorReportTask::SaveReportToSdCard() { char file_path[FS_MAX_PATH]; - + /* Ensure path exists. */ EnsureReportDirectories(); - + /* Get a timestamp. */ u64 timestamp; if (!GetCurrentTime(×tamp)) { timestamp = svcGetSystemTick(); } - + /* Open report file. */ snprintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, this->title_id); FILE *f_report = fopen(file_path, "w"); if (f_report != NULL) { ON_SCOPE_EXIT { fclose(f_report); }; - + fprintf(f_report, "Atmosphère Fatal Report (v1.0):\n"); fprintf(f_report, "Result: 0x%X (2%03d-%04d)\n\n", this->ctx->error_code, R_MODULE(this->ctx->error_code), R_DESCRIPTION(this->ctx->error_code)); fprintf(f_report, "Title ID: %016lx\n", this->title_id); @@ -90,7 +90,7 @@ void ErrorReportTask::SaveReportToSdCard() { fprintf(f_report, "Process Name: %s\n", this->ctx->proc_name); } fprintf(f_report, u8"Firmware: %s (Atmosphère %u.%u.%u-%s)\n", GetFatalConfig()->firmware_version.display_version, CURRENT_ATMOSPHERE_VERSION, GetAtmosphereGitRevision()); - + if (this->ctx->cpu_ctx.is_aarch32) { fprintf(f_report, "General Purpose Registers:\n"); for (size_t i = 0; i < NumAarch32Gprs; i++) { @@ -118,15 +118,15 @@ void ErrorReportTask::SaveReportToSdCard() { fprintf(f_report, " ReturnAddress[%02u]: %016lx\n", i, this->ctx->cpu_ctx.aarch64_ctx.stack_trace[i]); } } - + } - + if (this->ctx->stack_dump_size) { snprintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, this->title_id); FILE *f_stackdump = fopen(file_path, "wb"); if (f_stackdump == NULL) { return; } ON_SCOPE_EXIT { fclose(f_stackdump); }; - + fwrite(this->ctx->stack_dump, this->ctx->stack_dump_size, 1, f_stackdump); } } @@ -135,15 +135,15 @@ Result ErrorReportTask::Run() { if (this->create_report) { /* Here, Nintendo creates an error report with erpt. AMS will not do that. */ } - + /* Save report to SD card. */ if (!this->ctx->is_creport) { SaveReportToSdCard(); } - + /* Signal we're done with our job. */ eventFire(this->erpt_event); - - + + return ResultSuccess; } \ No newline at end of file diff --git a/stratosphere/fatal/source/fatal_task_error_report.hpp b/stratosphere/fatal/source/fatal_task_error_report.hpp index f4c2d1a51..8cfbafb1c 100644 --- a/stratosphere/fatal/source/fatal_task_error_report.hpp +++ b/stratosphere/fatal/source/fatal_task_error_report.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_task_power.cpp b/stratosphere/fatal/source/fatal_task_power.cpp index 4f9117804..2813d0468 100644 --- a/stratosphere/fatal/source/fatal_task_power.cpp +++ b/stratosphere/fatal/source/fatal_task_power.cpp @@ -13,35 +13,35 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_task_power.hpp" #include "fatal_config.hpp" bool PowerControlTask::TryShutdown() { /* Set a timeout of 30 seconds. */ - TimeoutHelper timeout_helper(30000000000UL); + TimeoutHelper timeout_helper(30000000000UL); bool cancel_shutdown = false; PsmBatteryVoltageState bv_state = PsmBatteryVoltageState_Normal; - + while (true) { if (timeout_helper.TimedOut()) { break; } - + if (R_FAILED(psmGetBatteryVoltageState(&bv_state)) || bv_state == PsmBatteryVoltageState_NeedsShutdown) { break; } - + if (bv_state == PsmBatteryVoltageState_Normal) { cancel_shutdown = true; break; } - + /* Query voltage state every 5 seconds, for 30 seconds. */ svcSleepThread(5000000000UL); } - + if (!cancel_shutdown) { bpcShutdownSystem(); return true; @@ -52,7 +52,7 @@ bool PowerControlTask::TryShutdown() { void PowerControlTask::MonitorBatteryState() { PsmBatteryVoltageState bv_state = PsmBatteryVoltageState_Normal; - + /* Check the battery state, and shutdown on low voltage. */ if (R_FAILED(psmGetBatteryVoltageState(&bv_state)) || bv_state == PsmBatteryVoltageState_NeedsShutdown) { /* Wait a second for the error report task to finish. */ @@ -60,15 +60,15 @@ void PowerControlTask::MonitorBatteryState() { this->TryShutdown(); return; } - + /* Signal we've checked the battery at least once. */ eventFire(this->battery_event); - + while (true) { if (R_FAILED(psmGetBatteryVoltageState(&bv_state))) { bv_state = PsmBatteryVoltageState_NeedsShutdown; } - + switch (bv_state) { case PsmBatteryVoltageState_NeedsShutdown: case PsmBatteryVoltageState_NeedsSleep: @@ -82,7 +82,7 @@ void PowerControlTask::MonitorBatteryState() { default: break; } - + /* Query voltage state every 5 seconds. */ svcSleepThread(5000000000UL); } @@ -91,13 +91,13 @@ void PowerControlTask::MonitorBatteryState() { void PowerButtonObserveTask::WaitForPowerButton() { /* Wait up to a second for error report generation to finish. */ eventWait(this->erpt_event, TimeoutHelper::NsToTick(1000000000UL)); - + /* Force a reboot after some time if kiosk unit. */ const FatalConfig *config = GetFatalConfig(); TimeoutHelper reboot_helper(config->quest_reboot_interval_second * 1000000000UL); - + TimeoutHelper auto_reboot_helper(config->fatal_auto_reboot_interval * 1000000); - + bool check_vol_up = true, check_vol_down = true; GpioPadSession vol_up_btn, vol_down_btn; if (R_FAILED(gpioOpenSession(&vol_up_btn, GpioPadName_ButtonVolUp))) { @@ -106,11 +106,11 @@ void PowerButtonObserveTask::WaitForPowerButton() { if (R_FAILED(gpioOpenSession(&vol_down_btn, GpioPadName_ButtonVolDown))) { check_vol_down = false; } - + /* Ensure we close on early return. */ ON_SCOPE_EXIT { if (check_vol_up) { gpioPadClose(&vol_up_btn); } }; ON_SCOPE_EXIT { if (check_vol_down) { gpioPadClose(&vol_down_btn); } }; - + /* Set direction input. */ if (check_vol_up) { gpioPadSetDirection(&vol_up_btn, GpioDirection_Input); @@ -118,7 +118,7 @@ void PowerButtonObserveTask::WaitForPowerButton() { if (check_vol_down) { gpioPadSetDirection(&vol_down_btn, GpioDirection_Input); } - + BpcSleepButtonState state; GpioValue val; while (true) { @@ -128,20 +128,20 @@ void PowerButtonObserveTask::WaitForPowerButton() { bpcRebootSystem(); return; } - + if (check_vol_up && R_SUCCEEDED((rc = gpioPadGetValue(&vol_up_btn, &val))) && val == GpioValue_Low) { bpcRebootSystem(); } - + if (check_vol_down && R_SUCCEEDED((rc = gpioPadGetValue(&vol_down_btn, &val))) && val == GpioValue_Low) { bpcRebootSystem(); } - + if ((R_SUCCEEDED(rc = bpcGetSleepButtonState(&state)) && state == BpcSleepButtonState_Held) || (config->quest_flag && reboot_helper.TimedOut())) { bpcRebootSystem(); return; } - + /* Wait 100 ms between button checks. */ svcSleepThread(100000000UL); } diff --git a/stratosphere/fatal/source/fatal_task_power.hpp b/stratosphere/fatal/source/fatal_task_power.hpp index 98fcab932..7c767bbd3 100644 --- a/stratosphere/fatal/source/fatal_task_power.hpp +++ b/stratosphere/fatal/source/fatal_task_power.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_task_screen.cpp b/stratosphere/fatal/source/fatal_task_screen.cpp index 7202197ee..a1fa670c8 100644 --- a/stratosphere/fatal/source/fatal_task_screen.cpp +++ b/stratosphere/fatal/source/fatal_task_screen.cpp @@ -43,92 +43,69 @@ u32 GetPixelOffset(uint32_t x, uint32_t y) } Result ShowFatalTask::SetupDisplayInternal() { - Result rc; ViDisplay display; /* Try to open the display. */ - if (R_FAILED((rc = viOpenDisplay("Internal", &display)))) { - if (rc == ResultViNotFound) { + R_TRY_CATCH(viOpenDisplay("Internal", &display)) { + R_CATCH(ResultViNotFound) { return ResultSuccess; - } else { - return rc; } - } + } R_END_TRY_CATCH; + /* Guarantee we close the display. */ ON_SCOPE_EXIT { viCloseDisplay(&display); }; /* Turn on the screen. */ - if (R_FAILED((rc = viSetDisplayPowerState(&display, ViPowerState_On)))) { - return rc; - } + R_TRY(viSetDisplayPowerState(&display, ViPowerState_On)); /* Set alpha to 1.0f. */ - if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) { - return rc; - } + R_TRY(viSetDisplayAlpha(&display, 1.0f)); - return rc; + return ResultSuccess; } Result ShowFatalTask::SetupDisplayExternal() { - Result rc; ViDisplay display; /* Try to open the display. */ - if (R_FAILED((rc = viOpenDisplay("External", &display)))) { - if (rc == ResultViNotFound) { + R_TRY_CATCH(viOpenDisplay("External", &display)) { + R_CATCH(ResultViNotFound) { return ResultSuccess; - } else { - return rc; } - } + } R_END_TRY_CATCH; + /* Guarantee we close the display. */ ON_SCOPE_EXIT { viCloseDisplay(&display); }; /* Set alpha to 1.0f. */ - if (R_FAILED((rc = viSetDisplayAlpha(&display, 1.0f)))) { - return rc; - } + R_TRY(viSetDisplayAlpha(&display, 1.0f)); - return rc; + return ResultSuccess; } Result ShowFatalTask::PrepareScreenForDrawing() { - Result rc = ResultSuccess; - /* Connect to vi. */ - if (R_FAILED((rc = viInitialize(ViServiceType_Manager)))) { - return rc; - } + R_TRY(viInitialize(ViServiceType_Manager)); /* Close other content. */ viSetContentVisibility(false); /* Setup the two displays. */ - if (R_FAILED((rc = SetupDisplayInternal())) || R_FAILED((rc = SetupDisplayExternal()))) { - return rc; - } + R_TRY(SetupDisplayInternal()); + R_TRY(SetupDisplayExternal()); /* Open the default display. */ - if (R_FAILED((rc = viOpenDefaultDisplay(&this->display)))) { - return rc; - } + R_TRY(viOpenDefaultDisplay(&this->display)); /* Reset the display magnification to its default value. */ u32 display_width, display_height; - if (R_FAILED((rc = viGetDisplayLogicalResolution(&this->display, &display_width, &display_height)))) { - return rc; - } + R_TRY(viGetDisplayLogicalResolution(&this->display, &display_width, &display_height)); /* viSetDisplayMagnification was added in 3.0.0. */ if (GetRuntimeFirmwareVersion() >= FirmwareVersion_300) { - if (R_FAILED((rc = viSetDisplayMagnification(&this->display, 0, 0, display_width, display_height)))) { - return rc; - } + R_TRY(viSetDisplayMagnification(&this->display, 0, 0, display_width, display_height)); } /* Create layer to draw to. */ - if (R_FAILED((rc = viCreateLayer(&this->display, &this->layer)))) { - return rc; - } + R_TRY(viCreateLayer(&this->display, &this->layer)); /* Setup the layer. */ { @@ -144,47 +121,36 @@ Result ShowFatalTask::PrepareScreenForDrawing() { const float layer_y = static_cast((display_height - layer_height) / 2); u64 layer_z; - if (R_FAILED((rc = viSetLayerSize(&this->layer, layer_width, layer_height)))) { - return rc; - } + R_TRY(viSetLayerSize(&this->layer, layer_width, layer_height)); /* Set the layer's Z at display maximum, to be above everything else .*/ /* NOTE: Fatal hardcodes 100 here. */ - if (R_SUCCEEDED((rc = viGetDisplayMaximumZ(&this->display, &layer_z)))) { - if (R_FAILED((rc = viSetLayerZ(&this->layer, layer_z)))) { - return rc; - } + if (R_SUCCEEDED(viGetDisplayMaximumZ(&this->display, &layer_z))) { + R_TRY(viSetLayerZ(&this->layer, layer_z)); } /* Center the layer in the screen. */ - if (R_FAILED((rc = viSetLayerPosition(&this->layer, layer_x, layer_y)))) { - return rc; - } + R_TRY(viSetLayerPosition(&this->layer, layer_x, layer_y)); /* Create framebuffer. */ - if (R_FAILED(rc = nwindowCreateFromLayer(&this->win, &this->layer))) { - return rc; - } - if (R_FAILED(rc = framebufferCreate(&this->fb, &this->win, raw_width, raw_height, PIXEL_FORMAT_RGB_565, 1))) { - return rc; - } + R_TRY(nwindowCreateFromLayer(&this->win, &this->layer)); + R_TRY(framebufferCreate(&this->fb, &this->win, raw_width, raw_height, PIXEL_FORMAT_RGB_565, 1)); } - - return rc; + return ResultSuccess; } Result ShowFatalTask::ShowFatal() { - Result rc = ResultSuccess; const FatalConfig *config = GetFatalConfig(); + /* Prepare screen for drawing. */ DoWithSmSession([&]() { - rc = PrepareScreenForDrawing(); + Result rc = PrepareScreenForDrawing(); + if (R_FAILED(rc)) { + *(volatile u32 *)(0xCAFEBABE) = rc; + std::abort(); + } }); - if (R_FAILED(rc)) { - *(volatile u32 *)(0xCAFEBABE) = rc; - return rc; - } /* Dequeue a buffer. */ u16 *tiled_buf = reinterpret_cast(framebufferBegin(&this->fb, NULL)); @@ -407,7 +373,7 @@ Result ShowFatalTask::ShowFatal() { /* Enqueue the buffer. */ framebufferEnd(&fb); - return rc; + return ResultSuccess; } Result ShowFatalTask::Run() { diff --git a/stratosphere/fatal/source/fatal_task_screen.hpp b/stratosphere/fatal/source/fatal_task_screen.hpp index 077c50fab..1c96a6f5d 100644 --- a/stratosphere/fatal/source/fatal_task_screen.hpp +++ b/stratosphere/fatal/source/fatal_task_screen.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_task_sound.cpp b/stratosphere/fatal/source/fatal_task_sound.cpp index dc2dbbec2..64e7e845e 100644 --- a/stratosphere/fatal/source/fatal_task_sound.cpp +++ b/stratosphere/fatal/source/fatal_task_sound.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_task_sound.hpp" @@ -40,17 +40,17 @@ void StopSoundTask::StopSound() { cmd.dev = 0xC802; cmd.val = 200; i2csessionSendAuto(&audio, &cmd, sizeof(cmd), I2cTransactionOption_All); - + for (u16 dev = 97; dev <= 102; dev++) { cmd.dev = dev; cmd.val = 0; i2csessionSendAuto(&audio, &cmd, sizeof(cmd), I2cTransactionOption_All); } - + i2csessionClose(&audio); } } - + /* Talk to the ALC5639 over GPIO, and disable audio output */ { GpioPadSession audio; @@ -58,10 +58,10 @@ void StopSoundTask::StopSound() { /* Set direction output, sleep 200 ms so it can take effect. */ gpioPadSetDirection(&audio, GpioDirection_Output); svcSleepThread(200000000UL); - + /* Pull audio codec low. */ gpioPadSetValue(&audio, GpioValue_Low); - + gpioPadClose(&audio); } } diff --git a/stratosphere/fatal/source/fatal_task_sound.hpp b/stratosphere/fatal/source/fatal_task_sound.hpp index 2a956e46a..4fa7b0abe 100644 --- a/stratosphere/fatal/source/fatal_task_sound.hpp +++ b/stratosphere/fatal/source/fatal_task_sound.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_throw.cpp b/stratosphere/fatal/source/fatal_throw.cpp index 2e6bc3c56..911044723 100644 --- a/stratosphere/fatal/source/fatal_throw.cpp +++ b/stratosphere/fatal/source/fatal_throw.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_throw.hpp" #include "fatal_event_manager.hpp" @@ -28,20 +28,19 @@ static Result SetThrown() { if (g_thrown) { return ResultFatalAlreadyThrown; } - + g_thrown = true; return ResultSuccess; } Result ThrowFatalForSelf(u32 error) { u64 pid = 0; - + svcGetProcessId(&pid, CUR_PROCESS_HANDLE); return ThrowFatalImpl(error, pid, FatalType_ErrorScreen, nullptr); } Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu_ctx) { - Result rc = ResultSuccess; FatalThrowContext ctx = {0}; ctx.error_code = error; if (cpu_ctx != nullptr) { @@ -62,27 +61,27 @@ Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu } /* Reassign this unconditionally, for convenience. */ cpu_ctx = &ctx.cpu_ctx; - + /* Get config. */ const FatalConfig *config = GetFatalConfig(); - + /* Get title id. On failure, it'll be zero. */ u64 title_id = 0; - pminfoGetTitleId(&title_id, pid); + pminfoGetTitleId(&title_id, pid); ctx.is_creport = title_id == TitleId_Creport; - + /* Support for ams creport. TODO: Make this its own command? */ if (ctx.is_creport && !cpu_ctx->is_aarch32 && cpu_ctx->aarch64_ctx.afsr0 != 0) { title_id = cpu_ctx->aarch64_ctx.afsr0; } - + /* Atmosphere extension: automatic debug info collection. */ if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200 && !ctx.is_creport) { if ((cpu_ctx->is_aarch32 && cpu_ctx->aarch32_ctx.stack_trace_size == 0) || (!cpu_ctx->is_aarch32 && cpu_ctx->aarch64_ctx.stack_trace_size == 0)) { TryCollectDebugInformation(&ctx, pid); } } - + switch (policy) { case FatalType_ErrorReport: /* TODO: Don't write an error report. */ @@ -91,20 +90,18 @@ Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu case FatalType_ErrorScreen: { /* Ensure we only throw once. */ - if (R_FAILED((rc = SetThrown()))) { - return rc; - } - + R_TRY(SetThrown()); + /* Signal that fatal is about to happen. */ GetEventManager()->SignalEvents(); - + /* Create events. */ Event erpt_event; Event battery_event; if (R_FAILED(eventCreate(&erpt_event, false)) || R_FAILED(eventCreate(&battery_event, false))) { std::abort(); } - + /* Run tasks. */ if (config->transition_to_fatal) { RunFatalTasks(&ctx, title_id, policy == FatalType_ErrorReportAndErrorScreen, &erpt_event, &battery_event); @@ -112,13 +109,13 @@ Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu /* If flag is not set, don't show the fatal screen. */ return ResultSuccess; } - + } break; default: /* N aborts here. Should we just return an error code? */ std::abort(); } - + return ResultSuccess; } diff --git a/stratosphere/fatal/source/fatal_throw.hpp b/stratosphere/fatal/source/fatal_throw.hpp index 3bb47b358..b6c260bbe 100644 --- a/stratosphere/fatal/source/fatal_throw.hpp +++ b/stratosphere/fatal/source/fatal_throw.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include diff --git a/stratosphere/fatal/source/fatal_types.hpp b/stratosphere/fatal/source/fatal_types.hpp index f82ccfaa2..2778d03c2 100644 --- a/stratosphere/fatal/source/fatal_types.hpp +++ b/stratosphere/fatal/source/fatal_types.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include @@ -24,7 +24,7 @@ static constexpr size_t NumAarch32Gprs = 16; struct Aarch64CpuContext { using RegisterType = u64; static constexpr size_t MaxStackTraceDepth = 0x20; - + /* Registers, exception context. N left names for these fields in fatal .rodata. */ union { RegisterType x[NumAarch64Gprs]; @@ -41,7 +41,7 @@ struct Aarch64CpuContext { RegisterType afsr1; RegisterType esr; RegisterType far; - + /* Misc. */ RegisterType stack_trace[MaxStackTraceDepth]; RegisterType start_address; @@ -52,7 +52,7 @@ struct Aarch64CpuContext { struct Aarch32CpuContext { using RegisterType = u32; static constexpr size_t MaxStackTraceDepth = 0x20; - + /* Registers, exception context. N left names for these fields in fatal .rodata. */ union { RegisterType r[NumAarch32Gprs]; @@ -70,7 +70,7 @@ struct Aarch32CpuContext { RegisterType afsr1; RegisterType esr; RegisterType far; - + /* Misc. Yes, stack_trace_size is really laid out differently than aarch64... */ RegisterType stack_trace[MaxStackTraceDepth]; u32 stack_trace_size; @@ -83,7 +83,7 @@ struct FatalCpuContext { Aarch64CpuContext aarch64_ctx; Aarch32CpuContext aarch32_ctx; }; - + bool is_aarch32; u32 type; }; diff --git a/stratosphere/fatal/source/fatal_user.cpp b/stratosphere/fatal/source/fatal_user.cpp index 3b7648ede..39148274c 100644 --- a/stratosphere/fatal/source/fatal_user.cpp +++ b/stratosphere/fatal/source/fatal_user.cpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include "fatal_user.hpp" #include "fatal_throw.hpp" diff --git a/stratosphere/fatal/source/fatal_user.hpp b/stratosphere/fatal/source/fatal_user.hpp index efb4e7fa0..1ba64e24c 100644 --- a/stratosphere/fatal/source/fatal_user.hpp +++ b/stratosphere/fatal/source/fatal_user.hpp @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #pragma once #include #include @@ -27,7 +27,7 @@ enum UserCmd { }; class UserService final : public IServiceObject { - private: + private: /* Actual commands. */ Result ThrowFatal(u32 error, PidDescriptor pid_desc); Result ThrowFatalWithPolicy(u32 error, PidDescriptor pid_desc, FatalType policy);