[PATCH 2/2] MIPS: import exception registers saving from linux kernel
Antony Pavlov
antonynpavlov at gmail.com
Tue Dec 3 15:48:55 EST 2013
Checking registers saving:
$ make qemu-malta_defconfig
$ make
...
$ qemu-system-mips -nodefaults -M malta -m 256 \
-nographic -serial stdio -bios ./barebox-flash-image
...
barebox:/ md -l 0x03
Ooops, address error on load or ifetch!
$ 0 : 00000000 00000000 ffffffff 0000003f
$ 4 : 00000000 ffffffff 00000004 00000004
$ 8 : 00000003 a0404d50 00000001 00000002
$12 : a0404d50 0000000a a0840000 00000003
$16 : 00000100 a0404d50 00000100 00000003
$20 : 00000000 a0406cd8 00000000 00000000
$24 : a083b4d8 a083058c
$28 : 00000000 a03ffca8 a0406ab0 a0830604
Hi : 00000000
Lo : 00000040
epc : a083056c
ra : a0830604
Status: 00000006
Cause : 00000410
Config: 80008482
### ERROR ### Please RESET the board ###
Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
arch/mips/include/asm/stackframe.h | 105 +++++++++++++++++++++++++++++++++++++
arch/mips/lib/genex.S | 2 +
arch/mips/lib/traps.c | 46 +++++++++++++---
3 files changed, 146 insertions(+), 7 deletions(-)
create mode 100644 arch/mips/include/asm/stackframe.h
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
new file mode 100644
index 0000000..0266ec6
--- /dev/null
+++ b/arch/mips/include/asm/stackframe.h
@@ -0,0 +1,105 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#ifndef _ASM_STACKFRAME_H
+#define _ASM_STACKFRAME_H
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+
+ .macro SAVE_AT
+ .set push
+ .set noat
+ LONG_S $1, PT_R1(sp)
+ .set pop
+ .endm
+
+ .macro SAVE_TEMP
+ mfhi v1
+#ifdef CONFIG_32BIT
+ LONG_S $8, PT_R8(sp)
+ LONG_S $9, PT_R9(sp)
+#endif
+ LONG_S $10, PT_R10(sp)
+ LONG_S $11, PT_R11(sp)
+ LONG_S $12, PT_R12(sp)
+
+ LONG_S v1, PT_HI(sp)
+ mflo v1
+
+ LONG_S $13, PT_R13(sp)
+ LONG_S $14, PT_R14(sp)
+ LONG_S $15, PT_R15(sp)
+ LONG_S $24, PT_R24(sp)
+
+ LONG_S v1, PT_LO(sp)
+
+ .endm
+
+ .macro SAVE_STATIC
+ LONG_S $16, PT_R16(sp)
+ LONG_S $17, PT_R17(sp)
+ LONG_S $18, PT_R18(sp)
+ LONG_S $19, PT_R19(sp)
+ LONG_S $20, PT_R20(sp)
+ LONG_S $21, PT_R21(sp)
+ LONG_S $22, PT_R22(sp)
+ LONG_S $23, PT_R23(sp)
+ LONG_S $30, PT_R30(sp)
+ .endm
+
+ .macro SAVE_SOME
+ .set push
+ .set noat
+ .set reorder
+ .set at=k0
+ move k1, sp
+ PTR_SUBU k1, PT_SIZE
+ .set noat
+ move k0, sp
+ move sp, k1
+ LONG_S k0, PT_R29(sp)
+ LONG_S $3, PT_R3(sp)
+ /*
+ * You might think that you don't need to save $0,
+ * but the FPU emulator and gdb remote debug stub
+ * need it to operate correctly
+ */
+ LONG_S $0, PT_R0(sp)
+ mfc0 v1, CP0_STATUS
+ LONG_S $2, PT_R2(sp)
+ LONG_S v1, PT_STATUS(sp)
+ LONG_S $4, PT_R4(sp)
+ mfc0 v1, CP0_CAUSE
+ LONG_S $5, PT_R5(sp)
+ LONG_S v1, PT_CAUSE(sp)
+ LONG_S $6, PT_R6(sp)
+ MFC0 v1, CP0_EPC
+ LONG_S $7, PT_R7(sp)
+#ifdef CONFIG_64BIT
+ LONG_S $8, PT_R8(sp)
+ LONG_S $9, PT_R9(sp)
+#endif
+ LONG_S v1, PT_EPC(sp)
+ LONG_S $25, PT_R25(sp)
+ LONG_S $28, PT_R28(sp)
+ LONG_S $31, PT_R31(sp)
+ .set pop
+ .endm
+
+ .macro SAVE_ALL
+ SAVE_SOME
+ SAVE_AT
+ SAVE_TEMP
+ SAVE_STATIC
+ .endm
+
+#endif /* _ASM_STACKFRAME_H */
diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S
index d6f65a2..8941714 100644
--- a/arch/mips/lib/genex.S
+++ b/arch/mips/lib/genex.S
@@ -1,6 +1,7 @@
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
.text
.set macro
@@ -10,6 +11,7 @@
/* Exception vector */
NESTED(handle_reserved, 0, sp)
+ SAVE_ALL
la k0, barebox_exc_handler
jal k0
move a0, sp
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
index 4e167cc..0a5914e 100644
--- a/arch/mips/lib/traps.c
+++ b/arch/mips/lib/traps.c
@@ -1,8 +1,9 @@
#include <common.h>
#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
-void barebox_exc_handler(void *regs);
+void barebox_exc_handler(const struct pt_regs *regs);
/*
* Trap codes from OpenBSD trap.h
@@ -95,13 +96,44 @@ static char *get_exc_name(u32 cause)
return "unknown exception";
}
-void barebox_exc_handler(void *regs)
+void barebox_exc_handler(const struct pt_regs *regs)
{
- printf("\nOoops, %s!\n", get_exc_name(read_c0_cause()));
- printf("EPC = 0x%08x\n", read_c0_epc());
- printf("CP0_STATUS = 0x%08x\n", read_c0_status());
- printf("CP0_CAUSE = 0x%08x\n", read_c0_cause());
- printf("CP0_CONFIG = 0x%08x\n\n", read_c0_config());
+ const int field = 2 * sizeof(unsigned long);
+ unsigned int cause = regs->cp0_cause;
+ int i;
+
+ printf("\nOoops, %s!\n\n", get_exc_name(cause));
+
+ /*
+ * Saved main processor registers
+ */
+ for (i = 0; i < 32; ) {
+ if ((i % 4) == 0)
+ printf("$%2d :", i);
+ if (i == 0)
+ printf(" %0*lx", field, 0UL);
+ else if (i == 26 || i == 27)
+ printf(" %*s", field, "");
+ else
+ printf(" %0*lx", field, regs->regs[i]);
+
+ i++;
+ if ((i % 4) == 0)
+ printf("\n");
+ }
+
+ printf("Hi : %0*lx\n", field, regs->hi);
+ printf("Lo : %0*lx\n", field, regs->lo);
+
+ /*
+ * Saved cp0 registers
+ */
+ printf("epc : %0*lx\n", field, regs->cp0_epc);
+ printf("ra : %0*lx\n", field, regs->regs[31]);
+
+ printf("Status: %08x\n", (uint32_t) regs->cp0_status);
+ printf("Cause : %08x\n", cause);
+ printf("Config: %08x\n\n", read_c0_config());
hang();
}
--
1.8.4.4
More information about the barebox
mailing list