fusee/exo: support dynamic control of invert flag for logging

This commit is contained in:
Michael Scire 2020-12-11 03:18:21 -08:00
parent 14a415c4b2
commit 63e3c02688
9 changed files with 35 additions and 27 deletions

View file

@ -43,6 +43,9 @@
# Desc: Controls the baud rate exosphere will set up for logging. # Desc: Controls the baud rate exosphere will set up for logging.
# NOTE: 0 is treated as equivalent to 115200. # NOTE: 0 is treated as equivalent to 115200.
# Key: log_inverted, default: 0.
# Desc: Controls whether the logging uart port is inverted.
[exosphere] [exosphere]
debugmode=1 debugmode=1
debugmode_user=0 debugmode_user=0
@ -53,3 +56,4 @@ blank_prodinfo_emummc=0
allow_writing_to_cal_sysmmc=0 allow_writing_to_cal_sysmmc=0
log_port=0 log_port=0
log_baud_rate=115200 log_baud_rate=115200
log_inverted=0

View file

@ -960,7 +960,7 @@ namespace ams::secmon {
} }
void SetupLogForBoot() { void SetupLogForBoot() {
log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate()); log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate(), secmon::GetLogFlags());
log::SendText("OHAYO\n", 6); log::SendText("OHAYO\n", 6);
log::Flush(); log::Flush();
} }

View file

@ -34,13 +34,15 @@
#define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u) #define EXOSPHERE_FLAG_BLANK_PRODINFO (1 << 5u)
#define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u) #define EXOSPHERE_FLAG_ALLOW_WRITING_TO_CAL_SYSMMC (1 << 6u)
#define EXOSPHERE_LOG_FLAG_INVERTED (1 << 0u)
typedef struct { typedef struct {
uint32_t magic; uint32_t magic;
uint32_t target_firmware; uint32_t target_firmware;
uint32_t flags[2]; uint32_t flags[2];
uint16_t lcd_vendor; uint16_t lcd_vendor;
uint8_t reserved0;
uint8_t log_port; uint8_t log_port;
uint8_t log_flags;
uint32_t log_baud_rate; uint32_t log_baud_rate;
uint32_t reserved1[2]; uint32_t reserved1[2];
exo_emummc_config_t emummc_cfg; 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_ALLOW_WRITING_TO_CAL_SYSMMC_KEY "allow_writing_to_cal_sysmmc"
#define EXOSPHERE_LOG_PORT_KEY "log_port" #define EXOSPHERE_LOG_PORT_KEY "log_port"
#define EXOSPHERE_LOG_BAUD_RATE_KEY "log_baud_rate" #define EXOSPHERE_LOG_BAUD_RATE_KEY "log_baud_rate"
#define EXOSPHERE_LOG_INVERTED_KEY "log_inverted"
typedef struct { typedef struct {
int debugmode; int debugmode;
@ -71,6 +74,7 @@ typedef struct {
int allow_writing_to_cal_sysmmc; int allow_writing_to_cal_sysmmc;
int log_port; int log_port;
int log_baud_rate; int log_baud_rate;
int log_inverted;
} exosphere_parse_cfg_t; } exosphere_parse_cfg_t;
#endif #endif

View file

@ -1031,7 +1031,7 @@ static const kernel_info_t g_kernel_infos[] = {
KERNEL_PATCHES(1100) KERNEL_PATCHES(1100)
}, },
{ /* 11.0.1. */ { /* 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_offset = 0x1C4,
.hash_size = 0x69000 - 0x1C4, .hash_size = 0x69000 - 0x1C4,
.embedded_ini_offset = 0x69000, .embedded_ini_offset = 0x69000,

View file

@ -210,6 +210,13 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
} else { } else {
parse_cfg->log_baud_rate = 115200; 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 { } else {
return 0; return 0;
} }
@ -495,6 +502,7 @@ static void nxboot_configure_exosphere(uint32_t target_firmware, unsigned int ke
.allow_writing_to_cal_sysmmc = 0, .allow_writing_to_cal_sysmmc = 0,
.log_port = 0, .log_port = 0,
.log_baud_rate = 115200, .log_baud_rate = 115200,
.log_inverted = 0,
}; };
/* If we have an ini to read, parse it. */ /* 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_port = parse_cfg.log_port;
exo_cfg.log_baud_rate = parse_cfg.log_baud_rate; 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)) { 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"); fatal_error("[NXBOOT] Invalid Exosphere target firmware!\n");

View file

@ -35,7 +35,7 @@ namespace ams::log {
#endif #endif
void Initialize(); void Initialize();
void Initialize(uart::Port port, u32 baud_rate); void Initialize(uart::Port port, u32 baud_rate, u32 flags);
void Finalize(); void Finalize();
void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void Printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));

View file

@ -120,6 +120,10 @@ namespace ams::secmon {
return GetSecmonConfiguration().GetLogPort(); return GetSecmonConfiguration().GetLogPort();
} }
ALWAYS_INLINE u8 GetLogFlags() {
return GetSecmonConfiguration().GetLogFlags();
}
ALWAYS_INLINE u32 GetLogBaudRate() { ALWAYS_INLINE u32 GetLogBaudRate() {
return GetSecmonConfiguration().GetLogBaudRate(); return GetSecmonConfiguration().GetLogBaudRate();
} }

View file

@ -40,8 +40,8 @@ namespace ams::secmon {
ams::TargetFirmware target_firmware; ams::TargetFirmware target_firmware;
u32 flags[2]; u32 flags[2];
u16 lcd_vendor; u16 lcd_vendor;
u8 reserved0;
u8 log_port; u8 log_port;
u8 log_flags;
u32 log_baud_rate; u32 log_baud_rate;
u32 reserved1[2]; u32 reserved1[2];
EmummcConfiguration emummc_cfg; EmummcConfiguration emummc_cfg;
@ -60,7 +60,8 @@ namespace ams::secmon {
u8 log_port; u8 log_port;
u32 flags[2]; u32 flags[2];
u16 lcd_vendor; u16 lcd_vendor;
u16 reserved0; u8 log_flags;
u8 reserved0;
u32 log_baud_rate; u32 log_baud_rate;
u32 reserved1[(0x80 - 0x1C) / sizeof(u32)]; u32 reserved1[(0x80 - 0x1C) / sizeof(u32)];
@ -70,6 +71,7 @@ namespace ams::secmon {
this->flags[1] = storage.flags[1]; this->flags[1] = storage.flags[1];
this->lcd_vendor = storage.lcd_vendor; this->lcd_vendor = storage.lcd_vendor;
this->log_port = storage.log_port; 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; 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<fuse::SocType>(this->soc_type); } constexpr fuse::SocType GetSocType() const { return static_cast<fuse::SocType>(this->soc_type); }
constexpr fuse::HardwareState GetHardwareState() const { return static_cast<fuse::HardwareState>(this->hardware_state); } constexpr fuse::HardwareState GetHardwareState() const { return static_cast<fuse::HardwareState>(this->hardware_state); }
constexpr uart::Port GetLogPort() const { return static_cast<uart::Port>(this->log_port); } constexpr uart::Port GetLogPort() const { return static_cast<uart::Port>(this->log_port); }
constexpr u8 GetLogFlags() const { return this->log_flags; }
constexpr u16 GetLcdVendor() const { return this->lcd_vendor; } constexpr u16 GetLcdVendor() const { return this->lcd_vendor; }
@ -113,6 +116,7 @@ namespace ams::secmon {
.log_port = uart::Port_ReservedDebug, .log_port = uart::Port_ReservedDebug,
.flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None }, .flags = { SecureMonitorConfigurationFlag_Default, SecureMonitorConfigurationFlag_None },
.lcd_vendor = {}, .lcd_vendor = {},
.log_flags = {},
.reserved0 = {}, .reserved0 = {},
.log_baud_rate = 115200, .log_baud_rate = 115200,
.reserved1 = {}, .reserved1 = {},

View file

@ -20,28 +20,11 @@ namespace ams::log {
namespace { namespace {
constexpr inline uart::Port DefaultLogPort = uart::Port_ReservedDebug; constexpr inline uart::Port DefaultLogPort = uart::Port_ReservedDebug;
constexpr inline u32 DefaultLogFlags = static_cast<u32>(uart::Flag_None);
constexpr inline int DefaultBaudRate = 115200; constexpr inline int DefaultBaudRate = 115200;
constinit uart::Port g_log_port = DefaultLogPort; constinit uart::Port g_log_port = DefaultLogPort;
constinit bool g_initialized_uart = false; 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) { ALWAYS_INLINE void SetupUartClock(uart::Port port) {
/* The debug port must always be set up, for compatibility with official hos. */ /* The debug port must always be set up, for compatibility with official hos. */
pinmux::SetupUartA(); pinmux::SetupUartA();
@ -64,15 +47,15 @@ namespace ams::log {
} }
void Initialize() { 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. */ /* Initialize pinmux and clock for the target uart port. */
SetupUartClock(port); SetupUartClock(port);
/* Initialize the target uart port. */ /* Initialize the target uart port. */
uart::Initialize(port, baud_rate, GetPortFlags(port)); uart::Initialize(port, baud_rate, flags);
/* Note that we've initialized. */ /* Note that we've initialized. */
g_log_port = port; g_log_port = port;