[U-Boot] [PATCH 3/9] openrisc: Add cpu files

Marek Vasut marek.vasut at gmail.com
Mon Nov 21 23:50:17 CET 2011


> Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
> ---
>  arch/openrisc/config.mk        |   27 ++++
>  arch/openrisc/cpu/Makefile     |   47 ++++++
>  arch/openrisc/cpu/cache.c      |  157 +++++++++++++++++++
>  arch/openrisc/cpu/cpu.c        |  157 +++++++++++++++++++
>  arch/openrisc/cpu/exceptions.c |  109 +++++++++++++
>  arch/openrisc/cpu/interrupts.c |  120 ++++++++++++++
>  arch/openrisc/cpu/start.S      |  335
> ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 952
> insertions(+), 0 deletions(-)
>  create mode 100644 arch/openrisc/config.mk
>  create mode 100644 arch/openrisc/cpu/Makefile
>  create mode 100644 arch/openrisc/cpu/cache.c
>  create mode 100644 arch/openrisc/cpu/cpu.c
>  create mode 100644 arch/openrisc/cpu/exceptions.c
>  create mode 100644 arch/openrisc/cpu/interrupts.c
>  create mode 100644 arch/openrisc/cpu/start.S
> 
> diff --git a/arch/openrisc/config.mk b/arch/openrisc/config.mk
> new file mode 100644
> index 0000000..bea3d12
> --- /dev/null
> +++ b/arch/openrisc/config.mk
> @@ -0,0 +1,27 @@
> +#
> +# (C) Copyright 2011
> +# Julius Baxter <julius at opencores.org>
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +CROSS_COMPILE ?= or32-elf-
> +
> +# r10 used for global object pointer, already set in OR32 GCC but just to
> be +# clear
> +PLATFORM_CPPFLAGS += -DCONFIG_OPENRISC -D__OR1K__ -ffixed-r10
> +
> +CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
> \ No newline at end of file
> diff --git a/arch/openrisc/cpu/Makefile b/arch/openrisc/cpu/Makefile
> new file mode 100644
> index 0000000..b3b1a24
> --- /dev/null
> +++ b/arch/openrisc/cpu/Makefile
> @@ -0,0 +1,47 @@
> +#
> +# (C) Copyright 2011
> +# Julius Baxter <julius at opencores.org>
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	= $(obj)lib$(CPU).o
> +
> +START	= start.o
> +COBJS-y	= cache.o cpu.o exceptions.o interrupts.o
> +
> +SRCS	:= $(START:.o=.S) $(COBJS-y:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS-y))
> +START	:= $(addprefix $(obj),$(START))
> +
> +all:	$(obj).depend $(START) $(LIB)
> +
> +$(LIB):	$(OBJS)
> +	$(call cmd_link_o_target, $(OBJS))
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/arch/openrisc/cpu/cache.c b/arch/openrisc/cpu/cache.c
> new file mode 100644
> index 0000000..9dd627f
> --- /dev/null
> +++ b/arch/openrisc/cpu/cache.c
> @@ -0,0 +1,157 @@
> +/*
> + * (C) Copyright 2011, Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius at opencores.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm/system.h>
> +#include <common.h>
> +
> +/* cache line size can be either 16 or 32 bytes */
> +static inline unsigned long get_linesize(void)
> +{
> +	return (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;

What's mfspr ... if it's some register, then maybe mfspr_read() ?

> +}
> +
> +void flush_dcache_range(unsigned long addr, unsigned long stop)
> +{
> +	unsigned long linesize = get_linesize();
> +
> +	while (addr < stop) {
> +		mtspr(SPR_DCBFR, addr);
> +		addr += linesize;
> +	}
> +}
> +
> +void invalidate_dcache_range(unsigned long addr, unsigned long stop)
> +{
> +	unsigned long linesize = get_linesize();
> +
> +	while (addr < stop) {
> +		mtspr(SPR_DCBIR, addr);
> +		addr += linesize;
> +	}
> +}
> +
> +static void invalidate_icache_range(unsigned long addr, unsigned long
> stop) +{
> +	unsigned long linesize = get_linesize();
> +
> +	while (addr < stop) {
> +		mtspr(SPR_ICBIR, addr);
> +		addr += linesize;
> +	}
> +}
> +
> +void flush_cache(unsigned long addr, unsigned long size)
> +{
> +	flush_dcache_range(addr, addr + size);
> +	invalidate_icache_range(addr, addr + size);
> +}
> +
> +int icache_status(void)
> +{
> +	return mfspr(SPR_SR) & SPR_SR_ICE;
> +}
> +
> +int checkicache(void)
> +{
> +	unsigned long iccfgr;
> +	unsigned long cache_set_size;
> +	unsigned long cache_ways;
> +	unsigned long cache_block_size;
> +
> +	iccfgr = mfspr(SPR_ICCFGR);
> +	cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
> +	cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
> +	cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
> +
> +	return cache_set_size * cache_ways * cache_block_size;
> +}
> +
> +int dcache_status(void)
> +{
> +	return mfspr(SPR_SR) & SPR_SR_DCE;
> +}
> +
> +int checkdcache(void)
> +{
> +	unsigned long dccfgr;
> +	unsigned long cache_set_size;
> +	unsigned long cache_ways;
> +	unsigned long cache_block_size;
> +
> +	dccfgr = mfspr(SPR_DCCFGR);
> +	cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
> +	cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
> +	cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
> +
> +	return cache_set_size * cache_ways * cache_block_size;
> +}
> +
> +void dcache_enable(void)
> +{
> +	mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +}
> +
> +void dcache_disable(void)
> +{
> +	mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
> +}
> +
> +void icache_enable(void)
> +{
> +	mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");
> +	asm("l.nop");

Hm, maybe mtspr and those nops together need some ordering ?

> +}
> +
> +void icache_disable(void)
> +{
> +	mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
> +}
> +
> +int cache_init(void)
> +{
> +	if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
> +		icache_disable();
> +		invalidate_icache_range(0, checkicache());
> +		icache_enable();
> +	}
> +
> +	if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
> +		dcache_disable();
> +		invalidate_dcache_range(0, checkdcache());
> +		dcache_enable();
> +	}
> +
> +	return 0;
> +}
> diff --git a/arch/openrisc/cpu/cpu.c b/arch/openrisc/cpu/cpu.c
> new file mode 100644
> index 0000000..3b69285
> --- /dev/null
> +++ b/arch/openrisc/cpu/cpu.c
> @@ -0,0 +1,157 @@
> +/*
> + * (C) Copyright 2011, Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius at opencores.org>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm/system.h>
> +#include <asm/openrisc_exc.h>
> +#include <common.h>
> +
> +static volatile int illegal_instruction;
> +
> +void illegal_instruction_handler(void)
> +{
> +	ulong *epcr = (ulong *)mfspr(SPR_EPCR_BASE);
> +
> +	/* skip over the illegal instruction */
> +	mtspr(SPR_EPCR_BASE, (ulong)(++epcr));
> +	illegal_instruction = 1;
> +}
> +
> +void checkinstructions(void)
> +{
> +	ulong ra = 1, rb = 1, rc;
> +
> +	exception_install_handler(EXC_ILLEGAL_INSTR,
> +				illegal_instruction_handler);
> +
> +	illegal_instruction = 0;
> +	asm volatile("l.mul %0,%1,%2" : "=r" (rc) : "r" (ra), "r" (rb));
> +	printf("           Hardware multiplier: %s\n",
> +		illegal_instruction ? "no" : "yes");
> +
> +	illegal_instruction = 0;
> +	asm volatile("l.div %0,%1,%2" : "=r" (rc) : "r" (ra), "r" (rb));
> +	printf("           Hardware divider: %s\n",
> +		illegal_instruction ? "no" : "yes");
> +
> +	exception_free_handler(EXC_ILLEGAL_INSTR);
> +
> +}
> +
> +int checkcpu(void)
> +{
> +	ulong upr = mfspr(SPR_UPR);
> +	ulong vr = mfspr(SPR_VR);
> +	ulong iccfgr = mfspr(SPR_ICCFGR);
> +	ulong dccfgr = mfspr(SPR_DCCFGR);
> +	ulong immucfgr = mfspr(SPR_IMMUCFGR);
> +	ulong dmmucfgr = mfspr(SPR_DMMUCFGR);
> +	ulong cpucfgr = mfspr(SPR_CPUCFGR);
> +	uint ver = (vr & SPR_VR_VER) >> 24;
> +	uint rev = vr & SPR_VR_REV;
> +	uint block_size;
> +	uint ways;
> +	uint sets;
> +
> +	printf("CPU:   OpenRISC-%x00 (rev %d) @ %d MHz\n",
> +		ver, rev, (CONFIG_SYS_CLK_FREQ / 1000000));

The CPU won't tell you it's speed ?

> +
> +	if (upr & SPR_UPR_DCP) {
> +		block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
> +		ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
> +		printf("       D-Cache: %d bytes, %d bytes/line, %d way(s)\n",
> +		       checkdcache(), block_size, ways);
> +	} else {
> +		printf("       D-Cache: no\n");
> +	}
> +
> +	if (upr & SPR_UPR_ICP) {
> +		block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
> +		ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
> +		printf("       I-Cache: %d bytes, %d bytes/line, %d way(s)\n",
> +		       checkicache(), block_size, ways);
> +	} else {
> +		printf("       I-Cache: no\n");
> +	}
> +
> +	if (upr & SPR_UPR_DMP) {
> +		sets = 1 << ((dmmucfgr & SPR_DMMUCFGR_NTS) >> 2);
> +		ways = (dmmucfgr & SPR_DMMUCFGR_NTW) + 1;
> +		printf("       DMMU: %d sets, %d way(s)\n",
> +		       sets, ways);
> +	} else {
> +		printf("       DMMU: no\n");
> +	}
> +
> +	if (upr & SPR_UPR_IMP) {
> +		sets = 1 << ((immucfgr & SPR_IMMUCFGR_NTS) >> 2);
> +		ways = (immucfgr & SPR_IMMUCFGR_NTW) + 1;
> +		printf("       IMMU: %d sets, %d way(s)\n",
> +		       sets, ways);
> +	} else {
> +		printf("       IMMU: no\n");
> +	}
> +
> +	printf("       MAC unit: %s\n",
> +		(upr & SPR_UPR_MP) ? "yes" : "no");
> +	printf("       Debug unit: %s\n",
> +		(upr & SPR_UPR_DUP) ? "yes" : "no");
> +	printf("       Performance counters: %s\n",
> +		(upr & SPR_UPR_PCUP) ? "yes" : "no");
> +	printf("       Power management: %s\n",
> +		(upr & SPR_UPR_PMP) ? "yes" : "no");
> +	printf("       Interrupt controller: %s\n",
> +		(upr & SPR_UPR_PICP) ? "yes" : "no");
> +	printf("       Timer: %s\n",
> +		(upr & SPR_UPR_TTP) ? "yes" : "no");
> +	printf("       Custom unit(s): %s\n",
> +		(upr & SPR_UPR_CUP) ? "yes" : "no");
> +
> +	printf("       Supported instructions:\n");
> +	printf("           ORBIS32: %s\n",
> +		(cpucfgr & SPR_CPUCFGR_OB32S) ? "yes" : "no");
> +	printf("           ORBIS64: %s\n",
> +		(cpucfgr & SPR_CPUCFGR_OB64S) ? "yes" : "no");
> +	printf("           ORFPX32: %s\n",
> +		(cpucfgr & SPR_CPUCFGR_OF32S) ? "yes" : "no");
> +	printf("           ORFPX64: %s\n",
> +		(cpucfgr & SPR_CPUCFGR_OF64S) ? "yes" : "no");
> +
> +	checkinstructions();
> +
> +	return 0;
> +}
> +
> +int cleanup_before_linux(void)
> +{
> +	disable_interrupts();
> +	return 0;
> +}
> +
> +extern void __reset(void);
> +
> +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	disable_interrupts();
> +	__reset();
> +	return 0;
> +}
> diff --git a/arch/openrisc/cpu/exceptions.c
> b/arch/openrisc/cpu/exceptions.c new file mode 100644
> index 0000000..06935be
> --- /dev/null
> +++ b/arch/openrisc/cpu/exceptions.c
> @@ -0,0 +1,109 @@
> +/*
> + * (C) Copyright 2011, Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius at opencores.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm/system.h>
> +#include <common.h>
> +#include <stdio_dev.h>
> +
> +extern void hang(void);
> +
> +static void (*handlers[32])(void);
> +
> +void exception_install_handler(int exception, void (*handler)(void))
> +{
> +	if (exception < 0 || exception > 31)
> +		return;
> +
> +	handlers[exception] = handler;
> +}
> +
> +void exception_free_handler(int exception)
> +{
> +	if (exception < 0 || exception > 31)
> +		return;
> +
> +	handlers[exception] = 0;
> +}
> +
> +static void exception_hang(int vect)
> +{
> +	printf("Unhandled exception at 0x%x ", vect & 0xff00);
> +	switch (vect & 0xff00) {
> +	case 0x100:
> +		puts("(Reset)\n");
> +		break;
> +	case 0x200:
> +		puts("(Bus Error)\n");
> +		break;
> +	case 0x300:
> +		puts("(Data Page Fault)\n");
> +		break;
> +	case 0x400:
> +		puts("(Instruction Page Fault)\n");
> +		break;
> +	case 0x500:
> +		puts("(Tick Timer)\n");
> +		break;
> +	case 0x600:
> +		puts("(Alignment)\n");
> +		break;
> +	case 0x700:
> +		puts("(Illegal Instruction)\n");
> +		break;
> +	case 0x800:
> +		puts("(External Interrupt)\n");
> +		break;
> +	case 0x900:
> +		puts("(D-TLB Miss)\n");
> +		break;
> +	case 0xa00:
> +		puts("(I-TLB Miss)\n");
> +		break;
> +	case 0xb00:
> +		puts("(Range)\n");
> +		break;
> +	case 0xc00:
> +		puts("(System Call)\n");
> +		break;
> +	case 0xd00:
> +		puts("(Floating Point)\n");
> +		break;
> +	case 0xe00:
> +		puts("(Trap)\n");
> +		break;
> +	default:
> +		puts("(Unknown exception)\n");
> +		break;
> +	}
> +	printf("EPCR: 0x%08lx\n", mfspr(SPR_EPCR_BASE));
> +	printf("EEAR: 0x%08lx\n", mfspr(SPR_EEAR_BASE));
> +	printf("ESR:  0x%08lx\n", mfspr(SPR_ESR_BASE));
> +	hang();
> +}
> +
> +void exception_handler(int vect)
> +{
> +	int exception = vect >> 8;
> +
> +	if (handlers[exception])
> +		handlers[exception]();
> +	else
> +		exception_hang(vect);
> +}
> diff --git a/arch/openrisc/cpu/interrupts.c
> b/arch/openrisc/cpu/interrupts.c new file mode 100644
> index 0000000..62d266a
> --- /dev/null
> +++ b/arch/openrisc/cpu/interrupts.c
> @@ -0,0 +1,120 @@
> +/*
> + * (C) Copyright 2011, Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius at opencores.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm/types.h>
> +#include <asm/ptrace.h>
> +#include <asm/system.h>
> +#include <asm/openrisc_exc.h>
> +#include <common.h>
> +
> +struct irq_action {
> +	interrupt_handler_t *handler;
> +	void *arg;
> +	int count;
> +};
> +
> +static struct irq_action handlers[32];
> +
> +void interrupt_handler(void)
> +{
> +	int irq;
> +
> +	while ((irq = ffs(mfspr(SPR_PICSR)))) {
> +		if (handlers[--irq].handler) {
> +			handlers[irq].handler(handlers[irq].arg);
> +			handlers[irq].count++;
> +		} else {
> +			/* disable the interrupt */
> +			mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1 << irq));
> +			printf("Unhandled interrupt: %d\n", irq);
> +		}
> +		/* clear the interrupt */
> +		mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1 << irq));
> +	}
> +}
> +
> +int interrupt_init(void)
> +{
> +	/* install handler for external interrupt exception */
> +	exception_install_handler(EXC_EXT_IRQ, interrupt_handler);
> +	/* Enable interrupts in supervisor register */
> +	mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
> +
> +	return 0;
> +}
> +
> +void enable_interrupts(void)
> +{
> +	/* Set interrupt enable bit in supervisor register */
> +	mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
> +	/* Enable timer exception */
> +	mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
> +}
> +
> +int disable_interrupts(void)
> +{
> +	/* Clear interrupt enable bit in supervisor register */
> +	mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
> +	/* Disable timer exception */
> +	mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
> +	return 0;
> +}
> +
> +void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
> +{
> +	if (irq < 0 || irq > 31)
> +		return;
> +
> +	handlers[irq].handler = handler;
> +	handlers[irq].arg = arg;
> +}
> +
> +void irq_free_handler(int irq)
> +{
> +	if (irq < 0 || irq > 31)
> +		return;
> +
> +	handlers[irq].handler = 0;
> +	handlers[irq].arg = 0;
> +}
> +
> +#if defined(CONFIG_CMD_IRQ)
> +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	int i;
> +
> +	printf("\nInterrupt-Information:\n\n");
> +	printf("Nr  Routine   Arg       Count\n");
> +	printf("-----------------------------\n");
> +
> +	for (i = 0; i < 32; i++) {
> +		if (handlers[i].handler) {
> +			printf("%02d  %08lx  %08lx  %d\n",
> +				i,
> +				(ulong)handlers[i].handler,
> +				(ulong)handlers[i].arg,
> +				handlers[i].count);
> +		}
> +	}
> +	printf("\n");
> +
> +	return 0;
> +}
> +#endif
> diff --git a/arch/openrisc/cpu/start.S b/arch/openrisc/cpu/start.S
> new file mode 100644
> index 0000000..03e6a8e
> --- /dev/null
> +++ b/arch/openrisc/cpu/start.S
> @@ -0,0 +1,335 @@
> +/*
> + * (C) Copyright 2011, Stefan Kristiansson
> <stefan.kristiansson at saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <julius at opencores.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm-offsets.h>
> +#include <asm/spr-defs.h>
> +#include <config.h>
> +
> +#define EXCEPTION_STACK_SIZE (128+128)
> +
> +#define HANDLE_EXCEPTION			\
> +	l.addi	r1, r1, -EXCEPTION_STACK_SIZE	;\
> +	l.sw	0x1c(r1), r9			;\
> +	l.jal	_exception_handler		;\
> +	 l.nop					;\
> +	l.lwz 	r9, 0x1c(r1)			;\
> +	l.addi	r1, r1, EXCEPTION_STACK_SIZE	;\
> +	l.rfe					;\
> +	 l.nop
> +
> +	.section .vectors, "ax"
> +	.global __reset
> +
> +	/* reset */
> +	.org	0x100
> +__reset:
> +	/* there is no guarantee r0 is hardwired to zero, clear it here */
> +	l.andi	r0, r0, 0
> +	/* reset stack and frame pointers */
> +	l.andi	r1, r0, 0
> +	l.andi	r2, r0, 0
> +
> +	/* set supervisor mode */
> +	l.ori	r3,r0,SPR_SR_SM
> +	l.mtspr	r0,r3,SPR_SR
> +
> +	/* Relocate u-boot */
> +	l.movhi	r3,hi(__start)		/* source start address */
> +	l.ori	r3,r3,lo(__start)
> +	l.movhi	r4,hi(_stext)		/* dest start address */
> +	l.ori	r4,r4,lo(_stext)
> +	l.movhi	r5,hi(__end)		/* dest end address */
> +	l.ori	r5,r5,lo(__end)
> +
> +.L_reloc:
> +	l.lwz	r6,0(r3)
> +	l.sw	0(r4),r6
> +	l.addi	r3,r3,4
> +	l.sfltu	r4,r5
> +	l.bf	.L_reloc
> +	 l.addi	r4,r4,4			/* delay slot */

The formating here doesn't seem right?

> +
> +#ifdef CONFIG_SYS_RELOCATE_VECTORS
> +	/* Relocate vectors from 0xf0000000 to 0x00000000 */
> +	l.movhi r4, 0xf000 /* source */
> +	l.movhi r5, 0      /* destination */
> +	l.addi	r6, r5, CONFIG_SYS_VECTORS_LEN /* length */
> +.L_relocvectors:
> +	l.lwz	r7, 0(r4)
> +	l.sw	0(r5), r7
> +	l.addi	r5, r5, 4
> +	l.sfeq	r5,r6
> +	l.bnf	.L_relocvectors
> +	 l.addi	r4,r4, 4
> +#endif
> +
> +	l.j	_start
> +	 l.nop

Please fix globally ?

> +
> +	/* bus error */
> +	.org	0x200
> +	HANDLE_EXCEPTION
> +
> +	/* data page fault */
> +	.org	0x300
> +	HANDLE_EXCEPTION
> +
> +	/* instruction page fault */
> +	.org	0x400
> +	HANDLE_EXCEPTION
> +
> +	/* tick timer */
> +	.org	0x500
> +	HANDLE_EXCEPTION
> +
> +	/* alignment */
> +	.org	0x600
> +	HANDLE_EXCEPTION
> +
> +	/* illegal instruction */
> +	.org	0x700
> +	HANDLE_EXCEPTION
> +
> +	/* external interrupt */
> +	.org	0x800
> +	HANDLE_EXCEPTION
> +
> +	/* D-TLB miss */
> +	.org	0x900
> +	HANDLE_EXCEPTION
> +
> +	/* I-TLB miss */
> +	.org	0xa00
> +	HANDLE_EXCEPTION
> +
> +	/* range */
> +	.org	0xb00
> +	HANDLE_EXCEPTION
> +
> +	/* system call */
> +	.org	0xc00
> +	HANDLE_EXCEPTION
> +
> +	/* floating point */
> +	.org	0xd00
> +	HANDLE_EXCEPTION
> +
> +	/* trap */
> +	.org	0xe00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0xf00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1100
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1200
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1300
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1400
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1500
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1600
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1700
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1800
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1900
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1a00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1b00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1c00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1d00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1e00
> +	HANDLE_EXCEPTION
> +
> +	/* reserved */
> +	.org	0x1f00
> +	HANDLE_EXCEPTION
> +
> +	/* Startup routine */
> +	.text
> +	.global _start
> +_start:
> +	/* Init stack and frame pointers */
> +	l.movhi	r1, hi(CONFIG_SYS_INIT_SP_ADDR)
> +	l.ori	r1, r1, lo(CONFIG_SYS_INIT_SP_ADDR)
> +	l.or	r2, r0, r1
> +
> +	/* clear BSS segments */
> +	l.movhi	r4, hi(_bss_start)
> +	l.ori	r4, r4, lo(_bss_start)
> +	l.movhi	r5, hi(_bss_end)
> +	l.ori	r5, r5, lo(_bss_end)
> +.L_clear_bss:
> +	l.sw	0(r4), r0
> +	l.sfltu	r4,r5
> +	l.bf	.L_clear_bss
> +	 l.addi	r4,r4,4
> +
> +	/* Reset registers before jumping to board_init */
> +	l.andi	r3, r0, 0
> +	l.andi	r4, r0, 0
> +	l.andi	r5, r0, 0
> +	l.andi	r6, r0, 0
> +	l.andi	r7, r0, 0
> +	l.andi	r8, r0, 0
> +	l.andi	r9, r0, 0
> +	l.andi	r10, r0, 0
> +	l.andi	r11, r0, 0
> +	l.andi	r12, r0, 0
> +	l.andi	r13, r0, 0
> +	l.andi	r14, r0, 0
> +	l.andi	r15, r0, 0
> +	l.andi	r17, r0, 0
> +	l.andi	r18, r0, 0
> +	l.andi	r19, r0, 0
> +	l.andi	r20, r0, 0
> +	l.andi	r21, r0, 0
> +	l.andi	r22, r0, 0
> +	l.andi	r23, r0, 0
> +	l.andi	r24, r0, 0
> +	l.andi	r25, r0, 0
> +	l.andi	r26, r0, 0
> +	l.andi	r27, r0, 0
> +	l.andi	r28, r0, 0
> +	l.andi	r29, r0, 0
> +	l.andi	r30, r0, 0
> +	l.andi	r31, r0, 0
> +
> +	l.j	board_init
> +	 l.nop
> +
> +	.size	_start, .-_start
> +
> +/*
> + * Store state onto stack and call the real exception handler
> + */
> +	.section .text
> +	.extern	exception_handler
> +	.type	_exception_handler, at function
> +
> +_exception_handler:
> +	/* Store state (r9 already saved)*/
> +	l.sw	0x00(r1), r2
> +	l.sw	0x04(r1), r3
> +	l.sw	0x08(r1), r4
> +	l.sw	0x0c(r1), r5
> +	l.sw	0x10(r1), r6
> +	l.sw	0x14(r1), r7
> +	l.sw	0x18(r1), r8
> +	l.sw	0x20(r1), r10
> +	l.sw	0x24(r1), r11
> +	l.sw	0x28(r1), r12
> +	l.sw	0x2c(r1), r13
> +	l.sw	0x30(r1), r14
> +	l.sw	0x34(r1), r15
> +	l.sw	0x38(r1), r16
> +	l.sw	0x3c(r1), r17
> +	l.sw	0x40(r1), r18
> +	l.sw	0x44(r1), r19
> +	l.sw	0x48(r1), r20
> +	l.sw	0x4c(r1), r21
> +	l.sw	0x50(r1), r22
> +	l.sw	0x54(r1), r23
> +	l.sw	0x58(r1), r24
> +	l.sw	0x5c(r1), r25
> +	l.sw	0x60(r1), r26
> +	l.sw	0x64(r1), r27
> +	l.sw	0x68(r1), r28
> +	l.sw	0x6c(r1), r29
> +	l.sw	0x70(r1), r30
> +	l.sw	0x74(r1), r31
> +
> +	/* Save return address */
> +	l.or	r14, r0, r9
> +	/* Call exception handler with the link address as argument */
> +	l.jal	exception_handler
> +	 l.or	r3, r0, r14
> +	/* Load return address */
> +	l.or	r9, r0, r14
> +
> +	/* Restore state */
> +	l.lwz	r2, 0x00(r1)
> +	l.lwz	r3, 0x04(r1)
> +	l.lwz	r4, 0x08(r1)
> +	l.lwz	r5, 0x0c(r1)
> +	l.lwz	r6, 0x10(r1)
> +	l.lwz	r7, 0x14(r1)
> +	l.lwz	r8, 0x18(r1)
> +	l.lwz	r10, 0x20(r1)
> +	l.lwz	r11, 0x24(r1)
> +	l.lwz	r12, 0x28(r1)
> +	l.lwz	r13, 0x2c(r1)
> +	l.lwz	r14, 0x30(r1)
> +	l.lwz	r15, 0x34(r1)
> +	l.lwz	r16, 0x38(r1)
> +	l.lwz	r17, 0x3c(r1)
> +	l.lwz	r18, 0x40(r1)
> +	l.lwz	r19, 0x44(r1)
> +	l.lwz	r20, 0x48(r1)
> +	l.lwz	r21, 0x4c(r1)
> +	l.lwz	r22, 0x50(r1)
> +	l.lwz	r23, 0x54(r1)
> +	l.lwz	r24, 0x58(r1)
> +	l.lwz	r25, 0x5c(r1)
> +	l.lwz	r26, 0x60(r1)
> +	l.lwz	r27, 0x64(r1)
> +	l.lwz	r28, 0x68(r1)
> +	l.lwz	r29, 0x6c(r1)
> +	l.lwz	r30, 0x70(r1)
> +	l.lwz	r31, 0x74(r1)
> +	l.jr	r9
> +	 l.nop

M


More information about the U-Boot mailing list