All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Antony Pavlov <antonynpavlov@gmail.com>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH] MIPS: add initial exceptions handling
Date: Fri, 27 Jul 2012 09:48:05 +0200	[thread overview]
Message-ID: <20120727074805.GU30009@pengutronix.de> (raw)
In-Reply-To: <1343253627-5247-1-git-send-email-antonynpavlov@gmail.com>

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

  reply	other threads:[~2012-07-27  7:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-25 22:00 [PATCH] MIPS: add initial exceptions handling Antony Pavlov
2012-07-27  7:48 ` Sascha Hauer [this message]
2012-07-27  7:49   ` Antony Pavlov
2012-07-27  8:05     ` Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120727074805.GU30009@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=antonynpavlov@gmail.com \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.