From 5f905c6b42acc19dcee167421131f3af201ee8e9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 17 Dec 2018 13:22:08 -0800 Subject: [PATCH] warmboot: Add device debug configuration --- exosphere/lp0fw/src/fuse.h | 189 +++++++++++++++++++++++++++++++++++ exosphere/lp0fw/src/lp0.c | 4 + exosphere/lp0fw/src/misc.c | 47 +++++++++ exosphere/lp0fw/src/misc.h | 33 ++++++ exosphere/lp0fw/src/pmc.h | 2 +- exosphere/lp0fw/src/sysreg.h | 46 +++++++++ 6 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 exosphere/lp0fw/src/fuse.h create mode 100644 exosphere/lp0fw/src/misc.c create mode 100644 exosphere/lp0fw/src/misc.h create mode 100644 exosphere/lp0fw/src/sysreg.h diff --git a/exosphere/lp0fw/src/fuse.h b/exosphere/lp0fw/src/fuse.h new file mode 100644 index 000000000..b07e8b9d5 --- /dev/null +++ b/exosphere/lp0fw/src/fuse.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2018 Atmosphère-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 . + */ + +#ifndef EXOSPHERE_WARMBOOT_BIN_FUSE_H +#define EXOSPHERE_WARMBOOT_BIN_FUSE_H + +#include +#include + +#include "utils.h" + +typedef struct { + uint32_t FUSE_CTRL; + uint32_t FUSE_REG_ADDR; + uint32_t FUSE_REG_READ; + uint32_t FUSE_REG_WRITE; + uint32_t FUSE_TIME_RD1; + uint32_t FUSE_TIME_RD2; + uint32_t FUSE_TIME_PGM1; + uint32_t FUSE_TIME_PGM2; + uint32_t FUSE_PRIV2INTFC; + uint32_t FUSE_FUSEBYPASS; + uint32_t FUSE_PRIVATEKEYDISABLE; + uint32_t FUSE_DIS_PGM; + uint32_t FUSE_WRITE_ACCESS; + uint32_t FUSE_PWR_GOOD_SW; + uint32_t _0x38[0x32]; +} fuse_registers_t; + +typedef struct { + uint32_t FUSE_PRODUCTION_MODE; + uint32_t _0x4; + uint32_t _0x8; + uint32_t _0xC; + uint32_t FUSE_SKU_INFO; + uint32_t FUSE_CPU_SPEEDO_0; + uint32_t FUSE_CPU_IDDQ; + uint32_t _0x1C; + uint32_t _0x20; + uint32_t _0x24; + uint32_t FUSE_FT_REV; + uint32_t FUSE_CPU_SPEEDO_1; + uint32_t FUSE_CPU_SPEEDO_2; + uint32_t FUSE_SOC_SPEEDO_0; + uint32_t FUSE_SOC_SPEEDO_1; + uint32_t FUSE_SOC_SPEEDO_2; + uint32_t FUSE_SOC_IDDQ; + uint32_t _0x44; + uint32_t FUSE_FA; + uint32_t _0x4C; + uint32_t _0x50; + uint32_t _0x54; + uint32_t _0x58; + uint32_t _0x5C; + uint32_t _0x60; + uint32_t FUSE_PUBLIC_KEY[0x8]; + uint32_t FUSE_TSENSOR_1; + uint32_t FUSE_TSENSOR_2; + uint32_t _0x8C; + uint32_t FUSE_CP_REV; + uint32_t _0x94; + uint32_t FUSE_TSENSOR_0; + uint32_t FUSE_FIRST_BOOTROM_PATCH_SIZE_REG; + uint32_t FUSE_SECURITY_MODE; + uint32_t FUSE_PRIVATE_KEY[0x4]; + uint32_t FUSE_DEVICE_KEY; + uint32_t _0xB8; + uint32_t _0xBC; + uint32_t FUSE_RESERVED_SW; + uint32_t FUSE_VP8_ENABLE; + uint32_t FUSE_RESERVED_ODM[0x8]; + uint32_t _0xE8; + uint32_t _0xEC; + uint32_t FUSE_SKU_USB_CALIB; + uint32_t FUSE_SKU_DIRECT_CONFIG; + uint32_t _0xF8; + uint32_t _0xFC; + uint32_t FUSE_VENDOR_CODE; + uint32_t FUSE_FAB_CODE; + uint32_t FUSE_LOT_CODE_0; + uint32_t FUSE_LOT_CODE_1; + uint32_t FUSE_WAFER_ID; + uint32_t FUSE_X_COORDINATE; + uint32_t FUSE_Y_COORDINATE; + uint32_t _0x11C; + uint32_t _0x120; + uint32_t FUSE_SATA_CALIB; + uint32_t FUSE_GPU_IDDQ; + uint32_t FUSE_TSENSOR_3; + uint32_t _0x130; + uint32_t _0x134; + uint32_t _0x138; + uint32_t _0x13C; + uint32_t _0x140; + uint32_t _0x144; + uint32_t FUSE_OPT_SUBREVISION; + uint32_t _0x14C; + uint32_t _0x150; + uint32_t FUSE_TSENSOR_4; + uint32_t FUSE_TSENSOR_5; + uint32_t FUSE_TSENSOR_6; + uint32_t FUSE_TSENSOR_7; + uint32_t FUSE_OPT_PRIV_SEC_DIS; + uint32_t FUSE_PKC_DISABLE; + uint32_t _0x16C; + uint32_t _0x170; + uint32_t _0x174; + uint32_t _0x178; + uint32_t _0x17C; + uint32_t FUSE_TSENSOR_COMMON; + uint32_t _0x184; + uint32_t _0x188; + uint32_t _0x18C; + uint32_t _0x190; + uint32_t _0x194; + uint32_t _0x198; + uint32_t FUSE_DEBUG_AUTH_OVERRIDE; + uint32_t _0x1A0; + uint32_t _0x1A4; + uint32_t _0x1A8; + uint32_t _0x1AC; + uint32_t _0x1B0; + uint32_t _0x1B4; + uint32_t _0x1B8; + uint32_t _0x1BC; + uint32_t _0x1D0; + uint32_t FUSE_TSENSOR_8; + uint32_t _0x1D8; + uint32_t _0x1DC; + uint32_t _0x1E0; + uint32_t _0x1E4; + uint32_t _0x1E8; + uint32_t _0x1EC; + uint32_t _0x1F0; + uint32_t _0x1F4; + uint32_t _0x1F8; + uint32_t _0x1FC; + uint32_t _0x200; + uint32_t FUSE_RESERVED_CALIB; + uint32_t _0x208; + uint32_t _0x20C; + uint32_t _0x210; + uint32_t _0x214; + uint32_t _0x218; + uint32_t FUSE_TSENSOR_9; + uint32_t _0x220; + uint32_t _0x224; + uint32_t _0x228; + uint32_t _0x22C; + uint32_t _0x230; + uint32_t _0x234; + uint32_t _0x238; + uint32_t _0x23C; + uint32_t _0x240; + uint32_t _0x244; + uint32_t _0x248; + uint32_t _0x24C; + uint32_t FUSE_USB_CALIB_EXT; + uint32_t _0x254; + uint32_t _0x258; + uint32_t _0x25C; + uint32_t _0x260; + uint32_t _0x264; + uint32_t _0x268; + uint32_t _0x26C; + uint32_t _0x270; + uint32_t _0x274; + uint32_t _0x278; + uint32_t _0x27C; + uint32_t FUSE_SPARE_BIT[0x20]; +} fuse_chip_registers_t; + +#define FUSE_REGS ((volatile fuse_registers_t *)(0x7000F800)) +#define FUSE_CHIP_REGS ((volatile fuse_chip_registers_t *)(0x7000F900)) + +#endif diff --git a/exosphere/lp0fw/src/lp0.c b/exosphere/lp0fw/src/lp0.c index 7f1c77ec4..fd6525a41 100644 --- a/exosphere/lp0fw/src/lp0.c +++ b/exosphere/lp0fw/src/lp0.c @@ -18,6 +18,7 @@ #include "lp0.h" #include "mc.h" #include "pmc.h" +#include "misc.h" #include "timer.h" void reboot(void) { @@ -39,6 +40,9 @@ void lp0_entry_main(warmboot_metadata_t *meta) { disable_bpmp_access_to_dram(); } + /* Configure debugging depending on FUSE_PRODUCTION_MODE */ + configure_device_dbg_settings(); + /* TODO: stuff */ while (true) { /* TODO: Halt BPMP */ } diff --git a/exosphere/lp0fw/src/misc.c b/exosphere/lp0fw/src/misc.c new file mode 100644 index 000000000..3310f0e86 --- /dev/null +++ b/exosphere/lp0fw/src/misc.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Atmosphère-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 . + */ + +#include + +#include "utils.h" +#include "misc.h" +#include "fuse.h" +#include "sysreg.h" +#include "pmc.h" + +void configure_device_dbg_settings(void) { + /* Enable RTCK daisychaining by setting TBE bit. */ + APB_MISC_PP_CONFIG_CTL_0 = 0x80; + + /* Literally none of this is documented in the TRM, lol. */ + if (FUSE_CHIP_REGS->FUSE_SECURITY_MODE == 1) { + uint32_t secure_boot_val = 0b0100; /* Sets NIDEN for aarch64. */ + uint32_t misc_val = 0x40; + if (APBDEV_PMC_STICKY_BITS_0 & 0x40) { + misc_val = 0x0; + } else { + secure_boot_val = 0b1101; /* Sets SPNIDEN, NIDEN, DBGEN for aarch64. */ + } + SB_PFCFG_0 = (SB_PFCFG_0 & ~0b1111) | secure_boot_val; /* Configures debug bits. */ + APB_MISC_PP_CONFIG_CTL_0 |= misc_val; /* Undocumented, seems to control invasive debugging/JTAG. */ + } + + /* Set sticky bits based SECURITY_MODE. */ + APBDEV_PMC_STICKY_BITS_0 |= FUSE_CHIP_REGS->FUSE_SECURITY_MODE; + + /* Set E_INPUT in PINMUX_AUX_GPIO_PA6_0 */ + PINMUX_AUX_GPIO_PA6_0 |= 0x40; +} diff --git a/exosphere/lp0fw/src/misc.h b/exosphere/lp0fw/src/misc.h new file mode 100644 index 000000000..6d34e075f --- /dev/null +++ b/exosphere/lp0fw/src/misc.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 Atmosphère-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 . + */ + +#ifndef EXOSPHERE_WARMBOOT_BIN_MISC_H +#define EXOSPHERE_WARMBOOT_BIN_MISC_H + +#include + +#define MISC_BASE (0x70000000) + +#define MAKE_MISC_REG(n) MAKE_REG32(MISC_BASE + n) + +#define APB_MISC_PP_CONFIG_CTL_0 MAKE_MISC_REG(0x024) + + +#define PINMUX_AUX_GPIO_PA6_0 MAKE_MISC_REG(0x3244) + +void configure_device_dbg_settings(void); + +#endif diff --git a/exosphere/lp0fw/src/pmc.h b/exosphere/lp0fw/src/pmc.h index dd32e9c2e..9025fbd33 100644 --- a/exosphere/lp0fw/src/pmc.h +++ b/exosphere/lp0fw/src/pmc.h @@ -37,7 +37,7 @@ #define APBDEV_PMC_SCRATCH13_0 MAKE_PMC_REG(0x084) #define APBDEV_PMC_SCRATCH18_0 MAKE_PMC_REG(0x098) - +#define APBDEV_PMC_STICKY_BITS_0 MAKE_PMC_REG(0x2C0) #define APBDEV_PMC_WEAK_BIAS_0 MAKE_PMC_REG(0x2C8) #define APBDEV_PMC_IO_DPD3_REQ_0 MAKE_PMC_REG(0x45C) diff --git a/exosphere/lp0fw/src/sysreg.h b/exosphere/lp0fw/src/sysreg.h new file mode 100644 index 000000000..87e0fc0fa --- /dev/null +++ b/exosphere/lp0fw/src/sysreg.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Atmosphère-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 . + */ + +#ifndef EXOSPHERE_WARMBOOT_BIN_SYSREG_H +#define EXOSPHERE_WARMBOOT_BIN_SYSREG_H + +#include + + +#define SYSREG_BASE (0x6000C000) + +#define SB_BASE (SYSREG_BASE + 0x200) + +#define MAKE_SYSREG(n) MAKE_REG32(SYSREG_BASE + n) +#define MAKE_SB_REG(n) MAKE_REG32(SB_BASE + n) + +#define AHB_ARBITRATION_DISABLE_0 MAKE_SYSREG(0x004) + +#define SB_CSR_0 MAKE_SB_REG(0x00) +#define SB_PIROM_START_0 MAKE_SB_REG(0x04) +#define SB_PFCFG_0 MAKE_SB_REG(0x08) +#define SB_SECURE_SPAREREG_0_0 MAKE_SB_REG(0x0C) +#define SB_SECURE_SPAREREG_1_0 MAKE_SB_REG(0x10) +#define SB_SECURE_SPAREREG_2_0 MAKE_SB_REG(0x14) +#define SB_SECURE_SPAREREG_3_0 MAKE_SB_REG(0x18) +#define SB_SECURE_SPAREREG_4_0 MAKE_SB_REG(0x1C) +#define SB_SECURE_SPAREREG_5_0 MAKE_SB_REG(0x20) +#define SB_SECURE_SPAREREG_6_0 MAKE_SB_REG(0x24) +#define SB_SECURE_SPAREREG_7_0 MAKE_SB_REG(0x28) +#define SB_AA64_RESET_LOW_0 MAKE_SB_REG(0x30) +#define SB_AA64_RESET_HIGH_0 MAKE_SB_REG(0x34) + +#endif