diff --git a/exosphere/src/coldboot_init.c b/exosphere/src/coldboot_init.c index 766639814..ead503f73 100644 --- a/exosphere/src/coldboot_init.c +++ b/exosphere/src/coldboot_init.c @@ -9,10 +9,10 @@ extern const uint8_t __main_start__[], __main_end__[], __main_lma__[]; extern const uint8_t __pk2ldr_start__[], __pk2ldr_end__[], __pk2ldr_lma__[]; extern const uint8_t __vectors_start__[], __vectors_end__[], __vectors_lma__[]; -extern void flush_dcache_all_tzram_pa(void); -extern void invalidate_icache_all_tzram_pa(void); - -uintptr_t get_coldboot_crt0_stack_address(void); +/* warmboot_init.c */ +void set_memory_registers_enable_mmu(void); +void flush_dcache_all_tzram_pa(void); +void invalidate_icache_all_tzram_pa(void); static void identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) { static const uintptr_t addrs[] = { TUPLE_FOLD_LEFT_0(EVAL(IDENTIY_MAPPING_ID_MAX), _MMAPID, COMMA) }; @@ -123,16 +123,15 @@ __attribute__((target("cmodel=large"), noinline)) static void copy_other_section void coldboot_init(void) { /* TODO: Set NX BOOTLOADER clock time field */ copy_warmboot_crt0(); - /* TODO: set some mmio regs, etc. */ - /* TODO: initialize DMA controllers */ + /* At this point, we can (and will) access functions located in .warm_crt0 */ + /* TODO: initialize DMA controllers, etc. */ configure_ttbls(); copy_other_sections(); - - /* TODO: set the MMU regs & tlbi & enable MMU */ + set_memory_registers_enable_mmu(); flush_dcache_all_tzram_pa(); invalidate_icache_all_tzram_pa(); - /* At this point we can access the mapped segments */ + /* At this point we can access all the mapped segments */ /* TODO: zero-initialize the cpu context */ - /* Nintendo clears the (emtpy) pk2ldr's BSS section, but we embed it 0-filled in the binary */ + /* Nintendo clears the (emtpy) pk2ldr's BSS section here , but we embed it 0-filled in the binary */ } diff --git a/exosphere/src/coldboot_main.c b/exosphere/src/coldboot_main.c index 9efec95f8..57e0edf02 100644 --- a/exosphere/src/coldboot_main.c +++ b/exosphere/src/coldboot_main.c @@ -5,9 +5,9 @@ #include "arm.h" extern uint8_t __pk2ldr_start__[], __pk2ldr_end__[]; -extern void __jump_to_lower_el(uint64_t arg, uintptr_t ep, unsigned int el); -void coldboot_main(void); +/* start.s */ +void __jump_to_lower_el(uint64_t arg, uintptr_t ep, unsigned int el); void coldboot_main(void) { uintptr_t *mmu_l3_table = (uintptr_t *)TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE); diff --git a/exosphere/src/memory_map.h b/exosphere/src/memory_map.h index edf26c8c4..dbc7287d3 100644 --- a/exosphere/src/memory_map.h +++ b/exosphere/src/memory_map.h @@ -4,8 +4,8 @@ #include "mmu.h" #include "preprocessor.h" -#define ATTRIB_MEMTYPE_NORMAL MMU_PTE_BLOCK_MEMTYPE(0) -#define ATTRIB_MEMTYPE_DEVICE MMU_PTE_BLOCK_MEMTYPE(1) +#define ATTRIB_MEMTYPE_NORMAL MMU_PTE_BLOCK_MEMTYPE(MMU_MT_NORMAL) +#define ATTRIB_MEMTYPE_DEVICE MMU_PTE_BLOCK_MEMTYPE(MMU_MT_DEVICE_NGNRE) /* Identity mappings (addr, size, additional attributes, is block range) */ #define _MMAPID0 ( 0x40020000ull, 0x20000ull, 0ull, false ) /* iRAM-C+D (contains the secmon's coldboot crt0) */ diff --git a/exosphere/src/mmu.h b/exosphere/src/mmu.h index c493263aa..5c32dcbc2 100644 --- a/exosphere/src/mmu.h +++ b/exosphere/src/mmu.h @@ -32,11 +32,10 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#define MMU_MT_DEVICE_NGNRNE 0ull +/* Memory attributes, see set_memory_registers_enable_mmu */ +#define MMU_MT_NORMAL 0ull #define MMU_MT_DEVICE_NGNRE 1ull -#define MMU_MT_DEVICE_GRE 2ull -#define MMU_MT_NORMAL_NC 3ull -#define MMU_MT_NORMAL 4ull +#define MMU_MT_DEVICE_NGNRNE 2ull /* not used, also the same as Attr4-7 */ /* * Hardware page table definitions. @@ -112,6 +111,7 @@ #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) +#define TCR_PS(x) ((x) << 16) #define TCR_EPD1_DISABLE BIT(23) #define TCR_EL1_RSVD BIT(31) diff --git a/exosphere/src/warmboot_init.c b/exosphere/src/warmboot_init.c index 7e5ab7f0e..d3ebf93ef 100644 --- a/exosphere/src/warmboot_init.c +++ b/exosphere/src/warmboot_init.c @@ -1,12 +1,10 @@ #include "utils.h" #include "memory_map.h" +/* start.s */ void __set_memory_registers(uintptr_t ttbr0, uintptr_t vbar, uint64_t cpuectlr, uint32_t scr, uint32_t tcr, uint32_t cptr, uint64_t mair, uint32_t sctlr); -uintptr_t get_warmboot_crt0_stack_address(void); -void set_memory_registers(void); - void flush_dcache_all_tzram_pa(void) { /* TODO */ } @@ -19,6 +17,59 @@ uintptr_t get_warmboot_crt0_stack_address(void) { return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE012_STACK) + 0x800; } +void set_memory_registers_enable_mmu(void) { + static const uintptr_t vbar = TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800; + static const uintptr_t ttbr0 = vbar - 64; + + /* + - Disable table walk descriptor access prefetch. + - L2 instruction fetch prefetch distance = 3 (reset value) + - L2 load/store data prefetch distance = 8 (reset value) + - Enable the processor to receive instruction cache and TLB maintenance operations broadcast from other processors in the cluster + */ + static const uint64_t cpuectlr = 0x1B00000040ull; + + /* + - The next lower level is Aarch64 + - Secure instruction fetch (when the PE is in Secure state, this bit disables instruction fetch from Non-secure memory) + - External Abort/SError taken to EL3 + - FIQ taken to EL3 + - NS (EL0 and EL1 are nonsecure) + */ + static const uint32_t scr = 0x63D; + + /* + - PA size: 36-bit (64 GB) + - Granule size: 4KB + - Shareability attribute for memory associated with translation table walks using TTBR0_EL3: Inner Shareable + - Outer cacheability attribute for memory associated with translation table walks using TTBR0_EL3: Normal memory, Outer Write-Back Read-Allocate Write-Allocate Cacheable + - Inner cacheability attribute for memory associated with translation table walks using TTBR0_EL3: Normal memory, Inner Write-Back Read-Allocate Write-Allocate Cacheable + - T0SZ = 31 (33-bit address space) + */ + static const uint32_t tcr = TCR_EL3_RSVD | TCR_PS(1) | TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA | TCR_T0SZ(33); + + /* Nothing trapped */ + static const uint32_t cptr = 0; + + /* + - Attribute 0: Normal memory, Inner and Outer Write-Back Read-Allocate Write-Allocate Non-transient + - Attribute 1: Device-nGnRE memory + - Other attributes: Device-nGnRnE memory + */ + static const uint64_t mair = 0x4FFull; + + /* + - Cacheability control, for EL3 instruction accesses DISABLED + (- SP Alignment check bit NOT SET) + - Cacheability control, for EL3 data accesses DISABLED (normal memory accesses from EL3 are cacheable) + (- Alignement check bit NOT SET) + - MMU enabled for EL3 stage 1 address translation + */ + static const uint32_t sctlr = 0x30C51835ull; + + __set_memory_registers(ttbr0, vbar, cpuectlr, scr, tcr, cptr, mair, sctlr); +} + void warmboot_init(void) { /* TODO: Implement. */ } diff --git a/exosphere/src/warmboot_main.c b/exosphere/src/warmboot_main.c index 486bfa42a..8442f6065 100644 --- a/exosphere/src/warmboot_main.c +++ b/exosphere/src/warmboot_main.c @@ -2,9 +2,8 @@ #include "mmu.h" #include "memory_map.h" -extern void __jump_to_lower_el(uint64_t arg, uintptr_t ep, unsigned int el); - -void warmboot_main(void); +/* start.s */ +void __jump_to_lower_el(uint64_t arg, uintptr_t ep, unsigned int el); void warmboot_main(void) { /* TODO */