shithub: riscv

Download patch

ref: 8b1e81d71f4d898c97460578fe282f2ebeb5a1de
parent: abe9dad9530b68b427a706d6f4c3947dd5d9cc73
author: cinap_lenrek <[email protected]>
date: Sun Oct 29 12:36:51 EDT 2023

bcm64: use generic 9/arm64/* files

--- a/sys/src/9/bcm64/archbcm3.c
+++ b/sys/src/9/bcm64/archbcm3.c
@@ -9,7 +9,7 @@
 #include "fns.h"
 #include "../port/error.h"
 #include "io.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 
 typedef struct Mbox Mbox;
 typedef struct Mboxes Mboxes;
--- a/sys/src/9/bcm64/archbcm4.c
+++ b/sys/src/9/bcm64/archbcm4.c
@@ -10,7 +10,7 @@
 #include "../port/error.h"
 #include "io.h"
 #include "../port/pci.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 
 typedef struct Mbox Mbox;
 typedef struct Mboxes Mboxes;
--- a/sys/src/9/bcm64/cache.v8.s
+++ /dev/null
@@ -1,212 +1,0 @@
-#include "sysreg.h"
-
-#undef	SYSREG
-#define	SYSREG(op0,op1,Cn,Cm,op2)	SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
-
-/*
- * instruction cache operations
- */
-TEXT cacheiinvse(SB), 1, $-4
-	MOVWU	len+8(FP), R2
-	ADD	R0, R2
-
-	MRS	DAIF, R11
-	MSR	$0x2, DAIFSet
-	MOVWU	$1, R10
-	MSR	R10, CSSELR_EL1
-	ISB	$SY
-	MRS	CCSIDR_EL1, R4
-
-	ANDW	$7, R4
-	ADDW	$4, R4		// log2(linelen)
-	LSL	R4, R10
-	LSR	R4, R0
-	LSL	R4, R0
-
-_iinvse:
-	IC	R0, 3,7,5,1	// IVAU
-	ADD	R10, R0
-	CMP	R0, R2
-	BGT	_iinvse
-	DSB	$NSH
-	ISB	$SY
-	MSR	R11, DAIF
-	RETURN
-
-TEXT cacheiinv(SB), 1, $-4
-	IC	R0, 0,7,5,0	// IALLU
-	DSB	$NSH
-	ISB	$SY
-	RETURN
-
-TEXT cacheuwbinv(SB), 1, $0
-	BL	cachedwbinv(SB)
-	BL	cacheiinv(SB)
-	RETURN
-
-/*
- * data cache operations
- */
-TEXT cachedwbse(SB), 1, $-4
-	MOV	LR, R29
-	BL	cachedva<>(SB)
-TEXT dccvac(SB), 1, $-4
-	DC	R0, 3,7,10,1	// CVAC
-	RETURN
-
-TEXT cacheduwbse(SB), 1, $-4
-	MOV	LR, R29
-	BL	cachedva<>(SB)
-TEXT dccvau(SB), 1, $-4
-	DC	R0, 3,7,11,1	// CVAU
-	RETURN
-
-TEXT cachedinvse(SB), 1, $-4
-	MOV	LR, R29
-	BL	cachedva<>(SB)
-TEXT dcivac(SB), 1, $-4
-	DC	R0, 0,7,6,1	// IVAC
-	RETURN
-
-TEXT cachedwbinvse(SB), 1, $-4
-	MOV	LR, R29
-	BL	cachedva<>(SB)
-TEXT dccivac(SB), 1, $-4
-	DC	R0, 3,7,14,1	// CIVAC
-	RETURN
-
-TEXT cachedva<>(SB), 1, $-4
-	MOV	LR, R1
-	MOVWU	len+8(FP), R2
-	ADD	R0, R2
-
-	MRS	DAIF, R11
-	MSR	$0x2, DAIFSet
-	MOVWU	$0, R10
-	MSR	R10, CSSELR_EL1
-	ISB	$SY
-	MRS	CCSIDR_EL1, R4
-
-	ANDW	$7, R4
-	ADDW	$4, R4		// log2(linelen)
-	MOVWU	$1, R10
-	LSL	R4, R10
-	LSR	R4, R0
-	LSL	R4, R0
-
-	DSB	$SY
-	ISB	$SY
-_cachedva:
-	BL	(R1)
-	ADD	R10, R0
-	CMP	R0, R2
-	BGT	_cachedva
-	DSB	$SY
-	ISB	$SY
-	MSR	R11, DAIF
-	RET	R29
-
-/*
- * l1 cache operations
- */
-TEXT cachedwb(SB), 1, $-4
-	MOVWU	$0, R0
-_cachedwb:
-	MOV	LR, R29
-	BL	cachedsw<>(SB)
-TEXT dccsw(SB), 1, $-4
-	DC	R0, 0,7,10,2	// CSW
-	RETURN
-
-TEXT cachedinv(SB), 1, $-4
-	MOVWU	$0, R0
-_cachedinv:
-	MOV	LR, R29
-	BL	cachedsw<>(SB)
-TEXT dcisw(SB), 1, $-4
-	DC	R0, 0,7,6,2	// ISW
-	RETURN
-
-TEXT cachedwbinv(SB), 1, $-4
-	MOVWU	$0, R0
-_cachedwbinv:
-	MOV	LR, R29
-	BL	cachedsw<>(SB)
-TEXT dccisw(SB), 1, $-4
-	DC	R0, 0,7,14,2	// CISW
-	RETURN
-
-/*
- * l2 cache operations
- */
-TEXT l2cacheuwb(SB), 1, $-4
-	MOVWU	$1, R0
-	B	_cachedwb
-TEXT l2cacheuinv(SB), 1, $-4
-	MOVWU	$1, R0
-	B	_cachedinv
-TEXT l2cacheuwbinv(SB), 1, $-4
-	MOVWU	$1, R0
-	B	_cachedwbinv
-
-TEXT cachesize(SB), 1, $-4
-	MRS	DAIF, R11
-	MSR	$0x2, DAIFSet
-	MSR	R0, CSSELR_EL1
-	ISB	$SY
-	MRS	CCSIDR_EL1, R0
-	MSR	R11, DAIF
-	RETURN
-
-TEXT cachedsw<>(SB), 1, $-4
-	MOV	LR, R1
-
-	MRS	DAIF, R11
-	MSR	$0x2, DAIFSet
-	ADDW	R0, R0, R8
-	MSR	R8, CSSELR_EL1
-	ISB	$SY
-	MRS	CCSIDR_EL1, R4
-
-	LSR	$3, R4, R7
-	ANDW	$1023, R7	// lastway
-	ADDW	$1, R7, R5	// #ways
-
-	LSR	$13, R4, R2
-	ANDW	$32767, R2	// lastset
-	ADDW	$1, R2		// #sets
-
-	ANDW	$7, R4
-	ADDW	$4, R4		// log2(linelen)
-
-	MOVWU	$32, R3		// wayshift = 32 - log2(#ways)
-_countlog2ways:
-	CBZ	R7, _loop	// lastway == 0?
-	LSR	$1, R7		// lastway >>= 1
-	SUB	$1, R3		// wayshift--
-	B _countlog2ways
-_loop:
-	DSB	$SY
-	ISB	$SY
-_nextway:
-	MOVWU	$0, R6		// set
-_nextset:
-	LSL	R3, R7, R0	// way<<wayshift
-	LSL	R4, R6, R9	// set<<log2(linelen)
-	ORRW	R8, R0		// level
-	ORRW	R9, R0		// setway
-
-	BL	(R1)		// op(setway)
-
-	ADDW	$1, R6		// set++
-	CMPW	R2, R6
-	BLT	_nextset
-
-	ADDW	$1, R7		// way++
-	CMPW	R5, R7
-	BLT	_nextway
-
-	DSB	$SY
-	ISB	$SY
-	MSR	R11, DAIF
-	RET	R29
--- a/sys/src/9/bcm64/clock.c
+++ b/sys/src/9/bcm64/clock.c
@@ -19,7 +19,7 @@
 #include "fns.h"
 #include "io.h"
 #include "ureg.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 
 enum {
 	SYSTIMERS	= VIRTIO+0x3000,
--- a/sys/src/9/bcm64/fpu.c
+++ /dev/null
@@ -1,289 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-
-#include "ureg.h"
-#include "sysreg.h"
-
-/* libc */
-extern ulong getfcr(void);
-extern void setfcr(ulong fcr);
-extern ulong getfsr(void);
-extern void setfsr(ulong fsr);
-
-static FPsave fpsave0;
-
-static void
-fpsave(FPsave *p)
-{
-	p->control = getfcr();
-	p->status = getfsr();
-	fpsaveregs(p->regs);
-	fpoff();
-}
-
-static void
-fprestore(FPsave *p)
-{
-	fpon();
-	setfcr(p->control);
-	setfsr(p->status);
-	fploadregs(p->regs);
-}
-
-static void
-fpinit(void)
-{
-	fprestore(&fpsave0);
-}
-
-void
-fpuinit(void)
-{
-	m->fpstate = FPinit;
-	m->fpsave = nil;
-	fpoff();
-}
-
-static FPsave*
-fpalloc(void)
-{
-	FPsave *save;
-
-	while((save = mallocalign(sizeof(FPsave), 16, 0, 0)) == nil){
-		spllo();
-		resrcwait("no memory for FPsave");
-		splhi();
-	}
-	return save;
-}
-
-static void
-fpfree(FPsave *save)
-{
-	free(save);
-}
-
-
-/*
- *  Protect or save FPU state and setup new state
- *  (lazily in the case of user process) for the kernel.
- *  All syscalls, traps and interrupts (except mathtrap()!)
- *  are handled between fpukenter() and fpukexit(),
- *  so they can use floating point and vector instructions.
- */
-FPsave*
-fpukenter(Ureg*)
-{
-	if(up == nil){
-		switch(m->fpstate){
-		case FPactive:
-			fpsave(m->fpsave);
-			/* wet floor */
-		case FPinactive:
-			m->fpstate = FPinit;
-			return m->fpsave;
-		}
-		return nil;
-	}
-
-	switch(up->fpstate){
-	case FPactive:
-		up->fpstate = FPprotected;
-		fpoff();
-		/* wet floor */
-	case FPprotected:
-		return nil;
-	}
-
-	switch(up->kfpstate){
-	case FPactive:
-		fpsave(up->kfpsave);
-		/* wet floor */
-	case FPinactive:
-		up->kfpstate = FPinit;
-		return up->kfpsave;
-	}
-	return nil;
-}
-
-void
-fpukexit(Ureg *ureg, FPsave *save)
-{
-	if(up == nil){
-		switch(m->fpstate){
-		case FPactive:
-			fpoff();
-			/* wet floor */
-		case FPinactive:
-			fpfree(m->fpsave);
-			m->fpstate = FPinit;
-		}
-		m->fpsave = save;
-		if(save != nil)
-			m->fpstate = FPinactive;
-		return;
-	}
-
-	if(up->fpstate == FPprotected){
-		if(userureg(ureg)){
-			up->fpstate = FPactive;
-			fpon();
-		}
-		return;
-	}
-
-	switch(up->kfpstate){
-	case FPactive:
-		fpoff();
-		/* wet floor */
-	case FPinactive:
-		fpfree(up->kfpsave);
-		up->kfpstate = FPinit;
-	}
-	up->kfpsave = save;
-	if(save != nil)
-		up->kfpstate = FPinactive;
-}
-
-void
-fpuprocsetup(Proc *p)
-{
-	p->fpstate = FPinit;
-}
-
-void
-fpuprocfork(Proc *p)
-{
-	int s;
-
-	s = splhi();
-	switch(up->fpstate & ~FPillegal){
-	case FPprotected:
-		fpon();
-		/* wet floor */
-	case FPactive:
-		fpsave(up->fpsave);
-		up->fpstate = FPinactive;
-		/* wet floor */
-	case FPinactive:
-		if(p->fpsave == nil)
-			p->fpsave = fpalloc();
-		memmove(p->fpsave, up->fpsave, sizeof(FPsave));
-		p->fpstate = FPinactive;
-	}
-	splx(s);
-}
-
-void
-fpuprocsave(Proc *p)
-{
-	if(p->state == Moribund){
-		if(p->fpstate == FPactive || p->kfpstate == FPactive)
-			fpoff();
-		fpfree(p->fpsave);
-		fpfree(p->kfpsave);
-		p->fpsave = p->kfpsave = nil;
-		p->fpstate = p->kfpstate = FPinit;
-		return;
-	}
-	if(p->kfpstate == FPactive){
-		fpsave(p->kfpsave);
-		p->kfpstate = FPinactive;
-		return;
-	}
-	if(p->fpstate == FPprotected)
-		fpon();
-	else if(p->fpstate != FPactive)
-		return;
-	fpsave(p->fpsave);
-	p->fpstate = FPinactive;
-}
-
-void
-fpuprocrestore(Proc*)
-{
-	/*
-	 * when the scheduler switches,
-	 * we can discard its fp state.
-	 */
-	switch(m->fpstate){
-	case FPactive:
-		fpoff();
-		/* wet floor */
-	case FPinactive:
-		fpfree(m->fpsave);
-		m->fpsave = nil;
-		m->fpstate = FPinit;
-	}
-}
-
-void
-mathtrap(Ureg *ureg)
-{
-	if(!userureg(ureg)){
-		if(up == nil){
-			switch(m->fpstate){
-			case FPinit:
-				m->fpsave = fpalloc();
-				m->fpstate = FPactive;
-				fpinit();
-				break;
-			case FPinactive:
-				fprestore(m->fpsave);
-				m->fpstate = FPactive;
-				break;
-			default:
-				panic("floating point error in irq");
-			}
-			return;
-		}
-
-		if(up->fpstate == FPprotected){
-			fpon();
-			fpsave(up->fpsave);
-			up->fpstate = FPinactive;
-		}
-
-		switch(up->kfpstate){
-		case FPinit:
-			up->kfpsave = fpalloc();
-			up->kfpstate = FPactive;
-			fpinit();
-			break;
-		case FPinactive:
-			fprestore(up->kfpsave);
-			up->kfpstate = FPactive;
-			break;
-		default:
-			panic("floating point error in trap");
-		}
-		return;
-	}
-
-	if(up->fpstate & FPillegal){
-		postnote(up, 1, "sys: floating point in note handler", NDebug);
-		return;
-	}
-	switch(up->fpstate){
-	case FPinit:
-		if(up->fpsave == nil)
-			up->fpsave = fpalloc();
-		up->fpstate = FPactive;
-		fpinit();
-		break;
-	case FPinactive:
-		fprestore(up->fpsave);
-		up->fpstate = FPactive;
-		break;
-	case FPprotected:
-		up->fpstate = FPactive;
-		fpon();
-		break;
-	case FPactive:
-		postnote(up, 1, "sys: floating point error", NDebug);
-		break;
-	}
-}
--- a/sys/src/9/bcm64/gic.c
+++ b/sys/src/9/bcm64/gic.c
@@ -6,7 +6,7 @@
 #include "io.h"
 #include "../port/pci.h"
 #include "ureg.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 #include "../port/error.h"
 
 enum {
--- a/sys/src/9/bcm64/init9.s
+++ /dev/null
@@ -1,4 +1,0 @@
-TEXT main(SB), 1, $8
-	MOV	$setSB(SB), R28		/* load the SB */
-	MOV	$boot(SB), R0
-	B	startboot(SB)
--- a/sys/src/9/bcm64/l.s
+++ b/sys/src/9/bcm64/l.s
@@ -1,5 +1,5 @@
 #include "mem.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 
 #undef	SYSREG
 #define	SYSREG(op0,op1,Cn,Cm,op2)	SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
--- a/sys/src/9/bcm64/main.c
+++ b/sys/src/9/bcm64/main.c
@@ -6,7 +6,7 @@
 #include "fns.h"
 #include "../port/error.h"
 #include "io.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 #include "rebootcode.i"
 
 #include <pool.h>
--- a/sys/src/9/bcm64/mkfile
+++ b/sys/src/9/bcm64/mkfile
@@ -88,8 +88,16 @@
 /$objtype/$p$CONF:D: $p$CONF s$p$CONF
 	cp -x $p$CONF s$p$CONF /$objtype/
 
+ARM64FILES=`{../port/mkfilelist ../arm64}
+^($ARM64FILES)\.$O:R:	'../arm64/\1.c'
+	$CC $CFLAGS -I. -. ../arm64/$stem1.c
 
-REPCC=`{../port/mkfilelist ../bcm}
+cache.v8.$O:	../arm64/cache.v8.s
+	$AS $AFLAGS -I. -. ../arm64/cache.v8.s
+init9.$O:	../arm64/init9.s
+	$AS $AFLAGS -I. -. ../arm64/init9.s
+
+REPCC=`{../port/mkfilelist ../bcm | sed 's/(fpu|trap)[|)]//g'}
 ^($REPCC)\.$O:R:	'../bcm/\1.c'
 	$CC $CFLAGS -I. -. ../bcm/$stem1.c
 
@@ -101,7 +109,7 @@
 	/$objtype/include/ureg.h
 trap.$O main.$O: /sys/include/tos.h
 l.$O cache.v8.$O mmu.$O rebootcode.$O: mem.h
-l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O mmu.$O rebootcode.$O: sysreg.h
+l.$O cache.v8.$O archbcm3.$O clock.$O fpu.$O trap.$O mmu.$O rebootcode.$O: ../arm64/sysreg.h
 main.$O: rebootcode.i
 pcibcm.$O: ../port/pci.h
 
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -3,7 +3,7 @@
 #include "mem.h"
 #include "dat.h"
 #include "fns.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 
 #define INITMAP	(ROUND((uintptr)end + BY2PG, PGLSZ(1))-KZERO)
 
--- a/sys/src/9/bcm64/rebootcode.s
+++ b/sys/src/9/bcm64/rebootcode.s
@@ -1,5 +1,5 @@
 #include "mem.h"
-#include "sysreg.h"
+#include "../arm64/sysreg.h"
 
 #undef	SYSREG
 #define	SYSREG(op0,op1,Cn,Cm,op2)	SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
--- a/sys/src/9/bcm64/sysreg.h
+++ /dev/null
@@ -1,66 +1,0 @@
-#define MIDR_EL1			SYSREG(3,0,0,0,0)
-#define MPIDR_EL1			SYSREG(3,0,0,0,5)
-#define ID_AA64AFR0_EL1			SYSREG(3,0,0,5,4)
-#define ID_AA64AFR1_EL1			SYSREG(3,0,0,5,5)
-#define ID_AA64DFR0_EL1			SYSREG(3,0,0,5,0)
-#define ID_AA64DFR1_EL1			SYSREG(3,0,0,5,1)
-#define ID_AA64ISAR0_EL1		SYSREG(3,0,0,6,0)
-#define ID_AA64ISAR1_EL1		SYSREG(3,0,0,6,1)
-#define ID_AA64MMFR0_EL1		SYSREG(3,0,0,7,0)
-#define ID_AA64MMFR1_EL1		SYSREG(3,0,0,7,1)
-#define ID_AA64PFR0_EL1			SYSREG(3,0,0,4,0)
-#define ID_AA64PFR1_EL1			SYSREG(3,0,0,4,1)
-#define SCTLR_EL1			SYSREG(3,0,1,0,0)
-#define CPACR_EL1			SYSREG(3,0,1,0,2)
-#define MAIR_EL1			SYSREG(3,0,10,2,0)
-#define TCR_EL1				SYSREG(3,0,2,0,2)
-#define TTBR0_EL1			SYSREG(3,0,2,0,0)
-#define TTBR1_EL1			SYSREG(3,0,2,0,1)
-#define ESR_EL1				SYSREG(3,0,5,2,0)
-#define FAR_EL1				SYSREG(3,0,6,0,0)
-#define VBAR_EL1			SYSREG(3,0,12,0,0)
-#define VTTBR_EL2			SYSREG(3,4,2,1,0)
-#define SP_EL0				SYSREG(3,0,4,1,0)
-#define SP_EL1				SYSREG(3,4,4,1,0)
-#define SP_EL2				SYSREG(3,6,4,1,0)
-#define SCTLR_EL2			SYSREG(3,4,1,0,0)
-#define HCR_EL2				SYSREG(3,4,1,1,0)
-#define MDCR_EL2			SYSREG(3,4,1,1,1)
-#define PMCR_EL0			SYSREG(3,3,9,12,0)
-#define PMCNTENSET			SYSREG(3,3,9,12,1)
-#define PMCCNTR_EL0			SYSREG(3,3,9,13,0)
-#define PMUSERENR_EL0			SYSREG(3,3,9,14,0)
-
-#define CNTPCT_EL0			SYSREG(3,3,14,0,1)
-#define CNTVCT_EL0			SYSREG(3,3,14,0,2)
-#define CNTKCTL_EL1			SYSREG(3,0,14,1,0)
-#define CNTP_TVAL_EL0			SYSREG(3,3,14,2,0)
-#define CNTP_CTL_EL0			SYSREG(3,3,14,2,1)
-#define CNTP_CVAL_EL0			SYSREG(3,3,14,2,2)
-
-#define TPIDR_EL0			SYSREG(3,3,13,0,2)
-#define TPIDR_EL1			SYSREG(3,0,13,0,4)
-
-#define CCSIDR_EL1			SYSREG(3,1,0,0,0)
-#define CSSELR_EL1			SYSREG(3,2,0,0,0)
-
-#define ACTLR_EL2			SYSREG(3,4,1,0,1)
-#define CPUACTLR_EL1			SYSREG(3,1,15,2,0)
-#define CPUECTLR_EL1			SYSREG(3,1,15,2,1)
-#define CBAR_EL1			SYSREG(3,1,15,3,0)
-
-/* l.s redefines this for the assembler */
-#define SYSREG(op0,op1,Cn,Cm,op2)	((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)
-
-#define	OSHLD	(0<<2 | 1)
-#define OSHST	(0<<2 | 2)
-#define	OSH	(0<<2 | 3)
-#define NSHLD	(1<<2 | 1)
-#define NSHST	(1<<2 | 2)
-#define NSH	(1<<2 | 3)
-#define ISHLD	(2<<2 | 1)
-#define ISHST	(2<<2 | 2)
-#define ISH	(2<<2 | 3)
-#define LD	(3<<2 | 1)
-#define ST	(3<<2 | 2)
-#define SY	(3<<2 | 3)
--- a/sys/src/9/bcm64/trap.c
+++ /dev/null
@@ -1,688 +1,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "../port/error.h"
-#include "../port/systab.h"
-
-#include <tos.h>
-#include "ureg.h"
-#include "sysreg.h"
-
-int	(*buserror)(Ureg*);
-
-/* SPSR bits user can modify */
-#define USPSRMASK	(0xFULL<<28)
-
-static void
-setupvector(u32int *v, void (*t)(void), void (*f)(void))
-{
-	int i;
-
-	for(i = 0; i < 0x80/4; i++){
-		v[i] = ((u32int*)t)[i];
-		if(v[i] == 0x14000000){
-			v[i] |= ((u32int*)f - &v[i]) & 0x3ffffff;
-			return;
-		}
-	}
-	panic("bug in vector code");
-}
-
-void
-trapinit(void)
-{
-	extern void vsys(void);
-	extern void vtrap(void);
-	extern void virq(void);
-	extern void vfiq(void);
-	extern void vserr(void);
-
-	extern void vsys0(void);
-	extern void vtrap0(void);
-	extern void vtrap1(void);
-
-	static u32int *v;
-
-	intrcpushutdown();
-	if(v == nil){
-		/* disable everything */
-		intrsoff();
-
-		v = mallocalign(0x80*4*4, 1<<11, 0, 0);
-		if(v == nil)
-			panic("no memory for vector table");
-
-		setupvector(&v[0x000/4], vtrap,	vtrap0);
-		setupvector(&v[0x080/4], virq,	vtrap0);
-		setupvector(&v[0x100/4], vfiq,	vtrap0);
-		setupvector(&v[0x180/4], vserr,	vtrap0);
-
-		setupvector(&v[0x200/4], vtrap,	vtrap1);
-		setupvector(&v[0x280/4], virq,	vtrap1);
-		setupvector(&v[0x300/4], vfiq,	vtrap1);
-		setupvector(&v[0x380/4], vserr,	vtrap1);
-
-		setupvector(&v[0x400/4], vsys,	vsys0);
-		setupvector(&v[0x480/4], virq,	vtrap0);
-		setupvector(&v[0x500/4], vfiq,	vtrap0);
-		setupvector(&v[0x580/4], vserr, vtrap0);
-
-		setupvector(&v[0x600/4], vtrap,	vtrap0);
-		setupvector(&v[0x680/4], virq,	vtrap0);
-		setupvector(&v[0x700/4], vfiq,	vtrap0);
-		setupvector(&v[0x780/4], vserr,	vtrap0);
-
-		cacheduwbse(v, 0x80*4*4);
-	}
-	cacheiinvse(v, 0x80*4*4);
-	syswr(VBAR_EL1, (uintptr)v);
-	splx(0x3<<6);	// unmask serr and debug
-}
-
-static char *traps[64] = {
-	[0x00]	"sys: trap: unknown",
-	[0x01]	"sys: trap: WFI or WFE instruction execution",
-	[0x0E]	"sys: trap: illegal execution state",
-	[0x18]	"sys: trap: illegal MSR/MRS access",
-	[0x22]	"sys: trap: misaligned pc",
-	[0x26]	"sys: trap: stack pointer misaligned",
-	[0x30]	"sys: breakpoint",
-	[0x32]	"sys: software step",
-	[0x34]	"sys: watchpoint",
-	[0x3C]	"sys: breakpoint",
-};
-
-void
-trap(Ureg *ureg)
-{
-	FPsave *f = nil;
-	u32int type, intr;
-	int user;
-
-	intr = ureg->type >> 32;
-	if(intr == 2){
-		fiq(ureg);
-		return;
-	}
-	splflo();
-	user = kenter(ureg);
-	type = (u32int)ureg->type >> 26;
-	switch(type){
-	case 0x20:	// instruction abort from lower level
-	case 0x21:	// instruction abort from same level
-	case 0x24:	// data abort from lower level
-	case 0x25:	// data abort from same level
-		f = fpukenter(ureg);
-		faultarm64(ureg);
-		break;
-	case 0x07:	// SIMD/FP
-	case 0x2C:	// FPU exception (A64 only)
-		mathtrap(ureg);
-		break;
-	case 0x00:	// unknown
-		if(intr == 1){
-			f = fpukenter(ureg);
-			if(!irq(ureg))
-				preempted();
-			else if(up != nil && up->delaysched)
-				sched();
-			break;
-		}
-		if(intr == 3){
-	case 0x2F:	// SError interrupt
-			f = fpukenter(ureg);
-			if(buserror != nil && (*buserror)(ureg))
-				break;
-			dumpregs(ureg);
-			panic("SError interrupt");
-			break;
-		}
-		/* wet floor */
-	case 0x01:	// WFI or WFE instruction execution
-	case 0x03:	// MCR or MRC access to CP15 (A32 only)
-	case 0x04:	// MCRR or MRC access to CP15 (A32 only)
-	case 0x05:	// MCR or MRC access to CP14 (A32 only)
-	case 0x06:	// LDC or STD access to CP14 (A32 only)
-	case 0x08:	// MCR or MRC to CP10 (A32 only)
-	case 0x0C:	// MRC access to CP14 (A32 only)
-	case 0x0E:	// Illegal Execution State
-	case 0x11:	// SVC instruction execution (A32 only)
-	case 0x12:	// HVC instruction execution (A32 only)
-	case 0x13:	// SMC instruction execution (A32 only)
-	case 0x15:	// SVC instruction execution (A64 only)
-	case 0x16:	// HVC instruction execution (A64 only)
-	case 0x17:	// SMC instruction execution (A64 only)
-	case 0x18:	// MSR/MRS (A64)
-	case 0x22:	// misaligned pc
-	case 0x26:	// stack pointer misaligned
-	case 0x28:	// FPU exception (A32 only)
-	case 0x30:	// breakpoint from lower level
-	case 0x31:	// breakpoint from same level
-	case 0x32:	// software step from lower level
-	case 0x33:	// software step from same level
-	case 0x34:	// watchpoint execution from lower level
-	case 0x35:	// watchpoint exception from same level
-	case 0x38:	// breapoint (A32 only)
-	case 0x3A:	// vector catch exception (A32 only)
-	case 0x3C:	// BRK instruction (A64 only)
-	default:
-		f = fpukenter(ureg);
-		if(!userureg(ureg)){
-			dumpregs(ureg);
-			panic("unhandled trap");
-		}
-		if(traps[type] == nil) type = 0;	// unknown
-		postnote(up, 1, traps[type], NDebug);
-		break;
-	}
-
-	splhi();
-	if(user){
-		if(up->procctl || up->nnote)
-			notify(ureg);
-		kexit(ureg);
-	}
-	if(type != 0x07 && type != 0x2C)
-		fpukexit(ureg, f);
-}
-
-void
-syscall(Ureg *ureg)
-{
-	vlong startns, stopns;
-	uintptr sp, ret;
-	ulong scallnr;
-	int i, s;
-	char *e;
-
-	if(!kenter(ureg))
-		panic("syscall from  kernel");
-	fpukenter(ureg);
-	
-	m->syscall++;
-	up->insyscall = 1;
-	up->pc = ureg->pc;
-	
-	sp = ureg->sp;
-	up->scallnr = scallnr = ureg->r0;
-	spllo();
-	
-	up->nerrlab = 0;
-	startns = 0;
-	ret = -1;
-	if(!waserror()){
-		if(sp < USTKTOP - BY2PG || sp > USTKTOP - sizeof(Sargs) - BY2WD){
-			validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-			evenaddr(sp);
-		}
-		up->s = *((Sargs*) (sp + BY2WD));
-
-		if(up->procctl == Proc_tracesyscall){
-			syscallfmt(scallnr, ureg->pc, (va_list) up->s.args);
-			s = splhi();
-			up->procctl = Proc_stopme;
-			procctl();
-			splx(s);
-			startns = todget(nil);
-		}
-		
-		if(scallnr >= nsyscall || systab[scallnr] == nil){
-			pprint("bad sys call number %lud pc %#p", scallnr, ureg->pc);
-			postnote(up, 1, "sys: bad sys call", NDebug);
-			error(Ebadarg);
-		}
-		up->psstate = sysctab[scallnr];
-		ret = systab[scallnr]((va_list)up->s.args);
-		poperror();
-	}else{
-		e = up->syserrstr;
-		up->syserrstr = up->errstr;
-		up->errstr = e;
-	}
-	if(up->nerrlab){
-		print("bad errstack [%lud]: %d extra\n", scallnr, up->nerrlab);
-		for(i = 0; i < NERR; i++)
-			print("sp=%#p pc=%#p\n", up->errlab[i].sp, up->errlab[i].pc);
-		panic("error stack");
-	}
-	ureg->r0 = ret;
-	if(up->procctl == Proc_tracesyscall){
-		stopns = todget(nil);
-		sysretfmt(scallnr, (va_list) up->s.args, ret, startns, stopns);
-		s = splhi();
-		up->procctl = Proc_stopme;
-		procctl();
-		splx(s);
-	}
-	up->insyscall = 0;
-	up->psstate = 0;
-
-	if(scallnr == NOTED){
-		noted(ureg, *((ulong*) up->s.args));
-		/*
-		 * normally, syscall() returns to forkret()
-		 * not restoring general registers when going
-		 * to userspace. to completely restore the
-		 * interrupted context, we have to return thru
-		 * noteret(). we override return pc to jump to
-		 * to it when returning form syscall()
-		 */
-		returnto(noteret);
-
-		splhi();
-		up->fpstate &= ~FPillegal;
-	}
-	else
-		splhi();
-
-	if(scallnr != RFORK && (up->procctl || up->nnote))
-		notify(ureg);
-
-	if(up->delaysched){
-		sched();
-		splhi();
-	}
-
-	kexit(ureg);
-	fpukexit(ureg, nil);
-}
-
-int
-notify(Ureg *ureg)
-{
-	uintptr sp;
-	char *msg;
-
-	if(up->procctl)
-		procctl();
-	if(up->nnote == 0)
-		return 0;
-
-	spllo();
-	qlock(&up->debug);
-	msg = popnote(ureg);
-	if(msg == nil){
-		qunlock(&up->debug);
-		splhi();
-		return 0;
-	}
-
-	sp = ureg->sp;
-	sp -= 256;	/* debugging: preserve context causing problem */
-	sp -= sizeof(Ureg);
-	sp = STACKALIGN(sp);
-
-	if(!okaddr((uintptr)up->notify, 1, 0)
-	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
-	|| ((uintptr) up->notify & 3) != 0
-	|| (sp & 7) != 0){
-		qunlock(&up->debug);
-		pprint("suicide: bad address in notify: handler=%#p sp=%#p\n",
-			up->notify, sp);
-		pexit("Suicide", 0);
-	}
-
-	memmove((Ureg*)sp, ureg, sizeof(Ureg));
-	*(Ureg**)(sp-BY2WD) = up->ureg;	/* word under Ureg is old up->ureg */
-	up->ureg = (void*)sp;
-	sp -= BY2WD+ERRMAX;
-	memmove((char*)sp, msg, ERRMAX);
-	sp -= 3*BY2WD;
-	*(uintptr*)(sp+2*BY2WD) = sp+3*BY2WD;
-	*(uintptr*)(sp+1*BY2WD) = (uintptr)up->ureg;
-	ureg->r0 = (uintptr) up->ureg;
-	ureg->sp = sp;
-	ureg->pc = (uintptr) up->notify;
-	ureg->link = 0;
-	qunlock(&up->debug);
-
-	splhi();
-	fpuprocsave(up);
-	up->fpstate |= FPillegal;
-	return 1;
-}
-
-void
-noted(Ureg *ureg, ulong arg0)
-{
-	Ureg *nureg;
-	uintptr oureg, sp;
-
-	qlock(&up->debug);
-	if(arg0 != NRSTR && !up->notified){
-		qunlock(&up->debug);
-		pprint("call to noted() when not notified\n");
-		pexit("Suicide", 0);
-	}
-	up->notified = 0;
-	
-	nureg = up->ureg;
-	
-	oureg = (uintptr) nureg;
-	if(!okaddr(oureg - BY2WD, BY2WD + sizeof(Ureg), 0) || (oureg & 7) != 0){
-		qunlock(&up->debug);
-		pprint("bad ureg in noted or call to noted when not notified\n");
-		pexit("Suicide", 0);
-	}
-
-	nureg->psr = (nureg->psr & USPSRMASK) | (ureg->psr & ~USPSRMASK);
-	memmove(ureg, nureg, sizeof(Ureg));
-	
-	switch(arg0){
-	case NCONT: case NRSTR:
-		if(!okaddr(nureg->pc, BY2WD, 0) || !okaddr(nureg->sp, BY2WD, 0) ||
-				(nureg->pc & 3) != 0 || (nureg->sp & 7) != 0){
-			qunlock(&up->debug);
-			pprint("suicide: trap in noted\n");
-			pexit("Suicide", 0);
-		}
-		up->ureg = (Ureg *) (*(uintptr*) (oureg - BY2WD));
-		qunlock(&up->debug);
-		break;
-	
-	case NSAVE:
-		if(!okaddr(nureg->pc, BY2WD, 0) || !okaddr(nureg->sp, BY2WD, 0) ||
-				(nureg->pc & 3) != 0 || (nureg->sp & 7) != 0){
-			qunlock(&up->debug);
-			pprint("suicide: trap in noted\n");
-			pexit("Suicide", 0);
-		}
-		qunlock(&up->debug);
-		sp = oureg - 4 * BY2WD - ERRMAX;
-		ureg->sp = sp;
-		ureg->r0 = (uintptr) oureg;
-		((uintptr *) sp)[1] = oureg;
-		((uintptr *) sp)[0] = 0;
-		break;
-	
-	default:
-		up->lastnote->flag = NDebug;
-	
-	case NDFLT:
-		qunlock(&up->debug);
-		if(up->lastnote->flag == NDebug)
-			pprint("suicide: %s\n", up->lastnote->msg);
-		pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
-	}
-}
-
-static void
-faultnote(Ureg *ureg, char *access, uintptr addr)
-{
-	extern void checkpages(void);
-	char buf[ERRMAX];
-
-	if(!userureg(ureg)){
-		dumpregs(ureg);
-		panic("fault: %s addr=%#p", access, addr);
-	}
-	checkpages();
-	snprint(buf, sizeof(buf), "sys: trap: fault %s addr=%#p", access, addr);
-	postnote(up, 1, buf, NDebug);
-}
-
-void
-faultarm64(Ureg *ureg)
-{
-	int user, read;
-	uintptr addr;
-
-	user = userureg(ureg);
-	if(user)
-		up->insyscall = 1;
-	else {
-		extern void _peekinst(void);
-
-		if(ureg->pc == (uintptr)_peekinst){
-			ureg->pc = ureg->link;
-			return;
-		}
-		if(waserror()){
-			if(up->nerrlab == 0){
-				pprint("suicide: sys: %s\n", up->errstr);
-				pexit(up->errstr, 1);
-			}
-			nexterror();
-		}
-	}
-
-	addr = getfar();
-	read = (ureg->type & (1<<6)) == 0;
-
-	switch((u32int)ureg->type & 0x3F){
-	case  4: case  5: case  6: case  7:	// Tanslation fault.
-	case  8: case  9: case 10: case 11:	// Access flag fault.
-	case 12: case 13: case 14: case 15:	// Permission fault.
-	case 48:				// tlb conflict fault.
-		if(fault(addr, ureg->pc, read) == 0)
-			break;
-
-		/* wet floor */
-	case  0: case  1: case  2: case  3:	// Address size fault.
-	case 16: 				// synchronous external abort.
-	case 24: 				// synchronous parity error on a memory access.
-	case 20: case 21: case 22: case 23:	// synchronous external abort on a table walk.
-	case 28: case 29: case 30: case 31:	// synchronous parity error on table walk.
-	case 33:				// alignment fault.
-	case 52:				// implementation defined, lockdown abort.
-	case 53:				// implementation defined, unsuppoted exclusive.
-	case 61:				// first level domain fault
-	case 62:				// second level domain fault
-	default:
-		faultnote(ureg, read? "read": "write", addr);
-	}
-
-	if(user)
-		up->insyscall = 0;
-	else
-		poperror();
-}
-
-int
-userureg(Ureg* ureg)
-{
-	return (ureg->psr & 15) == 0;
-}
-
-uintptr
-userpc(void)
-{
-	Ureg *ur = up->dbgreg;
-	return ur->pc;
-}
-
-uintptr
-dbgpc(Proc *)
-{
-	Ureg *ur = up->dbgreg;
-	if(ur == nil)
-		return 0;
-	return ur->pc;
-}
-
-void
-procfork(Proc *p)
-{
-	fpuprocfork(p);
-	p->tpidr = up->tpidr;
-}
-
-void
-procsetup(Proc *p)
-{
-	fpuprocsetup(p);
-	p->tpidr = 0;
-	syswr(TPIDR_EL0, p->tpidr);
-}
-
-void
-procsave(Proc *p)
-{
-	fpuprocsave(p);
-	if(p->kp == 0)
-		p->tpidr = sysrd(TPIDR_EL0);
-	putasid(p);	// release asid
-}
-
-void
-procrestore(Proc *p)
-{
-	fpuprocrestore(p);
-	if(p->kp == 0)
-		syswr(TPIDR_EL0, p->tpidr);
-}
-
-void
-kprocchild(Proc *p, void (*entry)(void))
-{
-	p->sched.pc = (uintptr) entry;
-	p->sched.sp = (uintptr) p - 16;
-	*(void**)p->sched.sp = kprocchild;	/* fake */
-}
-
-void
-forkchild(Proc *p, Ureg *ureg)
-{
-	Ureg *cureg;
-
-	p->sched.pc = (uintptr) forkret;
-	p->sched.sp = (uintptr) p - TRAPFRAMESIZE;
-
-	cureg = (Ureg*) (p->sched.sp + 16);
-	memmove(cureg, ureg, sizeof(Ureg));
-	cureg->r0 = 0;
-}
-
-uintptr
-execregs(uintptr entry, ulong ssize, ulong nargs)
-{
-	uintptr *sp;
-	Ureg *ureg;
-
-	sp = (uintptr*)(USTKTOP - ssize);
-	*--sp = nargs;
-
-	ureg = up->dbgreg;
-	ureg->sp = (uintptr)sp;
-	ureg->pc = entry;
-	ureg->link = 0;
-	return USTKTOP-sizeof(Tos);
-}
-
-void
-evenaddr(uintptr addr)
-{
-	if(addr & 3){
-		postnote(up, 1, "sys: odd address", NDebug);
-		error(Ebadarg);
-	}
-}
-
-void
-callwithureg(void (*f) (Ureg *))
-{
-	Ureg u;
-	
-	u.pc = getcallerpc(&f);
-	u.sp = (uintptr) &f;
-	f(&u);
-}
-
-void
-setkernur(Ureg *ureg, Proc *p)
-{
-	ureg->pc = p->sched.pc;
-	ureg->sp = p->sched.sp;
-	ureg->link = (uintptr)sched;
-}
-
-void
-setupwatchpts(Proc*, Watchpt*, int)
-{
-}
-
-void
-setregisters(Ureg* ureg, char* pureg, char* uva, int n)
-{
-	ulong v;
-
-	v = ureg->psr;
-	memmove(pureg, uva, n);
-	ureg->psr = (ureg->psr & USPSRMASK) | (v & ~USPSRMASK);
-}
-
-static void
-dumpstackwithureg(Ureg *ureg)
-{
-	uintptr v, estack, sp;
-	char *s;
-	int i;
-
-	if((s = getconf("*nodumpstack")) != nil && strcmp(s, "0") != 0){
-		iprint("dumpstack disabled\n");
-		return;
-	}
-	iprint("ktrace /kernel/path %#p %#p %#p # pc, sp, link\n",
-		ureg->pc, ureg->sp, ureg->link);
-	delay(2000);
-
-	sp = ureg->sp;
-	if(sp < KZERO || (sp & 7) != 0)
-		sp = (uintptr)&ureg;
-
-	estack = (uintptr)m+MACHSIZE;
-	if(up != nil && sp <= (uintptr)up)
-		estack = (uintptr)up;
-
-	if(sp > estack){
-		if(up != nil)
-			iprint("&up %#p sp %#p\n", up, sp);
-		else
-			iprint("&m %#p sp %#p\n", m, sp);
-		return;
-	}
-
-	i = 0;
-	for(; sp < estack; sp += sizeof(uintptr)){
-		v = *(uintptr*)sp;
-		if(KTZERO < v && v < (uintptr)etext && (v & 3) == 0){
-			iprint("%#8.8lux=%#8.8lux ", (ulong)sp, (ulong)v);
-			i++;
-		}
-		if(i == 4){
-			i = 0;
-			iprint("\n");
-		}
-	}
-	if(i)
-		iprint("\n");
-}
-
-void
-dumpstack(void)
-{
-	callwithureg(dumpstackwithureg);
-}
-
-void
-dumpregs(Ureg *ureg)
-{
-	u64int *r;
-	int i, x;
-
-	x = splhi();
-	if(up != nil)
-		iprint("cpu%d: dumpregs ureg %#p process %lud: %s\n", m->machno, ureg,
-			up->pid, up->text);
-	else
-		iprint("cpu%d: dumpregs ureg %#p\n", m->machno, ureg);
-	r = &ureg->r0;
-	for(i = 0; i < 30; i += 3)
-		iprint("R%d %.16llux  R%d %.16llux  R%d %.16llux\n", i, r[i], i+1, r[i+1], i+2, r[i+2]);
-	iprint("PC %#p  SP %#p  LR %#p  PSR %llux  TYPE %llux\n",
-		ureg->pc, ureg->sp, ureg->link,
-		ureg->psr, ureg->type);
-	splx(x);
-}