diff options
Diffstat (limited to 'cpu/arm720t')
-rwxr-xr-x | cpu/arm720t/Makefile | 43 | ||||
-rwxr-xr-x | cpu/arm720t/config.mk | 35 | ||||
-rwxr-xr-x | cpu/arm720t/cpu.c | 257 | ||||
-rwxr-xr-x | cpu/arm720t/interrupts.c | 413 | ||||
-rwxr-xr-x | cpu/arm720t/serial.c | 126 | ||||
-rwxr-xr-x | cpu/arm720t/serial_netarm.c | 201 | ||||
-rwxr-xr-x | cpu/arm720t/start.S | 542 |
7 files changed, 1617 insertions, 0 deletions
diff --git a/cpu/arm720t/Makefile b/cpu/arm720t/Makefile new file mode 100755 index 0000000..f273d92 --- /dev/null +++ b/cpu/arm720t/Makefile @@ -0,0 +1,43 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 = lib$(CPU).a + +START = start.o +OBJS = serial.o serial_netarm.o interrupts.o cpu.o + +all: .depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) crv $@ $(OBJS) + +######################################################################### + +.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/arm720t/config.mk b/cpu/arm720t/config.mk new file mode 100755 index 0000000..641b91c --- /dev/null +++ b/cpu/arm720t/config.mk @@ -0,0 +1,35 @@ +# +# (C) Copyright 2002 +# Sysgo Real-Time Solutions, GmbH <www.elinos.com> +# Marius Groeger <mgroeger@sysgo.de> +# +# 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_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -msoft-float + +PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c new file mode 100755 index 0000000..a5b6de7 --- /dev/null +++ b/cpu/arm720t/cpu.c @@ -0,0 +1,257 @@ +/* + * (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> + * + * 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 <common.h> +#include <command.h> +#include <clps7111.h> +#include <asm/hardware.h> + +int cpu_init (void) +{ + /* + * setup up stacks if necessary + */ +#ifdef CONFIG_USE_IRQ + IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; + FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; +#endif + return 0; +} + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + * and we set the CPU-speed to 73 MHz - see start.S for details + */ + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + unsigned long i; + + disable_interrupts (); + + /* turn off I-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~0x1000; + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + + /* flush I-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); +#ifdef CONFIG_ARM7_REVD + /* go to high speed */ + IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; +#endif +#elif defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) + disable_interrupts (); + /* Nothing more needed */ +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No cleanup before linux for IntegratorAP/CM720T as yet */ +#else +#error No cleanup_before_linux() defined for this CPU type +#endif + return 0; +} + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + disable_interrupts (); + reset_cpu (0); + /*NOTREACHED*/ + return (0); +} + +/* + * Instruction and Data cache enable and disable functions + * + */ + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) +/* read co-processor 15, register #1 (control register) */ +static unsigned long read_p15_c1(void) +{ + unsigned long value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" + : "=r" (value) + : + : "memory"); + /* printf("p15/c1 is = %08lx\n", value); */ + return value; +} + +/* write to co-processor 15, register #1 (control register) */ +static void write_p15_c1(unsigned long value) +{ + /* printf("write %08lx to p15/c1\n", value); */ + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" + : + : "r" (value) + : "memory"); + + read_p15_c1(); +} + +static void cp_delay (void) +{ + volatile int i; + + /* copro seems to need some delay between reading and writing */ + for (i = 0; i < 100; i++); +} + +/* See also ARM Ref. Man. */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_IDC (1<<2) /* icache and/or dcache off/on */ +#define C1_WRITE_BUFFER (1<<3) /* write buffer off/on */ +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ + +void icache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_IDC); +} + +void icache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IDC); +} + +int icache_status (void) +{ + return (read_p15_c1 () & C1_IDC) != 0; +} + +void dcache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_IDC); +} + +void dcache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IDC); +} + +int dcache_status (void) +{ + return (read_p15_c1 () & C1_IDC) != 0; +} + +#elif defined(CONFIG_S3C4510B) + +void icache_enable (void) +{ + s32 i; + + /* disable all cache bits */ + CLR_REG( REG_SYSCFG, 0x3F); + + /* 8KB cache, write enable */ + SET_REG( REG_SYSCFG, CACHE_WRITE_BUFF | CACHE_MODE_01); + + /* clear TAG RAM bits */ + for ( i = 0; i < 256; i++) + PUT_REG( CACHE_TAG_RAM + 4*i, 0x00000000); + + /* clear SET0 RAM */ + for(i=0; i < 1024; i++) + PUT_REG( CACHE_SET0_RAM + 4*i, 0x00000000); + + /* clear SET1 RAM */ + for(i=0; i < 1024; i++) + PUT_REG( CACHE_SET1_RAM + 4*i, 0x00000000); + + /* enable cache */ + SET_REG( REG_SYSCFG, CACHE_ENABLE); + +} + +void icache_disable (void) +{ + /* disable all cache bits */ + CLR_REG( REG_SYSCFG, 0x3F); +} + +int icache_status (void) +{ + return GET_REG( REG_SYSCFG) & CACHE_ENABLE; +} + +void dcache_enable (void) +{ + /* we don't have seperate instruction/data caches */ + icache_enable(); +} + +void dcache_disable (void) +{ + /* we don't have seperate instruction/data caches */ + icache_disable(); +} + +int dcache_status (void) +{ + /* we don't have seperate instruction/data caches */ + return icache_status(); +} + +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No specific cache setup for IntegratorAP/CM720T as yet */ + void icache_enable (void) + { + } +#else +#error No icache/dcache enable/disable functions defined for this CPU type +#endif diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c new file mode 100755 index 0000000..da62502 --- /dev/null +++ b/cpu/arm720t/interrupts.c @@ -0,0 +1,413 @@ +/* + * (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> + * + * 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 <common.h> +#include <clps7111.h> +#include <asm/proc-armv/ptrace.h> +#include <asm/hardware.h> + +#ifndef CONFIG_NETARM +/* we always count down the max. */ +#define TIMER_LOAD_VAL 0xffff +/* macro to read the 16 bit timer */ +#define READ_TIMER (IO_TC1D & 0xffff) +#else +#define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE)) +#define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL)) +#define TM2STAT (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_STATUS)) +#define TIMER_LOAD_VAL NETARM_GEN_TSTAT_CTC_MASK +#define READ_TIMER (TM2STAT & NETARM_GEN_TSTAT_CTC_MASK) +#endif + +#ifdef CONFIG_S3C4510B +/* require interrupts for the S3C4510B */ +# ifndef CONFIG_USE_IRQ +# error CONFIG_USE_IRQ _must_ be defined when using CONFIG_S3C4510B +# else +static struct _irq_handler IRQ_HANDLER[N_IRQS]; +# endif +#endif /* CONFIG_S3C4510B */ + +#ifdef CONFIG_USE_IRQ +/* enable IRQ/FIQ interrupts */ +void enable_interrupts (void) +{ + unsigned long temp; + __asm__ __volatile__("mrs %0, cpsr\n" + "bic %0, %0, #0x80\n" + "msr cpsr_c, %0" + : "=r" (temp) + : + : "memory"); +} + + +/* + * disable IRQ/FIQ interrupts + * returns true if interrupts had been enabled before we disabled them + */ +int disable_interrupts (void) +{ + unsigned long old,temp; + __asm__ __volatile__("mrs %0, cpsr\n" + "orr %1, %0, #0x80\n" + "msr cpsr_c, %1" + : "=r" (old), "=r" (temp) + : + : "memory"); + return (old & 0x80) == 0; +} +#else /* CONFIG_USE_IRQ */ +void enable_interrupts (void) +{ + return; +} +int disable_interrupts (void) +{ + return 0; +} +#endif + +void bad_mode (void) +{ + panic ("Resetting CPU ...\n"); + reset_cpu (0); +} + +void show_regs (struct pt_regs *regs) +{ + unsigned long flags; + const char *processor_modes[] = + { "USER_26", "FIQ_26", "IRQ_26", "SVC_26", "UK4_26", "UK5_26", +"UK6_26", "UK7_26", + "UK8_26", "UK9_26", "UK10_26", "UK11_26", "UK12_26", "UK13_26", + "UK14_26", "UK15_26", + "USER_32", "FIQ_32", "IRQ_32", "SVC_32", "UK4_32", "UK5_32", + "UK6_32", "ABT_32", + "UK8_32", "UK9_32", "UK10_32", "UND_32", "UK12_32", "UK13_32", + "UK14_32", "SYS_32" + }; + + flags = condition_codes (regs); + + printf ("pc : [<%08lx>] lr : [<%08lx>]\n" + "sp : %08lx ip : %08lx fp : %08lx\n", + instruction_pointer (regs), + regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); + printf ("r10: %08lx r9 : %08lx r8 : %08lx\n", + regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); + printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); + printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); + printf ("Flags: %c%c%c%c", + flags & CC_N_BIT ? 'N' : 'n', + flags & CC_Z_BIT ? 'Z' : 'z', + flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); + printf (" IRQs %s FIQs %s Mode %s%s\n", + interrupts_enabled (regs) ? "on" : "off", + fast_interrupts_enabled (regs) ? "on" : "off", + processor_modes[processor_mode (regs)], + thumb_mode (regs) ? " (T)" : ""); +} + +void do_undefined_instruction (struct pt_regs *pt_regs) +{ + printf ("undefined instruction\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_software_interrupt (struct pt_regs *pt_regs) +{ + printf ("software interrupt\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_prefetch_abort (struct pt_regs *pt_regs) +{ + printf ("prefetch abort\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_data_abort (struct pt_regs *pt_regs) +{ + printf ("data abort\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_not_used (struct pt_regs *pt_regs) +{ + printf ("not used\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_fiq (struct pt_regs *pt_regs) +{ + printf ("fast interrupt request\n"); + show_regs (pt_regs); + bad_mode (); +} + +void do_irq (struct pt_regs *pt_regs) +{ +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) + printf ("interrupt request\n"); + show_regs (pt_regs); + bad_mode (); +#elif defined(CONFIG_S3C4510B) + unsigned int pending; + + while ( (pending = GET_REG( REG_INTOFFSET)) != 0x54) { /* sentinal value for no pending interrutps */ + IRQ_HANDLER[pending>>2].m_func( IRQ_HANDLER[pending>>2].m_data); + + /* clear pending interrupt */ + PUT_REG( REG_INTPEND, (1<<(pending>>2))); + } +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No do_irq() for IntegratorAP/CM720T as yet */ +#else +#error do_irq() not defined for this CPU type +#endif +} + + +#ifdef CONFIG_S3C4510B +static void default_isr( void *data) { + printf ("default_isr(): called for IRQ %d\n", (int)data); +} + +static void timer_isr( void *data) { + unsigned int *pTime = (unsigned int *)data; + + (*pTime)++; + if ( !(*pTime % (CFG_HZ/4))) { + /* toggle LED 0 */ + PUT_REG( REG_IOPDATA, GET_REG(REG_IOPDATA) ^ 0x1); + } + +} +#endif + +#if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* Use IntegratorAP routines in board/integratorap.c */ +#else + +static ulong timestamp; +static ulong lastdec; + +int interrupt_init (void) +{ + +#if defined(CONFIG_NETARM) + /* disable all interrupts */ + IRQEN = 0; + + /* operate timer 2 in non-prescale mode */ + TM2CTRL = ( NETARM_GEN_TIMER_SET_HZ(CFG_HZ) | + NETARM_GEN_TCTL_ENABLE | + NETARM_GEN_TCTL_INIT_COUNT(TIMER_LOAD_VAL)); + + /* set timer 2 counter */ + lastdec = TIMER_LOAD_VAL; +#elif defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + /* disable all interrupts */ + IO_INTMR1 = 0; + + /* operate timer 1 in prescale mode */ + IO_SYSCON1 |= SYSCON1_TC1M; + + /* select 2kHz clock source for timer 1 */ + IO_SYSCON1 &= ~SYSCON1_TC1S; + + /* set timer 1 counter */ + lastdec = IO_TC1D = TIMER_LOAD_VAL; +#elif defined(CONFIG_S3C4510B) + int i; + + /* install default interrupt handlers */ + for ( i = 0; i < N_IRQS; i++) { + IRQ_HANDLER[i].m_data = (void *)i; + IRQ_HANDLER[i].m_func = default_isr; + } + + /* configure interrupts for IRQ mode */ + PUT_REG( REG_INTMODE, 0x0); + /* clear any pending interrupts */ + PUT_REG( REG_INTPEND, 0x1FFFFF); + + lastdec = 0; + + /* install interrupt handler for timer */ + IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp; + IRQ_HANDLER[INT_TIMER0].m_func = timer_isr; + + /* configure free running timer 0 */ + PUT_REG( REG_TMOD, 0x0); + /* Stop timer 0 */ + CLR_REG( REG_TMOD, TM0_RUN); + + /* Configure for interval mode */ + CLR_REG( REG_TMOD, TM1_TOGGLE); + + /* + * Load Timer data register with count down value. + * count_down_val = CFG_SYS_CLK_FREQ/CFG_HZ + */ + PUT_REG( REG_TDATA0, (CFG_SYS_CLK_FREQ / CFG_HZ)); + + /* + * Enable global interrupt + * Enable timer0 interrupt + */ + CLR_REG( REG_INTMASK, ((1<<INT_GLOBAL) | (1<<INT_TIMER0))); + + /* Start timer */ + SET_REG( REG_TMOD, TM0_RUN); + +#else +#error No interrupt_init() defined for this CPU type +#endif + timestamp = 0; + + return (0); +} + +#endif /* ! IntegratorAP */ + +/* + * timer without interrupts + */ + + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_NETARM) || defined(CONFIG_ARMADILLO) + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay (unsigned long usec) +{ + ulong tmo; + + tmo = usec / 1000; + tmo *= CFG_HZ; + tmo /= 1000; + + tmo += get_timer (0); + + while (get_timer_masked () < tmo) + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; + + 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; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CFG_HZ; + tmo /= 1000; + } else { + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +#elif defined(CONFIG_S3C4510B) + +ulong get_timer (ulong base) +{ + return timestamp - base; +} + +void udelay (unsigned long usec) +{ + u32 ticks; + + ticks = (usec * CFG_HZ) / 1000000; + + ticks += get_timer (0); + + while (get_timer (0) < ticks) + /*NOP*/; + +} + +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No timer routines for IntegratorAP/CM720T as yet */ +#else +#error Timer routines not defined for this CPU type +#endif diff --git a/cpu/arm720t/serial.c b/cpu/arm720t/serial.c new file mode 100755 index 0000000..0f99979 --- /dev/null +++ b/cpu/arm720t/serial.c @@ -0,0 +1,126 @@ +/* + * (C) Copyright 2002-2004 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * (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> + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * 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 <common.h> + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + +#include <clps7111.h> + +void serial_setbrg (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + unsigned int reg = 0; + + switch (gd->baudrate) { + case 1200: reg = 191; break; + case 9600: reg = 23; break; + case 19200: reg = 11; break; + case 38400: reg = 5; break; + case 57600: reg = 3; break; + case 115200: reg = 1; break; + default: hang (); break; + } + + /* init serial serial 1,2 */ + IO_SYSCON1 = SYSCON1_UART1EN; + IO_SYSCON2 = SYSCON2_UART2EN; + + reg |= UBRLCR_WRDLEN8; + + IO_UBRLCR1 = reg; + IO_UBRLCR2 = reg; +} + + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + * + */ +int serial_init (void) +{ + serial_setbrg (); + + return (0); +} + + +/* + * Output a single byte to the serial port. + */ +void serial_putc (const char c) +{ + int tmo; + + /* If \n, also do \r */ + if (c == '\n') + serial_putc ('\r'); + + tmo = get_timer (0) + 1 * CFG_HZ; + while (IO_SYSFLG1 & SYSFLG1_UTXFF) + if (get_timer (0) > tmo) + break; + + IO_UARTDR1 = c; +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_tstc (void) +{ + return !(IO_SYSFLG1 & SYSFLG1_URXFE); +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_getc (void) +{ + while (IO_SYSFLG1 & SYSFLG1_URXFE); + + return IO_UARTDR1 & 0xff; +} + +void +serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +#endif /* defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) */ diff --git a/cpu/arm720t/serial_netarm.c b/cpu/arm720t/serial_netarm.c new file mode 100755 index 0000000..5ad98f0 --- /dev/null +++ b/cpu/arm720t/serial_netarm.c @@ -0,0 +1,201 @@ +/* + * Serial Port stuff - taken from Linux + * + * (C) Copyright 2002 + * MAZeT GmbH <www.mazet.de> + * Stephan Linz <linz@mazet.de>, <linz@li-pro.net> + * + * (c) 2004 + * IMMS gGmbH <www.imms.de> + * Thomas Elste <info@elste.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 <common.h> + +#ifdef CONFIG_NETARM + +#include <asm/hardware.h> + +#define PORTA (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTA)) +#if !defined(CONFIG_NETARM_NS7520) +#define PORTB (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTB)) +#else +#define PORTC (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTC)) +#endif + +/* wait until transmitter is ready for another character */ +#define TXWAITRDY(registers) \ +{ \ + ulong tmo = get_timer(0) + 1 * CFG_HZ; \ + while (((registers)->status_a & NETARM_SER_STATA_TX_RDY) == 0 ) { \ + if (get_timer(0) > tmo) \ + break; \ + } \ +} + + +#ifndef CONFIG_UART1_CONSOLE +volatile netarm_serial_channel_t *serial_reg_ch1 = get_serial_channel(0); +volatile netarm_serial_channel_t *serial_reg_ch2 = get_serial_channel(1); +#else +volatile netarm_serial_channel_t *serial_reg_ch1 = get_serial_channel(1); +volatile netarm_serial_channel_t *serial_reg_ch2 = get_serial_channel(0); +#endif + +extern void _netarm_led_FAIL1(void); + +/* + * Setup both serial i/f with given baudrate + */ +void serial_setbrg (void) +{ + /* get the gd pointer */ + DECLARE_GLOBAL_DATA_PTR; + + /* set 0 ... make sure pins are configured for serial */ +#if !defined(CONFIG_NETARM_NS7520) + PORTA = PORTB = + NETARM_GEN_PORT_MODE (0xef) | NETARM_GEN_PORT_DIR (0xe0); +#else + PORTA = NETARM_GEN_PORT_MODE (0xef) | NETARM_GEN_PORT_DIR (0xe0); + PORTC = NETARM_GEN_PORT_CSF (0xef) | NETARM_GEN_PORT_MODE (0xef) | NETARM_GEN_PORT_DIR (0xe0); +#endif + + /* first turn em off */ + serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a = 0; + + /* clear match register, we don't need it */ + serial_reg_ch1->rx_match = serial_reg_ch2->rx_match = 0; + + /* setup bit rate generator and rx buffer gap timer (1 byte only) */ + if ((gd->baudrate >= MIN_BAUD_RATE) + && (gd->baudrate <= MAX_BAUD_RATE)) { + serial_reg_ch1->bitrate = serial_reg_ch2->bitrate = + NETARM_SER_BR_X16 (gd->baudrate); + serial_reg_ch1->rx_buf_timer = serial_reg_ch2->rx_buf_timer = + 0; + serial_reg_ch1->rx_char_timer = serial_reg_ch2->rx_char_timer = + NETARM_SER_RXGAP (gd->baudrate); + } else { + hang (); + } + + /* setup port mode */ + serial_reg_ch1->ctrl_b = serial_reg_ch2->ctrl_b = + ( NETARM_SER_CTLB_RCGT_EN | + NETARM_SER_CTLB_UART_MODE); + serial_reg_ch1->ctrl_a = serial_reg_ch2->ctrl_a = + ( NETARM_SER_CTLA_ENABLE | + NETARM_SER_CTLA_P_NONE | + /* see errata */ + NETARM_SER_CTLA_2STOP | + NETARM_SER_CTLA_8BITS | + NETARM_SER_CTLA_DTR_EN | + NETARM_SER_CTLA_RTS_EN); +} + + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + */ +int serial_init (void) +{ + serial_setbrg (); + return 0; +} + + +/* + * Output a single byte to the serial port. + */ +void serial_putc (const char c) +{ + volatile unsigned char *fifo; + + /* If \n, also do \r */ + if (c == '\n') + serial_putc ('\r'); + + fifo = (volatile unsigned char *) &(serial_reg_ch1->fifo); + TXWAITRDY (serial_reg_ch1); + *fifo = c; +} + +/* + * Test of a single byte from the serial port. Returns 1 on success, 0 + * otherwise. + */ +int serial_tstc(void) +{ + return serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY; +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. + */ +int serial_getc (void) +{ + unsigned int ch_uint; + volatile unsigned int *fifo; + volatile unsigned char *fifo_char = NULL; + int buf_count = 0; + + while (!(serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY)) + /* NOP */ ; + + fifo = (volatile unsigned int *) &(serial_reg_ch1->fifo); + fifo_char = (unsigned char *) &ch_uint; + ch_uint = *fifo; + + buf_count = NETARM_SER_STATA_RXFDB (serial_reg_ch1->status_a); + switch (buf_count) { + case NETARM_SER_STATA_RXFDB_4BYTES: + buf_count = 4; + break; + case NETARM_SER_STATA_RXFDB_3BYTES: + buf_count = 3; + break; + case NETARM_SER_STATA_RXFDB_2BYTES: + buf_count = 2; + break; + case NETARM_SER_STATA_RXFDB_1BYTES: + buf_count = 1; + break; + default: + /* panic, be never here */ + break; + } + + serial_reg_ch1->status_a |= NETARM_SER_STATA_RX_CLOSED; + + return ch_uint & 0xff; +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + +#endif /* CONFIG_NETARM */ diff --git a/cpu/arm720t/start.S b/cpu/arm720t/start.S new file mode 100755 index 0000000..e66d109 --- /dev/null +++ b/cpu/arm720t/start.S @@ -0,0 +1,542 @@ +/* + * armboot - Startup Code for ARM720 CPU-core + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * + * 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 <version.h> +#include <asm/hardware.h> + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from RAM! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: + .word 0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: + .word 0x0badc0de +#endif + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0x13 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + +#ifndef CONFIG_SKIP_RELOCATE_UBOOT +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + beq stack_setup + +#if TEXT_BASE + ldr r2, =0x0 /* Relocate the exception vectors */ + cmp r1, r2 /* and associated data to address */ + ldmneia r0!, {r3-r10} /* 0x0. Do nothing if TEXT_BASE is */ + stmneia r2!, {r3-r10} /* 0x0. Copy the first 15 words. */ + ldmneia r0, {r3-r9} + stmneia r2, {r3-r9} + adrne r0, _start /* restore r0 */ +#endif + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + +#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ +#ifdef CONFIG_USE_IRQ + sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + +/* Interupt-Controller base addresses */ +INTMR1: .word 0x80000280 @ 32 bit size +INTMR2: .word 0x80001280 @ 16 bit size +INTMR3: .word 0x80002280 @ 8 bit size + +/* SYSCONs */ +SYSCON1: .word 0x80000100 +SYSCON2: .word 0x80001100 +SYSCON3: .word 0x80002200 + +#define CLKCTL 0x6 /* mask */ +#define CLKCTL_18 0x0 /* 18.432 MHz */ +#define CLKCTL_36 0x2 /* 36.864 MHz */ +#define CLKCTL_49 0x4 /* 49.152 MHz */ +#define CLKCTL_73 0x6 /* 73.728 MHz */ + +#endif + +cpu_init_crit: +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + + /* + * mask all IRQs by clearing all bits in the INTMRs + */ + mov r1, #0x00 + ldr r0, INTMR1 + str r1, [r0] + ldr r0, INTMR2 + str r1, [r0] + ldr r0, INTMR3 + str r1, [r0] + + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15,0,r0,c1,c0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x0000008f @ clear bits 7, 3:0 (B--- WCAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + mcr p15,0,r0,c1,c0 +#elif defined(CONFIG_NETARM) + /* + * prior to software reset : need to set pin PORTC4 to be *HRESET + */ + ldr r0, =NETARM_GEN_MODULE_BASE + ldr r1, =(NETARM_GEN_PORT_MODE(0x10) | \ + NETARM_GEN_PORT_DIR(0x10)) + str r1, [r0, #+NETARM_GEN_PORTC] + /* + * software reset : see HW Ref. Guide 8.2.4 : Software Service register + * for an explanation of this process + */ + ldr r0, =NETARM_GEN_MODULE_BASE + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE] + /* + * setup PLL and System Config + */ + ldr r0, =NETARM_GEN_MODULE_BASE + + ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \ + NETARM_GEN_SYS_CFG_BUSFULL | \ + NETARM_GEN_SYS_CFG_USER_EN | \ + NETARM_GEN_SYS_CFG_ALIGN_ABORT | \ + NETARM_GEN_SYS_CFG_BUSARB_INT | \ + NETARM_GEN_SYS_CFG_BUSMON_EN ) + + str r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL] + +#ifndef CONFIG_NETARM_PLL_BYPASS + ldr r1, =( NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \ + NETARM_GEN_PLL_CTL_POLTST_DEF | \ + NETARM_GEN_PLL_CTL_INDIV(1) | \ + NETARM_GEN_PLL_CTL_ICP_DEF | \ + NETARM_GEN_PLL_CTL_OUTDIV(2) ) + str r1, [r0, #+NETARM_GEN_PLL_CONTROL] +#endif + + /* + * mask all IRQs by clearing all bits in the INTMRs + */ + mov r1, #0 + ldr r0, =NETARM_GEN_MODULE_BASE + str r1, [r0, #+NETARM_GEN_INTR_ENABLE] + +#elif defined(CONFIG_S3C4510B) + + /* + * Mask off all IRQ sources + */ + ldr r1, =REG_INTMASK + ldr r0, =0x3FFFFF + str r0, [r1] + + /* + * Disable Cache + */ + ldr r0, =REG_SYSCFG + ldr r1, =0x83ffffa0 /* cache-disabled */ + str r1, [r0] + +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No specific initialisation for IntegratorAP/CM720T as yet */ +#else +#error No cpu_init_crit() defined for current CPU type +#endif + +#ifdef CONFIG_ARM7_REVD + /* set clock speed */ + /* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */ + /* !!! not doing DRAM refresh properly! */ + ldr r0, SYSCON3 + ldr r1, [r0] + bic r1, r1, #CLKCTL + orr r1, r1, #CLKCTL_36 + str r1, [r0] +#endif + + mov ip, lr + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependent, you will + * find a lowlevel_init.S in your board directory. + */ + bl lowlevel_init + mov lr, ip + + mov pc, lr + + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + + ldr r2, _armboot_start + sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) + sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 + add r0, sp, #S_FRAME_SIZE @ restore sp_SVC + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r + mov r0, sp + .endm + + .macro irq_save_user_regs + sub sp, sp, #S_FRAME_SIZE + stmia sp, {r0 - r12} @ Calling r0-r12 + add r8, sp, #S_PC + stmdb r8, {sp, lr}^ @ Calling SP, LR + str lr, [r8, #0] @ Save calling PC + mrs r6, spsr + str r6, [r8, #4] @ Save CPSR + str r0, [r8, #8] @ Save OLD_R0 + mov r0, sp + .endm + + .macro irq_restore_user_regs + ldmia sp, {r0 - lr}^ @ Calling r0 - lr + mov r0, r0 + ldr lr, [sp, #S_PC] @ Get PC + add sp, sp, #S_FRAME_SIZE + subs pc, lr, #4 @ return & move spsr_svc into cpsr + .endm + + .macro get_bad_stack + ldr r13, _armboot_start @ setup our mode stack + sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) + sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + + str lr, [r13] @ save caller lr / spsr + mrs lr, spsr + str lr, [r13, #4] + + mov r13, #MODE_SVC @ prepare SVC-Mode + msr spsr_c, r13 + mov lr, pc + movs pc, lr + .endm + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + +#ifdef CONFIG_USE_IRQ + + .align 5 +irq: + get_irq_stack + irq_save_user_regs + bl do_irq + irq_restore_user_regs + + .align 5 +fiq: + get_fiq_stack + /* someone ought to write a more effiction fiq_save_user_regs */ + irq_save_user_regs + bl do_fiq + irq_restore_user_regs + +#else + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq + +#endif + +#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO) + .align 5 +.globl reset_cpu +reset_cpu: + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate cache + mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x000f @ ............wcam + bic ip, ip, #0x2100 @ ..v....s........ + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 +#elif defined(CONFIG_NETARM) + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, =NETARM_MEM_MODULE_BASE + ldr r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR] + ldr r1, =0xFFFFF000 + and r0, r1, r0 + ldr r1, =(relocate-TEXT_BASE) + add r0, r1, r0 + ldr r4, =NETARM_GEN_MODULE_BASE + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETA + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + ldr r1, =NETARM_GEN_SW_SVC_RESETB + str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE] + mov pc, r0 +#elif defined(CONFIG_S3C4510B) +/* Nothing done here as reseting the CPU is board specific, depending + * on external peripherals such as watchdog timers, etc. */ +#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) + /* No specific reset actions for IntegratorAP/CM720T as yet */ +#else +#error No reset_cpu() defined for current CPU type +#endif |