from richard all the little fiddly bits to get armv6/armv7 working for pi/pi2 CACHELINESZ has it's fingers in everything Reference: /n/atom/patch/applied/pivarmv7 Date: Sun Jan 3 07:18:39 CET 2016 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/bcm/arm.s Sun Jan 3 07:17:35 2016 +++ /sys/src/9/bcm/arm.s Sun Jan 3 07:17:36 2016 @@ -1,5 +1,5 @@ /* - * armv6 machine assist, definitions + * armv6/v7 machine assist, definitions * * loader uses R11 as scratch. */ @@ -29,8 +29,31 @@ #define MCRR(coproc, op, rd, rn, crm) \ WORD $(0xec400000|(rn)<<16|(rd)<<12|(coproc)<<8|(op)<<4|(crm)) +#define MRRC(coproc, op, rd, rn, crm) \ + WORD $(0xec500000|(rn)<<16|(rd)<<12|(coproc)<<8|(op)<<4|(crm)) + +#define LDREX(fp,t) WORD $(0xe<<28|0x01900f9f | (fp)<<16 | (t)<<12) +/* `The order of operands is from left to right in dataflow order' - asm man */ +#define STREX(f,tp,r) WORD $(0xe<<28|0x01800f90 | (tp)<<16 | (r)<<12 | (f)<<0) +#define CLREX WORD $0xf57ff01f + +#define CPSIE WORD $0xf1080080 /* intr enable: zeroes I bit */ +#define CPSID WORD $0xf10c0080 /* intr disable: sets I bit */ #define OKAY \ MOVW $0x7E200028,R2; \ MOVW $0x10000,R3; \ MOVW R3,(R2) + +#define PUTC(s) + +/* + * get cpu id, or zero if armv6 + */ +#define CPUID(r) \ + MRC CpSC, 0, r, C(CpID), C(CpIDfeat), 7; \ + CMP $0, r; \ + B.EQ 2(PC); \ + MRC CpSC, 0, r, C(CpID), C(CpIDidct), CpIDmpid; \ + AND.S $(MAXMACH-1), r + --- /sys/src/9/bcm/l.s Sun Jan 3 07:17:38 2016 +++ /sys/src/9/bcm/l.s Sun Jan 3 07:17:40 2016 @@ -1,10 +1,14 @@ /* - * Broadcom bcm2835 SoC, as used in Raspberry Pi - * arm1176jzf-s processor (armv6) + * Common startup for armv6 and armv7 + * The rest of l.s has been moved to armv[67].s */ #include "arm.s" +/* + * on bcm2836, only cpu0 starts here + * other cpus enter at cpureset in armv7.s + */ TEXT _start(SB), 1, $-4 /* * load physical base for SB addressing while mmu is off @@ -22,253 +26,14 @@ 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 + * do arch-dependent startup (no return) */ - MOVW $1, R1 - MCR CpSC, 0, R1, C(CpSPM), C(CpSPMperf), CpSPMctl - - /* - * call main and loop forever if it returns - */ - BL ,main(SB) + BL ,armstart(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 --- /sys/src/9/bcm/lexception.s Sun Jan 3 07:17:42 2016 +++ /sys/src/9/bcm/lexception.s Sun Jan 3 07:17:43 2016 @@ -34,7 +34,6 @@ MOVW.W R14, -4(R13) /* ... */ /* avoid the ambiguity described in notes/movm.w. */ -// MOVM.DB.W.S [R0-R14], (R13) /* save user level registers, at end r13 points to ureg */ MOVM.DB.S [R0-R14], (R13) /* save user level registers */ SUB $(15*4), R13 /* r13 now points to ureg */ @@ -109,7 +108,6 @@ * We'll assume that the old value of R13 should be stored on the stack. */ /* save kernel level registers, at end r13 points to ureg */ -// MOVM.DB.W [R0-R14], (R13) MOVM.DB [R0-R14], (R13) SUB $(15*4), R13 /* SP now points to saved R0 */ @@ -137,7 +135,6 @@ MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */ /* avoid the ambiguity described in notes/movm.w. */ -// MOVM.DB.W.S [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */ MOVM.DB.S [R0-R14], (R13) /* save kernel level registers */ SUB $(15*4), R13 /* r13 now points to ureg */ @@ -165,7 +162,8 @@ MOVW SPSR, R9 /* interrupted psr */ MOVW R14, R10 /* interrupted pc */ MOVM.DB.W [R8-R10], (R13) /* save in ureg */ - MOVM.DB.W.S [R0-R14], (R13) /* save interrupted regs */ + MOVM.DB.S [R0-R14], (R13) /* save interrupted regs */ + SUB $(15*4), R13 MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */ MOVW $(MACHADDR), R10 /* m */ MOVW 8(R10), R9 /* up */ @@ -181,7 +179,7 @@ MOVM.DB.S (R13), [R0-R14] /* restore registers */ ADD $8, R13 /* pop past ureg->{type+psr} */ RFE /* MOVM.IA.S.W (R13), [R15] */ - + /* * set the stack value for the mode passed in R0 */ --- /sys/src/9/bcm/armv6.s Thu Jan 1 00:00:00 1970 +++ /sys/src/9/bcm/armv6.s Sun Jan 3 07:17:44 2016 @@ -0,0 +1,277 @@ +/* + * Broadcom bcm2835 SoC, as used in Raspberry Pi + * arm1176jzf-s processor (armv6) + */ + +#include "arm.s" +#define CACHELINESZ 32 + +TEXT armstart(SB), 1, $-4 + + /* + * 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 + + /* ACT LED on */ + MOVW $0x20200014,R2 + MOVW (R2),R3 + AND $~(7<<21),R3 + ORR $(1<<21),R3 + MOVW R3,(R2) + MOVW $0x20200020,R2 + MOVW $0x8000,R3 + MOVW R3,(R2) + + /* + * 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 + +/* + * L2 cache is not enabled + */ +TEXT l2cacheuwbinv(SB), 1, $-4 + RET + +/* + * invalidate instruction cache + */ +TEXT cacheiinv(SB), 1, $-4 + MOVW $0, R0 + MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall + RET --- /sys/src/9/bcm/armv7.s Thu Jan 1 00:00:00 1970 +++ /sys/src/9/bcm/armv7.s Sun Jan 3 07:17:45 2016 @@ -0,0 +1,282 @@ +/* + * Broadcom bcm2836 SoC, as used in Raspberry Pi 2 + * 4 x Cortex-A7 processor (armv7) + */ + +#include "arm.s" +#define CACHELINESZ 64 + +TEXT armstart(SB), 1, $-4 + + /* + * disable the mmu and caches + * invalidate tlb + */ + MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl + BIC $(CpCdcache|CpCicache|CpCmmu), R1 + ORR $(CpCsbo|CpCsw), R1 + BIC $CpCsbz, R1 + MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl + 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) + MCR CpSC, 0, R0, C(CpTTB), C(0), CpTTB1 /* cortex has two */ + + /* + * enable caches, mmu, and high vectors + */ + MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl + ORR $CpACsmp, R1 /* turn SMP on */ + MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl + BARRIERS + + MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl + ORR $(CpChv|CpCdcache|CpCicache|CpCmmu), R0 + MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl + BARRIERS + + /* + * 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<<31), R1 + MCR CpSC, 0, R1, C(CpCLD), C(CpCLDena), CpCLDenacyc + MOVW $1, R1 + MCR CpSC, 0, R1, C(CpCLD), C(CpCLDena), CpCLDenapmnc + + /* + * call main and loop forever if it returns + */ + BL ,main(SB) + B ,0(PC) + + BL _div(SB) /* hack to load _div, etc. */ + +TEXT cpidget(SB), 1, $-4 /* main ID */ + MRC CpSC, 0, R0, C(CpID), C(0), CpIDid + RET + +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(CpCLD), C(CpCLDcyc), 0 + 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 + +/* + * `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 + + 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 + +#include "cache.v7.s" --- /sys/src/9/bcm/pisdalloc.c Sun Jan 3 07:17:47 2016 +++ /sys/src/9/bcm/pisdalloc.c Sun Jan 3 07:17:48 2016 @@ -8,7 +8,7 @@ void* sdmalloc(usize n) { - return mallocalign(n, CACHELINESZ, 0, 0); + return mallocalign(n, BLOCKALIGN, 0, 0); } void --- /sys/src/9/bcm/usbdwc.c Sun Jan 3 07:17:51 2016 +++ /sys/src/9/bcm/usbdwc.c Sun Jan 3 07:17:52 2016 @@ -61,7 +61,7 @@ static int debug; static char Ebadlen[] = "bad usb request length"; -static char Enotconfig[] = "usb endpoint not configured"; +static char Enotconf[] = "usb endpoint not configured"; static void clog(Ep *ep, Hostchan *hc); static void logdump(Ep *ep); @@ -347,7 +347,7 @@ else n = len; hc->hctsiz = n | npkt<hcdma = PADDR(a); + hc->hcdma = dmaaddr(a); nleft = len; logstart(ep); @@ -524,8 +524,8 @@ if(datalen <= 0 || datalen > Maxctllen) error(Ebadlen); /* XXX cache madness */ - epio->cb = b = allocb(ROUND(datalen, ep->maxpkt) + CACHELINESZ); - b->wp = (uchar*)ROUND((uintptr)b->wp, CACHELINESZ); + epio->cb = b = allocb(ROUND(datalen, ep->maxpkt) + BLOCKALIGN); + b->wp = (uchar*)ROUND((uintptr)b->wp, BLOCKALIGN); memset(b->wp, 0x55, b->lim - b->wp); cachedwbinvse(b->wp, b->lim - b->wp); data = b->wp; @@ -708,7 +708,7 @@ ep->dev->nb, ep->nb, ep->ttype); switch(ep->ttype){ case Tnone: - error(Enotconfig); + error(Enotconf); case Tintr: assert(ep->pollival > 0); /* fall through */ @@ -773,8 +773,8 @@ /* fall through */ case Tbulk: /* XXX cache madness */ - b = allocb(ROUND(n, ep->maxpkt) + CACHELINESZ); - p = (uchar*)ROUND((uintptr)b->base, CACHELINESZ); + b = allocb(ROUND(n, ep->maxpkt) + BLOCKALIGN); + p = (uchar*)ROUND((uintptr)b->base, BLOCKALIGN); cachedwbinvse(p, n); nr = eptrans(ep, Read, p, n); epio->lastpoll = TK2MS(m->ticks); @@ -815,8 +815,8 @@ case Tctl: case Tbulk: /* XXX cache madness */ - b = allocb(n + CACHELINESZ); - p = (uchar*)ROUND((uintptr)b->base, CACHELINESZ); + b = allocb(n + BLOCKALIGN); + p = (uchar*)ROUND((uintptr)b->base, BLOCKALIGN); memmove(p, a, n); cachedwbse(p, n); if(ep->ttype == Tctl) --- /sys/src/9/bcm/mem.h Sun Jan 3 07:17:54 2016 +++ /sys/src/9/bcm/mem.h Sun Jan 3 07:17:55 2016 @@ -6,6 +6,7 @@ #define GiB 1073741824u /* Gibi 000000000040000000 */ #define HOWMANY(x, y) (((x)+((y)-1))/(y)) +#define ROUND(a, b) ROUNDUP(a, b) #define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) /* ceiling */ #define ROUNDDN(x, y) (((x)/(y))*(y)) /* floor */ #define MIN(a, b) ((a) < (b)? (a): (b)) @@ -18,15 +19,21 @@ #define PGSHIFT 12 /* log(BY2PG) */ #define PGROUND(s) ROUNDUP(s, BY2PG) #define UTROUND(s) ROUNDUP(s, BY2PG) -#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1)) -#define MAXMACH 1 /* max # cpus system can run */ +#define MAXMACH 4 /* max # cpus system can run */ #define MACHSIZE BY2PG #define KSTKSIZE (8*KiB) #define STACKALIGN(sp) ((sp) & ~3) /* bug: assure with alloc */ /* + * Magic registers + */ + +#define USER 9 /* R9 is up-> */ +#define MACH 10 /* R10 is m-> */ + +/* * Address spaces. * KTZERO is used by kprof and dumpstack (if any). * @@ -37,8 +44,8 @@ */ #define KSEG0 0x80000000 /* kernel segment */ -/* mask to check segment; good for 512MB dram */ -#define KSEGM 0xE0000000 +/* mask to check segment; good for 1GB dram */ +#define KSEGM 0xC0000000 #define KZERO KSEG0 /* kernel address space */ #define CONFADDR (KZERO+0x100) /* unparsed plan9.ini */ #define MACHADDR (KZERO+0x2000) /* Mach structure */ @@ -48,7 +55,7 @@ #define L1 (KZERO+0x4000) /* tt ptes: 16KiB aligned */ #define KTZERO (KZERO+0x8000) /* kernel text start */ #define VIRTIO 0x7E000000 /* i/o registers */ -#define FRAMEBUFFER 0xA0000000 /* video framebuffer */ +#define FRAMEBUFFER 0xC0000000 /* video framebuffer */ #define UZERO 0 /* user segment */ #define UTZERO (UZERO+BY2PG) /* user text start */ @@ -63,7 +70,7 @@ /* * Legacy... */ -#define BLOCKALIGN 32 /* only used in allocb.c */ +#define BLOCKALIGN 64 /* should be CACHELINESZ */ #define KSTACK KSTKSIZE /* @@ -74,7 +81,6 @@ #define BY2WD 4 #define BY2V 8 /* only used in xalloc.c */ -#define CACHELINESZ 32 #define PTEMAPMEM (1024*1024) #define PTEPERTAB (PTEMAPMEM/BY2PG) #define SEGMAPSIZE 1984 @@ -96,8 +102,4 @@ * BUS addresses as seen from the videocore gpu. */ #define PHYSDRAM 0 -#define BUSDRAM 0x40000000 -#define DRAMSIZE (512*MiB) -#define PHYSIO 0x20000000 -#define BUSIO 0x7E000000 #define IOSIZE (16*MiB) --- /sys/src/9/bcm/pi Sun Jan 3 07:17:57 2016 +++ /sys/src/9/bcm/pi Sun Jan 3 07:17:58 2016 @@ -16,6 +16,9 @@ mouse mouse pckb latin1 uart +# spi spi +# gpio +# i2c fakertc sd pisdalloc @@ -49,6 +52,7 @@ uartmini + armv6 sdmmc emmc sdloop # sdaoe @@ -56,7 +60,6 @@ dma vcore vfp3 coproc -# softfpu port int cpuserver = 0; --- /sys/src/9/bcm/pi2 Thu Jan 1 00:00:00 1970 +++ /sys/src/9/bcm/pi2 Sun Jan 3 07:17:59 2016 @@ -0,0 +1,72 @@ +dev + root + cons + env + pipe + proc + mnt + srv + dup + arch + ssl + tls + cap + ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno + draw screen swcursor + mouse mouse + pckb latin1 + uart + + fakertc + sd pisdalloc + usb + ether netif + cec + +link + archbcm2 + loopbackmedium + ethermedium + usbdwc + etherusb + +ip + il + tcp + udp + ipifc + icmp + icmp6 + ipmux + +misc + physalloc + qmalloc + noswap + drawalloc + + allocb + + uartmini + + armv7 + sdmmc emmc + sdloop +# sdaoe + + dma + vcore + vfp3 coproc + +port + int cpuserver = 0; + +boot boot #S/sdM0/ + tcp + il + +bootdir + boot$CONF.out boot + /arm/bin/ip/ipconfig + /arm/bin/auth/factotum + /arm/bin/usb/usbd --- /sys/src/9/bcm/pi2cpu Thu Jan 1 00:00:00 1970 +++ /sys/src/9/bcm/pi2cpu Sun Jan 3 07:18:00 2016 @@ -0,0 +1,74 @@ +dev + root + cons + env + pipe + proc + mnt + srv + dup + arch + ssl + tls + cap + ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno + draw screen swcursor + mouse mouse + pckb latin1 + uart + + fakertc + sd pisdalloc + usb + ether netif + aoe + cec + +link + archbcm2 + loopbackmedium + ethermedium + usbdwc + etherusb + +ip + il + tcp + udp + ipifc + icmp + icmp6 + ipmux + +misc + physalloc + qmalloc + noswap + drawalloc + + allocb + + armv7 + uartmini + + sdmmc emmc + sdloop + sdaoe + + dma + vcore + vfp3 coproc + +port + int cpuserver = 1; + +boot cpu boot #S/sdM0/ + local + tcp + il + +bootdir + boot$CONF.out boot + /arm/bin/ip/ipconfig + /arm/bin/auth/factotum + /arm/bin/usb/usbd --- /sys/src/9/bcm/picpu Sun Jan 3 07:18:02 2016 +++ /sys/src/9/bcm/picpu Sun Jan 3 07:18:03 2016 @@ -22,6 +22,7 @@ usb ether netif aoe + snap cec link @@ -50,6 +51,7 @@ uartmini + armv6 sdmmc emmc sdloop sdaoe @@ -57,7 +59,6 @@ dma vcore vfp3 coproc -# softfpu port int cpuserver = 1; --- /sys/src/9/bcm/pifat Sun Jan 3 07:18:05 2016 +++ /sys/src/9/bcm/pifat Sun Jan 3 07:18:06 2016 @@ -44,10 +44,11 @@ xalloc uartmini + armv6 sdmmc emmc + sdloop dma -# vfp3 coproc - softfpu + vfp3 coproc port int cpuserver = 0; --- /sys/src/9/bcm/piq Sun Jan 3 07:18:08 2016 +++ /sys/src/9/bcm/piq Sun Jan 3 07:18:09 2016 @@ -14,8 +14,7 @@ ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno draw screen swcursor mouse mouse - kbmap - pckb latin1 + pckb latin1 uart fakertc @@ -49,8 +48,9 @@ uartmini + armv6 sdmmc emmc -# sdloop + sdloop # sdaoe dma