
Add nds32 architecture with generic cpu core support. Add nds32 architecture with n1213s cpu core support.
Signed-off-by: Macpaul Lin macpaul@andestech.com --- arch/nds32/config.mk | 32 +++ arch/nds32/cpu/Makefile | 52 ++++ arch/nds32/cpu/config.mk | 28 ++ arch/nds32/cpu/cpu.c | 171 ++++++++++++ arch/nds32/cpu/interrupts.c | 293 +++++++++++++++++++++ arch/nds32/cpu/lowlevel_init.S | 192 ++++++++++++++ arch/nds32/cpu/n1213s/Makefile | 53 ++++ arch/nds32/cpu/n1213s/ag101/Makefile | 50 ++++ arch/nds32/cpu/n1213s/ag101/cpu.c | 171 ++++++++++++ arch/nds32/cpu/n1213s/config.mk | 28 ++ arch/nds32/cpu/n1213s/interrupts.c | 27 ++ arch/nds32/cpu/n1213s/lowlevel_init.S | 27 ++ arch/nds32/cpu/n1213s/start.S | 27 ++ arch/nds32/cpu/start.S | 456 +++++++++++++++++++++++++++++++++ arch/nds32/cpu/u-boot.lds | 67 +++++ 15 files changed, 1674 insertions(+), 0 deletions(-) create mode 100644 arch/nds32/config.mk create mode 100644 arch/nds32/cpu/Makefile create mode 100644 arch/nds32/cpu/config.mk create mode 100644 arch/nds32/cpu/cpu.c create mode 100644 arch/nds32/cpu/interrupts.c create mode 100644 arch/nds32/cpu/lowlevel_init.S create mode 100644 arch/nds32/cpu/n1213s/Makefile create mode 100644 arch/nds32/cpu/n1213s/ag101/Makefile create mode 100644 arch/nds32/cpu/n1213s/ag101/cpu.c create mode 100644 arch/nds32/cpu/n1213s/config.mk create mode 100644 arch/nds32/cpu/n1213s/interrupts.c create mode 100644 arch/nds32/cpu/n1213s/lowlevel_init.S create mode 100644 arch/nds32/cpu/n1213s/start.S create mode 100644 arch/nds32/cpu/start.S create mode 100644 arch/nds32/cpu/u-boot.lds
diff --git a/arch/nds32/config.mk b/arch/nds32/config.mk new file mode 100644 index 0000000..e88e516 --- /dev/null +++ b/arch/nds32/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2000-2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2006 +# Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com +# Macpaul Lin, Andes Technology Corporation macpaul@andestech.com +# +# 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 + +CROSS_COMPILE ?= nds32le-linux- + +STANDALONE_LOAD_ADDR = 0x300000 -T nds32.lds + +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common +PLATFORM_CPPFLAGS += -DCONFIG_NDS32 -D__nds32__ -G0 -ffixed-8 diff --git a/arch/nds32/cpu/Makefile b/arch/nds32/cpu/Makefile new file mode 100644 index 0000000..7eee48c --- /dev/null +++ b/arch/nds32/cpu/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2006 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com +# Macpaul Lin, Andes Technology Corporation macpaul@andestech.com +# +# 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).a + +START = start.o +COBJS = interrupts.o cpu.o +SOBJS = lowlevel_init.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/nds32/cpu/config.mk b/arch/nds32/cpu/config.mk new file mode 100644 index 0000000..316332e --- /dev/null +++ b/arch/nds32/cpu/config.mk @@ -0,0 +1,28 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, gj@denx.de +# +# Copyright (C) 2006 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com +# Macpaul Lin, Andes Technology Corporation macpaul@andestech.com +# +# 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 +# + +PLATFORM_CPPFLAGS += diff --git a/arch/nds32/cpu/cpu.c b/arch/nds32/cpu/cpu.c new file mode 100644 index 0000000..d8fc5cf --- /dev/null +++ b/arch/nds32/cpu/cpu.c @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, gj@denx.de + * + * Copyright (C) 2006 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com + * Macpaul Lin, Andes Technology Corporation macpaul@andestech.com + * + * 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 + */ + +/* + * CPU specific code + */ + +#include <asm/andesboot.h> +#include <command.h> + +/* it makes no sense to use the caches if the MMU also isn't used */ +void cpu_init(void) +{ + /* + * setup up stack if necessary + */ + _andesboot_real_end = _andesboot_end + CONFIG_STACKSIZE; +} + +void cleanup_before_linux(void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we disable interrupt and caches. + */ + +#ifdef CONFIG_MMU + unsigned long i; +#endif + + disable_interrupts(); + +#ifdef CONFIG_MMU + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + + /* flush I/D-cache */ + invalidate_icac(); + invalidate_dcac(); +#endif + +} + + +void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + extern void reset_cpu(ulong addr); + + disable_interrupts(); +// reset_cpu(0); FIXME: -by Shawn, currently no ROM loader at addr 0 + reset_cpu(TEXT_BASE); //reset to the base addr of andesboot + /*NOTREACHED*/ +} + + +void flush_cache (unsigned long dummy1, unsigned long dummy2) +{ +/* + unsigned long u32IfRun = 0; + + if(u32IfRun) return; + u32IfRun = 1; + + reset_cpu((unsigned long)flush_cache); + return; +*/ +} + + +void icache_enable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "ori $p0, $p0, 0x01 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +void icache_disable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "li $p1, ~0x01 \n\t" + "and $p0, $p0, $p1 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +int icache_status(void) +{ + int ret; + + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "andi %0, $p0, 0x01 \n\t" + : "=r" (ret) + : + : "memory" + ); + + return ret; +} + +void dcache_enable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "ori $p0, $p0, 0x02 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +void dcache_disable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "li $p1, ~0x02 \n\t" + "and $p0, $p0, $p1 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +int dcache_status(void) +{ + int ret; + + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "andi %0, $p0, 0x02 \n\t" + : "=r" (ret) + : + : "memory" + ); + + return ret; +} diff --git a/arch/nds32/cpu/interrupts.c b/arch/nds32/cpu/interrupts.c new file mode 100644 index 0000000..89a2cd6 --- /dev/null +++ b/arch/nds32/cpu/interrupts.c @@ -0,0 +1,293 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke azu@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, gj@denx.de + * + * Copyright (C) 2006 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com + * Macpaul Lin, Andes Technology Corporation macpaul@andestech.com + * + * 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/andesboot.h> + +//#include <board/AndesTech/include/porting.h> +#include "../../../board/AndesTech/include/porting.h" +#undef INTERRUPT_MODE + +#include <asm/ptregs.h> + +extern void reset_cpu(ulong addr); + +int GIE_status(void) +{ + int ret; + + __asm__ __volatile__ ( + "mfsr $p0, $psw \n\t" + "andi %0, %0, 0x1 \n\t" + : "=r" (ret) + : + : "memory" + ); + return ret; +} + + +#ifdef CONFIG_USE_INTERRUPT +/* enable interrupts */ +void enable_interrupts (void) +{ + __asm__ __volatile__("setgie.e"); +} + + +/* + * disable interrupts + * Return TRUE if GIE is enabled before we disable it. + */ +int disable_interrupts (void) +{ + int GIE_OriStatus; + + GIE_OriStatus = GIE_status(); + + __asm__ __volatile__("setgie.d"); + + return GIE_OriStatus; +} +#endif + + +void bad_mode(void) +{ + panic("Resetting CPU ...\n"); + reset_cpu(0); +} + +void show_regs(struct pt_regs * regs) +{ + const char *processor_modes[]= + { "USER", "SuperUser" , "HyperVisor" }; + + printf("\n"); + printf("pc : [<%08lx>] sp: [<%08lx>]\n" + "ra : %08lx gp : %08lx fp : %08lx\n", + regs->PC, regs->SP, regs->RA, regs->GP, regs->FP); + printf("D1H: %081x D1L: %08lx D0H: %081x D0L: %08lx\n", + regs->D1HI, regs->D1LO, regs->D0HI, regs->D0LO); + printf("r27: %081x r26: %08lx r25: %08lx r24: %08lx\n", + regs->R27, regs->R26, regs->R25, regs->R24); + printf("r23: %081x r22: %08lx r21: %08lx r20: %08lx\n", + regs->R23, regs->R22, regs->R21, regs->R20); + printf("r19: %081x r18: %08lx r17: %08lx r16: %08lx\n", + regs->R19, regs->R18, regs->R17, regs->R16); + printf("r15: %081x r14: %08lx r13: %08lx r12: %08lx\n", + regs->R15, regs->R14, regs->R13, regs->R12); + printf("r11: %081x r10: %08lx r9 : %08lx r8 : %08lx\n", + regs->R11, regs->R10, regs->R9, regs->R8); + printf("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + regs->R7, regs->R6, regs->R5, regs->R4); + printf("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + regs->R3, regs->R2, regs->R1, regs->R0); + printf(" Interrupts %s Mode %s\n", + interrupts_enabled(regs) ? "on" : "off", + processor_modes[processor_mode(regs)]); +} + +void do_interruption(struct pt_regs *pt_regs, int EVIC_num) +{ + const char *interruption_type[]= + { "Reset", "TLB Fill", "TLB Not Present", "TLB Misc", + "VLPT Miss", "Cache Parity Error", "Debug", + "General Exception", "External Interrupt" }; + + printf("%s\n", interruption_type[EVIC_num]); + show_regs(pt_regs); + bad_mode(); +} + +/* + * functions copy from flib (timer.c) + */ +typedef struct +{ + UINT32 Tm1En:1; // Timer1 enable bit + UINT32 Tm1Clock:1; // Timer1 clock source (0: PCLK, 1: EXT1CLK) + UINT32 Tm1OfEn:1; // Timer1 over flow interrupt enable bit + UINT32 Tm2En:1; + UINT32 Tm2Clock:1; + UINT32 Tm2OfEn:1; + UINT32 Tm3En:1; + UINT32 Tm3Clock:1; + UINT32 Tm3OfEn:1; + UINT32 Tm1UpDown:1; + UINT32 Tm2UpDown:1; + UINT32 Tm3UpDown:1; + + UINT32 Reserved; +}fLib_TimerControl; + + +typedef struct +{ + UINT32 TimerValue; + UINT32 TimerLoad; + UINT32 TimerMatch1; + UINT32 TimerMatch2; +}fLib_TimerReg; + + +/* + * TimerBase[0] is a NULL entry + */ +fLib_TimerReg *TimerBase[] ={0, (fLib_TimerReg *) NDS32_COMMON_TIMER1_BASE, + (fLib_TimerReg *) NDS32_COMMON_TIMER2_BASE,(fLib_TimerReg *)NDS32_COMMON_TIMER3_BASE}; + +#define TIMER_LOAD_VAL 0x80000000 + +/* + * warning: + * timer = 1, 2, 3 + */ +UINT32 Read_Timer_Counter(UINT32 timer) +{ + volatile fLib_TimerReg *Timer = TimerBase[timer]; + + return Timer->TimerValue; +} + +void Set_Timer_AutoReloadValue(UINT32 timer, UINT32 value) +{ + volatile fLib_TimerReg *Timer = TimerBase[timer]; + + Timer->TimerLoad = value; +} + +static ulong timestamp; +static ulong lastdec; + +int interrupt_init (void) +{ + volatile fLib_TimerControl *TimerControl=(fLib_TimerControl *)(NDS32_COMMON_CT_BASE + TIMER_CR); + + TimerControl->Tm1UpDown = 0; // Set timer1 to down count + TimerControl->Tm2UpDown = 0; // Set timer2 to down count + TimerControl->Tm3UpDown = 0; // Set timer3 to down count + + TimerControl->Tm1En = 1; // enable timer 1 + TimerControl->Tm1Clock = 0; + TimerControl->Tm1OfEn = 0; // over flow interrupt disable + + TimerControl->Tm2En = 0; // disable timer 2 + TimerControl->Tm3En = 0; // disable timer 3 + + Set_Timer_AutoReloadValue(1, TIMER_LOAD_VAL); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer (ulong base) +{ + return (get_timer_masked() / CONFIG_SYS_HZ) - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay(unsigned long usec) +{ + ulong tmo; + + tmo = usec * (CONFIG_SYS_HZ / 1000000); + //tmo *= CONFIG_SYS_HZ; + //tmo /= 1000; + + tmo += get_timer(0); + + while(get_timer_masked() < tmo) + { + /*NOP*/; + } +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = Read_Timer_Counter(1); + timestamp = 0; +} + +/* + * 1. get timestamp + * 2. lastdec = now + */ +ulong get_timer_masked(void) +{ + ulong now = Read_Timer_Counter(1);; + + if (lastdec >= now) + { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + + +void udelay_masked(unsigned long usec) +{ + ulong tmo; + + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + + reset_timer_masked(); + + while(get_timer_masked() < tmo) + { + /*NOP*/; + } +} + diff --git a/arch/nds32/cpu/lowlevel_init.S b/arch/nds32/cpu/lowlevel_init.S new file mode 100644 index 0000000..50c3ff1 --- /dev/null +++ b/arch/nds32/cpu/lowlevel_init.S @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2006 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com + * Macpaul Lin, Andes Technology Corporation macpaul@andestech.com + * + * 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 + */ + +.text + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +.globl lowlevel_init +lowlevel_init: + move $r10, $lp + jal mem_init + jal remap + jal uart_init + + ret $r10 + +mem_init: + move $r11, $lp + li $r0, 0x90200004 + li $r1, 0x00151151 + swi $r1, [$r0] + + li $r0, 0x90100018 + li $r1, 0x100b0000 + swi $r1, [$r0] + li $r0, 0x98100030 + lwi $r1, [$r0] + li $r2, 0x00010000 + or $r1, $r1, $r2 + swi $r1, [$r0] +#ifdef __NDS32_N1213_43U1H__ /* AG101 */ + lwi $r1, [$r0] + li $r2, 0x00e00000 + or $r1, $r1, $r2 + swi $r1, [$r0] + li $r0, 0x98100028 + lwi $r1, [$r0] + li $r2, 0x00000010 + or $r1, $r1, $r2 + swi $r1, [$r0] + li $r0, 0x9810004c + lwi $r1, [$r0] + li $r2, 0x0007f000 + or $r1, $r1, $r2 + swi $r1, [$r0] +#endif + li $r0, 0x90300000 + li $r1, 0x00011312 + swi $r1, [$r0] + li $r1, 0x00480180 + swi $r1, [$r0+0x4] + li $r1, 0x00002326 + swi $r1, [$r0+0x8] + li $r1, 0x00000010 + swi $r1, [$r0+0xc] +1: + lwi $r1, [$r0+0xc] + andi $r1, $r1, 0x1c + bnez $r1, 1b + + li $r1, 0x00000004 + swi $r1, [$r0+0xc] +2: + lwi $r1, [$r0+0xc] + bnez $r1, 2b + + li $r1, 0x00000008 + swi $r1, [$r0+0xc] +3: + lwi $r1, [$r0+0xc] + bnez $r1, 3b + + move $lp, $r11 + ret + +remap: + move $r11, $lp +#ifdef __NDS32_N1213_43U1H__ /* AG101 */ + bal 2f +relo_base: + move $r0, $lp +#else +relo_base: + mfusr $r0, $pc +#endif + + /* relocation, copy ROM code to SDRAM(current is at 0x10000000) */ + li $r4, 0x10000000 + li $r5, 0x0 + la $r1, relo_base + sub $r2, $r0, $r1 + sethi $r6, hi20(andesboot_end) + ori $r6, $r6, lo12(andesboot_end) + add $r6, $r6, $r2 +1: + lwi $r7, [$r5] + swi $r7, [$r4] + addi $r5, $r5, #4 + addi $r4, $r4, #4 + blt $r5, $r6, 1b + + /* Remapping */ + li $r0, 0x90300000 + li $r1, 0x00001100 + swi $r1, [$r0+0x10] + li $r1, 0x0 + swi $r1, [$r0+0x14] + swi $r1, [$r0+0x18] + swi $r1, [$r0+0x1c] + li $r1, 0x00001000 + swi $r1, [$r0+0x10] + + li $r0, 0x90100088 + lwi $r1, [$r0] + ori $r1, $r1, 0x1 + swi $r1, [$r0] + + li $r0, 0x90200000 +#ifdef __NDS32_N1213_43U1H__ /* AG101 */ + li $r1, 0x10400062 + swi $r1, [$r0+0x8] + li $r1, 0x000ff3ff + swi $r1, [$r0+0xc] +#else + li $r1, 0x10400062 + swi $r1, [$r0] +#endif + + move $lp, $r11 +2: + ret + +uart_init: +#! 1. fLib_SetSerialMode(DebugSerialPort, SERIAL_MDR_UART); + li $r0, #0x99600000 !; CPE_UART4_BASE = 0x99600000 + lwi $r1, [$r0+#0x20] !; mdr = mdr = inw(CPE_UART4_BASE + SERIAL_MDR) + li $r2, #0xfffffffc !; mdr &= ~(0x3) ; SERIAL_MDR_MODE_SEL = 0x3 + and $r1, $r1, $r2 + swi $r1, [$r0+#0x20] !; outw(CPE_UART4_BASE + SERIAL_MDR, mdr | mode); +#! 2. fLib_SerialInit(DebugSerialPort, (int)DEFAULT_HOST_BAUD, PARITY_NONE, 0, 8); +#! dgbserialport = 0x99600000; baud = (UART_CLOCK / 614400) = 24; PARITY_NONE = 0; num = 0; len = 8; + li $r0, #0x99600000 !;lcr = inw(port + SERIAL_LCR) & ~SERIAL_LCR_DLAB; SERIAL_LCR = 0x0c + lwi $r1, [$r0+#0x0c] + li $r2, #0xffffff7f !; SERIAL_LCR_DLAB = 0x80 + and $r1, $r1, $r2 + li $r2, #0x80 !; outw(port + SERIAL_LCR,SERIAL_LCR_DLAB); + swi $r2, [$r0+#0x0c] + li $r2, #0 !; outw(port + SERIAL_DLM, ((baudrate & 0xf00) >> 8)); + swi $r2, [$r0+#0x4] +#ifdef __NDS32_N1213_43U1H__ /* AG101 */ + li $r2, #60 !; outw(port + SERIAL_DLL, (baudrate & 0xff)); +#else + li $r2, #24 !; outw(port + SERIAL_DLL, (baudrate & 0xff)); +#endif + swi $r2, [$r0+#0x0] + andi $r1, $r1, #0xc0 !; lcr &= 0xc0; + li $r2, #3 !; len-=5; + or $r1, $r1, $r2 !; lcr|=len; + swi $r1, [$r0+#0x0c] !; outw(port+SERIAL_LCR,lcr); +#! 3. fLib_SetSerialFifoCtrl(DebugSerialPort, 0, 0, ENABLE(1), ENABLE(1)); + li $r0, #0x99600000 + li $r1, #0x7 !; fcr = 0x7 + swi $r1, [$r0+#0x8] !; SERIAL_FCR = 0x08; outw(port+SERIAL_FCR,fcr); + + ret + +.globl show_led +show_led: + li $r8, 0x902ffffc ! 0x902ffffc + swi $r7, [$r8] + ret +#endif diff --git a/arch/nds32/cpu/n1213s/Makefile b/arch/nds32/cpu/n1213s/Makefile new file mode 100644 index 0000000..1cc3731 --- /dev/null +++ b/arch/nds32/cpu/n1213s/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2006 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com +# Macpaul Lin, Andes Technology Corporation macpaul@andestech.com +# +# 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).a + +START = start.o +COBJS = interrupts.o +SOBJS = lowlevel_init.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + sed -e "s/start.o/$(CPU)/start.o/" ../u-boot.lds > ./u-boot.lds + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/nds32/cpu/n1213s/ag101/Makefile b/arch/nds32/cpu/n1213s/ag101/Makefile new file mode 100644 index 0000000..65ccf94 --- /dev/null +++ b/arch/nds32/cpu/n1213s/ag101/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2009 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar prafulla@marvell.com +# +# Copyright (C) 2006 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com +# Macpaul Lin, Andes Technology Corporation macpaul@andestech.com +# +# 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., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +COBJS-y = cpu.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/nds32/cpu/n1213s/ag101/cpu.c b/arch/nds32/cpu/n1213s/ag101/cpu.c new file mode 100644 index 0000000..d8fc5cf --- /dev/null +++ b/arch/nds32/cpu/n1213s/ag101/cpu.c @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, gj@denx.de + * + * Copyright (C) 2006 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com + * Macpaul Lin, Andes Technology Corporation macpaul@andestech.com + * + * 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 + */ + +/* + * CPU specific code + */ + +#include <asm/andesboot.h> +#include <command.h> + +/* it makes no sense to use the caches if the MMU also isn't used */ +void cpu_init(void) +{ + /* + * setup up stack if necessary + */ + _andesboot_real_end = _andesboot_end + CONFIG_STACKSIZE; +} + +void cleanup_before_linux(void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we disable interrupt and caches. + */ + +#ifdef CONFIG_MMU + unsigned long i; +#endif + + disable_interrupts(); + +#ifdef CONFIG_MMU + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + + /* flush I/D-cache */ + invalidate_icac(); + invalidate_dcac(); +#endif + +} + + +void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + extern void reset_cpu(ulong addr); + + disable_interrupts(); +// reset_cpu(0); FIXME: -by Shawn, currently no ROM loader at addr 0 + reset_cpu(TEXT_BASE); //reset to the base addr of andesboot + /*NOTREACHED*/ +} + + +void flush_cache (unsigned long dummy1, unsigned long dummy2) +{ +/* + unsigned long u32IfRun = 0; + + if(u32IfRun) return; + u32IfRun = 1; + + reset_cpu((unsigned long)flush_cache); + return; +*/ +} + + +void icache_enable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "ori $p0, $p0, 0x01 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +void icache_disable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "li $p1, ~0x01 \n\t" + "and $p0, $p0, $p1 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +int icache_status(void) +{ + int ret; + + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "andi %0, $p0, 0x01 \n\t" + : "=r" (ret) + : + : "memory" + ); + + return ret; +} + +void dcache_enable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "ori $p0, $p0, 0x02 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +void dcache_disable(void) +{ + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "li $p1, ~0x02 \n\t" + "and $p0, $p0, $p1 \n\t" + "mtsr $p0, $mr8 \n\t" + "isb \n\t" + ); +} + +int dcache_status(void) +{ + int ret; + + __asm__ __volatile__ ( + "mfsr $p0, $mr8 \n\t" + "andi %0, $p0, 0x02 \n\t" + : "=r" (ret) + : + : "memory" + ); + + return ret; +} diff --git a/arch/nds32/cpu/n1213s/config.mk b/arch/nds32/cpu/n1213s/config.mk new file mode 100644 index 0000000..316332e --- /dev/null +++ b/arch/nds32/cpu/n1213s/config.mk @@ -0,0 +1,28 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, gj@denx.de +# +# Copyright (C) 2006 Andes Technology Corporation +# Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com +# Macpaul Lin, Andes Technology Corporation macpaul@andestech.com +# +# 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 +# + +PLATFORM_CPPFLAGS += diff --git a/arch/nds32/cpu/n1213s/interrupts.c b/arch/nds32/cpu/n1213s/interrupts.c new file mode 100644 index 0000000..a115a72 --- /dev/null +++ b/arch/nds32/cpu/n1213s/interrupts.c @@ -0,0 +1,27 @@ +/* + * Andesboot - Startup Code for Whitiger core + * + * Copyright (C) 2010 Andes Technology Corporation + * Copyright (C) 2010 Macpaul macpaul@andestech.com + * + * 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 "../interrupts.c" + diff --git a/arch/nds32/cpu/n1213s/lowlevel_init.S b/arch/nds32/cpu/n1213s/lowlevel_init.S new file mode 100644 index 0000000..26e0727 --- /dev/null +++ b/arch/nds32/cpu/n1213s/lowlevel_init.S @@ -0,0 +1,27 @@ +/* + * Andesboot - Startup Code for Whitiger core + * + * Copyright (C) 2010 Andes Technology Corporation + * Copyright (C) 2010 Macpaul macpaul@andestech.com + * + * 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 "../lowlevel_init.S" + diff --git a/arch/nds32/cpu/n1213s/start.S b/arch/nds32/cpu/n1213s/start.S new file mode 100644 index 0000000..e93d048 --- /dev/null +++ b/arch/nds32/cpu/n1213s/start.S @@ -0,0 +1,27 @@ +/* + * Andesboot - Startup Code for Whitiger core + * + * Copyright (C) 2010 Andes Technology Corporation + * Copyright (C) 2010 Macpaul macpaul@andestech.com + * + * 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 "../start.S" + diff --git a/arch/nds32/cpu/start.S b/arch/nds32/cpu/start.S new file mode 100644 index 0000000..12cd30f --- /dev/null +++ b/arch/nds32/cpu/start.S @@ -0,0 +1,456 @@ +/* + * Andesboot - Startup Code for Whitiger core + * + * Copyright (c) 2001 Marius Gröger mag@sysgo.de + * Copyright (c) 2002 Alex Züpke azu@sysgo.de + * Copyright (c) 2002 Gary Jennejohn gj@denx.de + * + * Copyright (C) 2006 Andes Technology Corporation + * Copyright (C) 2006 Shawn Lin nobuhiro@andestech.com + * Copyright (C) 2010 Macpaul macpaul@andestech.com + * + * 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 <config.h> +#include <common.h> +#include <version.h> +#include <nds32_common.h> + +#if defined(CONFIG_AG101) +#include <./configs/ag101.h> +#endif + +!======================================================================== +! Jump vector table for EVIC mode +!======================================================================== + +#define ENA_DCAC 2UL +#define DIS_DCAC ~ENA_DCAC +#define ICAC_MEM_kbfISET (0x07) ! I Cache sets per way +#define ICAC_MEM_kbfIWAY (0x07<<3) ! I cache ways +#define ICAC_MEM_kbfISZ (0x07<<6) ! I cache line size +#define DCAC_MEM_kbfDSET (0x07) ! D Cache sets per way +#define DCAC_MEM_kbfDWAY (0x07<<3) ! D cache ways +#define DCAC_MEM_kbfDSZ (0x07<<6) ! D cache line size + +#define psw $ir0 +#define EIT_INTR_PSW $ir1 // interruption $PSW +#define EIT_PREV_IPSW $ir2 // previous ... +#define EIT_IVB $ir3 // intr vector base address +#define EIT_EVA $ir4 // MMU related Exception Virtual Address register +#define EIT_PREV_EVA $ir5 // previous $eva +#define EIT_ITYPE $ir6 // interruption type +#define EIT_PREV_ITYPE $ir7 // prev intr type +#define EIT_MACH_ERR $ir8 // machine error log +#define EIT_INTR_PC $ir9 // Interruption PC +#define EIT_PREV_IPC $ir10 // previous $IPC +#define EIT_OVL_INTR_PC $ir11 // overflow interruption PC +#define EIT_PREV_P0 $ir12 // prev $P0 +#define EIT_PREV_P1 $ir13 // prev $p1 +#define CR_ICAC_MEM $cr1 // Insn cache/memory config register +#define CR_DCAC_MEM $cr2 // Data cache/memory config register +#define MR_CAC_CTL $mr8 + + +.globl _start + +_start: b reset + b TLB_fill + b TLB_not_present + b TLB_misc + b TLB_VLPT_miss + b cache_parity_error + b debug + b general_exception + b internal_interrupt ! H0I + b internal_interrupt ! H1I + b internal_interrupt ! H2I + b internal_interrupt ! H3I + b internal_interrupt ! H4I + b internal_interrupt ! H5I + + .balign 16 + + +!======================================================================== +! Andesboot Startup Code (reset vector) +! +! 1. bootstrap +! 1.1 reset - start of Andesboot +! 1.2 to superuser mode - as is when reset +! 1.3 Turn off watchdog timer +! 2. Do critical init when reboot (not from mem) +! 3. Relocate andesboot to ram +! 4. Setup stack +! 5. Jump to second stage (start_andesboot) +!======================================================================== + +! Note: TEXT_BASE is defined by the (board-dependent) linker script +_TEXT_BASE: + .word TEXT_BASE + +.globl _andesboot_start +_andesboot_start: + .word _start + +! Note: andesboot_end is defined by the (board-dependent) linker script +.globl _andesboot_end +_andesboot_end: + .word andesboot_end + +! _andesboot_real_end is the first usable RAM address behind Andesboot +! and the various stacks +.globl _andesboot_real_end +_andesboot_real_end: + .word 0x0badc0de + + +!============================================= +! The bootstrap code of Andesboot +!============================================= + +reset: + +load_lli: +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + jal load_lowlevel_init + jral $p0 +#endif + + ! Set the Whitiger core to superuser mode + ! According to spec, it is already when reset + +#define WD_CR 0xC +#define WdEnable 0x1 + + ! Turn off the watchdog, according to Faraday FTWDT010 spec + li $p0, (NDS32_COMMON_WATCHDOG_BASE+WD_CR) ! Get the address of the WD CR + lwi $p1, [$p0] ! Get the WD configuration + andi $p1, $p1, 0x1f ! Wipe out useless bits + li $r0, ~WdEnable + and $p1, $p1, $r0 ! Set WD disable + sw $p1, [$p0] ! Write back to WD CR + + ! Disable Interrupts by clear GIE in $PSW reg + setgie.d + +! Do CPU critical regs init only at reboot, not when booting from ram +#ifdef CONFIG_INIT_CRITICAL + bal cpu_init_crit ! Do CPU critical regs init +#endif +.align 2 +relocate: + ! relocate andesboot to RAM + jal 2f + !la $r0, _start ! $r0 = source start address + !l.w $r2, _andesboot_start ! Andesboot start address + !l.w $r3, _andesboot_end ! Andesboot end address + !sub $r2, $r3, $r2 ! $r2 = size of Andesboot + !l.w $r1, _TEXT_BASE ! $r1 = destination start address + move $r0, $lp + la $p0, _start + la $p1, relocate+4 + sub $p0, $p1, $p0 + sub $r0, $r0, $p0 + + la $p0, _andesboot_end + sub $p0, $p0, $p1 + move $r3, $lp + lw $r3, [$r3+$p0] ! _andesboot_end + addi $p0, $p0, -4 + move $r2, $lp + lw $r2, [$r2+$p0] ! _andesboot_start + sub $r2, $r3, $r2 + addi $p0, $p0, -4 + move $r1, $lp + lw $r1, [$r1+$p0] ! _TEXT_BASE + + ! $r0 = source address + ! $r1 = destination address + ! $r2 = size to copy +copy_loop: + lmw.bim $r3, [$r0], $r10 + smw.bim $r3, [$r1], $r10 + addi $r2, $r2, -32 + bgez $r2, copy_loop + + ! Set up the stack + l.w $p0, _andesboot_end ! Defined by the board linker script + li $p1, CONFIG_STACKSIZE ! (128*1024) defined in config.h + add $sp, $p0, $p1 + + bal fLib_InitBSSMemory + + ! Jump to start_andesboot (2nd phase) + l.w $p0, __start_andesboot + br $p0 + +__start_andesboot: .word start_andesboot + + + +!========================================================================= +! Initialize CPU critical registers +! +! 1. Setup control registers +! 1.1 Mask all IRQs +! 1.2 Flush cache and TLB +! 1.3 Disable MMU and cache +! 2. Setup memory timing +!========================================================================= + + +cpu_init_crit: + !push ra + move $r0, $lp + ! Disable Interrupts by clear GIE in $PSW reg + setgie.d + + ! Flush caches and TLB + + ! Invalidate caches + bal invalidate_icac + bal invalidate_dcac + + ! Flush TLB + mfsr $p0, $MMU_CFG + andi $p0, $p0, 0x3 ! MMPS + li $p1, 0x2 ! TLB MMU + bne $p0, $p1, 1f + tlbop FlushAll ! Flush TLB + +1: + ! Disable MMU, Dcache + ! Whitiger is MMU disabled when reset + ! Disable the D$ + mfsr $p0, MR_CAC_CTL ! Get the $CACHE_CTL reg + li $p1, DIS_DCAC + and $p0, $p0, $p1 ! Set DC_EN bit + mtsr $p0, MR_CAC_CTL ! write back the $CACHE_CTL reg + isb + + ! RAM is initialized in the dram_init()(board/nds32/cpe.c) + ! Remove the memsetup.S in the board directory. + !pop ra + + move $lp, $r0 +2: + ret + +fLib_InitBSSMemory: + smw.adm $r4, [$sp], $r6, #0x1 + + la $r4, __bss_start + la $r5, __bss_end + move $r6, #0 +1: + swi.p $r6, [$r4], #4 + blt $r4, $r5, 1b ! Check if done.. + + lmw.bim $r4, [$sp], $r6, #0x1 + ret + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +load_lowlevel_init: + la $r6, lowlevel_init + la $r7, load_lli + 4 + sub $p0, $r6, $r7 + add $p0, $p0, $lp +ret +#endif + +!======================================================= +! Invalidate I$ +!======================================================= +invalidate_icac: + mfsr $t0, CR_ICAC_MEM ! read $cr1(I CAC/MEM cfg. reg.) configuration + andi $p0, $t0, ICAC_MEM_kbfISZ ! Get the ISZ field + beqz $p0, end_flush_icache ! if $p0=0, then no I CAC existed + srli $p0, $p0, 6 ! get $p0 the index of I$ block + addi $t1, $p0, 2 ! $t1= bit width of I cache line size(ISZ) + li $t4, 1 + sll $t5, $t4, $t1 ! get $t5 cache line size + andi $p1, $t0, ICAC_MEM_kbfISET! get the ISET field + addi $t2, $p1, 6 ! $t2= bit width of ISET + andi $p1, $t0, ICAC_MEM_kbfIWAY! get bitfield of Iway + srli $p1, $p1, 3 + addi $p1, $p1, 1 ! then $p1 is I way number + add $t3, $t2, $t1 ! SHIFT + sll $p1, $p1, $t3 ! GET the total cache size +ICAC_LOOP: + sub $p1, $p1, $t5 + cctl $p1, L1I_IX_INVAL + bnez $p1, ICAC_LOOP +end_flush_icache: + ret +!======================================================= +! Invalidate D$ +!======================================================= +invalidate_dcac: + mfsr $t0, CR_DCAC_MEM ! read $cr2(D CAC/MEM cfg. reg.) configuration + andi $p0, $t0, DCAC_MEM_kbfDSZ ! Get the DSZ field + beqz $p0, end_flush_dcache ! if $p0=0, then no D CAC existed + srli $p0, $p0, 6 ! get $p0 the index of D$ block + addi $t1, $p0, 2 ! $t1= bit width of D cache line size(DSZ) + li $t4, 1 + sll $t5, $t4, $t1 ! get $t5 cache line size + andi $p1, $t0, DCAC_MEM_kbfDSET! get the DSET field + addi $t2, $p1, 6 ! $t2= bit width of DSET + andi $p1, $t0, DCAC_MEM_kbfDWAY! get bitfield of D way + srli $p1, $p1, 3 + addi $p1, $p1, 1 ! then $p1 is D way number + add $t3, $t2, $t1 ! SHIFT + sll $p1, $p1, $t3 ! GET the total cache size +DCAC_LOOP: + sub $p1, $p1, $t5 + cctl $p1, L1D_IX_INVAL + bnez $p1, DCAC_LOOP +end_flush_dcache: + ret + +!======================================================================== +! Interrupt handling +!======================================================================== + +/* + * exception handlers + */ + .align 5 + + .macro SAVE_ALL + ! FIXME: Other way to get PC? + ! FIXME: Update according to the newest spec!! +1: la $r28, 1 + push $r28 + mfsr $r28, psw ! $psw + push $r28 + mfsr $r28, EIT_EVA ! $ir1 $EVA + push $r28 + mfsr $r28, EIT_ITYPE ! $ir2 $ITYPE + push $r28 + mfsr $r28, EIT_MACH_ERR ! $ir3 Mach Error + push $r28 + mfsr $r28, EIT_INTR_PSW ! $ir5 $IPSW + push $r28 + mfsr $r28, EIT_PREV_IPSW ! $ir6 prev $IPSW + push $r28 + mfsr $r28, EIT_PREV_EVA ! $ir7 prev $EVA + push $r28 + mfsr $r28, EIT_PREV_ITYPE ! $ir8 prev $ITYPE + push $r28 + mfsr $r28, EIT_INTR_PC ! $ir9 Interruption PC + push $r28 + mfsr $r28, EIT_PREV_IPC ! $ir10 prev Interruption PC + push $r28 + mfsr $r28, EIT_OVL_INTR_PC ! $ir11:OVerflowed interruption PC + push $r28 + mfusr $r28, $d1.lo + push $r28 + mfusr $r28, $d1.hi + push $r28 + mfusr $r28, $d0.lo + push $r28 + mfusr $r28, $d0.hi + push $r28 + pushm $r0,$r30 // we will also store $sp-$r31, ra-$r30, $gp-$r29, $r28-$fp + addi $sp, $sp, -4 ! make room for implicit pt_regs parameters + .endm + + .align 5 +TLB_fill: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 1 ! Determine interruption type + bal do_interruption + + .align 5 +TLB_not_present: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 2 ! Determine interruption type + bal do_interruption + + .align 5 +TLB_misc: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 3 ! Determine interruption type + bal do_interruption + + .align 5 +TLB_VLPT_miss: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 4 ! Determine interruption type + bal do_interruption + + .align 5 +cache_parity_error: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 5 ! Determine interruption type + bal do_interruption + + .align 5 +debug: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 6 ! Determine interruption type + bal do_interruption + + .align 5 +general_exception: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 7 ! Determine interruption type + bal do_interruption + + + .align 5 +internal_interrupt: + SAVE_ALL + move $r0, $sp ! To get the kernel stack + li $r1, 8 ! Determine interruption type + bal do_interruption + + .align 5 + +!=========================================== +!void reset_cpu(ulong addr); +! $r0: input address to jump to +!=========================================== +.globl reset_cpu +reset_cpu: +! No need to disable MMU because we never enable it! + + bal invalidate_icac + bal invalidate_dcac + mfsr $p0, $MMU_CFG + andi $p0, $p0, 0x3 ! MMPS + li $p1, 0x2 ! TLB MMU + bne $p0, $p1, 1f + tlbop FlushAll ! Flush TLB +1: + mfsr $p0, MR_CAC_CTL ! Get the $CACHE_CTL reg + li $p1, DIS_DCAC + and $p0, $p0, $p1 ! Clear the DC_EN bit + mtsr $p0, MR_CAC_CTL ! Write back the $CACHE_CTL reg + br $r0 ! Jump to the input address + diff --git a/arch/nds32/cpu/u-boot.lds b/arch/nds32/cpu/u-boot.lds new file mode 100644 index 0000000..e74bb0f --- /dev/null +++ b/arch/nds32/cpu/u-boot.lds @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2006 Andes Technology Corporation + * Shawn Lin, Andes Technology Corporation nobuhiro@andestech.com + * Macpaul Lin, Andes Technology Corporation macpaul@andestech.com + * + * 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 + */ + +OUTPUT_FORMAT("elf32-nds32", "elf32-nds32", "elf32-nds32") +OUTPUT_ARCH(nds32) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + arch/nds32/cpu/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + __bss_end = .; + + . = ALIGN(4); + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + + andesboot_end = .; + + . = 0x02000000; + .u_boot_ohci_data_st : { *(.u_boot_ohci_data_st) } +}