From e1d75f008457884a5cefcabbe3ab02309ad1a33f Mon Sep 17 00:00:00 2001 From: Lightos1 <124387232+Lightos1@users.noreply.github.com> Date: Sun, 12 Apr 2026 22:00:45 +0200 Subject: [PATCH] add oc_log files --- .../loader/source/oc/oc_common.hpp | 1 + .../stratosphere/loader/source/oc/oc_log.cpp | 128 ++++++++++++++++++ .../stratosphere/loader/source/oc/oc_log.hpp | 27 ++++ 3 files changed, 156 insertions(+) create mode 100644 Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp create mode 100644 Source/Atmosphere/stratosphere/loader/source/oc/oc_log.hpp diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp index bf05e26f..2e900f72 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp @@ -28,6 +28,7 @@ #endif #include "customize.hpp" +#include "oc_log.hpp" #define PATCH_OFFSET(offset, value) \ static_assert(sizeof(__typeof__(offset)) <= sizeof(u64)); \ diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp new file mode 100644 index 00000000..911ccfae --- /dev/null +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-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 . + */ + +/* See https://github.com/lulle2007200/emuMMC/blob/internal-emummc/source/ */ + +#include "oc_common.hpp" + +#if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) +#include "fatal_handler_bin.h" +#endif + +namespace ams::ldr::hoc { + + #define ATMOSPHERE_REBOOT_TO_FATAL_MAGIC 0x32454641 + #define ATMOSPHERE_IRAM_PAYLOAD_BASE 0x40010000 + #define ATMOSPHERE_FATAL_ERROR_ADDR 0x4003E000 + + _Alignas(4096) u8 working_buf[4096]; + + void SmcRebootToIramPayload() { + SecmonArgs args; + args.X[0] = 0xC3000401; + args.X[1] = 65001; + args.X[2] = 0; + args.X[3] = 2; + svcCallSecureMonitor(&args); + } + + Result SmcCopyToIram(uintptr_t dest, const void *src, u32 size) { + SecmonArgs args; + args.X[0] = 0xF0000201; + args.X[1] = (u64)src; + args.X[2] = (u64)dest; + args.X[3] = size; + args.X[4] = 1; + svcCallSecureMonitor(&args); + Result rc = 0; + if (args.X[0] != 0) { + rc = (26u | ((u32)args.X[0] << 9u)); + } + return rc; + } + + Result SmcCopyFromIram(void *dest, uintptr_t src, u32 size) { + SecmonArgs args; + args.X[0] = 0xF0000201; + args.X[1] = (u64)dest; + args.X[2] = (u64)src; + args.X[3] = size; + args.X[4] = 0; + svcCallSecureMonitor(&args); + Result rc = 0; + if (args.X[0] != 0) { + rc = (26u | ((u32)args.X[0] << 9u)); + } + return rc; + } + + struct log_ctx_t { + u32 magic; + u32 sz; + u32 start; + u32 end; + char buf[]; + }; + + #define IRAM_LOG_CTX_ADDR 0x4003C000 + #define IRAM_LOG_MAX_SZ 4096 + + #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) + void Log(const char *data, ...) { + static const u32 max_log_sz = sizeof(working_buf) - sizeof(log_ctx_t); + static bool initDone = false; + log_ctx_t *log_ctx = (log_ctx_t*)working_buf; + + SmcCopyFromIram(working_buf, IRAM_LOG_CTX_ADDR, sizeof(working_buf)); + + if (!initDone) { + initDone = true; + log_ctx->buf[0] = '\0'; + log_ctx->magic = 0xaabbccdd; + log_ctx->start = 0; + log_ctx->end = 0; + } + + va_list args; + va_start(args, data); + s32 res = vsnprintf(log_ctx->buf + log_ctx->end, max_log_sz - log_ctx->end, data, args); + va_end(args); + + if (res < 0 || res >= (static_cast(max_log_sz - log_ctx->end))) { + SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)); + return; + } + + log_ctx->end += res; + SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)); + } + #endif + + #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) + void ViewLog() { + constexpr size_t PageSize = 4096; + for (size_t ofs = 0; ofs < fatal_handler_bin_size; ofs += PageSize) { + memcpy(&working_buf, fatal_handler_bin + ofs, std::min(fatal_handler_bin_size - ofs, PageSize)); + SmcCopyToIram(ATMOSPHERE_IRAM_PAYLOAD_BASE + ofs, &working_buf, std::min(fatal_handler_bin_size - ofs, PageSize)); + } + + SmcRebootToIramPayload(); + + while(true){} + } + #endif +} diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.hpp new file mode 100644 index 00000000..615405ea --- /dev/null +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-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 . + */ + +/* See https://github.com/lulle2007200/emuMMC/blob/internal-emummc/source/ */ + +#pragma once + +namespace ams::ldr::hoc { + + void Log(const char *data, ...); + void ViewLog(); + +}