/* * Copyright (c) 2018-2020 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 extern "C" void _start(); namespace ams::result::impl { NORETURN void OnResultAssertion(Result result) { MESOSPHERE_PANIC("OnResultAssertion(2%03d-%04d)", result.GetModule(), result.GetDescription()); } } namespace ams::kern { namespace { size_t g_panic_count = 0; [[gnu::unused]] void PrintCurrentState() { if (g_panic_count == 1) { g_panic_count++; MESOSPHERE_RELEASE_LOG("Base Address: %p\n", _start); /* TODO: Dump register state. */ #ifdef ATMOSPHERE_ARCH_ARM64 MESOSPHERE_RELEASE_LOG("Backtrace:\n"); uintptr_t fp = reinterpret_cast(__builtin_frame_address(0)); for (size_t i = 0; i < 32 && fp && util::IsAligned(fp, 0x10) && cpu::GetPhysicalAddressWritable(nullptr, fp, true); i++) { struct { uintptr_t fp; uintptr_t lr; } *stack_frame = reinterpret_cast(fp); MESOSPHERE_RELEASE_LOG(" [%02zx]: %p\n", i, reinterpret_cast(stack_frame->lr)); fp = stack_frame->fp; } #endif } } NORETURN void StopSystem() { #ifdef MESOSPHERE_BUILD_FOR_DEBUGGING PrintCurrentState(); #endif KSystemControl::StopSystem(); } } NORETURN WEAK_SYMBOL void Panic(const char *file, int line, const char *format, ...) { #ifdef MESOSPHERE_BUILD_FOR_DEBUGGING if (g_panic_count == 0) { g_panic_count++; ::std::va_list vl; va_start(vl, format); MESOSPHERE_RELEASE_LOG("KernelPanic (Core %d): %s:%d\n", GetCurrentCoreId(), file, line); MESOSPHERE_RELEASE_VLOG(format, vl); MESOSPHERE_RELEASE_LOG("\n"); va_end(vl); } #endif StopSystem(); } NORETURN WEAK_SYMBOL void Panic() { StopSystem(); } }