- refactored arm11/sys.c

- moved common.h from the ARM9 tree to the common code tree
- does proper deinit now on the ARM11 side

the bug that caused it to fail to launch some FIRMs has been fixed - it can even boot stock FIRMs
This commit is contained in:
Wolfvak 2019-04-16 15:42:20 -03:00 committed by d0k3
parent 016eac6982
commit 5e56cd2f77
8 changed files with 163 additions and 157 deletions

View File

@ -1,4 +1,6 @@
#include <types.h> #include <types.h>
#include <common.h>
#include <arm.h> #include <arm.h>
#include "arm/mmu.h" #include "arm/mmu.h"
@ -68,44 +70,26 @@ static MMU_Lvl2_Table *Alloc_Lvl2(void)
/* functions to convert from internal page flag format to ARM */ /* functions to convert from internal page flag format to ARM */
/* {TEX, CB} */
static const u8 MMU_TypeLUT[MEMORY_TYPES][2] = {
[STRONGLY_ORDERED] = {0, 0},
[NON_CACHEABLE] = {1, 0},
[DEVICE_SHARED] = {0, 1},
[DEVICE_NONSHARED] = {2, 0},
[CACHED_WT] = {0, 2},
[CACHED_WB] = {1, 3},
[CACHED_WB_ALLOC] = {1, 3},
};
static u32 MMU_GetTEX(u32 f) static u32 MMU_GetTEX(u32 f)
{ {
switch(MMU_FLAGS_TYPE(f)) { return MMU_TypeLUT[MMU_FLAGS_TYPE(f)][0];
default:
case STRONGLY_ORDERED:
case CACHED_WT:
case DEVICE_SHARED:
return 0;
case CACHED_WB:
case NON_CACHEABLE:
case CACHED_WB_ALLOC:
return 1;
case DEVICE_NONSHARED:
return 2;
}
} }
static u32 MMU_GetCB(u32 f) static u32 MMU_GetCB(u32 f)
{ {
switch(MMU_FLAGS_TYPE(f)) { return MMU_TypeLUT[MMU_FLAGS_TYPE(f)][1];
default:
case STRONGLY_ORDERED:
case NON_CACHEABLE:
case DEVICE_NONSHARED:
return 0;
case DEVICE_SHARED:
return 1;
case CACHED_WT:
return 2;
case CACHED_WB:
case CACHED_WB_ALLOC:
return 3;
}
} }
static u32 MMU_GetAP(u32 f) static u32 MMU_GetAP(u32 f)
@ -114,10 +98,8 @@ static u32 MMU_GetAP(u32 f)
default: default:
case NO_ACCESS: case NO_ACCESS:
return 0; return 0;
case READ_ONLY: case READ_ONLY:
return 0x21; return 0x21;
case READ_WRITE: case READ_WRITE:
return 0x01; return 0x01;
} }
@ -281,11 +263,10 @@ u32 MMU_Map(u32 va, u32 pa, u32 size, u32 flags)
.mapfn = MMU_MapPage, .mapfn = MMU_MapPage,
}, },
}; };
static const size_t VMapperCount = sizeof(VMappers)/sizeof(*VMappers);
while(size > 0) { while(size > 0) {
size_t i = 0; size_t i = 0;
for (i = 0; i < VMapperCount; i++) { for (i = 0; i < countof(VMappers); i++) {
u32 abits = VMappers[i].bits; u32 abits = VMappers[i].bits;
if (MMU_MappingFits(va, pa, size, abits)) { if (MMU_MappingFits(va, pa, size, abits)) {
@ -303,7 +284,7 @@ u32 MMU_Map(u32 va, u32 pa, u32 size, u32 flags)
} }
} }
if (i == VMapperCount) if (i == countof(VMappers))
return size; return size;
} }

View File

@ -10,6 +10,7 @@ enum MMU_MemoryType {
CACHED_WT, CACHED_WT,
CACHED_WB, CACHED_WB,
CACHED_WB_ALLOC, CACHED_WB_ALLOC,
MEMORY_TYPES,
}; };
enum MMU_MemoryAccess { enum MMU_MemoryAccess {

View File

@ -45,20 +45,24 @@ __boot:
b 1b b 1b
corezero_start: corezero_start:
@ assume __bss_len is 16 byte aligned
ldr r0, =__bss_pa ldr r0, =__bss_pa
ldr r1, =__bss_len ldr r1, =__bss_len
mov r2, #0 mov r2, #0
mov r3, #0
mov r4, #0
mov r5, #0
add r1, r0, r1 add r1, r0, r1
.Lclearbss: .Lclearbss:
cmp r0, r1 cmp r0, r1
strlt r2, [r0], #4 stmltia r0!, {r2-r5}
blt .Lclearbss blt .Lclearbss
bl SYS_CoreZeroInit
coresmp_start: coresmp_start:
bl SYS_CoreInit bl SYS_CoreInit
bl MPCoreMain b MainLoop
b __boot
.section .bss.stack .section .bss.stack
.align 3 .align 3

View File

@ -8,8 +8,9 @@
#include "hw/i2c.h" #include "hw/i2c.h"
#include "hw/mcu.h" #include "hw/mcu.h"
static bool legacy; #include "system/sys.h"
void SYS_CoreShutdown(void);
static bool legacy = false;
void PXI_RX_Handler(u32 __attribute__((unused)) irqn) void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
{ {
@ -98,21 +99,18 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
return; return;
} }
void MPCoreMain(void) void MainLoop(void)
{ {
legacy = false;
GIC_Enable(IRQ_PXI_RX, BIT(0), GIC_HIGHEST_PRIO, PXI_RX_Handler); GIC_Enable(IRQ_PXI_RX, BIT(0), GIC_HIGHEST_PRIO, PXI_RX_Handler);
// ARM9 won't try anything funny until this point
PXI_Barrier(ARM11_READY_BARRIER); PXI_Barrier(ARM11_READY_BARRIER);
ARM_EnableInterrupts();
// Process IRQs until the ARM9 tells us it's time to boot something else // Process IRQs until the ARM9 tells us it's time to boot something else
do { do {
ARM_WFI(); ARM_WFI();
} while(!legacy); } while(!legacy);
// Perform any needed deinit stuff SYS_CoreZeroShutdown();
ARM_DisableInterrupts();
SYS_CoreShutdown(); SYS_CoreShutdown();
} }

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <types.h>
#define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_len; static const u32 n##_pa = (u32)&__##n##_pa, n##_va = (u32)&__##n##_va; #define DEF_SECT_(n) extern u32 __##n##_pa, __##n##_va, __##n##_len; static const u32 n##_pa = (u32)&__##n##_pa, n##_va = (u32)&__##n##_va;
DEF_SECT_(vector) DEF_SECT_(vector)
DEF_SECT_(text) DEF_SECT_(text)

View File

@ -8,14 +8,13 @@
#include "hw/i2c.h" #include "hw/i2c.h"
#include "system/sections.h"
#define CFG11_MPCORE_CLKCNT ((vu16*)(0x10141300)) #define CFG11_MPCORE_CLKCNT ((vu16*)(0x10141300))
#define CFG11_SOCINFO ((vu16*)(0x10140FFC)) #define CFG11_SOCINFO ((vu16*)(0x10140FFC))
#define LEGACY_BOOT_ENTRY ((vu32*)0x1FFFFFFC) #define LEGACY_BOOT_ENTRYPOINT ((vu32*)0x1FFFFFFC)
#define LEGACY_BOOT_ROUTINE_SMP (0x0001004C)
#define INIT_DONE (0xDDEEFFAA)
static volatile u32 sys_init_state = 0;
static bool SYS_IsNewConsole(void) static bool SYS_IsNewConsole(void)
{ {
@ -45,16 +44,11 @@ static void SYS_EnableClkMult(void)
} }
} }
#include "sections.h" void SYS_CoreZeroInit(void)
#define MMU_FLAGS_DEF MMU_FLAGS(STRONGLY_ORDERED, READ_WRITE, 0, 1)
static void SYS_CoreZeroInit(void)
{ {
GIC_GlobalReset(); GIC_GlobalReset();
GIC_LocalReset();
*LEGACY_BOOT_ENTRY = 0; *LEGACY_BOOT_ENTRYPOINT = 0;
SYS_EnableClkMult(); SYS_EnableClkMult();
@ -77,11 +71,13 @@ static void SYS_CoreZeroInit(void)
MMU_Map(0x18000000, 0x18000000, 6UL << 20, MMU_FLAGS(CACHED_WT, READ_WRITE, 1, 1)); MMU_Map(0x18000000, 0x18000000, 6UL << 20, MMU_FLAGS(CACHED_WT, READ_WRITE, 1, 1));
// FCRAM // FCRAM
MMU_Map(0x20000000, 0x20000000, 128UL << 20, MMU_FLAGS(CACHED_WB, READ_WRITE, 1, 1)); if (SYS_IsNewConsole()) {
} MMU_Map(0x20000000, 0x20000000, 256UL << 20, MMU_FLAGS(CACHED_WB, READ_WRITE, 1, 1));
} else {
MMU_Map(0x20000000, 0x20000000, 128UL << 20, MMU_FLAGS(CACHED_WB, READ_WRITE, 1, 1));
}
static void SYS_InitPeripherals(void) // Initialize peripherals
{
PXI_Reset(); PXI_Reset();
I2C_init(); I2C_init();
//MCU_init(); //MCU_init();
@ -89,19 +85,13 @@ static void SYS_InitPeripherals(void)
void SYS_CoreInit(void) void SYS_CoreInit(void)
{ {
if (!ARM_CoreID()) { // Reset local GIC registers
SYS_CoreZeroInit(); GIC_LocalReset();
} else {
while(sys_init_state != INIT_DONE)
ARM_WFE();
GIC_LocalReset(); // Set up MMU registers
}
// set up MMU registers
MMU_Init(); MMU_Init();
// enable fancy ARM11 stuff // Enable fancy ARM11 features
ARM_SetACR(ARM_GetACR() | ARM_SetACR(ARM_GetACR() |
ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP); ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP);
@ -110,32 +100,20 @@ void SYS_CoreInit(void)
ARM_DSB(); ARM_DSB();
if (!ARM_CoreID()) { ARM_EnableInterrupts();
SYS_InitPeripherals(); }
sys_init_state = INIT_DONE; void SYS_CoreZeroShutdown(void)
ARM_DSB(); {
ARM_SEV(); ARM_DisableInterrupts();
} GIC_GlobalReset();
} }
// assumes all cores have been initialized
void SYS_CoreShutdown(void) void SYS_CoreShutdown(void)
{ {
u32 core = ARM_CoreID(); u32 core = ARM_CoreID();
if (!core) { ARM_DisableInterrupts();
// wait for the other cores to do their thing
while(sys_init_state != (INIT_DONE - MAX_CPU + 1)) {
ARM_WFE();
ARM_DSB();
}
GIC_GlobalReset();
} else {
__atomic_sub_fetch(&sys_init_state, 1, __ATOMIC_SEQ_CST);
ARM_SEV();
}
GIC_LocalReset(); GIC_LocalReset();
@ -148,11 +126,11 @@ void SYS_CoreShutdown(void)
~(ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP)); ~(ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP));
if (!core) { if (!core) {
while(*LEGACY_BOOT_ENTRY == 0); while(*LEGACY_BOOT_ENTRYPOINT == 0);
((void (*)(void))(*LEGACY_BOOT_ENTRY))(); ((void (*)(void))(*LEGACY_BOOT_ENTRYPOINT))();
} else { } else {
// Branch to bootrom function that does SMP reinit magic // Branch to bootrom function that does SMP reinit magic
// (waits for IPI + branches to word @ 0x1FFFFFDC) // (waits for IPI + branches to word @ 0x1FFFFFDC)
((void (*)(void))0x0001004C)(); ((void (*)(void))LEGACY_BOOT_ROUTINE_SMP)();
} }
} }

20
arm11/source/system/sys.h Executable file
View File

@ -0,0 +1,20 @@
#pragma once
#include <types.h>
/*
how to run the SYS_Core(Zero){Init,Shutdown} functions:
for init:
- FIRST run CoreZeroInit ONCE
- all cores must run CoreInit ONCE
for shutdown:
- all non-zero cores must call CoreShutdown
- core zero must call CoreZeroShutdown, then CoreShutdown
*/
void SYS_CoreZeroInit(void);
void SYS_CoreInit(void);
void SYS_CoreZeroShutdown(void);
void SYS_CoreShutdown(void);

38
arm9/source/common/common.h → common/common.h Normal file → Executable file
View File

@ -7,46 +7,68 @@
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <types.h>
#include <stdalign.h> #include <stdalign.h>
#ifdef MONITOR_HEAP #include <types.h>
#ifdef ARM9
# ifdef MONITOR_HEAP
#include "mymalloc.h" #include "mymalloc.h"
#define malloc my_malloc #define malloc my_malloc
#define free my_free #define free my_free
# endif
#endif #endif
#define max(a,b) \ #define max(a,b) \
(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b))
#define min(a,b) \ #define min(a,b) \
(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b))
#define getbe16(d) \ #define getbe16(d) \
(((d)[0]<<8) | (d)[1]) (((d)[0]<<8) | (d)[1])
#define getbe32(d) \ #define getbe32(d) \
((((u32) getbe16(d))<<16) | ((u32) getbe16(d+2))) ((((u32) getbe16(d))<<16) | ((u32) getbe16((d)+2)))
#define getbe64(d) \ #define getbe64(d) \
((((u64) getbe32(d))<<32) | ((u64) getbe32(d+4))) ((((u64) getbe32(d))<<32) | ((u64) getbe32((d)+4)))
#define getle16(d) \ #define getle16(d) \
(((d)[1]<<8) | (d)[0]) (((d)[1]<<8) | (d)[0])
#define getle32(d) \ #define getle32(d) \
((((u32) getle16(d+2))<<16) | ((u32) getle16(d))) ((((u32) getle16((d)+2))<<16) | ((u32) getle16(d)))
#define getle64(d) \ #define getle64(d) \
((((u64) getle32(d+4))<<32) | ((u64) getle32(d))) ((((u64) getle32((d)+4))<<32) | ((u64) getle32(d)))
#define align(v,a) \ #define align(v,a) \
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
#define countof(x) \ #define countof(x) \
(sizeof(x) / sizeof((x)[0])) (sizeof(x) / sizeof(*(x)))
#define bkpt \ #define bkpt \
asm("bkpt\n\t") asm volatile("bkpt\n\t")
#define STATIC_ASSERT(...) \ #define STATIC_ASSERT(...) \
_Static_assert((__VA_ARGS__), #__VA_ARGS__) _Static_assert((__VA_ARGS__), #__VA_ARGS__)
static inline u32 xbits(u32 *map, u32 start, u32 n)
{
u32 ret, mask, off, shift;
if (n > 32)
return -1;
mask = ((u32)(1 << n)) - 1;
off = start / 32;
shift = start % 32;
ret = map[off] >> shift;
if ((n + shift) > 32)
ret |= map[off+1] << (32 - shift);
return ret & mask;
}
// standard output path (support file paths are in support.h) // standard output path (support file paths are in support.h)
#define OUTPUT_PATH "0:/gm9/out" #define OUTPUT_PATH "0:/gm9/out"