Implements missings parts of pk2ldr, refactor relocation a bit

This commit is contained in:
TuxSH 2018-03-01 19:11:09 +01:00
parent 568781bc7e
commit 82f10b4320
5 changed files with 105 additions and 41 deletions

View file

@ -214,6 +214,7 @@ SECTIONS
*(COMMON)
. = ALIGN(8);
__main_end__ = ABSOLUTE(.);
__end_lma__ = LOADADDR(.bss) + __main_end__ - __main_bss_start__;
} >main AT>fake
__end__ = ABSOLUTE(.) ;

View file

@ -6,10 +6,12 @@
extern const uint8_t __start_cold[];
extern const uint8_t __warmboot_crt0_start__[], __warmboot_crt0_end__[], __warmboot_crt0_lma__[];
extern const uint8_t __main_start__[], __main_bss_start__[], __main_end__[], __main_lma__[];
extern const uint8_t __pk2ldr_start__[], __pk2ldr_bss_start__[], __pk2ldr_end__[], __pk2ldr_lma__[];
extern const uint8_t __vectors_start__[], __vectors_end__[], __vectors_lma__[];
extern const uint8_t __warmboot_crt0_start__[], __warmboot_crt0_end__[];
extern const uint8_t __main_start__[], __main_bss_start__[], __main_end__[];
extern const uint8_t __pk2ldr_start__[], __pk2ldr_bss_start__[], __pk2ldr_end__[];
extern const uint8_t __vectors_start__[], __vectors_end__[];
extern const size_t __warmboot_crt0_offset, __main_offset, __pk2ldr_offset, __vectors_offset;
/* warmboot_init.c */
void set_memory_registers_enable_mmu(void);
@ -98,22 +100,22 @@ static void configure_ttbls(void) {
tzram_map_all_segments(mmu_l3_tbl);
}
__attribute__((noinline)) static void copy_lma_to_vma(const void *vma, const void *lma, size_t size) {
__attribute__((noinline)) static void copy_lma_to_vma(const void *vma, size_t offset, size_t size) {
uint64_t *p_vma = (uint64_t *)vma;
const uint64_t *p_lma = (const uint64_t *)((size_t)lma + __start_cold);
const uint64_t *p_lma = (const uint64_t *)(__start_cold + offset);
for (size_t i = 0; i < size / 8; i++) {
p_vma[i] = p_lma[i];
}
}
FAR_REACHING static void copy_warmboot_crt0(void) {
copy_lma_to_vma(__warmboot_crt0_start__, __warmboot_crt0_lma__, __warmboot_crt0_end__ - __warmboot_crt0_start__);
copy_lma_to_vma(__warmboot_crt0_start__, __warmboot_crt0_offset, __warmboot_crt0_end__ - __warmboot_crt0_start__);
}
FAR_REACHING static void copy_other_sections(void) {
copy_lma_to_vma(__main_start__, __main_lma__, __main_end__ - __main_start__);
copy_lma_to_vma(__pk2ldr_start__, __pk2ldr_lma__, __pk2ldr_end__ - __pk2ldr_start__);
copy_lma_to_vma(__vectors_start__, __vectors_lma__, __vectors_end__ - __vectors_start__);
copy_lma_to_vma(__main_start__, __main_offset, __main_end__ - __main_start__);
copy_lma_to_vma(__pk2ldr_start__, __pk2ldr_offset, __pk2ldr_end__ - __pk2ldr_start__);
copy_lma_to_vma(__vectors_start__, __vectors_offset, __vectors_end__ - __vectors_start__);
}
FAR_REACHING static void set_memory_registers_enable_mmu_tzram_pa(void) {
@ -128,10 +130,10 @@ FAR_REACHING static void flush_dcache_all_tzram_pa(void) {
((void (*)(void))v)();
}
FAR_REACHING static void invalidate_icache_all_inner_shareable_tzram_pa(void) {
FAR_REACHING static void invalidate_icache_all_tzram_pa(void) {
uintptr_t pa = TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN);
uintptr_t main_pa = pa | ((uintptr_t)__main_start__ & 0xFFF);
uintptr_t v = (uintptr_t)invalidate_icache_all_inner_shareable - (uintptr_t)__main_start__ + (uintptr_t)main_pa;
uintptr_t v = (uintptr_t)invalidate_icache_all - (uintptr_t)__main_start__ + (uintptr_t)main_pa;
((void (*)(void))v)();
}
@ -155,12 +157,10 @@ void coldboot_init(void) {
configure_ttbls();
set_memory_registers_enable_mmu_tzram_pa();
copy_other_sections();
flush_dcache_all_tzram_pa();
invalidate_icache_all_inner_shareable_tzram_pa();
invalidate_icache_all_tzram_pa();
/* At this point we can access all the mapped segments (all other functions, data...) normally */
clear_bss();

View file

@ -8,7 +8,7 @@
static struct {
unsigned int id;
void (*handler)(void);
} g_registered_interrupts[MAX_REGISTERED_INTERRUPTS] = { {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL} };
} g_registered_interrupts[MAX_REGISTERED_INTERRUPTS] = { {0} };
static unsigned int get_interrupt_id(void) {
return GICC_IAR;

View file

@ -14,6 +14,9 @@
#include "randomcache.h"
#include "timers.h"
extern void *__start_cold_addr;
extern size_t __bin_size;
/* Hardware init, sets up the RNG and SESSION keyslots, derives new DEVICE key. */
static void setup_se(void) {
uint8_t work_buffer[0x10];
@ -331,6 +334,38 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke
memset(load_buf, 0, PACKAGE2_SIZE_MAX);
}
static void sync_with_nx_bootloader(int state) {
if (MAILBOX_NX_BOOTLOADER_SETUP_STATE == state - 1) {
while (MAILBOX_NX_BOOTLOADER_SETUP_STATE < state) {
wait(1);
}
}
}
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_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
uintptr_t *mmu_l2_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_L2_TRANSLATION_TABLE);
uintptr_t *mmu_l3_tbl = (uintptr_t *)TZRAM_GET_SEGMENT_PA(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_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64);
mmu_unmap_range(1, mmu_l1_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_DRAM), IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_DRAM));
tlb_invalidate_all_inner_shareable();
}
uintptr_t get_pk2ldr_stack_address(void) {
return TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_PK2LDR) + 0x2000;
}
@ -350,12 +385,15 @@ void load_package2(void) {
/* Initialize the PMC secure scratch registers, initialize MISC registers, */
/* And assign "se_operation_completed" to Interrupt 0x5A. */
/* TODO: initalize cpu context */
/* TODO: Read and save BOOTREASON stored by NX_BOOTLOADER at 0x1F009FE00 */
/* Initialize cache'd random bytes for kernel. */
randomcache_init();
/* TODO: memclear the initial copy of Exosphere running in IRAM (relocated to TZRAM by earlier code). */
/* memclear the initial copy of Exosphere running in IRAM (relocated to TZRAM by earlier code). */
memset(__start_cold_addr, 0, __bin_size);
/* Let NX Bootloader know that we're running. */
MAILBOX_NX_BOOTLOADER_IS_SECMON_AWAKE = 1;
@ -363,23 +401,19 @@ void load_package2(void) {
/* Wait for 1 second, to allow time for NX_BOOTLOADER to draw to the screen. This is useful for debugging. */
wait(1000000);
/* Synchronize with NX BOOTLOADER. */
if (MAILBOX_NX_BOOTLOADER_SETUP_STATE == NX_BOOTLOADER_STATE_INIT) {
while (MAILBOX_NX_BOOTLOADER_SETUP_STATE < NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG) {
wait(1);
}
}
/* Synchronize with NX BOOTLOADER. */
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG);
/* Load Boot Config into global. */
setup_boot_config();
/* Synchronize with NX BOOTLOADER. */
if (MAILBOX_NX_BOOTLOADER_SETUP_STATE == NX_BOOTLOADER_STATE_MOVED_BOOTCONFIG) {
while (MAILBOX_NX_BOOTLOADER_SETUP_STATE < NX_BOOTLOADER_STATE_LOADED_PACKAGE2) {
wait(1);
}
}
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_LOADED_PACKAGE2);
/* Remove the identity mapping for iRAM-C+D and TZRAM */
identity_unmap_iram_cd_tzram();
/* Load header from NX_BOOTLOADER-initialized DRAM. */
package2_header_t header;
@ -387,35 +421,29 @@ void load_package2(void) {
memcpy(&header, NX_BOOTLOADER_PACKAGE2_LOAD_ADDRESS, sizeof(header));
flush_dcache_range((uint8_t *)&header, (uint8_t *)&header + sizeof(header));
/* Perform signature checks. */
verify_header_signature(&header);
/* Decrypt header, get key revision required. */
uint32_t package2_mkey_rev = decrypt_and_validate_header(&header);
/* Load Package2 Sections. */
load_package2_sections(&header.metadata, package2_mkey_rev);
/* Clean up cache. */
flush_dcache_all();
invalidate_icache_all_inner_shareable();
invalidate_icache_all(); /* non-broadcasting */
/* Set CORE0 entrypoint for Package2. */
set_core_entrypoint_and_argument(0, DRAM_BASE_PHYSICAL + header.metadata.entrypoint, 0);
/* Synchronize with NX BOOTLOADER. */
if (MAILBOX_NX_BOOTLOADER_SETUP_STATE == NX_BOOTLOADER_STATE_LOADED_PACKAGE2) {
while (MAILBOX_NX_BOOTLOADER_SETUP_STATE < NX_BOOTLOADER_STATE_FINISHED) {
wait(1);
}
}
/* Remove the DRAM identity mapping. */
indentity_unmap_dram();
/* TODO: MISC register 0x1F0098C00 |= 0x2000; */
/* Synchronize with NX BOOTLOADER. */
sync_with_nx_bootloader(NX_BOOTLOADER_STATE_FINISHED);
/* TODO: lots of boring MMIO */
/* TODO: Update SCR_EL3 depending on value in Bootconfig. */
}

View file

@ -81,6 +81,11 @@ __start_cold:
mov sp, x0
mov fp, #0
bl coldboot_init
adr x0, __start_cold
ldr x1, =__start_cold_addr
str x0, [x1]
ldr x16, =__jump_to_main_cold
br x16
@ -196,3 +201,33 @@ __jump_to_lower_el:
isb
eret
.align 3
.section .cold_start.rodata.reloc_constants, "a", %progbits
.global __warmboot_crt0_offset
__warmboot_crt0_offset:
.quad __warmboot_crt0_lma__
.global __main_offset
__main_offset:
.quad __main_lma__
.global __pk2ldr_offset
__pk2ldr_offset:
.quad __pk2ldr_lma__
.global __vectors_offset
__vectors_offset:
.quad __vectors_lma__
.align 3
.section .rodata.__bin_size, "a", %progbits
.global __bin_size
__bin_size:
.quad __end_lma__
.align 3
.section .bss.__start_cold_addr, "w", %nobits
.global __start_cold_addr
__start_cold_addr:
.space 8