mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-09 22:56:35 +00:00
Implements missings parts of pk2ldr, refactor relocation a bit
This commit is contained in:
parent
568781bc7e
commit
82f10b4320
5 changed files with 105 additions and 41 deletions
|
@ -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(.) ;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue