From 5565a2d131b8696bd4dc3f4831e59a48e51f4545 Mon Sep 17 00:00:00 2001 From: Resaec Date: Wed, 25 Apr 2018 17:49:42 +0200 Subject: [PATCH 01/10] creating an enum for all used MC registers replacing all MC_REG hex values with its enum --- exosphere/src/bootup.c | 109 ++++++++++++++++++++++++----------------- exosphere/src/mc.h | 88 ++++++++++++++++++++++++++++++--- 2 files changed, 146 insertions(+), 51 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index fb710c838..de5e7a1b5 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -66,21 +66,29 @@ void bootup_misc_mmio(void) { APBDEV_PMC_DPD_ENABLE_0 = 0; /* Setup MC. */ - /* TODO: What are these MC reg writes? */ - MAKE_MC_REG(0x984) = 1; - MAKE_MC_REG(0x648) = 0; - MAKE_MC_REG(0x64C) = 0; - MAKE_MC_REG(0x650) = 1; - MAKE_MC_REG(0x670) = 0; - MAKE_MC_REG(0x674) = 0; - MAKE_MC_REG(0x678) = 1; - MAKE_MC_REG(0x9A0) = 0; - MAKE_MC_REG(0x9A4) = 0; - MAKE_MC_REG(0x9A8) = 0; - MAKE_MC_REG(0x9AC) = 1; - MC_SECURITY_CFG0_0 = 0; - MC_SECURITY_CFG1_0 = 0; - MC_SECURITY_CFG3_0 = 3; + MAKE_MC_REG(MC_REGISTER_VIDEO_PROTECT_GPU_OVERRIDE_0_0) = 1; + + /* undefined in reference manual */ + MAKE_MC_REG(MC_REGISTER_0x648) = 0; + MAKE_MC_REG(MC_REGISTER_0x64C) = 0; + MAKE_MC_REG(MC_REGISTER_0x650) = 1; + + /* disable SEC carveout */ + MAKE_MC_REG(MC_REGISTER_SEC_CARVEOUT_BOM_0) = 0; + MAKE_MC_REG(MC_REGISTER_SEC_CARVEOUT_SIZE_MB_0) = 0; + MAKE_MC_REG(MC_REGISTER_SEC_CARVEOUT_REG_CTRL_0) = 1; + + /* disable MTS carveout */ + MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_BOM_0) = 0; + MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_SIZE_MB_0) = 0; + MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_ADR_HI_0) = 0; + MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_REG_CTRL_0) = 1; + + /* disable security carveout - SECURITY_CFG0_0, CFG1_0, CFG3_0 */ + MAKE_MC_REG(MC_REGISTER_SECURITY_BOM) = 0; + MAKE_MC_REG(MC_REGISTER_SECURITY_SIZE_MB) = 0; + MAKE_MC_REG(MC_REGISTER_SECURITY_BOM_HI) = 0x11; + configure_default_carveouts(); /* Mark registers secure world only. */ @@ -102,33 +110,45 @@ void bootup_misc_mmio(void) { /* Starting on 4.x on non-dev units, mark SDMMC1 secure only. */ sec_disable_2 |= 1; } + 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; + /* reset translation tables to allow all */ + MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_0_0) = 0xFFFFFFFF; + MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_1_0) = 0xFFFFFFFF; + MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_2_0) = 0xFFFFFFFF; + MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_3_0) = 0xFFFFFFFF; + MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_4_0) = 0xFFFFFFFF; + + MAKE_MC_REG(MC_REGISTER_0x38) = 0; + MAKE_MC_REG(MC_REGISTER_0x3C) = 0; + + /* disable stall calls after ring1 and ring3 requests */ + MAKE_MC_REG(MC_REGISTER_EMEM_ARB_RING1_THROTTLE_0) = 0; + MAKE_MC_REG(MC_REGISTER_EMEM_ARB_RING3_THROTTLE_0) = 0; + + MAKE_MC_REG(MC_REGISTER_EMEM_ARB_OVERRIDE_0) = 0; /* disable overrides */ + MAKE_MC_REG(MC_REGISTER_EMEM_ARB_RSV_0) = 0; /* null reserved register */ + + MAKE_MC_REG(MC_REGISTER_0xF0) = 0; + + /* disable clock-enable overrides */ + MAKE_MC_REG(MC_REGISTER_CLKEN_OVERRIDE_0) = 0; + + /* reset PTB, TLB and PTC */ + MAKE_MC_REG(MC_REGISTER_SMMU_PTB_DATA_0) = 0; + MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0) = 0x30000030; + MAKE_MC_REG(MC_REGISTER_SMMU_PTC_CONFIG_0) = 0x2800003F; + /* 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; - (void)(MAKE_MC_REG(0x014)); - MAKE_MC_REG(0x034) = 0; - (void)(MAKE_MC_REG(0x014)); - MAKE_MC_REG(0x030) = 0; - (void)(MAKE_MC_REG(0x014)); - MAKE_MC_REG(0x010) = 1; - (void)(MAKE_MC_REG(0x014)); + (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); + MAKE_MC_REG(MC_REGISTER_SMMU_PTC_FLUSH_0) = 0; + (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); + MAKE_MC_REG(MC_REGISTER_SMMU_TLB_FLUSH_0) = 0; + (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); + MAKE_MC_REG(MC_REGISTER_SMMU_CONFIG_0) = 0x1; /* enable SMMU */ + (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_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); @@ -168,19 +188,20 @@ void bootup_misc_mmio(void) { g_has_booted_up = true; } else if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) { /* TODO: What are these MC reg writes? */ - MAKE_MC_REG(0x65C) = 0xFFFFF000; - MAKE_MC_REG(0x660) = 0; - MAKE_MC_REG(0x964) |= 1; + MAKE_MC_REG(MC_REGISTER_0x65C) = 0xFFFFF000; + MAKE_MC_REG(MC_REGISTER_0x660) = 0; + MAKE_MC_REG(MC_REGISTER_IRAM_REG_CTRL_0) |= 1; /* overlap at 18.11.1.86 and 18.11.1.87 - lock write access to IRAM and EMEM registers */ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; } } void setup_4x_mmio(void) { /* TODO: What are these MC reg writes? */ - MAKE_MC_REG(0x65C) = 0xFFFFF000; - MAKE_MC_REG(0x660) = 0; - MAKE_MC_REG(0x964) |= 1; + MAKE_MC_REG(MC_REGISTER_0x65C) = 0xFFFFF000; + MAKE_MC_REG(MC_REGISTER_0x660) = 0; + MAKE_MC_REG(MC_REGISTER_IRAM_REG_CTRL_0) |= 1; /* as above, lock write access to IRAM and EMEM registers */ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; + /* TODO: What are these PMC scratch writes? */ APBDEV_PMC_SECURE_SCRATCH51_0 = (APBDEV_PMC_SECURE_SCRATCH51_0 & 0xFFFF8000) | 0x4000; APBDEV_PMC_SECURE_SCRATCH16_0 &= 0x3FFFFFFF; diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index af98dd262..246efe990 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -14,14 +14,14 @@ static inline uintptr_t get_mc_base(void) { #define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n) -#define MC_SMMU_PTB_ASID_0 MAKE_MC_REG(0x01C) -#define MC_SMMU_PTB_DATA_0 MAKE_MC_REG(0x020) -#define MC_SMMU_AVPC_ASID_0 MAKE_MC_REG(0x23C) -#define MC_SMMU_PPCS1_ASID_0 MAKE_MC_REG(0x298) +#define MC_SMMU_PTB_ASID_0 MAKE_MC_REG(MC_REGISTER_SMMU_PTB_ASID_0) +#define MC_SMMU_PTB_DATA_0 MAKE_MC_REG(MC_REGISTER_SMMU_PTB_DATA_0) +#define MC_SMMU_AVPC_ASID_0 MAKE_MC_REG(MC_REGISTER_SMMU_AVPC_ASID_0) +#define MC_SMMU_PPCS1_ASID_0 MAKE_MC_REG(MC_REGISTER_SMMU_PPCS1_ASID_0) -#define MC_SECURITY_CFG0_0 MAKE_MC_REG(0x070) -#define MC_SECURITY_CFG1_0 MAKE_MC_REG(0x074) -#define MC_SECURITY_CFG3_0 MAKE_MC_REG(0x9BC) +#define MC_SECURITY_CFG0_0 MAKE_MC_REG(MC_REGISTER_SECURITY_BOM) +#define MC_SECURITY_CFG1_0 MAKE_MC_REG(MC_REGISTER_SECURITY_SIZE_MB) +#define MC_SECURITY_CFG3_0 MAKE_MC_REG(MC_REGISTER_SECURITY_BOM_HI) #define CARVEOUT_ID_MIN 1 @@ -47,6 +47,80 @@ typedef struct { uint8_t padding[0x28]; } security_carveout_t; +/* 18.11.1 MC Registers */ +typedef enum { + MC_REGISTER_SMMU_CONFIG_0 = 0x10, + MC_REGISTER_SMMU_TLB_CONFIG_0 = 0x14, /* Controls usage of the TLB */ + MC_REGISTER_SMMU_PTC_CONFIG_0 = 0x18, /* Controls usage of the PTC */ + MC_REGISTER_SMMU_PTB_ASID_0 = 0x1C, + MC_REGISTER_SMMU_PTB_DATA_0 = 0x20, + + MC_REGISTER_SMMU_TLB_FLUSH_0 = 0x30, + MC_REGISTER_SMMU_PTC_FLUSH_0 = 0x34, + MC_REGISTER_0x38 = 0x38, + MC_REGISTER_0x3C = 0x3C, + + /* SECURITY_BOM is the base of the secured region, limited to MB granularity. + This must point to a region of the physical address map allocated to EMEM for it to be effective; the MC cannot secure address space it does not own. (In other words, this is an absolute address, not an offset.) + Above is the list of clients with the TrustZone-security access. [18.11.1.20] + Note that AXICIF clients will adhere to the standard AXI protocol "aprot[1]==0" indication for secure requests. */ + MC_REGISTER_SECURITY_BOM = 0x70, + MC_REGISTER_SECURITY_CFG0_0 = MC_REGISTER_SECURITY_BOM, + + MC_REGISTER_SECURITY_SIZE_MB = 0x74, /* SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ + MC_REGISTER_SECURITY_CFG1_0 = MC_REGISTER_SECURITY_SIZE_MB, + + MC_REGISTER_EMEM_ARB_RING1_THROTTLE_0 = 0xE0, + MC_REGISTER_EMEM_ARB_RING3_THROTTLE_0 = 0xE4, + MC_REGISTER_EMEM_ARB_OVERRIDE_0 = 0xE8, + MC_REGISTER_EMEM_ARB_RSV_0 = 0xEC, + MC_REGISTER_0xF0 = 0xF0, + MC_REGISTER_CLKEN_OVERRIDE_0 = 0xF4, + + MC_REGISTER_SMMU_TRANSLATION_ENABLE_0_0 = 0x228, + MC_REGISTER_SMMU_TRANSLATION_ENABLE_1_0 = 0x22C, + MC_REGISTER_SMMU_TRANSLATION_ENABLE_2_0 = 0x230, + MC_REGISTER_SMMU_TRANSLATION_ENABLE_3_0 = 0x234, + + MC_REGISTER_SMMU_AVPC_ASID_0 = 0x23C, + + MC_REGISTER_SMMU_PPCS1_ASID_0 = 0x298, + + MC_REGISTER_0x648 = 0x648, + MC_REGISTER_0x64C = 0x64C, + MC_REGISTER_0x650 = 0x650, + + MC_REGISTER_0x65C = 0x65C, + MC_REGISTER_0x660 = 0x660, + + MC_REGISTER_IRAM_REG_CTRL_0 = 0x964, + MC_REGISTER_EMEM_CFG_ACCESS_CTRL_0 = MC_REGISTER_IRAM_REG_CTRL_0, + + MC_REGISTER_SEC_CARVEOUT_BOM_0 = 0x670, /* [PMC_SECURE] Base address for the SEC carveout address space */ + MC_REGISTER_SEC_CARVEOUT_SIZE_MB_0 = 0x674, /* [PMC_SECURE] SEC_CARVEOUT_SIZE_MB is the size, in megabytes, of the SEC carveout region. If set to 0, the security check in MC is disabled */ + /* [PMC_SECURE] Sticky bit to control the writes to the other Sec Carveout aperture registers + 0 = Enabled + 1 = Disabled */ + MC_REGISTER_SEC_CARVEOUT_REG_CTRL_0 = 0x678, + + MC_REGISTER_VIDEO_PROTECT_GPU_OVERRIDE_0_0 = 0x984, + + MC_REGISTER_MTS_CARVEOUT_BOM_0 = 0x9A0, + MC_REGISTER_MTS_CARVEOUT_SIZE_MB_0 = 0x9A4, + MC_REGISTER_MTS_CARVEOUT_ADR_HI_0 = 0x9A8, + /* MTS_CARVEOUT_WRITE_ACCESS + 0 = Enabled + 1 = Disabled */ + MC_REGISTER_MTS_CARVEOUT_REG_CTRL_0 = 0x9AC, + + /* Base Address Higher Bits + SECURITY_BOM_HI has the higher address bits beyond 32 bits of the + base of the secured region, limited to MB granularity */ + MC_REGISTER_SECURITY_BOM_HI = 0x9BC, + MC_REGISTER_SECURITY_CFG3_0 = MC_REGISTER_SECURITY_BOM_HI, + + MC_REGISTER_SMMU_TRANSLATION_ENABLE_4_0 = 0xB98 +} MC_REGISTER; volatile security_carveout_t *get_carveout_by_id(unsigned int carveout); void configure_default_carveouts(void); From 79b4b608e5185db23f83ab7c1b09700cb3efd77f Mon Sep 17 00:00:00 2001 From: Resaec Date: Thu, 26 Apr 2018 00:30:16 +0200 Subject: [PATCH 02/10] mc.h switch from enum to struct --- exosphere/src/mc.h | 116 ++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index 246efe990..148086c47 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -48,79 +48,75 @@ typedef struct { } security_carveout_t; /* 18.11.1 MC Registers */ -typedef enum { - MC_REGISTER_SMMU_CONFIG_0 = 0x10, - MC_REGISTER_SMMU_TLB_CONFIG_0 = 0x14, /* Controls usage of the TLB */ - MC_REGISTER_SMMU_PTC_CONFIG_0 = 0x18, /* Controls usage of the PTC */ - MC_REGISTER_SMMU_PTB_ASID_0 = 0x1C, - MC_REGISTER_SMMU_PTB_DATA_0 = 0x20, - - MC_REGISTER_SMMU_TLB_FLUSH_0 = 0x30, - MC_REGISTER_SMMU_PTC_FLUSH_0 = 0x34, - MC_REGISTER_0x38 = 0x38, - MC_REGISTER_0x3C = 0x3C, - +typedef struct { + uint32_t _0x0[4]; + uint32_t SMMU_CONFIG_0; + uint32_t SMMU_TLB_CONFIG_0; /* Controls usage of the TLB */ + uint32_t SMMU_PTC_CONFIG_0; /* Controls usage of the PTC */ + uint32_t SMMU_PTB_ASID_0; + uint32_t SMMU_PTB_DATA_0; + uint32_t _0x24[3]; + uint32_t SMMU_TLB_FLUSH_0; + uint32_t SMMU_PTC_FLUSH_0; + uint32_t _0x38; + uint32_t _0x3C; + uint32_t _0x40[12]; /* SECURITY_BOM is the base of the secured region, limited to MB granularity. This must point to a region of the physical address map allocated to EMEM for it to be effective; the MC cannot secure address space it does not own. (In other words, this is an absolute address, not an offset.) Above is the list of clients with the TrustZone-security access. [18.11.1.20] Note that AXICIF clients will adhere to the standard AXI protocol "aprot[1]==0" indication for secure requests. */ - MC_REGISTER_SECURITY_BOM = 0x70, - MC_REGISTER_SECURITY_CFG0_0 = MC_REGISTER_SECURITY_BOM, - - MC_REGISTER_SECURITY_SIZE_MB = 0x74, /* SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ - MC_REGISTER_SECURITY_CFG1_0 = MC_REGISTER_SECURITY_SIZE_MB, - - MC_REGISTER_EMEM_ARB_RING1_THROTTLE_0 = 0xE0, - MC_REGISTER_EMEM_ARB_RING3_THROTTLE_0 = 0xE4, - MC_REGISTER_EMEM_ARB_OVERRIDE_0 = 0xE8, - MC_REGISTER_EMEM_ARB_RSV_0 = 0xEC, - MC_REGISTER_0xF0 = 0xF0, - MC_REGISTER_CLKEN_OVERRIDE_0 = 0xF4, - - MC_REGISTER_SMMU_TRANSLATION_ENABLE_0_0 = 0x228, - MC_REGISTER_SMMU_TRANSLATION_ENABLE_1_0 = 0x22C, - MC_REGISTER_SMMU_TRANSLATION_ENABLE_2_0 = 0x230, - MC_REGISTER_SMMU_TRANSLATION_ENABLE_3_0 = 0x234, - - MC_REGISTER_SMMU_AVPC_ASID_0 = 0x23C, - - MC_REGISTER_SMMU_PPCS1_ASID_0 = 0x298, - - MC_REGISTER_0x648 = 0x648, - MC_REGISTER_0x64C = 0x64C, - MC_REGISTER_0x650 = 0x650, - - MC_REGISTER_0x65C = 0x65C, - MC_REGISTER_0x660 = 0x660, - - MC_REGISTER_IRAM_REG_CTRL_0 = 0x964, - MC_REGISTER_EMEM_CFG_ACCESS_CTRL_0 = MC_REGISTER_IRAM_REG_CTRL_0, - - MC_REGISTER_SEC_CARVEOUT_BOM_0 = 0x670, /* [PMC_SECURE] Base address for the SEC carveout address space */ - MC_REGISTER_SEC_CARVEOUT_SIZE_MB_0 = 0x674, /* [PMC_SECURE] SEC_CARVEOUT_SIZE_MB is the size, in megabytes, of the SEC carveout region. If set to 0, the security check in MC is disabled */ + uint32_t SECURITY_BOM; + uint32_t SECURITY_SIZE_MB; /* SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ + uint32_t _0x78[26]; + uint32_t EMEM_ARB_RING1_THROTTLE_0; + uint32_t EMEM_ARB_RING3_THROTTLE_0; + uint32_t EMEM_ARB_OVERRIDE_0; + uint32_t EMEM_ARB_RSV_0; + uint32_t _0xF0; + uint32_t CLKEN_OVERRIDE_0; + uint32_t _0xF8[76]; + uint32_t SMMU_TRANSLATION_ENABLE_0_0; + uint32_t SMMU_TRANSLATION_ENABLE_1_0; + uint32_t SMMU_TRANSLATION_ENABLE_2_0; + uint32_t SMMU_TRANSLATION_ENABLE_3_0; + uint32_t _0x234[1]; + uint32_t SMMU_AVPC_ASID_0; + uint32_t _0x240[22]; + uint32_t SMMU_PPCS1_ASID_0; + uint32_t _0x29C[235]; + uint32_t _0x648; + uint32_t _0x64C; + uint32_t _0x650; + uint32_t _0x654[2]; + uint32_t _0x65C; + uint32_t _0x660; + uint32_t _0x664[3]; + uint32_t SEC_CARVEOUT_BOM_0; /* [PMC_SECURE] Base address for the SEC carveout address space */ + uint32_t SEC_CARVEOUT_SIZE_MB_0; /* [PMC_SECURE] SEC_CARVEOUT_SIZE_MB is the size, in megabytes, of the SEC carveout region. If set to 0, the security check in MC is disabled */ /* [PMC_SECURE] Sticky bit to control the writes to the other Sec Carveout aperture registers 0 = Enabled 1 = Disabled */ - MC_REGISTER_SEC_CARVEOUT_REG_CTRL_0 = 0x678, - - MC_REGISTER_VIDEO_PROTECT_GPU_OVERRIDE_0_0 = 0x984, - - MC_REGISTER_MTS_CARVEOUT_BOM_0 = 0x9A0, - MC_REGISTER_MTS_CARVEOUT_SIZE_MB_0 = 0x9A4, - MC_REGISTER_MTS_CARVEOUT_ADR_HI_0 = 0x9A8, + uint32_t SEC_CARVEOUT_REG_CTRL_0; + uint32_t _0x67C[186]; + uint32_t EMEM_CFG_ACCESS_CTRL_0_AND_IRAM_REG_CTRL_0; + uint32_t _0x968[7]; + uint32_t VIDEO_PROTECT_GPU_OVERRIDE_0_0; + uint32_t _0x988[6]; + uint32_t MTS_CARVEOUT_BOM_0; + uint32_t MTS_CARVEOUT_SIZE_MB_0; + uint32_t MTS_CARVEOUT_ADR_HI_0; /* MTS_CARVEOUT_WRITE_ACCESS 0 = Enabled 1 = Disabled */ - MC_REGISTER_MTS_CARVEOUT_REG_CTRL_0 = 0x9AC, - + uint32_t MTS_CARVEOUT_REG_CTRL_0; + uint32_t _0x9B0[3]; /* Base Address Higher Bits SECURITY_BOM_HI has the higher address bits beyond 32 bits of the base of the secured region, limited to MB granularity */ - MC_REGISTER_SECURITY_BOM_HI = 0x9BC, - MC_REGISTER_SECURITY_CFG3_0 = MC_REGISTER_SECURITY_BOM_HI, - - MC_REGISTER_SMMU_TRANSLATION_ENABLE_4_0 = 0xB98 -} MC_REGISTER; + uint32_t SECURITY_BOM_HI; + uint32_t _0x9C0[118]; + uint32_t SMMU_TRANSLATION_ENABLE_4_0; +} mc_register_t; volatile security_carveout_t *get_carveout_by_id(unsigned int carveout); void configure_default_carveouts(void); From 0ebf9aab2466f552d995eb9b88f5f1d9794002c0 Mon Sep 17 00:00:00 2001 From: Resaec Date: Thu, 26 Apr 2018 18:21:57 +0200 Subject: [PATCH 03/10] added function get_mc_reg() to obtain a pointer to mc_register_t located at MC_BASE --- exosphere/src/mc.c | 4 ++++ exosphere/src/mc.h | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/exosphere/src/mc.c b/exosphere/src/mc.c index 6a5cf7980..1aa8153c2 100644 --- a/exosphere/src/mc.c +++ b/exosphere/src/mc.c @@ -93,3 +93,7 @@ void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint6 carveout->flags_9 = 0; carveout->allowed_clients = 0x8B; } + +volatile mc_register_t *get_mc_reg() { + return (volatile mc_register_t *)(MC_BASE); +} diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index 148086c47..68d8f291e 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -65,8 +65,8 @@ typedef struct { This must point to a region of the physical address map allocated to EMEM for it to be effective; the MC cannot secure address space it does not own. (In other words, this is an absolute address, not an offset.) Above is the list of clients with the TrustZone-security access. [18.11.1.20] Note that AXICIF clients will adhere to the standard AXI protocol "aprot[1]==0" indication for secure requests. */ - uint32_t SECURITY_BOM; - uint32_t SECURITY_SIZE_MB; /* SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ + uint32_t SECURITY_BOM; /* MC_SECURITY_CFG0_0 */ + uint32_t SECURITY_SIZE_MB; /* MC_SECURITY_CFG1_0 -- SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ uint32_t _0x78[26]; uint32_t EMEM_ARB_RING1_THROTTLE_0; uint32_t EMEM_ARB_RING3_THROTTLE_0; @@ -113,14 +113,15 @@ typedef struct { /* Base Address Higher Bits SECURITY_BOM_HI has the higher address bits beyond 32 bits of the base of the secured region, limited to MB granularity */ - uint32_t SECURITY_BOM_HI; + uint32_t SECURITY_BOM_HI; /* MC_SECURITY_CFG3_0 */ uint32_t _0x9C0[118]; uint32_t SMMU_TRANSLATION_ENABLE_4_0; -} mc_register_t; +} mc_register_t; /* 0xB98 */ volatile security_carveout_t *get_carveout_by_id(unsigned int carveout); void configure_default_carveouts(void); void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size); +volatile mc_register_t *get_mc_reg(); #endif From 33824b51f46cc3f56bb7e38e64f399b35becf938 Mon Sep 17 00:00:00 2001 From: Resaec Date: Thu, 26 Apr 2018 18:23:42 +0200 Subject: [PATCH 04/10] replace MAKE_MC_REG() with mc_register_t pointer access --- exosphere/src/bootup.c | 96 +++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index de5e7a1b5..cb19a6b90 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -66,28 +66,29 @@ void bootup_misc_mmio(void) { APBDEV_PMC_DPD_ENABLE_0 = 0; /* Setup MC. */ - MAKE_MC_REG(MC_REGISTER_VIDEO_PROTECT_GPU_OVERRIDE_0_0) = 1; + volatile mc_register_t *mc_register = get_mc_reg(); + mc_register->VIDEO_PROTECT_GPU_OVERRIDE_0_0 = 1; /* undefined in reference manual */ - MAKE_MC_REG(MC_REGISTER_0x648) = 0; - MAKE_MC_REG(MC_REGISTER_0x64C) = 0; - MAKE_MC_REG(MC_REGISTER_0x650) = 1; + mc_register->_0x648 = 0; + mc_register->_0x64C = 0; + mc_register->_0x650 = 1; /* disable SEC carveout */ - MAKE_MC_REG(MC_REGISTER_SEC_CARVEOUT_BOM_0) = 0; - MAKE_MC_REG(MC_REGISTER_SEC_CARVEOUT_SIZE_MB_0) = 0; - MAKE_MC_REG(MC_REGISTER_SEC_CARVEOUT_REG_CTRL_0) = 1; + mc_register->SEC_CARVEOUT_BOM_0 = 0; + mc_register->SEC_CARVEOUT_SIZE_MB_0 = 0; + mc_register->SEC_CARVEOUT_REG_CTRL_0 = 1; /* disable MTS carveout */ - MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_BOM_0) = 0; - MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_SIZE_MB_0) = 0; - MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_ADR_HI_0) = 0; - MAKE_MC_REG(MC_REGISTER_MTS_CARVEOUT_REG_CTRL_0) = 1; + mc_register->MTS_CARVEOUT_BOM_0 = 0; + mc_register->MTS_CARVEOUT_SIZE_MB_0 = 0; + mc_register->MTS_CARVEOUT_ADR_HI_0 = 0; + mc_register->MTS_CARVEOUT_REG_CTRL_0 = 1; /* disable security carveout - SECURITY_CFG0_0, CFG1_0, CFG3_0 */ - MAKE_MC_REG(MC_REGISTER_SECURITY_BOM) = 0; - MAKE_MC_REG(MC_REGISTER_SECURITY_SIZE_MB) = 0; - MAKE_MC_REG(MC_REGISTER_SECURITY_BOM_HI) = 0x11; + mc_register->SECURITY_BOM = 0; + mc_register->SECURITY_SIZE_MB = 0; + mc_register->SECURITY_BOM_HI = 0x11; configure_default_carveouts(); @@ -115,40 +116,42 @@ void bootup_misc_mmio(void) { APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = sec_disable_2; /* reset translation tables to allow all */ - MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_0_0) = 0xFFFFFFFF; - MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_1_0) = 0xFFFFFFFF; - MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_2_0) = 0xFFFFFFFF; - MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_3_0) = 0xFFFFFFFF; - MAKE_MC_REG(MC_REGISTER_SMMU_TRANSLATION_ENABLE_4_0) = 0xFFFFFFFF; + mc_register->SMMU_TRANSLATION_ENABLE_0_0 = 0xFFFFFFFF; + mc_register->SMMU_TRANSLATION_ENABLE_1_0 = 0xFFFFFFFF; + mc_register->SMMU_TRANSLATION_ENABLE_2_0 = 0xFFFFFFFF; + mc_register->SMMU_TRANSLATION_ENABLE_3_0 = 0xFFFFFFFF; + mc_register->SMMU_TRANSLATION_ENABLE_4_0 = 0xFFFFFFFF; - MAKE_MC_REG(MC_REGISTER_0x38) = 0; - MAKE_MC_REG(MC_REGISTER_0x3C) = 0; + /* unknown null */ + mc_register->_0x38 = 0; + mc_register->_0x3C = 0; /* disable stall calls after ring1 and ring3 requests */ - MAKE_MC_REG(MC_REGISTER_EMEM_ARB_RING1_THROTTLE_0) = 0; - MAKE_MC_REG(MC_REGISTER_EMEM_ARB_RING3_THROTTLE_0) = 0; + mc_register->EMEM_ARB_RING1_THROTTLE_0 = 0; + mc_register->EMEM_ARB_RING3_THROTTLE_0 = 0; - MAKE_MC_REG(MC_REGISTER_EMEM_ARB_OVERRIDE_0) = 0; /* disable overrides */ - MAKE_MC_REG(MC_REGISTER_EMEM_ARB_RSV_0) = 0; /* null reserved register */ + mc_register->EMEM_ARB_OVERRIDE_0 = 0; /* disable overrides */ + mc_register->EMEM_ARB_RSV_0 = 0; /* null reserved register */ - MAKE_MC_REG(MC_REGISTER_0xF0) = 0; + /* unknown null */ + mc_register->_0xF0 = 0; /* disable clock-enable overrides */ - MAKE_MC_REG(MC_REGISTER_CLKEN_OVERRIDE_0) = 0; - + mc_register->CLKEN_OVERRIDE_0 = 0; + /* reset PTB, TLB and PTC */ - MAKE_MC_REG(MC_REGISTER_SMMU_PTB_DATA_0) = 0; - MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0) = 0x30000030; - MAKE_MC_REG(MC_REGISTER_SMMU_PTC_CONFIG_0) = 0x2800003F; + mc_register->SMMU_PTB_DATA_0 = 0; + mc_register->SMMU_TLB_CONFIG_0 = 0x30000030; + mc_register->SMMU_PTC_CONFIG_0 = 0x2800003F; /* TODO: What are these MC reg writes? */ - (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); - MAKE_MC_REG(MC_REGISTER_SMMU_PTC_FLUSH_0) = 0; - (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); - MAKE_MC_REG(MC_REGISTER_SMMU_TLB_FLUSH_0) = 0; - (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); - MAKE_MC_REG(MC_REGISTER_SMMU_CONFIG_0) = 0x1; /* enable SMMU */ - (void)(MAKE_MC_REG(MC_REGISTER_SMMU_TLB_CONFIG_0)); + (void)(mc_register->SMMU_TLB_CONFIG_0); + mc_register->SMMU_PTC_FLUSH_0 = 0; + (void)(mc_register->SMMU_TLB_CONFIG_0); + mc_register->SMMU_TLB_FLUSH_0 = 0; + (void)(mc_register->SMMU_TLB_CONFIG_0); + mc_register->SMMU_CONFIG_0 = 0x1; /* enable SMMU */ + (void)(mc_register->SMMU_TLB_CONFIG_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); @@ -188,18 +191,19 @@ void bootup_misc_mmio(void) { g_has_booted_up = true; } else if (exosphere_get_target_firmware() < EXOSPHERE_TARGET_FIRMWARE_400) { /* TODO: What are these MC reg writes? */ - MAKE_MC_REG(MC_REGISTER_0x65C) = 0xFFFFF000; - MAKE_MC_REG(MC_REGISTER_0x660) = 0; - MAKE_MC_REG(MC_REGISTER_IRAM_REG_CTRL_0) |= 1; /* overlap at 18.11.1.86 and 18.11.1.87 - lock write access to IRAM and EMEM registers */ + mc_register->_0x65C = 0xFFFFF000; + mc_register->_0x660 = 0; + mc_register->EMEM_CFG_ACCESS_CTRL_0_AND_IRAM_REG_CTRL_0 |= 1; /* overlap at 18.11.1.86 and 18.11.1.87 - lock write access to IRAM and EMEM registers */ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; } } void setup_4x_mmio(void) { + volatile mc_register_t *mc_register = get_mc_reg(); /* TODO: What are these MC reg writes? */ - MAKE_MC_REG(MC_REGISTER_0x65C) = 0xFFFFF000; - MAKE_MC_REG(MC_REGISTER_0x660) = 0; - MAKE_MC_REG(MC_REGISTER_IRAM_REG_CTRL_0) |= 1; /* as above, lock write access to IRAM and EMEM registers */ + mc_register->_0x65C = 0xFFFFF000; + mc_register->_0x660 = 0; + mc_register->EMEM_CFG_ACCESS_CTRL_0_AND_IRAM_REG_CTRL_0 |= 1; /* as above, lock write access to IRAM and EMEM registers */ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; /* TODO: What are these PMC scratch writes? */ @@ -218,6 +222,7 @@ void setup_4x_mmio(void) { APBDEV_PMC_SECURE_SCRATCH103_0 = 0x0; APBDEV_PMC_SECURE_SCRATCH39_0 = (APBDEV_PMC_SECURE_SCRATCH39_0 & 0xF8000000) | 0x88; /* TODO: Do we want to bother locking the secure scratch registers? */ + /* 4.x Jamais Vu mitigations. */ /* Overwrite exception vectors. */ BPMP_VECTOR_RESET = BPMP_MITIGATION_RESET_VAL; @@ -228,8 +233,10 @@ void setup_4x_mmio(void) { BPMP_VECTOR_UNK = BPMP_MITIGATION_RESET_VAL; BPMP_VECTOR_IRQ = BPMP_MITIGATION_RESET_VAL; BPMP_VECTOR_FIQ = BPMP_MITIGATION_RESET_VAL; + /* Disable AHB arbitration for the BPMP. */ AHB_ARBITRATION_DISABLE_0 |= 2; + /* Set SMMU for BPMP/APB-DMA to point to TZRAM. */ MC_SMMU_PTB_ASID_0 = 1; MC_SMMU_PTB_DATA_0 = 0x70012; @@ -239,6 +246,7 @@ void setup_4x_mmio(void) { while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 5) { wait(1); } + /* If not in a debugging context, setup the activity monitor. */ if ((get_debug_authentication_status() & 3) != 3) { FLOW_CTLR_HALT_COP_EVENTS_0 = 0x40000000; From 0674839e89640aa86d02a03eead7fc2d2960a426 Mon Sep 17 00:00:00 2001 From: Resaec Date: Thu, 26 Apr 2018 18:26:23 +0200 Subject: [PATCH 05/10] refactor ramaining #define access --- exosphere/src/bootup.c | 9 +++++---- exosphere/src/mc.h | 10 ---------- exosphere/src/warmboot_main.c | 5 +++-- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index cb19a6b90..e967d3332 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -238,10 +238,11 @@ void setup_4x_mmio(void) { AHB_ARBITRATION_DISABLE_0 |= 2; /* Set SMMU for BPMP/APB-DMA to point to TZRAM. */ - MC_SMMU_PTB_ASID_0 = 1; - MC_SMMU_PTB_DATA_0 = 0x70012; - MC_SMMU_AVPC_ASID_0 = 0x80000001; - MC_SMMU_PPCS1_ASID_0 = 0x80000001; + mc_register->SMMU_PTB_ASID_0 = 1; + mc_register->SMMU_PTB_DATA_0 = 0x70012; + mc_register->SMMU_AVPC_ASID_0 = 0x80000001; + mc_register->SMMU_PPCS1_ASID_0 = 0x80000001; + /* Wait for the BPMP to halt. */ while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 5) { wait(1); diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index 68d8f291e..f044c915d 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -14,16 +14,6 @@ static inline uintptr_t get_mc_base(void) { #define MAKE_MC_REG(n) MAKE_REG32(MC_BASE + n) -#define MC_SMMU_PTB_ASID_0 MAKE_MC_REG(MC_REGISTER_SMMU_PTB_ASID_0) -#define MC_SMMU_PTB_DATA_0 MAKE_MC_REG(MC_REGISTER_SMMU_PTB_DATA_0) -#define MC_SMMU_AVPC_ASID_0 MAKE_MC_REG(MC_REGISTER_SMMU_AVPC_ASID_0) -#define MC_SMMU_PPCS1_ASID_0 MAKE_MC_REG(MC_REGISTER_SMMU_PPCS1_ASID_0) - -#define MC_SECURITY_CFG0_0 MAKE_MC_REG(MC_REGISTER_SECURITY_BOM) -#define MC_SECURITY_CFG1_0 MAKE_MC_REG(MC_REGISTER_SECURITY_SIZE_MB) -#define MC_SECURITY_CFG3_0 MAKE_MC_REG(MC_REGISTER_SECURITY_BOM_HI) - - #define CARVEOUT_ID_MIN 1 #define CARVEOUT_ID_MAX 5 diff --git a/exosphere/src/warmboot_main.c b/exosphere/src/warmboot_main.c index 8c5103dbb..0323bbe9f 100644 --- a/exosphere/src/warmboot_main.c +++ b/exosphere/src/warmboot_main.c @@ -30,7 +30,7 @@ void __attribute__((noreturn)) warmboot_main(void) { identity_unmap_iram_cd_tzram(); /* On warmboot (not cpu_on) only */ - if (MC_SECURITY_CFG3_0 == 0) { + if (get_mc_reg()->SECURITY_BOM_HI == 0) { if (!configitem_is_retail()) { /* TODO: uart_log("OHAYO"); */ } @@ -60,7 +60,8 @@ void __attribute__((noreturn)) warmboot_main(void) { clear_user_smc_in_progress(); if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { - setup_4x_mmio(); } + setup_4x_mmio(); + } } setup_current_core_state(); From 9337162f99a3c63725d2a232497b33bb45d1f8c4 Mon Sep 17 00:00:00 2001 From: Resaec Date: Fri, 27 Apr 2018 22:08:23 +0200 Subject: [PATCH 06/10] bad dec to hex conversion at line 91 --- exosphere/src/bootup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index e967d3332..b1c1c5482 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -88,7 +88,7 @@ void bootup_misc_mmio(void) { /* disable security carveout - SECURITY_CFG0_0, CFG1_0, CFG3_0 */ mc_register->SECURITY_BOM = 0; mc_register->SECURITY_SIZE_MB = 0; - mc_register->SECURITY_BOM_HI = 0x11; + mc_register->SECURITY_BOM_HI = 3; configure_default_carveouts(); @@ -150,7 +150,7 @@ void bootup_misc_mmio(void) { (void)(mc_register->SMMU_TLB_CONFIG_0); mc_register->SMMU_TLB_FLUSH_0 = 0; (void)(mc_register->SMMU_TLB_CONFIG_0); - mc_register->SMMU_CONFIG_0 = 0x1; /* enable SMMU */ + mc_register->SMMU_CONFIG_0 = 1; /* enable SMMU */ (void)(mc_register->SMMU_TLB_CONFIG_0); /* Clear RESET Vector, setup CPU Secure Boot RESET Vectors. */ From 4f5ed74e436fde85663dc179d94b2c6e64ac0431 Mon Sep 17 00:00:00 2001 From: Resaec Date: Sat, 28 Apr 2018 06:15:51 +0200 Subject: [PATCH 07/10] extending the register struct the manual is unordered at times, there is probably still something missing reverted wrong SECURITY_CFG* naming --- exosphere/src/bootup.c | 6 +- exosphere/src/mc.h | 212 +++++++++++++++++++++++++++------- exosphere/src/warmboot_init.c | 2 +- exosphere/src/warmboot_main.c | 2 +- 4 files changed, 178 insertions(+), 44 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index b1c1c5482..630cb326f 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -86,9 +86,9 @@ void bootup_misc_mmio(void) { mc_register->MTS_CARVEOUT_REG_CTRL_0 = 1; /* disable security carveout - SECURITY_CFG0_0, CFG1_0, CFG3_0 */ - mc_register->SECURITY_BOM = 0; - mc_register->SECURITY_SIZE_MB = 0; - mc_register->SECURITY_BOM_HI = 3; + mc_register->SECURITY_CFG0_0 = 0; + mc_register->SECURITY_CFG1_0 = 0; + mc_register->SECURITY_CFG3_0 = 3; configure_default_carveouts(); diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index f044c915d..5f05bd3ea 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -39,73 +39,207 @@ typedef struct { /* 18.11.1 MC Registers */ typedef struct { - uint32_t _0x0[4]; - uint32_t SMMU_CONFIG_0; + uint32_t INTSTATUS_0; + uint32_t INTMASK_0; + uint32_t ERR_STATUS_0; + uint32_t ERR_ADR_0; + uint32_t SMMU_CONFIG_0; /* 0x10 */ uint32_t SMMU_TLB_CONFIG_0; /* Controls usage of the TLB */ uint32_t SMMU_PTC_CONFIG_0; /* Controls usage of the PTC */ uint32_t SMMU_PTB_ASID_0; - uint32_t SMMU_PTB_DATA_0; - uint32_t _0x24[3]; - uint32_t SMMU_TLB_FLUSH_0; + uint32_t SMMU_PTB_DATA_0; /* 0x20 */ + uint32_t _0x24[3]; /* undefined */ + uint32_t SMMU_TLB_FLUSH_0; /* 0x30 */ uint32_t SMMU_PTC_FLUSH_0; - uint32_t _0x38; - uint32_t _0x3C; - uint32_t _0x40[12]; + uint32_t _0x38; /* unknown */ + uint32_t _0x3C; /* unknown */ + uint32_t _0x40[4]; /* undefined */ + uint32_t EMEM_CFG_0; /* 0x50 */ + uint32_t EMEM_ADR_CFG_0; + uint32_t EMEM_ADR_CFG_DEV0_0; + uint32_t EMEM_ADR_CFG_DEV1_0; + uint32_t EMEM_ADR_CFG_CHANNEL_MASK_0; /* 0x60 */ + uint32_t EMEM_ADR_CFG_BANK_MASK_0_0; + uint32_t EMEM_ADR_CFG_BANK_MASK_1_0; + uint32_t EMEM_ADR_CFG_BANK_MASK_2_0; + /* SECURITY_BOM is the base of the secured region, limited to MB granularity. This must point to a region of the physical address map allocated to EMEM for it to be effective; the MC cannot secure address space it does not own. (In other words, this is an absolute address, not an offset.) Above is the list of clients with the TrustZone-security access. [18.11.1.20] - Note that AXICIF clients will adhere to the standard AXI protocol "aprot[1]==0" indication for secure requests. */ - uint32_t SECURITY_BOM; /* MC_SECURITY_CFG0_0 */ - uint32_t SECURITY_SIZE_MB; /* MC_SECURITY_CFG1_0 -- SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ - uint32_t _0x78[26]; - uint32_t EMEM_ARB_RING1_THROTTLE_0; + Note that AXICIF clients will adhere to the standard AXI protocol "aprot[1]==0" indication for secure requests. + 0x70 + */ + uint32_t SECURITY_CFG0_0; + uint32_t SECURITY_CFG1_0; /* SECURITY_SIZE_MB is the size, in megabytes, of the secured region. If set to 0, the security check in MC is disabled */ + uint32_t _0x78[6]; /* undefined */ + uint32_t EMEM_ARB_CFG_0; /* 0x90 */ + uint32_t EMEM_ARB_OUTSTANDING_REQ_0; + uint32_t EMEM_ARB_TIMING_RCD_0; + uint32_t EMEM_ARB_TIMING_RP_0; + uint32_t EMEM_ARB_TIMING_RC_0; /* 0xA0 */ + uint32_t EMEM_ARB_TIMING_RAS_0; + uint32_t EMEM_ARB_TIMING_FAW_0; + uint32_t EMEM_ARB_TIMING_RRD_0; + uint32_t EMEM_ARB_TIMING_RAP2PRE_0; /* 0xB0 */ + uint32_t EMEM_ARB_TIMING_WAP2PRE_0; + uint32_t EMEM_ARB_TIMING_R2R_0; + uint32_t EMEM_ARB_TIMING_W2W_0; + uint32_t EMEM_ARB_TIMING_R2W_0; /* 0xC0 */ + uint32_t EMEM_ARB_TIMING_W2R_0; + uint32_t EMEM_ARB_MISC2_0; + uint32_t _0xCC[1]; /* undefined */ + uint32_t EMEM_ARB_DA_TURNS_0; /* 0x D0 */ + uint32_t EMEM_ARB_DA_COVERS_0; + uint32_t EMEM_ARB_MISC0_0; + uint32_t EMEM_ARB_MISC1_0; + uint32_t EMEM_ARB_RING1_THROTTLE_0; /* 0xE0 */ uint32_t EMEM_ARB_RING3_THROTTLE_0; uint32_t EMEM_ARB_OVERRIDE_0; uint32_t EMEM_ARB_RSV_0; - uint32_t _0xF0; + uint32_t _0xF0[1]; /* undefined */ /* 0xF0 */ uint32_t CLKEN_OVERRIDE_0; - uint32_t _0xF8[76]; + uint32_t _0xF8[1]; /* undefined */ + uint32_t TIMING_CONTROL_0; + uint32_t STAT_CONTROL_0; /* 0x100 */ + uint32_t _0x104[63]; /* undefined */ + uint32_t CLIENT_HOTRESET_CTRL_0; /* 0x200 */ + uint32_t CLIENT_HOTRESET_STATUS_0; + uint32_t EMEM_ARB_ISOCHRONOUS_0_0; + uint32_t EMEM_ARB_ISOCHRONOUS_1_0; + uint32_t EMEM_ARB_ISOCHRONOUS_2_0; /* 0x210 */ + uint32_t EMEM_ARB_ISOCHRONOUS_3_0; + uint32_t EMEM_ARB_HYSTERESIS_0_0; + uint32_t EMEM_ARB_HYSTERESIS_1_0; + uint32_t EMEM_ARB_HYSTERESIS_2_0; /* 0x220 */ + uint32_t EMEM_ARB_HYSTERESIS_3_0; uint32_t SMMU_TRANSLATION_ENABLE_0_0; uint32_t SMMU_TRANSLATION_ENABLE_1_0; - uint32_t SMMU_TRANSLATION_ENABLE_2_0; + uint32_t SMMU_TRANSLATION_ENABLE_2_0; /* 0x230 */ uint32_t SMMU_TRANSLATION_ENABLE_3_0; - uint32_t _0x234[1]; + uint32_t SMMU_AFI_ASID_0; uint32_t SMMU_AVPC_ASID_0; - uint32_t _0x240[22]; + uint32_t SMMU_DC_ASID_0; /* 0x240 */ + uint32_t SMMU_DCB_ASID_0; + uint32_t _0x228[2]; /* undefined */ + uint32_t SMMU_HC_ASID_0; /* 0x250 */ + uint32_t SMMU_HDA_ASID_0; + uint32_t SMMU_ISP2_ASID_0; + uint32_t _0x25C[2]; /* undefined */ + uint32_t SMMU_NVENC_ASID_0; + uint32_t SMMU_NV_ASID_0; + uint32_t SMMU_NV2_ASID_0; + uint32_t SMMU_PPCS_ASID_0; /* 0x270 */ + uint32_t SMMU_SATA_ASID_0; + uint32_t _0x278[2]; /* undefined */ + uint32_t SMMU_VI_ASID_0; /* 0x280 */ + uint32_t SMMU_VIC_ASID_0; + uint32_t SMMU_XUSB_HOST_ASID_0; + uint32_t SMMU_XUSB_DEV_ASID_0; + uint32_t _0x290[1]; /* undefined */ + uint32_t SMMU_TSEC_ASID_0; uint32_t SMMU_PPCS1_ASID_0; - uint32_t _0x29C[235]; - uint32_t _0x648; - uint32_t _0x64C; - uint32_t _0x650; - uint32_t _0x654[2]; - uint32_t _0x65C; - uint32_t _0x660; - uint32_t _0x664[3]; - uint32_t SEC_CARVEOUT_BOM_0; /* [PMC_SECURE] Base address for the SEC carveout address space */ + uint32_t _0x29C[95]; /* undefined */ + uint32_t VIDEO_PROTECT_VPR_OVERRIDE_0; + uint32_t _0x41C[93]; /* undefined */ + uint32_t VIDEO_PROTECT_VPR_OVERRIDE1_0; /* 0x590 */ + uint32_t _0x594[27]; /* undefined */ + uint32_t SMMU_TLB_SET_SELECTION_MASK_0_0; /* 0x600 */ + uint32_t _0x604[1]; /* undefined */ + uint32_t DISPLAY_SNAP_RING_0; + uint32_t _0x648; /* unknown */ + uint32_t _0x64C; /* unknown */ + uint32_t _0x650; /* unknown */ /* 0x650 */ + uint32_t ERR_VPR_STATUS_0; + uint32_t ERR_VPR_ADR_0; + uint32_t _0x65C; /* unknown */ + uint32_t _0x660; /* unknown */ /* 0x660 */ + uint32_t EMEM_CFG_ACCESS_CTRL_0; + uint32_t TZ_SECURITY_CTRL_0; + uint32_t EMEM_ARB_OUTSTANDING_REQ_RING3_0; /* Access Control Bit for EMEM_CFG Registers - Sticky write access lock - 18.11.1.87 */ + uint32_t SEC_CARVEOUT_BOM_0; /* [PMC_SECURE] Base address for the SEC carveout address space */ /* 0x670 */ uint32_t SEC_CARVEOUT_SIZE_MB_0; /* [PMC_SECURE] SEC_CARVEOUT_SIZE_MB is the size, in megabytes, of the SEC carveout region. If set to 0, the security check in MC is disabled */ + /* [PMC_SECURE] Sticky bit to control the writes to the other Sec Carveout aperture registers 0 = Enabled - 1 = Disabled */ + 1 = Disabled + */ uint32_t SEC_CARVEOUT_REG_CTRL_0; - uint32_t _0x67C[186]; - uint32_t EMEM_CFG_ACCESS_CTRL_0_AND_IRAM_REG_CTRL_0; - uint32_t _0x968[7]; + uint32_t ERR_SEC_STATUS_0; + uint32_t ERR_SEC_ADR_0; /* 0x680 */ + uint32_t PC_IDLE_CLOCK_GATE_CONFIG_0; + uint32_t STUTTER_CONTROL_0; + uint32_t _0x68C[9]; /* undefined */ + uint32_t EMEM_ARB_NISO_THROTTLE_0; /* 0x6B0 */ + uint32_t EMEM_ARB_OUTSTANDING_REQ_NISO_0; + uint32_t EMEM_ARB_NISO_THROTTLE_MASK_0; + uint32_t EMEM_ARB_RING0_THROTTLE_MASK_0; + uint32_t EMEM_ARB_TIMING_RFCPB_0; /* 0x6C0 */ + uint32_t EMEM_ARB_TIMING_CCDMW_0; + uint32_t _0x6C8[10]; /* undefined */ + uint32_t EMEM_ARB_REFPB_HP_CTRL_0; /* 0x6F0 */ + uint32_t EMEM_ARB_REFPB_BANK_CTRL_0; + uint32_t _0x6F8[155]; /* undefined */ + uint32_t IRAM_REG_CTRL_0; + uint32_t EMEM_ARB_OVERRIDE_1_0; + uint32_t _0x96C[1]; /* undefined */ + uint32_t CLIENT_HOTRESET_CTRL_1_0; /* 0x970 */ + uint32_t CLIENT_HOTRESET_STATUS_1_0; + uint32_t _0x978[3]; /* undefined */ uint32_t VIDEO_PROTECT_GPU_OVERRIDE_0_0; - uint32_t _0x988[6]; - uint32_t MTS_CARVEOUT_BOM_0; + uint32_t VIDEO_PROTECT_GPU_OVERRIDE_1_0; + uint32_t _0x98C[5]; /* undefined */ + uint32_t MTS_CARVEOUT_BOM_0; /* 0x9A0 */ uint32_t MTS_CARVEOUT_SIZE_MB_0; uint32_t MTS_CARVEOUT_ADR_HI_0; + /* MTS_CARVEOUT_WRITE_ACCESS 0 = Enabled - 1 = Disabled */ + 1 = Disabled + */ uint32_t MTS_CARVEOUT_REG_CTRL_0; - uint32_t _0x9B0[3]; + uint32_t _0x9B0[2]; /* undefined */ /* 0x9B0 */ + uint32_t SMMU_PTC_FLUSH_1_0; + /* Base Address Higher Bits SECURITY_BOM_HI has the higher address bits beyond 32 bits of the - base of the secured region, limited to MB granularity */ - uint32_t SECURITY_BOM_HI; /* MC_SECURITY_CFG3_0 */ - uint32_t _0x9C0[118]; - uint32_t SMMU_TRANSLATION_ENABLE_4_0; + base of the secured region, limited to MB granularity + */ + uint32_t SECURITY_CFG3_0; + uint32_t EMEM_BANK_SWIZZLE_CFG0_0; /* 0x9C0 */ + uint32_t EMEM_BANK_SWIZZLE_CFG1_0; + uint32_t EMEM_BANK_SWIZZLE_CFG2_0; + uint32_t EMEM_BANK_SWIZZLE_CFG3_0; + uint32_t _0x9D0[1]; /* undefined */ + uint32_t SEC_CARVEOUT_ADR_HI_0; + uint32_t _0x9D8[44]; /* undefined */ + uint32_t SMMU_DC1_ASID_0; /* 0xA88 */ + uint32_t _0xA8C[2]; /* undefined */ + uint32_t SMMU_SDMMC1A_ASID_0; + uint32_t SMMU_SDMMC2A_ASID_0; + uint32_t SMMU_SDMMC3A_ASID_0; + uint32_t SMMU_SDMMC4A_ASID_0; /* 0xAA0 */ + uint32_t SMMU_ISP2B_ASID_0; + uint32_t SMMU_GPU_ASID_0; + uint32_t SMMU_GPUB_ASID_0; + uint32_t SMMU_PPCS2_ASID_0; /* 0xAB0 */ + uint32_t SMMU_NVDEC_ASID_0; + uint32_t SMMU_APE_ASID_0; + uint32_t SMMU_SE_ASID_0; + uint32_t SMMU_NVJPG_ASID_0; /* 0xAC0 */ + uint32_t SMMU_HC1_ASID_0; + uint32_t SMMU_SE1_ASID_0; + uint32_t SMMU_AXIAP_ASID_0; + uint32_t SMMU_ETR_ASID_0; /* 0xAD0 */ + uint32_t SMMU_TSECB_ASID_0; + uint32_t SMMU_TSEC1_ASID_0; + uint32_t SMMU_TSECB1_ASID_0; + uint32_t SMMU_NVDEC1_ASID_0; /* 0xAE0 */ + uint32_t _0xAE4[39]; /* undefined */ + uint32_t EMEM_ARB_NISO_THROTTLE_MASK_1_0; /* 0xB80 */ + uint32_t EMEM_ARB_HYSTERESIS_4_0; + uint32_t _0xB88[3]; /* undefined */ + uint32_t EMEM_ARB_ISOCHRONOUS_4_0; + uint32_t SMMU_TRANSLATION_ENABLE_4_0; /* 0xB98 */ } mc_register_t; /* 0xB98 */ volatile security_carveout_t *get_carveout_by_id(unsigned int carveout); diff --git a/exosphere/src/warmboot_init.c b/exosphere/src/warmboot_init.c index 86fadfb4b..acb65c242 100644 --- a/exosphere/src/warmboot_init.c +++ b/exosphere/src/warmboot_init.c @@ -166,7 +166,7 @@ void warmboot_init(boot_func_list_t *func_list) { func_list->funcs.invalidate_icache_all(); /* On warmboot (not cpu_on) only */ - if (MC_SECURITY_CFG3_0 == 0) { + if (get_mc_reg()->SECURITY_CFG3_0 == 0) { init_dma_controllers(func_list->target_firmware); } diff --git a/exosphere/src/warmboot_main.c b/exosphere/src/warmboot_main.c index 0323bbe9f..32bd26c3d 100644 --- a/exosphere/src/warmboot_main.c +++ b/exosphere/src/warmboot_main.c @@ -30,7 +30,7 @@ void __attribute__((noreturn)) warmboot_main(void) { identity_unmap_iram_cd_tzram(); /* On warmboot (not cpu_on) only */ - if (get_mc_reg()->SECURITY_BOM_HI == 0) { + if (get_mc_reg()->SECURITY_CFG3_0 == 0) { if (!configitem_is_retail()) { /* TODO: uart_log("OHAYO"); */ } From 2095c633aa9a940b31e1040a2172946cea605380 Mon Sep 17 00:00:00 2001 From: Resaec Date: Sat, 28 Apr 2018 06:18:20 +0200 Subject: [PATCH 08/10] those too --- exosphere/src/bootup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index 630cb326f..0a28082af 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -193,7 +193,7 @@ void bootup_misc_mmio(void) { /* TODO: What are these MC reg writes? */ mc_register->_0x65C = 0xFFFFF000; mc_register->_0x660 = 0; - mc_register->EMEM_CFG_ACCESS_CTRL_0_AND_IRAM_REG_CTRL_0 |= 1; /* overlap at 18.11.1.86 and 18.11.1.87 - lock write access to IRAM and EMEM registers */ + mc_register->IRAM_REG_CTRL_0 |= 1; /* lock write access to IRAM registers */ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; } } @@ -203,7 +203,7 @@ void setup_4x_mmio(void) { /* TODO: What are these MC reg writes? */ mc_register->_0x65C = 0xFFFFF000; mc_register->_0x660 = 0; - mc_register->EMEM_CFG_ACCESS_CTRL_0_AND_IRAM_REG_CTRL_0 |= 1; /* as above, lock write access to IRAM and EMEM registers */ + mc_register->IRAM_REG_CTRL_0 |= 1; /* lock write access to IRAM registers */ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD_0 &= 0xFFF7FFFF; /* TODO: What are these PMC scratch writes? */ From 5d975631400a3161f19bd5e0df658485d4df65d3 Mon Sep 17 00:00:00 2001 From: Resaec Date: Sat, 28 Apr 2018 06:21:14 +0200 Subject: [PATCH 09/10] adding register enumerators for SMMU_TLB_CONFIG, SMMU_PTC_CONFIG, SMMU_PTB_DATA, SMMU_AVPC_ASID and SMMU_PPCS1_ASID refactoring mc_register writes where posible --- exosphere/src/bootup.c | 12 +++++------ exosphere/src/mc.h | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index 0a28082af..bc50a7ede 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -141,8 +141,8 @@ void bootup_misc_mmio(void) { /* reset PTB, TLB and PTC */ mc_register->SMMU_PTB_DATA_0 = 0; - mc_register->SMMU_TLB_CONFIG_0 = 0x30000030; - mc_register->SMMU_PTC_CONFIG_0 = 0x2800003F; + mc_register->SMMU_TLB_CONFIG_0 = SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION | SMMU_TLB_CONFIG_HIT_UNDER_MISS | 0x30; /* reset to default - 0x30 => TLB_ACTIVE_LINES */ + mc_register->SMMU_PTC_CONFIG_0 = SMMU_PTC_CONFIG_CACHE_ENABLE | 0x8000000 | 0x3F; /* reset to default, except PTC_LINE_MASK - 0x8000000 = 0x8 << 27 => PTC_REQ_LIMIT - 0x37 => PTC_INDEX_MAP */ /* TODO: What are these MC reg writes? */ (void)(mc_register->SMMU_TLB_CONFIG_0); @@ -238,10 +238,10 @@ void setup_4x_mmio(void) { AHB_ARBITRATION_DISABLE_0 |= 2; /* Set SMMU for BPMP/APB-DMA to point to TZRAM. */ - mc_register->SMMU_PTB_ASID_0 = 1; - mc_register->SMMU_PTB_DATA_0 = 0x70012; - mc_register->SMMU_AVPC_ASID_0 = 0x80000001; - mc_register->SMMU_PPCS1_ASID_0 = 0x80000001; + mc_register->SMMU_PTB_ASID_0 = 0x1; /* CURRENT_ASID */ + mc_register->SMMU_PTB_DATA_0 = 0x70012; /* ASID_PDE_BASE */ + mc_register->SMMU_AVPC_ASID_0 = SMMU_AVPC_ASID_AVPC_SMMU_ENABLE | 0x1; /* 0x1 => AVPC_ASID */ + mc_register->SMMU_PPCS1_ASID_0 = SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE | 0x1; /* 0x1 => PPCS1_ASID */ /* Wait for the BPMP to halt. */ while ((FLOW_CTLR_HALT_COP_EVENTS_0 >> 29) != 5) { diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index 5f05bd3ea..e2ae8c1bd 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -242,6 +242,55 @@ typedef struct { uint32_t SMMU_TRANSLATION_ENABLE_4_0; /* 0xB98 */ } mc_register_t; /* 0xB98 */ +/* 18.11.1.6 MC_SMMU_TLB_CONFIG_0 */ +typedef enum{ + /* Set the number of active lines. + Allows the TLB to be made "virtually smaller" to save power. + "Inactive" lines will never hit and never hold data + */ + SMMU_TLB_CONFIG_ACTIVE_LINES = 0x3F << 0, + SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION = 1 << 28, /* When enabled, forces round robin (RR) arbitration between TLB hit and miss FIFOs */ + + /* Allow hits to pass misses in the TLB. + This value may not be changed on the fly. + Ideally, this should be set before enabling the SMMU. + At the very least, the TLB needs to be flushed and traffic through the SMMU stopped before changing this value + */ + SMMU_TLB_CONFIG_HIT_UNDER_MISS = 1 << 29, + SMMU_TLB_CONFIG_STATS_TEST = 1 << 30, /* Set stats registers to all "1s" */ + SMMU_TLB_CONFIG_STATS_ENABLE = 1 << 31, /* Enable TLB Hit and Miss counters */ +} SMMU_TLB_CONFIG; + +/* 18.11.1.7 MC_SMMU_PTC_CONFIG_0 */ +typedef enum { + SMMU_PTC_CONFIG_INDEX_MAP = 0x7F << 0, /* XOR pattern for tag generation */ + SMMU_PTC_CONFIG_LINE_MASK = 0xF << 8, /* XOR pattern for line generation */ + SMMU_PTC_CONFIG_REQ_LIMIT = 0xF << 24, /* Limit outstanding PTC fill requests to the DRAM */ + SMMU_PTC_CONFIG_CACHE_ENABLE = 1 << 29, /* Enable the PTC cache */ + SMMU_PTC_CONFIG_STATS_TEST = 1 << 30, /* Set stats registers to all "1s" */ + SMMU_PTC_CONFIG_STATS_ENABLE = 1 << 31 /* Enable PTC Hit and Miss counters */ +} SMMU_PTC_CONFIG; + +/* 18.11.1.9 MC_SMMU_PTB_DATA_0 */ +typedef enum { + SSM_PTB_DATA_ASID_PDE_BASE = 0x3FFFFF << 0, /* Pointer to page of PDEs, bits [33:12] for this ASID */ + SSM_PTB_DATA_ASID_NONSECURE = 1 << 29, /* if set, non-secure accesses are allowed for this ASID */ + SSM_PTB_DATA_ASID_WRITABLE = 1 << 30, /* if set, writes are allowed for this ASID */ + SSM_PTB_DATA_ASID_READABLE = 1 << 31 /* if set, reads are allowed for this ASID */ +} SMMU_PTB_DATA; + +/* 18.11.1.63 MC_SMMU_AVPC_ASID_0 */ +typedef enum { + SMMU_AVPC_ASID_AVPC_ASID = 0x7F << 0, /* If translation enabled, ASID to use when va[33:32] = 0x0 */ + SMMU_AVPC_ASID_AVPC_SMMU_ENABLE = 1 << 31 /* if set, translation is enabled for this client */ +} SMMU_AVPC_ASID; + +/* 18.11.1.79 MC_SMMU_PPCS1_ASID_0 */ +typedef enum{ + SMMU_PPCS1_ASID_PPCS1_ASID = 0x7F << 0, /* if set, translation is enabled for this client */ + SMMU_PPCS1_ASID_PPCS1_SMMU_ENABLE = 1 << 31 /* If translation enabled, ASID to use when va[33:32] = 0x0 */ +} SMMU_PPCS1_ASID; + volatile security_carveout_t *get_carveout_by_id(unsigned int carveout); void configure_default_carveouts(void); void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size); From edfd0a0196f257567dba05721cc9a88f9404e1ad Mon Sep 17 00:00:00 2001 From: Resaec Date: Tue, 1 May 2018 01:05:28 +0200 Subject: [PATCH 10/10] _0xF0 is an unknown register, it is used in bootup.c, compiles fine now --- exosphere/src/mc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index e2ae8c1bd..b3aa9d265 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -96,7 +96,7 @@ typedef struct { uint32_t EMEM_ARB_RING3_THROTTLE_0; uint32_t EMEM_ARB_OVERRIDE_0; uint32_t EMEM_ARB_RSV_0; - uint32_t _0xF0[1]; /* undefined */ /* 0xF0 */ + uint32_t _0xF0; /* unknown */ /* 0xF0 */ uint32_t CLKEN_OVERRIDE_0; uint32_t _0xF8[1]; /* undefined */ uint32_t TIMING_CONTROL_0;