From a292e95c2f5ddceceea67fe58263d1708a11f9a3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 2 Mar 2018 13:44:21 -0800 Subject: [PATCH] Finish bootup_misc_mmio() - Cur build gets to end of pk2ldr. --- exosphere/src/actmon.c | 24 +++++++++++ exosphere/src/actmon.h | 23 ++++++++++ exosphere/src/bootup.c | 79 ++++++++++++++++++++++++++++++++++- exosphere/src/bpmp.h | 1 + exosphere/src/car.h | 1 + exosphere/src/coldboot_init.c | 4 ++ exosphere/src/cpu_context.c | 8 +++- exosphere/src/cpu_context.h | 2 + exosphere/src/interrupt.h | 1 + exosphere/src/pmc.h | 5 +++ exosphere/src/sysreg.h | 31 ++++++++++++++ 11 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 exosphere/src/actmon.c create mode 100644 exosphere/src/actmon.h create mode 100644 exosphere/src/sysreg.h diff --git a/exosphere/src/actmon.c b/exosphere/src/actmon.c new file mode 100644 index 000000000..bd28675b6 --- /dev/null +++ b/exosphere/src/actmon.c @@ -0,0 +1,24 @@ +#include + +#include "utils.h" +#include "actmon.h" + +static void (*g_actmon_callback)(void) = NULL; + +void actmon_set_callback(void (*callback)(void)) { + g_actmon_callback = callback; +} + +void actmon_on_bpmp_wakeup(void) { + /* This gets set as the actmon interrupt handler on 4.x. */ + panic(0xF0A00036); +} + +void actmon_interrupt_handler(void) { + ACTMON_COP_CTRL_0 = 0; + ACTMON_COP_INTR_STATUS_0 = ACTMON_COP_INTR_STATUS_0; + if (g_actmon_callback != NULL) { + g_actmon_callback(); + g_actmon_callback = NULL; + } +} \ No newline at end of file diff --git a/exosphere/src/actmon.h b/exosphere/src/actmon.h new file mode 100644 index 000000000..d27493d4e --- /dev/null +++ b/exosphere/src/actmon.h @@ -0,0 +1,23 @@ +#ifndef EXOSPHERE_ACTIVITY_MONITOR_H +#define EXOSPHERE_ACTIVITY_MONITOR_H + +#include "sysreg.h" + +/* Exosphere Driver for the Tegra X1 Activity Monitor. */ + +/* NOTE: ACTMON registers lie in the SYSREG region! */ +#define ACTMON_BASE (SYSREG_BASE + 0x800) + +#define MAKE_ACTMON_REG(n) (*((volatile uint32_t *)(ACTMON_BASE + n))) + +#define ACTMON_GLB_STATUS_0 MAKE_ACTMON_REG(0x000) +#define ACTMON_COP_CTRL_0 MAKE_ACTMON_REG(0x0C0) +#define ACTMON_COP_INTR_STATUS_0 MAKE_ACTMON_REG(0x0E4) + +void actmon_interrupt_handler(void); + +void actmon_on_bpmp_wakeup(void); + +void actmon_set_callback(void (*callback)(void)); + +#endif \ No newline at end of file diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index 098d92abb..44acb528f 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -1,4 +1,5 @@ #include +#include #include "utils.h" #include "bootup.h" @@ -7,11 +8,19 @@ #include "flow.h" #include "pmc.h" #include "mc.h" +#include "car.h" #include "se.h" #include "masterkey.h" #include "configitem.h" #include "timers.h" #include "misc.h" +#include "bpmp.h" +#include "sysreg.h" +#include "interrupt.h" +#include "cpu_context.h" +#include "actmon.h" + +static bool g_has_booted_up = false; void bootup_misc_mmio(void) { /* Initialize Fuse registers. */ @@ -33,6 +42,12 @@ void bootup_misc_mmio(void) { se_generate_random_key(KEYSLOT_SWITCH_SRKGENKEY, KEYSLOT_SWITCH_RNGKEY); se_generate_srk(KEYSLOT_SWITCH_SRKGENKEY); + /* TODO: Why does this DRAM write occur? */ + if (!g_has_booted_up && mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) { + /* 4.x writes this magic number into DRAM. Why? */ + (*(volatile uint32_t *)(0x8005FFFC)) = 0xC0EDBBCC; + } + /* Todo: What? */ MAKE_TIMERS_REG(0x1A4) = 0xF1E0; @@ -82,10 +97,70 @@ void bootup_misc_mmio(void) { APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 = sec_disable_1; APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2; + /* TODO: What are these MC reg writes? */ + MAKE_MC_REG(0x228) = 0xFFFFFFFF; + MAKE_MC_REG(0x22C) = 0xFFFFFFFF; + MAKE_MC_REG(0x230) = 0xFFFFFFFF; + MAKE_MC_REG(0x234) = 0xFFFFFFFF; + MAKE_MC_REG(0xB98) = 0xFFFFFFFF; + MAKE_MC_REG(0x038) = 0; + MAKE_MC_REG(0x03C) = 0; + MAKE_MC_REG(0x0E0) = 0; + MAKE_MC_REG(0x0E4) = 0; + MAKE_MC_REG(0x0E8) = 0; + MAKE_MC_REG(0x0EC) = 0; + MAKE_MC_REG(0x0F0) = 0; + MAKE_MC_REG(0x0F4) = 0; + MAKE_MC_REG(0x020) = 0; + MAKE_MC_REG(0x014) = 0x30000030; + MAKE_MC_REG(0x018) = 0x2800003F; + MAKE_MC_REG(0x034) = 0; + MAKE_MC_REG(0x030) = 0; + MAKE_MC_REG(0x010) = 0; + + /* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */ + uint32_t reset_vec = TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN); + EVP_CPU_RESET_VECTOR_0 = 0; + SB_AA64_RESET_LOW_0 = reset_vec | 1; + SB_AA64_RESET_HIGH_0 = 0; + + /* Lock Non-Secure writes to Secure Boot RESET Vector. */ + SB_CSR_0 = 2; + + /* Setup PMC Secure Scratch RESET Vector for warmboot. */ + APBDEV_PMC_SECURE_SCRATCH34_0 = reset_vec; + APBDEV_PMC_SECURE_SCRATCH35_0 = 0; + APBDEV_PMC_SEC_DISABLE3_0 = 0x500000; + + /* Setup FIQs. */ + - /* TODO */ - /* Initialize the PMC secure scratch registers, initialize MISC registers, */ /* And assign "se_operation_completed" to Interrupt 0x5A. */ + intr_set_priority(INTERRUPT_ID_SECURITY_ENGINE, 0); + intr_set_group(INTERRUPT_ID_SECURITY_ENGINE, 0); + intr_set_enabled(INTERRUPT_ID_SECURITY_ENGINE, 1); + intr_set_cpu_mask(INTERRUPT_ID_SECURITY_ENGINE, 8); + intr_set_edge_level(INTERRUPT_ID_SECURITY_ENGINE, 0); + intr_set_priority(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0); + intr_set_group(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0); + intr_set_enabled(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 1); + intr_set_cpu_mask(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 8); + intr_set_edge_level(INTERRUPT_ID_ACTIVITY_MONITOR_4X, 0); + + if (!g_has_booted_up) { + intr_register_handler(INTERRUPT_ID_SECURITY_ENGINE, se_operation_completed); + intr_register_handler(INTERRUPT_ID_ACTIVITY_MONITOR_4X, actmon_interrupt_handler); + for (unsigned int core = 1; core < NUM_CPU_CORES; core++) { + set_core_is_active(core, false); + } + g_has_booted_up = true; + } else if (mkey_get_revision() < MASTERKEY_REVISION_400_CURRENT) { + /* TODO: What are these MC reg writes? */ + MAKE_MC_REG(0x65C) = 0xFFFFF000; + MAKE_MC_REG(0x660) = 0; + MAKE_MC_REG(0x964) |= 1; + CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; + } } void setup_4x_mmio(void) { diff --git a/exosphere/src/bpmp.h b/exosphere/src/bpmp.h index e60995f1b..0c74a8b94 100644 --- a/exosphere/src/bpmp.h +++ b/exosphere/src/bpmp.h @@ -12,6 +12,7 @@ static inline uintptr_t get_bpmp_vector_base(void) { #define BPMP_VECTOR_BASE (get_bpmp_vector_base()) +#define EVP_CPU_RESET_VECTOR_0 (*((volatile uint32_t *)(BPMP_VECTOR_BASE + 0x100))) #define BPMP_VECTOR_RESET (*((volatile uint32_t *)(BPMP_VECTOR_BASE + 0x200))) #define BPMP_VECTOR_UNDEF (*((volatile uint32_t *)(BPMP_VECTOR_BASE + 0x204))) diff --git a/exosphere/src/car.h b/exosphere/src/car.h index 34fbef8da..1ba4ccfde 100644 --- a/exosphere/src/car.h +++ b/exosphere/src/car.h @@ -13,6 +13,7 @@ #define CLK_RST_CONTROLLER_MISC_CLK_ENB_0 MAKE_CAR_REG(0x048) #define CLK_RST_CONTROLLER_RST_DEVICES_H_0 MAKE_CAR_REG(0x008) +#define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 MAKE_CAR_REG(0x3A4) #define NUM_CAR_BANKS 7 diff --git a/exosphere/src/coldboot_init.c b/exosphere/src/coldboot_init.c index 839b57e9f..23867bbb4 100644 --- a/exosphere/src/coldboot_init.c +++ b/exosphere/src/coldboot_init.c @@ -126,6 +126,10 @@ void coldboot_init_dma_controllers(void) { /* SYSCTR0_CNTCR_0 = ENABLE | HALT_ON_DEBUG (write-once init) */ (*((volatile uint32_t *)(0x700F0000))) = 3; + /* Set some unknown registers in HOST1X. */ + (*((volatile uint32_t *)(0x500038F8))) &= 0xFFFFFFFE; + (*((volatile uint32_t *)(0x50003300))) = 0; + /* AHB_MASTER_SWID_0 */ (*((volatile uint32_t *)(0x6000C018))) = 0; diff --git a/exosphere/src/cpu_context.c b/exosphere/src/cpu_context.c index f964b362b..9a8401b17 100644 --- a/exosphere/src/cpu_context.c +++ b/exosphere/src/cpu_context.c @@ -157,11 +157,15 @@ void restore_current_core_context(void) { } } +void set_core_is_active(uint32_t core, bool is_active) { + g_cpu_contexts[core].is_active = (is_active) ? 1 : 0; +} + void set_current_core_active(void) { - g_cpu_contexts[get_core_id()].is_active = 1; + set_core_is_active(get_core_id(), true); } void set_current_core_inactive(void) { - g_cpu_contexts[get_core_id()].is_active = 0; + set_core_is_active(get_core_id(), false); } diff --git a/exosphere/src/cpu_context.h b/exosphere/src/cpu_context.h index ca506b3e3..2b4f6b6d6 100644 --- a/exosphere/src/cpu_context.h +++ b/exosphere/src/cpu_context.h @@ -2,6 +2,7 @@ #define EXOSPHERE_CPU_CTX_H #include +#include /* Exosphere CPU Management functionality. */ @@ -47,6 +48,7 @@ typedef struct { void save_current_core_context(void); void restore_current_core_context(void); +void set_core_is_active(uint32_t core, bool is_active); void set_current_core_active(void); void set_current_core_inactive(void); diff --git a/exosphere/src/interrupt.h b/exosphere/src/interrupt.h index 8283cd9f8..338820907 100644 --- a/exosphere/src/interrupt.h +++ b/exosphere/src/interrupt.h @@ -9,6 +9,7 @@ #define MAX_REGISTERED_INTERRUPTS 4 #define INTERRUPT_ID_SECURITY_ENGINE 0x5A +#define INTERRUPT_ID_ACTIVITY_MONITOR_4X 0x4D #define INTERRUPT_ID_USER_SECURITY_ENGINE 0x2C static inline uintptr_t get_gicd_base(void) { diff --git a/exosphere/src/pmc.h b/exosphere/src/pmc.h index 0d28d40f9..fd9d4b487 100644 --- a/exosphere/src/pmc.h +++ b/exosphere/src/pmc.h @@ -35,5 +35,10 @@ static inline uintptr_t get_pmc_base(void) { #define APBDEV_PMC_SCRATCH200_0 (*((volatile uint32_t *)(PMC_BASE + 0x840))) +#define APBDEV_PMC_SEC_DISABLE3_0 (*((volatile uint32_t *)(PMC_BASE + 0x2D8))) +#define APBDEV_PMC_SECURE_SCRATCH34_0 (*((volatile uint32_t *)(PMC_BASE + 0x368))) +#define APBDEV_PMC_SECURE_SCRATCH35_0 (*((volatile uint32_t *)(PMC_BASE + 0x36C))) + + #endif diff --git a/exosphere/src/sysreg.h b/exosphere/src/sysreg.h new file mode 100644 index 000000000..4329b5765 --- /dev/null +++ b/exosphere/src/sysreg.h @@ -0,0 +1,31 @@ +#ifndef EXOSPHERE_SYSREG_H +#define EXOSPHERE_SYSREG_H + +#include + +#include "memory_map.h" + +/* Exosphere driver for the Tegra X1 System Registers. */ + +#define SYSREG_BASE (MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_SYSREGS)) + +#define SB_BASE (SYSREG_BASE + 0x200) + +#define MAKE_SYSREG(n) (*((volatile uint32_t *)(SYSREG_BASE + n))) +#define MAKE_SB_REG(n) (*((volatile uint32_t *)(SB_BASE + n))) + +#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 \ No newline at end of file