* [PATCH 1/2] MIPS: add asm-offsets.h generation
2013-12-03 20:48 [PATCH 0/2] MIPS: import exception stuff from linux kernel Antony Pavlov
@ 2013-12-03 20:48 ` Antony Pavlov
2013-12-03 20:48 ` [PATCH 2/2] MIPS: import exception registers saving from linux kernel Antony Pavlov
2013-12-04 16:02 ` [PATCH 0/2] MIPS: import exception stuff " Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Antony Pavlov @ 2013-12-03 20:48 UTC (permalink / raw)
To: barebox
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
arch/mips/Makefile | 43 ++++++++++++++++++++++++++
arch/mips/include/asm/asm-offsets.h | 1 +
arch/mips/include/asm/ptrace.h | 35 +++++++++++++++++++++
arch/mips/lib/asm-offsets.c | 61 +++++++++++++++++++++++++++++++++++++
include/linux/kbuild.h | 15 +++++++++
5 files changed, 155 insertions(+)
create mode 100644 arch/mips/include/asm/asm-offsets.h
create mode 100644 arch/mips/include/asm/ptrace.h
create mode 100644 arch/mips/lib/asm-offsets.c
create mode 100644 include/linux/kbuild.h
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index dc0fe56..62e1acf 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -143,3 +143,46 @@ dtbs: scripts
KBUILD_DTBS := dtbs
KBUILD_IMAGE ?= $(KBUILD_BINARY)
+
+#####
+# Generate asm-offsets.h
+#
+
+offsets-file := include/generated/asm-offsets.h
+
+always += $(offsets-file)
+targets += $(offsets-file)
+targets += arch/$(SRCARCH)/lib/asm-offsets.s
+
+# Default sed regexp - multiline due to syntax constraints
+define sed-y
+ "/^->/{s:->#\(.*\):/* \1 */:; \
+ s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
+ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
+ s:->::; p;}"
+endef
+
+quiet_cmd_offsets = GEN $@
+define cmd_offsets
+ (set -e; \
+ echo "#ifndef __ASM_OFFSETS_H__"; \
+ echo "#define __ASM_OFFSETS_H__"; \
+ echo "/*"; \
+ echo " * DO NOT MODIFY."; \
+ echo " *"; \
+ echo " * This file was generated by Kbuild"; \
+ echo " *"; \
+ echo " */"; \
+ echo ""; \
+ sed -ne $(sed-y) $<; \
+ echo ""; \
+ echo "#endif" ) > $@
+endef
+
+# We use internal kbuild rules to avoid the "is up to date" message from make
+arch/$(SRCARCH)/lib/asm-offsets.s: arch/$(SRCARCH)/lib/asm-offsets.c FORCE
+ $(Q)mkdir -p $(dir $@)
+ $(call if_changed_dep,cc_s_c)
+
+$(obj)/$(offsets-file): arch/$(SRCARCH)/lib/asm-offsets.s Makefile
+ $(call cmd,offsets)
diff --git a/arch/mips/include/asm/asm-offsets.h b/arch/mips/include/asm/asm-offsets.h
new file mode 100644
index 0000000..d370ee3
--- /dev/null
+++ b/arch/mips/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
new file mode 100644
index 0000000..211834d
--- /dev/null
+++ b/arch/mips/include/asm/ptrace.h
@@ -0,0 +1,35 @@
+/*
+ * 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, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+/*
+ * This struct defines the way the registers are stored on the stack during an
+ * exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+#ifdef CONFIG_32BIT
+ /* Pad bytes for argument save space on the stack. */
+ unsigned long pad0[6];
+#endif
+
+ /* Saved main processor registers. */
+ unsigned long regs[32];
+
+ /* Saved special registers. */
+ unsigned long cp0_status;
+ unsigned long hi;
+ unsigned long lo;
+ unsigned long cp0_badvaddr;
+ unsigned long cp0_cause;
+ unsigned long cp0_epc;
+} __attribute__ ((aligned (8)));
+
+#endif /* _ASM_PTRACE_H */
diff --git a/arch/mips/lib/asm-offsets.c b/arch/mips/lib/asm-offsets.c
new file mode 100644
index 0000000..457bc8a
--- /dev/null
+++ b/arch/mips/lib/asm-offsets.c
@@ -0,0 +1,61 @@
+/*
+ * offset.c: Calculate pt_regs and task_struct offsets.
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+
+#include <linux/kbuild.h>
+#include <linux/stddef.h>
+#include <asm/ptrace.h>
+
+void output_ptreg_defines(void);
+
+void output_ptreg_defines(void)
+{
+ COMMENT("MIPS pt_regs offsets.");
+ OFFSET(PT_R0, pt_regs, regs[0]);
+ OFFSET(PT_R1, pt_regs, regs[1]);
+ OFFSET(PT_R2, pt_regs, regs[2]);
+ OFFSET(PT_R3, pt_regs, regs[3]);
+ OFFSET(PT_R4, pt_regs, regs[4]);
+ OFFSET(PT_R5, pt_regs, regs[5]);
+ OFFSET(PT_R6, pt_regs, regs[6]);
+ OFFSET(PT_R7, pt_regs, regs[7]);
+ OFFSET(PT_R8, pt_regs, regs[8]);
+ OFFSET(PT_R9, pt_regs, regs[9]);
+ OFFSET(PT_R10, pt_regs, regs[10]);
+ OFFSET(PT_R11, pt_regs, regs[11]);
+ OFFSET(PT_R12, pt_regs, regs[12]);
+ OFFSET(PT_R13, pt_regs, regs[13]);
+ OFFSET(PT_R14, pt_regs, regs[14]);
+ OFFSET(PT_R15, pt_regs, regs[15]);
+ OFFSET(PT_R16, pt_regs, regs[16]);
+ OFFSET(PT_R17, pt_regs, regs[17]);
+ OFFSET(PT_R18, pt_regs, regs[18]);
+ OFFSET(PT_R19, pt_regs, regs[19]);
+ OFFSET(PT_R20, pt_regs, regs[20]);
+ OFFSET(PT_R21, pt_regs, regs[21]);
+ OFFSET(PT_R22, pt_regs, regs[22]);
+ OFFSET(PT_R23, pt_regs, regs[23]);
+ OFFSET(PT_R24, pt_regs, regs[24]);
+ OFFSET(PT_R25, pt_regs, regs[25]);
+ OFFSET(PT_R26, pt_regs, regs[26]);
+ OFFSET(PT_R27, pt_regs, regs[27]);
+ OFFSET(PT_R28, pt_regs, regs[28]);
+ OFFSET(PT_R29, pt_regs, regs[29]);
+ OFFSET(PT_R30, pt_regs, regs[30]);
+ OFFSET(PT_R31, pt_regs, regs[31]);
+ OFFSET(PT_LO, pt_regs, lo);
+ OFFSET(PT_HI, pt_regs, hi);
+ OFFSET(PT_EPC, pt_regs, cp0_epc);
+ OFFSET(PT_BVADDR, pt_regs, cp0_badvaddr);
+ OFFSET(PT_STATUS, pt_regs, cp0_status);
+ OFFSET(PT_CAUSE, pt_regs, cp0_cause);
+ DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ BLANK();
+}
diff --git a/include/linux/kbuild.h b/include/linux/kbuild.h
new file mode 100644
index 0000000..359d4a8
--- /dev/null
+++ b/include/linux/kbuild.h
@@ -0,0 +1,15 @@
+#ifndef __LINUX_KBUILD_H
+#define __LINUX_KBUILD_H
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+#define OFFSET(sym, str, mem) \
+ DEFINE(sym, offsetof(struct str, mem))
+
+#define COMMENT(x) \
+ asm volatile("\n->#" x)
+
+#endif
--
1.8.4.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] MIPS: import exception registers saving from linux kernel
2013-12-03 20:48 [PATCH 0/2] MIPS: import exception stuff from linux kernel Antony Pavlov
2013-12-03 20:48 ` [PATCH 1/2] MIPS: add asm-offsets.h generation Antony Pavlov
@ 2013-12-03 20:48 ` Antony Pavlov
2013-12-04 16:02 ` [PATCH 0/2] MIPS: import exception stuff " Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Antony Pavlov @ 2013-12-03 20:48 UTC (permalink / raw)
To: barebox
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@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
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 4+ messages in thread