strat: use m_ for member variables
This commit is contained in:
@@ -75,43 +75,43 @@ namespace ams::fatal::srv {
|
||||
|
||||
FatalConfig::FatalConfig() {
|
||||
/* Get information from set. */
|
||||
settings::system::GetSerialNumber(std::addressof(this->serial_number));
|
||||
settings::system::GetFirmwareVersion(std::addressof(this->firmware_version));
|
||||
setsysGetQuestFlag(std::addressof(this->quest_flag));
|
||||
settings::system::GetSerialNumber(std::addressof(m_serial_number));
|
||||
settings::system::GetFirmwareVersion(std::addressof(m_firmware_version));
|
||||
setsysGetQuestFlag(std::addressof(m_quest_flag));
|
||||
this->UpdateLanguageCode();
|
||||
|
||||
/* Read information from settings. */
|
||||
settings::fwdbg::GetSettingsItemValue(std::addressof(this->transition_to_fatal), sizeof(this->transition_to_fatal), "fatal", "transition_to_fatal");
|
||||
settings::fwdbg::GetSettingsItemValue(std::addressof(this->show_extra_info), sizeof(this->show_extra_info), "fatal", "show_extra_info");
|
||||
settings::fwdbg::GetSettingsItemValue(std::addressof(m_transition_to_fatal), sizeof(m_transition_to_fatal), "fatal", "transition_to_fatal");
|
||||
settings::fwdbg::GetSettingsItemValue(std::addressof(m_show_extra_info), sizeof(m_show_extra_info), "fatal", "show_extra_info");
|
||||
|
||||
u64 quest_interval_second;
|
||||
settings::fwdbg::GetSettingsItemValue(std::addressof(quest_interval_second), sizeof(quest_interval_second), "fatal", "quest_reboot_interval_second");
|
||||
this->quest_reboot_interval = TimeSpan::FromSeconds(quest_interval_second);
|
||||
m_quest_reboot_interval = TimeSpan::FromSeconds(quest_interval_second);
|
||||
|
||||
/* Atmosphere extension for automatic reboot. */
|
||||
u64 auto_reboot_ms;
|
||||
if (settings::fwdbg::GetSettingsItemValue(std::addressof(auto_reboot_ms), sizeof(auto_reboot_ms), "atmosphere", "fatal_auto_reboot_interval") == sizeof(auto_reboot_ms)) {
|
||||
this->fatal_auto_reboot_interval = TimeSpan::FromMilliSeconds(auto_reboot_ms);
|
||||
this->fatal_auto_reboot_enabled = auto_reboot_ms != 0;
|
||||
m_fatal_auto_reboot_interval = TimeSpan::FromMilliSeconds(auto_reboot_ms);
|
||||
m_fatal_auto_reboot_enabled = auto_reboot_ms != 0;
|
||||
}
|
||||
|
||||
/* Setup messages. */
|
||||
{
|
||||
this->error_msg = "Error Code: 2%03d-%04d (0x%x)\n";
|
||||
m_error_msg = "Error Code: 2%03d-%04d (0x%x)\n";
|
||||
|
||||
this->error_desc = "An error has occurred.\n\n"
|
||||
"Please press the POWER Button to restart the console normally, or a VOL button\n"
|
||||
"to reboot to a payload (or RCM, if none is present). If you are unable to\n"
|
||||
"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
|
||||
"If the problem persists, refer to the Nintendo Support Website.\n"
|
||||
"support.nintendo.com/switch/error\n";
|
||||
m_error_desc = "An error has occurred.\n\n"
|
||||
"Please press the POWER Button to restart the console normally, or a VOL button\n"
|
||||
"to reboot to a payload (or RCM, if none is present). If you are unable to\n"
|
||||
"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
|
||||
"If the problem persists, refer to the Nintendo Support Website.\n"
|
||||
"support.nintendo.com/switch/error\n";
|
||||
|
||||
/* If you're running Atmosphere on a quest unit for some reason, talk to me on discord. */
|
||||
this->quest_desc = "Please call 1-800-875-1852 for service.\n\n"
|
||||
"Also, please be aware that running Atmosphere on a Quest device is not fully\n"
|
||||
"supported. Perhaps try booting your device without Atmosphere before calling\n"
|
||||
"an official Nintendo service hotline. If you encounter further issues, please\n"
|
||||
"contact SciresM#0524 on Discord, or via some other means.\n";
|
||||
m_quest_desc = "Please call 1-800-875-1852 for service.\n\n"
|
||||
"Also, please be aware that running Atmosphere on a Quest device is not fully\n"
|
||||
"supported. Perhaps try booting your device without Atmosphere before calling\n"
|
||||
"an official Nintendo service hotline. If you encounter further issues, please\n"
|
||||
"contact SciresM#0524 on Discord, or via some other means.\n";
|
||||
|
||||
/* TODO: Try to load dynamically? */
|
||||
/* FsStorage message_storage; */
|
||||
|
||||
@@ -20,70 +20,70 @@ namespace ams::fatal::srv {
|
||||
|
||||
class FatalConfig {
|
||||
private:
|
||||
settings::system::SerialNumber serial_number{};
|
||||
settings::system::FirmwareVersion firmware_version{};
|
||||
u64 language_code{};
|
||||
TimeSpan quest_reboot_interval{};
|
||||
bool transition_to_fatal{};
|
||||
bool show_extra_info{};
|
||||
bool quest_flag{};
|
||||
const char *error_msg{};
|
||||
const char *error_desc{};
|
||||
const char *quest_desc{};
|
||||
TimeSpan fatal_auto_reboot_interval{};
|
||||
bool fatal_auto_reboot_enabled{};
|
||||
settings::system::SerialNumber m_serial_number{};
|
||||
settings::system::FirmwareVersion m_firmware_version{};
|
||||
u64 m_language_code{};
|
||||
TimeSpan m_quest_reboot_interval{};
|
||||
bool m_transition_to_fatal{};
|
||||
bool m_show_extra_info{};
|
||||
bool m_quest_flag{};
|
||||
const char *m_error_msg{};
|
||||
const char *m_error_desc{};
|
||||
const char *m_quest_desc{};
|
||||
TimeSpan m_fatal_auto_reboot_interval{};
|
||||
bool m_fatal_auto_reboot_enabled{};
|
||||
public:
|
||||
FatalConfig();
|
||||
|
||||
const settings::system::SerialNumber &GetSerialNumber() const {
|
||||
return this->serial_number;
|
||||
return m_serial_number;
|
||||
}
|
||||
|
||||
const settings::system::FirmwareVersion &GetFirmwareVersion() const {
|
||||
return this->firmware_version;
|
||||
return m_firmware_version;
|
||||
}
|
||||
|
||||
void UpdateLanguageCode() {
|
||||
setGetLanguageCode(&this->language_code);
|
||||
setGetLanguageCode(&m_language_code);
|
||||
}
|
||||
|
||||
u64 GetLanguageCode() const {
|
||||
return this->language_code;
|
||||
return m_language_code;
|
||||
}
|
||||
|
||||
bool ShouldTransitionToFatal() const {
|
||||
return this->transition_to_fatal;
|
||||
return m_transition_to_fatal;
|
||||
}
|
||||
|
||||
bool ShouldShowExtraInfo() const {
|
||||
return this->show_extra_info;
|
||||
return m_show_extra_info;
|
||||
}
|
||||
|
||||
bool IsQuest() const {
|
||||
return this->quest_flag;
|
||||
return m_quest_flag;
|
||||
}
|
||||
|
||||
bool IsFatalRebootEnabled() const {
|
||||
return this->fatal_auto_reboot_enabled;
|
||||
return m_fatal_auto_reboot_enabled;
|
||||
}
|
||||
|
||||
TimeSpan GetQuestRebootTimeoutInterval() const {
|
||||
return this->quest_reboot_interval;
|
||||
return m_quest_reboot_interval;
|
||||
}
|
||||
|
||||
TimeSpan GetFatalRebootTimeoutInterval() const {
|
||||
return this->fatal_auto_reboot_interval;
|
||||
return m_fatal_auto_reboot_interval;
|
||||
}
|
||||
|
||||
const char *GetErrorMessage() const {
|
||||
return this->error_msg;
|
||||
return m_error_msg;
|
||||
}
|
||||
|
||||
const char *GetErrorDescription() const {
|
||||
if (this->IsQuest()) {
|
||||
return this->quest_desc;
|
||||
return m_quest_desc;
|
||||
} else {
|
||||
return this->error_desc;
|
||||
return m_error_desc;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,26 +18,26 @@
|
||||
|
||||
namespace ams::fatal::srv {
|
||||
|
||||
FatalEventManager::FatalEventManager() : lock() {
|
||||
FatalEventManager::FatalEventManager() : m_lock() {
|
||||
/* Just create all the events. */
|
||||
for (size_t i = 0; i < FatalEventManager::NumFatalEvents; i++) {
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(this->events[i]), os::EventClearMode_AutoClear, true));
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(m_events[i]), os::EventClearMode_AutoClear, true));
|
||||
}
|
||||
}
|
||||
|
||||
Result FatalEventManager::GetEvent(const os::SystemEventType **out) {
|
||||
std::scoped_lock lk{this->lock};
|
||||
std::scoped_lock lk{m_lock};
|
||||
|
||||
/* Only allow GetEvent to succeed NumFatalEvents times. */
|
||||
R_UNLESS(this->num_events_gotten < FatalEventManager::NumFatalEvents, fatal::ResultTooManyEvents());
|
||||
R_UNLESS(m_num_events_gotten < FatalEventManager::NumFatalEvents, fatal::ResultTooManyEvents());
|
||||
|
||||
*out = std::addressof(this->events[this->num_events_gotten++]);
|
||||
*out = std::addressof(m_events[m_num_events_gotten++]);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void FatalEventManager::SignalEvents() {
|
||||
for (size_t i = 0; i < FatalEventManager::NumFatalEvents; i++) {
|
||||
os::SignalSystemEvent(std::addressof(this->events[i]));
|
||||
os::SignalSystemEvent(std::addressof(m_events[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ namespace ams::fatal::srv {
|
||||
public:
|
||||
static constexpr size_t NumFatalEvents = 3;
|
||||
private:
|
||||
os::SdkMutex lock;
|
||||
size_t num_events_gotten = 0;
|
||||
os::SystemEventType events[NumFatalEvents];
|
||||
os::SdkMutex m_lock;
|
||||
size_t m_num_events_gotten = 0;
|
||||
os::SystemEventType m_events[NumFatalEvents];
|
||||
public:
|
||||
FatalEventManager();
|
||||
Result GetEvent(const os::SystemEventType **out);
|
||||
|
||||
@@ -90,8 +90,8 @@ namespace ams::fatal::srv {
|
||||
}
|
||||
|
||||
/* Advance, if we write successfully. */
|
||||
if (R_SUCCEEDED(fs::WriteFile(this->file, this->offset, data, size, fs::WriteOption::Flush))) {
|
||||
this->offset += size;
|
||||
if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::Flush))) {
|
||||
m_offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,24 +22,24 @@ namespace ams::fatal::srv {
|
||||
NON_COPYABLE(ScopedFile);
|
||||
NON_MOVEABLE(ScopedFile);
|
||||
private:
|
||||
fs::FileHandle file;
|
||||
s64 offset;
|
||||
bool opened;
|
||||
fs::FileHandle m_file;
|
||||
s64 m_offset;
|
||||
bool m_opened;
|
||||
public:
|
||||
ScopedFile(const char *path) : file(), offset(), opened(false) {
|
||||
ScopedFile(const char *path) : m_file(), m_offset(), m_opened(false) {
|
||||
if (R_SUCCEEDED(fs::CreateFile(path, 0))) {
|
||||
this->opened = R_SUCCEEDED(fs::OpenFile(std::addressof(this->file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
|
||||
m_opened = R_SUCCEEDED(fs::OpenFile(std::addressof(m_file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
|
||||
}
|
||||
}
|
||||
|
||||
~ScopedFile() {
|
||||
if (this->opened) {
|
||||
fs::CloseFile(file);
|
||||
if (m_opened) {
|
||||
fs::CloseFile(m_file);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsOpen() const {
|
||||
return this->opened;
|
||||
return m_opened;
|
||||
}
|
||||
|
||||
void WriteString(const char *str);
|
||||
|
||||
@@ -28,27 +28,27 @@ namespace ams::fatal::srv {
|
||||
/* Service Context. */
|
||||
class ServiceContext {
|
||||
private:
|
||||
os::Event erpt_event;
|
||||
os::Event battery_event;
|
||||
ThrowContext context;
|
||||
FatalEventManager event_manager;
|
||||
bool has_thrown;
|
||||
os::Event m_erpt_event;
|
||||
os::Event m_battery_event;
|
||||
ThrowContext m_context;
|
||||
FatalEventManager m_event_manager;
|
||||
bool m_has_thrown;
|
||||
private:
|
||||
Result TrySetHasThrown() {
|
||||
R_UNLESS(!this->has_thrown, fatal::ResultAlreadyThrown());
|
||||
this->has_thrown = true;
|
||||
R_UNLESS(!m_has_thrown, fatal::ResultAlreadyThrown());
|
||||
m_has_thrown = true;
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
ServiceContext()
|
||||
: erpt_event(os::EventClearMode_ManualClear), battery_event(os::EventClearMode_ManualClear),
|
||||
context(std::addressof(erpt_event), std::addressof(battery_event)), has_thrown(false)
|
||||
: m_erpt_event(os::EventClearMode_ManualClear), m_battery_event(os::EventClearMode_ManualClear),
|
||||
m_context(std::addressof(m_erpt_event), std::addressof(m_battery_event)), m_has_thrown(false)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
Result GetEvent(const os::SystemEventType **out) {
|
||||
return this->event_manager.GetEvent(out);
|
||||
return m_event_manager.GetEvent(out);
|
||||
}
|
||||
|
||||
Result ThrowFatal(Result result, os::ProcessId process_id) {
|
||||
@@ -73,51 +73,51 @@ namespace ams::fatal::srv {
|
||||
/* Note that we've thrown fatal. */
|
||||
R_TRY(this->TrySetHasThrown());
|
||||
|
||||
/* At this point we have exclusive access to this->context. */
|
||||
this->context.result = result;
|
||||
this->context.cpu_ctx = cpu_ctx;
|
||||
/* At this point we have exclusive access to m_context. */
|
||||
m_context.result = result;
|
||||
m_context.cpu_ctx = cpu_ctx;
|
||||
|
||||
/* Cap the stack trace to a sane limit. */
|
||||
if (cpu_ctx.architecture == CpuContext::Architecture_Aarch64) {
|
||||
this->context.cpu_ctx.aarch64_ctx.stack_trace_size = std::max(size_t(this->context.cpu_ctx.aarch64_ctx.stack_trace_size), aarch64::CpuContext::MaxStackTraceDepth);
|
||||
m_context.cpu_ctx.aarch64_ctx.stack_trace_size = std::max(size_t(m_context.cpu_ctx.aarch64_ctx.stack_trace_size), aarch64::CpuContext::MaxStackTraceDepth);
|
||||
} else {
|
||||
this->context.cpu_ctx.aarch32_ctx.stack_trace_size = std::max(size_t(this->context.cpu_ctx.aarch32_ctx.stack_trace_size), aarch32::CpuContext::MaxStackTraceDepth);
|
||||
m_context.cpu_ctx.aarch32_ctx.stack_trace_size = std::max(size_t(m_context.cpu_ctx.aarch32_ctx.stack_trace_size), aarch32::CpuContext::MaxStackTraceDepth);
|
||||
}
|
||||
|
||||
/* Get program id. */
|
||||
pm::info::GetProgramId(std::addressof(this->context.program_id), process_id);
|
||||
this->context.is_creport = (this->context.program_id == ncm::SystemProgramId::Creport);
|
||||
pm::info::GetProgramId(std::addressof(m_context.program_id), process_id);
|
||||
m_context.is_creport = (m_context.program_id == ncm::SystemProgramId::Creport);
|
||||
|
||||
if (!this->context.is_creport) {
|
||||
if (!m_context.is_creport) {
|
||||
/* On firmware version 2.0.0, use debugging SVCs to collect information. */
|
||||
if (hos::GetVersion() >= hos::Version_2_0_0) {
|
||||
fatal::srv::TryCollectDebugInformation(std::addressof(this->context), process_id);
|
||||
fatal::srv::TryCollectDebugInformation(std::addressof(m_context), process_id);
|
||||
}
|
||||
} else {
|
||||
/* We received info from creport. Parse program id from afsr0. */
|
||||
if (cpu_ctx.architecture == CpuContext::Architecture_Aarch64) {
|
||||
this->context.program_id = cpu_ctx.aarch64_ctx.GetProgramIdForAtmosphere();
|
||||
m_context.program_id = cpu_ctx.aarch64_ctx.GetProgramIdForAtmosphere();
|
||||
} else {
|
||||
this->context.program_id = cpu_ctx.aarch32_ctx.GetProgramIdForAtmosphere();
|
||||
m_context.program_id = cpu_ctx.aarch32_ctx.GetProgramIdForAtmosphere();
|
||||
}
|
||||
}
|
||||
|
||||
/* Decide whether to generate a report. */
|
||||
this->context.generate_error_report = (policy == FatalPolicy_ErrorReportAndErrorScreen);
|
||||
m_context.generate_error_report = (policy == FatalPolicy_ErrorReportAndErrorScreen);
|
||||
|
||||
/* Adjust error code (ResultSuccess()/2000-0000 -> err::ResultSystemProgramAbort()/2162-0002). */
|
||||
if (R_SUCCEEDED(this->context.result)) {
|
||||
this->context.result = err::ResultSystemProgramAbort();
|
||||
if (R_SUCCEEDED(m_context.result)) {
|
||||
m_context.result = err::ResultSystemProgramAbort();
|
||||
}
|
||||
|
||||
switch (policy) {
|
||||
case FatalPolicy_ErrorReportAndErrorScreen:
|
||||
case FatalPolicy_ErrorScreen:
|
||||
/* Signal that we're throwing. */
|
||||
this->event_manager.SignalEvents();
|
||||
m_event_manager.SignalEvents();
|
||||
|
||||
if (GetFatalConfig().ShouldTransitionToFatal()) {
|
||||
RunTasks(std::addressof(this->context));
|
||||
RunTasks(std::addressof(m_context));
|
||||
}
|
||||
break;
|
||||
/* N aborts here. Should we just return an error code? */
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ams::fatal::srv {
|
||||
class TaskThread {
|
||||
NON_COPYABLE(TaskThread);
|
||||
private:
|
||||
os::ThreadType thread;
|
||||
os::ThreadType m_thread;
|
||||
private:
|
||||
static void RunTaskImpl(void *arg) {
|
||||
ITask *task = reinterpret_cast<ITask *>(arg);
|
||||
@@ -41,9 +41,9 @@ namespace ams::fatal::srv {
|
||||
public:
|
||||
TaskThread() { /* ... */ }
|
||||
void StartTask(ITask *task) {
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(this->thread), RunTaskImpl, task, task->GetStack(), task->GetStackSize(), AMS_GET_SYSTEM_THREAD_PRIORITY(fatalsrv, FatalTaskThread), 3));
|
||||
os::SetThreadNamePointer(std::addressof(this->thread), AMS_GET_SYSTEM_THREAD_NAME(fatalsrv, FatalTaskThread));
|
||||
os::StartThread(std::addressof(this->thread));
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_thread), RunTaskImpl, task, task->GetStack(), task->GetStackSize(), AMS_GET_SYSTEM_THREAD_PRIORITY(fatalsrv, FatalTaskThread), 3));
|
||||
os::SetThreadNamePointer(std::addressof(m_thread), AMS_GET_SYSTEM_THREAD_NAME(fatalsrv, FatalTaskThread));
|
||||
os::StartThread(std::addressof(m_thread));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,13 +52,13 @@ namespace ams::fatal::srv {
|
||||
private:
|
||||
static constexpr size_t MaxTasks = 8;
|
||||
private:
|
||||
TaskThread task_threads[MaxTasks];
|
||||
size_t task_count = 0;
|
||||
TaskThread m_task_threads[MaxTasks];
|
||||
size_t m_task_count = 0;
|
||||
public:
|
||||
TaskManager() { /* ... */ }
|
||||
void StartTask(ITask *task) {
|
||||
AMS_ABORT_UNLESS(this->task_count < MaxTasks);
|
||||
this->task_threads[this->task_count++].StartTask(task);
|
||||
AMS_ABORT_UNLESS(m_task_count < MaxTasks);
|
||||
m_task_threads[m_task_count++].StartTask(task);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace ams::fatal::srv {
|
||||
|
||||
class ITask {
|
||||
protected:
|
||||
const ThrowContext *context = nullptr;
|
||||
const ThrowContext *m_context = nullptr;
|
||||
public:
|
||||
void Initialize(const ThrowContext *context) {
|
||||
this->context = context;
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
virtual Result Run() = 0;
|
||||
@@ -38,10 +38,10 @@ namespace ams::fatal::srv {
|
||||
static constexpr size_t StackSize = _StackSize;
|
||||
static_assert(util::IsAligned(StackSize, os::MemoryPageSize), "StackSize alignment");
|
||||
protected:
|
||||
alignas(os::MemoryPageSize) u8 stack_mem[StackSize] = {};
|
||||
alignas(os::MemoryPageSize) u8 m_stack_mem[StackSize] = {};
|
||||
public:
|
||||
virtual u8 *GetStack() override final {
|
||||
return this->stack_mem;
|
||||
return m_stack_mem;
|
||||
}
|
||||
|
||||
virtual size_t GetStackSize() const override final {
|
||||
|
||||
@@ -79,61 +79,61 @@ namespace ams::fatal::srv {
|
||||
|
||||
/* Open report file. */
|
||||
{
|
||||
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, static_cast<u64>(this->context->program_id));
|
||||
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, static_cast<u64>(m_context->program_id));
|
||||
ScopedFile file(file_path);
|
||||
if (file.IsOpen()) {
|
||||
file.WriteFormat("Atmosphère Fatal Report (v1.1):\n");
|
||||
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->context->result.GetValue(), this->context->result.GetModule(), this->context->result.GetDescription());
|
||||
file.WriteFormat("Program ID: %016lx\n", static_cast<u64>(this->context->program_id));
|
||||
if (strlen(this->context->proc_name)) {
|
||||
file.WriteFormat("Process Name: %s\n", this->context->proc_name);
|
||||
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", m_context->result.GetValue(), m_context->result.GetModule(), m_context->result.GetDescription());
|
||||
file.WriteFormat("Program ID: %016lx\n", static_cast<u64>(m_context->program_id));
|
||||
if (strlen(m_context->proc_name)) {
|
||||
file.WriteFormat("Process Name: %s\n", m_context->proc_name);
|
||||
}
|
||||
file.WriteFormat("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) {
|
||||
if (m_context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32) {
|
||||
file.WriteFormat("General Purpose Registers:\n");
|
||||
for (size_t i = 0; i <= aarch32::RegisterName_PC; i++) {
|
||||
if (this->context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
|
||||
file.WriteFormat( " %3s: %08x\n", aarch32::CpuContext::RegisterNameStrings[i], this->context->cpu_ctx.aarch32_ctx.r[i]);
|
||||
if (m_context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
|
||||
file.WriteFormat( " %3s: %08x\n", aarch32::CpuContext::RegisterNameStrings[i], m_context->cpu_ctx.aarch32_ctx.r[i]);
|
||||
}
|
||||
}
|
||||
file.WriteFormat("Start Address: %08x\n", this->context->cpu_ctx.aarch32_ctx.base_address);
|
||||
file.WriteFormat("Start Address: %08x\n", m_context->cpu_ctx.aarch32_ctx.base_address);
|
||||
file.WriteFormat("Stack Trace:\n");
|
||||
for (unsigned int i = 0; i < this->context->cpu_ctx.aarch32_ctx.stack_trace_size; i++) {
|
||||
file.WriteFormat(" ReturnAddress[%02u]: %08x\n", i, this->context->cpu_ctx.aarch32_ctx.stack_trace[i]);
|
||||
for (unsigned int i = 0; i < m_context->cpu_ctx.aarch32_ctx.stack_trace_size; i++) {
|
||||
file.WriteFormat(" ReturnAddress[%02u]: %08x\n", i, m_context->cpu_ctx.aarch32_ctx.stack_trace[i]);
|
||||
}
|
||||
} else {
|
||||
file.WriteFormat("General Purpose Registers:\n");
|
||||
for (size_t i = 0; i <= aarch64::RegisterName_PC; i++) {
|
||||
if (this->context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
|
||||
file.WriteFormat( " %3s: %016lx\n", aarch64::CpuContext::RegisterNameStrings[i], this->context->cpu_ctx.aarch64_ctx.x[i]);
|
||||
if (m_context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
|
||||
file.WriteFormat( " %3s: %016lx\n", aarch64::CpuContext::RegisterNameStrings[i], m_context->cpu_ctx.aarch64_ctx.x[i]);
|
||||
}
|
||||
}
|
||||
file.WriteFormat("Start Address: %016lx\n", this->context->cpu_ctx.aarch64_ctx.base_address);
|
||||
file.WriteFormat("Start Address: %016lx\n", m_context->cpu_ctx.aarch64_ctx.base_address);
|
||||
file.WriteFormat("Stack Trace:\n");
|
||||
for (unsigned int i = 0; i < this->context->cpu_ctx.aarch64_ctx.stack_trace_size; i++) {
|
||||
file.WriteFormat(" ReturnAddress[%02u]: %016lx\n", i, this->context->cpu_ctx.aarch64_ctx.stack_trace[i]);
|
||||
for (unsigned int i = 0; i < m_context->cpu_ctx.aarch64_ctx.stack_trace_size; i++) {
|
||||
file.WriteFormat(" ReturnAddress[%02u]: %016lx\n", i, m_context->cpu_ctx.aarch64_ctx.stack_trace[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->context->stack_dump_size != 0) {
|
||||
if (m_context->stack_dump_size != 0) {
|
||||
file.WriteFormat("Stack Dump: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
|
||||
for (size_t i = 0; i < 0x10; i++) {
|
||||
const size_t ofs = i * 0x10;
|
||||
file.WriteFormat(" %012lx %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
this->context->stack_dump_base + ofs, this->context->stack_dump[ofs + 0], this->context->stack_dump[ofs + 1], this->context->stack_dump[ofs + 2], this->context->stack_dump[ofs + 3], this->context->stack_dump[ofs + 4], this->context->stack_dump[ofs + 5], this->context->stack_dump[ofs + 6], this->context->stack_dump[ofs + 7],
|
||||
this->context->stack_dump[ofs + 8], this->context->stack_dump[ofs + 9], this->context->stack_dump[ofs + 10], this->context->stack_dump[ofs + 11], this->context->stack_dump[ofs + 12], this->context->stack_dump[ofs + 13], this->context->stack_dump[ofs + 14], this->context->stack_dump[ofs + 15]);
|
||||
m_context->stack_dump_base + ofs, m_context->stack_dump[ofs + 0], m_context->stack_dump[ofs + 1], m_context->stack_dump[ofs + 2], m_context->stack_dump[ofs + 3], m_context->stack_dump[ofs + 4], m_context->stack_dump[ofs + 5], m_context->stack_dump[ofs + 6], m_context->stack_dump[ofs + 7],
|
||||
m_context->stack_dump[ofs + 8], m_context->stack_dump[ofs + 9], m_context->stack_dump[ofs + 10], m_context->stack_dump[ofs + 11], m_context->stack_dump[ofs + 12], m_context->stack_dump[ofs + 13], m_context->stack_dump[ofs + 14], m_context->stack_dump[ofs + 15]);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->context->tls_address != 0) {
|
||||
file.WriteFormat("TLS Address: %016lx\n", this->context->tls_address);
|
||||
if (m_context->tls_address != 0) {
|
||||
file.WriteFormat("TLS Address: %016lx\n", m_context->tls_address);
|
||||
file.WriteFormat("TLS Dump: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
|
||||
for (size_t i = 0; i < 0x10; i++) {
|
||||
const size_t ofs = i * 0x10;
|
||||
file.WriteFormat(" %012lx %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
this->context->tls_address + ofs, this->context->tls_dump[ofs + 0], this->context->tls_dump[ofs + 1], this->context->tls_dump[ofs + 2], this->context->tls_dump[ofs + 3], this->context->tls_dump[ofs + 4], this->context->tls_dump[ofs + 5], this->context->tls_dump[ofs + 6], this->context->tls_dump[ofs + 7],
|
||||
this->context->tls_dump[ofs + 8], this->context->tls_dump[ofs + 9], this->context->tls_dump[ofs + 10], this->context->tls_dump[ofs + 11], this->context->tls_dump[ofs + 12], this->context->tls_dump[ofs + 13], this->context->tls_dump[ofs + 14], this->context->tls_dump[ofs + 15]);
|
||||
m_context->tls_address + ofs, m_context->tls_dump[ofs + 0], m_context->tls_dump[ofs + 1], m_context->tls_dump[ofs + 2], m_context->tls_dump[ofs + 3], m_context->tls_dump[ofs + 4], m_context->tls_dump[ofs + 5], m_context->tls_dump[ofs + 6], m_context->tls_dump[ofs + 7],
|
||||
m_context->tls_dump[ofs + 8], m_context->tls_dump[ofs + 9], m_context->tls_dump[ofs + 10], m_context->tls_dump[ofs + 11], m_context->tls_dump[ofs + 12], m_context->tls_dump[ofs + 13], m_context->tls_dump[ofs + 14], m_context->tls_dump[ofs + 15]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,29 +141,29 @@ namespace ams::fatal::srv {
|
||||
|
||||
/* Dump data to file. */
|
||||
{
|
||||
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, static_cast<u64>(this->context->program_id));
|
||||
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, static_cast<u64>(m_context->program_id));
|
||||
ScopedFile file(file_path);
|
||||
if (file.IsOpen()) {
|
||||
file.Write(this->context->tls_dump, sizeof(this->context->tls_dump));
|
||||
if (this->context->stack_dump_size) {
|
||||
file.Write(this->context->stack_dump, this->context->stack_dump_size);
|
||||
file.Write(m_context->tls_dump, sizeof(m_context->tls_dump));
|
||||
if (m_context->stack_dump_size) {
|
||||
file.Write(m_context->stack_dump, m_context->stack_dump_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Result ErrorReportTask::Run() {
|
||||
if (this->context->generate_error_report) {
|
||||
if (m_context->generate_error_report) {
|
||||
/* Here, Nintendo creates an error report with erpt. AMS will not do that. */
|
||||
}
|
||||
|
||||
/* Save report to SD card. */
|
||||
if (!this->context->is_creport) {
|
||||
if (!m_context->is_creport) {
|
||||
this->SaveReportToSdCard();
|
||||
}
|
||||
|
||||
/* Signal we're done with our job. */
|
||||
this->context->erpt_event->Signal();
|
||||
m_context->erpt_event->Signal();
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
@@ -53,17 +53,17 @@ namespace ams::fatal::srv {
|
||||
|
||||
class RebootTimingObserver {
|
||||
private:
|
||||
os::Tick start_tick;
|
||||
TimeSpan interval;
|
||||
bool flag;
|
||||
os::Tick m_start_tick;
|
||||
TimeSpan m_interval;
|
||||
bool m_flag;
|
||||
public:
|
||||
RebootTimingObserver(bool flag, TimeSpan iv) : start_tick(os::GetSystemTick()), interval(iv), flag(flag) {
|
||||
RebootTimingObserver(bool flag, TimeSpan iv) : m_start_tick(os::GetSystemTick()), m_interval(iv), m_flag(flag) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
bool IsRebootTiming() const {
|
||||
auto current_tick = os::GetSystemTick();
|
||||
return this->flag && (current_tick - this->start_tick).ToTimeSpan() >= this->interval;
|
||||
return m_flag && (current_tick - m_start_tick).ToTimeSpan() >= m_interval;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -114,13 +114,13 @@ namespace ams::fatal::srv {
|
||||
/* Check the battery state, and shutdown on low voltage. */
|
||||
if (R_FAILED(psmGetBatteryVoltageState(std::addressof(bv_state))) || bv_state == PsmBatteryVoltageState_NeedsShutdown) {
|
||||
/* Wait a second for the error report task to finish. */
|
||||
this->context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
|
||||
m_context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
|
||||
this->TryShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Signal we've checked the battery at least once. */
|
||||
this->context->battery_event->Signal();
|
||||
m_context->battery_event->Signal();
|
||||
|
||||
/* Loop querying voltage state every 5 seconds. */
|
||||
while (true) {
|
||||
@@ -148,7 +148,7 @@ namespace ams::fatal::srv {
|
||||
|
||||
void PowerButtonObserveTask::WaitForPowerButton() {
|
||||
/* Wait up to a second for error report generation to finish. */
|
||||
this->context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
|
||||
m_context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
|
||||
|
||||
/* Force a reboot after some time if kiosk unit. */
|
||||
const auto &config = GetFatalConfig();
|
||||
|
||||
@@ -70,10 +70,10 @@ namespace ams::fatal::srv {
|
||||
/* Task definitions. */
|
||||
class ShowFatalTask : public ITaskWithStack<0x8000> {
|
||||
private:
|
||||
ViDisplay display;
|
||||
ViLayer layer;
|
||||
NWindow win;
|
||||
NvMap map;
|
||||
ViDisplay m_display;
|
||||
ViLayer m_layer;
|
||||
NWindow m_win;
|
||||
NvMap m_map;
|
||||
private:
|
||||
Result SetupDisplayInternal();
|
||||
Result SetupDisplayExternal();
|
||||
@@ -156,19 +156,19 @@ namespace ams::fatal::srv {
|
||||
R_TRY(SetupDisplayExternal());
|
||||
|
||||
/* Open the default display. */
|
||||
R_TRY(viOpenDefaultDisplay(std::addressof(this->display)));
|
||||
R_TRY(viOpenDefaultDisplay(std::addressof(m_display)));
|
||||
|
||||
/* Reset the display magnification to its default value. */
|
||||
s32 display_width, display_height;
|
||||
R_TRY(viGetDisplayLogicalResolution(std::addressof(this->display), std::addressof(display_width), std::addressof(display_height)));
|
||||
R_TRY(viGetDisplayLogicalResolution(std::addressof(m_display), std::addressof(display_width), std::addressof(display_height)));
|
||||
|
||||
/* viSetDisplayMagnification was added in 3.0.0. */
|
||||
if (hos::GetVersion() >= hos::Version_3_0_0) {
|
||||
R_TRY(viSetDisplayMagnification(std::addressof(this->display), 0, 0, display_width, display_height));
|
||||
R_TRY(viSetDisplayMagnification(std::addressof(m_display), 0, 0, display_width, display_height));
|
||||
}
|
||||
|
||||
/* Create layer to draw to. */
|
||||
R_TRY(viCreateLayer(std::addressof(this->display), std::addressof(this->layer)));
|
||||
R_TRY(viCreateLayer(std::addressof(m_display), std::addressof(m_layer)));
|
||||
|
||||
/* Setup the layer. */
|
||||
{
|
||||
@@ -183,16 +183,16 @@ namespace ams::fatal::srv {
|
||||
const float layer_x = static_cast<float>((display_width - LayerWidth) / 2);
|
||||
const float layer_y = static_cast<float>((display_height - LayerHeight) / 2);
|
||||
|
||||
R_TRY(viSetLayerSize(std::addressof(this->layer), LayerWidth, LayerHeight));
|
||||
R_TRY(viSetLayerSize(std::addressof(m_layer), LayerWidth, LayerHeight));
|
||||
|
||||
/* Set the layer's Z at display maximum, to be above everything else .*/
|
||||
R_TRY(viSetLayerZ(std::addressof(this->layer), FatalLayerZ));
|
||||
R_TRY(viSetLayerZ(std::addressof(m_layer), FatalLayerZ));
|
||||
|
||||
/* Center the layer in the screen. */
|
||||
R_TRY(viSetLayerPosition(std::addressof(this->layer), layer_x, layer_y));
|
||||
R_TRY(viSetLayerPosition(std::addressof(m_layer), layer_x, layer_y));
|
||||
|
||||
/* Create framebuffer. */
|
||||
R_TRY(nwindowCreateFromLayer(std::addressof(this->win), std::addressof(this->layer)));
|
||||
R_TRY(nwindowCreateFromLayer(std::addressof(m_win), std::addressof(m_layer)));
|
||||
R_TRY(this->InitializeNativeWindow());
|
||||
}
|
||||
|
||||
@@ -229,14 +229,14 @@ namespace ams::fatal::srv {
|
||||
/* Draw error message and firmware. */
|
||||
font::SetPosition(start_x, start_y);
|
||||
font::SetFontSize(16.0f);
|
||||
font::PrintFormat(config.GetErrorMessage(), this->context->result.GetModule(), this->context->result.GetDescription(), this->context->result.GetValue());
|
||||
font::PrintFormat(config.GetErrorMessage(), m_context->result.GetModule(), m_context->result.GetDescription(), m_context->result.GetValue());
|
||||
font::AddSpacingLines(0.5f);
|
||||
font::PrintFormatLine( "Program: %016lX", static_cast<u64>(this->context->program_id));
|
||||
font::PrintFormatLine( "Program: %016lX", static_cast<u64>(m_context->program_id));
|
||||
font::AddSpacingLines(0.5f);
|
||||
|
||||
font::PrintFormatLine("Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision());
|
||||
font::AddSpacingLines(1.5f);
|
||||
if (!exosphere::ResultVersionMismatch::Includes(this->context->result)) {
|
||||
if (!exosphere::ResultVersionMismatch::Includes(m_context->result)) {
|
||||
font::Print(config.GetErrorDescription());
|
||||
} else {
|
||||
/* Print a special message for atmosphere version mismatch. */
|
||||
@@ -260,7 +260,7 @@ namespace ams::fatal::srv {
|
||||
u32 pc_x = 0;
|
||||
|
||||
/* Note architecutre. */
|
||||
const bool is_aarch32 = this->context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32;
|
||||
const bool is_aarch32 = m_context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32;
|
||||
|
||||
/* Print GPRs. */
|
||||
font::SetFontSize(14.0f);
|
||||
@@ -273,8 +273,8 @@ namespace ams::fatal::srv {
|
||||
u32 x = font::GetX();
|
||||
font::PrintFormat("%s:", aarch32::CpuContext::RegisterNameStrings[i]);
|
||||
font::SetPosition(x + 47, font::GetY());
|
||||
if (this->context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
|
||||
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.r[i]);
|
||||
if (m_context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
|
||||
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.r[i]);
|
||||
font::PrintMonospaceBlank(8);
|
||||
} else {
|
||||
font::PrintMonospaceBlank(16);
|
||||
@@ -283,8 +283,8 @@ namespace ams::fatal::srv {
|
||||
pc_x = font::GetX();
|
||||
font::PrintFormat("%s:", aarch32::CpuContext::RegisterNameStrings[i + (aarch32::RegisterName_GeneralPurposeCount / 2)]);
|
||||
font::SetPosition(pc_x + 47, font::GetY());
|
||||
if (this->context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i + (aarch32::RegisterName_GeneralPurposeCount / 2)))) {
|
||||
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.r[i + (aarch32::RegisterName_GeneralPurposeCount / 2)]);
|
||||
if (m_context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i + (aarch32::RegisterName_GeneralPurposeCount / 2)))) {
|
||||
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.r[i + (aarch32::RegisterName_GeneralPurposeCount / 2)]);
|
||||
font::PrintMonospaceBlank(8);
|
||||
} else {
|
||||
font::PrintMonospaceBlank(16);
|
||||
@@ -303,8 +303,8 @@ namespace ams::fatal::srv {
|
||||
u32 x = font::GetX();
|
||||
font::PrintFormat("%s:", aarch64::CpuContext::RegisterNameStrings[i]);
|
||||
font::SetPosition(x + 47, font::GetY());
|
||||
if (this->context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
|
||||
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.x[i]);
|
||||
if (m_context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
|
||||
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.x[i]);
|
||||
} else {
|
||||
font::PrintMonospaceBlank(16);
|
||||
}
|
||||
@@ -312,8 +312,8 @@ namespace ams::fatal::srv {
|
||||
pc_x = font::GetX();
|
||||
font::PrintFormat("%s:", aarch64::CpuContext::RegisterNameStrings[i + (aarch64::RegisterName_GeneralPurposeCount / 2)]);
|
||||
font::SetPosition(pc_x + 47, font::GetY());
|
||||
if (this->context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i + (aarch64::RegisterName_GeneralPurposeCount / 2)))) {
|
||||
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.x[i + (aarch64::RegisterName_GeneralPurposeCount / 2)]);
|
||||
if (m_context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i + (aarch64::RegisterName_GeneralPurposeCount / 2)))) {
|
||||
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.x[i + (aarch64::RegisterName_GeneralPurposeCount / 2)]);
|
||||
} else {
|
||||
font::PrintMonospaceBlank(16);
|
||||
}
|
||||
@@ -336,17 +336,17 @@ namespace ams::fatal::srv {
|
||||
font::SetPosition(x + 47, font::GetY());
|
||||
}
|
||||
if (is_aarch32) {
|
||||
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.pc);
|
||||
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.pc);
|
||||
} else {
|
||||
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.pc);
|
||||
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.pc);
|
||||
}
|
||||
|
||||
/* Print Backtrace. */
|
||||
u32 bt_size;
|
||||
if (is_aarch32) {
|
||||
bt_size = this->context->cpu_ctx.aarch32_ctx.stack_trace_size;
|
||||
bt_size = m_context->cpu_ctx.aarch32_ctx.stack_trace_size;
|
||||
} else {
|
||||
bt_size = this->context->cpu_ctx.aarch64_ctx.stack_trace_size;
|
||||
bt_size = m_context->cpu_ctx.aarch64_ctx.stack_trace_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -354,29 +354,29 @@ namespace ams::fatal::srv {
|
||||
if (bt_size == 0) {
|
||||
if (is_aarch32) {
|
||||
font::Print("Start Address: ");
|
||||
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.base_address);
|
||||
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.base_address);
|
||||
font::PrintLine("");
|
||||
} else {
|
||||
font::Print("Start Address: ");
|
||||
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.base_address);
|
||||
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.base_address);
|
||||
font::PrintLine("");
|
||||
}
|
||||
} else {
|
||||
if (is_aarch32) {
|
||||
font::Print("Backtrace - Start Address: ");
|
||||
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.base_address);
|
||||
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.base_address);
|
||||
font::PrintLine("");
|
||||
font::AddSpacingLines(0.5f);
|
||||
for (u32 i = 0; i < aarch32::CpuContext::MaxStackTraceDepth / 2; i++) {
|
||||
u32 bt_cur = 0, bt_next = 0;
|
||||
if (i < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
bt_cur = this->context->cpu_ctx.aarch32_ctx.stack_trace[i];
|
||||
if (i < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
bt_cur = m_context->cpu_ctx.aarch32_ctx.stack_trace[i];
|
||||
}
|
||||
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
bt_next = this->context->cpu_ctx.aarch32_ctx.stack_trace[i + aarch32::CpuContext::MaxStackTraceDepth / 2];
|
||||
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
bt_next = m_context->cpu_ctx.aarch32_ctx.stack_trace[i + aarch32::CpuContext::MaxStackTraceDepth / 2];
|
||||
}
|
||||
|
||||
if (i < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
if (i < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
u32 x = font::GetX();
|
||||
font::PrintFormat("BT[%02d]: ", i);
|
||||
font::SetPosition(x + 72, font::GetY());
|
||||
@@ -385,7 +385,7 @@ namespace ams::fatal::srv {
|
||||
font::Print(" ");
|
||||
}
|
||||
|
||||
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
|
||||
u32 x = font::GetX();
|
||||
font::PrintFormat("BT[%02d]: ", i + aarch32::CpuContext::MaxStackTraceDepth / 2);
|
||||
font::SetPosition(x + 72, font::GetY());
|
||||
@@ -398,19 +398,19 @@ namespace ams::fatal::srv {
|
||||
}
|
||||
} else {
|
||||
font::Print("Backtrace - Start Address: ");
|
||||
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.base_address);
|
||||
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.base_address);
|
||||
font::PrintLine("");
|
||||
font::AddSpacingLines(0.5f);
|
||||
for (u32 i = 0; i < aarch64::CpuContext::MaxStackTraceDepth / 2; i++) {
|
||||
u64 bt_cur = 0, bt_next = 0;
|
||||
if (i < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
bt_cur = this->context->cpu_ctx.aarch64_ctx.stack_trace[i];
|
||||
if (i < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
bt_cur = m_context->cpu_ctx.aarch64_ctx.stack_trace[i];
|
||||
}
|
||||
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
bt_next = this->context->cpu_ctx.aarch64_ctx.stack_trace[i + aarch64::CpuContext::MaxStackTraceDepth / 2];
|
||||
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
bt_next = m_context->cpu_ctx.aarch64_ctx.stack_trace[i + aarch64::CpuContext::MaxStackTraceDepth / 2];
|
||||
}
|
||||
|
||||
if (i < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
if (i < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
u32 x = font::GetX();
|
||||
font::PrintFormat("BT[%02d]: ", i);
|
||||
font::SetPosition(x + 72, font::GetY());
|
||||
@@ -418,7 +418,7 @@ namespace ams::fatal::srv {
|
||||
font::Print(" ");
|
||||
}
|
||||
|
||||
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
u32 x = font::GetX();
|
||||
font::PrintFormat("BT[%02d]: ", i + aarch64::CpuContext::MaxStackTraceDepth / 2);
|
||||
font::SetPosition(x + 72, font::GetY());
|
||||
@@ -439,7 +439,7 @@ namespace ams::fatal::srv {
|
||||
R_TRY(nvFenceInit());
|
||||
|
||||
/* Create nvmap. */
|
||||
R_TRY(nvMapCreate(std::addressof(this->map), g_framebuffer_memory, sizeof(g_framebuffer_memory), 0x20000, NvKind_Pitch, true));
|
||||
R_TRY(nvMapCreate(std::addressof(m_map), g_framebuffer_memory, sizeof(g_framebuffer_memory), 0x20000, NvKind_Pitch, true));
|
||||
|
||||
/* Setup graphics buffer. */
|
||||
{
|
||||
@@ -458,14 +458,14 @@ namespace ams::fatal::srv {
|
||||
grbuf.planes[0].layout = NvLayout_BlockLinear;
|
||||
grbuf.planes[0].kind = NvKind_Generic_16BX2;
|
||||
grbuf.planes[0].block_height_log2 = 4;
|
||||
grbuf.nvmap_id = nvMapGetId(std::addressof(this->map));
|
||||
grbuf.nvmap_id = nvMapGetId(std::addressof(m_map));
|
||||
grbuf.stride = FatalScreenWidthAligned;
|
||||
grbuf.total_size = sizeof(g_framebuffer_memory);
|
||||
grbuf.planes[0].pitch = FatalScreenWidthAlignedBytes;
|
||||
grbuf.planes[0].size = sizeof(g_framebuffer_memory);
|
||||
grbuf.planes[0].offset = 0;
|
||||
|
||||
R_TRY(nwindowConfigureBuffer(std::addressof(this->win), 0, std::addressof(grbuf)));
|
||||
R_TRY(nwindowConfigureBuffer(std::addressof(m_win), 0, std::addressof(grbuf)));
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
@@ -473,9 +473,9 @@ namespace ams::fatal::srv {
|
||||
|
||||
void ShowFatalTask::DisplayPreRenderedFrame() {
|
||||
s32 slot;
|
||||
R_ABORT_UNLESS(nwindowDequeueBuffer(std::addressof(this->win), std::addressof(slot), nullptr));
|
||||
R_ABORT_UNLESS(nwindowDequeueBuffer(std::addressof(m_win), std::addressof(slot), nullptr));
|
||||
dd::FlushDataCache(g_framebuffer_memory, sizeof(g_framebuffer_memory));
|
||||
R_ABORT_UNLESS(nwindowQueueBuffer(std::addressof(this->win), this->win.cur_slot, NULL));
|
||||
R_ABORT_UNLESS(nwindowQueueBuffer(std::addressof(m_win), m_win.cur_slot, NULL));
|
||||
}
|
||||
|
||||
Result ShowFatalTask::ShowFatal() {
|
||||
@@ -493,7 +493,7 @@ namespace ams::fatal::srv {
|
||||
|
||||
Result ShowFatalTask::Run() {
|
||||
/* Don't show the fatal error screen until we've verified the battery is okay. */
|
||||
this->context->battery_event->Wait();
|
||||
m_context->battery_event->Wait();
|
||||
|
||||
return ShowFatal();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user