570 lines
12 KiB
ArmAsm
570 lines
12 KiB
ArmAsm
|
/*
|
||
|
* ti omap3530 SoC machine assist
|
||
|
* arm cortex-a8 processor
|
||
|
*
|
||
|
* loader uses R11 as scratch.
|
||
|
* R9 and R10 are used for `extern register' variables.
|
||
|
*
|
||
|
* ARM v7 arch. ref. man. §B1.3.3 that we don't need barriers
|
||
|
* around moves to CPSR.
|
||
|
*/
|
||
|
|
||
|
#include "arm.s"
|
||
|
|
||
|
/*
|
||
|
* MCR and MRC are counter-intuitively named.
|
||
|
* MCR coproc, opcode1, Rd, CRn, CRm[, opcode2] # arm -> coproc
|
||
|
* MRC coproc, opcode1, Rd, CRn, CRm[, opcode2] # coproc -> arm
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Entered here from Das U-Boot or another Plan 9 kernel with MMU disabled.
|
||
|
* Until the MMU is enabled it is OK to call functions provided
|
||
|
* they are within ±32MiB relative and do not require any
|
||
|
* local variables or more than one argument (i.e. there is
|
||
|
* no stack).
|
||
|
*/
|
||
|
TEXT _start(SB), 1, $-4
|
||
|
MOVW $setR12(SB), R12 /* load the SB */
|
||
|
SUB $KZERO, R12
|
||
|
ADD $PHYSDRAM, R12
|
||
|
|
||
|
/* SVC mode, interrupts disabled */
|
||
|
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
|
||
|
MOVW R1, CPSR
|
||
|
BARRIERS
|
||
|
|
||
|
DELAY(printloopret, 1)
|
||
|
WAVE('\r')
|
||
|
DELAY(printloopnl, 1)
|
||
|
WAVE('\n')
|
||
|
/*
|
||
|
* work around errata
|
||
|
*/
|
||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
|
||
|
ORR $(CpACissue1|CpACldstissue1), R1 /* fight omap35x errata 3.1.1.9 */
|
||
|
ORR $CpACibe, R1 /* enable cp15 invalidate */
|
||
|
ORR $CpACl1pe, R1 /* enable l1 parity checking */
|
||
|
ORR $CpCalign, R1 /* catch alignment errors */
|
||
|
BIC $CpACasa, R1 /* no speculative accesses */
|
||
|
/* go faster with fewer restrictions */
|
||
|
BIC $(CpACcachenopipe|CpACcp15serial|CpACcp15waitidle|CpACcp15pipeflush), R1
|
||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
|
||
|
ISB
|
||
|
|
||
|
MRC CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
|
||
|
ORR $CpCl2nowralloc, R1 /* fight cortex errata 460075 */
|
||
|
ORR $(CpCl2ecc|CpCl2eccparity), R1
|
||
|
#ifdef TEDIUM
|
||
|
/*
|
||
|
* I don't know why this clobbers the system, but I'm tired
|
||
|
* of arguing with this fussy processor. To hell with it.
|
||
|
*/
|
||
|
MCR CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
|
||
|
ISB
|
||
|
#endif
|
||
|
DELAY(printloops, 1)
|
||
|
WAVE('P')
|
||
|
/*
|
||
|
* disable the MMU & caches
|
||
|
*/
|
||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||
|
BIC $(CpCdcache|CpCicache|CpCmmu), R1
|
||
|
ORR $CpCsbo, R1
|
||
|
BIC $CpCsbz, R1
|
||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||
|
ISB
|
||
|
|
||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
|
||
|
BIC $CpACl2en, R1 /* turn l2 cache off */
|
||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
|
||
|
ISB
|
||
|
|
||
|
WAVE('l')
|
||
|
DELAY(printloop3, 1)
|
||
|
|
||
|
WAVE('a')
|
||
|
/* clear Mach */
|
||
|
MOVW $PADDR(MACHADDR), R4 /* address of Mach */
|
||
|
MOVW $0, R0
|
||
|
_machZ:
|
||
|
MOVW R0, (R4)
|
||
|
ADD $4, R4
|
||
|
CMP.S $PADDR(L1+L1X(0)), R4 /* end at top-level page table */
|
||
|
BNE _machZ
|
||
|
|
||
|
/*
|
||
|
* set up the MMU page table
|
||
|
*/
|
||
|
|
||
|
WAVE('n')
|
||
|
/* clear all PTEs first, to provide a default */
|
||
|
// MOVW $PADDR(L1+L1X(0)), R4 /* address of PTE for 0 */
|
||
|
_ptenv0:
|
||
|
ZEROPTE()
|
||
|
CMP.S $PADDR(L1+16*KiB), R4
|
||
|
BNE _ptenv0
|
||
|
|
||
|
DELAY(printloop4, 2)
|
||
|
WAVE(' ')
|
||
|
/*
|
||
|
* set up double map of PHYSDRAM, KZERO to PHYSDRAM for first few MBs,
|
||
|
* but only if KZERO and PHYSDRAM differ.
|
||
|
*/
|
||
|
MOVW $PTEDRAM, R2 /* PTE bits */
|
||
|
MOVW $PHYSDRAM, R3 /* pa */
|
||
|
CMP $KZERO, R3
|
||
|
BEQ no2map
|
||
|
MOVW $PADDR(L1+L1X(PHYSDRAM)), R4 /* address of PTE for PHYSDRAM */
|
||
|
MOVW $DOUBLEMAPMBS, R5
|
||
|
_ptdbl:
|
||
|
FILLPTE()
|
||
|
SUB.S $1, R5
|
||
|
BNE _ptdbl
|
||
|
no2map:
|
||
|
|
||
|
/*
|
||
|
* back up and fill in PTEs for memory at KZERO.
|
||
|
* beagle has 1 bank of 256MB of SDRAM at PHYSDRAM;
|
||
|
* igepv2 has 1 bank of 512MB at PHYSDRAM.
|
||
|
* Map the maximum (512MB).
|
||
|
*/
|
||
|
WAVE('9')
|
||
|
MOVW $PTEDRAM, R2 /* PTE bits */
|
||
|
MOVW $PHYSDRAM, R3
|
||
|
MOVW $PADDR(L1+L1X(KZERO)), R4 /* start with PTE for KZERO */
|
||
|
MOVW $512, R5 /* inner loop count (MBs) */
|
||
|
_ptekrw: /* set PTEs */
|
||
|
FILLPTE()
|
||
|
SUB.S $1, R5 /* decrement inner loop count */
|
||
|
BNE _ptekrw
|
||
|
|
||
|
/*
|
||
|
* back up and fill in PTEs for MMIO
|
||
|
* stop somewhere after uarts
|
||
|
*/
|
||
|
WAVE(' ')
|
||
|
MOVW $PTEIO, R2 /* PTE bits */
|
||
|
MOVW $PHYSIO, R3
|
||
|
MOVW $PADDR(L1+L1X(VIRTIO)), R4 /* start with PTE for VIRTIO */
|
||
|
_ptenv2:
|
||
|
FILLPTE()
|
||
|
CMP.S $PADDR(L1+L1X(PHYSIOEND)), R4
|
||
|
BNE _ptenv2
|
||
|
|
||
|
/* mmu.c sets up the trap vectors later */
|
||
|
|
||
|
/*
|
||
|
* set up a temporary stack; avoid data & bss segments
|
||
|
*/
|
||
|
MOVW $(PHYSDRAM | (128*1024*1024)), R13
|
||
|
|
||
|
/* invalidate caches */
|
||
|
BL cachedinv(SB)
|
||
|
MOVW $KZERO, R0
|
||
|
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
|
||
|
ISB
|
||
|
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
|
||
|
BARRIERS
|
||
|
|
||
|
WAVE('f')
|
||
|
/*
|
||
|
* turn caches on
|
||
|
*/
|
||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
|
||
|
ORR $CpACl2en, R1 /* turn l2 cache on */
|
||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
|
||
|
BARRIERS
|
||
|
|
||
|
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||
|
ORR $(CpCdcache|CpCicache), R1
|
||
|
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||
|
BARRIERS
|
||
|
|
||
|
WAVE('r')
|
||
|
/* set the domain access control */
|
||
|
MOVW $Client, R0
|
||
|
BL dacput(SB)
|
||
|
|
||
|
DELAY(printloop5, 2)
|
||
|
WAVE('o')
|
||
|
/* set the translation table base */
|
||
|
MOVW $PADDR(L1), R0
|
||
|
BL ttbput(SB)
|
||
|
|
||
|
MOVW $0, R0
|
||
|
BL pidput(SB) /* paranoia */
|
||
|
|
||
|
WAVE('m')
|
||
|
/*
|
||
|
* the little dance to turn the MMU on
|
||
|
*/
|
||
|
BL cacheuwbinv(SB)
|
||
|
BL mmuinvalidate(SB)
|
||
|
BL mmuenable(SB)
|
||
|
|
||
|
WAVE(' ')
|
||
|
/* warp the PC into the virtual map */
|
||
|
MOVW $KZERO, R0
|
||
|
BL _r15warp(SB)
|
||
|
|
||
|
/*
|
||
|
* now running at KZERO+something!
|
||
|
*/
|
||
|
|
||
|
MOVW $setR12(SB), R12 /* reload the SB */
|
||
|
|
||
|
/*
|
||
|
* set up temporary stack again, in case we've just switched
|
||
|
* to a new register set.
|
||
|
*/
|
||
|
MOVW $(KZERO|(128*1024*1024)), R13
|
||
|
|
||
|
/* can now execute arbitrary C code */
|
||
|
|
||
|
BL cacheuwbinv(SB)
|
||
|
|
||
|
WAVE('B')
|
||
|
MOVW $PHYSDRAM, R3 /* pa */
|
||
|
CMP $KZERO, R3
|
||
|
BEQ no2unmap
|
||
|
/* undo double map of PHYSDRAM, KZERO & first few MBs */
|
||
|
MOVW $(L1+L1X(PHYSDRAM)), R4 /* addr. of PTE for PHYSDRAM */
|
||
|
MOVW $0, R0
|
||
|
MOVW $DOUBLEMAPMBS, R5
|
||
|
_ptudbl:
|
||
|
ZEROPTE()
|
||
|
SUB.S $1, R5
|
||
|
BNE _ptudbl
|
||
|
no2unmap:
|
||
|
BARRIERS
|
||
|
MOVW $KZERO, R0
|
||
|
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
|
||
|
BARRIERS
|
||
|
|
||
|
#ifdef HIGH_SECURITY /* i.e., not GP omap */
|
||
|
/* hack: set `secure monitor' vector base addr for cortex */
|
||
|
// MOVW $HVECTORS, R0
|
||
|
MOVW $PADDR(L1), R0
|
||
|
SUB $(MACHSIZE+(2*1024)), R0
|
||
|
MCR CpSC, 0, R0, C(CpVECS), C(CpVECSbase), CpVECSmon
|
||
|
ISB
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* call main in C
|
||
|
* pass Mach to main and set up the stack in it
|
||
|
*/
|
||
|
MOVW $(MACHADDR), R0 /* Mach */
|
||
|
MOVW R0, R13
|
||
|
ADD $(MACHSIZE), R13 /* stack pointer */
|
||
|
SUB $4, R13 /* space for link register */
|
||
|
MOVW R0, R10 /* m = MACHADDR */
|
||
|
WAVE('e')
|
||
|
BL main(SB) /* void main(Mach*) */
|
||
|
/*FALLTHROUGH*/
|
||
|
|
||
|
/*
|
||
|
* reset the system
|
||
|
*/
|
||
|
|
||
|
TEXT _reset(SB), 1, $-4
|
||
|
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R0
|
||
|
MOVW R0, CPSR
|
||
|
BARRIERS
|
||
|
|
||
|
DELAY(printloopr, 2)
|
||
|
WAVE('!')
|
||
|
WAVE('r')
|
||
|
WAVE('e')
|
||
|
WAVE('s')
|
||
|
WAVE('e')
|
||
|
WAVE('t')
|
||
|
WAVE('!')
|
||
|
WAVE('\r')
|
||
|
WAVE('\n')
|
||
|
|
||
|
/* turn the caches off */
|
||
|
BL cacheuwbinv(SB)
|
||
|
|
||
|
MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
BIC $(CpCicache|CpCdcache|CpCalign), R0
|
||
|
ORR $CpCsw, R0 /* enable SWP */
|
||
|
MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
BARRIERS
|
||
|
|
||
|
/* redo double map of PHYSDRAM, KZERO & first few MBs */
|
||
|
MOVW $PTEDRAM, R2 /* PTE bits */
|
||
|
MOVW $PHYSDRAM, R3 /* pa */
|
||
|
MOVW $(L1+L1X(PHYSDRAM)), R4 /* address of PHYSDRAM's PTE */
|
||
|
MOVW $DOUBLEMAPMBS, R5
|
||
|
_ptrdbl:
|
||
|
FILLPTE()
|
||
|
SUB.S $1, R5
|
||
|
BNE _ptrdbl
|
||
|
|
||
|
MOVW $PHYSDRAM, R0
|
||
|
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
|
||
|
BARRIERS
|
||
|
|
||
|
/* turn the MMU off */
|
||
|
MOVW $PHYSDRAM, R0
|
||
|
BL _r15warp(SB)
|
||
|
BL mmuinvalidate(SB)
|
||
|
BL mmudisable(SB)
|
||
|
|
||
|
/* set new reset vector */
|
||
|
MOVW $HVECTORS, R2
|
||
|
MOVW $0xe59ff018, R3 /* MOVW 0x18(R15), R15 */
|
||
|
MOVW R3, (R2)
|
||
|
BARRIERS
|
||
|
|
||
|
// MOVW $PHYSFLASH, R3 /* TODO */
|
||
|
// MOVW R3, 0x20(R2) /* where $0xe59ff018 jumps to */
|
||
|
|
||
|
/* ...and jump to it */
|
||
|
// MOVW R2, R15 /* software reboot */
|
||
|
_limbo: /* should not get here... */
|
||
|
BL idlehands(SB)
|
||
|
B _limbo /* ... and can't get out */
|
||
|
BL _div(SB) /* hack to load _div, etc. */
|
||
|
|
||
|
TEXT _r15warp(SB), 1, $-4
|
||
|
BIC $KSEGM, R14 /* link reg, will become PC */
|
||
|
ORR R0, R14
|
||
|
BIC $KSEGM, R13 /* SP too */
|
||
|
ORR R0, R13
|
||
|
RET
|
||
|
|
||
|
/*
|
||
|
* `single-element' cache operations.
|
||
|
* in arm arch v7, they operate on all cache levels, so separate
|
||
|
* l2 functions are unnecessary.
|
||
|
*/
|
||
|
|
||
|
TEXT cachedwbse(SB), $-4 /* D writeback SE */
|
||
|
MOVW R0, R2
|
||
|
|
||
|
MOVW CPSR, R3
|
||
|
CPSID /* splhi */
|
||
|
|
||
|
BARRIERS /* force outstanding stores to cache */
|
||
|
MOVW R2, R0
|
||
|
MOVW 4(FP), R1
|
||
|
ADD R0, R1 /* R1 is end address */
|
||
|
BIC $(CACHELINESZ-1), R0 /* cache line start */
|
||
|
_dwbse:
|
||
|
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEse
|
||
|
/* can't have a BARRIER here since it zeroes R0 */
|
||
|
ADD $CACHELINESZ, R0
|
||
|
CMP.S R0, R1
|
||
|
BGT _dwbse
|
||
|
B _wait
|
||
|
|
||
|
TEXT cachedwbinvse(SB), $-4 /* D writeback+invalidate SE */
|
||
|
MOVW R0, R2
|
||
|
|
||
|
MOVW CPSR, R3
|
||
|
CPSID /* splhi */
|
||
|
|
||
|
BARRIERS /* force outstanding stores to cache */
|
||
|
MOVW R2, R0
|
||
|
MOVW 4(FP), R1
|
||
|
ADD R0, R1 /* R1 is end address */
|
||
|
BIC $(CACHELINESZ-1), R0 /* cache line start */
|
||
|
_dwbinvse:
|
||
|
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEse
|
||
|
/* can't have a BARRIER here since it zeroes R0 */
|
||
|
ADD $CACHELINESZ, R0
|
||
|
CMP.S R0, R1
|
||
|
BGT _dwbinvse
|
||
|
_wait: /* drain write buffer */
|
||
|
BARRIERS
|
||
|
/* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
|
||
|
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
|
||
|
ISB
|
||
|
|
||
|
MOVW R3, CPSR /* splx */
|
||
|
RET
|
||
|
|
||
|
TEXT cachedinvse(SB), $-4 /* D invalidate SE */
|
||
|
MOVW R0, R2
|
||
|
|
||
|
MOVW CPSR, R3
|
||
|
CPSID /* splhi */
|
||
|
|
||
|
BARRIERS /* force outstanding stores to cache */
|
||
|
MOVW R2, R0
|
||
|
MOVW 4(FP), R1
|
||
|
ADD R0, R1 /* R1 is end address */
|
||
|
BIC $(CACHELINESZ-1), R0 /* cache line start */
|
||
|
_dinvse:
|
||
|
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEse
|
||
|
/* can't have a BARRIER here since it zeroes R0 */
|
||
|
ADD $CACHELINESZ, R0
|
||
|
CMP.S R0, R1
|
||
|
BGT _dinvse
|
||
|
B _wait
|
||
|
|
||
|
/*
|
||
|
* enable mmu and high vectors
|
||
|
*/
|
||
|
TEXT mmuenable(SB), 1, $-4
|
||
|
MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
ORR $(CpChv|CpCmmu), R0
|
||
|
MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
BARRIERS
|
||
|
RET
|
||
|
|
||
|
TEXT mmudisable(SB), 1, $-4
|
||
|
MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
BIC $(CpChv|CpCmmu), R0
|
||
|
MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
BARRIERS
|
||
|
RET
|
||
|
|
||
|
/*
|
||
|
* If one of these MCR instructions crashes or hangs the machine,
|
||
|
* check your Level 1 page table (at TTB) closely.
|
||
|
*/
|
||
|
TEXT mmuinvalidate(SB), $-4 /* invalidate all */
|
||
|
MOVW CPSR, R2
|
||
|
CPSID /* interrupts off */
|
||
|
|
||
|
BARRIERS
|
||
|
MOVW PC, R0 /* some valid virtual address */
|
||
|
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
|
||
|
BARRIERS
|
||
|
MOVW R2, CPSR /* interrupts restored */
|
||
|
RET
|
||
|
|
||
|
TEXT mmuinvalidateaddr(SB), $-4 /* invalidate single entry */
|
||
|
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinvse
|
||
|
BARRIERS
|
||
|
RET
|
||
|
|
||
|
TEXT cpidget(SB), 1, $-4 /* main ID */
|
||
|
MRC CpSC, 0, R0, C(CpID), C(0), CpIDid
|
||
|
RET
|
||
|
|
||
|
TEXT cpctget(SB), 1, $-4 /* cache type */
|
||
|
MRC CpSC, 0, R0, C(CpID), C(0), CpIDct
|
||
|
RET
|
||
|
|
||
|
TEXT controlget(SB), 1, $-4 /* control */
|
||
|
MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||
|
RET
|
||
|
|
||
|
TEXT ttbget(SB), 1, $-4 /* translation table base */
|
||
|
MRC CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
|
||
|
RET
|
||
|
|
||
|
TEXT ttbput(SB), 1, $-4 /* translation table base */
|
||
|
MCR CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
|
||
|
MCR CpSC, 0, R0, C(CpTTB), C(0), CpTTB1 /* cortex has two */
|
||
|
ISB
|
||
|
RET
|
||
|
|
||
|
TEXT dacget(SB), 1, $-4 /* domain access control */
|
||
|
MRC CpSC, 0, R0, C(CpDAC), C(0)
|
||
|
RET
|
||
|
|
||
|
TEXT dacput(SB), 1, $-4 /* domain access control */
|
||
|
MCR CpSC, 0, R0, C(CpDAC), C(0)
|
||
|
ISB
|
||
|
RET
|
||
|
|
||
|
TEXT fsrget(SB), 1, $-4 /* fault status */
|
||
|
MRC CpSC, 0, R0, C(CpFSR), C(0)
|
||
|
RET
|
||
|
|
||
|
TEXT farget(SB), 1, $-4 /* fault address */
|
||
|
MRC CpSC, 0, R0, C(CpFAR), C(0x0)
|
||
|
RET
|
||
|
|
||
|
TEXT getpsr(SB), 1, $-4
|
||
|
MOVW CPSR, R0
|
||
|
RET
|
||
|
|
||
|
TEXT getscr(SB), 1, $-4
|
||
|
MRC CpSC, 0, R0, C(CpCONTROL), C(CpCONTROLscr), CpSCRscr
|
||
|
RET
|
||
|
|
||
|
TEXT pidget(SB), 1, $-4 /* address translation pid */
|
||
|
MRC CpSC, 0, R0, C(CpPID), C(0x0)
|
||
|
RET
|
||
|
|
||
|
TEXT pidput(SB), 1, $-4 /* address translation pid */
|
||
|
MCR CpSC, 0, R0, C(CpPID), C(0x0)
|
||
|
ISB
|
||
|
RET
|
||
|
|
||
|
TEXT splhi(SB), 1, $-4
|
||
|
MOVW CPSR, R0
|
||
|
CPSID /* turn off interrupts */
|
||
|
|
||
|
MOVW $(MACHADDR+4), R2 /* save caller pc in Mach */
|
||
|
MOVW R14, 0(R2)
|
||
|
RET
|
||
|
|
||
|
TEXT spllo(SB), 1, $-4 /* start marker for devkprof.c */
|
||
|
MOVW CPSR, R0
|
||
|
CPSIE
|
||
|
RET
|
||
|
|
||
|
TEXT splx(SB), 1, $-4
|
||
|
MOVW $(MACHADDR+0x04), R2 /* save caller pc in Mach */
|
||
|
MOVW R14, 0(R2)
|
||
|
|
||
|
MOVW CPSR, R3
|
||
|
MOVW R0, CPSR /* reset interrupt level */
|
||
|
MOVW R3, R0 /* must return old CPSR */
|
||
|
RET
|
||
|
|
||
|
TEXT spldone(SB), 1, $0 /* end marker for devkprof.c */
|
||
|
RET
|
||
|
|
||
|
TEXT islo(SB), 1, $-4
|
||
|
MOVW CPSR, R0
|
||
|
AND $(PsrDirq), R0
|
||
|
EOR $(PsrDirq), R0
|
||
|
RET
|
||
|
|
||
|
TEXT tas(SB), $-4
|
||
|
TEXT _tas(SB), $-4
|
||
|
MOVW R0,R1
|
||
|
MOVW $1,R0
|
||
|
SWPW R0,(R1) /* fix: deprecated in armv7 */
|
||
|
RET
|
||
|
|
||
|
TEXT clz(SB), $-4
|
||
|
CLZ(0, 0) /* 0 is R0 */
|
||
|
RET
|
||
|
|
||
|
TEXT setlabel(SB), 1, $-4
|
||
|
MOVW R13, 0(R0) /* sp */
|
||
|
MOVW R14, 4(R0) /* pc */
|
||
|
MOVW $0, R0
|
||
|
RET
|
||
|
|
||
|
TEXT gotolabel(SB), 1, $-4
|
||
|
MOVW 0(R0), R13 /* sp */
|
||
|
MOVW 4(R0), R14 /* pc */
|
||
|
MOVW $1, R0
|
||
|
RET
|
||
|
|
||
|
TEXT getcallerpc(SB), 1, $-4
|
||
|
MOVW 0(R13), R0
|
||
|
RET
|
||
|
|
||
|
TEXT idlehands(SB), $-4
|
||
|
BARRIERS
|
||
|
WFI
|
||
|
RET
|
||
|
|
||
|
TEXT coherence(SB), $-4
|
||
|
BARRIERS
|
||
|
RET
|
||
|
|
||
|
#include "cache.v7.s"
|