commit acdede61fa11439c96c2fb5712664b9d19e9d3c1
parent e9ce4b5143311cb0d25489884aa4afc468b8146f
Author: Roberto Vargas <roberto.vargas@arm.com>
Date: Wed, 17 Oct 2018 11:28:17 +0100
Merge tag 'panic'
Change-Id: Iab4e8d9fda28ab5958a4e18776f1095de3645aaa
Diffstat:
13 files changed, 227 insertions(+), 206 deletions(-)
diff --git a/arch/amd64/arch.c b/arch/amd64/arch.c
@@ -1,9 +1,8 @@
#include <rcode.h>
void
-panic(const char *msg)
+halt(void)
{
- printk("panic: %s\n", msg);
for (;;)
;
}
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
@@ -6,14 +6,13 @@ MORECFLAGS = -DUARTBASE=0x1c0c0000 \
-DUARTBAUDRATE=115200 \
ROMOBJS = rom-crt-$(SYS).o \
- rom-$(SYS).o panic.o \
+ rom-$(SYS).o \
arch.o \
$(DRVDIR)/uart.o \
$(SRCDIR)/romfw/builtin.o \
RAMOBJS = ram-crt-$(SYS).o \
ram-$(SYS).o \
- panic.o \
arch.o \
$(DRVDIR)/uart.o \
$(SRCDIR)/ramfw/builtin.o \
diff --git a/arch/arm64/arch.s b/arch/arm64/arch.s
@@ -1,10 +1,7 @@
.file "arch.s"
-DAIF_ABT = 2
-DAIF_DBG = 4
-
.text
- .globl panic,enaabt,disabt,enadbg,disdbg,wfi,wfe
+ .globl panic,halt,enaint,exception
.globl rd_actlr_r,wr_actlr_r
.globl rd_id_aa64rmfr0_r,wr_id_aa64rmfr0_r
.globl rd_rcr_r,wr_rcr_r,rd_rdscr_r,wr_rdscr_r
@@ -12,34 +9,14 @@ DAIF_DBG = 4
.globl vectbl,swtch,isb,inm8,inm16,inm32
.globl outm8,outm16,outm32
-enaabt:
- msr daifclr,DAIF_ABT
- ret
-
-disabt:
- msr daifset,DAIF_ABT
- ret
-
-enadbg:
- msr daifclr,DAIF_DBG
- ret
-
-disdbg:
- msr daifset,DAIF_DBG
+enaint:
+ msr daifclr,#15
ret
isb:
isb
ret
-wfi:
- wfi
- ret
-
-wfe:
- wfe
- ret
-
rd_actlr_r:
mrs x0,S3_6_C1_C0_3
ret
@@ -115,39 +92,12 @@ outm32:
str w0, [x1]
ret
-panic:
- stp x1,x0,[sp,#-16]!
- stp x3,x2,[sp,#-16]!
- stp x5,x4,[sp,#-16]!
- stp x7,x6,[sp,#-16]!
- stp x9,x8,[sp,#-16]!
- stp x11,x10,[sp,#-16]!
- stp x13,x12,[sp,#-16]!
- stp x15,x14,[sp,#-16]!
- stp x17,x16,[sp,#-16]!
- stp x19,x18,[sp,#-16]!
- stp x21,x20,[sp,#-16]!
- stp x23,x22,[sp,#-16]!
- stp x25,x24,[sp,#-16]!
- stp x27,x26,[sp,#-16]!
- stp x29,x28,[sp,#-16]!
- stp xzr,x30,[sp,#-16]!
-
- mrs x3,S3_6_C4_C0_6 /* SPSR_R */
- mrs x2,S3_6_C4_C0_3 /* ELR_R */
- stp x3,x2,[sp,#-16]!
-
- mrs x3,S3_6_C6_C0_6 /* FAR_R */
- mrs x2,S3_6_C5_C2_6 /* ESR_R */
- stp x3,x2,[sp,#-16]!
-
- mov x3,sp
- stp xzr,x3,[sp,#-16]!
-
- mov x1,sp
- b cpanic
+halt:
+ msr daifset,#15
+ wfe
+ b halt
-_synchdl:
+exception:
stp x1,x0,[sp,#-16]!
stp x3,x2,[sp,#-16]!
stp x5,x4,[sp,#-16]!
@@ -182,10 +132,16 @@ _synchdl:
msr spsel,#0
stp xzr,xzr,[sp,#-16]!
mov x29,sp
- bl synchdl
+ bl trap
adr x0,outsync
b panic
+ .section .rodata
+outsync:
+ .asciz "out of sync"
+
+
+ .text
swtch:
ldp xzr,x1,[x0],#16
mov sp,x1
@@ -218,67 +174,29 @@ swtch:
ldp x1,x0,[sp],#16
eret
-_badtrap:
- stp x1,x0,[sp,#-16]!
- stp x3,x2,[sp,#-16]!
- stp x5,x4,[sp,#-16]!
- stp x7,x6,[sp,#-16]!
- stp x9,x8,[sp,#-16]!
- stp x11,x10,[sp,#-16]!
- stp x13,x12,[sp,#-16]!
- stp x15,x14,[sp,#-16]!
- stp x17,x16,[sp,#-16]!
- stp x19,x18,[sp,#-16]!
- stp x21,x20,[sp,#-16]!
- stp x23,x22,[sp,#-16]!
- stp x25,x24,[sp,#-16]!
- stp x27,x26,[sp,#-16]!
- stp x29,x28,[sp,#-16]!
- stp xzr,x30,[sp,#-16]!
-
- mrs x3,S3_6_C4_C0_6 /* SPSR_R */
- mrs x2,S3_6_C4_C0_3 /* ELR_R */
- stp x3,x2,[sp,#-16]!
-
- mrs x3,S3_6_C6_C0_6 /* FAR_R */
- mrs x2,S3_6_C5_C2_6 /* ESR_R */
- stp x3,x2,[sp,#-16]!
-
- mov x3,sp
- stp xzr,x3,[sp,#-16]!
-
- adr x0,unexpected
- mov x1,sp
- b cpanic
-
.align 11
vectbl:
/* Current EL with SP0 */
- b _badtrap; nop /* Sync */
- b _badtrap; nop /* IRQ/vIRQ */
- b _badtrap; nop /* FIQ/vFIQ */
- b _badtrap; nop /* SError/VSError */
+ b exception; nop /* Sync */
+ b exception; nop /* IRQ/vIRQ */
+ b exception; nop /* FIQ/vFIQ */
+ b exception; nop /* SError/VSError */
/* Current EL with SPx */
- b _badtrap; nop /* Sync */
- b _badtrap; nop /* IRQ/vIRQ */
- b _badtrap; nop /* FIQ/vFIQ */
- b _badtrap; nop /* SError/VSError */
+ b exception; nop /* Sync */
+ b exception; nop /* IRQ/vIRQ */
+ b exception; nop /* FIQ/vFIQ */
+ b exception; nop /* SError/VSError */
/* Lower EL using AArch64 */
- b _synchdl; nop /* Sync */
- b _badtrap; nop /* IRQ/vIRQ */
- b _badtrap; nop /* FIQ/vFIQ */
- b _badtrap; nop /* SError/VSError */
+ b exception; nop /* Sync */
+ b exception; nop /* IRQ/vIRQ */
+ b exception; nop /* FIQ/vFIQ */
+ b exception; nop /* SError/VSError */
/* Lower EL using AArch32 */
- b _synchdl; nop /* Sync */
- b _badtrap; nop /* IRQ/vIRQ */
- b _badtrap; nop /* FIQ/vFIQ */
- b _badtrap; nop /* SError/VSError */
+ b exception; nop /* Sync */
+ b exception; nop /* IRQ/vIRQ */
+ b exception; nop /* FIQ/vFIQ */
+ b exception; nop /* SError/VSError */
- .section .rodata
-unexpected:
- .asciz "unexpected exception"
-outsync:
- .asciz "out of sync"
diff --git a/arch/arm64/panic.c b/arch/arm64/panic.c
@@ -1,66 +0,0 @@
-#include <rcode.h>
-
-void
-dumpregs(struct trapframe *fp)
-{
- printk("x0=%llx\tx1=%llx\tx2=%llx\tx3=%llx\n"
- "x4=%llx\tx5=%llx\tx6=%llx\tx7=%llx\n"
- "x8=%llx\tx9=%llx\tx10=%llx\tx11=%llx\n"
- "x12=%llx\tx13=%llx\tx14=%llx\tx15=%llx\n"
- "x16=%llx\tx17=%llx\tx18=%llx\tx19=%llx\n"
- "x20=%llx\tx21=%llx\tx22=%llx\tx23=%llx\n"
- "x24=%llx\tx25=%llx\tx26=%llx\tx27=%llx\n"
- "x28=%llx\tx29=%llx\tx30=%llx\telr=%llx\n"
- "spsr=%llx\tesr=%llx\tfar=%llx\n"
- "sp=%llx\n",
- fp->x0, fp->x1, fp->x2, fp->x3,
- fp->x4, fp->x5, fp->x6, fp->x7,
- fp->x8, fp->x9, fp->x10, fp->x11,
- fp->x12, fp->x13, fp->x14, fp->x15,
- fp->x16, fp->x17, fp->x18, fp->x19,
- fp->x20, fp->x21, fp->x22, fp->x23,
- fp->x24, fp->x25, fp->x26, fp->x27,
- fp->x28, fp->x29, fp->x30, fp->elr,
- fp->spsr, fp->esr, fp->far, fp->sp);
-}
-
-void
-backtrace(struct trapframe *fp)
-{
- void **bp;
-
- printk("backtrace:\n");
- for (bp = (void **) fp->x29; *bp; bp = (void **) *bp)
- printk("%llx\n", bp[1]);
-}
-
-void
-dumpstack(struct trapframe *fp)
-{
- int *sp, i;
-
- printk("stack dump:\n");
- sp = fp->sp;
- for (i = 0; i < 16; i++)
- printk("%x%c", *sp++, (i % 4 == 0) ? '\n' : ' ');
-}
-
-void
-cpanic(const char *msg, struct trapframe *fp)
-{
- /*
- * check against 1 to be more robust
- * against memory corruptions
- */
- if (bss->in_panic != 1) {
- bss->in_panic = 1;
- printk("panic: %s\n", msg);
-
- dumpregs(fp);
- backtrace(fp);
- dumpstack(fp);
- }
-
- for (disabt(); ; disabt())
- wfe();
-}
diff --git a/arch/arm64/rom-none.c b/arch/arm64/rom-none.c
@@ -27,10 +27,11 @@ main(void *text, void *ram, size_t ramsiz)
memset(fp, 0, sizeof(*fp));
bss->text = text;
+ bss->backtrace = 1;
+ bss->dumpstack = 1;
bss->uartbase = (void *)UARTBASE;
-
uartinit(UARTCLK, UARTBAUDRATE);
- enaabt();
+ enaint();
isb();
fp->sp = bp + (ramsiz - 16);
diff --git a/include/rcode.h b/include/rcode.h
@@ -12,10 +12,64 @@
typedef struct rmucmd Rmucmd;
+enum ecvals {
+ UNKNOWN = 0x00, /* unknown reason */
+ TRAPWFI = 0x01, /* trapped wfi or wfe */
+ TRAPMCR = 0x03, /* trapped mcr or mrc (coproc == 1111) */
+ TRAPMCRR = 0x04, /* trapped mcrr or mrrc (coproc == 1111) */
+ TRAPMCR2 = 0x05, /* trapped mcr or mrc (coproc == 1110) */
+ TRAPLDC = 0x06, /* trapped LDC or STC */
+ TRAPSVE = 0x07, /* trapped SVE */
+ TRAPVMRS = 0x08, /* trapped VMRS */
+ TRAPPTRA = 0x09, /* trapped pointer autentication */
+ TRAPMCRR2 = 0x0c, /* trapped mcrr or mrrc (coproc == 1110) */
+ ILL = 0x0f, /* Illegal execution state */
+ SVC32 = 0x11, /* SVC in AArch32 */
+ HVC32 = 0x12, /* HVC in AArch32 */
+ SMC32 = 0x13, /* SVC in AArch32 */
+ SVC = 0x15, /* SVC */
+ HVC = 0x16, /* HVC */
+ SMC = 0x17, /* SMC */
+ TRAPSYS = 0x18, /* Trapped MSR, MRS or System instruction */
+ SVE = 0x19, /* SVE */
+ TRAP = 0x1a, /* trapped ERET, ERETAA, ERETAB */
+ EL3EXCP = 0x1f, /* implementation defined exception to EL3 */
+ IABORT = 0x20, /* Instruction abort from lower level */
+ IABORTL = 0x21, /* Instruction abort from current level */
+ PCALIGN = 0x22, /* PC aligment fault exception */
+ DABORT = 0x24, /* Data abort from lower level */
+ DABORTL = 0x25, /* Data abort from current level */
+ SPALIGN = 0x26, /* SP aligment fault exception */
+ FPE32 = 0x28, /* Floating-point exception in AArch32 */
+ FPE = 0x2c, /* Floating-point exception in AArch64 */
+ RMC = 0x2e, /* RMC */
+ SERROR = 0x2f, /* Serror interrupt */
+ BREAK = 0x30, /* Breakpoint exception from lower level */
+ BREAKL = 0x31, /* Breakpoint exception from current level */
+ STEP = 0x32, /* Software step from lower level */
+ STEPL = 0x33, /* Software step from current level */
+ WATCH = 0x34, /* Watchpoint from lower level */
+ WATCHL = 0x35, /* Watchpoint from current level */
+ BKPT = 0x38, /* BKPT instruction in AArch32 */
+ VECTOR = 0x3a, /* Vector catch exception in AArch32 */
+ BRK = 0x3c, /* BRK instruction in AArch64 */
+ NR_EC_VALS
+};
+
+#ifdef NDEBUG
+#define NR_EC_STR 0
+#else
+#define NR_EC_STR NR_EC_VALS
+#endif
+
struct bssmap {
- char in_panic;
+ unsigned char in_panic;
+ unsigned char dumpstack;
+ unsigned char backtrace;
void *text;
void *uartbase;
+ const char *errstr;
+ Rmucmd *cmd;
};
struct rowidx {
@@ -56,19 +110,17 @@ bss(void)
}
#define bss bss()
-extern void badrmc(Rmucmd *cmd, int error);
+extern void trap(struct trapframe *fp);
+extern void exception(void);
+extern void badrmc(int error);
extern void panic(const char *msg);
extern void printk(const char * restrict fmt, ...);
extern void rmc(Rmucmd *cmd);
extern void swtch(struct trapframe *fp);
/* architectural functions */
-extern void enaabt(void);
-extern void disabt(void);
-extern void enadbg(void);
-extern void disdbg(void);
-extern void wfi(void);
-extern void wfe(void);
+extern void halt(void);
+extern void enaint(void);
extern unsigned long long rd_actlr_r(void);
extern void wr_actlr_r(unsigned long long v);
extern unsigned long long rd_id_aa64rmfr0_r(void);
@@ -92,3 +144,4 @@ extern uint32_t outm32(uint32_t, void *addr);
/* global constant variables */
extern const struct rowidx rowidx[];
extern const ptrdiff_t handler[];
+extern const char *const ecstr[];
diff --git a/scripts/genecstr.sh b/scripts/genecstr.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+trap 'r=$?;rm -f $$.c;exit $r'
+
+awk '
+BEGIN {print "#include <rcode.h>\n"}
+/^enum ecvals \{/ {print "const char *const ecstr[] = {"
+ print "#ifndef NDEBUG"
+ inhome = 1}
+
+inhome && /=/ {sub(/,/, "", $1)
+ printf("\t[%s] = \"", $1)
+ for (i = 5; i <= NF-1; ++i)
+ printf("%s%s", $i, (i == NF-1) ? "\"" : " ")
+ print ","}
+
+inhome && /^}/ {print "#endif"
+ print "\tNULL"
+ print "};"
+ inhome = 0}' $@ > $$.c && mv $$.c ecstr.c
diff --git a/src/.gitignore b/src/.gitignore
@@ -0,0 +1 @@
+ecstr.c
diff --git a/src/Makefile b/src/Makefile
@@ -4,16 +4,21 @@ include $(PROJECTDIR)/scripts/rules.mk
LIBS = libc librmu libtypes libhdl
IMGS = ramfw romfw
DIRS = $(LIBS) $(IMGS)
+OBJS = rmc.o ecstr.o
-all: $(IMGS) rmc.o
+all: $(IMGS)
gen: FORCE
+@cd libtypes && $(MAKE) gen
-$(IMGS): $(LIBS)
+ecstr.c: $(INCDIR)/rcode.h
+ $(SCRIPTDIR)/genecstr.sh $(INCDIR)/rcode.h
+
+$(IMGS): $(LIBS) $(OBJS)
$(DIRS): FORCE
+@cd $@ && $(MAKE)
clean:
$(FORALL)
+ rm -f ecstr.c
diff --git a/src/ramfw/Makefile b/src/ramfw/Makefile
@@ -2,6 +2,7 @@ PROJECTDIR=../..
include $(PROJECTDIR)/scripts/rules.mk
OBJS = ../rmc.o \
+ ../ecstr.o \
rmctbl.o \
all: builtin.o
diff --git a/src/rmc.c b/src/rmc.c
@@ -1,19 +1,107 @@
#include <rcode.h>
+static void
+dumpregs(struct trapframe *fp)
+{
+ printk("x0=%llx\tx1=%llx\tx2=%llx\tx3=%llx\n"
+ "x4=%llx\tx5=%llx\tx6=%llx\tx7=%llx\n"
+ "x8=%llx\tx9=%llx\tx10=%llx\tx11=%llx\n"
+ "x12=%llx\tx13=%llx\tx14=%llx\tx15=%llx\n"
+ "x16=%llx\tx17=%llx\tx18=%llx\tx19=%llx\n"
+ "x20=%llx\tx21=%llx\tx22=%llx\tx23=%llx\n"
+ "x24=%llx\tx25=%llx\tx26=%llx\tx27=%llx\n"
+ "x28=%llx\tx29=%llx\tx30=%llx\telr=%llx\n"
+ "spsr=%llx\tesr=%llx\tfar=%llx\n"
+ "sp=%llx\n",
+ fp->x0, fp->x1, fp->x2, fp->x3,
+ fp->x4, fp->x5, fp->x6, fp->x7,
+ fp->x8, fp->x9, fp->x10, fp->x11,
+ fp->x12, fp->x13, fp->x14, fp->x15,
+ fp->x16, fp->x17, fp->x18, fp->x19,
+ fp->x20, fp->x21, fp->x22, fp->x23,
+ fp->x24, fp->x25, fp->x26, fp->x27,
+ fp->x28, fp->x29, fp->x30, fp->elr,
+ fp->spsr, fp->esr, fp->far, fp->sp);
+}
+
+static void
+backtrace(struct trapframe *fp)
+{
+ void **bp;
+
+ if (!bss->backtrace)
+ return;
+ printk("backtrace:\n");
+ for (bp = (void **) fp->x29; *bp; bp = (void **) *bp)
+ printk("%llx\n", bp[1]);
+}
+
+static void
+dumpstack(struct trapframe *fp)
+{
+ int *sp, i;
+
+ if (!bss->dumpstack)
+ return;
+ printk("stack dump:\n");
+ sp = fp->sp;
+ for (i = 0; i < 16; i++)
+ printk("%x%c", *sp++, (i % 4 == 0) ? '\n' : ' ');
+}
+
+static void
+panicfmt(const char *msg, struct trapframe *fp)
+{
+ /*
+ * check against 1 to be more robust
+ * against memory corruptions
+ */
+ if (bss->in_panic != 1) {
+ bss->in_panic = 1;
+ printk("panic: %s\n", msg);
+
+ dumpregs(fp);
+ backtrace(fp);
+ dumpstack(fp);
+ }
+}
+
+void
+panic(const char *msg)
+{
+ bss->errstr = msg;
+ exception();
+}
+
void
-synchdl(struct trapframe *fp)
+trap(struct trapframe *fp)
{
Rmucmd cmd;
- unsigned why;
+ enum ecvals ec;
+ char *msg;
+
+ dbg("exception handler\n");
+ if (bss->errstr) {
+ panicfmt(bss->errstr, fp);
+ halt();
+ }
- dbg("sync handler\n");
+ ec = (fp->esr >> 26) & 0x3f;
+
+ if (ec != RMC) {
+ msg = NULL;
+ if (ec < NR_EC_STR)
+ msg = ecstr[ec];
+ if (!msg)
+ msg = "unknown reason";
+ panicfmt(msg, fp);
+ halt();
+ }
- why = fp->esr >> 26;
cmd.imm1 = fp->esr & 0xff;
cmd.imm2 = (fp->esr >> 8) & 0xff;
-
- if (why != 0x2e)
- panic("synchdl");
+ cmd.fp = fp;
+ bss->cmd = &cmd;
if (!setjmp(cmd.recover))
rmc(&cmd);
@@ -22,8 +110,10 @@ synchdl(struct trapframe *fp)
}
void
-badrmc(Rmucmd *cmd, int error)
+badrmc(int error)
{
+ Rmucmd *cmd = bss->cmd;
+
dbg("bad RMC: %d, %d = %d\n", cmd->imm1, cmd->imm2, error);
cmd->fp->x0 = error;
longjmp(cmd->recover, 1);
@@ -61,7 +151,7 @@ rmc(Rmucmd *cmd)
idx = &rowidx[cmd->imm1];
if (cmd->imm2 >= idx->cnt)
- badrmc(cmd, 1); /* TODO: put the correct code */
+ badrmc(1); /* TODO: put the correct code */
/*
* and now we have to reallocate the function pointer,
diff --git a/src/romfw/Makefile b/src/romfw/Makefile
@@ -2,6 +2,7 @@ PROJECTDIR=../..
include $(PROJECTDIR)/scripts/rules.mk
OBJS = ../rmc.o \
+ ../ecstr.o \
rmctbl.o \
all: builtin.o
diff --git a/test/test1/test.c b/test/test1/test.c
@@ -24,9 +24,8 @@ main(int argc, char *argv[])
}
void
-panic(const char *msg)
+halt(const char *msg)
{
- printk("panic: %s\n", msg);
abort();
}