Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

/*
 * sheevaplug machine assist
 * arm926ej-s processor at 1.2GHz
 *
 * loader uses R11 as scratch.
 * R9 and R10 are used for `extern register' variables.
 *
 * ARM v7 arch. ref. man. (I know, this is v5) §B1.3.3 that
 * we don't need barriers around moves to CPSR.  The ARM v6 manual
 * seems to be silent on the subject.
 */
#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 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 */
_main:
        /* SVC mode, interrupts disabled */
        MOVW    $(PsrDirq|PsrDfiq|PsrMsvc), R1
        MOVW    R1, CPSR
        BARRIERS

        /*
         * disable the MMU & caches,
         * switch to system permission & 32-bit addresses.
         */
        MOVW    $(CpCsystem|CpCd32|CpCi32), R1
        MCR     CpSC, 0, R1, C(CpCONTROL), C(0)
        ISB

        /*
         * disable the Sheevaplug's L2 cache, invalidate all caches
         */

        /* flush caches.  926ejs manual says we have to do it iteratively. */
_dwbinv0:
        MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
        BNE     _dwbinv0
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        /* make the l2 cache pay attention and disable resets */
        MOVW    $(PHYSIO+0x20100), R1   /* CPUCSREG */
        MOVW    $0, R0
        MOVW    R0, 8(R1)               /* cpu->rstout = 0; */
        MOVW    (4*10)(R1), R2
        ORR     $(1<<3), R2             /* cpu->l2cfg |= L2exists */
        MOVW    R2, (4*10)(R1)
        ISB

        /* invalidate l2 cache */
        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
        ISB

        /* disable l2 cache.  do this while l1 caches are off */
        MRC     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
        /* disabling write allocation is probably for cortex-a8 errata 460075 */
        /* l2 off, no wr alloc, no streaming */
        BIC     $(CpTCl2ena | CpTCl2wralloc | CpTCldcstream), R1
        MCR     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
        BARRIERS

        /* flush caches.  926ejs manual says we have to do it iteratively. */
_dwbinv1:
        MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
        BNE     _dwbinv1
        BARRIERS

PUTC('\r')
        /* turn off watchdog; see clock.c */
        MOVW    $(PHYSIO+0x20300), R1   /* tmr = (TimerReg *)soc.clock; */
        MOVW    $0, R0
        MOVW    R0, 0(R1)               /* tmr->ctl = 0; */
        BARRIERS

        /* clear Mach */
        MOVW    $0, R0
        MOVW    $PADDR(MACHADDR), R4            /* address of Mach */
_machZ:
        MOVW    R0, (R4)
        ADD     $4, R4                          /* bump PTE address */
        CMP.S   $PADDR(L1+L1X(0)), R4
        BNE     _machZ

        /*
         * set up the MMU page table
         */

        /* clear all PTEs first, to provide a default */
PUTC('\n')
        MOVW    $PADDR(L1+L1X(0)), R4           /* address of PTE for 0 */
_ptenv0:
        ZEROPTE()
        CMP.S   $PADDR(L1+16*KiB), R4
        BNE     _ptenv0

        /* double map of PHYSDRAM, KZERO to PHYSDRAM for first few MBs */
        MOVW    $PTEDRAM, R2                    /* PTE bits */
        MOVW    $PHYSDRAM, R3                   /* pa */
        MOVW    $PADDR(L1+L1X(PHYSDRAM)), R4  /* address of PTE for PHYSDRAM */
        MOVW    $16, R5
_ptdbl:
        FILLPTE()
        SUB.S   $1, R5
        BNE     _ptdbl

        /*
         * back up and fill in PTEs for memory at KZERO
         * there is 1 bank of 512MB of SDRAM at PHYSDRAM
         */
        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 */
_ptekrw:                                        /* set PTEs for 512MiB */
        FILLPTE()
        SUB.S   $1, R5
        BNE     _ptekrw

        /*
         * back up and fill in PTE for MMIO
         */
        MOVW    $PTEIO, R2                      /* PTE bits */
        MOVW    $PHYSIO, R3
        MOVW    $PADDR(L1+L1X(VIRTIO)), R4      /* start with PTE for VIRTIO */
        FILLPTE()

        /* mmu.c sets up the vectors later */

        /*
         * set up a temporary stack; avoid data & bss segments
         */
        MOVW    $(PHYSDRAM | (400*1024*1024)), R13

PUTC('P')
        /* set the domain access control */
        MOVW    $Client, R0
        BL      dacput(SB)

        /* set the translation table base */
        MOVW    $PADDR(L1), R0
        BL      ttbput(SB)

        MOVW    $0, R0
        BL      pidput(SB)              /* paranoia */

        /* the little dance to turn the MMU & caches on */
PUTC('l')
        BL      cacheuwbinv(SB)
        BL      mmuinvalidate(SB)
        BL      mmuenable(SB)

PUTC('a')
        /* 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|(400*1024*1024)), R13

        /* can now execute arbitrary C code */

        BL      cacheuwbinv(SB)

PUTC('n')
        /* undo double map of 0, KZERO */
        MOVW    $PADDR(L1+L1X(0)), R4           /* address of PTE for 0 */
        MOVW    $0, R0
        MOVW    $16, R5
_ptudbl:
        MOVW    R0, (R4)
        ADD     $4, R4                          /* bump PTE address */
        ADD     $MiB, R0                        /* bump pa */
        SUB.S   $1, R5
        BNE     _ptudbl
        BARRIERS
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinvse
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
        BARRIERS

PUTC(' ')
        /* pass Mach to main and set up the stack */
        MOVW    $(MACHADDR), R0                 /* Mach */
        MOVW    R0, R13
        ADD     $(MACHSIZE), R13                /* stack pointer */
        SUB     $4, R13                         /* space for link register */
        BL      main(SB)                        /* void main(Mach*) */
        /* fall through */


/* not used */
TEXT _reset(SB), 1, $-4
        /* turn the caches off */
        MOVW    $(PsrDirq|PsrDfiq|PsrMsvc), R0
        MOVW    R0, CPSR
        BARRIERS
        BL      cacheuwbinv(SB)
        MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
        BIC     $(CpCwb|CpCicache|CpCdcache|CpCalign), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
        BARRIERS
PUTC('R')

        /* redo double map of 0, KZERO */
        MOVW    $(L1+L1X(0)), R4                /* address of PTE for 0 */
        MOVW    $PTEDRAM, R2                    /* PTE bits */
        MOVW    $0, R3
        MOVW    $16, R5
_ptrdbl:
        ORR     R3, R2, R1              /* first identity-map 0 to 0, etc. */
        MOVW    R1, (R4)
        ADD     $4, R4                          /* bump PTE address */
        ADD     $MiB, R3                        /* bump pa */
        SUB.S   $1, R5
        BNE     _ptrdbl

        BARRIERS
PUTC('e')
        MOVW    $0, R0
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinv
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
        BARRIERS

        /* back to 29- or 26-bit addressing, mainly for SB */
        MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
        BIC     $(CpCd32|CpCi32), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
        BARRIERS

        /* turn the MMU off */
        MOVW    $PHYSDRAM, R0
        BL      _r15warp(SB)
        BL      mmuinvalidate(SB)
        BL      mmudisable(SB)

PUTC('s')
        /* set new reset vector */
        MOVW    $0, R2
        MOVW    $0xe59ff018, R3                 /* MOVW 0x18(R15), R15 */
        MOVW    R3, (R2)
PUTC('e')

        MOVW    $PHYSBOOTROM, R3
        MOVW    R3, 0x20(R2)                    /* where $0xe59ff018 jumps to */
        BARRIERS
PUTC('t')
PUTC('\r')
PUTC('\n')

        /* ...and jump to it */
        MOVW    R2, R15                         /* software reboot */
_limbo:                                         /* should not get here... */
        B       _limbo                          /* ... and can't get out */
        BL      _div(SB)                        /* hack to load _div, etc. */

TEXT _r15warp(SB), 1, $-4
        BIC     $KSEGM, R14
        ORR     R0, R14
        BIC     $KSEGM, R13
        ORR     R0, R13
        RET

/* clobbers R1, R6 */
TEXT myputc(SB), 1, $-4
        MOVW    $PHYSCONS, R6
_busy:
        MOVW    20(R6), R1
        BIC.S   $~(1<<5), R1                    /* (x->lsr & LSRthre) == 0? */
        BEQ     _busy
        MOVW    R3, (R6)                        /* print */
        ISB
        RET

/*
 * l1 caches
 */

TEXT l1cacheson(SB), 1, $-4
        MOVW    CPSR, R5
        ORR     $(PsrDirq|PsrDfiq), R5, R4
        MOVW    R4, CPSR                        /* splhi */

        MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
        ORR     $(CpCdcache|CpCicache|CpCwb), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
        BARRIERS

        MOVW    R5, CPSR                        /* splx */
        RET

TEXT l1cachesoff(SB), 1, $-4
        MOVM.DB.W [R14], (SP)                   /* save lr on stack */

        MOVW    CPSR, R5
        ORR     $(PsrDirq|PsrDfiq), R5, R4
        MOVW    R4, CPSR                        /* splhi */

        BL      cacheuwbinv(SB)

        MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
        BIC     $(CpCdcache|CpCicache|CpCwb), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
        BARRIERS

        MOVW    R5, CPSR                        /* splx */
        MOVM.IA.W (SP), [R14]                   /* restore lr */
        RET

/*
 * cache* functions affect only the L1 caches, which are VIVT.
 */

TEXT cachedwb(SB), 1, $-4                       /* D writeback */
        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        BARRIERS                        /* force outstanding stores to cache */
        /* keep writing back dirty cache lines until no more exist */
_dwb:
        MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwb), CpCACHEtest
        BNE     _dwb
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT cachedwbse(SB), 1, $-4                     /* D writeback SE */
        MOVW    R0, R2                          /* first arg: address */

        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        BARRIERS                        /* force outstanding stores to cache */
        MOVW    4(FP), R1                       /* second arg: size */

//      CMP.S   $(4*1024), R1
//      BGT     _dwb
        ADD     R2, R1
        BIC     $(CACHELINESZ-1), R2
_dwbse:
        MCR     CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse
        ADD     $CACHELINESZ, R2
        CMP.S   R2, R1
        BGT     _dwbse
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT cachedwbinv(SB), 1, $-4                    /* D writeback+invalidate */
        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        BARRIERS                        /* force outstanding stores to cache */
        /* keep writing back dirty cache lines until no more exist */
_dwbinv:
        MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
        BNE     _dwbinv
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT cachedwbinvse(SB), 1, $-4                  /* D writeback+invalidate SE */
        MOVW    R0, R2                          /* first arg: address */

        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        BARRIERS                        /* force outstanding stores to cache */
        MOVW    4(FP), R1                       /* second arg: size */

        DSB
//      CMP.S   $(4*1024), R1
//      BGT     _dwbinv
        ADD     R2, R1
        BIC     $(CACHELINESZ-1), R2
_dwbinvse:
        MCR     CpSC, 0, R2, C(CpCACHE), C(CpCACHEwbi), CpCACHEse
        ADD     $CACHELINESZ, R2
        CMP.S   R2, R1
        BGT     _dwbinvse
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT cachedinvse(SB), 1, $-4                    /* D invalidate SE */
        MOVW    R0, R2                          /* first arg: address */

        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        MOVW    4(FP), R1                       /* second arg: size */

        DSB
//      CMP.S   $(4*1024), R1
//      BGT     _dinv
        ADD     R2, R1
        BIC     $(CACHELINESZ-1), R2
_dinvse:
        MCR     CpSC, 0, R2, C(CpCACHE), C(CpCACHEinvd), CpCACHEse
        ADD     $CACHELINESZ, R2
        CMP.S   R2, R1
        BGT     _dinvse
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT cacheuwbinv(SB), 1, $-4                    /* D+I writeback+invalidate */
        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        BARRIERS                        /* force outstanding stores to cache */
        /* keep writing back dirty cache lines until no more exist */
_uwbinv:                                        /* D writeback+invalidate */
        MRC     CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
        BNE     _uwbinv
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    $0, R0                          /* I invalidate */
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT cacheiinv(SB), 1, $-4                      /* I invalidate */
        BARRIERS
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS
        RET

TEXT cachedinv(SB), 1, $-4                      /* D invalidate */
_dinv:
        BARRIERS
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEall
        /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
        BARRIERS
        RET

/*
 * l2 cache
 *
 * these functions assume that the necessary l1 cache operations have been
 * or will be done explicitly by the caller.
 */

/* enable l2 cache in config coproc. reg.  do this while l1 caches are off. */
TEXT l2cachecfgon(SB), 1, $-4
        BARRIERS
        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
        BARRIERS

        MRC     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
        ORR     $(CpTCl2ena | CpTCl2prefdis), R1  /* l2 on, prefetch off */
        MCR     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
        BARRIERS
        RET

/* disable l2 cache in config coproc. reg.  do this while l1 caches are off. */
TEXT l2cachecfgoff(SB), 1, $-4
        BARRIERS
        MRC     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
        BIC     $CpTCl2ena, R1
        MCR     CpSC, CpL2, R1, C(CpTESTCFG), C(CpTCl2cfg), CpTCl2conf
        BARRIERS

        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
        BARRIERS
        RET

TEXT l2cacheuwb(SB), 1, $-4                     /* L2 unified writeback */
        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all
        ISB
        RET

TEXT l2cacheuwbse(SB), 1, $-4                   /* L2 unified writeback SE */
        MOVW    R0, R2                          /* first arg: address */

        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        MOVW    4(FP), R1                       /* second arg: size */

        ADD     R2, R1
        BIC     $(CACHELINESZ-1), R2
_l2wbse:
        MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2flush), CpTCl2seva
        ADD     $CACHELINESZ, R2
        CMP.S   R2, R1
        BGT     _l2wbse
        ISB

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT l2cacheuwbinv(SB), 1, $-4          /* L2 unified writeback+invalidate */
        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all
        ISB
        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
        ISB

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT l2cacheuwbinvse(SB), 1, $-4        /* L2 unified writeback+invalidate SE */
        MOVW    R0, R2                          /* first arg: address */

        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        MOVW    4(FP), R1                       /* second arg: size */

        ADD     R2, R1
        BIC     $(CACHELINESZ-1), R2
_l2wbinvse:
        MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2flush), CpTCl2seva
        ISB
        MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2inv), CpTCl2seva
        ADD     $CACHELINESZ, R2
        CMP.S   R2, R1
        BGT     _l2wbinvse
        ISB

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT l2cacheuinv(SB), 1, $-4                    /* L2 unified invalidate */
        MCR     CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
        ISB
        RET

TEXT l2cacheuinvse(SB), 1, $-4                  /* L2 unified invalidate SE */
        MOVW    R0, R2                          /* first arg: address */

        MOVW    CPSR, R3                        /* splhi */
        ORR     $(PsrDirq), R3, R1
        MOVW    R1, CPSR

        MOVW    4(FP), R1                       /* second arg: size */

        ADD     R2, R1
        BIC     $(CACHELINESZ-1), R2
_l2invse:
        MCR     CpSC, CpL2, R2, C(CpTESTCFG), C(CpTCl2inv), CpTCl2seva
        ADD     $CACHELINESZ, R2
        CMP.S   R2, R1
        BGT     _l2invse
        ISB

        MOVW    R3, CPSR                        /* splx */
        RET

/*
 *  enable mmu, i and d caches, and high vector
 */
TEXT mmuenable(SB), 1, $-4
        MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
        ORR     $(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb|CpCsystem), R0
        BIC     $(CpCrom), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
        BARRIERS
        RET

TEXT mmudisable(SB), 1, $-4
        MRC     CpSC, 0, R0, C(CpCONTROL), C(0)
        BIC     $(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0)
        BARRIERS
        RET

TEXT mmuinvalidate(SB), 1, $-4                  /* invalidate all */
        MOVW    $0, R0
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
        BARRIERS
        RET

TEXT mmuinvalidateaddr(SB), 1, $-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)
        RET

TEXT ttbget(SB), 1, $-4                         /* translation table base */
        MRC     CpSC, 0, R0, C(CpTTB), C(0)
        RET

TEXT ttbput(SB), 1, $-4                         /* translation table base */
        MCR     CpSC, 0, R0, C(CpTTB), C(0)
        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 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    $(MACHADDR+4), R2               /* save caller pc in Mach */
        MOVW    R14, 0(R2)

        MOVW    CPSR, R0                        /* turn off interrupts */
        ORR     $(PsrDirq), R0, R1
        MOVW    R1, CPSR
        RET

TEXT spllo(SB), 1, $-4
        MOVW    CPSR, R0
        BIC     $(PsrDirq), R0, R1
        MOVW    R1, CPSR
        RET

TEXT splx(SB), 1, $-4
        MOVW    $(MACHADDR+0x04), R2            /* save caller pc in Mach */
        MOVW    R14, 0(R2)

        MOVW    R0, R1                          /* reset interrupt level */
        MOVW    CPSR, R0
        MOVW    R1, CPSR
        RET

TEXT splxpc(SB), 1, $-4                         /* for iunlock */
        MOVW    R0, R1
        MOVW    CPSR, R0
        MOVW    R1, CPSR
        RET

TEXT spldone(SB), 1, $0
        RET

TEXT islo(SB), 1, $-4
        MOVW    CPSR, R0
        AND     $(PsrDirq), R0
        EOR     $(PsrDirq), R0
        RET

TEXT splfhi(SB), $-4
        MOVW    CPSR, R0
        ORR     $(PsrDfiq|PsrDirq), R0, R1
        MOVW    R1, CPSR
        RET

//TEXT splflo(SB), $-4
//      MOVW    CPSR, R0
//      BIC     $(PsrDfiq), R0, R1
//      MOVW    R1, CPSR
//      RET

TEXT    tas(SB), $-4
TEXT    _tas(SB), $-4
        MOVW    R0,R1
        MOVW    $1,R0
        SWPW    R0,(R1)                 /* fix: deprecated in armv7 */
        RET

//TEXT tas32(SB), 1, $-4
//      MOVW    R0, R1
//      MOVW    $0xDEADDEAD, R0
//      MOVW    R0, R3
//      SWPW    R0, (R1)
//      CMP.S   R0, R3
//      BEQ     _tasout
//      EOR     R3, R3                  /* R3 = 0 */
//      CMP.S   R0, R3
//      BEQ     _tasout
//      MOVW    $1, R15                 /* abort: lock != 0 && lock != $0xDEADDEAD */
//_tasout:
//      RET

TEXT clz(SB), 1, $-4
        CLZ(0, 0)                       /* 0 is R0 */
        RET

TEXT setlabel(SB), 1, $-4
        MOVW    R13, 0(R0)              /* sp */
        MOVW    R14, 4(R0)              /* pc */
        BARRIERS
        MOVW    $0, R0
        RET

TEXT gotolabel(SB), 1, $-4
        MOVW    0(R0), R13              /* sp */
        MOVW    4(R0), R14              /* pc */
        BARRIERS
        MOVW    $1, R0
        RET

TEXT getcallerpc(SB), 1, $-4
        MOVW    0(R13), R0
        RET

TEXT _idlehands(SB), 1, $-4
        MOVW    CPSR, R3
//      ORR     $PsrDirq, R3, R1                /* splhi */
        BIC     $PsrDirq, R3, R1                /* spllo */
        MOVW    R1, CPSR

        MOVW    $0, R0                          /* wait for interrupt */
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEintr), CpCACHEwait
        ISB

        MOVW    R3, CPSR                        /* splx */
        RET

TEXT barriers(SB), 1, $-4
        BARRIERS
        RET

Generated by GNU Enscript 1.6.6.