diff --git a/config_templates/exosphere.ini b/config_templates/exosphere.ini index dc7b3fde8..b60a3f31c 100644 --- a/config_templates/exosphere.ini +++ b/config_templates/exosphere.ini @@ -35,6 +35,14 @@ # mmc space, encrypted to prevent detection. This backup can be used # to prevent unrecoverable edits in emergencies. +# Key: log_port, default: 0. +# Desc: Controls what uart port exosphere will set up for logging. +# NOTE: 0 = UART-A, 1 = UART-B, 2 = UART-C, 3 = UART-D + +# Key: log_baud_rate, default: 115200 +# Desc: Controls the baud rate exosphere will set up for logging. +# NOTE: 0 is treated as equivalent to 115200. + [exosphere] debugmode=1 debugmode_user=0 @@ -43,3 +51,5 @@ enable_user_pmu_access=0 blank_prodinfo_sysmmc=0 blank_prodinfo_emummc=0 allow_writing_to_cal_sysmmc=0 +log_port=0 +log_baud_rate=115200 diff --git a/exosphere/program/source/secmon_setup.cpp b/exosphere/program/source/secmon_setup.cpp index bf47eec7d..836786252 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(); + log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate()); log::SendText("OHAYO\n", 6); log::Flush(); } diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 9c1e5ae20..e7b52edcc 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -282,6 +282,10 @@ namespace ams::secmon::smc { return SmcResult::NotInitialized; } break; + case ConfigItem::ExosphereLogConfiguration: + /* Get the log configuration. */ + args.r[1] = (static_cast(static_cast(secmon::GetLogPort())) << 32) | static_cast(secmon::GetLogBaudRate()); + break; default: return SmcResult::InvalidArgument; } diff --git a/exosphere/program/source/smc/secmon_smc_info.hpp b/exosphere/program/source/smc/secmon_smc_info.hpp index 7f33cbdba..12870324e 100644 --- a/exosphere/program/source/smc/secmon_smc_info.hpp +++ b/exosphere/program/source/smc/secmon_smc_info.hpp @@ -40,15 +40,16 @@ namespace ams::secmon::smc { Package2Hash = 17, /* Extension config items for exosphere. */ - ExosphereApiVersion = 65000, - ExosphereNeedsReboot = 65001, - ExosphereNeedsShutdown = 65002, - ExosphereGitCommitHash = 65003, - ExosphereHasRcmBugPatch = 65004, - ExosphereBlankProdInfo = 65005, - ExosphereAllowCalWrites = 65006, - ExosphereEmummcType = 65007, - ExospherePayloadAddress = 65008, + ExosphereApiVersion = 65000, + ExosphereNeedsReboot = 65001, + ExosphereNeedsShutdown = 65002, + ExosphereGitCommitHash = 65003, + ExosphereHasRcmBugPatch = 65004, + ExosphereBlankProdInfo = 65005, + ExosphereAllowCalWrites = 65006, + ExosphereEmummcType = 65007, + ExospherePayloadAddress = 65008, + ExosphereLogConfiguration = 65009, }; SmcResult SmcGetConfigUser(SmcArguments &args); diff --git a/exosphere/program/source/smc/secmon_smc_power_management.cpp b/exosphere/program/source/smc/secmon_smc_power_management.cpp index 7ed5f3377..6de49c6c8 100644 --- a/exosphere/program/source/smc/secmon_smc_power_management.cpp +++ b/exosphere/program/source/smc/secmon_smc_power_management.cpp @@ -409,6 +409,7 @@ namespace ams::secmon::smc { /* NOTE: Nintendo only does this on dev, but we will always do it. */ if (true /* !pkg1::IsProduction() */) { log::SendText("OYASUMI\n", 8); + log::Flush(); } /* If we're on erista, configure the bootrom to allow our custom warmboot firmware. */ diff --git a/fusee/fusee-secondary/src/exocfg.h b/fusee/fusee-secondary/src/exocfg.h index 933ffad49..7aac28bb5 100644 --- a/fusee/fusee-secondary/src/exocfg.h +++ b/fusee/fusee-secondary/src/exocfg.h @@ -37,8 +37,12 @@ typedef struct { uint32_t magic; uint32_t target_firmware; - uint32_t flags; - uint32_t reserved[5]; + uint32_t flags[2]; + uint16_t lcd_vendor; + uint8_t reserved0; + uint8_t log_port; + uint32_t log_baud_rate; + uint32_t reserved1[2]; exo_emummc_config_t emummc_cfg; } exosphere_config_t; @@ -54,6 +58,8 @@ _Static_assert(sizeof(exosphere_config_t) == 0x20 + sizeof(exo_emummc_config_t), #define EXOSPHERE_BLANK_PRODINFO_SYSMMC_KEY "blank_prodinfo_sysmmc" #define EXOSPHERE_BLANK_PRODINFO_EMUMMC_KEY "blank_prodinfo_emummc" #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" typedef struct { int debugmode; @@ -63,6 +69,8 @@ typedef struct { int blank_prodinfo_sysmmc; int blank_prodinfo_emummc; int allow_writing_to_cal_sysmmc; + int log_port; + int log_baud_rate; } exosphere_parse_cfg_t; #endif diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index d1a329c2d..e797ac01b 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -196,6 +196,20 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na } else if (tmp == 0) { parse_cfg->allow_writing_to_cal_sysmmc = 0; } + } else if (strcmp(name, EXOSPHERE_LOG_PORT_KEY) == 0) { + sscanf(value, "%d", &tmp); + if (0 <= tmp && tmp < 4) { + parse_cfg->log_port = tmp; + } else { + parse_cfg->log_port = 0; + } + } else if (strcmp(name, EXOSPHERE_LOG_BAUD_RATE_KEY) == 0) { + sscanf(value, "%d", &tmp); + if (tmp > 0) { + parse_cfg->log_baud_rate = tmp; + } else { + parse_cfg->log_baud_rate = 115200; + } } else { return 0; } @@ -478,6 +492,8 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke .blank_prodinfo_sysmmc = 0, .blank_prodinfo_emummc = 0, .allow_writing_to_cal_sysmmc = 0, + .log_port = 0, + .log_baud_rate = 115200, }; /* If we have an ini to read, parse it. */ @@ -498,6 +514,9 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke if (parse_cfg.blank_prodinfo_emummc && is_emummc) exo_cfg.flags |= EXOSPHERE_FLAG_BLANK_PRODINFO; if (parse_cfg.allow_writing_to_cal_sysmmc) exo_cfg.flags |= EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC; + exo_cfg.log_port = parse_cfg.log_port; + exo_cfg.log_baud_rate = parse_cfg.log_baud_rate; + 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 7ddde611d..cecf8d156 100644 --- a/libraries/libexosphere/include/exosphere/log.hpp +++ b/libraries/libexosphere/include/exosphere/log.hpp @@ -35,6 +35,7 @@ namespace ams::log { #endif void Initialize(); + void Initialize(uart::Port port, u32 baud_rate); 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 bddcf1b75..aa231787f 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 @@ -116,6 +116,14 @@ namespace ams::secmon { return GetSecmonConfiguration().GetLcdVendor(); } + ALWAYS_INLINE uart::Port GetLogPort() { + return GetSecmonConfiguration().GetLogPort(); + } + + ALWAYS_INLINE u32 GetLogBaudRate() { + return GetSecmonConfiguration().GetLogBaudRate(); + } + ALWAYS_INLINE bool IsProduction() { return GetSecmonConfiguration().IsProduction(); } diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp index c29708018..f53a633d0 100644 --- a/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp +++ b/libraries/libexosphere/include/exosphere/secmon/secmon_monitor_context.hpp @@ -16,6 +16,7 @@ #pragma once #include #include +#include #include namespace ams::secmon { @@ -39,8 +40,10 @@ namespace ams::secmon { ams::TargetFirmware target_firmware; u32 flags[2]; u16 lcd_vendor; - u16 reserved0; - u32 reserved1[3]; + u8 reserved0; + u8 log_port; + u32 log_baud_rate; + u32 reserved1[2]; EmummcConfiguration emummc_cfg; constexpr bool IsValid() const { return this->magic == Magic; } @@ -54,17 +57,20 @@ namespace ams::secmon { u8 hardware_type; u8 soc_type; u8 hardware_state; - u8 pad_0B[1]; + u8 log_port; u32 flags[2]; u16 lcd_vendor; u16 reserved0; - u32 reserved1[(0x80 - 0x18) / sizeof(u32)]; + u32 log_baud_rate; + u32 reserved1[(0x80 - 0x1C) / sizeof(u32)]; constexpr void CopyFrom(const SecureMonitorStorageConfiguration &storage) { this->target_firmware = storage.target_firmware; this->flags[0] = storage.flags[0]; this->flags[1] = storage.flags[1]; this->lcd_vendor = storage.lcd_vendor; + this->log_port = storage.log_port; + this->log_baud_rate = storage.log_baud_rate != 0 ? storage.log_baud_rate : 115200; } void SetFuseInfo() { @@ -78,9 +84,12 @@ namespace ams::secmon { constexpr fuse::HardwareType GetHardwareType() const { return static_cast(this->hardware_type); } 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 u16 GetLcdVendor() const { return this->lcd_vendor; } + constexpr u32 GetLogBaudRate() const { return this->log_baud_rate; } + constexpr bool IsProduction() const { return this->GetHardwareState() != fuse::HardwareState_Development; } constexpr bool IsDevelopmentFunctionEnabledForKernel() const { return (this->flags[0] & SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel) != 0; } @@ -101,10 +110,11 @@ namespace ams::secmon { .hardware_type = {}, .soc_type = {}, .hardware_state = {}, - .pad_0B = {}, + .log_port = uart::Port_ReservedDebug, .flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None }, .lcd_vendor = {}, .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 068dddc20..5ce2831c2 100644 --- a/libraries/libexosphere/source/log/log_api.cpp +++ b/libraries/libexosphere/source/log/log_api.cpp @@ -19,58 +19,63 @@ namespace ams::log { namespace { - constexpr inline uart::Port UartLogPort = uart::Port_ReservedDebug; - constexpr inline int UartBaudRate = 115200; + constexpr inline uart::Port DefaultLogPort = uart::Port_ReservedDebug; + constexpr inline int DefaultBaudRate = 115200; + constinit uart::Port g_log_port = DefaultLogPort; constinit bool g_initialized_uart = false; - constexpr inline u32 UartPortFlags = [] { - if constexpr (UartLogPort == uart::Port_ReservedDebug) { - /* Logging to the debug port. */ - /* Don't invert transactions. */ - return uart::Flag_None; - } else if constexpr (UartLogPort == uart::Port_LeftJoyCon) { - /* Logging to left joy-con (e.g. with Joyless). */ - /* Invert transactions. */ - return uart::Flag_Inverted; - } else if constexpr (UartLogPort == uart::Port_RightJoyCon) { - /* Logging to right joy-con (e.g. with Joyless). */ - /* Invert transactions. */ - return uart::Flag_Inverted; - } else { - __builtin_unreachable(); + 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 SetupUart() { - if constexpr (UartLogPort == uart::Port_ReservedDebug) { - /* Logging to the debug port. */ - pinmux::SetupUartA(); - clkrst::EnableUartAClock(); - } else if constexpr (UartLogPort == uart::Port_LeftJoyCon) { + ALWAYS_INLINE void SetupUartClock(uart::Port port) { + /* The debug port must always be set up, for compatibility with official hos. */ + pinmux::SetupUartA(); + clkrst::EnableUartAClock(); + + /* If logging to a joy-con port, configure appropriately. */ + if (port == uart::Port_LeftJoyCon) { /* Logging to left joy-con (e.g. with Joyless). */ static_assert(uart::Port_LeftJoyCon == uart::Port_C); pinmux::SetupUartC(); clkrst::EnableUartCClock(); - } else if constexpr (UartLogPort == uart::Port_RightJoyCon) { + } else if (port == uart::Port_RightJoyCon) { /* Logging to right joy-con (e.g. with Joyless). */ static_assert(uart::Port_RightJoyCon == uart::Port_B); pinmux::SetupUartB(); clkrst::EnableUartBClock(); - } else { - __builtin_unreachable(); } } } void Initialize() { + return Initialize(DefaultLogPort, DefaultBaudRate); + } + + void Initialize(uart::Port port, u32 baud_rate) { /* Initialize pinmux and clock for the target uart port. */ - SetupUart(); + SetupUartClock(port); /* Initialize the target uart port. */ - uart::Initialize(UartLogPort, UartBaudRate, UartPortFlags); + uart::Initialize(port, baud_rate, GetPortFlags(port)); /* Note that we've initialized. */ + g_log_port = port; g_initialized_uart = true; } @@ -84,7 +89,7 @@ namespace ams::log { const auto len = util::TVSNPrintf(log_buf, sizeof(log_buf), fmt, vl); if (g_initialized_uart) { - uart::SendText(UartLogPort, log_buf, len); + uart::SendText(g_log_port, log_buf, len); } } @@ -115,13 +120,13 @@ namespace ams::log { void SendText(const void *text, size_t size) { if (g_initialized_uart) { - uart::SendText(UartLogPort, text, size); + uart::SendText(g_log_port, text, size); } } void Flush() { if (g_initialized_uart) { - uart::WaitFlush(UartLogPort); + uart::WaitFlush(g_log_port); } } diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp index c72015d01..f9d99aecf 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp @@ -30,6 +30,7 @@ namespace ams::kern::board::nintendo::nx { static size_t GetApplicationPoolSize(); static size_t GetAppletPoolSize(); static size_t GetMinimumNonSecureSystemPoolSize(); + static u8 GetDebugLogUartPort(); /* Randomness. */ static void GenerateRandomBytes(void *dst, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp b/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp index e2cde1342..4f19c19a6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_debug_log.hpp @@ -40,7 +40,7 @@ namespace ams::kern { #ifndef MESOSPHERE_DEBUG_LOG_SELECTED #ifdef ATMOSPHERE_BOARD_NINTENDO_NX - #define MESOSPHERE_DEBUG_LOG_USE_UART_A + #define MESOSPHERE_DEBUG_LOG_USE_UART #else #error "Unknown board for Default Debug Log Source" #endif diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index a54bf2c13..df41785d5 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -409,6 +409,15 @@ namespace ams::kern::board::nintendo::nx { return MinimumSize; } + u8 KSystemControl::Init::GetDebugLogUartPort() { + /* Get the log configuration. */ + u64 value = 0; + smc::init::GetConfig(std::addressof(value), 1, smc::ConfigItem::ExosphereLogConfiguration); + + /* Extract the port. */ + return static_cast((value >> 32) & 0xFF); + } + void KSystemControl::Init::CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { smc::init::CpuOn(core_id, entrypoint, arg); } diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp index b7d17072e..22233b78f 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -55,15 +55,16 @@ namespace ams::kern::board::nintendo::nx::smc { Package2Hash = 17, /* Extension config items for exosphere. */ - ExosphereApiVersion = 65000, - ExosphereNeedsReboot = 65001, - ExosphereNeedsShutdown = 65002, - ExosphereGitCommitHash = 65003, - ExosphereHasRcmBugPatch = 65004, - ExosphereBlankProdInfo = 65005, - ExosphereAllowCalWrites = 65006, - ExosphereEmummcType = 65007, - ExospherePayloadAddress = 65008, + ExosphereApiVersion = 65000, + ExosphereNeedsReboot = 65001, + ExosphereNeedsShutdown = 65002, + ExosphereGitCommitHash = 65003, + ExosphereHasRcmBugPatch = 65004, + ExosphereBlankProdInfo = 65005, + ExosphereAllowCalWrites = 65006, + ExosphereEmummcType = 65007, + ExospherePayloadAddress = 65008, + ExosphereLogConfiguration = 65009, }; enum class SmcResult { diff --git a/libraries/libmesosphere/source/kern_debug_log_impl.board.nintendo_nx.cpp b/libraries/libmesosphere/source/kern_debug_log_impl.board.nintendo_nx.cpp index 470287b9b..9b516e29f 100644 --- a/libraries/libmesosphere/source/kern_debug_log_impl.board.nintendo_nx.cpp +++ b/libraries/libmesosphere/source/kern_debug_log_impl.board.nintendo_nx.cpp @@ -18,10 +18,12 @@ namespace ams::kern { -#if defined(MESOSPHERE_DEBUG_LOG_USE_UART_A) || defined(MESOSPHERE_DEBUG_LOG_USE_UART_B) || defined(MESOSPHERE_DEBUG_LOG_USE_UART_C) || defined(MESOSPHERE_DEBUG_LOG_USE_UART_D) +#if defined(MESOSPHERE_DEBUG_LOG_USE_UART) namespace { + constexpr bool DoSaveAndRestore = false; + enum UartRegister { UartRegister_THR = 0, UartRegister_IER = 1, @@ -38,13 +40,13 @@ namespace ams::kern { KVirtualAddress g_uart_address = 0; - constinit u32 g_saved_registers[5]; + [[maybe_unused]] constinit u32 g_saved_registers[5]; - NOINLINE u32 ReadUartRegister(UartRegister which) { + ALWAYS_INLINE u32 ReadUartRegister(UartRegister which) { return GetPointer(g_uart_address)[which]; } - NOINLINE void WriteUartRegister(UartRegister which, u32 value) { + ALWAYS_INLINE void WriteUartRegister(UartRegister which, u32 value) { GetPointer(g_uart_address)[which] = value; } @@ -86,43 +88,47 @@ namespace ams::kern { } void KDebugLogImpl::Save() { - /* Save LCR, IER, FCR. */ - g_saved_registers[0] = ReadUartRegister(UartRegister_LCR); - g_saved_registers[1] = ReadUartRegister(UartRegister_IER); - g_saved_registers[2] = ReadUartRegister(UartRegister_FCR); + if constexpr (DoSaveAndRestore) { + /* Save LCR, IER, FCR. */ + g_saved_registers[0] = ReadUartRegister(UartRegister_LCR); + g_saved_registers[1] = ReadUartRegister(UartRegister_IER); + g_saved_registers[2] = ReadUartRegister(UartRegister_FCR); - /* Set Divisor Latch Access bit, to allow access to DLL/DLH */ - WriteUartRegister(UartRegister_LCR, 0x80); - ReadUartRegister(UartRegister_LCR); + /* Set Divisor Latch Access bit, to allow access to DLL/DLH */ + WriteUartRegister(UartRegister_LCR, 0x80); + ReadUartRegister(UartRegister_LCR); - /* Save DLL/DLH. */ - g_saved_registers[3] = ReadUartRegister(UartRegister_DLL); - g_saved_registers[4] = ReadUartRegister(UartRegister_DLH); + /* Save DLL/DLH. */ + g_saved_registers[3] = ReadUartRegister(UartRegister_DLL); + g_saved_registers[4] = ReadUartRegister(UartRegister_DLH); - /* Restore Divisor Latch Access bit. */ - WriteUartRegister(UartRegister_LCR, g_saved_registers[0]); - ReadUartRegister(UartRegister_LCR); + /* Restore Divisor Latch Access bit. */ + WriteUartRegister(UartRegister_LCR, g_saved_registers[0]); + ReadUartRegister(UartRegister_LCR); + } } void KDebugLogImpl::Restore() { - /* Set Divisor Latch Access bit, to allow access to DLL/DLH */ - WriteUartRegister(UartRegister_LCR, 0x80); - ReadUartRegister(UartRegister_LCR); + if constexpr (DoSaveAndRestore) { + /* Set Divisor Latch Access bit, to allow access to DLL/DLH */ + WriteUartRegister(UartRegister_LCR, 0x80); + ReadUartRegister(UartRegister_LCR); - /* Restore DLL/DLH. */ - WriteUartRegister(UartRegister_DLL, g_saved_registers[3]); - WriteUartRegister(UartRegister_DLH, g_saved_registers[4]); - ReadUartRegister(UartRegister_DLH); + /* Restore DLL/DLH. */ + WriteUartRegister(UartRegister_DLL, g_saved_registers[3]); + WriteUartRegister(UartRegister_DLH, g_saved_registers[4]); + ReadUartRegister(UartRegister_DLH); - /* Restore Divisor Latch Access bit. */ - WriteUartRegister(UartRegister_LCR, g_saved_registers[0]); - ReadUartRegister(UartRegister_LCR); + /* Restore Divisor Latch Access bit. */ + WriteUartRegister(UartRegister_LCR, g_saved_registers[0]); + ReadUartRegister(UartRegister_LCR); - /* Restore IER and FCR. */ - WriteUartRegister(UartRegister_IER, g_saved_registers[1]); - WriteUartRegister(UartRegister_FCR, g_saved_registers[2] | 2); - WriteUartRegister(UartRegister_IRDA_CSR, 0x02); - ReadUartRegister(UartRegister_FCR); + /* Restore IER and FCR. */ + WriteUartRegister(UartRegister_IER, g_saved_registers[1]); + WriteUartRegister(UartRegister_FCR, g_saved_registers[2] | 2); + WriteUartRegister(UartRegister_IRDA_CSR, 0x02); + ReadUartRegister(UartRegister_FCR); + } } #elif defined(MESOSPHERE_DEBUG_LOG_USE_IRAM_RINGBUFFER) diff --git a/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp b/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp index 8c051a15c..129edaba4 100644 --- a/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_layout.board.nintendo_nx.cpp @@ -26,14 +26,14 @@ namespace ams::kern { constexpr size_t CarveoutSizeMax = 512_MB - CarveoutAlignment; ALWAYS_INLINE bool SetupUartPhysicalMemoryRegion() { - #if defined(MESOSPHERE_DEBUG_LOG_USE_UART_A) - return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); - #elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_B) - return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); - #elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_C) - return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); - #elif defined(MESOSPHERE_DEBUG_LOG_USE_UART_D) - return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006300, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); + #if defined(MESOSPHERE_DEBUG_LOG_USE_UART) + switch (KSystemControl::Init::GetDebugLogUartPort()) { + case 0: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006000, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); + case 1: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006040, 0x40, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); + case 2: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006200, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); + case 3: return KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(0x70006300, 0x100, KMemoryRegionType_Uart | KMemoryRegionAttr_ShouldKernelMap); + default: return false; + } #elif defined(MESOSPHERE_DEBUG_LOG_USE_IRAM_RINGBUFFER) return true; #else