Exosphere: Fix MC carveout setup bug, now receives smcCpuOn from kernel on 1.0.0.

This commit is contained in:
Michael Scire 2018-05-21 20:14:06 -06:00
parent b777844d2d
commit ef9adabb40
5 changed files with 70 additions and 40 deletions

View File

@ -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+) */
}
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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());
}

View File

@ -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);