mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
exo/meso/fusee: support dynamic control of log port/baud rate
This commit is contained in:
parent
121c981bb4
commit
2de85c633a
17 changed files with 183 additions and 99 deletions
|
@ -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
|
||||
|
|
|
@ -960,7 +960,7 @@ namespace ams::secmon {
|
|||
}
|
||||
|
||||
void SetupLogForBoot() {
|
||||
log::Initialize();
|
||||
log::Initialize(secmon::GetLogPort(), secmon::GetLogBaudRate());
|
||||
log::SendText("OHAYO\n", 6);
|
||||
log::Flush();
|
||||
}
|
||||
|
|
|
@ -282,6 +282,10 @@ namespace ams::secmon::smc {
|
|||
return SmcResult::NotInitialized;
|
||||
}
|
||||
break;
|
||||
case ConfigItem::ExosphereLogConfiguration:
|
||||
/* Get the log configuration. */
|
||||
args.r[1] = (static_cast<u64>(static_cast<u8>(secmon::GetLogPort())) << 32) | static_cast<u64>(secmon::GetLogBaudRate());
|
||||
break;
|
||||
default:
|
||||
return SmcResult::InvalidArgument;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <exosphere/fuse.hpp>
|
||||
#include <exosphere/uart.hpp>
|
||||
#include <exosphere/secmon/secmon_emummc_context.hpp>
|
||||
|
||||
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<fuse::HardwareType>(this->hardware_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 uart::Port GetLogPort() const { return static_cast<uart::Port>(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 = {},
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<u8>((value >> 32) & 0xFF);
|
||||
}
|
||||
|
||||
void KSystemControl::Init::CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
||||
smc::init::CpuOn(core_id, entrypoint, arg);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<volatile u32>(g_uart_address)[which];
|
||||
}
|
||||
|
||||
NOINLINE void WriteUartRegister(UartRegister which, u32 value) {
|
||||
ALWAYS_INLINE void WriteUartRegister(UartRegister which, u32 value) {
|
||||
GetPointer<volatile u32>(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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue