diff options
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/coldfire/cpu.c | 87 | ||||
-rw-r--r-- | cpu/coldfire/fec.c | 296 | ||||
-rw-r--r-- | cpu/coldfire/fec.h | 28 | ||||
-rw-r--r-- | cpu/coldfire/interrupts.c | 127 | ||||
-rw-r--r-- | cpu/coldfire/serial.c | 168 | ||||
-rw-r--r-- | cpu/coldfire/start.S | 165 | ||||
-rw-r--r-- | cpu/mcf52x2/Makefile (renamed from cpu/coldfire/Makefile) | 6 | ||||
-rw-r--r-- | cpu/mcf52x2/config.mk (renamed from cpu/coldfire/config.mk) | 9 | ||||
-rw-r--r-- | cpu/mcf52x2/cpu.c | 123 | ||||
-rw-r--r-- | cpu/mcf52x2/cpu_init.c | 144 | ||||
-rw-r--r-- | cpu/mcf52x2/fec.c | 558 | ||||
-rw-r--r-- | cpu/mcf52x2/interrupts.c | 174 | ||||
-rw-r--r-- | cpu/mcf52x2/serial.c | 159 | ||||
-rw-r--r-- | cpu/mcf52x2/speed.c (renamed from cpu/coldfire/speed.c) | 18 | ||||
-rw-r--r-- | cpu/mcf52x2/start.S | 316 |
15 files changed, 1492 insertions, 886 deletions
diff --git a/cpu/coldfire/cpu.c b/cpu/coldfire/cpu.c deleted file mode 100644 index 5ce0639..0000000 --- a/cpu/coldfire/cpu.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * (C) Copyright 2000-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 <watchdog.h> -#include <command.h> -#ifdef CONFIG_M5272 -#include <asm/m5272.h> -#endif -#ifdef CONFIG_M5282 -#include <asm/m5282.h> -#endif -#include <asm/cache.h> - -int do_reset (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) -{ - return 0; -} - -unsigned long get_tbclk (void) -{ - return CFG_HZ; -} - -int checkcpu (void) -{ -#ifdef CONFIG_M5272 - puts ("MOTOROLA Coldfire MCF5272\n"); -#endif -#ifdef CONFIG_M5282 - puts ("MOTOROLA Coldfire MCF5282\n"); -#endif - return 0; -} - -void do_exception (void) -{ - printf ("\n\n*** Unexpected exception ... Reset Board! ***\n"); - for (;;); -} - -void do_buserror (void) -{ - printf ("\n\n*** Bus error ... Reset Board! ***\n"); - for (;;); -} - -void do_addresserror (void) -{ - printf ("\n\n*** Address error ... Reset Board! ***\n"); - for (;;); -} - -void trap_init (ulong value) -{ - extern void buserror_handler (void); - extern void addresserror_handler (void); - extern void exception_handler (void); - unsigned long *vec = 0; - int i; - - vec[2] = buserror_handler; - vec[3] = addresserror_handler; - for (i = 4; i < 256; i++) { - vec[i] = exception_handler; - } -} diff --git a/cpu/coldfire/fec.c b/cpu/coldfire/fec.c deleted file mode 100644 index 5062741..0000000 --- a/cpu/coldfire/fec.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * (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 <common.h> -#include <commproc.h> -#include <net.h> -#include <command.h> - - -/************************************************************** - * - * FEC Ethernet Initialization Routine - * - *************************************************************/ - -#define FEC_ECNTRL_ETHER_EN 0x00000002 -#define FEC_ECNTRL_RESET 0x00000001 - -#define FEC_RCNTRL_BC_REJ 0x00000010 -#define FEC_RCNTRL_PROM 0x00000008 -#define FEC_RCNTRL_MII_MODE 0x00000004 -#define FEC_RCNTRL_DRT 0x00000002 -#define FEC_RCNTRL_LOOP 0x00000001 - -#define FEC_TCNTRL_FDEN 0x00000004 -#define FEC_TCNTRL_HBC 0x00000002 -#define FEC_TCNTRL_GTS 0x00000001 - -#define FEC_RESET_DELAY 50000 - - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 -#define TX_BUF_CNT 2 -#define TOUT_LOOP 100 - -#define PKT_MAXBUF_SIZE 1518 -#define PKT_MINBUF_SIZE 64 -#define PKT_MAXBLR_SIZE 1520 - - -#ifdef CONFIG_M5272 -#define FEC_ADDR 0x10000840 -#endif -#ifdef CONFIG_M5282 -#define FEC_ADDR 0x40001000 -#endif - -#undef ET_DEBUG - -#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET) - - -static char txbuf[DBUF_LENGTH]; - -static uint rxIdx; /* index of the current RX buffer */ -static uint txIdx; /* index of the current TX buffer */ - -/* - * FEC Ethernet Tx and Rx buffer descriptors allocated at the - * immr->udata_bd address on Dual-Port RAM - * Provide for Double Buffering - */ - -typedef volatile struct CommonBufferDescriptor { - cbd_t rxbd[PKTBUFSRX]; /* Rx BD */ - cbd_t txbd[TX_BUF_CNT]; /* Tx BD */ -} RTXBD; - -static RTXBD *rtx = 0x380000; - - -int eth_send (volatile void *packet, int length) -{ - int j, rc; - volatile fec_t *fecp = FEC_ADDR; - - /* section 16.9.23.3 - * Wait for ready - */ - j = 0; - while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) - && (j < TOUT_LOOP)) { - udelay (1); - j++; - } - if (j >= TOUT_LOOP) { - printf ("TX not ready\n"); - } - - rtx->txbd[txIdx].cbd_bufaddr = (uint) packet; - rtx->txbd[txIdx].cbd_datlen = length; - rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST; - - /* Activate transmit Buffer Descriptor polling */ - fecp->fec_x_des_active = 0x01000000; /* Descriptor polling active */ - - j = 0; - while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) - && (j < TOUT_LOOP)) { - udelay (1); - j++; - } - if (j >= TOUT_LOOP) { - printf ("TX timeout\n"); - } -#ifdef ET_DEBUG - printf ("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n", - __FILE__, __LINE__, __FUNCTION__, j, rtx->txbd[txIdx].cbd_sc, - (rtx->txbd[txIdx].cbd_sc & 0x003C) >> 2); -#endif - /* return only status bits */ ; - rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS); - - txIdx = (txIdx + 1) % TX_BUF_CNT; - - return rc; -} - -int eth_rx (void) -{ - int length; - volatile fec_t *fecp = FEC_ADDR; - - for (;;) { - /* section 16.9.23.2 */ - if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { - length = -1; - break; /* nothing received - leave for() loop */ - } - - length = rtx->rxbd[rxIdx].cbd_datlen; - - if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) { -#ifdef ET_DEBUG - printf ("%s[%d] err: %x\n", - __FUNCTION__, __LINE__, - rtx->rxbd[rxIdx].cbd_sc); -#endif - } else { - /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[rxIdx], length - 4); - } - - /* Give the buffer back to the FEC. */ - rtx->rxbd[rxIdx].cbd_datlen = 0; - - /* wrap around buffer index when necessary */ - if ((rxIdx + 1) >= PKTBUFSRX) { - rtx->rxbd[PKTBUFSRX - 1].cbd_sc = - (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); - rxIdx = 0; - } else { - rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; - rxIdx++; - } - - /* Try to fill Buffer Descriptors */ - fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */ - } - - return length; -} - - -int eth_init (bd_t * bd) -{ - - int i; - volatile fec_t *fecp = FEC_ADDR; - - /* Whack a reset. - * A delay is required between a reset of the FEC block and - * initialization of other FEC registers because the reset takes - * some time to complete. If you don't delay, subsequent writes - * to FEC registers might get killed by the reset routine which is - * still in progress. - */ - - fecp->fec_ecntrl = FEC_ECNTRL_RESET; - for (i = 0; - (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY); - ++i) { - udelay (1); - } - if (i == FEC_RESET_DELAY) { - printf ("FEC_RESET_DELAY timeout\n"); - return 0; - } - - /* We use strictly polling mode only - */ - fecp->fec_imask = 0; - - /* Clear any pending interrupt */ - fecp->fec_ievent = 0xffffffff; - - /* Set station address */ -#define ea bd->bi_enetaddr - fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | - (ea[2] << 8) | (ea[3]); - fecp->fec_addr_high = (ea[4] << 24) | (ea[5] << 16); -#undef ea - - /* Clear multicast address hash table - */ - fecp->fec_hash_table_high = 0; - fecp->fec_hash_table_low = 0; - - /* Set maximum receive buffer size. - */ - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; - - /* - * Setup Buffers and Buffer Desriptors - */ - rxIdx = 0; - txIdx = 0; - - /* - * Setup Receiver Buffer Descriptors (13.14.24.18) - * Settings: - * Empty, Wrap - */ - for (i = 0; i < PKTBUFSRX; i++) { - rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; - } - rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* - * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) - * Settings: - * Last, Tx CRC - */ - for (i = 0; i < TX_BUF_CNT; i++) { - rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC; - rtx->txbd[i].cbd_datlen = 0; /* Reset */ - rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]); - } - rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; - - /* Set receive and transmit descriptor base - */ - fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]); - fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]); - - /* Enable MII mode - */ - - /* Half duplex mode */ - fecp->fec_r_cntrl = (PKT_MAXBUF_SIZE << 16) | FEC_RCNTRL_MII_MODE; - fecp->fec_r_cntrl = (PKT_MAXBUF_SIZE << 16) | FEC_RCNTRL_MII_MODE; - fecp->fec_x_cntrl = 0; - - fecp->fec_mii_speed = 0; - - /* Now enable the transmit and receive processing - */ - fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN; - - /* And last, try to fill Rx Buffer Descriptors */ - fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */ - - return 1; -} - - -void eth_halt (void) -{ - volatile fec_t *fecp = FEC_ADDR; - - fecp->fec_ecntrl = 0; -} -#endif diff --git a/cpu/coldfire/fec.h b/cpu/coldfire/fec.h deleted file mode 100644 index a49417c..0000000 --- a/cpu/coldfire/fec.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * (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 - */ - -#ifndef _FEC_H_ -#define _FEC_H_ - - -#endif /* _FEC_H_ */ diff --git a/cpu/coldfire/interrupts.c b/cpu/coldfire/interrupts.c deleted file mode 100644 index 3861ff1..0000000 --- a/cpu/coldfire/interrupts.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * (C) Copyright 2000-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 <watchdog.h> -#ifdef CONFIG_M5272 -#include <asm/m5272.h> -#endif -#ifdef CONFIG_M5282 -#include <asm/m5282.h> -#endif -#include <asm/mcftimer.h> -#include <asm/processor.h> -#include <commproc.h> - -static ulong timestamp; -static unsigned short lastinc; - -void coldfire_timer_init (void) -{ - volatile unsigned short *timerp; - - timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE4); - timestamp = 0; - -#ifdef CONFIG_M5272 - /* Set up TIMER 4 as poll clock */ - timerp[MCFTIMER_TMR] = MCFTIMER_TMR_DISABLE; - timerp[MCFTIMER_TRR] = lastinc = 0; - timerp[MCFTIMER_TMR] = (65 << 8) | MCFTIMER_TMR_CLK1 | - MCFTIMER_TMR_FREERUN | MCFTIMER_TMR_ENABLE; -#endif - -#ifdef CONFIG_M5282 - /* Set up TIMER 4 as poll clock */ - timerp[MCFTIMER_PCSR] = MCFTIMER_PCSR_OVW; - timerp[MCFTIMER_PMR] = lastinc = 0; - timerp[MCFTIMER_PCSR] = - (5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW; -#endif -} - - -void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) -{ -} -void irq_free_handler (int vec) -{ -} - -int interrupt_init (void) -{ - coldfire_timer_init (); - return 0; -} - -void enable_interrupts () -{ -} -int disable_interrupts () -{ - return 0; -} - -void set_timer (ulong t) -{ - volatile unsigned short *timerp; - - timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE4); - timestamp = 0; - -#ifdef CONFIG_M5272 - timerp[MCFTIMER_TRR] = lastinc = 0; -#endif - -#ifdef CONFIG_M5282 - timerp[MCFTIMER_PMR] = lastinc = 0; -#endif -} - -ulong get_timer (ulong base) -{ - unsigned short now, diff; - volatile unsigned short *timerp; - - timerp = (volatile unsigned short *) (MCF_MBAR + MCFTIMER_BASE4); - -#ifdef CONFIG_M5272 - now = timerp[MCFTIMER_TCN]; - diff = (now - lastinc); -#endif - -#ifdef CONFIG_M5282 - now = timerp[MCFTIMER_PCNTR]; - diff = -(now - lastinc); -#endif - - timestamp += diff; - lastinc = now; - return timestamp - base; -} - -void wait_ticks (unsigned long ticks) -{ - set_timer (0); - while (get_timer (0) < ticks); -} diff --git a/cpu/coldfire/serial.c b/cpu/coldfire/serial.c deleted file mode 100644 index a140fe3..0000000 --- a/cpu/coldfire/serial.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * (C) Copyright 2000-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 <commproc.h> -#include <command.h> - -#ifdef CONFIG_M5272 -#include <asm/m5272.h> -#endif -#ifdef CONFIG_M5282 -#include <asm/m5282.h> -#endif -#include <asm/mcfuart.h> - -#define DoubleClock(a) ((double)(MCF_CLK) / 32.0 / (double)(a)) - -void rs_serial_setbaudrate (int port, int baudrate) -{ -#ifdef CONFIG_M5272 - volatile unsigned char *uartp; - double clock, fraction; - - if (port == 0) - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE1); - else - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE2); - - clock = DoubleClock (baudrate); /* Set baud above */ - - fraction = ((clock - (int) clock) * 16.0) + 0.5; - - uartp[MCFUART_UBG1] = (((int) clock >> 8) & 0xff); /* set msb baud */ - uartp[MCFUART_UBG2] = ((int) clock & 0xff); /* set lsb baud */ - uartp[MCFUART_UFPD] = ((int) fraction & 0xf); /* set baud fraction adjust */ -#endif -} - -void rs_serial_init (int port, int baudrate) -{ - volatile unsigned char *uartp; - double clock, fraction; - - /* - * Reset UART, get it into known state... - */ - if (port == 0) - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE1); - else - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE2); - - uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ - uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ - uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */ - uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; /* reset Error pointer */ - - /* - * Set port for CONSOLE_BAUD_RATE, 8 data bits, 1 stop bit, no parity. - */ - uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; - uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; - - rs_serial_setbaudrate (port, baudrate); - - uartp[MCFUART_UCSR] = - MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; - uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; - - return; -} - - -/****************************************************************************/ - -/* - * Output a single character, using UART polled mode. - * This is used for console output. - */ - -void rs_put_char (char ch) -{ - volatile unsigned char *uartp; - int i; - - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE1); - - for (i = 0; (i < 0x10000); i++) { - if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) - break; - } - uartp[MCFUART_UTB] = ch; - return; -} - -int rs_is_char (void) -{ - volatile unsigned char *uartp; - - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE1); - return ((uartp[MCFUART_USR] & MCFUART_USR_RXREADY) ? 1 : 0); -} - -int rs_get_char (void) -{ - volatile unsigned char *uartp; - - uartp = (volatile unsigned char *) (MCF_MBAR + MCFUART_BASE1); - return (uartp[MCFUART_URB]); -} - -void serial_setbrg (void) -{ - DECLARE_GLOBAL_DATA_PTR; - rs_serial_setbaudrate (0, gd->bd->bi_baudrate); -} - -int serial_init (void) -{ - DECLARE_GLOBAL_DATA_PTR; - rs_serial_init (0, gd->bd->bi_baudrate); - return 0; -} - - -void serial_putc (const char c) -{ - if (c == '\n') - serial_putc ('\r'); - rs_put_char (c); -} - -void serial_puts (const char *s) -{ - while (*s) { - serial_putc (*s++); - } -} - -int serial_getc (void) -{ - while (!rs_is_char ()); - return rs_get_char (); -} - -int serial_tstc () -{ - return rs_is_char (); -} diff --git a/cpu/coldfire/start.S b/cpu/coldfire/start.S deleted file mode 100644 index 4454223..0000000 --- a/cpu/coldfire/start.S +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> - * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> - * Copyright (C) 2000-2003 Wolfgang Denk <wd@denx.de> - * Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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 "version.h" - -#ifndef CONFIG_IDENT_STRING -#define CONFIG_IDENT_STRING "" -#endif - -#define MCF_MBAR 0x10000000 -#define MEM_BUILTIN_ADDR 0x20000000 -#define MEM_BUILTIN_SIZE 0x1000 -#define DRAM_ADDR 0x0 -#define DRAM_SIZE 0x400000 - - .text - - .globl _start -_start: - nop - nop - move.w #0x2700,%sr - - move.l #0, %d0 - movec %d0, %VBR - -#ifdef CONFIG_M5272 - move.l #(MCF_MBAR+1), %d0 - move.c %d0, %MBAR - - move.l #(MEM_BUILTIN_ADDR+1), %d0 - movec %d0, %RAMBAR0 - - move.l #0x01000000, %d0 /* Invalidate cache cmd */ - movec %d0, %CACR /* Invalidate cache */ - move.l #0x0000c000, %d0 /* Setup cache mask */ - movec %d0, %ACR0 /* Enable cache */ - move.l #0xff00c000, %d0 /* Setup cache mask */ - movec %d0, %ACR1 /* Enable cache */ - move.l #0x80000100, %d0 /* Setup cache mask */ - movec %d0, %CACR /* Enable cache */ -#endif - - move.l #_sbss,%a0 - move.l #_ebss,%d0 -1: - clr.l (%a0)+ - cmp.l %a0,%d0 - bne.s 1b - -/* move.l #MEM_BUILTIN_ADDR+MEM_BUILTIN_SIZE, %sp */ - move.l #DRAM_ADDR+DRAM_SIZE, %sp - clr.l %sp@- - - jsr board_init_f - - .globl exception_handler -exception_handler: - move.w #0x2700,%sr - lea %sp@(-60),%sp - movem.l %d0-%d7/%a0-%a6,%sp@ - jsr do_exception - movem.l %sp@,%d0-%d7/%a0-%a6 - lea %sp@(60),%sp - rte - - .globl buserror_handler -buserror_handler: - move.w #0x2700,%sr - lea %sp@(-60),%sp - movem.l %d0-%d7/%a0-%a6,%sp@ - jsr do_buserror - movem.l %sp@,%d0-%d7/%a0-%a6 - lea %sp@(60),%sp - rte - - .globl addresserror_handler -addresserror_handler: - move.w #0x2700,%sr - lea %sp@(-60),%sp - movem.l %d0-%d7/%a0-%a6,%sp@ - jsr do_buserror - movem.l %sp@,%d0-%d7/%a0-%a6 - lea %sp@(60),%sp - rte - - .globl get_endaddr -get_endaddr: - movel #_end,%d0 - rts - -#ifdef CONFIG_M5272 - .globl icache_enable -icache_enable: - move.l #0x01000000, %d0 /* Invalidate cache cmd */ - movec %d0, %CACR /* Invalidate cache */ - move.l #0x0000c000, %d0 /* Setup cache mask */ - movec %d0, %ACR0 /* Enable cache */ - move.l #0xff00c000, %d0 /* Setup cache mask */ - movec %d0, %ACR1 /* Enable cache */ - move.l #0x80000100, %d0 /* Setup cache mask */ - movec %d0, %CACR /* Enable cache */ - moveq #1, %d0 - move.l %d0, icache_state - rts - - .globl icache_disable -icache_disable: - move.l #0x00000100, %d0 /* Setup cache mask */ - movec %d0, %CACR /* Enable cache */ - clr.l %d0 /* Setup cache mask */ - movec %d0, %ACR0 /* Enable cache */ - movec %d0, %ACR1 /* Enable cache */ - moveq #0, %d0 - move.l %d0, icache_state - rts -#endif - -#ifdef CONFIG_M5282 - .globl icache_enable -icache_enable: - rts - - .globl icache_disable -icache_disable: - rts -#endif - - .globl icache_status -icache_status: - move.l icache_state, %d0 - rts - - .data -icache_state: - .long 1 - - .globl version_string -version_string: - .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" - .ascii CONFIG_IDENT_STRING, "\0" diff --git a/cpu/coldfire/Makefile b/cpu/mcf52x2/Makefile index 3976f56..879deb7 100644 --- a/cpu/coldfire/Makefile +++ b/cpu/mcf52x2/Makefile @@ -1,5 +1,5 @@ # -# (C) Copyright 2000-2003 +# (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # See file CREDITS for list of people who contributed to this @@ -28,12 +28,12 @@ include $(TOPDIR)/config.mk LIB = lib$(CPU).a START = -OBJS = kgdb.o serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o +OBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o all: .depend $(START) $(LIB) $(LIB): $(OBJS) - $(AR) crv $@ $(OBJS) kgdb.o + $(AR) crv $@ $(OBJS) ######################################################################### diff --git a/cpu/coldfire/config.mk b/cpu/mcf52x2/config.mk index 72b33ce..650db85 100644 --- a/cpu/coldfire/config.mk +++ b/cpu/mcf52x2/config.mk @@ -1,5 +1,7 @@ # -# (C) Copyright 2000-2003 +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (C) Copyright 2000-2004 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # See file CREDITS for list of people who contributed to this @@ -21,6 +23,5 @@ # MA 02111-1307 USA # -PLATFORM_RELFLAGS += - -PLATFORM_CPPFLAGS += -m5200 +PLATFORM_RELFLAGS += -ffixed-d7 -msep-data +PLATFORM_CPPFLAGS += -m5307 diff --git a/cpu/mcf52x2/cpu.c b/cpu/mcf52x2/cpu.c new file mode 100644 index 0000000..b012222 --- /dev/null +++ b/cpu/mcf52x2/cpu.c @@ -0,0 +1,123 @@ +/* + * (C) Copyright 2003 + * Josef Baumgartner <josef.baumgartner@telex.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 <watchdog.h> +#include <command.h> + +#ifdef CONFIG_M5272 +#include <asm/immap_5272.h> +#include <asm/m5272.h> +#endif + +#ifdef CONFIG_M5282 + +#endif + + +#ifdef CONFIG_M5272 +int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + volatile wdog_t * wdp = (wdog_t *)(CFG_MBAR + MCFSIM_WRRR); + + wdp->wdog_wrrr = 0; + udelay (1000); + + /* enable watchdog, set timeout to 0 and wait */ + wdp->wdog_wrrr = 1; + while (1); + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) { + ulong *dirp = (ulong *)(CFG_MBAR + MCFSIM_DIR); + uchar msk; + char *suf; + + puts ("CPU: "); + msk = (*dirp > 28) & 0xf; + switch (msk) { + case 0x2: suf = "1K75N"; break; + case 0x4: suf = "3K75N"; break; + default: + suf = NULL; + printf ("MOTOROLA MCF5272 (Mask:%01x)\n", msk); + break; + } + + if (suf) + printf ("MOTOROLA MCF5272 %s\n", suf); + return 0; +}; + + +#if defined(CONFIG_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset (void) +{ + volatile immap_t * regp = (volatile immap_t *)CFG_MBAR; + regp->wdog_reg.wdog_wcr = 0; +} + +int watchdog_disable (void) +{ + volatile immap_t *regp = (volatile immap_t *)CFG_MBAR; + + regp->wdog_reg.wdog_wcr = 0; /* reset watchdog counter */ + regp->wdog_reg.wdog_wirr = 0; /* disable watchdog interrupt */ + regp->wdog_reg.wdog_wrrr = 0; /* disable watchdog timer */ + + puts ("WATCHDOG:disabled\n"); + return (0); +} + +int watchdog_init (void) +{ + volatile immap_t *regp = (volatile immap_t *)CFG_MBAR; + + regp->wdog_reg.wdog_wirr = 0; /* disable watchdog interrupt */ + + /* set timeout and enable watchdog */ + regp->wdog_reg.wdog_wrrr = ((CONFIG_WATCHDOG_TIMEOUT * CFG_HZ) / (32768 * 1000)) - 1; + regp->wdog_reg.wdog_wcr = 0; /* reset watchdog counter */ + + puts ("WATCHDOG:enabled\n"); + return (0); +} +#endif /* #ifdef CONFIG_WATCHDOG */ + +#endif /* #ifdef CONFIG_M5272 */ + + +#ifdef CONFIG_M5282 +int checkcpu (void) +{ + puts ("CPU: MOTOROLA Coldfire MCF5282\n"); + return 0; +} + +int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + return 0; +}; +#endif diff --git a/cpu/mcf52x2/cpu_init.c b/cpu/mcf52x2/cpu_init.c new file mode 100644 index 0000000..8aff8f1 --- /dev/null +++ b/cpu/mcf52x2/cpu_init.c @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2003 + * Josef Baumgartner <josef.baumgartner@telex.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 <watchdog.h> + +#ifdef CONFIG_M5272 +#include <asm/m5272.h> +#include <asm/immap_5272.h> +#endif + +#ifdef CONFIG_M5282 +#include <asm/m5282.h> +#include <asm/immap_5282.h> +#endif + +#ifdef CONFIG_M5272 +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f (void) +{ + /* if we come from RAM we assume the CPU is + * already initialized. + */ +#ifndef CONFIG_MONITOR_IS_IN_RAM + volatile immap_t *regp = (immap_t *)CFG_MBAR; + + volatile unsigned char *mbar; + mbar = (volatile unsigned char *) CFG_MBAR; + + regp->sysctrl_reg.sc_scr = CFG_SCR; + regp->sysctrl_reg.sc_spr = CFG_SPR; + + /* Setup Ports: */ + regp->gpio_reg.gpio_pacnt = CFG_PACNT; + regp->gpio_reg.gpio_paddr = CFG_PADDR; + regp->gpio_reg.gpio_padat = CFG_PADAT; + regp->gpio_reg.gpio_pbcnt = CFG_PBCNT; + regp->gpio_reg.gpio_pbddr = CFG_PBDDR; + regp->gpio_reg.gpio_pbdat = CFG_PBDAT; + regp->gpio_reg.gpio_pdcnt = CFG_PDCNT; + + /* Memory Controller: */ + regp->csctrl_reg.cs_br0 = CFG_BR0_PRELIM; + regp->csctrl_reg.cs_or0 = CFG_OR0_PRELIM; + +#if (defined(CFG_OR1_PRELIM) && defined(CFG_BR1_PRELIM)) + regp->csctrl_reg.cs_br1 = CFG_BR1_PRELIM; + regp->csctrl_reg.cs_or1 = CFG_OR1_PRELIM; +#endif + +#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM) + regp->csctrl_reg.cs_br2 = CFG_BR2_PRELIM; + regp->csctrl_reg.cs_or2 = CFG_OR2_PRELIM; +#endif + +#if defined(CFG_OR3_PRELIM) && defined(CFG_BR3_PRELIM) + regp->csctrl_reg.cs_br3 = CFG_BR3_PRELIM; + regp->csctrl_reg.cs_or3 = CFG_OR3_PRELIM; +#endif + +#if defined(CFG_OR4_PRELIM) && defined(CFG_BR4_PRELIM) + regp->csctrl_reg.cs_br4 = CFG_BR4_PRELIM; + regp->csctrl_reg.cs_or4 = CFG_OR4_PRELIM; +#endif + +#if defined(CFG_OR5_PRELIM) && defined(CFG_BR5_PRELIM) + regp->csctrl_reg.cs_br5 = CFG_BR5_PRELIM; + regp->csctrl_reg.cs_or5 = CFG_OR5_PRELIM; +#endif + +#if defined(CFG_OR6_PRELIM) && defined(CFG_BR6_PRELIM) + regp->csctrl_reg.cs_br6 = CFG_BR6_PRELIM; + regp->csctrl_reg.cs_or6 = CFG_OR6_PRELIM; +#endif + +#if defined(CFG_OR7_PRELIM) && defined(CFG_BR7_PRELIM) + regp->csctrl_reg.cs_br7 = CFG_BR7_PRELIM; + regp->csctrl_reg.cs_or7 = CFG_OR7_PRELIM; +#endif + +#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */ + + /* enable instruction cache now */ + icache_enable(); + +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r (void) +{ + return (0); +} +#endif /* #ifdef CONFIG_M5272 */ + + +#ifdef CONFIG_M5282 +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f (void) +{ + +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r (void) +{ + return (0); +} +#endif diff --git a/cpu/mcf52x2/fec.c b/cpu/mcf52x2/fec.c new file mode 100644 index 0000000..623a01d --- /dev/null +++ b/cpu/mcf52x2/fec.c @@ -0,0 +1,558 @@ +/* + * (C) Copyright 2000-2004 + * 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 <malloc.h> +#include <asm/fec.h> + +#ifdef CONFIG_M5272 +#include <asm/m5272.h> +#include <asm/immap_5272.h> +#endif + +#ifdef CONFIG_M5282 +#include <asm/m5282.h> +#include <asm/immap_5282.h> +#endif + +#include <net.h> +#include <command.h> + +#ifdef CONFIG_M5272 +#define FEC_ADDR (CFG_MBAR + 0x840) +#endif +#ifdef CONFIG_M5282 +#define FEC_ADDR (CFG_MBAR + 0x1000) +#endif + +#undef ET_DEBUG +#undef MII_DEBUG + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET) + +#ifdef CFG_DISCOVER_PHY +#include <miiphy.h> +static void mii_discover_phy (void); +#endif + +/* Ethernet Transmit and Receive Buffers */ +#define DBUF_LENGTH 1520 + +#define TX_BUF_CNT 2 + +#define TOUT_LOOP 100 + +#define PKT_MAXBUF_SIZE 1518 +#define PKT_MINBUF_SIZE 64 +#define PKT_MAXBLR_SIZE 1520 + + +static char txbuf[DBUF_LENGTH]; + +static uint rxIdx; /* index of the current RX buffer */ +static uint txIdx; /* index of the current TX buffer */ + +/* + * FEC Ethernet Tx and Rx buffer descriptors allocated at the + * immr->udata_bd address on Dual-Port RAM + * Provide for Double Buffering + */ + +typedef volatile struct CommonBufferDescriptor { + cbd_t rxbd[PKTBUFSRX]; /* Rx BD */ + cbd_t txbd[TX_BUF_CNT]; /* Tx BD */ +} RTXBD; + +static RTXBD *rtx = NULL; + +int eth_send (volatile void *packet, int length) +{ + int j, rc; + volatile fec_t *fecp = (fec_t *) (FEC_ADDR); + + /* section 16.9.23.3 + * Wait for ready + */ + j = 0; + while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) + && (j < TOUT_LOOP)) { + udelay (1); + j++; + } + if (j >= TOUT_LOOP) { + printf ("TX not ready\n"); + } + + rtx->txbd[txIdx].cbd_bufaddr = (uint) packet; + rtx->txbd[txIdx].cbd_datlen = length; + rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST; + + /* Activate transmit Buffer Descriptor polling */ + fecp->fec_x_des_active = 0x01000000; /* Descriptor polling active */ + + j = 0; + while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) + && (j < TOUT_LOOP)) { + udelay (1); + j++; + } + if (j >= TOUT_LOOP) { + printf ("TX timeout\n"); + } +#ifdef ET_DEBUG + printf ("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n", + __FILE__, __LINE__, __FUNCTION__, j, rtx->txbd[txIdx].cbd_sc, + (rtx->txbd[txIdx].cbd_sc & 0x003C) >> 2); +#endif + + /* return only status bits */ ; + rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS); + + txIdx = (txIdx + 1) % TX_BUF_CNT; + + return rc; +} + +int eth_rx (void) +{ + int length; + volatile fec_t *fecp = (fec_t *) FEC_ADDR; + + for (;;) { + /* section 16.9.23.2 */ + if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { + length = -1; + break; /* nothing received - leave for() loop */ + } + + length = rtx->rxbd[rxIdx].cbd_datlen; + + if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) { +#ifdef ET_DEBUG + printf ("%s[%d] err: %x\n", + __FUNCTION__, __LINE__, + rtx->rxbd[rxIdx].cbd_sc); +#endif + } else { + /* Pass the packet up to the protocol layers. */ + NetReceive (NetRxPackets[rxIdx], length - 4); + } + + /* Give the buffer back to the FEC. */ + rtx->rxbd[rxIdx].cbd_datlen = 0; + + /* wrap around buffer index when necessary */ + if ((rxIdx + 1) >= PKTBUFSRX) { + rtx->rxbd[PKTBUFSRX - 1].cbd_sc = + (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); + rxIdx = 0; + } else { + rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; + rxIdx++; + } + + /* Try to fill Buffer Descriptors */ + fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */ + } + + return length; +} + +/************************************************************** + * + * FEC Ethernet Initialization Routine + * + *************************************************************/ +#define FEC_ECNTRL_ETHER_EN 0x00000002 +#define FEC_ECNTRL_RESET 0x00000001 + +#define FEC_RCNTRL_BC_REJ 0x00000010 +#define FEC_RCNTRL_PROM 0x00000008 +#define FEC_RCNTRL_MII_MODE 0x00000004 +#define FEC_RCNTRL_DRT 0x00000002 +#define FEC_RCNTRL_LOOP 0x00000001 + +#define FEC_TCNTRL_FDEN 0x00000004 +#define FEC_TCNTRL_HBC 0x00000002 +#define FEC_TCNTRL_GTS 0x00000001 + +#define FEC_RESET_DELAY 50000 + +int eth_init (bd_t * bd) +{ + + int i; + volatile fec_t *fecp = (fec_t *) (FEC_ADDR); + + /* Whack a reset. + * A delay is required between a reset of the FEC block and + * initialization of other FEC registers because the reset takes + * some time to complete. If you don't delay, subsequent writes + * to FEC registers might get killed by the reset routine which is + * still in progress. + */ + fecp->fec_ecntrl = FEC_ECNTRL_RESET; + for (i = 0; + (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY); + ++i) { + udelay (1); + } + if (i == FEC_RESET_DELAY) { + printf ("FEC_RESET_DELAY timeout\n"); + return 0; + } + + /* We use strictly polling mode only + */ + fecp->fec_imask = 0; + + /* Clear any pending interrupt */ + fecp->fec_ievent = 0xffffffff; + + /* Set station address */ +#define ea bd->bi_enetaddr + fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | + (ea[2] << 8) | (ea[3]); + fecp->fec_addr_high = (ea[4] << 24) | (ea[5] << 16); +#ifdef ET_DEBUG + printf ("Eth Addrs: %02x:%02x:%02x:%02x:%02x:%02x\n", + ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]); +#endif +#undef ea + + /* Clear multicast address hash table + */ + fecp->fec_hash_table_high = 0; + fecp->fec_hash_table_low = 0; + + /* Set maximum receive buffer size. + */ + fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; + + /* + * Setup Buffers and Buffer Desriptors + */ + rxIdx = 0; + txIdx = 0; + + if (!rtx) { + rtx = (RTXBD *) CFG_ENET_BD_BASE; + } + + /* + * Setup Receiver Buffer Descriptors (13.14.24.18) + * Settings: + * Empty, Wrap + */ + for (i = 0; i < PKTBUFSRX; i++) { + rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; + rtx->rxbd[i].cbd_datlen = 0; /* Reset */ + rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; + } + rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; + + /* + * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) + * Settings: + * Last, Tx CRC + */ + for (i = 0; i < TX_BUF_CNT; i++) { + rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC; + rtx->txbd[i].cbd_datlen = 0; /* Reset */ + rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]); + } + rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; + + /* Set receive and transmit descriptor base + */ + fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]); + fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]); + + /* Enable MII mode + */ +#if 0 /* Full duplex mode */ + fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE; + fecp->fec_x_cntrl = FEC_TCNTRL_FDEN; +#else /* Half duplex mode */ + fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT; + fecp->fec_x_cntrl = 0; +#endif + /* Set MII speed */ + fecp->fec_mii_speed = 0x0e; + + /* Configure port B for MII. + */ + /* port initialization was already made in cpu_init_f() */ + + /* Now enable the transmit and receive processing + */ + fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN; + +#ifdef CFG_DISCOVER_PHY + /* wait for the PHY to wake up after reset */ + mii_discover_phy (); +#endif + + /* And last, try to fill Rx Buffer Descriptors */ + fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */ + + return 1; +} + +void eth_halt (void) +{ + volatile fec_t *fecp = (fec_t *) FEC_ADDR; + + fecp->fec_ecntrl = 0; +} + + +#if defined(CFG_DISCOVER_PHY) || (CONFIG_COMMANDS & CFG_CMD_MII) + +static int phyaddr = -1; /* didn't find a PHY yet */ +static uint phytype; + +/* Make MII read/write commands for the FEC. +*/ + +#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | \ + (REG & 0x1f) << 18)) + +#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | \ + (REG & 0x1f) << 18) | \ + (VAL & 0xffff)) + +/* Interrupt events/masks. +*/ +#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */ +#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */ +#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */ +#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */ +#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */ +#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */ +#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */ +#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */ +#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ +#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ + +/* PHY identification + */ +#define PHY_ID_LXT970 0x78100000 /* LXT970 */ +#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */ +#define PHY_ID_82555 0x02a80150 /* Intel 82555 */ +#define PHY_ID_QS6612 0x01814400 /* QS6612 */ +#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */ +#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */ +#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */ + +/* send command to phy using mii, wait for result */ +static uint mii_send (uint mii_cmd) +{ + uint mii_reply; + volatile fec_t *ep = (fec_t *) (FEC_ADDR); + + ep->fec_mii_data = mii_cmd; /* command to phy */ + + /* wait for mii complete */ + while (!(ep->fec_ievent & FEC_ENET_MII)); /* spin until done */ + mii_reply = ep->fec_mii_data; /* result from phy */ + ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */ +#ifdef ET_DEBUG + printf ("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", + __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); +#endif + return (mii_reply & 0xffff); /* data read from phy */ +} +#endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */ + +#if defined(CFG_DISCOVER_PHY) +static void mii_discover_phy (void) +{ +#define MAX_PHY_PASSES 11 + uint phyno; + int pass; + + phyaddr = -1; /* didn't find a PHY yet */ + for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { + if (pass > 1) { + /* PHY may need more time to recover from reset. + * The LXT970 needs 50ms typical, no maximum is + * specified, so wait 10ms before try again. + * With 11 passes this gives it 100ms to wake up. + */ + udelay (10000); /* wait 10ms */ + } + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { + phytype = mii_send (mk_mii_read (phyno, PHY_PHYIDR1)); +#ifdef ET_DEBUG + printf ("PHY type 0x%x pass %d type ", phytype, pass); +#endif + if (phytype != 0xffff) { + phyaddr = phyno; + phytype <<= 16; + phytype |= mii_send (mk_mii_read (phyno, + PHY_PHYIDR2)); + +#ifdef ET_DEBUG + printf ("PHY @ 0x%x pass %d type ", phyno, + pass); + switch (phytype & 0xfffffff0) { + case PHY_ID_LXT970: + printf ("LXT970\n"); + break; + case PHY_ID_LXT971: + printf ("LXT971\n"); + break; + case PHY_ID_82555: + printf ("82555\n"); + break; + case PHY_ID_QS6612: + printf ("QS6612\n"); + break; + case PHY_ID_AMD79C784: + printf ("AMD79C784\n"); + break; + case PHY_ID_LSI80225B: + printf ("LSI L80225/B\n"); + break; + default: + printf ("0x%08x\n", phytype); + break; + } +#endif + } + } + } + if (phyaddr < 0) { + printf ("No PHY device found.\n"); + } +} +#endif /* CFG_DISCOVER_PHY */ + +#if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII) + +static int mii_init_done = 0; + +/**************************************************************************** + * mii_init -- Initialize the MII for MII command without ethernet + * This function is a subset of eth_init + **************************************************************************** + */ +void mii_init (void) +{ + volatile fec_t *fecp = (fec_t *) (FEC_ADDR); + + int i; + + if (mii_init_done != 0) { + return; + } + + /* Whack a reset. + * A delay is required between a reset of the FEC block and + * initialization of other FEC registers because the reset takes + * some time to complete. If you don't delay, subsequent writes + * to FEC registers might get killed by the reset routine which is + * still in progress. + */ + + fecp->fec_ecntrl = FEC_ECNTRL_RESET; + for (i = 0; + (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY); + ++i) { + udelay (1); + } + if (i == FEC_RESET_DELAY) { + printf ("FEC_RESET_DELAY timeout\n"); + return; + } + + /* We use strictly polling mode only + */ + fecp->fec_imask = 0; + + /* Clear any pending interrupt + */ + fecp->fec_ievent = 0xffffffff; + + /* Set MII speed */ + fecp->fec_mii_speed = 0x0e; + + /* Configure port B for MII. + */ + /* port initialization was already made in cpu_init_f() */ + + /* Now enable the transmit and receive processing */ + fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN; + + mii_init_done = 1; +} + +/***************************************************************************** + * Read and write a MII PHY register, routines used by MII Utilities + * + * FIXME: These routines are expected to return 0 on success, but mii_send + * does _not_ return an error code. Maybe 0xFFFF means error, i.e. + * no PHY connected... + * For now always return 0. + * FIXME: These routines only work after calling eth_init() at least once! + * Otherwise they hang in mii_send() !!! Sorry! + *****************************************************************************/ + +int miiphy_read (unsigned char addr, unsigned char reg, unsigned short *value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr); +#endif + rdreg = mii_send (mk_mii_read (addr, reg)); + + *value = rdreg; + +#ifdef MII_DEBUG + printf ("0x%04x\n", *value); +#endif + + return 0; +} + +int miiphy_write (unsigned char addr, unsigned char reg, unsigned short value) +{ + short rdreg; /* register working value */ + +#ifdef MII_DEBUG + printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr); +#endif + + rdreg = mii_send (mk_mii_write (addr, reg, value)); + +#ifdef MII_DEBUG + printf ("0x%04x\n", value); +#endif + + return 0; +} +#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII) */ + +#endif /* CFG_CMD_NET, FEC_ENET */ diff --git a/cpu/mcf52x2/interrupts.c b/cpu/mcf52x2/interrupts.c new file mode 100644 index 0000000..fa181d9 --- /dev/null +++ b/cpu/mcf52x2/interrupts.c @@ -0,0 +1,174 @@ +/* + * (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * + * (C) Copyright 2000-2004 + * 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 <watchdog.h> +#include <asm/processor.h> + +#ifdef CONFIG_M5272 +#include <asm/m5272.h> +#include <asm/immap_5272.h> +#endif + +#ifdef CONFIG_M5282 +#include <asm/m5282.h> +#include <asm/immap_5282.h> +#endif + + +#define NR_IRQS 31 + +/* + * Interrupt vector functions. + */ +struct interrupt_action { + interrupt_handler_t *handler; + void *arg; +} + +static struct interrupt_action irq_vecs[NR_IRQS]; + +static __inline__ unsigned short get_sr (void) +{ + unsigned short sr; + + asm volatile ("move.w %%sr,%0":"=r" (sr):); + + return sr; +} + +static __inline__ void set_sr (unsigned short sr) +{ + asm volatile ("move.w %0,%%sr"::"r" (sr)); +} + +/************************************************************************/ +/* + * Install and free an interrupt handler + */ +void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) +{ +#ifdef CONFIG_M5272 + volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1); +#endif + int vec_base = 0; + +#ifdef CONFIG_M5272 + vec_base = intp->int_pivr & 0xe0; +#endif + + if ((vec < vec_base) || (vec > vec_base + NR_IRQS)) { + printf ("irq_install_handler: wrong interrupt vector %d\n", + vec); + return; + } + + irq_vecs[vec - vec_base].handler = handler; + irq_vecs[vec - vec_base].arg = arg; +} + +void irq_free_handler (int vec) +{ +#ifdef CONFIG_M5272 + volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1); +#endif + int vec_base = 0; + +#ifdef CONFIG_M5272 + vec_base = intp->int_pivr & 0xe0; +#endif + + if ((vec < vec_base) || (vec > vec_base + NR_IRQS)) { + return; + } + + irq_vecs[vec - vec_base].handler = NULL; + irq_vecs[vec - vec_base].arg = NULL; +} + +void enable_interrupts (void) +{ + unsigned short sr; + + sr = get_sr (); + set_sr (sr & ~0x0700); +} + +int disable_interrupts (void) +{ + unsigned short sr; + + sr = get_sr (); + set_sr (sr | 0x0700); + + return ((sr & 0x0700) == 0); /* return TRUE, if interrupts were enabled before */ +} + +void int_handler (struct pt_regs *fp) +{ +#ifdef CONFIG_M5272 + volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1); +#endif + int vec, vec_base = 0; + + vec = (fp->vector >> 2) & 0xff; +#ifdef CONFIG_M5272 + vec_base = intp->int_pivr & 0xe0; +#endif + + if (irq_vecs[vec - vec_base].handler != NULL) { + irq_vecs[vec - + vec_base].handler (irq_vecs[vec - vec_base].arg); + } else { + printf ("\nBogus External Interrupt Vector %ld\n", vec); + } +} + +#ifdef CONFIG_M5272 +int interrupt_init (void) +{ + volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1); + + /* disable all external interrupts */ + intp->int_icr1 = 0x88888888; + intp->int_icr2 = 0x88888888; + intp->int_icr3 = 0x88888888; + intp->int_icr4 = 0x88888888; + intp->int_pitr = 0x00000000; + /* initialize vector register */ + intp->int_pivr = 0x40; + + enable_interrupts (); + + return 0; +} +#endif + +#ifdef CONFIG_M5282 +int interrupt_init (void) +{ + return 0; +} +#endif diff --git a/cpu/mcf52x2/serial.c b/cpu/mcf52x2/serial.c new file mode 100644 index 0000000..fbbd14d --- /dev/null +++ b/cpu/mcf52x2/serial.c @@ -0,0 +1,159 @@ +/* + * (C) Copyright 2000-2004 + * 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/mcfuart.h> + +#ifdef CONFIG_M5272 +#include <asm/m5272.h> +#endif + +#ifdef CONFIG_M5282 +#include <asm/m5282.h> +#endif + +#define DoubleClock(a) ((double)(CFG_CLK) / 32.0 / (double)(a)) + +void rs_serial_setbaudrate(int port,int baudrate) +{ +#ifdef CONFIG_M5272 + volatile unsigned char *uartp; + double clock, fraction; + + if (port == 0) + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1); + else + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2); + + clock = DoubleClock(baudrate); /* Set baud above */ + + fraction = ((clock - (int)clock) * 16.0) + 0.5; + + uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff); /* set msb baud */ + uartp[MCFUART_UBG2] = ((int)clock & 0xff); /* set lsb baud */ + uartp[MCFUART_UFPD] = ((int)fraction & 0xf); /* set baud fraction adjust */ +#endif +}; + +void rs_serial_init(int port,int baudrate) +{ + volatile unsigned char *uartp; + + /* + * Reset UART, get it into known state... + */ + if (port == 0) + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1); + else + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2); + + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */ + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; /* reset Error pointer */ + + /* + * Set port for CONSOLE_BAUD_RATE, 8 data bits, 1 stop bit, no parity. + */ + uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; + uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; + + rs_serial_setbaudrate(port,baudrate); + + uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; + uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; + + return; +} + +/****************************************************************************/ +/* + * Output a single character, using UART polled mode. + * This is used for console output. + */ + +void rs_put_char(char ch) +{ + volatile unsigned char *uartp; + int i; + + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1); + + for (i = 0; (i < 0x10000); i++) { + if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) + break; + } + uartp[MCFUART_UTB] = ch; + return; +} + +int rs_is_char(void) +{ + volatile unsigned char *uartp; + + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1); + return((uartp[MCFUART_USR] & MCFUART_USR_RXREADY) ? 1 : 0); +} + +int rs_get_char(void) +{ + volatile unsigned char *uartp; + + uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1); + return(uartp[MCFUART_URB]); +} + +void serial_setbrg(void) { + DECLARE_GLOBAL_DATA_PTR; + rs_serial_setbaudrate(0,gd->bd->bi_baudrate); +} + +int serial_init(void) { + DECLARE_GLOBAL_DATA_PTR; + rs_serial_init(0,gd->baudrate); + return 0; +} + + +void serial_putc(const char c) { + if (c == '\n') + serial_putc ('\r'); + rs_put_char(c); +} + +void serial_puts (const char *s) { + while (*s) { + serial_putc(*s++); + } +} + +int serial_getc(void) { + while(!rs_is_char()); + return rs_get_char(); +} + +int serial_tstc() { + return rs_is_char(); +} diff --git a/cpu/coldfire/speed.c b/cpu/mcf52x2/speed.c index 0fe0925..8d5c92f 100644 --- a/cpu/coldfire/speed.c +++ b/cpu/mcf52x2/speed.c @@ -1,6 +1,6 @@ /* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * (C) Copyright 2003 + * Josef Baumgartner <josef.baumgartner@telex.de> * * See file CREDITS for list of people who contributed to this * project. @@ -24,12 +24,14 @@ #include <common.h> #include <asm/processor.h> -ulong get_gclk_freq (void) +/* + * get_clocks() fills in gd->cpu_clock and gd->bus_clk + */ +int get_clocks (void) { - return 0; -} + DECLARE_GLOBAL_DATA_PTR; -ulong get_bus_freq (ulong gclk_freq) -{ - return 0; + gd->cpu_clk = CFG_CLK; + gd->bus_clk = gd->cpu_clk; + return (0); } diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S new file mode 100644 index 0000000..cf1b97d --- /dev/null +++ b/cpu/mcf52x2/start.S @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.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 "version.h" + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + + +#define _START _start +#define _FAULT _fault + + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; \ + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte + +/* If we come from a pre-loader we don't need an initial exception + * table. + */ +#if !defined(CONFIG_MONITOR_IS_IN_RAM) + +.text +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: + +.long 0x00000000, _START +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +#endif + + .text + + .globl _start +_start: + nop + nop + move.w #0x2700,%sr + + /* if we come from a pre-loader we have no exception table and + * therefore no VBR to set + */ +#if !defined(CONFIG_MONITOR_IS_IN_RAM) + move.l #CFG_FLASH_BASE, %d0 + movec %d0, %VBR +#endif + +#ifdef CONFIG_M5272 + move.l #(CFG_MBAR + 1), %d0 /* set MBAR address + valid flag */ + move.c %d0, %MBAR + + move.l #(CFG_INIT_RAM_ADDR + 1), %d0 + movec %d0, %RAMBAR0 +#endif + +#ifdef CONFIG_M5282 + /* Initialize IPSBAR */ + move.l #(CFG_MBAR + 1), %d0 /* set IPSBAR address + valid flag */ + move.l %d0, 0x40000000 + + /* Initialize FLASHBAR: locate internal Flash and validate it */ + move.l #(CFG_INT_FLASH_BASE + 0x21), %d0 + movec %d0, %RAMBAR0 + + /* Initialize RAMBAR1: locate SRAM and validate it */ + move.l #(CFG_INIT_RAM_ADDR + 0x21), %d0 + movec %d0, %RAMBAR1 +#endif + + /* invalidate and disable cache */ + move.l #0x01000000, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + + /* set stackpointer to end of internal ram to get some stackspace for the first c-code */ + move.l #(CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET), %sp + clr.l %sp@- + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CFG_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CFG_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CFG_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CFG_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CFG_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CFG_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CFG_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + jmp _fault + + .globl _exc_handler +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ +/* cache functions */ +#ifdef CONFIG_M5272 + .globl icache_enable +icache_enable: + move.l #0x01000000, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + move.l #0x0000c000, %d0 /* Setup cache mask */ + movec %d0, %ACR0 /* Enable cache */ + move.l #0xff00c000, %d0 /* Setup cache mask */ + movec %d0, %ACR1 /* Enable cache */ + move.l #0x80000100, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Enable cache */ + moveq #1, %d0 + move.l %d0, icache_state + rts +#endif + +#ifdef CONFIG_M5282 + .globl icache_enable +icache_enable: + move.l #0x01000000, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + move.l #0x0000c000, %d0 /* Setup cache mask */ + movec %d0, %ACR0 /* Enable cache */ + move.l #0xff00c000, %d0 /* Setup cache mask */ + movec %d0, %ACR1 /* Enable cache */ + move.l #0x80400100, %d0 /* Setup cache mask, data cache disabel*/ + movec %d0, %CACR /* Enable cache */ + moveq #1, %d0 + move.l %d0, icache_state + rts +#endif + + .globl icache_disable +icache_disable: + move.l #0x00000100, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Enable cache */ + clr.l %d0 /* Setup cache mask */ + movec %d0, %ACR0 /* Enable cache */ + movec %d0, %ACR1 /* Enable cache */ + moveq #0, %d0 + move.l %d0, icache_state + rts + + .globl icache_status +icache_status: + move.l icache_state, %d0 + rts + + .data +icache_state: + .long 1 + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" |