Add most of warmboot_main

This commit is contained in:
TuxSH 2018-03-03 19:31:22 +01:00
parent be6b67669f
commit 03c1ad7119
12 changed files with 135 additions and 57 deletions

View file

@ -64,7 +64,7 @@ bool bootconfig_is_debug_mode(void) {
return (LOADED_BOOTCONFIG->unsigned_config.data[0x10] & 2) != 0;
}
bool bootconfig_should_set_scr_el3_bit(void) {
bool bootconfig_take_extabt_serror_to_el3(void) {
return (LOADED_BOOTCONFIG->unsigned_config.data[0x10] & 6) != 6;
}

View file

@ -43,7 +43,7 @@ bool bootconfig_is_package2_unsigned(void);
bool bootconfig_disable_program_verification(void);
bool bootconfig_is_debug_mode(void);
bool bootconfig_should_set_scr_el3_bit(void);
bool bootconfig_take_extabt_serror_to_el3(void);
uint64_t bootconfig_get_memory_arrangement(void);
uint64_t bootconfig_get_kernel_memory_configuration(void);

View file

@ -21,6 +21,11 @@
#include "actmon.h"
#include "syscrt0.h"
#include "mmu.h"
#include "arm.h"
#include "memory_map.h"
#include "synchronization.h"
static bool g_has_booted_up = false;
void bootup_misc_mmio(void) {
@ -181,12 +186,12 @@ void setup_current_core_state(void) {
SET_SYSREG(sctlr_el1, 0xC50838ull);
SET_SYSREG(sctlr_el2, 0x30C50838ull);
do { __asm__ __volatile__ ("isb"); } while (false);
__isb();
SET_SYSREG(cntfrq_el0, MAKE_SYSCRT0_REG(0x20)); /* TODO: Reg name. */
SET_SYSREG(cnthctl_el2, 3ull);
do { __asm__ __volatile__ ("isb"); } while (false);
__isb();
/* Setup Interrupts, flow. */
flow_clear_csr0_and_events(get_core_id());
@ -198,3 +203,40 @@ void setup_current_core_state(void) {
/* Restore current core context. */
restore_current_core_context();
}
void identity_unmap_iram_cd_tzram(void) {
/* See also: configure_ttbls (in coldboot_init.c). */
uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
uintptr_t *mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
mmu_unmap_range(3, mmu_l3_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_IRAM_CD), IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_IRAM_CD));
mmu_unmap_range(3, mmu_l3_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_TZRAM), IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_TZRAM));
mmu_unmap(2, mmu_l2_tbl, 0x40000000);
mmu_unmap(2, mmu_l2_tbl, 0x7C000000);
mmu_unmap(1, mmu_l1_tbl, 0x40000000);
tlb_invalidate_all_inner_shareable();
}
void secure_additional_devices(void) {
if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0 |= 0x2000; /* make PMC secure-only (2.x+ but see note below) */
APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0 |= 0X510; /* make MC0, MC1, MCB secure-only (4.x+) */
} else {
/* TODO: Detect 1.x */
}
}
void set_extabt_serror_taken_to_el3(bool taken_to_el3) {
uint64_t temp_scr_el3;
__asm__ __volatile__ ("mrs %0, scr_el3" : "=r"(temp_scr_el3) :: "memory");
temp_scr_el3 &= 0xFFFFFFF7;
temp_scr_el3 |= taken_to_el3 ? 8 : 0;
__asm__ __volatile__ ("msr scr_el3, %0" :: "r"(temp_scr_el3) : "memory");
__isb();
}

View file

@ -9,4 +9,10 @@ void setup_4x_mmio(void);
void setup_current_core_state(void);
void identity_unmap_iram_cd_tzram(void);
void secure_additional_devices(void);
void set_extabt_serror_taken_to_el3(bool taken_to_el3);
#endif

View file

@ -31,7 +31,7 @@ static saved_cpu_context_t g_cpu_contexts[NUM_CPU_CORES] = {0};
void use_core_entrypoint_and_argument(uint32_t core, uintptr_t *entrypoint_addr, uint64_t *argument) {
saved_cpu_context_t *ctx = &g_cpu_contexts[core];
if(ctx->ELR_EL3 == 0 || ctx->is_active) {
panic(0xFA000007); /* invalid context */
panic(0xF7F00007); /* invalid context */
}
*entrypoint_addr = ctx->ELR_EL3;
@ -39,7 +39,7 @@ void use_core_entrypoint_and_argument(uint32_t core, uintptr_t *entrypoint_addr,
ctx->ELR_EL3 = 0;
ctx->argument = 0;
ctx->is_active = true;
ctx->is_active = 1;
}
void set_core_entrypoint_and_argument(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument) {
@ -47,7 +47,7 @@ void set_core_entrypoint_and_argument(uint32_t core, uintptr_t entrypoint_addr,
g_cpu_contexts[core].argument = argument;
}
void core_jump_to_lower_el(void) {
void __attribute__((noreturn)) core_jump_to_lower_el(void) {
uintptr_t ep;
uint64_t arg;
unsigned int core_id = get_core_id();
@ -178,6 +178,10 @@ void restore_current_core_context(void) {
}
}
bool is_core_active(uint32_t core) {
return g_cpu_contexts[core].is_active != 0;
}
void set_core_is_active(uint32_t core, bool is_active) {
g_cpu_contexts[core].is_active = (is_active) ? 1 : 0;
}

View file

@ -50,13 +50,14 @@ typedef struct {
void save_current_core_context(void);
void restore_current_core_context(void);
bool is_core_active(uint32_t core);
void set_core_is_active(uint32_t core, bool is_active);
void set_current_core_active(void);
void set_current_core_inactive(void);
void use_core_entrypoint_and_argument(uint32_t core, uintptr_t *entrypoint_addr, uint64_t *argument);
void set_core_entrypoint_and_argument(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument);
void core_jump_to_lower_el(void);
void __attribute__((noreturn)) core_jump_to_lower_el(void);
uint32_t cpu_on(uint32_t core, uintptr_t entrypoint_addr, uint64_t argument);
uint32_t cpu_off(void);

View file

@ -14,6 +14,7 @@
#include "pmc.h"
#include "randomcache.h"
#include "timers.h"
#include "bootconfig.h"
extern void *__start_cold_addr;
extern size_t __bin_size;
@ -25,7 +26,7 @@ static void setup_se(void) {
/* Sanity check the Security Engine. */
se_verify_flags_cleared();
/* Initialize Interrupts. */
/* Initialize interrupts. */
intr_initialize_gic_nonsecure();
/* Perform some sanity initialization. */
@ -35,8 +36,6 @@ static void setup_se(void) {
p_security_engine->RSA_KEY_READ_DISABLE_REG = 0;
p_security_engine->_0x0 &= 0xFFFFFFFB;
/* Currently unknown what each flag does. */
for (unsigned int i = 0; i < KEYSLOT_AES_MAX; i++) {
set_aes_keyslot_flags(i, 0x15);
@ -342,23 +341,6 @@ static void sync_with_nx_bootloader(int state) {
}
}
static void identity_unmap_iram_cd_tzram(void) {
/* See also: configure_ttbls (in coldboot_init.c). */
uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
uintptr_t *mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
mmu_unmap_range(3, mmu_l3_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_IRAM_CD), IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_IRAM_CD));
mmu_unmap_range(3, mmu_l3_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_TZRAM), IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_TZRAM));
mmu_unmap(2, mmu_l2_tbl, 0x40000000);
mmu_unmap(2, mmu_l2_tbl, 0x7C000000);
mmu_unmap(1, mmu_l1_tbl, 0x40000000);
tlb_invalidate_all_inner_shareable();
}
static void indentity_unmap_dram(void) {
uintptr_t *mmu_l1_tbl = (uintptr_t *)(TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
@ -410,6 +392,9 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_LOADED_PACKAGE2);
}
/* Make PMC (2.x+), MC (4.x+) registers secure-only */
secure_additional_devices();
/* Remove the identity mapping for iRAM-C+D & TZRAM */
identity_unmap_iram_cd_tzram();
@ -449,18 +434,5 @@ void load_package2(coldboot_crt0_reloc_list_t *reloc_list) {
}
/* Update SCR_EL3 depending on value in Bootconfig. */
do {
uint64_t temp_scr_el3;
__asm__ __volatile__ ("mrs %0, scr_el3" : "=r"(temp_scr_el3) :: "memory");
temp_scr_el3 &= 0xFFFFFFF7;
if (bootconfig_should_set_scr_el3_bit()) {
temp_scr_el3 |= 8;
}
__asm__ __volatile__ ("msr scr_el3, %0" :: "r"(temp_scr_el3) : "memory");
__asm__ __volatile__("isb");
} while(false);
set_extabt_serror_taken_to_el3(bootconfig_take_extabt_serror_to_el3());
}

View file

@ -188,7 +188,7 @@ __jump_to_main_warm:
mov w0, #0 /* use core0,1,2 stack bottom + 0x800 (VA of warmboot crt0 sp) temporarily */
bl get_exception_entry_stack_address
add sp, x0, #0x800
b warmboot_main
bl warmboot_main
.section .text.__set_exception_entry_stack, "ax", %progbits
.type __set_exception_entry_stack, %function

View file

@ -21,6 +21,10 @@ static inline void __dmb_sy(void) {
__asm__ __volatile__ ("dmb sy" ::: "memory");
}
static inline void __isb(void) {
__asm__ __volatile__ ("isb" ::: "memory");
}
static inline void __sev(void) {
__asm__ __volatile__ ("sev");
}

View file

@ -20,8 +20,7 @@ uintptr_t get_warmboot_crt0_stack_address_critsec_enter(void) {
if (core_id) {
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x1000;
}
else {
} else {
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x80 * (core_id + 1);
}
}
@ -143,7 +142,8 @@ void warmboot_init(boot_func_list_t *func_list) {
func_list->funcs.flush_dcache_all();
func_list->funcs.invalidate_icache_all();
if(MC_SECURITY_CFG0_0 != 0) {
/* On warmboot (not cpu_on) only */
if (MC_SECURITY_CFG0_0 != 0) {
init_dma_controllers();
}

View file

@ -2,8 +2,57 @@
#include "mmu.h"
#include "memory_map.h"
#include "cpu_context.h"
#include "bootconfig.h"
#include "configitem.h"
#include "masterkey.h"
#include "bootup.h"
#include "smc_api.h"
void warmboot_main(void) {
/* TODO: lots of stuff */
#include "se.h"
#include "mc.h"
#include "interrupt.h"
void __attribute__((noreturn)) warmboot_main(void) {
/*
This function and its callers are reached in either of the following events, under normal conditions:
- warmboot (core 3)
- cpu_on
*/
if (is_core_active(get_core_id())) {
panic(0xF7F00007); /* invalid CPU context */
}
/* IRAM C+D identity mapping has actually been removed on coldboot but we don't really care */
identity_unmap_iram_cd_tzram();
/* On warmboot (not cpu_on) only */
if (MC_SECURITY_CFG0_0 != 0) {
if (!configitem_is_retail()) {
/* TODO: uart_log("OHAYO"); */
}
/* Sanity check the Security Engine. */
se_verify_flags_cleared();
/* Initialize interrupts. */
intr_initialize_gic_nonsecure();
bootup_misc_mmio();
/* Make PMC (2.x+), MC (4.x+) registers secure-only */
secure_additional_devices();
/* TODO: car+clkreset stuff, some other mmio (?) */
if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT) {
setup_4x_mmio(); /* TODO */
}
}
clear_priv_smc_in_progress();
setup_current_core_state();
/* Update SCR_EL3 depending on value in Bootconfig. */
set_extabt_serror_taken_to_el3(bootconfig_take_extabt_serror_to_el3());
core_jump_to_lower_el();
}