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 5ce063990..000000000 --- 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 50627415e..000000000 --- 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 a49417c66..000000000 --- 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 3861ff101..000000000 --- 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 a140fe3db..000000000 --- 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 44542231d..000000000 --- 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 3976f5689..879deb714 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 72b33cea2..650db8583 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 000000000..b01222279 --- /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 000000000..8aff8f1ae --- /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 000000000..623a01dbb --- /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 000000000..fa181d9bc --- /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 000000000..fbbd14d62 --- /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 0fe0925d1..8d5c92f37 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 000000000..cf1b97d84 --- /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" |