From 63e3c02688839b7336e186078dbe274a0405ba5a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 11 Dec 2020 03:18:21 -0800 Subject: [PATCH] fusee/exo: support dynamic control of invert flag for logging --- config_templates/exosphere.ini | 4 +++ exosphere/program/source/secmon_setup.cpp | 2 +- fusee/fusee-secondary/src/exocfg.h | 6 ++++- fusee/fusee-secondary/src/kernel_patches.c | 2 +- fusee/fusee-secondary/src/nxboot.c | 9 +++++++ .../libexosphere/include/exosphere/log.hpp | 2 +- ...ecmon_configuration_context.arch.arm64.hpp | 4 +++ .../secmon/secmon_monitor_context.hpp | 8 ++++-- libraries/libexosphere/source/log/log_api.cpp | 25 +++---------------- 9 files changed, 35 insertions(+), 27 deletions(-) diff --git a/config_templates/exosphere.ini b/config_templates/exosphere.ini index b60a3f31c..e8dc82377 100644 --- a/config_templates/exosphere.ini +++ b/config_templates/exosphere.ini @@ -43,6 +43,9 @@ # Desc: Controls the baud rate exosphere will set up for logging. # NOTE: 0 is treated as equivalent to 115200. +# Key: log_inverted, default: 0. +# Desc: Controls whether the logging uart port is inverted. + [exosphere] debugmode=1 debugmode_user=0 @@ -53,3 +56,4 @@ blank_prodinfo_emummc=0 allow_writing_to_cal_sysmmc=0 log_port=0 log_baud_rate=115200 +log_inverted=0 diff --git a/exosphere/program/source/secmon_setup.cpp b/exosphere/program/source/secmon_setup.cpp index 836786252..5eabdbdd6 100644 --- a/exosphere/program/source/secmon_setup.cpp +++ b/exosphere/program/source/secmon_setup.cpp @@ -960,7 +960,7 @@ namespace ams::secmon { } void SetupLogForBoot() { - log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate()); + log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate(), secmon::GetLogFlags()); log::SendText("OHAYO\n", 6); log::Flush(); } diff --git a/fusee/fusee-secondary/src/exocfg.h b/fusee/fusee-secondary/src/exocfg.h index 7aac28bb5..36cca04dc 100644 --- a/fusee/fusee-secondary/src/exocfg.h +++ b/fusee/fusee-secondary/src/exocfg.h @@ -34,13 +34,15 @@ #define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u) #define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u) +#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u) + typedef struct { uint32_t magic; uint32_t target_firmware; uint32_t flags[2]; uint16_t lcd_vendor; - uint8_t reserved0; uint8_t log_port; + uint8_t log_flags; uint32_t log_baud_rate; uint32_t reserved1[2]; exo_emummc_config_t emummc_cfg; @@ -60,6 +62,7 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t), #define EXOSPHERE_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc" #define EXOSPHERE_LOG_PORT_KEY "log_port" #define EXOSPHERE_LOG_BAUD_RATE_KEY "log_baud_rate" +#define EXOSPHERE_LOG_INVERTED_KEY "log_inverted" typedef struct { int debugmode; @@ -71,6 +74,7 @@ typedef struct { int allow_writing_to_cal_sysmmc; int log_port; int log_baud_rate; + int log_inverted; } exosphere_parse_cfg_t; #endif diff --git a/fusee/fusee-secondary/src/kernel_patches.c b/fusee/fusee-secondary/src/kernel_patches.c index 8e82de0a7..6678f8008 100644 --- a/fusee/fusee-secondary/src/kernel_patches.c +++ b/fusee/fusee-secondary/src/kernel_patches.c @@ -1031,7 +1031,7 @@ static const kernel_info_t g_kernel_infos[] = { KERNEL_PATCHES(1100) }, { /* 11.0.1. */ - .hash = {68B972B79755875E24958D990A77ABF1C5C1328067F0A2EC9CEFC322E342C04D, }, + .hash = {0x68, 0xB9, 0x72, 0xB7, 0x97, 0x55, 0x87, 0x5E, 0x24, 0x95, 0x8D, 0x99, 0x0A, 0x77, 0xAB, 0xF1, 0xC5, 0xC1, 0x32, 0x80, 0x67, 0xF0, 0xA2, 0xEC, 0x9C, 0xEF, 0xC3, 0x22, 0xE3, 0x42, 0xC0, 0x4D, }, .hash_offset = 0x1C4, .hash_size = 0x69000 - 0x1C4, .embedded_ini_offset = 0x69000, diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 7400aa6b9..a53c6522b 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -210,6 +210,13 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na } else { parse_cfg->log_baud_rate = 115200; } + } else if (strcmp(name, EXOSPHERE_LOG_INVERTED_KEY) == 0) { + sscanf(value, "%d", &tmp); + if (tmp == 1) { + parse_cfg->log_inverted = 1; + } else if (tmp == 0) { + parse_cfg->log_inverted = 0; + } } else { return 0; } @@ -495,6 +502,7 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke .allow_writing_to_cal_sysmmc = 0, .log_port = 0, .log_baud_rate = 115200, + .log_inverted = 0, }; /* If we have an ini to read, parse it. */ @@ -517,6 +525,7 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke exo_cfg.log_port = parse_cfg.log_port; exo_cfg.log_baud_rate = parse_cfg.log_baud_rate; + if (parse_cfg.log_inverted) exo_cfg.log_flags |= EXOSPHERE_LOG_FLAG_INVERTED; if ((exo_cfg.target_firmware < ATMOSPHERE_TARGET_FIRMWARE_MIN) || (exo_cfg.target_firmware > ATMOSPHERE_TARGET_FIRMWARE_MAX)) { fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n"); diff --git a/libraries/libexosphere/include/exosphere/log.hpp b/libraries/libexosphere/include/exosphere/log.hpp index cecf8d156..2afd8e4a1 100644 --- a/libraries/libexosphere/include/exosphere/log.hpp +++ b/libraries/libexosphere/include/exosphere/log.hpp @@ -35,7 +35,7 @@ namespace ams::log { #endif void Initialize(); - void Initialize(uart::Port port, u32 baud_rate); + void Initialize(uart::Port port, u32 baud_rate, u32 flags); void Finalize(); void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp index aa231787f..7e554676d 100644 --- a/libraries/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp +++ b/libraries/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp @@ -120,6 +120,10 @@ namespace ams::secmon { return GetSecmonConfiguration().GetLogPort(); } + ALWAYS_INLINE u8 GetLogFlags() { + return GetSecmonConfiguration().GetLogFlags(); + } + ALWAYS_INLINE u32 GetLogBaudRate() { return GetSecmonConfiguration().GetLogBaudRate(); } diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp index f53a633d0..6c974b1c7 100644 --- a/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp +++ b/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp @@ -40,8 +40,8 @@ namespace ams::secmon { ams::TargetFirmware target_firmware; u32 flags[2]; u16 lcd_vendor; - u8 reserved0; u8 log_port; + u8 log_flags; u32 log_baud_rate; u32 reserved1[2]; EmummcConfiguration emummc_cfg; @@ -60,7 +60,8 @@ namespace ams::secmon { u8 log_port; u32 flags[2]; u16 lcd_vendor; - u16 reserved0; + u8 log_flags; + u8 reserved0; u32 log_baud_rate; u32 reserved1[(0x80 - 0x1C) / sizeof(u32)]; @@ -70,6 +71,7 @@ namespace ams::secmon { this->flags[1] = storage.flags[1]; this->lcd_vendor = storage.lcd_vendor; this->log_port = storage.log_port; + this->log_flags = storage.log_flags; this->log_baud_rate = storage.log_baud_rate != 0 ? storage.log_baud_rate : 115200; } @@ -85,6 +87,7 @@ namespace ams::secmon { constexpr fuse::SocType GetSocType() const { return static_cast(this->soc_type); } constexpr fuse::HardwareState GetHardwareState() const { return static_cast(this->hardware_state); } constexpr uart::Port GetLogPort() const { return static_cast(this->log_port); } + constexpr u8 GetLogFlags() const { return this->log_flags; } constexpr u16 GetLcdVendor() const { return this->lcd_vendor; } @@ -113,6 +116,7 @@ namespace ams::secmon { .log_port = uart::Port_ReservedDebug, .flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None }, .lcd_vendor = {}, + .log_flags = {}, .reserved0 = {}, .log_baud_rate = 115200, .reserved1 = {}, diff --git a/libraries/libexosphere/source/log/log_api.cpp b/libraries/libexosphere/source/log/log_api.cpp index 5ce2831c2..62b40ab04 100644 --- a/libraries/libexosphere/source/log/log_api.cpp +++ b/libraries/libexosphere/source/log/log_api.cpp @@ -20,28 +20,11 @@ namespace ams::log { namespace { constexpr inline uart::Port DefaultLogPort = uart::Port_ReservedDebug; + constexpr inline u32 DefaultLogFlags = static_cast(uart::Flag_None); constexpr inline int DefaultBaudRate = 115200; constinit uart::Port g_log_port = DefaultLogPort; constinit bool g_initialized_uart = false; - ALWAYS_INLINE u32 GetPortFlags(uart::Port port) { - switch (port) { - case uart::Port_ReservedDebug: - /* Logging to the debug port. */ - /* Don't invert transactions. */ - return uart::Flag_None; - case uart::Port_LeftJoyCon: - /* Logging to left joy-con (e.g. with Joyless). */ - /* Invert transactions. */ - return uart::Flag_Inverted; - case uart::Port_RightJoyCon: - /* Logging to right joy-con (e.g. with Joyless). */ - /* Invert transactions. */ - return uart::Flag_Inverted; - AMS_UNREACHABLE_DEFAULT_CASE(); - } - } - ALWAYS_INLINE void SetupUartClock(uart::Port port) { /* The debug port must always be set up, for compatibility with official hos. */ pinmux::SetupUartA(); @@ -64,15 +47,15 @@ namespace ams::log { } void Initialize() { - return Initialize(DefaultLogPort, DefaultBaudRate); + return Initialize(DefaultLogPort, DefaultBaudRate, DefaultLogFlags); } - void Initialize(uart::Port port, u32 baud_rate) { + void Initialize(uart::Port port, u32 baud_rate, u32 flags) { /* Initialize pinmux and clock for the target uart port. */ SetupUartClock(port); /* Initialize the target uart port. */ - uart::Initialize(port, baud_rate, GetPortFlags(port)); + uart::Initialize(port, baud_rate, flags); /* Note that we've initialized. */ g_log_port = port;