* [PATCH] MIPS: add initial exceptions handling
@ 2012-07-25 22:00 Antony Pavlov
2012-07-27 7:48 ` Sascha Hauer
0 siblings, 1 reply; 4+ messages in thread
From: Antony Pavlov @ 2012-07-25 22:00 UTC (permalink / raw)
To: barebox
Checking exception handling:
$ make qemu-malta_defconfig
$ make
...
$ qemu-system-mips -nodefaults -M malta -m 256 \
-nographic -serial stdio -bios ./barebox.bin
...
barebox:/ md -l 0x03
Ooops, address error on load or ifetch!
EPC = 0xa082783c
CP0_STATUS = 0x00000006
CP0_CAUSE = 0x00000410
CP0_CONFIG = 0x80008482
### ERROR ### Please RESET the board ###
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
---
arch/mips/boot/main_entry.c | 47 ++++++++++++++++
arch/mips/include/asm/addrspace.h | 109 +++++++++++++++++++++++++++++++++++++
arch/mips/lib/Makefile | 2 +
arch/mips/lib/genex.S | 31 +++++++++++
arch/mips/lib/traps.c | 107 ++++++++++++++++++++++++++++++++++++
5 files changed, 296 insertions(+)
create mode 100644 arch/mips/include/asm/addrspace.h
create mode 100644 arch/mips/lib/genex.S
create mode 100644 arch/mips/lib/traps.c
diff --git a/arch/mips/boot/main_entry.c b/arch/mips/boot/main_entry.c
index 8f5f6fc..a38ad31 100644
--- a/arch/mips/boot/main_entry.c
+++ b/arch/mips/boot/main_entry.c
@@ -25,11 +25,56 @@
#include <string.h>
#include <asm/sections.h>
#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
extern void start_barebox(void);
+extern void handle_reserved(void);
void main_entry(void);
+unsigned long exception_handlers[32];
+
+static void set_except_vector(int n, void *addr)
+{
+ unsigned handler = (unsigned long) addr;
+
+ exception_handlers[n] = handler;
+}
+
+static void trap_init(void)
+{
+ extern char except_vec3_generic;
+ int i;
+
+ unsigned long ebase;
+
+ ebase = CKSEG1;
+
+ /*
+ * Copy the generic exception handlers to their final destination.
+ * This will be overriden later as suitable for a particular
+ * configuration.
+ */
+ memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80);
+
+ /*
+ * Setup default vectors
+ */
+ for (i = 0; i <= 31; i++) {
+ set_except_vector(i, &handle_reserved);
+ }
+
+ if (!cpu_has_4kex)
+ memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80);
+
+ /* FIXME: handle tlb */
+ memcpy((void *)(ebase), &except_vec3_generic, 0x80);
+
+ /* unset BOOT EXCEPTION VECTOR bit */
+ write_c0_status(read_c0_status() & ~ST0_BEV);
+}
+
/**
* Called plainly from assembler code
*
@@ -48,5 +93,7 @@ void main_entry(void)
r4k_cache_init();
}
+ trap_init();
+
start_barebox();
}
diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
new file mode 100644
index 0000000..17d480d
--- /dev/null
+++ b/arch/mips/include/asm/addrspace.h
@@ -0,0 +1,109 @@
+/*
+ * 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) 1996, 99 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ADDRSPACE_H
+#define _ASM_ADDRSPACE_H
+
+/*
+ * Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ATYPE_
+#define _ATYPE32_
+#define _ATYPE64_
+#define _CONST64_(x) x
+#else
+#define _ATYPE_ __PTRDIFF_TYPE__
+#define _ATYPE32_ int
+#define _ATYPE64_ __s64
+#ifdef CONFIG_64BIT
+#define _CONST64_(x) x ## L
+#else
+#define _CONST64_(x) x ## LL
+#endif
+#endif
+
+/*
+ * 32-bit MIPS address spaces
+ */
+#ifdef __ASSEMBLY__
+#define _ACAST32_
+#define _ACAST64_
+#else
+#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */
+#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */
+#endif
+
+/*
+ * Returns the kernel segment base of a given address
+ */
+#define KSEGX(a) ((_ACAST32_(a)) & 0xe0000000)
+
+/*
+ * Returns the physical address of a CKSEGx / XKPHYS address
+ */
+#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
+#define XPHYSADDR(a) ((_ACAST64_(a)) & \
+ _CONST64_(0x000000ffffffffff))
+
+#ifdef CONFIG_64BIT
+
+/*
+ * Memory segments (64bit kernel mode addresses)
+ * The compatibility segments use the full 64-bit sign extended value. Note
+ * the R8000 doesn't have them so don't reference these in generic MIPS code.
+ */
+#define XKUSEG _CONST64_(0x0000000000000000)
+#define XKSSEG _CONST64_(0x4000000000000000)
+#define XKPHYS _CONST64_(0x8000000000000000)
+#define XKSEG _CONST64_(0xc000000000000000)
+#define CKSEG0 _CONST64_(0xffffffff80000000)
+#define CKSEG1 _CONST64_(0xffffffffa0000000)
+#define CKSSEG _CONST64_(0xffffffffc0000000)
+#define CKSEG3 _CONST64_(0xffffffffe0000000)
+
+#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
+#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1)
+#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2)
+#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3)
+
+#else
+
+#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0)
+#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1)
+#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2)
+#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3)
+
+/*
+ * Map an address to a certain kernel segment
+ */
+#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0)
+#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1)
+#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2)
+#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3)
+
+/*
+ * Memory segments (32bit kernel mode addresses)
+ * These are the traditional names used in the 32-bit universe.
+ */
+#define KUSEG 0x00000000
+#define KSEG0 0x80000000
+#define KSEG1 0xa0000000
+#define KSEG2 0xc0000000
+#define KSEG3 0xe0000000
+
+#define CKUSEG 0x00000000
+#define CKSEG0 0x80000000
+#define CKSEG1 0xa0000000
+#define CKSEG2 0xc0000000
+#define CKSEG3 0xe0000000
+
+#endif
+
+#endif /* _ASM_ADDRSPACE_H */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index b99bb71..a31046b 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -5,6 +5,8 @@ obj-y += ashldi3.o
obj-y += ashrdi3.o
obj-y += memory.o
obj-y += cpu-probe.o
+obj-y += traps.o
+obj-y += genex.o
obj-$(CONFIG_CPU_MIPS32) += c-r4k.o
obj-$(CONFIG_CPU_MIPS64) += c-r4k.o
diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S
new file mode 100644
index 0000000..d6f65a2
--- /dev/null
+++ b/arch/mips/lib/genex.S
@@ -0,0 +1,31 @@
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+ .text
+ .set macro
+ .set noat
+ .set noreorder
+ .align 5
+
+/* Exception vector */
+NESTED(handle_reserved, 0, sp)
+ la k0, barebox_exc_handler
+ jal k0
+ move a0, sp
+ /* will never return here */
+ END(handle_reserved)
+
+/* General exception vector */
+NESTED(except_vec3_generic, 0, sp)
+ .set noat
+ mfc0 k1, CP0_CAUSE
+ la k0, exception_handlers
+ andi k1, k1, 0x7c
+ addu k0, k0, k1
+ lw k0, (k0)
+ nop
+ jr k0
+ nop
+ END(except_vec3_generic)
+ .set at
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
new file mode 100644
index 0000000..4e167cc
--- /dev/null
+++ b/arch/mips/lib/traps.c
@@ -0,0 +1,107 @@
+#include <common.h>
+
+#include <asm/mipsregs.h>
+
+void barebox_exc_handler(void *regs);
+
+/*
+ * Trap codes from OpenBSD trap.h
+ */
+#define T_INT 0 /* Interrupt pending */
+#define T_TLB_MOD 1 /* TLB modified fault */
+#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */
+#define T_TLB_ST_MISS 3 /* TLB miss on a store */
+#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */
+#define T_ADDR_ERR_ST 5 /* Address error on a store */
+#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */
+#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */
+#define T_SYSCALL 8 /* System call */
+#define T_BREAK 9 /* Breakpoint */
+#define T_RES_INST 10 /* Reserved instruction exception */
+#define T_COP_UNUSABLE 11 /* Coprocessor unusable */
+#define T_OVFLOW 12 /* Arithmetic overflow */
+#define T_TRAP 13 /* Trap instruction */
+#define T_VCEI 14 /* Virtual coherency instruction */
+#define T_FPE 15 /* Floating point exception */
+#define T_IWATCH 16 /* Inst. Watch address reference */
+#define T_DWATCH 23 /* Data Watch address reference */
+#define T_VCED 31 /* Virtual coherency data */
+
+#define CR_EXC_CODE 0x0000007c
+#define CR_EXC_CODE_SHIFT 2
+
+static char *get_exc_name(u32 cause)
+{
+ switch ((cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) {
+
+ case T_INT:
+ return "interrupt pending";
+
+ case T_TLB_MOD:
+ return "TLB modified";
+
+ case T_TLB_LD_MISS:
+ return "TLB miss on load or ifetch";
+
+ case T_TLB_ST_MISS:
+ return "TLB miss on store";
+
+ case T_ADDR_ERR_LD:
+ return "address error on load or ifetch";
+
+ case T_ADDR_ERR_ST:
+ return "address error on store";
+
+ case T_BUS_ERR_IFETCH:
+ return "bus error on ifetch";
+
+ case T_BUS_ERR_LD_ST:
+ return "bus error on load or store";
+
+ case T_SYSCALL:
+ return "system call";
+
+ case T_BREAK:
+ return "breakpoint";
+
+ case T_RES_INST:
+ return "reserved instruction";
+
+ case T_COP_UNUSABLE:
+ return "coprocessor unusable";
+
+ case T_OVFLOW:
+ return "arithmetic overflow";
+
+ case T_TRAP:
+ return "trap instruction";
+
+ case T_VCEI:
+ return "virtual coherency instruction";
+
+ case T_FPE:
+ return "floating point";
+
+ case T_IWATCH:
+ return "iwatch";
+
+ case T_DWATCH:
+ return "dwatch";
+
+ case T_VCED:
+ return "virtual coherency data";
+ }
+
+ return "unknown exception";
+}
+
+void barebox_exc_handler(void *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());
+
+ hang();
+}
--
1.7.10
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] MIPS: add initial exceptions handling 2012-07-25 22:00 [PATCH] MIPS: add initial exceptions handling Antony Pavlov @ 2012-07-27 7:48 ` Sascha Hauer 2012-07-27 7:49 ` Antony Pavlov 0 siblings, 1 reply; 4+ messages in thread From: Sascha Hauer @ 2012-07-27 7:48 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox Hi Antony, Looks fine from my perspective. Should I apply this one? Sascha On Thu, Jul 26, 2012 at 02:00:27AM +0400, Antony Pavlov wrote: > Checking exception handling: > > $ make qemu-malta_defconfig > $ make > > ... > > $ qemu-system-mips -nodefaults -M malta -m 256 \ > -nographic -serial stdio -bios ./barebox.bin > > ... > > barebox:/ md -l 0x03 > > Ooops, address error on load or ifetch! > EPC = 0xa082783c > CP0_STATUS = 0x00000006 > CP0_CAUSE = 0x00000410 > CP0_CONFIG = 0x80008482 > > ### ERROR ### Please RESET the board ### > > Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > --- > arch/mips/boot/main_entry.c | 47 ++++++++++++++++ > arch/mips/include/asm/addrspace.h | 109 +++++++++++++++++++++++++++++++++++++ > arch/mips/lib/Makefile | 2 + > arch/mips/lib/genex.S | 31 +++++++++++ > arch/mips/lib/traps.c | 107 ++++++++++++++++++++++++++++++++++++ > 5 files changed, 296 insertions(+) > create mode 100644 arch/mips/include/asm/addrspace.h > create mode 100644 arch/mips/lib/genex.S > create mode 100644 arch/mips/lib/traps.c > > diff --git a/arch/mips/boot/main_entry.c b/arch/mips/boot/main_entry.c > index 8f5f6fc..a38ad31 100644 > --- a/arch/mips/boot/main_entry.c > +++ b/arch/mips/boot/main_entry.c > @@ -25,11 +25,56 @@ > #include <string.h> > #include <asm/sections.h> > #include <asm/cpu-features.h> > +#include <asm/mipsregs.h> > +#include <asm/addrspace.h> > > extern void start_barebox(void); > +extern void handle_reserved(void); > > void main_entry(void); > > +unsigned long exception_handlers[32]; > + > +static void set_except_vector(int n, void *addr) > +{ > + unsigned handler = (unsigned long) addr; > + > + exception_handlers[n] = handler; > +} > + > +static void trap_init(void) > +{ > + extern char except_vec3_generic; > + int i; > + > + unsigned long ebase; > + > + ebase = CKSEG1; > + > + /* > + * Copy the generic exception handlers to their final destination. > + * This will be overriden later as suitable for a particular > + * configuration. > + */ > + memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80); > + > + /* > + * Setup default vectors > + */ > + for (i = 0; i <= 31; i++) { > + set_except_vector(i, &handle_reserved); > + } > + > + if (!cpu_has_4kex) > + memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80); > + > + /* FIXME: handle tlb */ > + memcpy((void *)(ebase), &except_vec3_generic, 0x80); > + > + /* unset BOOT EXCEPTION VECTOR bit */ > + write_c0_status(read_c0_status() & ~ST0_BEV); > +} > + > /** > * Called plainly from assembler code > * > @@ -48,5 +93,7 @@ void main_entry(void) > r4k_cache_init(); > } > > + trap_init(); > + > start_barebox(); > } > diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h > new file mode 100644 > index 0000000..17d480d > --- /dev/null > +++ b/arch/mips/include/asm/addrspace.h > @@ -0,0 +1,109 @@ > +/* > + * 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) 1996, 99 Ralf Baechle > + * Copyright (C) 2000, 2002 Maciej W. Rozycki > + * Copyright (C) 1990, 1999 by Silicon Graphics, Inc. > + */ > +#ifndef _ASM_ADDRSPACE_H > +#define _ASM_ADDRSPACE_H > + > +/* > + * Configure language > + */ > +#ifdef __ASSEMBLY__ > +#define _ATYPE_ > +#define _ATYPE32_ > +#define _ATYPE64_ > +#define _CONST64_(x) x > +#else > +#define _ATYPE_ __PTRDIFF_TYPE__ > +#define _ATYPE32_ int > +#define _ATYPE64_ __s64 > +#ifdef CONFIG_64BIT > +#define _CONST64_(x) x ## L > +#else > +#define _CONST64_(x) x ## LL > +#endif > +#endif > + > +/* > + * 32-bit MIPS address spaces > + */ > +#ifdef __ASSEMBLY__ > +#define _ACAST32_ > +#define _ACAST64_ > +#else > +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ > +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ > +#endif > + > +/* > + * Returns the kernel segment base of a given address > + */ > +#define KSEGX(a) ((_ACAST32_(a)) & 0xe0000000) > + > +/* > + * Returns the physical address of a CKSEGx / XKPHYS address > + */ > +#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) > +#define XPHYSADDR(a) ((_ACAST64_(a)) & \ > + _CONST64_(0x000000ffffffffff)) > + > +#ifdef CONFIG_64BIT > + > +/* > + * Memory segments (64bit kernel mode addresses) > + * The compatibility segments use the full 64-bit sign extended value. Note > + * the R8000 doesn't have them so don't reference these in generic MIPS code. > + */ > +#define XKUSEG _CONST64_(0x0000000000000000) > +#define XKSSEG _CONST64_(0x4000000000000000) > +#define XKPHYS _CONST64_(0x8000000000000000) > +#define XKSEG _CONST64_(0xc000000000000000) > +#define CKSEG0 _CONST64_(0xffffffff80000000) > +#define CKSEG1 _CONST64_(0xffffffffa0000000) > +#define CKSSEG _CONST64_(0xffffffffc0000000) > +#define CKSEG3 _CONST64_(0xffffffffe0000000) > + > +#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0) > +#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1) > +#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2) > +#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3) > + > +#else > + > +#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) > +#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) > +#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) > +#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) > + > +/* > + * Map an address to a certain kernel segment > + */ > +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) > +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) > +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) > +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) > + > +/* > + * Memory segments (32bit kernel mode addresses) > + * These are the traditional names used in the 32-bit universe. > + */ > +#define KUSEG 0x00000000 > +#define KSEG0 0x80000000 > +#define KSEG1 0xa0000000 > +#define KSEG2 0xc0000000 > +#define KSEG3 0xe0000000 > + > +#define CKUSEG 0x00000000 > +#define CKSEG0 0x80000000 > +#define CKSEG1 0xa0000000 > +#define CKSEG2 0xc0000000 > +#define CKSEG3 0xe0000000 > + > +#endif > + > +#endif /* _ASM_ADDRSPACE_H */ > diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile > index b99bb71..a31046b 100644 > --- a/arch/mips/lib/Makefile > +++ b/arch/mips/lib/Makefile > @@ -5,6 +5,8 @@ obj-y += ashldi3.o > obj-y += ashrdi3.o > obj-y += memory.o > obj-y += cpu-probe.o > +obj-y += traps.o > +obj-y += genex.o > > obj-$(CONFIG_CPU_MIPS32) += c-r4k.o > obj-$(CONFIG_CPU_MIPS64) += c-r4k.o > diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S > new file mode 100644 > index 0000000..d6f65a2 > --- /dev/null > +++ b/arch/mips/lib/genex.S > @@ -0,0 +1,31 @@ > +#include <asm/asm.h> > +#include <asm/regdef.h> > +#include <asm/mipsregs.h> > + > + .text > + .set macro > + .set noat > + .set noreorder > + .align 5 > + > +/* Exception vector */ > +NESTED(handle_reserved, 0, sp) > + la k0, barebox_exc_handler > + jal k0 > + move a0, sp > + /* will never return here */ > + END(handle_reserved) > + > +/* General exception vector */ > +NESTED(except_vec3_generic, 0, sp) > + .set noat > + mfc0 k1, CP0_CAUSE > + la k0, exception_handlers > + andi k1, k1, 0x7c > + addu k0, k0, k1 > + lw k0, (k0) > + nop > + jr k0 > + nop > + END(except_vec3_generic) > + .set at > diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c > new file mode 100644 > index 0000000..4e167cc > --- /dev/null > +++ b/arch/mips/lib/traps.c > @@ -0,0 +1,107 @@ > +#include <common.h> > + > +#include <asm/mipsregs.h> > + > +void barebox_exc_handler(void *regs); > + > +/* > + * Trap codes from OpenBSD trap.h > + */ > +#define T_INT 0 /* Interrupt pending */ > +#define T_TLB_MOD 1 /* TLB modified fault */ > +#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ > +#define T_TLB_ST_MISS 3 /* TLB miss on a store */ > +#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ > +#define T_ADDR_ERR_ST 5 /* Address error on a store */ > +#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ > +#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ > +#define T_SYSCALL 8 /* System call */ > +#define T_BREAK 9 /* Breakpoint */ > +#define T_RES_INST 10 /* Reserved instruction exception */ > +#define T_COP_UNUSABLE 11 /* Coprocessor unusable */ > +#define T_OVFLOW 12 /* Arithmetic overflow */ > +#define T_TRAP 13 /* Trap instruction */ > +#define T_VCEI 14 /* Virtual coherency instruction */ > +#define T_FPE 15 /* Floating point exception */ > +#define T_IWATCH 16 /* Inst. Watch address reference */ > +#define T_DWATCH 23 /* Data Watch address reference */ > +#define T_VCED 31 /* Virtual coherency data */ > + > +#define CR_EXC_CODE 0x0000007c > +#define CR_EXC_CODE_SHIFT 2 > + > +static char *get_exc_name(u32 cause) > +{ > + switch ((cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) { > + > + case T_INT: > + return "interrupt pending"; > + > + case T_TLB_MOD: > + return "TLB modified"; > + > + case T_TLB_LD_MISS: > + return "TLB miss on load or ifetch"; > + > + case T_TLB_ST_MISS: > + return "TLB miss on store"; > + > + case T_ADDR_ERR_LD: > + return "address error on load or ifetch"; > + > + case T_ADDR_ERR_ST: > + return "address error on store"; > + > + case T_BUS_ERR_IFETCH: > + return "bus error on ifetch"; > + > + case T_BUS_ERR_LD_ST: > + return "bus error on load or store"; > + > + case T_SYSCALL: > + return "system call"; > + > + case T_BREAK: > + return "breakpoint"; > + > + case T_RES_INST: > + return "reserved instruction"; > + > + case T_COP_UNUSABLE: > + return "coprocessor unusable"; > + > + case T_OVFLOW: > + return "arithmetic overflow"; > + > + case T_TRAP: > + return "trap instruction"; > + > + case T_VCEI: > + return "virtual coherency instruction"; > + > + case T_FPE: > + return "floating point"; > + > + case T_IWATCH: > + return "iwatch"; > + > + case T_DWATCH: > + return "dwatch"; > + > + case T_VCED: > + return "virtual coherency data"; > + } > + > + return "unknown exception"; > +} > + > +void barebox_exc_handler(void *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()); > + > + hang(); > +} > -- > 1.7.10 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] MIPS: add initial exceptions handling 2012-07-27 7:48 ` Sascha Hauer @ 2012-07-27 7:49 ` Antony Pavlov 2012-07-27 8:05 ` Sascha Hauer 0 siblings, 1 reply; 4+ messages in thread From: Antony Pavlov @ 2012-07-27 7:49 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox On 27 July 2012 11:48, Sascha Hauer <s.hauer@pengutronix.de> wrote: > Hi Antony, > > Looks fine from my perspective. Should I apply this one? Apply this one please. > On Thu, Jul 26, 2012 at 02:00:27AM +0400, Antony Pavlov wrote: >> Checking exception handling: >> >> $ make qemu-malta_defconfig >> $ make >> >> ... >> >> $ qemu-system-mips -nodefaults -M malta -m 256 \ >> -nographic -serial stdio -bios ./barebox.bin >> >> ... >> >> barebox:/ md -l 0x03 >> >> Ooops, address error on load or ifetch! >> EPC = 0xa082783c >> CP0_STATUS = 0x00000006 >> CP0_CAUSE = 0x00000410 >> CP0_CONFIG = 0x80008482 >> >> ### ERROR ### Please RESET the board ### >> >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> >> --- >> arch/mips/boot/main_entry.c | 47 ++++++++++++++++ >> arch/mips/include/asm/addrspace.h | 109 +++++++++++++++++++++++++++++++++++++ >> arch/mips/lib/Makefile | 2 + >> arch/mips/lib/genex.S | 31 +++++++++++ >> arch/mips/lib/traps.c | 107 ++++++++++++++++++++++++++++++++++++ >> 5 files changed, 296 insertions(+) >> create mode 100644 arch/mips/include/asm/addrspace.h >> create mode 100644 arch/mips/lib/genex.S >> create mode 100644 arch/mips/lib/traps.c >> >> diff --git a/arch/mips/boot/main_entry.c b/arch/mips/boot/main_entry.c >> index 8f5f6fc..a38ad31 100644 >> --- a/arch/mips/boot/main_entry.c >> +++ b/arch/mips/boot/main_entry.c >> @@ -25,11 +25,56 @@ >> #include <string.h> >> #include <asm/sections.h> >> #include <asm/cpu-features.h> >> +#include <asm/mipsregs.h> >> +#include <asm/addrspace.h> >> >> extern void start_barebox(void); >> +extern void handle_reserved(void); >> >> void main_entry(void); >> >> +unsigned long exception_handlers[32]; >> + >> +static void set_except_vector(int n, void *addr) >> +{ >> + unsigned handler = (unsigned long) addr; >> + >> + exception_handlers[n] = handler; >> +} >> + >> +static void trap_init(void) >> +{ >> + extern char except_vec3_generic; >> + int i; >> + >> + unsigned long ebase; >> + >> + ebase = CKSEG1; >> + >> + /* >> + * Copy the generic exception handlers to their final destination. >> + * This will be overriden later as suitable for a particular >> + * configuration. >> + */ >> + memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80); >> + >> + /* >> + * Setup default vectors >> + */ >> + for (i = 0; i <= 31; i++) { >> + set_except_vector(i, &handle_reserved); >> + } >> + >> + if (!cpu_has_4kex) >> + memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80); >> + >> + /* FIXME: handle tlb */ >> + memcpy((void *)(ebase), &except_vec3_generic, 0x80); >> + >> + /* unset BOOT EXCEPTION VECTOR bit */ >> + write_c0_status(read_c0_status() & ~ST0_BEV); >> +} >> + >> /** >> * Called plainly from assembler code >> * >> @@ -48,5 +93,7 @@ void main_entry(void) >> r4k_cache_init(); >> } >> >> + trap_init(); >> + >> start_barebox(); >> } >> diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h >> new file mode 100644 >> index 0000000..17d480d >> --- /dev/null >> +++ b/arch/mips/include/asm/addrspace.h >> @@ -0,0 +1,109 @@ >> +/* >> + * 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) 1996, 99 Ralf Baechle >> + * Copyright (C) 2000, 2002 Maciej W. Rozycki >> + * Copyright (C) 1990, 1999 by Silicon Graphics, Inc. >> + */ >> +#ifndef _ASM_ADDRSPACE_H >> +#define _ASM_ADDRSPACE_H >> + >> +/* >> + * Configure language >> + */ >> +#ifdef __ASSEMBLY__ >> +#define _ATYPE_ >> +#define _ATYPE32_ >> +#define _ATYPE64_ >> +#define _CONST64_(x) x >> +#else >> +#define _ATYPE_ __PTRDIFF_TYPE__ >> +#define _ATYPE32_ int >> +#define _ATYPE64_ __s64 >> +#ifdef CONFIG_64BIT >> +#define _CONST64_(x) x ## L >> +#else >> +#define _CONST64_(x) x ## LL >> +#endif >> +#endif >> + >> +/* >> + * 32-bit MIPS address spaces >> + */ >> +#ifdef __ASSEMBLY__ >> +#define _ACAST32_ >> +#define _ACAST64_ >> +#else >> +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ >> +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ >> +#endif >> + >> +/* >> + * Returns the kernel segment base of a given address >> + */ >> +#define KSEGX(a) ((_ACAST32_(a)) & 0xe0000000) >> + >> +/* >> + * Returns the physical address of a CKSEGx / XKPHYS address >> + */ >> +#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) >> +#define XPHYSADDR(a) ((_ACAST64_(a)) & \ >> + _CONST64_(0x000000ffffffffff)) >> + >> +#ifdef CONFIG_64BIT >> + >> +/* >> + * Memory segments (64bit kernel mode addresses) >> + * The compatibility segments use the full 64-bit sign extended value. Note >> + * the R8000 doesn't have them so don't reference these in generic MIPS code. >> + */ >> +#define XKUSEG _CONST64_(0x0000000000000000) >> +#define XKSSEG _CONST64_(0x4000000000000000) >> +#define XKPHYS _CONST64_(0x8000000000000000) >> +#define XKSEG _CONST64_(0xc000000000000000) >> +#define CKSEG0 _CONST64_(0xffffffff80000000) >> +#define CKSEG1 _CONST64_(0xffffffffa0000000) >> +#define CKSSEG _CONST64_(0xffffffffc0000000) >> +#define CKSEG3 _CONST64_(0xffffffffe0000000) >> + >> +#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0) >> +#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1) >> +#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2) >> +#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3) >> + >> +#else >> + >> +#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) >> +#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) >> +#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) >> +#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) >> + >> +/* >> + * Map an address to a certain kernel segment >> + */ >> +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) >> +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) >> +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) >> +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) >> + >> +/* >> + * Memory segments (32bit kernel mode addresses) >> + * These are the traditional names used in the 32-bit universe. >> + */ >> +#define KUSEG 0x00000000 >> +#define KSEG0 0x80000000 >> +#define KSEG1 0xa0000000 >> +#define KSEG2 0xc0000000 >> +#define KSEG3 0xe0000000 >> + >> +#define CKUSEG 0x00000000 >> +#define CKSEG0 0x80000000 >> +#define CKSEG1 0xa0000000 >> +#define CKSEG2 0xc0000000 >> +#define CKSEG3 0xe0000000 >> + >> +#endif >> + >> +#endif /* _ASM_ADDRSPACE_H */ >> diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile >> index b99bb71..a31046b 100644 >> --- a/arch/mips/lib/Makefile >> +++ b/arch/mips/lib/Makefile >> @@ -5,6 +5,8 @@ obj-y += ashldi3.o >> obj-y += ashrdi3.o >> obj-y += memory.o >> obj-y += cpu-probe.o >> +obj-y += traps.o >> +obj-y += genex.o >> >> obj-$(CONFIG_CPU_MIPS32) += c-r4k.o >> obj-$(CONFIG_CPU_MIPS64) += c-r4k.o >> diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S >> new file mode 100644 >> index 0000000..d6f65a2 >> --- /dev/null >> +++ b/arch/mips/lib/genex.S >> @@ -0,0 +1,31 @@ >> +#include <asm/asm.h> >> +#include <asm/regdef.h> >> +#include <asm/mipsregs.h> >> + >> + .text >> + .set macro >> + .set noat >> + .set noreorder >> + .align 5 >> + >> +/* Exception vector */ >> +NESTED(handle_reserved, 0, sp) >> + la k0, barebox_exc_handler >> + jal k0 >> + move a0, sp >> + /* will never return here */ >> + END(handle_reserved) >> + >> +/* General exception vector */ >> +NESTED(except_vec3_generic, 0, sp) >> + .set noat >> + mfc0 k1, CP0_CAUSE >> + la k0, exception_handlers >> + andi k1, k1, 0x7c >> + addu k0, k0, k1 >> + lw k0, (k0) >> + nop >> + jr k0 >> + nop >> + END(except_vec3_generic) >> + .set at >> diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c >> new file mode 100644 >> index 0000000..4e167cc >> --- /dev/null >> +++ b/arch/mips/lib/traps.c >> @@ -0,0 +1,107 @@ >> +#include <common.h> >> + >> +#include <asm/mipsregs.h> >> + >> +void barebox_exc_handler(void *regs); >> + >> +/* >> + * Trap codes from OpenBSD trap.h >> + */ >> +#define T_INT 0 /* Interrupt pending */ >> +#define T_TLB_MOD 1 /* TLB modified fault */ >> +#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ >> +#define T_TLB_ST_MISS 3 /* TLB miss on a store */ >> +#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ >> +#define T_ADDR_ERR_ST 5 /* Address error on a store */ >> +#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ >> +#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ >> +#define T_SYSCALL 8 /* System call */ >> +#define T_BREAK 9 /* Breakpoint */ >> +#define T_RES_INST 10 /* Reserved instruction exception */ >> +#define T_COP_UNUSABLE 11 /* Coprocessor unusable */ >> +#define T_OVFLOW 12 /* Arithmetic overflow */ >> +#define T_TRAP 13 /* Trap instruction */ >> +#define T_VCEI 14 /* Virtual coherency instruction */ >> +#define T_FPE 15 /* Floating point exception */ >> +#define T_IWATCH 16 /* Inst. Watch address reference */ >> +#define T_DWATCH 23 /* Data Watch address reference */ >> +#define T_VCED 31 /* Virtual coherency data */ >> + >> +#define CR_EXC_CODE 0x0000007c >> +#define CR_EXC_CODE_SHIFT 2 >> + >> +static char *get_exc_name(u32 cause) >> +{ >> + switch ((cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) { >> + >> + case T_INT: >> + return "interrupt pending"; >> + >> + case T_TLB_MOD: >> + return "TLB modified"; >> + >> + case T_TLB_LD_MISS: >> + return "TLB miss on load or ifetch"; >> + >> + case T_TLB_ST_MISS: >> + return "TLB miss on store"; >> + >> + case T_ADDR_ERR_LD: >> + return "address error on load or ifetch"; >> + >> + case T_ADDR_ERR_ST: >> + return "address error on store"; >> + >> + case T_BUS_ERR_IFETCH: >> + return "bus error on ifetch"; >> + >> + case T_BUS_ERR_LD_ST: >> + return "bus error on load or store"; >> + >> + case T_SYSCALL: >> + return "system call"; >> + >> + case T_BREAK: >> + return "breakpoint"; >> + >> + case T_RES_INST: >> + return "reserved instruction"; >> + >> + case T_COP_UNUSABLE: >> + return "coprocessor unusable"; >> + >> + case T_OVFLOW: >> + return "arithmetic overflow"; >> + >> + case T_TRAP: >> + return "trap instruction"; >> + >> + case T_VCEI: >> + return "virtual coherency instruction"; >> + >> + case T_FPE: >> + return "floating point"; >> + >> + case T_IWATCH: >> + return "iwatch"; >> + >> + case T_DWATCH: >> + return "dwatch"; >> + >> + case T_VCED: >> + return "virtual coherency data"; >> + } >> + >> + return "unknown exception"; >> +} >> + >> +void barebox_exc_handler(void *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()); >> + >> + hang(); >> +} >> -- >> 1.7.10 >> >> >> _______________________________________________ >> barebox mailing list >> barebox@lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/barebox >> > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | -- Best regards, Antony Pavlov _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] MIPS: add initial exceptions handling 2012-07-27 7:49 ` Antony Pavlov @ 2012-07-27 8:05 ` Sascha Hauer 0 siblings, 0 replies; 4+ messages in thread From: Sascha Hauer @ 2012-07-27 8:05 UTC (permalink / raw) To: Antony Pavlov; +Cc: barebox On Fri, Jul 27, 2012 at 11:49:43AM +0400, Antony Pavlov wrote: > On 27 July 2012 11:48, Sascha Hauer <s.hauer@pengutronix.de> wrote: > > Hi Antony, > > > > Looks fine from my perspective. Should I apply this one? > > Apply this one please. Ok, did that. Thanks Sascha > > > On Thu, Jul 26, 2012 at 02:00:27AM +0400, Antony Pavlov wrote: > >> Checking exception handling: > >> > >> $ make qemu-malta_defconfig > >> $ make > >> > >> ... > >> > >> $ qemu-system-mips -nodefaults -M malta -m 256 \ > >> -nographic -serial stdio -bios ./barebox.bin > >> > >> ... > >> > >> barebox:/ md -l 0x03 > >> > >> Ooops, address error on load or ifetch! > >> EPC = 0xa082783c > >> CP0_STATUS = 0x00000006 > >> CP0_CAUSE = 0x00000410 > >> CP0_CONFIG = 0x80008482 > >> > >> ### ERROR ### Please RESET the board ### > >> > >> Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> > >> --- > >> arch/mips/boot/main_entry.c | 47 ++++++++++++++++ > >> arch/mips/include/asm/addrspace.h | 109 +++++++++++++++++++++++++++++++++++++ > >> arch/mips/lib/Makefile | 2 + > >> arch/mips/lib/genex.S | 31 +++++++++++ > >> arch/mips/lib/traps.c | 107 ++++++++++++++++++++++++++++++++++++ > >> 5 files changed, 296 insertions(+) > >> create mode 100644 arch/mips/include/asm/addrspace.h > >> create mode 100644 arch/mips/lib/genex.S > >> create mode 100644 arch/mips/lib/traps.c > >> > >> diff --git a/arch/mips/boot/main_entry.c b/arch/mips/boot/main_entry.c > >> index 8f5f6fc..a38ad31 100644 > >> --- a/arch/mips/boot/main_entry.c > >> +++ b/arch/mips/boot/main_entry.c > >> @@ -25,11 +25,56 @@ > >> #include <string.h> > >> #include <asm/sections.h> > >> #include <asm/cpu-features.h> > >> +#include <asm/mipsregs.h> > >> +#include <asm/addrspace.h> > >> > >> extern void start_barebox(void); > >> +extern void handle_reserved(void); > >> > >> void main_entry(void); > >> > >> +unsigned long exception_handlers[32]; > >> + > >> +static void set_except_vector(int n, void *addr) > >> +{ > >> + unsigned handler = (unsigned long) addr; > >> + > >> + exception_handlers[n] = handler; > >> +} > >> + > >> +static void trap_init(void) > >> +{ > >> + extern char except_vec3_generic; > >> + int i; > >> + > >> + unsigned long ebase; > >> + > >> + ebase = CKSEG1; > >> + > >> + /* > >> + * Copy the generic exception handlers to their final destination. > >> + * This will be overriden later as suitable for a particular > >> + * configuration. > >> + */ > >> + memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80); > >> + > >> + /* > >> + * Setup default vectors > >> + */ > >> + for (i = 0; i <= 31; i++) { > >> + set_except_vector(i, &handle_reserved); > >> + } > >> + > >> + if (!cpu_has_4kex) > >> + memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80); > >> + > >> + /* FIXME: handle tlb */ > >> + memcpy((void *)(ebase), &except_vec3_generic, 0x80); > >> + > >> + /* unset BOOT EXCEPTION VECTOR bit */ > >> + write_c0_status(read_c0_status() & ~ST0_BEV); > >> +} > >> + > >> /** > >> * Called plainly from assembler code > >> * > >> @@ -48,5 +93,7 @@ void main_entry(void) > >> r4k_cache_init(); > >> } > >> > >> + trap_init(); > >> + > >> start_barebox(); > >> } > >> diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h > >> new file mode 100644 > >> index 0000000..17d480d > >> --- /dev/null > >> +++ b/arch/mips/include/asm/addrspace.h > >> @@ -0,0 +1,109 @@ > >> +/* > >> + * 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) 1996, 99 Ralf Baechle > >> + * Copyright (C) 2000, 2002 Maciej W. Rozycki > >> + * Copyright (C) 1990, 1999 by Silicon Graphics, Inc. > >> + */ > >> +#ifndef _ASM_ADDRSPACE_H > >> +#define _ASM_ADDRSPACE_H > >> + > >> +/* > >> + * Configure language > >> + */ > >> +#ifdef __ASSEMBLY__ > >> +#define _ATYPE_ > >> +#define _ATYPE32_ > >> +#define _ATYPE64_ > >> +#define _CONST64_(x) x > >> +#else > >> +#define _ATYPE_ __PTRDIFF_TYPE__ > >> +#define _ATYPE32_ int > >> +#define _ATYPE64_ __s64 > >> +#ifdef CONFIG_64BIT > >> +#define _CONST64_(x) x ## L > >> +#else > >> +#define _CONST64_(x) x ## LL > >> +#endif > >> +#endif > >> + > >> +/* > >> + * 32-bit MIPS address spaces > >> + */ > >> +#ifdef __ASSEMBLY__ > >> +#define _ACAST32_ > >> +#define _ACAST64_ > >> +#else > >> +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ > >> +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ > >> +#endif > >> + > >> +/* > >> + * Returns the kernel segment base of a given address > >> + */ > >> +#define KSEGX(a) ((_ACAST32_(a)) & 0xe0000000) > >> + > >> +/* > >> + * Returns the physical address of a CKSEGx / XKPHYS address > >> + */ > >> +#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) > >> +#define XPHYSADDR(a) ((_ACAST64_(a)) & \ > >> + _CONST64_(0x000000ffffffffff)) > >> + > >> +#ifdef CONFIG_64BIT > >> + > >> +/* > >> + * Memory segments (64bit kernel mode addresses) > >> + * The compatibility segments use the full 64-bit sign extended value. Note > >> + * the R8000 doesn't have them so don't reference these in generic MIPS code. > >> + */ > >> +#define XKUSEG _CONST64_(0x0000000000000000) > >> +#define XKSSEG _CONST64_(0x4000000000000000) > >> +#define XKPHYS _CONST64_(0x8000000000000000) > >> +#define XKSEG _CONST64_(0xc000000000000000) > >> +#define CKSEG0 _CONST64_(0xffffffff80000000) > >> +#define CKSEG1 _CONST64_(0xffffffffa0000000) > >> +#define CKSSEG _CONST64_(0xffffffffc0000000) > >> +#define CKSEG3 _CONST64_(0xffffffffe0000000) > >> + > >> +#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0) > >> +#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1) > >> +#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2) > >> +#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3) > >> + > >> +#else > >> + > >> +#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) > >> +#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) > >> +#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) > >> +#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) > >> + > >> +/* > >> + * Map an address to a certain kernel segment > >> + */ > >> +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) > >> +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) > >> +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) > >> +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) > >> + > >> +/* > >> + * Memory segments (32bit kernel mode addresses) > >> + * These are the traditional names used in the 32-bit universe. > >> + */ > >> +#define KUSEG 0x00000000 > >> +#define KSEG0 0x80000000 > >> +#define KSEG1 0xa0000000 > >> +#define KSEG2 0xc0000000 > >> +#define KSEG3 0xe0000000 > >> + > >> +#define CKUSEG 0x00000000 > >> +#define CKSEG0 0x80000000 > >> +#define CKSEG1 0xa0000000 > >> +#define CKSEG2 0xc0000000 > >> +#define CKSEG3 0xe0000000 > >> + > >> +#endif > >> + > >> +#endif /* _ASM_ADDRSPACE_H */ > >> diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile > >> index b99bb71..a31046b 100644 > >> --- a/arch/mips/lib/Makefile > >> +++ b/arch/mips/lib/Makefile > >> @@ -5,6 +5,8 @@ obj-y += ashldi3.o > >> obj-y += ashrdi3.o > >> obj-y += memory.o > >> obj-y += cpu-probe.o > >> +obj-y += traps.o > >> +obj-y += genex.o > >> > >> obj-$(CONFIG_CPU_MIPS32) += c-r4k.o > >> obj-$(CONFIG_CPU_MIPS64) += c-r4k.o > >> diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S > >> new file mode 100644 > >> index 0000000..d6f65a2 > >> --- /dev/null > >> +++ b/arch/mips/lib/genex.S > >> @@ -0,0 +1,31 @@ > >> +#include <asm/asm.h> > >> +#include <asm/regdef.h> > >> +#include <asm/mipsregs.h> > >> + > >> + .text > >> + .set macro > >> + .set noat > >> + .set noreorder > >> + .align 5 > >> + > >> +/* Exception vector */ > >> +NESTED(handle_reserved, 0, sp) > >> + la k0, barebox_exc_handler > >> + jal k0 > >> + move a0, sp > >> + /* will never return here */ > >> + END(handle_reserved) > >> + > >> +/* General exception vector */ > >> +NESTED(except_vec3_generic, 0, sp) > >> + .set noat > >> + mfc0 k1, CP0_CAUSE > >> + la k0, exception_handlers > >> + andi k1, k1, 0x7c > >> + addu k0, k0, k1 > >> + lw k0, (k0) > >> + nop > >> + jr k0 > >> + nop > >> + END(except_vec3_generic) > >> + .set at > >> diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c > >> new file mode 100644 > >> index 0000000..4e167cc > >> --- /dev/null > >> +++ b/arch/mips/lib/traps.c > >> @@ -0,0 +1,107 @@ > >> +#include <common.h> > >> + > >> +#include <asm/mipsregs.h> > >> + > >> +void barebox_exc_handler(void *regs); > >> + > >> +/* > >> + * Trap codes from OpenBSD trap.h > >> + */ > >> +#define T_INT 0 /* Interrupt pending */ > >> +#define T_TLB_MOD 1 /* TLB modified fault */ > >> +#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ > >> +#define T_TLB_ST_MISS 3 /* TLB miss on a store */ > >> +#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ > >> +#define T_ADDR_ERR_ST 5 /* Address error on a store */ > >> +#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ > >> +#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ > >> +#define T_SYSCALL 8 /* System call */ > >> +#define T_BREAK 9 /* Breakpoint */ > >> +#define T_RES_INST 10 /* Reserved instruction exception */ > >> +#define T_COP_UNUSABLE 11 /* Coprocessor unusable */ > >> +#define T_OVFLOW 12 /* Arithmetic overflow */ > >> +#define T_TRAP 13 /* Trap instruction */ > >> +#define T_VCEI 14 /* Virtual coherency instruction */ > >> +#define T_FPE 15 /* Floating point exception */ > >> +#define T_IWATCH 16 /* Inst. Watch address reference */ > >> +#define T_DWATCH 23 /* Data Watch address reference */ > >> +#define T_VCED 31 /* Virtual coherency data */ > >> + > >> +#define CR_EXC_CODE 0x0000007c > >> +#define CR_EXC_CODE_SHIFT 2 > >> + > >> +static char *get_exc_name(u32 cause) > >> +{ > >> + switch ((cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) { > >> + > >> + case T_INT: > >> + return "interrupt pending"; > >> + > >> + case T_TLB_MOD: > >> + return "TLB modified"; > >> + > >> + case T_TLB_LD_MISS: > >> + return "TLB miss on load or ifetch"; > >> + > >> + case T_TLB_ST_MISS: > >> + return "TLB miss on store"; > >> + > >> + case T_ADDR_ERR_LD: > >> + return "address error on load or ifetch"; > >> + > >> + case T_ADDR_ERR_ST: > >> + return "address error on store"; > >> + > >> + case T_BUS_ERR_IFETCH: > >> + return "bus error on ifetch"; > >> + > >> + case T_BUS_ERR_LD_ST: > >> + return "bus error on load or store"; > >> + > >> + case T_SYSCALL: > >> + return "system call"; > >> + > >> + case T_BREAK: > >> + return "breakpoint"; > >> + > >> + case T_RES_INST: > >> + return "reserved instruction"; > >> + > >> + case T_COP_UNUSABLE: > >> + return "coprocessor unusable"; > >> + > >> + case T_OVFLOW: > >> + return "arithmetic overflow"; > >> + > >> + case T_TRAP: > >> + return "trap instruction"; > >> + > >> + case T_VCEI: > >> + return "virtual coherency instruction"; > >> + > >> + case T_FPE: > >> + return "floating point"; > >> + > >> + case T_IWATCH: > >> + return "iwatch"; > >> + > >> + case T_DWATCH: > >> + return "dwatch"; > >> + > >> + case T_VCED: > >> + return "virtual coherency data"; > >> + } > >> + > >> + return "unknown exception"; > >> +} > >> + > >> +void barebox_exc_handler(void *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()); > >> + > >> + hang(); > >> +} > >> -- > >> 1.7.10 > >> > >> > >> _______________________________________________ > >> barebox mailing list > >> barebox@lists.infradead.org > >> http://lists.infradead.org/mailman/listinfo/barebox > >> > > > > -- > > Pengutronix e.K. | | > > Industrial Linux Solutions | http://www.pengutronix.de/ | > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | > > > > -- > Best regards, > Antony Pavlov > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-07-27 8:05 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-07-25 22:00 [PATCH] MIPS: add initial exceptions handling Antony Pavlov 2012-07-27 7:48 ` Sascha Hauer 2012-07-27 7:49 ` Antony Pavlov 2012-07-27 8:05 ` Sascha Hauer
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.