shithub: riscv

Download patch

ref: daf153009e0db3c5fb39a7011f86526c7d863653
parent: d74fdfc022acde11b522fcc77beed10880784cbc
parent: b715c39bfa1e2169f450f719ba8a7643c7b39b68
author: cinap_lenrek <cinap_lenrek@felloff.net>
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;