/*
* cortex arm arch v7 cache flushing and invalidation
* included by l.s and rebootcode.s
*/
TEXT cacheiinv(SB), $-4 /* I invalidate */
MOVW $0, R0
MTCP CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall /* ok on cortex */
ISB
RET
/*
* set/way operators, passed a suitable set/way value in R0.
*/
TEXT cachedwb_sw(SB), $-4
MTCP CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEsi
RET
TEXT cachedwbinv_sw(SB), $-4
MTCP CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEsi
RET
TEXT cachedinv_sw(SB), $-4
MTCP CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEsi
RET
/* set cache size select */
TEXT setcachelvl(SB), $-4
MTCP CpSC, CpIDcssel, R0, C(CpID), C(CpIDidct), 0
ISB
RET
/* return cache sizes */
TEXT getwayssets(SB), $-4
MFCP CpSC, CpIDcsize, R0, C(CpID), C(CpIDidct), 0
RET
/*
* l1 cache operations.
* l1 and l2 ops are intended to be called from C, thus need save no
* caller's regs, only those we need to preserve across calls.
*/
/*
* callers are assumed to be the above l1 and l2 ops.
* R0 is the function to call in the innermost loop.
* R8 is the cache level (1-origin: 1 or 2).
*
* R0 func to call at entry
* R1 func to call after entry
* R2 nsets
* R3 way shift (computed from R8)
* R4 set shift (computed from R8)
* R5 nways
* R6 set scratch
* R7 way scratch
* R8 cache level, 0-origin
* R9 extern reg up
* R10 extern reg m
*
* initial translation by 5c, then massaged by hand.
*/
TEXT wholecache+0(SB), $-4
MOVW CPSR, R2
MOVM.DB.W [R2,R14], (SP) /* save regs on stack */
MOVW R0, R1 /* save argument for inner loop in R1 */
SUB $1, R8 /* convert cache level to zero origin */
/* we might not have the MMU on yet, so map R1 (func) to R14's space */
MOVW R14, R0 /* get R14's segment ... */
AND $KSEGM, R0
BIC $KSEGM, R1 /* strip segment from func address */
ORR R0, R1 /* combine them */
wbuggery:
PUTC('?')
PUTC('c')
PUTC('w')
B topanic
sbuggery:
PUTC('?')
PUTC('c')
PUTC('s')
topanic:
MOVW $.string<>+0(SB), R0
BIC $KSEGM, R0 /* strip segment from address */
MOVW R14, R1 /* get R14's segment ... */
AND $KSEGM, R1
ORR R1, R0 /* combine them */
SUB $12, R13 /* not that it matters, since we're panicing */
MOVW R14, 8(R13)
BL panic(SB) /* panic("msg %#p", LR) */
bugloop:
WFI
B bugloop
DATA .string<>+0(SB)/8,$"bad cach"
DATA .string<>+8(SB)/8,$"e params"
DATA .string<>+16(SB)/8,$"\073 pc %\043p"
DATA .string<>+24(SB)/1,$"\z"
GLOBL .string<>+0(SB),$25