- 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 <common.h>
#include <arm.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 */
/* {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)
{
switch(MMU_FLAGS_TYPE(f)) {
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;
}
return MMU_TypeLUT[MMU_FLAGS_TYPE(f)][0];
}
static u32 MMU_GetCB(u32 f)
{
switch(MMU_FLAGS_TYPE(f)) {
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;
}
return MMU_TypeLUT[MMU_FLAGS_TYPE(f)][1];
}
static u32 MMU_GetAP(u32 f)
@ -114,10 +98,8 @@ static u32 MMU_GetAP(u32 f)
default:
case NO_ACCESS:
return 0;
case READ_ONLY:
return 0x21;
case READ_WRITE:
return 0x01;
}
@ -281,11 +263,10 @@ u32 MMU_Map(u32 va, u32 pa, u32 size, u32 flags)
.mapfn = MMU_MapPage,
},
};
static const size_t VMapperCount = sizeof(VMappers)/sizeof(*VMappers);
while(size > 0) {
size_t i = 0;
for (i = 0; i < VMapperCount; i++) {
for (i = 0; i < countof(VMappers); i++) {
u32 abits = VMappers[i].bits;
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;
}

View File

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

View File

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

View File

@ -8,8 +8,9 @@
#include "hw/i2c.h"
#include "hw/mcu.h"
static bool legacy;
void SYS_CoreShutdown(void);
#include "system/sys.h"
static bool legacy = false;
void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
{
@ -98,21 +99,18 @@ void PXI_RX_Handler(u32 __attribute__((unused)) irqn)
return;
}
void MPCoreMain(void)
void MainLoop(void)
{
legacy = false;
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);
ARM_EnableInterrupts();
// Process IRQs until the ARM9 tells us it's time to boot something else
do {
ARM_WFI();
} while(!legacy);
// Perform any needed deinit stuff
ARM_DisableInterrupts();
SYS_CoreZeroShutdown();
SYS_CoreShutdown();
}

View File

@ -1,5 +1,7 @@
#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;
DEF_SECT_(vector)
DEF_SECT_(text)

View File

@ -8,14 +8,13 @@
#include "hw/i2c.h"
#include "system/sections.h"
#define CFG11_MPCORE_CLKCNT ((vu16*)(0x10141300))
#define CFG11_SOCINFO ((vu16*)(0x10140FFC))
#define LEGACY_BOOT_ENTRY ((vu32*)0x1FFFFFFC)
#define INIT_DONE (0xDDEEFFAA)
static volatile u32 sys_init_state = 0;
#define LEGACY_BOOT_ENTRYPOINT ((vu32*)0x1FFFFFFC)
#define LEGACY_BOOT_ROUTINE_SMP (0x0001004C)
static bool SYS_IsNewConsole(void)
{
@ -45,16 +44,11 @@ static void SYS_EnableClkMult(void)
}
}
#include "sections.h"
#define MMU_FLAGS_DEF MMU_FLAGS(STRONGLY_ORDERED, READ_WRITE, 0, 1)
static void SYS_CoreZeroInit(void)
void SYS_CoreZeroInit(void)
{
GIC_GlobalReset();
GIC_LocalReset();
*LEGACY_BOOT_ENTRY = 0;
*LEGACY_BOOT_ENTRYPOINT = 0;
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));
// 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();
I2C_init();
//MCU_init();
@ -89,19 +85,13 @@ static void SYS_InitPeripherals(void)
void SYS_CoreInit(void)
{
if (!ARM_CoreID()) {
SYS_CoreZeroInit();
} else {
while(sys_init_state != INIT_DONE)
ARM_WFE();
// Reset local GIC registers
GIC_LocalReset();
GIC_LocalReset();
}
// set up MMU registers
// Set up MMU registers
MMU_Init();
// enable fancy ARM11 stuff
// Enable fancy ARM11 features
ARM_SetACR(ARM_GetACR() |
ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP);
@ -110,32 +100,20 @@ void SYS_CoreInit(void)
ARM_DSB();
if (!ARM_CoreID()) {
SYS_InitPeripherals();
sys_init_state = INIT_DONE;
ARM_DSB();
ARM_SEV();
}
ARM_EnableInterrupts();
}
void SYS_CoreZeroShutdown(void)
{
ARM_DisableInterrupts();
GIC_GlobalReset();
}
// assumes all cores have been initialized
void SYS_CoreShutdown(void)
{
u32 core = ARM_CoreID();
if (!core) {
// 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();
}
ARM_DisableInterrupts();
GIC_LocalReset();
@ -148,11 +126,11 @@ void SYS_CoreShutdown(void)
~(ACR_RETSTK | ACR_DBPRED | ACR_SBPRED | ACR_FOLDING | ACR_SMP));
if (!core) {
while(*LEGACY_BOOT_ENTRY == 0);
((void (*)(void))(*LEGACY_BOOT_ENTRY))();
while(*LEGACY_BOOT_ENTRYPOINT == 0);
((void (*)(void))(*LEGACY_BOOT_ENTRYPOINT))();
} else {
// Branch to bootrom function that does SMP reinit magic
// (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);

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

@ -1,59 +1,81 @@
#pragma once
#include <inttypes.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <types.h>
#include <stdalign.h>
#ifdef MONITOR_HEAP
#include "mymalloc.h"
#define malloc my_malloc
#define free my_free
#endif
#define max(a,b) \
(((a) > (b)) ? (a) : (b))
#define min(a,b) \
(((a) < (b)) ? (a) : (b))
#define getbe16(d) \
(((d)[0]<<8) | (d)[1])
#define getbe32(d) \
((((u32) getbe16(d))<<16) | ((u32) getbe16(d+2)))
#define getbe64(d) \
((((u64) getbe32(d))<<32) | ((u64) getbe32(d+4)))
#define getle16(d) \
(((d)[1]<<8) | (d)[0])
#define getle32(d) \
((((u32) getle16(d+2))<<16) | ((u32) getle16(d)))
#define getle64(d) \
((((u64) getle32(d+4))<<32) | ((u64) getle32(d)))
#define align(v,a) \
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
#define countof(x) \
(sizeof(x) / sizeof((x)[0]))
#define bkpt \
asm("bkpt\n\t")
#define STATIC_ASSERT(...) \
_Static_assert((__VA_ARGS__), #__VA_ARGS__)
// standard output path (support file paths are in support.h)
#define OUTPUT_PATH "0:/gm9/out"
// used in several places
#define STD_BUFFER_SIZE 0x100000 // must be a multiple of 0x200
// buffer area defines (in use by image.c, for RAMdrive)
#define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK
#define RAMDRV_SIZE_O3DS (0x5800000) // 88MB
#define RAMDRV_SIZE_N3DS (0xD800000) // 216MB
#pragma once
#include <inttypes.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdalign.h>
#include <types.h>
#ifdef ARM9
# ifdef MONITOR_HEAP
#include "mymalloc.h"
#define malloc my_malloc
#define free my_free
# endif
#endif
#define max(a,b) \
(((a) > (b)) ? (a) : (b))
#define min(a,b) \
(((a) < (b)) ? (a) : (b))
#define getbe16(d) \
(((d)[0]<<8) | (d)[1])
#define getbe32(d) \
((((u32) getbe16(d))<<16) | ((u32) getbe16((d)+2)))
#define getbe64(d) \
((((u64) getbe32(d))<<32) | ((u64) getbe32((d)+4)))
#define getle16(d) \
(((d)[1]<<8) | (d)[0])
#define getle32(d) \
((((u32) getle16((d)+2))<<16) | ((u32) getle16(d)))
#define getle64(d) \
((((u64) getle32((d)+4))<<32) | ((u64) getle32(d)))
#define align(v,a) \
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
#define countof(x) \
(sizeof(x) / sizeof(*(x)))
#define bkpt \
asm volatile("bkpt\n\t")
#define STATIC_ASSERT(...) \
_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)
#define OUTPUT_PATH "0:/gm9/out"
// used in several places
#define STD_BUFFER_SIZE 0x100000 // must be a multiple of 0x200
// buffer area defines (in use by image.c, for RAMdrive)
#define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK
#define RAMDRV_SIZE_O3DS (0x5800000) // 88MB
#define RAMDRV_SIZE_N3DS (0xD800000) // 216MB