forked from Mirror/GodMode9
rewrite the bootrom function header, add more operations and add ARM11 versions
- the bootrom is now mapped on the ARM11 - removed the waitClks in favor of a more canonical implementation (subs r0, r0, 4/5 + branch back)
This commit is contained in:
parent
d7444e144a
commit
f835469e19
@ -4,7 +4,7 @@ ENTRY(__boot)
|
|||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
AXIWRAM (RWX) : ORIGIN = 0x1FF80000, LENGTH = 128K
|
AXIWRAM (RWX) : ORIGIN = 0x1FF80000, LENGTH = 96K
|
||||||
HIGHRAM (RWX) : ORIGIN = 0xFFFF0000, LENGTH = 4K
|
HIGHRAM (RWX) : ORIGIN = 0xFFFF0000, LENGTH = 4K
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ typedef struct {
|
|||||||
static mmuLevel1Table mmuGlobalTT;
|
static mmuLevel1Table mmuGlobalTT;
|
||||||
|
|
||||||
// simple watermark allocator for 2nd level page tables
|
// simple watermark allocator for 2nd level page tables
|
||||||
#define MAX_SECOND_LEVEL (4)
|
#define MAX_SECOND_LEVEL (8)
|
||||||
static mmuLevel2Table mmuCoarseTables[MAX_SECOND_LEVEL];
|
static mmuLevel2Table mmuCoarseTables[MAX_SECOND_LEVEL];
|
||||||
static u32 mmuCoarseAllocated = 0;
|
static u32 mmuCoarseAllocated = 0;
|
||||||
static mmuLevel2Table *mmuAllocateLevel2Table(void)
|
static mmuLevel2Table *mmuAllocateLevel2Table(void)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <vram.h>
|
#include <vram.h>
|
||||||
|
#include <arm.h>
|
||||||
|
|
||||||
#include "arm/timer.h"
|
#include "arm/timer.h"
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ unsigned GFX_init(GfxFbFmt mode)
|
|||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E;
|
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E;
|
||||||
waitClks(12);
|
ARM_WaitCycles(12);
|
||||||
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_ALL;
|
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_ALL;
|
||||||
REG_GX_GPU_CLK = 0x100;
|
REG_GX_GPU_CLK = 0x100;
|
||||||
REG_GX_PSC_VRAM = 0;
|
REG_GX_PSC_VRAM = 0;
|
||||||
|
@ -86,6 +86,9 @@ void SYS_CoreZeroInit(void)
|
|||||||
mmuMapArea(SECTION_TRI(bss), MMU_FLAGS(MMU_CACHE_WBA, MMU_READ_WRITE, 1, 1));
|
mmuMapArea(SECTION_TRI(bss), MMU_FLAGS(MMU_CACHE_WBA, MMU_READ_WRITE, 1, 1));
|
||||||
mmuMapArea(SECTION_TRI(shared), MMU_FLAGS(MMU_STRONG_ORDER, MMU_READ_WRITE, 1, 1));
|
mmuMapArea(SECTION_TRI(shared), MMU_FLAGS(MMU_STRONG_ORDER, MMU_READ_WRITE, 1, 1));
|
||||||
|
|
||||||
|
// BootROM
|
||||||
|
mmuMapArea(0x00010000, 0x00010000, 32UL << 10, MMU_FLAGS(MMU_CACHE_WT, MMU_READ_ONLY, 0, 1));
|
||||||
|
|
||||||
// IO Registers
|
// IO Registers
|
||||||
mmuMapArea(0x10100000, 0x10100000, 4UL << 20, MMU_FLAGS(MMU_DEV_SHARED, MMU_READ_WRITE, 1, 1));
|
mmuMapArea(0x10100000, 0x10100000, 4UL << 20, MMU_FLAGS(MMU_DEV_SHARED, MMU_READ_WRITE, 1, 1));
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
.arm
|
.arm
|
||||||
|
|
||||||
#include <arm.h>
|
#include <arm.h>
|
||||||
#include <brf.h>
|
#include <bfn.h>
|
||||||
#include <entrypoints.h>
|
#include <entrypoints.h>
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
|
||||||
@ -27,9 +27,9 @@ _start:
|
|||||||
strlo r2, [r0], #4
|
strlo r2, [r0], #4
|
||||||
blo .LBSS_Clear
|
blo .LBSS_Clear
|
||||||
|
|
||||||
ldr r0, =BRF_WB_INV_DCACHE
|
ldr r0, =BFN_WRITEBACK_INVALIDATE_DCACHE
|
||||||
blx r0 @ Writeback & Invalidate Data Cache
|
blx r0 @ Writeback & Invalidate Data Cache
|
||||||
ldr r0, =BRF_INVALIDATE_ICACHE
|
ldr r0, =BFN_INVALIDATE_ICACHE
|
||||||
blx r0 @ Invalidate Instruction Cache
|
blx r0 @ Invalidate Instruction Cache
|
||||||
|
|
||||||
@ Disable caches / TCMs / MPU
|
@ Disable caches / TCMs / MPU
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
.arm
|
.arm
|
||||||
|
|
||||||
#include <arm.h>
|
#include <arm.h>
|
||||||
#include <brf.h>
|
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
|
||||||
.macro TRAP_ENTRY xrq_id
|
.macro TRAP_ENTRY xrq_id
|
||||||
|
230
common/arm.c
230
common/arm.c
@ -1,230 +0,0 @@
|
|||||||
#include <arm.h>
|
|
||||||
|
|
||||||
#define ARM_TARGET __attribute__((noinline, target("arm")))
|
|
||||||
|
|
||||||
#ifdef ARM11
|
|
||||||
#define ARM_CPS(m) asm_v("CPS " #m)
|
|
||||||
#define ARM_CPSID(m) asm_v("CPSID " #m)
|
|
||||||
#define ARM_CPSIE(m) asm_v("CPSIE " #m)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* An Instruction Synchronization Barrier (ISB) flushes the pipeline in the processor
|
|
||||||
* so that all instructions following the ISB are fetched from cache or memory
|
|
||||||
* after the ISB has been completed.
|
|
||||||
*/
|
|
||||||
void ARM_TARGET ARM_ISB(void) {
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c5, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A Data Memory Barrier (DMB) ensures that all explicit memory accesses before
|
|
||||||
* the DMB instruction complete before any explicit memory accesses after the DMB instruction start.
|
|
||||||
*/
|
|
||||||
void ARM_TARGET ARM_DMB(void) {
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c10, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait For Interrupt */
|
|
||||||
void ARM_TARGET ARM_WFI(void) {
|
|
||||||
asm_v("wfi\n\t");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait For Event */
|
|
||||||
void ARM_TARGET ARM_WFE(void) {
|
|
||||||
asm_v("wfe\n\t");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send Event */
|
|
||||||
void ARM_TARGET ARM_SEV(void) {
|
|
||||||
asm_v("sev\n\t");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Auxiliary Control Registers */
|
|
||||||
u32 ARM_TARGET ARM_GetACR(void) {
|
|
||||||
u32 acr;
|
|
||||||
ARM_MRC(p15, 0, acr, c1, c0, 1);
|
|
||||||
return acr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_SetACR(u32 acr) {
|
|
||||||
ARM_MCR(p15, 0, acr, c1, c0, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A Data Synchronization Barrier (DSB) completes when all
|
|
||||||
* instructions before this instruction complete.
|
|
||||||
*/
|
|
||||||
void ARM_TARGET ARM_DSB(void) {
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c10, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Control Registers */
|
|
||||||
u32 ARM_TARGET ARM_GetCR(void) {
|
|
||||||
u32 cr;
|
|
||||||
ARM_MRC(p15, 0, cr, c1, c0, 0);
|
|
||||||
return cr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_SetCR(u32 cr) {
|
|
||||||
ARM_MCR(p15, 0, cr, c1, c0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Thread ID Registers */
|
|
||||||
u32 ARM_TARGET ARM_GetTID(void) {
|
|
||||||
u32 tid;
|
|
||||||
#ifdef ARM9
|
|
||||||
ARM_MRC(p15, 0, tid, c13, c0, 1);
|
|
||||||
#else
|
|
||||||
ARM_MRC(p15, 0, tid, c13, c0, 4);
|
|
||||||
#endif
|
|
||||||
return tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_SetTID(u32 tid) {
|
|
||||||
#ifdef ARM9
|
|
||||||
ARM_MCR(p15, 0, tid, c13, c0, 1);
|
|
||||||
#else
|
|
||||||
ARM_MCR(p15, 0, tid, c13, c0, 4);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CPU ID */
|
|
||||||
u32 ARM_TARGET ARM_CoreID(void) {
|
|
||||||
u32 id;
|
|
||||||
#ifdef ARM9
|
|
||||||
id = 0;
|
|
||||||
#else
|
|
||||||
ARM_MRC(p15, 0, id, c0, c0, 5);
|
|
||||||
#endif
|
|
||||||
return id & 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Status Register */
|
|
||||||
u32 ARM_TARGET ARM_GetCPSR(void) {
|
|
||||||
u32 sr;
|
|
||||||
ARM_MRS(sr, cpsr);
|
|
||||||
return sr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_SetCPSR_c(u32 sr) {
|
|
||||||
ARM_MSR(cpsr_c, sr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_DisableInterrupts(void) {
|
|
||||||
#ifdef ARM9
|
|
||||||
ARM_SetCPSR_c(ARM_GetCPSR() | SR_NOINT);
|
|
||||||
#else
|
|
||||||
ARM_CPSID(if);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_EnableInterrupts(void) {
|
|
||||||
#ifdef ARM9
|
|
||||||
ARM_SetCPSR_c(ARM_GetCPSR() & ~SR_NOINT);
|
|
||||||
#else
|
|
||||||
ARM_CPSIE(if);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 ARM_TARGET ARM_EnterCritical(void) {
|
|
||||||
u32 stat = ARM_GetCPSR();
|
|
||||||
ARM_DisableInterrupts();
|
|
||||||
return stat & SR_NOINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_LeaveCritical(u32 stat) {
|
|
||||||
ARM_SetCPSR_c((ARM_GetCPSR() & ~SR_NOINT) | stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Cache functions */
|
|
||||||
void ARM_TARGET ARM_InvIC(void) {
|
|
||||||
#ifdef ARM9
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c5, 0);
|
|
||||||
#else
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c7, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_InvIC_Range(void *base, u32 len) {
|
|
||||||
u32 addr = (u32)base & ~0x1F;
|
|
||||||
len >>= 5;
|
|
||||||
|
|
||||||
do {
|
|
||||||
#ifdef ARM9
|
|
||||||
ARM_MCR(p15, 0, addr, c7, c5, 1);
|
|
||||||
#else
|
|
||||||
ARM_MCR(p15, 0, addr, c7, c7, 1);
|
|
||||||
#endif
|
|
||||||
addr += 0x20;
|
|
||||||
} while(len--);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_InvDC(void) {
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c6, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_InvDC_Range(void *base, u32 len) {
|
|
||||||
u32 addr = (u32)base & ~0x1F;
|
|
||||||
len >>= 5;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ARM_MCR(p15, 0, addr, c7, c6, 1);
|
|
||||||
addr += 0x20;
|
|
||||||
} while(len--);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_WbDC(void) {
|
|
||||||
#ifdef ARM9
|
|
||||||
u32 seg = 0, ind;
|
|
||||||
do {
|
|
||||||
ind = 0;
|
|
||||||
do {
|
|
||||||
ARM_MCR(p15, 0, seg | ind, c7, c10, 2);
|
|
||||||
ind += 0x20;
|
|
||||||
} while(ind < 0x400);
|
|
||||||
seg += 0x40000000;
|
|
||||||
} while(seg != 0);
|
|
||||||
#else
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c10, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_WbDC_Range(void *base, u32 len) {
|
|
||||||
u32 addr = (u32)base & ~0x1F;
|
|
||||||
len >>= 5;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ARM_MCR(p15, 0, addr, c7, c10, 1);
|
|
||||||
addr += 0x20;
|
|
||||||
} while(len--);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_WbInvDC(void) {
|
|
||||||
#ifdef ARM9
|
|
||||||
u32 seg = 0, ind;
|
|
||||||
do {
|
|
||||||
ind = 0;
|
|
||||||
do {
|
|
||||||
ARM_MCR(p15, 0, seg | ind, c7, c14, 2);
|
|
||||||
ind += 0x20;
|
|
||||||
} while(ind < 0x400);
|
|
||||||
seg += 0x40000000;
|
|
||||||
} while(seg != 0);
|
|
||||||
#else
|
|
||||||
ARM_MCR(p15, 0, 0, c7, c14, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_TARGET ARM_WbInvDC_Range(void *base, u32 len) {
|
|
||||||
u32 addr = (u32)base & ~0x1F;
|
|
||||||
len >>= 5;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ARM_MCR(p15, 0, addr, c7, c14, 1);
|
|
||||||
addr += 0x20;
|
|
||||||
} while(len--);
|
|
||||||
}
|
|
147
common/arm.h
147
common/arm.h
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#include <bfn.h>
|
||||||
|
|
||||||
/* Status Register flags */
|
/* Status Register flags */
|
||||||
#define SR_USR_MODE (0x10)
|
#define SR_USR_MODE (0x10)
|
||||||
#define SR_FIQ_MODE (0x11)
|
#define SR_FIQ_MODE (0x11)
|
||||||
@ -91,47 +93,126 @@
|
|||||||
#ifdef ARM11
|
#ifdef ARM11
|
||||||
#define REG_ARM_PMR(off, type) ((volatile type*)(0x17E00000 + (off)))
|
#define REG_ARM_PMR(off, type) ((volatile type*)(0x17E00000 + (off)))
|
||||||
|
|
||||||
void ARM_ISB(void);
|
static inline void ARM_ISB(void) {
|
||||||
void ARM_DMB(void);
|
((void (*)(void))(BFN_INSTSYNCBARRIER))();
|
||||||
void ARM_WFI(void);
|
}
|
||||||
void ARM_WFE(void);
|
|
||||||
void ARM_SEV(void);
|
static inline void ARM_DMB(void) {
|
||||||
u32 ARM_GetACR(void);
|
((void (*)(void))(BFN_DATAMEMBARRIER))();
|
||||||
void ARM_SetACR(u32 acr);
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WFI(void) {
|
||||||
|
// replace with a bootrom call if
|
||||||
|
// switching to thumb is necessary
|
||||||
|
asm_v("wfi\n\t":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WFE(void) {
|
||||||
|
asm_v("wfe\n\t":::"memory"); // same as above
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_SEV(void) {
|
||||||
|
asm_v("sev\n\t":::"memory"); // same as above
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Control Registers */
|
||||||
|
static inline u32 ARM_GetCR(void) {
|
||||||
|
u32 cr;
|
||||||
|
ARM_MRC(p15, 0, cr, c1, c0, 0);
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_SetCR(u32 cr) {
|
||||||
|
ARM_MCR(p15, 0, cr, c1, c0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ARM_GetACR(void) {
|
||||||
|
u32 acr;
|
||||||
|
ARM_MRC(p15, 0, acr, c1, c0, 1);
|
||||||
|
return acr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_SetACR(u32 acr) {
|
||||||
|
ARM_MCR(p15, 0, acr, c1, c0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Data Synchronization Barrier
|
/*
|
||||||
void ARM_DSB(void);
|
* A Data Synchronization Barrier (DSB) completes when all
|
||||||
|
* instructions before this instruction complete.
|
||||||
|
*/
|
||||||
|
static inline void ARM_DSB(void) {
|
||||||
|
((void (*)(void))(BFN_DATASYNCBARRIER))();
|
||||||
|
}
|
||||||
|
|
||||||
// Get and set Control Register
|
/* CPU ID */
|
||||||
u32 ARM_GetCR(void);
|
static inline u32 ARM_CoreID(void) {
|
||||||
void ARM_SetCR(u32 cr);
|
u32 id;
|
||||||
|
#ifdef ARM9
|
||||||
|
id = 0;
|
||||||
|
#else
|
||||||
|
ARM_MRC(p15, 0, id, c0, c0, 5);
|
||||||
|
#endif
|
||||||
|
return id & 3;
|
||||||
|
}
|
||||||
|
|
||||||
// Get and set Thread ID
|
/* Status register management */
|
||||||
u32 ARM_GetTID(void);
|
static inline u32 ARM_EnterCritical(void) {
|
||||||
void ARM_SetTID(u32 tid);
|
return ((u32 (*)(void))(BFN_ENTERCRITICALSECTION))();
|
||||||
|
}
|
||||||
|
|
||||||
// Core ID (not CPU ID)
|
static inline void ARM_LeaveCritical(u32 stat) {
|
||||||
u32 ARM_CoreID(void);
|
((void (*)(u32))(BFN_LEAVECRITICALSECTION))(stat);
|
||||||
|
}
|
||||||
|
|
||||||
// Get and set CPSR
|
static inline void ARM_DisableInterrupts(void) {
|
||||||
u32 ARM_GetCPSR(void);
|
ARM_LeaveCritical(SR_NOINT);
|
||||||
void ARM_SetCPSR_c(u32 sr);
|
}
|
||||||
|
|
||||||
// Manage interrupts
|
static inline void ARM_EnableInterrupts(void) {
|
||||||
void ARM_DisableInterrupts(void);
|
ARM_LeaveCritical(0x00);
|
||||||
void ARM_EnableInterrupts(void);
|
}
|
||||||
u32 ARM_EnterCritical(void);
|
|
||||||
void ARM_LeaveCritical(u32 stat);
|
|
||||||
|
|
||||||
void ARM_InvIC(void);
|
/* Cache functions */
|
||||||
void ARM_InvIC_Range(void *base, u32 len);
|
static inline void ARM_InvIC(void) {
|
||||||
void ARM_InvDC(void);
|
((void (*)(void))(BFN_INVALIDATE_ICACHE))();
|
||||||
void ARM_InvDC_Range(void *base, u32 len);
|
}
|
||||||
void ARM_WbDC(void);
|
|
||||||
void ARM_WbDC_Range(void *base, u32 len);
|
static inline void ARM_InvIC_Range(void *base, u32 len) {
|
||||||
void ARM_WbInvDC(void);
|
((void (*)(u32, u32))(BFN_INVALIDATE_ICACHE_RANGE))((u32)base, len);
|
||||||
void ARM_WbInvDC_Range(void *base, u32 len);
|
#ifdef ARM11 // make sure to also invalidate the branch target cache
|
||||||
|
((void (*)(u32, u32))(BFN_INVALIDATE_BT_CACHE_RANGE))((u32)base, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_InvDC(void) {
|
||||||
|
((void (*)(void))(BFN_INVALIDATE_DCACHE))();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_InvDC_Range(void *base, u32 len) {
|
||||||
|
((void (*)(u32, u32))(BFN_INVALIDATE_DCACHE_RANGE))((u32)base, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WbDC(void) {
|
||||||
|
((void (*)(void))(BFN_WRITEBACK_DCACHE))();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WbDC_Range(void *base, u32 len) {
|
||||||
|
((void (*)(u32, u32))(BFN_WRITEBACK_DCACHE_RANGE))((u32)base, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WbInvDC(void) {
|
||||||
|
((void (*)(void))(BFN_WRITEBACK_INVALIDATE_DCACHE))();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WbInvDC_Range(void *base, u32 len) {
|
||||||
|
((void (*)(u32, u32))(BFN_WRITEBACK_INVALIDATE_DCACHE_RANGE))((u32)base, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ARM_WaitCycles(u32 cycles) {
|
||||||
|
((void (*)(u32))(BFN_WAITCYCLES))(cycles);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ARM_BKPT(void) {
|
static inline void ARM_BKPT(void) {
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
|
135
common/bfn.h
Normal file
135
common/bfn.h
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
Addresses and declarations of preexisting BootROM functions
|
||||||
|
All of these functions should follow the standard AAPCS convention
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ARM9
|
||||||
|
|
||||||
|
// void waitCycles(u32 cycles)
|
||||||
|
// delays execution time by cycles
|
||||||
|
#define BFN_WAITCYCLES (0xFFFF0198)
|
||||||
|
|
||||||
|
// void cpuSet(u32 val, u32 *dest, u32 count)
|
||||||
|
#define BFN_CPUSET (0xFFFF03A4)
|
||||||
|
|
||||||
|
// void cpuCpy(const u32 *src, u32 *dest, u32 count)
|
||||||
|
#define BFN_CPUCPY (0xFFFF03F0)
|
||||||
|
|
||||||
|
// u32 enterCriticalSection()
|
||||||
|
// disables interrupts and returns the old irq state
|
||||||
|
#define BFN_ENTERCRITICALSECTION (0xFFFF06EC)
|
||||||
|
|
||||||
|
// void leaveCriticalSection(u32 irqstate)
|
||||||
|
// restores the old irq state
|
||||||
|
#define BFN_LEAVECRITICALSECTION (0xFFFF0700)
|
||||||
|
|
||||||
|
// bool enableDCache()
|
||||||
|
// enables the data cache and returns the old dcache bit
|
||||||
|
#define BFN_ENABLE_DCACHE (0xFFFF0798)
|
||||||
|
|
||||||
|
// bool disableDCache()
|
||||||
|
// disables the data cache
|
||||||
|
#define BFN_DISABLE_DCACHE (0xFFFF07B0)
|
||||||
|
|
||||||
|
// bool setDCache(bool enable)
|
||||||
|
// toggles the data cache
|
||||||
|
#define BFN_SET_DCACHE (0xFFFF07C8)
|
||||||
|
|
||||||
|
// void invalidateDCache()
|
||||||
|
// invalidates all data cache entries
|
||||||
|
#define BFN_INVALIDATE_DCACHE (0xFFFF07F0)
|
||||||
|
|
||||||
|
// void writebackDCache()
|
||||||
|
// writes back all data cache entries
|
||||||
|
#define BFN_WRITEBACK_DCACHE (0xFFFF07FC)
|
||||||
|
|
||||||
|
// void writebackInvalidateDCache()
|
||||||
|
// writes back and invalidates all data cache entries
|
||||||
|
#define BFN_WRITEBACK_INVALIDATE_DCACHE (0xFFFF0830)
|
||||||
|
|
||||||
|
// void invalidateDCacheRange(u32 start, u32 end)
|
||||||
|
// invalidates data cache entries
|
||||||
|
#define BFN_INVALIDATE_DCACHE_RANGE (0xFFFF0868)
|
||||||
|
|
||||||
|
// void writebackDCacheRange(u32 start, u32 end)
|
||||||
|
// writes back data cache entries
|
||||||
|
#define BFN_WRITEBACK_DCACHE_RANGE (0xFFFF0884)
|
||||||
|
|
||||||
|
// void writebackInvalidateDCacheRange(u32 start, u32 end)
|
||||||
|
#define BFN_WRITEBACK_INVALIDATE_DCACHE_RANGE (0xFFFF08A8)
|
||||||
|
|
||||||
|
// void dataSynchronizationBarrier()
|
||||||
|
#define BFN_DATASYNCBARRIER (0xFFFF096C)
|
||||||
|
|
||||||
|
// bool enableICache()
|
||||||
|
#define BFN_ENABLE_ICACHE (0xFFFF0A5C)
|
||||||
|
|
||||||
|
// bool disableICache()
|
||||||
|
#define BFN_DISABLE_ICACHE (0xFFFF0A74)
|
||||||
|
|
||||||
|
// bool setICache(bool enable)
|
||||||
|
#define BFN_SET_ICACHE (0xFFFF0A8C)
|
||||||
|
|
||||||
|
// void invalidateICache()
|
||||||
|
#define BFN_INVALIDATE_ICACHE (0xFFFF0AB4)
|
||||||
|
|
||||||
|
// void invalidateICacheRange(u32 start, u32 end)
|
||||||
|
#define BFN_INVALIDATE_ICACHE_RANGE (0xFFFF0AC0)
|
||||||
|
|
||||||
|
// void enableMPU()
|
||||||
|
#define BFN_ENABLE_MPU (0xFFFF0C38)
|
||||||
|
|
||||||
|
// void disableMPU()
|
||||||
|
#define BFN_DISABLE_MPU (0xFFFF0C48)
|
||||||
|
|
||||||
|
// void resetControlRegisters()
|
||||||
|
// set CR0 to its reset state (MPU & caches disabled, high vectors, TCMs enabled)
|
||||||
|
// invalidates both instruction and data caches (without previously writing back!!)
|
||||||
|
#define BFN_RESET_CRS (0xFFFF0C58)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define BFN_WAITCYCLES (0x00011A38)
|
||||||
|
|
||||||
|
#define BFN_CPUSET (0x000116E4)
|
||||||
|
#define BFN_CPUCPY (0x00011730)
|
||||||
|
|
||||||
|
#define BFN_ENTERCRITICALSECTION (0x00011AC4)
|
||||||
|
#define BFN_LEAVECRITICALSECTION (0x00011AD8)
|
||||||
|
|
||||||
|
#define BFN_ENABLE_DCACHE (0x00011288)
|
||||||
|
#define BFN_DISABLE_DCACHE (0x000112A0)
|
||||||
|
#define BFN_SET_DCACHE (0x000112B8)
|
||||||
|
|
||||||
|
#define BFN_INVALIDATE_DCACHE (0x000112E0)
|
||||||
|
#define BFN_WRITEBACK_DCACHE (0x000112EC)
|
||||||
|
#define BFN_WRITEBACK_INVALIDATE_DCACHE (0x00011320)
|
||||||
|
|
||||||
|
#define BFN_INVALIDATE_DCACHE_RANGE (0x00011358)
|
||||||
|
#define BFN_WRITEBACK_DCACHE_RANGE (0x00011374)
|
||||||
|
#define BFN_WRITEBACK_INVALIDATE_DCACHE_RANGE (0x00011398)
|
||||||
|
|
||||||
|
#define BFN_DATASYNCBARRIER (0x000113C0)
|
||||||
|
|
||||||
|
#define BFN_DATAMEMBARRIER (0x000113E8)
|
||||||
|
|
||||||
|
#define BFN_ENABLE_ICACHE (0x000113F4)
|
||||||
|
#define BFN_DISABLE_ICACHE (0x0001140C)
|
||||||
|
#define BFN_SET_ICACHE (0x00011424)
|
||||||
|
|
||||||
|
// also invalidates the branch target cache in ARM11
|
||||||
|
#define BFN_INVALIDATE_ICACHE (0x0001144C)
|
||||||
|
|
||||||
|
// WARNING: DOES NOT INVALIDATE THE BRANCH TARGET CACHE
|
||||||
|
// NEEDS TO INVALIDATE IT AND FLUSH THE PREFETCH BUFFER
|
||||||
|
#define BFN_INVALIDATE_ICACHE_RANGE (0x00011458)
|
||||||
|
|
||||||
|
// void instructionSynchronizationBarrier()
|
||||||
|
#define BFN_INSTSYNCBARRIER (0x00011490)
|
||||||
|
|
||||||
|
// void invalidateBranchTargetCache()
|
||||||
|
#define BFN_INVALIDATE_BT_CACHE_RANGE (0x000114F4)
|
||||||
|
|
||||||
|
#endif
|
19
common/brf.h
19
common/brf.h
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef ARM9
|
|
||||||
|
|
||||||
/* None of these functions require a working stack */
|
|
||||||
/* Assume R0-R3, R12 are always clobbered */
|
|
||||||
#define BRF_INVALIDATE_DCACHE (0xFFFF07F0)
|
|
||||||
#define BRF_INVALIDATE_DCACHE_RANGE (0xFFFF0868)
|
|
||||||
#define BRF_WRITEBACK_DCACHE (0xFFFF07FC)
|
|
||||||
#define BRF_WRITEBACK_DCACHE_RANGE (0xFFFF0884)
|
|
||||||
#define BRF_WB_INV_DCACHE (0xFFFF0830)
|
|
||||||
#define BRF_WB_INV_DCACHE_RANGE (0xFFFF08A8)
|
|
||||||
#define BRF_INVALIDATE_ICACHE (0xFFFF0AB4)
|
|
||||||
#define BRF_INVALIDATE_ICACHE_RANGE (0xFFFF0AC0)
|
|
||||||
#define BRF_RESETCP15 (0xFFFF0C58)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#endif
|
|
@ -58,13 +58,6 @@
|
|||||||
#define assert(x) \
|
#define assert(x) \
|
||||||
(!!(x) ? (void)0 : __builtin_trap())
|
(!!(x) ? (void)0 : __builtin_trap())
|
||||||
|
|
||||||
static inline void waitClks(unsigned clk) {
|
|
||||||
clk >>= 1;
|
|
||||||
while(clk--) {
|
|
||||||
asm_v("nop":::"memory", "cc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STATIC_ASSERT(...) \
|
#define STATIC_ASSERT(...) \
|
||||||
_Static_assert((__VA_ARGS__), #__VA_ARGS__)
|
_Static_assert((__VA_ARGS__), #__VA_ARGS__)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user