> Signed-off-by: Stefan Kristiansson <stefan.kristians...@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 <jul...@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 <jul...@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.kristians...@saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <jul...@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.kristians...@saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <jul...@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.kristians...@saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <jul...@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.kristians...@saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <jul...@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.kristians...@saunalahti.fi> + * (C) Copyright 2011, Julius Baxter
> <jul...@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,@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
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to