diff options
Diffstat (limited to 'cpu/mips')
| -rw-r--r-- | cpu/mips/Makefile | 44 | ||||
| -rw-r--r-- | cpu/mips/cache.S | 265 | ||||
| -rw-r--r-- | cpu/mips/config.mk | 25 | ||||
| -rw-r--r-- | cpu/mips/cpu.c | 41 | ||||
| -rw-r--r-- | cpu/mips/incaip_clock.c | 107 | ||||
| -rw-r--r-- | cpu/mips/incaip_wdt.S | 73 | ||||
| -rw-r--r-- | cpu/mips/interrupts.c | 34 | ||||
| -rw-r--r-- | cpu/mips/serial.c | 282 | ||||
| -rw-r--r-- | cpu/mips/serial.h | 178 | ||||
| -rw-r--r-- | cpu/mips/start.S | 350 | 
10 files changed, 1399 insertions, 0 deletions
| diff --git a/cpu/mips/Makefile b/cpu/mips/Makefile new file mode 100644 index 000000000..91008bfe1 --- /dev/null +++ b/cpu/mips/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2003 +# 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	= interrupts.o cpu.o incaip_clock.o serial.o +SOBJS	= incaip_wdt.o cache.o + +all:	.depend $(START) $(LIB) + +$(LIB):	$(OBJS) $(SOBJS) +	$(AR) crv $@ $(OBJS) $(SOBJS) + +######################################################################### + +.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/mips/cache.S b/cpu/mips/cache.S new file mode 100644 index 000000000..aeb04b379 --- /dev/null +++ b/cpu/mips/cache.S @@ -0,0 +1,265 @@ +/* + *  Cache-handling routined for MIPS 4K CPUs + * + *  Copyright (c) 2003	Wolfgang Denk <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 <config.h> +#include <version.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/cacheops.h> + + +	/* 16KB is the maximum size of instruction and data caches on +	 * MIPS 4K. +	 */ +#define MIPS_MAX_CACHE_SIZE	0x4000 + + +/* + * cacheop macro to automate cache operations + * first some helpers... + */ +#define _mincache(size, maxsize) \ +   bltu  size,maxsize,9f ; \ +   move  size,maxsize ;    \ +9: + +#define _align(minaddr, maxaddr, linesize) \ +   .set noat ; \ +   subu  AT,linesize,1 ;   \ +   not   AT ;        \ +   and   minaddr,AT ;      \ +   addu  maxaddr,-1 ;      \ +   and   maxaddr,AT ;      \ +   .set at + +/* general operations */ +#define doop1(op1) \ +   cache op1,0(a0) +#define doop2(op1, op2) \ +   cache op1,0(a0) ;    \ +   nop ;          \ +   cache op2,0(a0) + +/* specials for cache initialisation */ +#define doop1lw(op1) \ +   lw zero,0(a0) +#define doop1lw1(op1) \ +   cache op1,0(a0) ;    \ +   lw zero,0(a0) ;      \ +   cache op1,0(a0) +#define doop121(op1,op2) \ +   cache op1,0(a0) ;    \ +   nop;           \ +   cache op2,0(a0) ;    \ +   nop;           \ +   cache op1,0(a0) + +#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \ +   .set  noreorder ;    \ +10:   doop##tag##ops ;  \ +   bne     minaddr,maxaddr,10b ; \ +   add      minaddr,linesize ;   \ +   .set  reorder + +/* finally the cache operation macros */ +#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \ +   blez  n,11f ;        \ +   addu  n,kva ;        \ +   _align(kva, n, cacheLineSize) ; \ +   _oploopn(kva, n, cacheLineSize, tag, ops) ; \ +11: + +#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \ +   _mincache(n, cacheSize);   \ +   blez  n,11f ;        \ +   addu  n,kva ;        \ +   _align(kva, n, cacheLineSize) ; \ +   _oploopn(kva, n, cacheLineSize, tag, ops) ; \ +11: + +#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \ +   vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op)) + +#define icacheop(kva, n, cacheSize, cacheLineSize, op) \ +   icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op)) + +/******************************************************************************* +* +* mips_cache_reset - low level initialisation of the primary caches +* +* This routine initialises the primary caches to ensure that they +* have good parity.  It must be called by the ROM before any cached locations +* are used to prevent the possibility of data with bad parity being written to +* memory. +* To initialise the instruction cache it is essential that a source of data +* with good parity is available. This routine +* will initialise an area of memory starting at location zero to be used as +* a source of parity. +* +* RETURNS: N/A +* +*/ +	.globl	mips_cache_reset +	.ent	mips_cache_reset +mips_cache_reset: + +	li	t2, CFG_ICACHE_SIZE +	li	t3, CFG_DCACHE_SIZE +	li	t4, CFG_CACHELINE_SIZE +	move	t5, t4 + + +	li	v0, MIPS_MAX_CACHE_SIZE + +	/* Now clear that much memory starting from zero. +	 */ + +	li	a0, KSEG1 +	addu	a1, a0, v0 + +2:	sw	zero, 0(a0) +	sw	zero, 4(a0) +	sw	zero, 8(a0) +	sw	zero, 12(a0) +	sw	zero, 16(a0) +	sw	zero, 20(a0) +	sw	zero, 24(a0) +	sw	zero, 28(a0) +	addu	a0, 32 +	bltu	a0, a1, 2b +    +	/* Set invalid tag. +	 */ + +	mtc0	zero, CP0_TAGLO + +   /* +    * The caches are probably in an indeterminate state, +    * so we force good parity into them by doing an +    * invalidate, load/fill, invalidate for each line. +    */ + +	/* Assume bottom of RAM will generate good parity for the cache. +	 */ + +	li	a0, K0BASE +	move	a2, t2		# icacheSize +	move	a3, t4		# icacheLineSize +	move	a1, a2 +	icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill)) + +	/* To support Orion/R4600, we initialise the data cache in 3 passes. +	 */ + +	/* 1: initialise dcache tags. +	 */ + +	li	a0, K0BASE +	move	a2, t3		# dcacheSize +	move	a3, t5		# dcacheLineSize +	move	a1, a2 +	icacheop(a0,a1,a2,a3,Index_Store_Tag_D) + +	/* 2: fill dcache. +	 */ + +	li	a0, K0BASE +	move	a2, t3		# dcacheSize +	move	a3, t5		# dcacheLineSize +	move	a1, a2 +	icacheopn(a0,a1,a2,a3,1lw,(dummy)) + +	/* 3: clear dcache tags. +	 */ + +	li	a0, K0BASE +	move	a2, t3		# dcacheSize +	move	a3, t5		# dcacheLineSize +	move	a1, a2 +	icacheop(a0,a1,a2,a3,Index_Store_Tag_D) + +	j  ra +	.end  mips_cache_reset + + +/******************************************************************************* +* +* dcache_status - get cache status +* +* RETURNS: 0 - cache disabled; 1 - cache enabled +* +*/ +	.globl	dcache_status +	.ent	dcache_status +dcache_status: + +	mfc0	v0, CP0_CONFIG +	andi	v0, v0, 1 +	j	ra + +	.end  dcache_status + +/******************************************************************************* +* +* dcache_disable - disable cache +* +* RETURNS: N/A +* +*/ +	.globl	dcache_disable +	.ent	dcache_disable +dcache_disable: + +	mfc0	t0, CP0_CONFIG +	li	t1, -8 +	and	t0, t0, t1 +	ori	t0, t0, CONF_CM_UNCACHED +	mtc0    t0, CP0_CONFIG +	j	ra + +	.end  dcache_disable + + +/******************************************************************************* +* +* mips_cache_lock - lock RAM area pointed to by a0 in cache. +* +* RETURNS: N/A +* +*/ +	.globl	mips_cache_lock +	.ent	mips_cache_lock +mips_cache_lock: +	li	a1, K0BASE - CFG_DCACHE_SIZE +	addu	a0, a1 +	li	a2, CFG_DCACHE_SIZE +	li	a3, CFG_CACHELINE_SIZE +	move	a1, a2 +	icacheop(a0,a1,a2,a3,0x1d) + +	j	ra +	.end	mips_cache_lock + diff --git a/cpu/mips/config.mk b/cpu/mips/config.mk new file mode 100644 index 000000000..4ea66172d --- /dev/null +++ b/cpu/mips/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2003 +# 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 +# + +PLATFORM_CPPFLAGS += -mcpu=4kc -EB -mabicalls + diff --git a/cpu/mips/cpu.c b/cpu/mips/cpu.c new file mode 100644 index 000000000..3fc3916b4 --- /dev/null +++ b/cpu/mips/cpu.c @@ -0,0 +1,41 @@ +/* + * (C) Copyright 2003 + * 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 <common.h> +#include <command.h> +#include <asm/inca-ip.h> + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#ifdef CONFIG_INCA_IP +	*INCA_IP_WDT_RST_REQ = 0x3f; +#endif +	fprintf(stderr, "*** reset failed ***\n"); +	return 0; +} + +void flush_cache (ulong start_addr, ulong size) +{ + +} + diff --git a/cpu/mips/incaip_clock.c b/cpu/mips/incaip_clock.c new file mode 100644 index 000000000..7fc6eb035 --- /dev/null +++ b/cpu/mips/incaip_clock.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2003 + * 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 <common.h> +#include <asm/inca-ip.h> + + + +/******************************************************************************* +* +* get_cpuclk - returns the frequency of the CPU.  +* +* Gets the value directly from the INCA-IP hardware. +* +* RETURNS:  +*          150.000.000 for 150 MHz +*          130.000.000. for 130 Mhz +*          100.000.000. for 100 Mhz +* NOTE: +*   This functions should be used by the hardware driver to get the correct +*   frequency of the CPU. Don't use the macros, which are set to init the CPU +*   frequency in the ROM code. +*/ +uint incaip_get_cpuclk(void) +{ +   /*-------------------------------------------------------------------------*/ +   /* CPU Clock Input Multiplexer (MUX I)                                     */ +   /* Multiplexer MUX I selects the maximum input clock to the CPU.           */ +   /*-------------------------------------------------------------------------*/ +   if (*((volatile ulong*)INCA_IP_CGU_CGU_MUXCR) & INCA_IP_CGU_CGU_MUXCR_MUXI) +   { +      /* MUX I set to 150 MHz clock */ +      return 150000000; +   } +   else +   { +      /* MUX I set to 100/133 MHz clock */ +      if (*((volatile ulong*)INCA_IP_CGU_CGU_DIVCR) & 0x40)  +      { +         /* Division value is 1/3, maximum CPU operating */ +         /* frequency is 133.3 MHz                       */ +         return 130000000; +      } +      else +      { +         /* Division value is 1/4, maximum CPU operating */ +         /* frequency is 100 MHz                         */ +         return 100000000; +      } +   } +} + +/******************************************************************************* +* +* get_fpiclk - returns the frequency of the FPI bus.  +* +* Gets the value directly from the INCA-IP hardware. +* +* RETURNS: Frquency in Hz +* +* NOTE: +*   This functions should be used by the hardware driver to get the correct +*   frequency of the CPU. Don't use the macros, which are set to init the CPU +*   frequency in the ROM code. +*   The calculation for the  +*/ +uint incaip_get_fpiclk(void) +{ +   uint  clkCPU; +    +   clkCPU = incaip_get_cpuclk(); +    +   switch (*((volatile ulong*)INCA_IP_CGU_CGU_DIVCR) & 0xC) +   { +      case 0x4: +         return clkCPU >> 1; /* devided by 2 */ +         break; +      case 0x8: +         return clkCPU >> 2; /* devided by 4 */ +         break; +      default: +         return clkCPU; +         break; +   } +} + + diff --git a/cpu/mips/incaip_wdt.S b/cpu/mips/incaip_wdt.S new file mode 100644 index 000000000..9455569f5 --- /dev/null +++ b/cpu/mips/incaip_wdt.S @@ -0,0 +1,73 @@ +/* + *  INCA-IP Watchdog timer management code. + * + *  Copyright (c) 2003	Wolfgang Denk <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 <config.h> +#include <version.h> +#include <asm/regdef.h> + + +#define WD_BASE            0xb8000000 +#define WD_CON0(value)     0x0020(value) +#define WD_CON1(value)     0x0024(value) +#define WD_DISABLE         0x00000008 +#define WD_ENABLE          0x00000000 +#define WD_WRITE_PW        0xFFFC00F8 +#define WD_WRITE_ENDINIT   0xFFFC00F3 +#define WD_WRITE_INIT      0xFFFC00F2 + + +	.globl	disable_incaip_wdt +disable_incaip_wdt: +	li	t0, WD_BASE + +	/* Calculate password. +	 */ +	lw	t2, WD_CON1(t0) +	and	t2, 0xC + +	lw	t3, WD_CON0(t0) +	and	t3, 0xFFFFFF01 + +	or	t3, t2 +	or 	t3, 0xF0 + +	sw	t3, WD_CON0(t0)		/* write password */ + +	/* Clear ENDINIT. +	 */ +	li	t1, WD_WRITE_INIT +	sw	t1, WD_CON0(t0) + + +	li	t1, WD_DISABLE +	sw	t1, WD_CON1(t0)		/* disable watchdog */ +	li	t1, WD_WRITE_PW +	sw	t1, WD_CON0(t0)		/* write password */ +	li	t1, WD_WRITE_ENDINIT +	sw	t1, WD_CON0(t0)		/* end command */ + +	j	ra +	nop + diff --git a/cpu/mips/interrupts.c b/cpu/mips/interrupts.c new file mode 100644 index 000000000..0490a7661 --- /dev/null +++ b/cpu/mips/interrupts.c @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2003 + * 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 <common.h> + +void enable_interrupts(void) +{ +} + +int disable_interrupts(void) +{ +	return 0; +} + diff --git a/cpu/mips/serial.c b/cpu/mips/serial.c new file mode 100644 index 000000000..ebda509b1 --- /dev/null +++ b/cpu/mips/serial.c @@ -0,0 +1,282 @@ +/* + * (INCA) ASC UART support + */ + +#include <common.h> +#include <asm/inca-ip.h> +#include "serial.h" + +#define SET_BIT(reg, mask)                  reg |= (mask) +#define CLEAR_BIT(reg, mask)                reg &= (~mask) +#define CLEAR_BITS(reg, mask)               CLEAR_BIT(reg, mask) +#define SET_BITS(reg, mask)                 SET_BIT(reg, mask) +#define SET_BITFIELD(reg, mask, off, val)   {reg &= (~mask); reg |= (val << off);} + +extern uint incaip_get_fpiclk(void); + +static int serial_setopt (void); + +/* pointer to ASC register base address */ +static volatile incaAsc_t *pAsc = (incaAsc_t *)INCA_IP_ASC; + +/****************************************************************************** +* +* serial_init - initialize a INCAASC channel +* +* This routine initializes the number of data bits, parity +* and set the selected baud rate. Interrupts are disabled. +* Set the modem control signals if the option is selected. +* +* RETURNS: N/A +*/ + +int serial_init (void) +{ +    /* we have to set PMU.EN13 bit to enable an ASC device*/ +    INCAASC_PMU_ENABLE(13); +     +    /* and we have to set CLC register*/ +    CLEAR_BIT(pAsc->asc_clc, ASCCLC_DISS); +    SET_BITFIELD(pAsc->asc_clc, ASCCLC_RMCMASK, ASCCLC_RMCOFFSET, 0x0001); +     +    /* initialy we are in async mode */ +    pAsc->asc_con = ASCCON_M_8ASYNC; + +    /* select input port */ +    pAsc->asc_pisel = (CONSOLE_TTY & 0x1); + +    /* TXFIFO's filling level */ +    SET_BITFIELD(pAsc->asc_txfcon, ASCTXFCON_TXFITLMASK, +                    ASCTXFCON_TXFITLOFF, INCAASC_TXFIFO_FL); +    /* enable TXFIFO */ +    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXFEN); + +    /* RXFIFO's filling level */ +    SET_BITFIELD(pAsc->asc_txfcon, ASCRXFCON_RXFITLMASK,  +                    ASCRXFCON_RXFITLOFF, INCAASC_RXFIFO_FL); +    /* enable RXFIFO */ +    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXFEN); + +    /* enable error signals */ +    SET_BIT(pAsc->asc_con, ASCCON_FEN); +    SET_BIT(pAsc->asc_con, ASCCON_OEN); + +    /* acknowledge ASC interrupts */ +    ASC_INTERRUPTS_CLEAR(INCAASC_IRQ_LINE_ALL); + +    /* disable ASC interrupts */ +    ASC_INTERRUPTS_DISABLE(INCAASC_IRQ_LINE_ALL); + +    /* set FIFOs into the transparent mode */ +    SET_BIT(pAsc->asc_txfcon, ASCTXFCON_TXTMEN); +    SET_BIT(pAsc->asc_rxfcon, ASCRXFCON_RXTMEN); + +    /* set baud rate */ +    serial_setbrg(); + +    /* set the options */ +    serial_setopt(); +     +    return 0; +} + +void serial_setbrg (void) +{ +    ulong      uiReloadValue, fdv; +    ulong      f_ASC; + +    f_ASC = incaip_get_fpiclk(); + +#ifndef INCAASC_USE_FDV +    fdv = 2; +    uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1; +#else  +    fdv = INCAASC_FDV_HIGH_BAUDRATE; +    uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1; +#endif /* INCAASC_USE_FDV */ +     +    if ( (uiReloadValue < 0) || (uiReloadValue > 8191) ) +    { +#ifndef INCAASC_USE_FDV +        fdv = 3; +        uiReloadValue = (f_ASC / (fdv * 16 * CONFIG_BAUDRATE)) - 1; +#else  +        fdv = INCAASC_FDV_LOW_BAUDRATE; +        uiReloadValue = (f_ASC / (8192 * CONFIG_BAUDRATE / fdv)) - 1; +#endif /* INCAASC_USE_FDV */ +         +        if ( (uiReloadValue < 0) || (uiReloadValue > 8191) ) +        { +            return;    /* can't impossibly generate that baud rate */ +        } +    } + +    /* Disable Baud Rate Generator; BG should only be written when R=0 */ +    CLEAR_BIT(pAsc->asc_con, ASCCON_R); + +#ifndef INCAASC_USE_FDV +    /* +     * Disable Fractional Divider (FDE) +     * Divide clock by reload-value + constant (BRS) +     */ +    /* FDE = 0 */ +    CLEAR_BIT(pAsc->asc_con, ASCCON_FDE); + +    if ( fdv == 2 ) +        CLEAR_BIT(pAsc->asc_con, ASCCON_BRS);   /* BRS = 0 */ +    else +        SET_BIT(pAsc->asc_con, ASCCON_BRS); /* BRS = 1 */ + +#else /* INCAASC_USE_FDV */ + +    /* Enable Fractional Divider */ +    SET_BIT(pAsc->asc_con, ASCCON_FDE); /* FDE = 1 */ + +    /* Set fractional divider value */ +    pAsc->asc_fdv = fdv & ASCFDV_VALUE_MASK; + +#endif /* INCAASC_USE_FDV */ + +    /* Set reload value in BG */ +    pAsc->asc_bg = uiReloadValue; + +    /* Enable Baud Rate Generator */ +    SET_BIT(pAsc->asc_con, ASCCON_R);           /* R = 1 */ +} + +/******************************************************************************* +* +* serial_setopt - set the serial options +* +* Set the channel operating mode to that specified. Following options +* are supported: CREAD, CSIZE, PARENB, and PARODD. +* +* Note, this routine disables the transmitter.  The calling routine +* may have to re-enable it. +* +* RETURNS: +* Returns 0 to indicate success, otherwise -1 is returned +*/ + +static int serial_setopt (void) +{ +    ulong  con; + +    switch ( ASC_OPTIONS & ASCOPT_CSIZE ) +    { +    /* 7-bit-data */ +    case ASCOPT_CS7: +        con = ASCCON_M_7ASYNCPAR;   /* 7-bit-data and parity bit */ +        break; + +    /* 8-bit-data */ +    case ASCOPT_CS8: +        if ( ASC_OPTIONS & ASCOPT_PARENB ) +            con = ASCCON_M_8ASYNCPAR;   /* 8-bit-data and parity bit */ +        else +            con = ASCCON_M_8ASYNC;      /* 8-bit-data no parity */ +        break; +     +    /*  +     *  only 7 and 8-bit frames are supported +     *  if we don't use IOCTL extensions  +     */ +    default: +        return -1; +    } + +    if ( ASC_OPTIONS & ASCOPT_STOPB ) +        SET_BIT(con, ASCCON_STP);       /* 2 stop bits */ +    else +        CLEAR_BIT(con, ASCCON_STP);     /* 1 stop bit */ + +    if ( ASC_OPTIONS & ASCOPT_PARENB ) +        SET_BIT(con, ASCCON_PEN);           /* enable parity checking */     +    else +        CLEAR_BIT(con, ASCCON_PEN);         /* disable parity checking */ +     +    if ( ASC_OPTIONS & ASCOPT_PARODD ) +        SET_BIT(con, ASCCON_ODD);       /* odd parity */ +    else +        CLEAR_BIT(con, ASCCON_ODD);     /* even parity */ + +    if ( ASC_OPTIONS & ASCOPT_CREAD ) +        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_SETREN); /* Receiver enable */ + +    pAsc->asc_con |= con; + +    return 0; +} + +void serial_putc (const char c) +{ +    uint txFl = 0; + +    if (c == '\n') serial_putc ('\r'); + +    /* check do we have a free space in the TX FIFO */ +    /* get current filling level */ +    do +    { +	txFl = ( pAsc->asc_fstat & ASCFSTAT_TXFFLMASK ) >> ASCFSTAT_TXFFLOFF; +    } +    while ( txFl == INCAASC_TXFIFO_FULL ); + +    pAsc->asc_tbuf = c; /* write char to Transmit Buffer Register */ +    /* check for errors */ +    if ( pAsc->asc_con & ASCCON_OE ) +    { +        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE); +        return; +    } +} + +void serial_puts (const char *s) +{ +    while (*s) +    { +	serial_putc (*s++); +    } +} + +int serial_getc (void) +{ +    ulong symbol_mask; +    char c; + +    while (!serial_tstc()); + +    symbol_mask = +	((ASC_OPTIONS & ASCOPT_CSIZE) == ASCOPT_CS7) ? (0x7f) : (0xff); +     +    c = (char)(pAsc->asc_rbuf & symbol_mask); + +    return c; +} + +int serial_tstc (void) +{ +    int res = 1; + +    if ( (pAsc->asc_fstat & ASCFSTAT_RXFFLMASK) == 0 ) +    { +        res = 0; +    } +    else if ( pAsc->asc_con & ASCCON_FE ) +    { +        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRFE); +        res = 0; +    } +    else if ( pAsc->asc_con & ASCCON_PE ) +    { +        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLRPE); +        res = 0; +    } +    else if ( pAsc->asc_con & ASCCON_OE ) +    { +        SET_BIT(pAsc->asc_whbcon, ASCWHBCON_CLROE); +        res = 0; +    } + +    return res; +} diff --git a/cpu/mips/serial.h b/cpu/mips/serial.h new file mode 100644 index 000000000..ee63360e6 --- /dev/null +++ b/cpu/mips/serial.h @@ -0,0 +1,178 @@ +/* incaAscSio.h - (INCA) ASC UART tty driver header */ + +#ifndef __INCincaAscSioh +#define __INCincaAscSioh + +#include <asm/inca-ip.h> + +/* channel operating modes */ +#define	ASCOPT_CSIZE	0x00000003 +#define	ASCOPT_CS7	0x00000001 +#define	ASCOPT_CS8	0x00000002 +#define	ASCOPT_PARENB	0x00000004 +#define	ASCOPT_STOPB	0x00000008 +#define	ASCOPT_PARODD	0x00000010 +#define	ASCOPT_CREAD	0x00000020 + +#define ASC_OPTIONS		(ASCOPT_CREAD | ASCOPT_CS8) + +/* ASC input select (0 or 1) */ +#define CONSOLE_TTY	0 + +/* use fractional divider for baudrate settings */ +#define INCAASC_USE_FDV + +#ifdef INCAASC_USE_FDV +   #define INCAASC_FDV_LOW_BAUDRATE        71 +   #define INCAASC_FDV_HIGH_BAUDRATE       453    +#endif /*INCAASC_USE_FDV*/ + + +#define INCAASC_TXFIFO_FL       1 +#define INCAASC_RXFIFO_FL       1 +#define INCAASC_TXFIFO_FULL     16 + +/* interrupt lines masks for the ASC device interrupts*/ +/* change these macroses if it's necessary */ +#define INCAASC_IRQ_LINE_ALL        0x000F0000  /* all IRQs */ + +#define INCAASC_IRQ_LINE_TIR            0x00010000      /* TIR - Tx */ +#define INCAASC_IRQ_LINE_RIR            0x00020000      /* RIR - Rx */ +#define INCAASC_IRQ_LINE_EIR            0x00040000      /* EIR - Err */ +#define INCAASC_IRQ_LINE_TBIR           0x00080000      /* TBIR - Tx Buf*/ + +/* interrupt controller access macros */     +#define ASC_INTERRUPTS_ENABLE(X)  \ +   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) |= X; +#define ASC_INTERRUPTS_DISABLE(X) \ +   *((volatile unsigned int*) INCA_IP_ICU_IM2_IER) &= ~X; +#define ASC_INTERRUPTS_CLEAR(X)   \ +   *((volatile unsigned int*) INCA_IP_ICU_IM2_ISR) = X; + +/* CLC register's bits and bitfields */ +#define ASCCLC_DISR        0x00000001 +#define ASCCLC_DISS        0x00000002 +#define ASCCLC_RMCMASK     0x0000FF00 +#define ASCCLC_RMCOFFSET   8 + +/* CON register's bits and bitfields */ +#define ASCCON_MODEMASK 0x0007 +    #define ASCCON_M_8SYNC          0x0 +    #define ASCCON_M_8ASYNC         0x1 +    #define ASCCON_M_8IRDAASYNC     0x2 +    #define ASCCON_M_7ASYNCPAR      0x3 +    #define ASCCON_M_9ASYNC         0x4 +    #define ASCCON_M_8WAKEUPASYNC   0x5 +    #define ASCCON_M_8ASYNCPAR      0x7 +#define ASCCON_STP      0x0008 +#define ASCCON_REN      0x0010 +#define ASCCON_PEN      0x0020 +#define ASCCON_FEN      0x0040 +#define ASCCON_OEN      0x0080 +#define ASCCON_PE       0x0100 +#define ASCCON_FE       0x0200 +#define ASCCON_OE       0x0400 +#define ASCCON_FDE      0x0800 +#define ASCCON_ODD      0x1000 +#define ASCCON_BRS      0x2000 +#define ASCCON_LB       0x4000 +#define ASCCON_R        0x8000 + +/* WHBCON register's bits and bitfields */ +#define ASCWHBCON_CLRREN    0x0010 +#define ASCWHBCON_SETREN    0x0020 +#define ASCWHBCON_CLRPE     0x0100 +#define ASCWHBCON_CLRFE     0x0200 +#define ASCWHBCON_CLROE     0x0400 +#define ASCWHBCON_SETPE     0x0800 +#define ASCWHBCON_SETFE     0x1000 +#define ASCWHBCON_SETOE     0x2000 + +/* ABCON register's bits and bitfields */ +#define ASCABCON_ABEN       0x0001 +#define ASCABCON_AUREN      0x0002 +#define ASCABCON_ABSTEN     0x0004 +#define ASCABCON_ABDETEN    0x0008 +#define ASCABCON_FCDETEN    0x0010 +#define ASCABCON_EMMASK     0x0300 +    #define ASCABCON_EMOFF          8 +        #define ASCABCON_EM_DISAB       0x0 +        #define ASCABCON_EM_DURAB       0x1 +        #define ASCABCON_EM_ALWAYS      0x2 +#define ASCABCON_TXINV      0x0400 +#define ASCABCON_RXINV      0x0800 + +/* FDV register mask, offset and bitfields*/ +#define ASCFDV_VALUE_MASK     0x000001FF + +/* WHBABCON register's bits and bitfields */ +#define ASCWHBABCON_SETABEN     0x0001 +#define ASCWHBABCON_CLRABEN     0x0002 + +/* ABSTAT register's bits and bitfields */ +#define ASCABSTAT_FCSDET    0x0001 +#define ASCABSTAT_FCCDET    0x0002 +#define ASCABSTAT_SCSDET    0x0004 +#define ASCABSTAT_SCCDET    0x0008 +#define ASCABSTAT_DETWAIT   0x0010 + +/* WHBABSTAT register's bits and bitfields */ +#define ASCWHBABSTAT_CLRFCSDET  0x0001 +#define ASCWHBABSTAT_SETFCSDET  0x0002 +#define ASCWHBABSTAT_CLRFCCDET  0x0004 +#define ASCWHBABSTAT_SETFCCDET  0x0008 +#define ASCWHBABSTAT_CLRSCSDET  0x0010 +#define ASCWHBABSTAT_SETSCSDET  0x0020 +#define ASCWHBABSTAT_SETSCCDET  0x0040 +#define ASCWHBABSTAT_CLRSCCDET  0x0080 +#define ASCWHBABSTAT_CLRDETWAIT 0x0100 +#define ASCWHBABSTAT_SETDETWAIT 0x0200 + +/* TXFCON register's bits and bitfields */ +#define ASCTXFCON_TXFEN         0x0001 +#define ASCTXFCON_TXFFLU        0x0002 +#define ASCTXFCON_TXTMEN        0x0004 +#define ASCTXFCON_TXFITLMASK    0x3F00 +#define ASCTXFCON_TXFITLOFF     8 + +/* RXFCON register's bits and bitfields */ +#define ASCRXFCON_RXFEN         0x0001 +#define ASCRXFCON_RXFFLU        0x0002 +#define ASCRXFCON_RXTMEN        0x0004 +#define ASCRXFCON_RXFITLMASK    0x3F00 +#define ASCRXFCON_RXFITLOFF     8 + +/* FSTAT register's bits and bitfields */ +#define ASCFSTAT_RXFFLMASK      0x003F +#define ASCFSTAT_TXFFLMASK      0x3F00 +#define ASCFSTAT_TXFFLOFF       8 + +#define INCAASC_PMU_ENABLE(BIT) *((volatile ulong*)0xBF102000) |= (0x1 << BIT); + +typedef  struct         /* incaAsc_t */ +{ +    volatile unsigned long  asc_clc;                            /*0x0000*/ +    volatile unsigned long  asc_pisel;                          /*0x0004*/ +    volatile unsigned long  asc_rsvd1[2];   /* for mapping */   /*0x0008*/ +    volatile unsigned long  asc_con;                            /*0x0010*/ +    volatile unsigned long  asc_bg;                             /*0x0014*/ +    volatile unsigned long  asc_fdv;                            /*0x0018*/ +    volatile unsigned long  asc_pmw;        /* not used */      /*0x001C*/ +    volatile unsigned long  asc_tbuf;                           /*0x0020*/ +    volatile unsigned long  asc_rbuf;                           /*0x0024*/ +    volatile unsigned long  asc_rsvd2[2];   /* for mapping */   /*0x0028*/ +    volatile unsigned long  asc_abcon;                          /*0x0030*/ +    volatile unsigned long  asc_abstat;     /* not used */      /*0x0034*/ +    volatile unsigned long  asc_rsvd3[2];   /* for mapping */   /*0x0038*/ +    volatile unsigned long  asc_rxfcon;                         /*0x0040*/ +    volatile unsigned long  asc_txfcon;                         /*0x0044*/ +    volatile unsigned long  asc_fstat;                          /*0x0048*/ +    volatile unsigned long  asc_rsvd4;      /* for mapping */   /*0x004C*/ +    volatile unsigned long  asc_whbcon;                         /*0x0050*/ +    volatile unsigned long  asc_whbabcon;                       /*0x0054*/ +    volatile unsigned long  asc_whbabstat;  /* not used */      /*0x0058*/ + +} incaAsc_t; + +#endif /* __INCincaAscSioh */ + diff --git a/cpu/mips/start.S b/cpu/mips/start.S new file mode 100644 index 000000000..bf1165561 --- /dev/null +++ b/cpu/mips/start.S @@ -0,0 +1,350 @@ +/* + *  Startup Code for MIPS32 CPU-core + * + *  Copyright (c) 2003	Wolfgang Denk <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 <config.h> +#include <version.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> + + +#define RVECENT(f,n) \ +   b f; nop +#define XVECENT(f,bev) \ +   b f     ;           \ +   li k0,bev + +	.set noreorder + +	.globl _start +	.text +_start: +	RVECENT(reset,0)	/* U-boot entry point */ +	RVECENT(reset,1)	/* software reboot */ +#ifdef CONFIG_INCA_IP +	.word 0x000020C4	/* EBU init code, fetched during booting */ +	.word 0x00000000        /* phase of the flash                    */ +#else +	RVECENT(romReserved,2) +#endif +	RVECENT(romReserved,3) +	RVECENT(romReserved,4) +	RVECENT(romReserved,5) +	RVECENT(romReserved,6) +	RVECENT(romReserved,7) +	RVECENT(romReserved,8) +	RVECENT(romReserved,9) +	RVECENT(romReserved,10) +	RVECENT(romReserved,11) +	RVECENT(romReserved,12) +	RVECENT(romReserved,13) +	RVECENT(romReserved,14) +	RVECENT(romReserved,15) +	RVECENT(romReserved,16) +	RVECENT(romReserved,17)  +	RVECENT(romReserved,18) +	RVECENT(romReserved,19) +	RVECENT(romReserved,20) +	RVECENT(romReserved,21) +	RVECENT(romReserved,22) +	RVECENT(romReserved,23) +	RVECENT(romReserved,24) +	RVECENT(romReserved,25) +	RVECENT(romReserved,26) +	RVECENT(romReserved,27) +	RVECENT(romReserved,28) +	RVECENT(romReserved,29) +	RVECENT(romReserved,30) +	RVECENT(romReserved,31) +	RVECENT(romReserved,32) +	RVECENT(romReserved,33) +	RVECENT(romReserved,34) +	RVECENT(romReserved,35) +	RVECENT(romReserved,36) +	RVECENT(romReserved,37) +	RVECENT(romReserved,38) +	RVECENT(romReserved,39) +	RVECENT(romReserved,40) +	RVECENT(romReserved,41) +	RVECENT(romReserved,42) +	RVECENT(romReserved,43) +	RVECENT(romReserved,44) +	RVECENT(romReserved,45) +	RVECENT(romReserved,46) +	RVECENT(romReserved,47) +	RVECENT(romReserved,48) +	RVECENT(romReserved,49) +	RVECENT(romReserved,50) +	RVECENT(romReserved,51) +	RVECENT(romReserved,52) +	RVECENT(romReserved,53) +	RVECENT(romReserved,54) +	RVECENT(romReserved,55) +	RVECENT(romReserved,56) +	RVECENT(romReserved,57) +	RVECENT(romReserved,58) +	RVECENT(romReserved,59) +	RVECENT(romReserved,60) +	RVECENT(romReserved,61) +	RVECENT(romReserved,62) +	RVECENT(romReserved,63)  +	XVECENT(romExcHandle,0x200)	/* bfc00200: R4000 tlbmiss vector */ +	RVECENT(romReserved,65) +	RVECENT(romReserved,66) +	RVECENT(romReserved,67) +	RVECENT(romReserved,68) +	RVECENT(romReserved,69) +	RVECENT(romReserved,70) +	RVECENT(romReserved,71) +	RVECENT(romReserved,72) +	RVECENT(romReserved,73) +	RVECENT(romReserved,74) +	RVECENT(romReserved,75) +	RVECENT(romReserved,76) +	RVECENT(romReserved,77) +	RVECENT(romReserved,78) +	RVECENT(romReserved,79)  +	XVECENT(romExcHandle,0x280)	/* bfc00280: R4000 xtlbmiss vector */ +	RVECENT(romReserved,81) +	RVECENT(romReserved,82) +	RVECENT(romReserved,83) +	RVECENT(romReserved,84) +	RVECENT(romReserved,85) +	RVECENT(romReserved,86) +	RVECENT(romReserved,87) +	RVECENT(romReserved,88) +	RVECENT(romReserved,89) +	RVECENT(romReserved,90) +	RVECENT(romReserved,91) +	RVECENT(romReserved,92) +	RVECENT(romReserved,93) +	RVECENT(romReserved,94) +	RVECENT(romReserved,95)  +	XVECENT(romExcHandle,0x300)	/* bfc00300: R4000 cache vector */ +	RVECENT(romReserved,97) +	RVECENT(romReserved,98) +	RVECENT(romReserved,99) +	RVECENT(romReserved,100) +	RVECENT(romReserved,101) +	RVECENT(romReserved,102) +	RVECENT(romReserved,103) +	RVECENT(romReserved,104) +	RVECENT(romReserved,105) +	RVECENT(romReserved,106) +	RVECENT(romReserved,107) +	RVECENT(romReserved,108) +	RVECENT(romReserved,109) +	RVECENT(romReserved,110) +	RVECENT(romReserved,111) +	XVECENT(romExcHandle,0x380)	/* bfc00380: R4000 general vector */ +	RVECENT(romReserved,113) +	RVECENT(romReserved,114) +	RVECENT(romReserved,115) +	RVECENT(romReserved,116) +	RVECENT(romReserved,116) +	RVECENT(romReserved,118) +	RVECENT(romReserved,119) +	RVECENT(romReserved,120) +	RVECENT(romReserved,121) +	RVECENT(romReserved,122) +	RVECENT(romReserved,123) +	RVECENT(romReserved,124) +	RVECENT(romReserved,125) +	RVECENT(romReserved,126) +	RVECENT(romReserved,127) +    +	/* We hope there are no more reserved vectors! +	 * 128 * 8 == 1024 == 0x400 +	 * so this is address R_VEC+0x400 == 0xbfc00400 +	 */ +	.align 4 +reset: + +	/* Clear watch registers. +	 */ +	mtc0	zero, CP0_WATCHLO +	mtc0	zero, CP0_WATCHHI + +	/* STATUS register */ +	mfc0	k0, CP0_STATUS +	li	k1, ~ST0_IE +	and	k0, k1 +	mtc0	k0, CP0_STATUS + +	/* CAUSE register */ +	mtc0	zero, CP0_CAUSE + +	/* Init Timer */ +	mtc0	zero, CP0_COUNT +	mtc0	zero, CP0_COMPARE + +	/* CONFIG0 register */ +	li	t0, CONF_CM_UNCACHED +	mtc0	t0, CP0_CONFIG + +#ifdef CONFIG_INCA_IP +	/* Disable INCA-IP Watchdog. +	 */ +	bal	disable_incaip_wdt +	nop +#endif + +	/* Initialize any external memory.  +	 */ +	bal	memsetup +	nop + +	/* Initialize caches... +	 */ +	bal	mips_cache_reset +	nop + +	/* ... and enable them. +	 */ +	li	t0, CONF_CM_CACHABLE_NONCOHERENT +	mtc0	t0, CP0_CONFIG + + +	/* Set up temporary stack. +	 */ +	li	a0, CFG_INIT_SP_OFFSET +	bal	mips_cache_lock +	nop + +	li	t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET +	la	sp, 0(t0) + +	/* Initialize GOT pointer. +	 */ +	bal	1f +	nop +	.word	_GLOBAL_OFFSET_TABLE_ - 1f + 4 +1: +	move	gp, ra +	lw	t1, 0(ra) +	add	gp, t1 +	la	t9, board_init_f +	j	t9 +	nop + + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * a0 = addr_sp + * a1 = gd + * a2 = destination address + */ +	.globl	relocate_code +	.ent	relocate_code +relocate_code: +	move	sp, a0		/* Set new stack pointer		*/ + +	/* +	 * Fix GOT pointer: +	 * +	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address +	 */ +	move	t6, gp +	sub	gp, CFG_MONITOR_BASE +	add	gp, a2			/* gp now adjusted		*/ +	sub	t6, gp, t6		/* t6 <-- relocation offset	*/ +	 +	li	t0, CFG_MONITOR_BASE +	add	t2, t0, CFG_MONITOR_LEN +	move	t1, a2 + +	/* +	 * t0 = source address +	 * t1 = target address +	 * t2 = source end address +	 */ +1: +	lw	t3, 0(t0) +	sw	t3, 0(t1) +	addu	t0, 4 +	ble	t0, t2, 1b +	addu	t1, 4			/* delay slot			*/ + +	/* If caches were enabled, we would have to flush them here. +	 */ + +	/* Jump to where we've relocated ourselves. +	 */ +	addi	t0, a2, in_ram - _start +	j	t0 +	nop + +	.word	uboot_end_data +	.word	uboot_end +	.word	num_got_entries + +in_ram: +	/* Now we want to update GOT. +	 */ +	lw	t3, -4(t0)	/* t3 <-- num_got_entries	*/ +	addi	t4, gp, 8	/* Skipping first two entries.	*/ +	li	t2, 2 +1: +	lw	t1, 0(t4) +	beqz	t1, 2f +	add	t1, t6 +	sw	t1, 0(t4) +2: +	addi	t2, 1 +	blt	t2, t3, 1b +	addi	t4, 4		/* delay slot			*/ + +	/* Clear BSS. +	 */ +	lw	t1, -12(t0)	/* t1 <-- uboot_end_data	*/ +	lw	t2, -8(t0)	/* t2 <-- uboot_end		*/ +	add	t1, t6		/* adjust pointers		*/ +	add	t2, t6 + +	sub	t1, 4 +1:	addi	t1, 4 +	bltl	t1, t2, 1b +	sw	zero, 0(t1)	/* delay slot			*/ +	 +	move	a0, a1 +	la	t9, board_init_r +	j	t9 +	move	a1, a2		/* delay slot			*/ + +	.end	relocate_code +	 + + +	/* Exception handlers. +	 */ +romReserved: +	b romReserved + +romExcHandle: +	b romExcHandle + |