> 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