mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Finish writing warmboot _crt0_
This commit is contained in:
parent
48e8d9c7de
commit
be6b67669f
4 changed files with 85 additions and 41 deletions
|
@ -122,39 +122,6 @@ uintptr_t get_coldboot_crt0_stack_address(void) {
|
||||||
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
|
return TZRAM_GET_SEGMENT_PA(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
|
||||||
}
|
}
|
||||||
|
|
||||||
void coldboot_init_dma_controllers(void) {
|
|
||||||
/* SYSCTR0_CNTCR_0 = ENABLE | HALT_ON_DEBUG (write-once init) */
|
|
||||||
(*((volatile uint32_t *)(0x700F0000))) = 3;
|
|
||||||
|
|
||||||
/* Set some unknown registers in HOST1X. */
|
|
||||||
(*((volatile uint32_t *)(0x500038F8))) &= 0xFFFFFFFE;
|
|
||||||
(*((volatile uint32_t *)(0x50003300))) = 0;
|
|
||||||
|
|
||||||
/* AHB_MASTER_SWID_0 */
|
|
||||||
(*((volatile uint32_t *)(0x6000C018))) = 0;
|
|
||||||
|
|
||||||
/* AHB_MASTER_SWID_1 - Makes USB1/USB2 use SWID[1] */
|
|
||||||
(*((volatile uint32_t *)(0x6000C038))) = 0x40040;
|
|
||||||
|
|
||||||
/* APBDMA_CHANNEL_SWID_0 = ~0 (SWID = 1 for all APB-DMA channels) */
|
|
||||||
(*((volatile uint32_t *)(0x6002003C))) = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
/* APBDMA_CHANNEL_SWID1_0 = 0 (See above) */
|
|
||||||
(*((volatile uint32_t *)(0x60020054))) = 0;
|
|
||||||
|
|
||||||
/* APBDMA_SECURITY_REG_0 = 0 (All APB-DMA channels non-secure) */
|
|
||||||
(*((volatile uint32_t *)(0x60020038))) = 0;
|
|
||||||
|
|
||||||
/* MSELECT_CONFIG_0 |= WRAP_TO_INCR_SLAVE0(APC) | WRAP_TO_INCR_SLAVE1(PCIe) | WRAP_TO_INCR_SLAVE2(GPU) */
|
|
||||||
(*((volatile uint32_t *)(0x50060000))) |= 0x38000000;
|
|
||||||
|
|
||||||
/* AHB_ARBITRATION_PRIORITY_CTRL_0 - Select high prio group with prio 7 */
|
|
||||||
(*((volatile uint32_t *)(0x6000C008))) = 0xE0000001;
|
|
||||||
|
|
||||||
/* AHB_GIZMO_TZRAM_0 |= DONT_SPLIT_AHB_WR */
|
|
||||||
(*((volatile uint32_t *)(0x6000C054))) = 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, boot_func_list_t *func_list, boot_func_list_t *func_list_warmboot) {
|
void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, boot_func_list_t *func_list, boot_func_list_t *func_list_warmboot) {
|
||||||
/* Custom approach */
|
/* Custom approach */
|
||||||
reloc_list->reloc_base = (uintptr_t)__start_cold;
|
reloc_list->reloc_base = (uintptr_t)__start_cold;
|
||||||
|
@ -168,8 +135,16 @@ void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, boot_func_list_t *fun
|
||||||
/* At this point, we can (and will) access functions located in .warm_crt0 */
|
/* At this point, we can (and will) access functions located in .warm_crt0 */
|
||||||
translate_warmboot_func_list(reloc_list, func_list);
|
translate_warmboot_func_list(reloc_list, func_list);
|
||||||
|
|
||||||
/* TODO: 4.x does slightly different init. How should we handle this? We can't detect master key revision yet. */
|
/*
|
||||||
coldboot_init_dma_controllers();
|
From https://events.static.linuxfound.org/sites/events/files/slides/slides_17.pdf :
|
||||||
|
Caches may write back dirty lines at any time:
|
||||||
|
- To make space for new allocations
|
||||||
|
- Even if MMU is off
|
||||||
|
- Even if Cacheable accesses are disabled (caches are never 'off')
|
||||||
|
*/
|
||||||
|
func_list->funcs.flush_dcache_all();
|
||||||
|
func_list->funcs.invalidate_icache_all();
|
||||||
|
func_list->funcs.init_dma_controllers();
|
||||||
|
|
||||||
configure_ttbls();
|
configure_ttbls();
|
||||||
func_list->funcs.set_memory_registers_enable_mmu();
|
func_list->funcs.set_memory_registers_enable_mmu();
|
||||||
|
@ -179,7 +154,6 @@ void coldboot_init(coldboot_crt0_reloc_list_t *reloc_list, boot_func_list_t *fun
|
||||||
do_relocation(reloc_list, reloc_list->nb_relocs_pre_mmu_init + i);
|
do_relocation(reloc_list, reloc_list->nb_relocs_pre_mmu_init + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func_list->funcs.flush_dcache_all();
|
func_list->funcs.flush_dcache_all();
|
||||||
func_list->funcs.invalidate_icache_all();
|
func_list->funcs.invalidate_icache_all();
|
||||||
/* At this point we can access all the mapped segments (all other functions, data...) normally */
|
/* At this point we can access all the mapped segments (all other functions, data...) normally */
|
||||||
|
|
|
@ -242,8 +242,9 @@ g_coldboot_crt0_relocation_list:
|
||||||
.align 3
|
.align 3
|
||||||
.global g_coldboot_crt0_main_func_list
|
.global g_coldboot_crt0_main_func_list
|
||||||
g_coldboot_crt0_main_func_list:
|
g_coldboot_crt0_main_func_list:
|
||||||
.quad 3 /* Number of functions */
|
.quad 4 /* Number of functions */
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
.quad init_dma_controllers
|
||||||
.quad set_memory_registers_enable_mmu
|
.quad set_memory_registers_enable_mmu
|
||||||
.quad flush_dcache_all
|
.quad flush_dcache_all
|
||||||
.quad invalidate_icache_all
|
.quad invalidate_icache_all
|
||||||
|
|
|
@ -24,11 +24,12 @@ typedef struct {
|
||||||
size_t nb_funcs;
|
size_t nb_funcs;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
void (*init_dma_controllers)(void);
|
||||||
void (*set_memory_registers_enable_mmu)(void);
|
void (*set_memory_registers_enable_mmu)(void);
|
||||||
void (*flush_dcache_all)(void);
|
void (*flush_dcache_all)(void);
|
||||||
void (*invalidate_icache_all)(void);
|
void (*invalidate_icache_all)(void);
|
||||||
} funcs;
|
} funcs;
|
||||||
uintptr_t addrs[3];
|
uintptr_t addrs[4];
|
||||||
};
|
};
|
||||||
} boot_func_list_t;
|
} boot_func_list_t;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "memory_map.h"
|
#include "memory_map.h"
|
||||||
|
#include "mc.h"
|
||||||
#include "arm.h"
|
#include "arm.h"
|
||||||
|
|
||||||
#include "synchronization.h"
|
#include "synchronization.h"
|
||||||
|
|
||||||
|
#undef MC_BASE
|
||||||
|
#define MC_BASE (MMIO_GET_DEVICE_PA(MMIO_DEVID_MC))
|
||||||
|
|
||||||
/* start.s */
|
/* start.s */
|
||||||
void __set_memory_registers(uintptr_t ttbr0, uintptr_t vbar, uint64_t cpuectlr, uint32_t scr,
|
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);
|
uint32_t tcr, uint32_t cptr, uint64_t mair, uint32_t sctlr);
|
||||||
|
@ -27,6 +30,41 @@ void warmboot_crt0_critical_section_enter(volatile critical_section_t *critical_
|
||||||
critical_section_enter(critical_section);
|
critical_section_enter(critical_section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_dma_controllers(void) {
|
||||||
|
/* TODO: 4.x does slightly different init. How should we handle this? We can't detect master key revision yet. */
|
||||||
|
|
||||||
|
/* SYSCTR0_CNTCR_0 = ENABLE | HALT_ON_DEBUG (write-once init) */
|
||||||
|
(*((volatile uint32_t *)(0x700F0000))) = 3;
|
||||||
|
|
||||||
|
/* Set some unknown registers in HOST1X. */
|
||||||
|
(*((volatile uint32_t *)(0x500038F8))) &= 0xFFFFFFFE;
|
||||||
|
(*((volatile uint32_t *)(0x50003300))) = 0;
|
||||||
|
|
||||||
|
/* AHB_MASTER_SWID_0 */
|
||||||
|
(*((volatile uint32_t *)(0x6000C018))) = 0;
|
||||||
|
|
||||||
|
/* AHB_MASTER_SWID_1 - Makes USB1/USB2 use SWID[1] */
|
||||||
|
(*((volatile uint32_t *)(0x6000C038))) = 0x40040;
|
||||||
|
|
||||||
|
/* APBDMA_CHANNEL_SWID_0 = ~0 (SWID = 1 for all APB-DMA channels) */
|
||||||
|
(*((volatile uint32_t *)(0x6002003C))) = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
/* APBDMA_CHANNEL_SWID1_0 = 0 (See above) */
|
||||||
|
(*((volatile uint32_t *)(0x60020054))) = 0;
|
||||||
|
|
||||||
|
/* APBDMA_SECURITY_REG_0 = 0 (All APB-DMA channels non-secure) */
|
||||||
|
(*((volatile uint32_t *)(0x60020038))) = 0;
|
||||||
|
|
||||||
|
/* MSELECT_CONFIG_0 |= WRAP_TO_INCR_SLAVE0(APC) | WRAP_TO_INCR_SLAVE1(PCIe) | WRAP_TO_INCR_SLAVE2(GPU) */
|
||||||
|
(*((volatile uint32_t *)(0x50060000))) |= 0x38000000;
|
||||||
|
|
||||||
|
/* AHB_ARBITRATION_PRIORITY_CTRL_0 - Select high prio group with prio 7 */
|
||||||
|
(*((volatile uint32_t *)(0x6000C008))) = 0xE0000001;
|
||||||
|
|
||||||
|
/* AHB_GIZMO_TZRAM_0 |= DONT_SPLIT_AHB_WR */
|
||||||
|
(*((volatile uint32_t *)(0x6000C054))) = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
void set_memory_registers_enable_mmu(void) {
|
void set_memory_registers_enable_mmu(void) {
|
||||||
static const uintptr_t vbar = TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800;
|
static const uintptr_t vbar = TZRAM_GET_SEGMENT_ADDRESS(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800;
|
||||||
static const uintptr_t ttbr0 = TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64;
|
static const uintptr_t ttbr0 = TZRAM_GET_SEGMENT_PA(TZRAM_SEGEMENT_ID_SECMON_EVT) + 0x800 - 64;
|
||||||
|
@ -80,6 +118,36 @@ void set_memory_registers_enable_mmu(void) {
|
||||||
__set_memory_registers(ttbr0, vbar, cpuectlr, scr, tcr, cptr, mair, sctlr);
|
__set_memory_registers(ttbr0, vbar, cpuectlr, scr, tcr, cptr, mair, sctlr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void warmboot_init(boot_func_list_t *func_list) {
|
static void identity_remap_tzram(void) {
|
||||||
(void)func_list;
|
/* 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_map_table(1, mmu_l1_tbl, 0x40000000, mmu_l2_tbl, 0);
|
||||||
|
mmu_map_table(2, mmu_l2_tbl, 0x7C000000, mmu_l3_tbl, 0);
|
||||||
|
|
||||||
|
identity_map_mapping(mmu_l1_tbl, mmu_l3_tbl, IDENTITY_GET_MAPPING_ADDRESS(IDENTITY_MAPPING_TZRAM),
|
||||||
|
IDENTITY_GET_MAPPING_SIZE(IDENTITY_MAPPING_TZRAM), IDENTITY_GET_MAPPING_ATTRIBS(IDENTITY_MAPPING_TZRAM),
|
||||||
|
IDENTITY_IS_MAPPING_BLOCK_RANGE(IDENTITY_MAPPING_TZRAM));
|
||||||
|
}
|
||||||
|
|
||||||
|
void warmboot_init(boot_func_list_t *func_list) {
|
||||||
|
/*
|
||||||
|
From https://events.static.linuxfound.org/sites/events/files/slides/slides_17.pdf :
|
||||||
|
Caches may write back dirty lines at any time:
|
||||||
|
- To make space for new allocations
|
||||||
|
- Even if MMU is off
|
||||||
|
- Even if Cacheable accesses are disabled (caches are never 'off')
|
||||||
|
*/
|
||||||
|
func_list->funcs.flush_dcache_all();
|
||||||
|
func_list->funcs.invalidate_icache_all();
|
||||||
|
|
||||||
|
if(MC_SECURITY_CFG0_0 != 0) {
|
||||||
|
init_dma_controllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
identity_remap_tzram();
|
||||||
|
/* Nintendo pointlessly fully invalidate the TLB & invalidate the data cache on the modified ranges here */
|
||||||
|
set_memory_registers_enable_mmu();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue