Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Broadcom bcm2835 SoC, as used in Raspberry Pi
 * arm1176jzf-s processor (armv6)
 */

#include "arm.s"

TEXT _start(SB), 1, $-4
        /*
         * load physical base for SB addressing while mmu is off
         * keep a handy zero in R0 until first function call
         */
        MOVW    $setR12(SB), R12
        SUB     $KZERO, R12
        ADD     $PHYSDRAM, R12
        MOVW    $0, R0

        /*
         * SVC mode, interrupts disabled
         */
        MOVW    $(PsrDirq|PsrDfiq|PsrMsvc), R1
        MOVW    R1, CPSR

        /*
         * disable the mmu and L1 caches
         * invalidate caches and tlb
         */
        MRC     CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
        BIC     $(CpCdcache|CpCicache|CpCpredict|CpCmmu), R1
        MCR     CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvu), CpCACHEall
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
        ISB

        /*
         * clear mach and page tables
         */
        MOVW    $PADDR(MACHADDR), R1
        MOVW    $PADDR(KTZERO), R2
_ramZ:
        MOVW    R0, (R1)
        ADD     $4, R1
        CMP     R1, R2
        BNE     _ramZ

        /*
         * start stack at top of mach (physical addr)
         * set up page tables for kernel
         */
        MOVW    $PADDR(MACHADDR+MACHSIZE-4), R13
        BL      ,mmuinit(SB)

        /*
         * set up domain access control and page table base
         */
        MOVW    $Client, R1
        MCR     CpSC, 0, R1, C(CpDAC), C(0)
        MOVW    $PADDR(L1), R1
        MCR     CpSC, 0, R1, C(CpTTB), C(0)

        /*
         * enable caches, mmu, and high vectors
         */
        MRC     CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
        ORR     $(CpChv|CpCdcache|CpCicache|CpCmmu), R0
        MCR     CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
        ISB

        /*
         * switch SB, SP, and PC into KZERO space
         */
        MOVW    $setR12(SB), R12
        MOVW    $(MACHADDR+MACHSIZE-4), R13
        MOVW    $_startpg(SB), R15

TEXT _startpg(SB), 1, $-4

        /*
         * enable cycle counter
         */
        MOVW    $1, R1
        MCR     CpSC, 0, R1, C(CpSPM), C(CpSPMperf), CpSPMctl

        /*
         * call main and loop forever if it returns
         */
        BL      ,main(SB)
        B       ,0(PC)

        BL      _div(SB)                /* hack to load _div, etc. */

TEXT fsrget(SB), 1, $-4                         /* data fault status */
        MRC     CpSC, 0, R0, C(CpFSR), C(0), CpFSRdata
        RET

TEXT ifsrget(SB), 1, $-4                        /* instruction fault status */
        MRC     CpSC, 0, R0, C(CpFSR), C(0), CpFSRinst
        RET

TEXT farget(SB), 1, $-4                         /* fault address */
        MRC     CpSC, 0, R0, C(CpFAR), C(0x0)
        RET

TEXT lcycles(SB), 1, $-4
        MRC     CpSC, 0, R0, C(CpSPM), C(CpSPMperf), CpSPMcyc
        RET

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

        MOVW    CPSR, R0                        /* turn off irqs (but not fiqs) */
        ORR     $(PsrDirq), R0, R1
        MOVW    R1, CPSR
        RET

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

        MOVW    CPSR, R0                        /* turn off irqs and fiqs */
        ORR     $(PsrDirq|PsrDfiq), R0, R1
        MOVW    R1, CPSR
        RET

TEXT splflo(SB), 1, $-4
        MOVW    CPSR, R0                        /* turn on fiqs */
        BIC     $(PsrDfiq), R0, R1
        MOVW    R1, CPSR
        RET

TEXT spllo(SB), 1, $-4
        MOVW    CPSR, R0                        /* turn on irqs and fiqs */
        BIC     $(PsrDirq|PsrDfiq), 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 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 armv6 */
        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
        MOVW    CPSR, R3
        BIC     $(PsrDirq|PsrDfiq), 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 coherence(SB), $-4
        BARRIERS
        RET

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

/*
 * mmuinvalidateaddr(va)
 *   invalidate tlb entry for virtual page address va, ASID 0
 */
TEXT mmuinvalidateaddr(SB), 1, $-4
        MCR     CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinvse
        BARRIERS
        RET

/*
 * drain write buffer
 * writeback and invalidate data cache
 */
TEXT cachedwbinv(SB), 1, $-4
        DSB
        MOVW    $0, R0
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEall
        RET

/*
 * cachedwbinvse(va, n)
 *   drain write buffer
 *   writeback and invalidate data cache range [va, va+n)
 */
TEXT cachedwbinvse(SB), 1, $-4
        MOVW    R0, R1          /* DSB clears R0 */
        DSB
        MOVW    n+4(FP), R2
        ADD     R1, R2
        SUB     $1, R2
        BIC     $(CACHELINESZ-1), R1
        BIC     $(CACHELINESZ-1), R2
        MCRR(CpSC, 0, 2, 1, CpCACHERANGEdwbi)
        RET

/*
 * cachedwbse(va, n)
 *   drain write buffer
 *   writeback data cache range [va, va+n)
 */
TEXT cachedwbse(SB), 1, $-4
        MOVW    R0, R1          /* DSB clears R0 */
        DSB
        MOVW    n+4(FP), R2
        ADD     R1, R2
        BIC     $(CACHELINESZ-1), R1
        BIC     $(CACHELINESZ-1), R2
        MCRR(CpSC, 0, 2, 1, CpCACHERANGEdwb)
        RET

/*
 * drain write buffer and prefetch buffer
 * writeback and invalidate data cache
 * invalidate instruction cache
 */
TEXT cacheuwbinv(SB), 1, $-4
        BARRIERS
        MOVW    $0, R0
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEall
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
        RET

/*
 * invalidate instruction cache
 */
TEXT cacheiinv(SB), 1, $-4
        MOVW    $0, R0
        MCR     CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
        RET

Generated by GNU Enscript 1.6.6.