From 82f10b4320ebc3da87113ec4a27455b55492a1ad Mon Sep 17 00:00:00 2001 From: TuxSH Date: Thu, 1 Mar 2018 19:11:09 +0100 Subject: [PATCH] Implements missings parts of pk2ldr, refactor relocation a bit --- exosphere/linker.ld | 1 + exosphere/src/coldboot_init.c | 30 +++++++------- exosphere/src/interrupt.c | 2 +- exosphere/src/package2.c | 78 ++++++++++++++++++++++++----------- exosphere/src/start.s | 35 ++++++++++++++++ 5 files changed, 105 insertions(+), 41 deletions(-) diff --git a/exosphere/linker.ld b/exosphere/linker.ld index d22864ee7..dca89617d 100644 --- a/exosphere/linker.ld +++ b/exosphere/linker.ld @@ -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(.) ; diff --git a/exosphere/src/coldboot_init.c b/exosphere/src/coldboot_init.c index 5fc91316a..3cc8f4a23 100644 --- a/exosphere/src/coldboot_init.c +++ b/exosphere/src/coldboot_init.c @@ -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(); diff --git a/exosphere/src/interrupt.c b/exosphere/src/interrupt.c index 36265502d..e020cddd7 100644 --- a/exosphere/src/interrupt.c +++ b/exosphere/src/interrupt.c @@ -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; diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index 6b94250da..e0efad752 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -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. */ } diff --git a/exosphere/src/start.s b/exosphere/src/start.s index 0c9b0692f..f231f1dac 100644 --- a/exosphere/src/start.s +++ b/exosphere/src/start.s @@ -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