ref: daf153009e0db3c5fb39a7011f86526c7d863653
parent: d74fdfc022acde11b522fcc77beed10880784cbc
parent: b715c39bfa1e2169f450f719ba8a7643c7b39b68
author: cinap_lenrek <[email protected]>
date: Sun Oct 28 02:17:34 EDT 2018
merge
--- a/sys/src/9/bcm/archbcm2.c
+++ b/sys/src/9/bcm/archbcm2.c
@@ -237,7 +237,7 @@
mb->clr[cpu].doorbell = 1;
trapinit();
clockinit();
- mmuinit1();
+ mmuinit1(0);
timersinit();
cpuidprint();
archreset();
--- a/sys/src/9/bcm/arm.s
+++ b/sys/src/9/bcm/arm.s
@@ -40,8 +40,6 @@
MOVW $0x10000,R3; \
MOVW R3,(R2)
-#define PUTC(s)
-
/*
* get cpu id, or zero if armv6
*/
--- a/sys/src/9/bcm/armv7.s
+++ b/sys/src/9/bcm/armv7.s
@@ -46,17 +46,6 @@
BARRIERS
/*
- * 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
-
- /*
* turn SMP on
* invalidate tlb
*/
@@ -68,6 +57,17 @@
BARRIERS
/*
+ * 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
*/
@@ -96,7 +96,6 @@
/*
* 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
--- a/sys/src/9/bcm/cache.v7.s
+++ b/sys/src/9/bcm/cache.v7.s
@@ -132,17 +132,6 @@
MOVW.P 8(R13), R15
/*
- * these shift values are for the Cortex-A8 L1 cache (A=2, L=6) and
- * the Cortex-A8 L2 cache (A=3, L=6).
- * A = log2(# of ways), L = log2(bytes per cache line).
- * see armv7 arch ref p. 1403.
- */
-#define L1WAYSH 30
-#define L1SETSH 6
-#define L2WAYSH 29
-#define L2SETSH 6
-
-/*
* 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 (one-origin: 1 or 2).
@@ -184,11 +173,12 @@
ADD $1, R2 /* R2 (sets) = ((R0 >> 13) & MASK(15)) + 1 */
/* precompute set/way shifts for inner loop */
+ MOVW $6, R4
CMP $0, R8 /* cache == 1? */
- MOVW.EQ $L1WAYSH, R3 /* yes */
- MOVW.EQ $L1SETSH, R4
- MOVW.NE $L2WAYSH, R3 /* no */
- MOVW.NE $L2SETSH, R4
+ MOVW.EQ $30, R3 /* l1 */
+ MOVW.NE $29, R3 /* l2 */
+ CMP $16, R5 /* armv8 has 16-way l2, adjust shift */
+ MOVW.EQ $28, R3
/* iterate over ways */
MOVW $0, R7 /* R7: way */
--- a/sys/src/9/bcm/clock.c
+++ b/sys/src/9/bcm/clock.c
@@ -98,7 +98,7 @@
{
if(m->machno == 0)
panic("cpu0: Unexpected local generic timer interrupt");
- cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask|Enable);
+ cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask);
timerintr(ureg, 0);
}
@@ -109,10 +109,6 @@
tm = (Armtimer*)ARMTIMER;
tm->ctl = 0;
- if(cpuserver)
- wdogfeed();
- else
- wdogoff();
}
void
@@ -125,10 +121,11 @@
if(((cprdsc(0, CpID, CpIDfeat, 1) >> 16) & 0xF) != 0) {
/* generic timer supported */
if(m->machno == 0){
- *(ulong*)(ARMLOCAL + Localctl) = 0; /* input clock is 19.2Mhz crystal */
+ *(ulong*)(ARMLOCAL + Localctl) = 0; /* input clock is 19.2Mhz crystal */
*(ulong*)(ARMLOCAL + Prescaler) = 0x06aaaaab; /* divide by (2^31/Prescaler) for 1Mhz */
}
cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask);
+ intrenable(IRQcntpns, localclockintr, nil, 0, "clock");
}
tn = (Systimers*)SYSTIMERS;
@@ -150,8 +147,7 @@
tm->load = 0;
tm->ctl = TmrPrescale1|CntEnable|CntWidth32;
intrenable(IRQtimer3, clockintr, nil, 0, "clock");
- }else
- intrenable(IRQcntpns, localclockintr, nil, 0, "clock");
+ }
}
void
@@ -230,14 +226,10 @@
void
microdelay(int n)
{
- Systimers *tn;
- u32int now, diff;
+ ulong now;
- diff = n + 1;
- tn = (Systimers*)SYSTIMERS;
- now = tn->clo;
- while(tn->clo - now < diff)
- ;
+ now = µs();
+ while(µs() - now < n);
}
void
--- a/sys/src/9/bcm/fns.h
+++ b/sys/src/9/bcm/fns.h
@@ -66,7 +66,7 @@
extern void l2cacheuwbinv(void);
extern void links(void);
extern void mmuinit(void*);
-extern void mmuinit1(void);
+extern void mmuinit1(int);
extern void mmuinvalidate(void);
extern void mmuinvalidateaddr(u32int);
extern uintptr mmukmap(uintptr, uintptr, usize);
--- a/sys/src/9/bcm/main.c
+++ b/sys/src/9/bcm/main.c
@@ -19,7 +19,7 @@
* Where configuration info is left for the loaded programme.
*/
#define BOOTARGS ((char*)CONFADDR)
-#define BOOTARGSLEN (MACHADDR-CONFADDR)
+#define BOOTARGSLEN (REBOOTADDR-PADDR(CONFADDR))
#define MAXCONF 64
#define MAXCONFLINE 160
@@ -301,7 +301,7 @@
pageinit();
userinit();
launchinit();
- mmuinit1();
+ mmuinit1(0);
schedinit();
assert(0); /* shouldn't have returned */
}
@@ -550,6 +550,35 @@
}
+static void
+rebootjump(ulong entry, ulong code, ulong size)
+{
+ static void (*f)(ulong, ulong, ulong);
+ static Lock lk;
+
+ intrsoff();
+ intrcpushutdown();
+
+ /* redo identity map */
+ mmuinit1(1);
+
+ lock(&lk);
+ if(f == nil){
+ /* setup reboot trampoline function */
+ f = (void*)REBOOTADDR;
+ memmove(f, rebootcode, sizeof(rebootcode));
+ cachedwbse(f, sizeof(rebootcode));
+ }
+ unlock(&lk);
+
+ cacheuwbinv();
+ l2cacheuwbinv();
+
+ (*f)(entry, code, size);
+
+ for(;;);
+}
+
/*
* exit kernel either on a panic or user request
*/
@@ -558,14 +587,8 @@
{
cpushutdown();
splfhi();
- if(m->machno != 0){
- void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
- intrsoff();
- intrcpushutdown();
- cacheuwbinv();
- (*f)(0, 0, 0);
- for(;;);
- }
+ if(m->machno != 0)
+ rebootjump(0, 0, 0);
archreboot();
}
@@ -585,8 +608,6 @@
void
reboot(void *entry, void *code, ulong size)
{
- void (*f)(ulong, ulong, ulong);
-
writeconf();
if (m->machno != 0) {
procwired(up, 0);
@@ -593,13 +614,8 @@
sched();
}
- /* setup reboot trampoline function */
- f = (void*)REBOOTADDR;
- memmove(f, rebootcode, sizeof(rebootcode));
- cachedwbse(f, sizeof(rebootcode));
-
cpushutdown();
- delay(500);
+ delay(1000);
splfhi();
@@ -611,14 +627,10 @@
/* stop the clock (and watchdog if any) */
clockshutdown();
- intrsoff();
- intrcpushutdown();
+ wdogoff();
- cacheuwbinv();
- l2cacheuwbinv();
-
/* off we go - never to return */
- (*f)(PADDR(entry), PADDR(code), size);
+ rebootjump(PADDR(entry), PADDR(code), size);
}
void
--- a/sys/src/9/bcm/mem.h
+++ b/sys/src/9/bcm/mem.h
@@ -44,6 +44,7 @@
#define KSEGM 0xC0000000
#define KZERO KSEG0 /* kernel address space */
#define CONFADDR (KZERO+0x100) /* unparsed plan9.ini */
+#define REBOOTADDR (0x1c00) /* reboot code - physical address */
#define MACHADDR (KZERO+0x2000) /* Mach structure */
#define L2 (KZERO+0x3000) /* L2 ptes for vectors etc */
#define VCBUFFER (KZERO+0x3400) /* videocore mailbox buffer */
@@ -61,9 +62,6 @@
#define USTKSIZE (8*1024*1024) /* user stack size */
#define TSTKTOP (USTKTOP-USTKSIZE) /* sysexec temporary stack */
#define TSTKSIZ 256
-
-/* address at which to copy and execute rebootcode */
-#define REBOOTADDR (KZERO+0x1800)
/*
* Legacy...
--- a/sys/src/9/bcm/mkfile
+++ b/sys/src/9/bcm/mkfile
@@ -123,8 +123,8 @@
reboot.h:D: rebootcode.s arm.s arm.h mem.h
$AS rebootcode.s
- # -lc is only for memmove. -T arg is PADDR(REBOOTADDR)
- $LD -l -s -T0x1800 -R4 -o reboot.out rebootcode.$O -lc
+ # -lc is only for memmove. -T arg is REBOOTADDR
+ $LD -l -s -T0x1c00 -R4 -o reboot.out rebootcode.$O -lc
{echo 'uchar rebootcode[]={'
xd -1x reboot.out |
sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
--- a/sys/src/9/bcm/mmu.c
+++ b/sys/src/9/bcm/mmu.c
@@ -12,6 +12,7 @@
#define L2AP(ap) l2ap(ap)
#define L1ptedramattrs soc.l1ptedramattrs
#define L2ptedramattrs soc.l2ptedramattrs
+#define PTEDRAM (PHYSDRAM|Dom0|L1AP(Krw)|Section|L1ptedramattrs)
enum {
L1lo = UZERO/MiB, /* L1X(UZERO)? */
@@ -43,7 +44,7 @@
/*
* identity map first MB of ram so mmu can be enabled
*/
- l1[L1X(PHYSDRAM)] = PHYSDRAM|Dom0|L1AP(Krw)|Section|L1ptedramattrs;
+ l1[L1X(PHYSDRAM)] = PTEDRAM;
/*
* map i/o registers
@@ -65,19 +66,19 @@
l2[L2X(va)] = PHYSDRAM|L2AP(Krw)|Small|L2ptedramattrs;
}
+/*
+ * enable/disable identity map of first MB of ram
+ */
void
-mmuinit1()
+mmuinit1(int on)
{
PTE *l1;
l1 = m->mmul1;
-
- /*
- * undo identity map of first MB of ram
- */
- l1[L1X(PHYSDRAM)] = 0;
+ l1[L1X(PHYSDRAM)] = on? PTEDRAM: Fault;
cachedwbtlb(&l1[L1X(PHYSDRAM)], sizeof(PTE));
mmuinvalidateaddr(PHYSDRAM);
+ mmuinvalidate();
}
static void
--- a/sys/src/9/bcm/rebootcode.s
+++ b/sys/src/9/bcm/rebootcode.s
@@ -3,8 +3,6 @@
*/
#include "arm.s"
-#define PTEDRAM (Dom0|L1AP(Krw)|Section)
-
#define WFI WORD $0xe320f003 /* wait for interrupt */
#define WFE WORD $0xe320f002 /* wait for event */
@@ -26,9 +24,17 @@
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
MOVW R1, CPSR
- /* prepare to turn off mmu */
- BL cachesoff(SB)
+ /* turn caches off */
+ MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
+ BIC $(CpCdcache|CpCicache|CpCpredict), R1
+ MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
+ BARRIERS
+ /* invalidate icache */
+ MOVW $0, R0
+ MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
+ BARRIERS
+
/* turn off mmu */
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
BIC $CpCmmu, R1
@@ -49,7 +55,7 @@
MOVW $0x40000060, R1
ADD R2<<2, R1
MOVW 0(R1), R0
- AND $0x10, R0
+ AND $0x10, R0
BEQ dowfi
MOVW $0x8000, R1
BL (R1)
@@ -72,47 +78,3 @@
ORR R8,R8
B (R8)
B 0(PC)
-
-/*
- * turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert
- * to tiny addresses. upon return, it will be safe to turn off the mmu.
- * clobbers R0-R2, and returns with SP invalid.
- */
-TEXT cachesoff(SB), 1, $-4
- MOVM.DB.W [R14,R1-R10], (R13) /* save regs on stack */
-
- /* turn caches off, invalidate icache */
- MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
- BIC $(CpCdcache|CpCicache|CpCpredict), R1
- MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
- MOVW $0, R0
- MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
-
- /* invalidate stale TLBs before changing them */
- BARRIERS
- MOVW $0, R0
- MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
- BARRIERS
-
- /* redo double map of first MiB PHYSDRAM = KZERO */
- MOVW 12(R(MACH)), R2 /* m->mmul1 (virtual addr) */
- MOVW $PTEDRAM, R1 /* PTE bits */
- MOVW R1, (R2)
- DSB
- MCR CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse
-
- /* invalidate stale TLBs again */
- BARRIERS
- MOVW $0, R0
- MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
- BARRIERS
-
- /* relocate SB and return address to PHYSDRAM addressing */
- MOVW $KSEGM, R1 /* clear segment bits */
- BIC R1, R12 /* adjust SB */
- MOVM.IA.W (R13), [R14,R1-R10] /* restore regs from stack */
-
- MOVW $KSEGM, R1 /* clear segment bits */
- BIC R1, R14 /* adjust return address */
-
- RET
--- a/sys/src/9/port/devuart.c
+++ b/sys/src/9/port/devuart.c
@@ -318,9 +318,8 @@
static void
uartdrainoutput(Uart *p)
{
- if(!p->enabled)
+ if(!p->enabled || up == nil || !islo())
return;
-
p->drain = 1;
if(waserror()){
p->drain = 0;