From ef9adabb4035c79173e0aa8290f626ad4997c6eb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 21 May 2018 20:14:06 -0600 Subject: [PATCH] Exosphere: Fix MC carveout setup bug, now receives smcCpuOn from kernel on 1.0.0. --- exosphere/src/bootup.c | 69 +++++++++++++++++++++++----------------- exosphere/src/mc.c | 30 ++++++++++++++--- exosphere/src/mc.h | 2 +- exosphere/src/package2.c | 7 ++-- exosphere/src/smc_api.c | 2 ++ 5 files changed, 70 insertions(+), 40 deletions(-) diff --git a/exosphere/src/bootup.c b/exosphere/src/bootup.c index c896714a6..6cfddf5d7 100644 --- a/exosphere/src/bootup.c +++ b/exosphere/src/bootup.c @@ -86,26 +86,33 @@ void bootup_misc_mmio(void) { /* Mark registers secure world only. */ - /* Mark SATA_AUX, DTV, QSPI, SE, SATA, LA secure only. */ - APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SE | APB_SSER0_SATA | APB_SSER0_LA; + if (exosphere_get_target_firmware() == EXOSPHERE_TARGET_FIRMWARE_100) { + /* TODO: Switch these to use the enum. */ + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = 0x500244; + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 = 0xA3700000; + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG2_0 = 0x304; + } else { + /* Mark SATA_AUX, DTV, QSPI, SE, SATA, LA secure only. */ + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 = APB_SSER0_SATA_AUX | APB_SSER0_DTV | APB_SSER0_QSPI | APB_SSER0_SE | APB_SSER0_SATA | APB_SSER0_LA; - /* By default, mark SPI1, SPI2, SPI3, SPI5, SPI6, I2C6 secure only. */ - uint32_t sec_disable_1 = APB_SSER1_SPI1 | APB_SSER1_SPI2 | APB_SSER1_SPI3 | APB_SSER1_SPI5 | APB_SSER1_SPI6 | APB_SSER1_I2C6; - /* By default, mark SDMMC3, DDS, DP2 secure only. */ - uint32_t sec_disable_2 = APB_SSER2_SDMMC3 | APB_SSER2_DDS | APB_SSER2_DP2; - uint64_t hardware_type = configitem_get_hardware_type(); - if (hardware_type != 1) { - /* Also mark I2C4 secure only, */ - sec_disable_1 |= APB_SSER1_I2C4; + /* By default, mark SPI1, SPI2, SPI3, SPI5, SPI6, I2C6 secure only. */ + uint32_t sec_disable_1 = APB_SSER1_SPI1 | APB_SSER1_SPI2 | APB_SSER1_SPI3 | APB_SSER1_SPI5 | APB_SSER1_SPI6 | APB_SSER1_I2C6; + /* By default, mark SDMMC3, DDS, DP2 secure only. */ + uint32_t sec_disable_2 = APB_SSER2_SDMMC3 | APB_SSER2_DDS | APB_SSER2_DP2; + uint64_t hardware_type = configitem_get_hardware_type(); + if (hardware_type != 1) { + /* Also mark I2C4 secure only, */ + sec_disable_1 |= APB_SSER1_I2C4; + } + if (hardware_type != 0 && exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { + /* Starting on 4.x on non-dev units, mark UARTB, UARTC, SPI4, I2C3 secure only. */ + sec_disable_1 |= APB_SSER1_UART_B | APB_SSER1_UART_C | APB_SSER1_SPI4 | APB_SSER1_I2C3; + /* Starting on 4.x on non-dev units, mark SDMMC1 secure only. */ + sec_disable_2 |= APB_SSER2_SDMMC1; + } + 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; } - if (hardware_type != 0 && exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { - /* Starting on 4.x on non-dev units, mark UARTB, UARTC, SPI4, I2C3 secure only. */ - sec_disable_1 |= APB_SSER1_UART_B | APB_SSER1_UART_C | APB_SSER1_SPI4 | APB_SSER1_I2C3; - /* Starting on 4.x on non-dev units, mark SDMMC1 secure only. */ - sec_disable_2 |= APB_SSER2_SDMMC1; - } - 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; @@ -156,15 +163,19 @@ void bootup_misc_mmio(void) { 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 (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { + 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); + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { + 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); } @@ -286,11 +297,11 @@ void identity_unmap_iram_cd_tzram(void) { } void secure_additional_devices(void) { - if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { - APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 |= APB_SSER0_PMC; /* make PMC secure-only (2.x+ but see note below) */ - APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 |= APB_SSER1_MC0 | APB_SSER1_MC1 | APB_SSER1_MCB; /* make MC0, MC1, MCB secure-only (4.x+) */ - } else { - /* TODO: Detect 1.x */ + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) { + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 |= APB_SSER0_PMC; /* make PMC secure-only (2.x+) */ + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_400) { + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 |= APB_SSER1_MC0 | APB_SSER1_MC1 | APB_SSER1_MCB; /* make MC0, MC1, MCB secure-only (4.x+) */ + } } } diff --git a/exosphere/src/mc.c b/exosphere/src/mc.c index 6a5cf7980..bf1259b4b 100644 --- a/exosphere/src/mc.c +++ b/exosphere/src/mc.c @@ -2,6 +2,7 @@ #include "memory_map.h" #include "mc.h" +#include "exocfg.h" volatile security_carveout_t *get_carveout_by_id(unsigned int carveout) { if (CARVEOUT_ID_MIN <= carveout && carveout <= CARVEOUT_ID_MAX) { @@ -64,12 +65,31 @@ void configure_default_carveouts(void) { carveout->allowed_clients = 0x4401E7E; /* Configure default Kernel carveouts based on 2.0.0+. */ + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_200) { + /* Configure Carveout 4 (KERNEL_BUILTINS) */ + configure_kernel_carveout(4, 0x80060000, KERNEL_CARVEOUT_SIZE_MAX); - /* Configure Carveout 4 (KERNEL_BUILTINS) */ - configure_kernel_carveout(4, 0x80060000, KERNEL_CARVEOUT_SIZE_MAX); - - /* Configure Carveout 5 (KERNEL_UNUSED) */ - configure_kernel_carveout(5, 0, 0); + /* Configure Carveout 5 (KERNEL_UNUSED) */ + configure_kernel_carveout(5, 0, 0); + } else { + for (unsigned int i = 4; i <= 5; i++) { + carveout = get_carveout_by_id(i); + carveout->paddr_low = 0; + carveout->paddr_high = 0; + carveout->size_big_pages = 0; + carveout->flags_0 = 0; + carveout->flags_1 = 0; + carveout->flags_2 = 0; + carveout->flags_3 = 0; + carveout->flags_4 = 0; + carveout->flags_5 = 0; + carveout->flags_6 = 0; + carveout->flags_7 = 0; + carveout->flags_8 = 0; + carveout->flags_9 = 0; + carveout->allowed_clients = 0x4000006; + } + } } void configure_kernel_carveout(unsigned int carveout_id, uint64_t address, uint64_t size) { diff --git a/exosphere/src/mc.h b/exosphere/src/mc.h index af98dd262..de5141700 100644 --- a/exosphere/src/mc.h +++ b/exosphere/src/mc.h @@ -44,7 +44,7 @@ typedef struct { uint32_t flags_7; uint32_t flags_8; uint32_t flags_9; - uint8_t padding[0x28]; + uint8_t padding[0x18]; } security_carveout_t; diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index cd79feacc..bc569be91 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -296,7 +296,6 @@ static uint32_t decrypt_and_validate_header(package2_header_t *header) { memcpy(metadata.ctr, header->metadata.ctr, sizeof(header->metadata.ctr)); /* See if this is the correct key. */ if (validate_package2_metadata(&metadata)) { - se_calculate_sha256(metadata.ctr, &header->metadata, sizeof(package2_meta_t)); header->metadata = metadata; return mkey_rev; } @@ -474,7 +473,7 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { /* Load Package2 Sections. */ load_package2_sections(&header.metadata, package2_mkey_rev); - + /* Clean up cache. */ flush_dcache_all(); invalidate_icache_all(); /* non-broadcasting */ @@ -497,7 +496,5 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) { set_version_specific_smcs(); /* Update SCR_EL3 depending on value in Bootconfig. */ - set_extabt_serror_taken_to_el3(bootconfig_take_extabt_serror_to_el3()); - strcpy((void *)MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM), (void *)"PK2LOADED"); - MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; + set_extabt_serror_taken_to_el3(bootconfig_take_extabt_serror_to_el3()); } diff --git a/exosphere/src/smc_api.c b/exosphere/src/smc_api.c index a26f457d5..bbedf6ede 100644 --- a/exosphere/src/smc_api.c +++ b/exosphere/src/smc_api.c @@ -230,6 +230,8 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) { generic_panic(); } + MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_DEBUG_IRAM)) = 0xD0D0D0D0; + MAKE_REG32(MMIO_GET_DEVICE_ADDRESS(MMIO_DEVID_RTC_PMC) + 0x400ull) = 0x10; /* Call function. */ args->X[0] = smc_handler(args);