diff options
41 files changed, 3972 insertions, 0 deletions
| @@ -2,6 +2,10 @@  Changes since U-Boot 1.0.0:  ====================================================================== +* Patch by Bernhard Kuhn, 28 Nov 2003: +  add support for Coldfire CPU +  add support for Motorola M5272C3 and M5282EVB boards +  * Patch by Pierre Aubert, 24 Nov 2003:    - add a return value for the fpga command    - add ide_preinit() function called in ide_init if CONFIG_IDE_PREINIT @@ -195,6 +195,10 @@ E: Raghu.Krishnaprasad@fci.com  D: Support for Adder-II MPC852T evaluation board  W: http://www.forcecomputers.com +N: Bernhard Kuhn +E: bkuhn@metrowerks.com +D Support for Coldfire CPU; Support for Motorola M5272C3 and M5282EVB boards +  N: Thomas Lange  E: thomas@corelatus.se  D: Support for GTH and dbau1x00 boards; lots of PCMCIA fixes @@ -72,6 +72,9 @@ endif  ifeq ($(ARCH),nios)  CROSS_COMPILE = nios-elf-  endif +ifeq ($(ARCH),m68k) +CROSS_COMPILE = m68k-elf- +endif  endif  endif @@ -802,6 +805,19 @@ TQM8265_AA_config:  unconfig  ZPC1900_config: unconfig  	@./mkconfig $(@:_config=) ppc mpc8260 zpc1900 +#======================================================================== +# M68K +#======================================================================== +######################################################################### +## Coldfire +######################################################################### + +M5272C3_config :		unconfig +	@./mkconfig $(@:_config=) m68k coldfire m5272c3 + +M5282EVB_config :		unconfig +	@./mkconfig $(@:_config=) m68k coldfire m5282evb +  #########################################################################  ## MPC85xx Systems  ######################################################################### diff --git a/board/m5272c3/Makefile b/board/m5272c3/Makefile new file mode 100644 index 000000000..378428e31 --- /dev/null +++ b/board/m5272c3/Makefile @@ -0,0 +1,40 @@ +# +# (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 $(TOPDIR)/config.mk + +LIB	= lib$(BOARD).a + +OBJS	= $(BOARD).o flash.o + +$(LIB):	.depend $(OBJS) +	$(AR) crv $@ $^ + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/m5272c3/config.mk b/board/m5272c3/config.mk new file mode 100644 index 000000000..e0cd8dafa --- /dev/null +++ b/board/m5272c3/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, 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 +# + +TEXT_BASE = 0x3e0000 diff --git a/board/m5272c3/flash.c b/board/m5272c3/flash.c new file mode 100644 index 000000000..fb918435c --- /dev/null +++ b/board/m5272c3/flash.c @@ -0,0 +1,378 @@ +/* + * (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> + +#define PHYS_FLASH_1 CFG_FLASH_BASE +#define FLASH_BANK_SIZE 0x200000 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +void flash_print_info (flash_info_t * info) +{ +	int i; + +	switch (info->flash_id & FLASH_VENDMASK) { +	case (AMD_MANUFACT & FLASH_VENDMASK): +		printf ("AMD: "); +		break; +	default: +		printf ("Unknown Vendor "); +		break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case (AMD_ID_PL160CB & FLASH_TYPEMASK): +		printf ("AM29PL160CB (16Mbit)\n"); +		break; +	default: +		printf ("Unknown Chip Type\n"); +		goto Done; +		break; +	} + +	printf ("  Size: %ld MB in %d Sectors\n", +		info->size >> 20, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i = 0; i < info->sector_count; i++) { +		if ((i % 5) == 0) { +			printf ("\n   "); +		} +		printf (" %08lX%s", info->start[i], +			info->protect[i] ? " (RO)" : "     "); +	} +	printf ("\n"); + +      Done: +} + + +unsigned long flash_init (void) +{ +	int i, j; +	ulong size = 0; + +	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { +		ulong flashbase = 0; + +		flash_info[i].flash_id = +			(AMD_MANUFACT & FLASH_VENDMASK) | +			(AMD_ID_PL160CB & FLASH_TYPEMASK); +		flash_info[i].size = FLASH_BANK_SIZE; +		flash_info[i].sector_count = CFG_MAX_FLASH_SECT; +		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); +		if (i == 0) +			flashbase = PHYS_FLASH_1; +		else +			panic ("configured to many flash banks!\n"); + +		for (j = 0; j < flash_info[i].sector_count; j++) { +			if (j == 0) { +				/* 1st is 16 KiB */ +				flash_info[i].start[j] = flashbase; +			} +			if ((j >= 1) && (j <= 2)) { +				/* 2nd and 3rd are 8 KiB */ +				flash_info[i].start[j] = +					flashbase + 0x4000 + 0x2000 * (j - 1); +			} +			if (j == 3) { +				/* 4th is 224 KiB */ +				flash_info[i].start[j] = flashbase + 0x8000; +			} +			if ((j >= 4) && (j <= 10)) { +				/* rest is 256 KiB */ +				flash_info[i].start[j] = +					flashbase + 0x40000 + 0x40000 * (j - +									 4); +			} +		} +		size += flash_info[i].size; +	} + +	flash_protect (FLAG_PROTECT_SET, +		       CFG_FLASH_BASE, +		       CFG_FLASH_BASE + 0x3ffff, &flash_info[0]); + +	return size; +} + + +#define CMD_READ_ARRAY		0x00F0 +#define CMD_UNLOCK1		0x00AA +#define CMD_UNLOCK2		0x0055 +#define CMD_ERASE_SETUP		0x0080 +#define CMD_ERASE_CONFIRM	0x0030 +#define CMD_PROGRAM		0x00A0 +#define CMD_UNLOCK_BYPASS	0x0020 + +#define MEM_FLASH_ADDR1		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555<<1))) +#define MEM_FLASH_ADDR2		(*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA<<1))) + +#define BIT_ERASE_DONE		0x0080 +#define BIT_RDY_MASK		0x0080 +#define BIT_PROGRAM_ERROR	0x0020 +#define BIT_TIMEOUT		0x80000000	/* our flag */ + +#define READY 1 +#define ERR   2 +#define TMO   4 + + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ +	ulong result; +	int iflag, cflag, prot, sect; +	int rc = ERR_OK; +	int chip1; + +	/* first look for protection bits */ + +	if (info->flash_id == FLASH_UNKNOWN) +		return ERR_UNKNOWN_FLASH_TYPE; + +	if ((s_first < 0) || (s_first > s_last)) { +		return ERR_INVAL; +	} + +	if ((info->flash_id & FLASH_VENDMASK) != +	    (AMD_MANUFACT & FLASH_VENDMASK)) { +		return ERR_UNKNOWN_FLASH_VENDOR; +	} + +	prot = 0; +	for (sect = s_first; sect <= s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} +	if (prot) +		return ERR_PROTECTED; + +	/* +	 * Disable interrupts which might cause a timeout +	 * here. Remember that our exception vectors are +	 * at address 0 in the flash, and we don't want a +	 * (ticker) exception to happen while the flash +	 * chip is in programming mode. +	 */ + +	cflag = icache_status (); +	icache_disable (); +	iflag = disable_interrupts (); + +	printf ("\n"); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { +		printf ("Erasing sector %2d ... ", sect); + +		/* arm simple, non interrupt dependent timer */ +		set_timer (0); + +		if (info->protect[sect] == 0) {	/* not protected */ +			volatile u16 *addr = +				(volatile u16 *) (info->start[sect]); + +			MEM_FLASH_ADDR1 = CMD_UNLOCK1; +			MEM_FLASH_ADDR2 = CMD_UNLOCK2; +			MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; + +			MEM_FLASH_ADDR1 = CMD_UNLOCK1; +			MEM_FLASH_ADDR2 = CMD_UNLOCK2; +			*addr = CMD_ERASE_CONFIRM; + +			/* wait until flash is ready */ +			chip1 = 0; + +			do { +				result = *addr; + +				/* check timeout */ +				if (get_timer (0) > CFG_FLASH_ERASE_TOUT) { +					MEM_FLASH_ADDR1 = CMD_READ_ARRAY; +					chip1 = TMO; +					break; +				} + +				if (!chip1 +				    && (result & 0xFFFF) & BIT_ERASE_DONE) +					chip1 = READY; + +			} while (!chip1); + +			MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + +			if (chip1 == ERR) { +				rc = ERR_PROG_ERROR; +				goto outahere; +			} +			if (chip1 == TMO) { +				rc = ERR_TIMOUT; +				goto outahere; +			} + +			printf ("ok.\n"); +		} else {	/* it was protected */ + +			printf ("protected!\n"); +		} +	} + +	if (ctrlc ()) +		printf ("User Interrupt!\n"); + +      outahere: +	/* allow flash to settle - wait 10 ms */ +	udelay (10000); + +	if (iflag) +		enable_interrupts (); + +	if (cflag) +		icache_enable (); + +	return rc; +} + + +volatile static int write_word (flash_info_t * info, ulong dest, ulong data) +{ +	volatile u16 *addr = (volatile u16 *) dest; +	ulong result; +	int rc = ERR_OK; +	int cflag, iflag; +	int chip1; + +	/* +	 * Check if Flash is (sufficiently) erased +	 */ +	result = *addr; +	if ((result & data) != data) +		return ERR_NOT_ERASED; + + +	/* +	 * Disable interrupts which might cause a timeout +	 * here. Remember that our exception vectors are +	 * at address 0 in the flash, and we don't want a +	 * (ticker) exception to happen while the flash +	 * chip is in programming mode. +	 */ + +	cflag = icache_status (); +	icache_disable (); +	iflag = disable_interrupts (); + +	MEM_FLASH_ADDR1 = CMD_UNLOCK1; +	MEM_FLASH_ADDR2 = CMD_UNLOCK2; +	MEM_FLASH_ADDR1 = CMD_PROGRAM; +	*addr = data; + +	/* arm simple, non interrupt dependent timer */ +	set_timer (0); + +	/* wait until flash is ready */ +	chip1 = 0; +	do { +		result = *addr; + +		/* check timeout */ +		if (get_timer (0) > CFG_FLASH_ERASE_TOUT) { +			chip1 = ERR | TMO; +			break; +		} +		if (!chip1 && ((result & 0x80) == (data & 0x80))) +			chip1 = READY; + +	} while (!chip1); + +	*addr = CMD_READ_ARRAY; + +	if (chip1 == ERR || *addr != data) +		rc = ERR_PROG_ERROR; + +	if (iflag) +		enable_interrupts (); + +	if (cflag) +		icache_enable (); + +	return rc; +} + + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ +	ulong wp, data; +	int rc; + +	if (addr & 1) { +		printf ("unaligned destination not supported\n"); +		return ERR_ALIGN; +	} + +#if 0 +	if (cnt & 1) { +		printf ("odd transfer sizes not supported\n"); +		return ERR_ALIGN; +	} +#endif + +	wp = addr; + +	if (addr & 1) { +		data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *) +							  src); +		if ((rc = write_word (info, wp - 1, data)) != 0) { +			return (rc); +		} +		src += 1; +		wp += 1; +		cnt -= 1; +	} + +	while (cnt >= 2) { +		data = *((volatile u16 *) src); +		if ((rc = write_word (info, wp, data)) != 0) { +			return (rc); +		} +		src += 2; +		wp += 2; +		cnt -= 2; +	} + +	if (cnt == 1) { +		data = (*((volatile u8 *) src) << 8) | +			*((volatile u8 *) (wp + 1)); +		if ((rc = write_word (info, wp, data)) != 0) { +			return (rc); +		} +		src += 1; +		wp += 1; +		cnt -= 1; +	} + +	return ERR_OK; +} diff --git a/board/m5272c3/m5272c3.c b/board/m5272c3/m5272c3.c new file mode 100644 index 000000000..91ec9a12d --- /dev/null +++ b/board/m5272c3/m5272c3.c @@ -0,0 +1,35 @@ +/* + * (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> + +int checkboard (void) +{ +	puts ("MOTOROLA MCF5272C3 Evaluation Board\n"); +	return 0; +} + +long int initdram (int board_type) +{ +	return 0x400000; +} diff --git a/board/m5272c3/u-boot.lds b/board/m5272c3/u-boot.lds new file mode 100644 index 000000000..0d3829ab2 --- /dev/null +++ b/board/m5272c3/u-boot.lds @@ -0,0 +1,135 @@ +/* + * (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 + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)		} +  .rela.text     : { *(.rela.text) 	} +  .rel.data      : { *(.rel.data)		} +  .rela.data     : { *(.rela.data) 	} +  .rel.rodata    : { *(.rel.rodata) 	} +  .rela.rodata   : { *(.rela.rodata) 	} +  .rel.got       : { *(.rel.got)		} +  .rela.got      : { *(.rela.got)		} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)		} +  .rela.bss      : { *(.rela.bss)		} +  .rel.plt       : { *(.rel.plt)		} +  .rela.plt      : { *(.rela.plt)		} +  .init          : { *(.init)	} +  .plt : { *(.plt) } +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ + +    cpu/coldfire/start.o	(.text) +    common/dlmalloc.o	(.text) +    lib_generic/string.o	(.text) +    lib_generic/vsprintf.o	(.text) +    lib_generic/crc32.o	(.text) +    lib_generic/zlib.o	(.text) + +/*    . = env_offset; */ +    common/environment.o(.text) + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x00FF) & 0xFFFFFF00; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(256); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(256); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   _sbss = .; +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +   . = ALIGN(4); +   _ebss = .; +  } +  _end = . ; +  PROVIDE (end = .); +} diff --git a/board/m5272c3/u-boot.lds.debug b/board/m5272c3/u-boot.lds.debug new file mode 100644 index 000000000..cb2a729fe --- /dev/null +++ b/board/m5272c3/u-boot.lds.debug @@ -0,0 +1,130 @@ +/* + * (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 + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)		} +  .rela.text     : { *(.rela.text) 	} +  .rel.data      : { *(.rel.data)		} +  .rela.data     : { *(.rela.data) 	} +  .rel.rodata    : { *(.rel.rodata) 	} +  .rela.rodata   : { *(.rela.rodata) 	} +  .rel.got       : { *(.rel.got)		} +  .rela.got      : { *(.rela.got)		} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)		} +  .rela.bss      : { *(.rela.bss)		} +  .rel.plt       : { *(.rel.plt)		} +  .rela.plt      : { *(.rela.plt)		} +  .init          : { *(.init)	} +  .plt : { *(.plt) } +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ + +    cpu/mpc8xx/start.o	(.text) +    common/dlmalloc.o	(.text) +    ppc/vsprintf.o	(.text) +    ppc/crc32.o		(.text) + +    . = env_offset; +    common/environment.o(.text) + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x0FFF) & 0xFFFFF000; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(4096); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(4096); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +  } +  _end = . ; +  PROVIDE (end = .); +} diff --git a/board/m5282evb/Makefile b/board/m5282evb/Makefile new file mode 100644 index 000000000..378428e31 --- /dev/null +++ b/board/m5282evb/Makefile @@ -0,0 +1,40 @@ +# +# (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 $(TOPDIR)/config.mk + +LIB	= lib$(BOARD).a + +OBJS	= $(BOARD).o flash.o + +$(LIB):	.depend $(OBJS) +	$(AR) crv $@ $^ + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/m5282evb/config.mk b/board/m5282evb/config.mk new file mode 100644 index 000000000..e0cd8dafa --- /dev/null +++ b/board/m5282evb/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, 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 +# + +TEXT_BASE = 0x3e0000 diff --git a/board/m5282evb/flash.c b/board/m5282evb/flash.c new file mode 100644 index 000000000..ff70783bd --- /dev/null +++ b/board/m5282evb/flash.c @@ -0,0 +1,378 @@ +/* + * (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> + +#define PHYS_FLASH_1 CFG_FLASH_BASE +#define FLASH_BANK_SIZE 0x200000 + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + +void flash_print_info (flash_info_t * info) +{ +	int i; + +	switch (info->flash_id & FLASH_VENDMASK) { +	case (AMD_MANUFACT & FLASH_VENDMASK): +		printf ("AMD: "); +		break; +	default: +		printf ("Unknown Vendor "); +		break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case (AMD_ID_PL160CB & FLASH_TYPEMASK): +		printf ("AM29PL160CB (16Mbit)\n"); +		break; +	default: +		printf ("Unknown Chip Type\n"); +		goto Done; +		break; +	} + +	printf ("  Size: %ld MB in %d Sectors\n", +		info->size >> 20, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i = 0; i < info->sector_count; i++) { +		if ((i % 5) == 0) { +			printf ("\n   "); +		} +		printf (" %08lX%s", info->start[i], +			info->protect[i] ? " (RO)" : "     "); +	} +	printf ("\n"); + +      Done: +} + + +unsigned long flash_init (void) +{ +	int i, j; +	ulong size = 0; + +	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { +		ulong flashbase = 0; + +		flash_info[i].flash_id = +			(AMD_MANUFACT & FLASH_VENDMASK) | +			(AMD_ID_PL160CB & FLASH_TYPEMASK); +		flash_info[i].size = FLASH_BANK_SIZE; +		flash_info[i].sector_count = CFG_MAX_FLASH_SECT; +		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); +		if (i == 0) +			flashbase = PHYS_FLASH_1; +		else +			panic ("configured to many flash banks!\n"); + +		for (j = 0; j < flash_info[i].sector_count; j++) { +			if (j == 0) { +				/* 1st is 16 KiB */ +				flash_info[i].start[j] = flashbase; +			} +			if ((j >= 1) && (j <= 2)) { +				/* 2nd and 3rd are 8 KiB */ +				flash_info[i].start[j] = +					flashbase + 0x4000 + 0x2000 * (j - 1); +			} +			if (j == 3) { +				/* 4th is 32 KiB */ +				flash_info[i].start[j] = flashbase + 0x8000; +			} +			if ((j >= 4) && (j <= 34)) { +				/* rest is 256 KiB */ +				flash_info[i].start[j] = +					flashbase + 0x10000 + 0x10000 * (j - +									 4); +			} +		} +		size += flash_info[i].size; +	} + +	flash_protect (FLAG_PROTECT_SET, +		       CFG_FLASH_BASE, +		       CFG_FLASH_BASE + 0xffff, &flash_info[0]); + +	return size; +} + + +#define CMD_READ_ARRAY		0x00F0 +#define CMD_UNLOCK1		0x00AA +#define CMD_UNLOCK2		0x0055 +#define CMD_ERASE_SETUP		0x0080 +#define CMD_ERASE_CONFIRM	0x0030 +#define CMD_PROGRAM		0x00A0 +#define CMD_UNLOCK_BYPASS	0x0020 + +#define MEM_FLASH_ADDR1		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555<<1))) +#define MEM_FLASH_ADDR2		(*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA<<1))) + +#define BIT_ERASE_DONE		0x0080 +#define BIT_RDY_MASK		0x0080 +#define BIT_PROGRAM_ERROR	0x0020 +#define BIT_TIMEOUT		0x80000000	/* our flag */ + +#define READY 1 +#define ERR   2 +#define TMO   4 + + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ +	ulong result; +	int iflag, cflag, prot, sect; +	int rc = ERR_OK; +	int chip1; + +	/* first look for protection bits */ + +	if (info->flash_id == FLASH_UNKNOWN) +		return ERR_UNKNOWN_FLASH_TYPE; + +	if ((s_first < 0) || (s_first > s_last)) { +		return ERR_INVAL; +	} + +	if ((info->flash_id & FLASH_VENDMASK) != +	    (AMD_MANUFACT & FLASH_VENDMASK)) { +		return ERR_UNKNOWN_FLASH_VENDOR; +	} + +	prot = 0; +	for (sect = s_first; sect <= s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} +	if (prot) +		return ERR_PROTECTED; + +	/* +	 * Disable interrupts which might cause a timeout +	 * here. Remember that our exception vectors are +	 * at address 0 in the flash, and we don't want a +	 * (ticker) exception to happen while the flash +	 * chip is in programming mode. +	 */ + +	cflag = icache_status (); +	icache_disable (); +	iflag = disable_interrupts (); + +	printf ("\n"); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { +		printf ("Erasing sector %2d ... ", sect); + +		/* arm simple, non interrupt dependent timer */ +		set_timer (0); + +		if (info->protect[sect] == 0) {	/* not protected */ +			volatile u16 *addr = +				(volatile u16 *) (info->start[sect]); + +			MEM_FLASH_ADDR1 = CMD_UNLOCK1; +			MEM_FLASH_ADDR2 = CMD_UNLOCK2; +			MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; + +			MEM_FLASH_ADDR1 = CMD_UNLOCK1; +			MEM_FLASH_ADDR2 = CMD_UNLOCK2; +			*addr = CMD_ERASE_CONFIRM; + +			/* wait until flash is ready */ +			chip1 = 0; + +			do { +				result = *addr; + +				/* check timeout */ +				if (get_timer (0) > CFG_FLASH_ERASE_TOUT) { +					MEM_FLASH_ADDR1 = CMD_READ_ARRAY; +					chip1 = TMO; +					break; +				} + +				if (!chip1 +				    && (result & 0xFFFF) & BIT_ERASE_DONE) +					chip1 = READY; + +			} while (!chip1); + +			MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + +			if (chip1 == ERR) { +				rc = ERR_PROG_ERROR; +				goto outahere; +			} +			if (chip1 == TMO) { +				rc = ERR_TIMOUT; +				goto outahere; +			} + +			printf ("ok.\n"); +		} else {	/* it was protected */ + +			printf ("protected!\n"); +		} +	} + +	if (ctrlc ()) +		printf ("User Interrupt!\n"); + +      outahere: +	/* allow flash to settle - wait 10 ms */ +	udelay (10000); + +	if (iflag) +		enable_interrupts (); + +	if (cflag) +		icache_enable (); + +	return rc; +} + + +volatile static int write_word (flash_info_t * info, ulong dest, ulong data) +{ +	volatile u16 *addr = (volatile u16 *) dest; +	ulong result; +	int rc = ERR_OK; +	int cflag, iflag; +	int chip1; + +	/* +	 * Check if Flash is (sufficiently) erased +	 */ +	result = *addr; +	if ((result & data) != data) +		return ERR_NOT_ERASED; + + +	/* +	 * Disable interrupts which might cause a timeout +	 * here. Remember that our exception vectors are +	 * at address 0 in the flash, and we don't want a +	 * (ticker) exception to happen while the flash +	 * chip is in programming mode. +	 */ + +	cflag = icache_status (); +	icache_disable (); +	iflag = disable_interrupts (); + +	MEM_FLASH_ADDR1 = CMD_UNLOCK1; +	MEM_FLASH_ADDR2 = CMD_UNLOCK2; +	MEM_FLASH_ADDR1 = CMD_PROGRAM; +	*addr = data; + +	/* arm simple, non interrupt dependent timer */ +	set_timer (0); + +	/* wait until flash is ready */ +	chip1 = 0; +	do { +		result = *addr; + +		/* check timeout */ +		if (get_timer (0) > CFG_FLASH_ERASE_TOUT) { +			chip1 = ERR | TMO; +			break; +		} +		if (!chip1 && ((result & 0x80) == (data & 0x80))) +			chip1 = READY; + +	} while (!chip1); + +	*addr = CMD_READ_ARRAY; + +	if (chip1 == ERR || *addr != data) +		rc = ERR_PROG_ERROR; + +	if (iflag) +		enable_interrupts (); + +	if (cflag) +		icache_enable (); + +	return rc; +} + + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ +	ulong wp, data; +	int rc; + +	if (addr & 1) { +		printf ("unaligned destination not supported\n"); +		return ERR_ALIGN; +	} + +#if 0 +	if (cnt & 1) { +		printf ("odd transfer sizes not supported\n"); +		return ERR_ALIGN; +	} +#endif + +	wp = addr; + +	if (addr & 1) { +		data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *) +							  src); +		if ((rc = write_word (info, wp - 1, data)) != 0) { +			return (rc); +		} +		src += 1; +		wp += 1; +		cnt -= 1; +	} + +	while (cnt >= 2) { +		data = *((volatile u16 *) src); +		if ((rc = write_word (info, wp, data)) != 0) { +			return (rc); +		} +		src += 2; +		wp += 2; +		cnt -= 2; +	} + +	if (cnt == 1) { +		data = (*((volatile u8 *) src) << 8) | +			*((volatile u8 *) (wp + 1)); +		if ((rc = write_word (info, wp, data)) != 0) { +			return (rc); +		} +		src += 1; +		wp += 1; +		cnt -= 1; +	} + +	return ERR_OK; +} diff --git a/board/m5282evb/m5282evb.c b/board/m5282evb/m5282evb.c new file mode 100644 index 000000000..a08af68ae --- /dev/null +++ b/board/m5282evb/m5282evb.c @@ -0,0 +1,35 @@ +/* + * (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> + +int checkboard (void) +{ +	puts ("MOTOROLA M5272EVB Evaluation Board\n"); +	return 0; +} + +long int initdram (int board_type) +{ +	return 0x1000000; +} diff --git a/board/m5282evb/u-boot.lds b/board/m5282evb/u-boot.lds new file mode 100644 index 000000000..0d3829ab2 --- /dev/null +++ b/board/m5282evb/u-boot.lds @@ -0,0 +1,135 @@ +/* + * (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 + */ + +OUTPUT_ARCH(m68k) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)		} +  .rela.text     : { *(.rela.text) 	} +  .rel.data      : { *(.rel.data)		} +  .rela.data     : { *(.rela.data) 	} +  .rel.rodata    : { *(.rel.rodata) 	} +  .rela.rodata   : { *(.rela.rodata) 	} +  .rel.got       : { *(.rel.got)		} +  .rela.got      : { *(.rela.got)		} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)		} +  .rela.bss      : { *(.rela.bss)		} +  .rel.plt       : { *(.rel.plt)		} +  .rela.plt      : { *(.rela.plt)		} +  .init          : { *(.init)	} +  .plt : { *(.plt) } +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ + +    cpu/coldfire/start.o	(.text) +    common/dlmalloc.o	(.text) +    lib_generic/string.o	(.text) +    lib_generic/vsprintf.o	(.text) +    lib_generic/crc32.o	(.text) +    lib_generic/zlib.o	(.text) + +/*    . = env_offset; */ +    common/environment.o(.text) + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x00FF) & 0xFFFFFF00; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(256); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(256); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   _sbss = .; +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +   . = ALIGN(4); +   _ebss = .; +  } +  _end = . ; +  PROVIDE (end = .); +} diff --git a/board/m5282evb/u-boot.lds.debug b/board/m5282evb/u-boot.lds.debug new file mode 100644 index 000000000..cb2a729fe --- /dev/null +++ b/board/m5282evb/u-boot.lds.debug @@ -0,0 +1,130 @@ +/* + * (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 + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)		} +  .rela.text     : { *(.rela.text) 	} +  .rel.data      : { *(.rel.data)		} +  .rela.data     : { *(.rela.data) 	} +  .rel.rodata    : { *(.rel.rodata) 	} +  .rela.rodata   : { *(.rela.rodata) 	} +  .rel.got       : { *(.rel.got)		} +  .rela.got      : { *(.rela.got)		} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)		} +  .rela.bss      : { *(.rela.bss)		} +  .rel.plt       : { *(.rel.plt)		} +  .rela.plt      : { *(.rela.plt)		} +  .init          : { *(.init)	} +  .plt : { *(.plt) } +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ + +    cpu/mpc8xx/start.o	(.text) +    common/dlmalloc.o	(.text) +    ppc/vsprintf.o	(.text) +    ppc/crc32.o		(.text) + +    . = env_offset; +    common/environment.o(.text) + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x0FFF) & 0xFFFFF000; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(4096); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(4096); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +  } +  _end = . ; +  PROVIDE (end = .); +} diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 78d4612c8..5e31400c9 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -240,6 +240,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	if (hdr->ih_arch != IH_CPU_MIPS)  #elif defined(__nios__)  	if (hdr->ih_arch != IH_CPU_NIOS) +#elif defined(__M68K__) +	if (hdr->ih_arch != IH_CPU_M68K)  #else  # error Unknown CPU type  #endif diff --git a/cpu/coldfire/Makefile b/cpu/coldfire/Makefile new file mode 100644 index 000000000..085d840c0 --- /dev/null +++ b/cpu/coldfire/Makefile @@ -0,0 +1,45 @@ +# +# (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 $(TOPDIR)/config.mk + +# CFLAGS += -DET_DEBUG + +LIB	= lib$(CPU).a + +START	=  +OBJS	= kgdb.o serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o + +all:	.depend $(START) $(LIB) + +$(LIB):	$(OBJS) +	$(AR) crv $@ $(OBJS) kgdb.o + +######################################################################### + +.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/coldfire/config.mk b/cpu/coldfire/config.mk new file mode 100644 index 000000000..72b33cea2 --- /dev/null +++ b/cpu/coldfire/config.mk @@ -0,0 +1,26 @@ +# +# (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 +# + +PLATFORM_RELFLAGS += + +PLATFORM_CPPFLAGS += -m5200 diff --git a/cpu/coldfire/cpu.c b/cpu/coldfire/cpu.c new file mode 100644 index 000000000..5ce063990 --- /dev/null +++ b/cpu/coldfire/cpu.c @@ -0,0 +1,87 @@ +/* + * (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 new file mode 100644 index 000000000..53a93c1ce --- /dev/null +++ b/cpu/coldfire/fec.c @@ -0,0 +1,300 @@ +/* + * (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 new file mode 100644 index 000000000..a49417c66 --- /dev/null +++ b/cpu/coldfire/fec.h @@ -0,0 +1,28 @@ +/* + * (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 new file mode 100644 index 000000000..3861ff101 --- /dev/null +++ b/cpu/coldfire/interrupts.c @@ -0,0 +1,127 @@ +/* + * (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 new file mode 100644 index 000000000..a140fe3db --- /dev/null +++ b/cpu/coldfire/serial.c @@ -0,0 +1,168 @@ +/* + * (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/speed.c b/cpu/coldfire/speed.c new file mode 100644 index 000000000..0fe0925d1 --- /dev/null +++ b/cpu/coldfire/speed.c @@ -0,0 +1,35 @@ +/* + * (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 <asm/processor.h> + +ulong get_gclk_freq (void) +{ +	return 0; +} + +ulong get_bus_freq (ulong gclk_freq) +{ +	return 0; +} diff --git a/cpu/coldfire/start.S b/cpu/coldfire/start.S new file mode 100644 index 000000000..7e02661e0 --- /dev/null +++ b/cpu/coldfire/start.S @@ -0,0 +1,165 @@ +/* + *  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/examples/Makefile b/examples/Makefile index 1e40c829e..7a7739f6d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -56,6 +56,11 @@ SREC   += sched.srec  BIN    += sched.bin  endif +ifeq ($(ARCH),m68k) +SREC = +BIN = +endif +  # The following example is pretty 8xx specific...  ifeq ($(CPU),mpc8xx)  SREC   += timer.srec diff --git a/include/asm-m68k/global_data.h b/include/asm-m68k/global_data.h new file mode 100644 index 000000000..89bc0ad3f --- /dev/null +++ b/include/asm-m68k/global_data.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2002-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 + */ + +#ifndef	__ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H +/* + * The following data structure is placed in some memory wich is + * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or + * some locked parts of the data cache) to allow for a minimum set of + * global variables during system initialization (until we have set + * up the memory controller so that we can use RAM). + * + * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t) + */ + +typedef	struct	global_data { +	bd_t		*bd; +	unsigned long	flags; +	unsigned long	baudrate; +	unsigned long	cpu_clk;	/* CPU clock in Hz!		*/ +	unsigned long	bus_clk; +	unsigned long	ram_size;	/* RAM size */ +	unsigned long	reloc_off;	/* Relocation Offset */ +	unsigned long	reset_status;	/* reset status register at boot	*/ +	unsigned long	env_addr;	/* Address  of Environment struct	*/ +	unsigned long	env_valid;	/* Checksum of Environment valid?	*/ +	unsigned long	have_console;	/* serial_init() was called		*/ +#ifdef CONFIG_BOARD_TYPES +	unsigned long	board_type; +#endif +} gd_t; + +/* + * Global Data Flags + */ +#define	GD_FLG_RELOC	0x00001		/* Code was relocated to RAM		*/ +#define	GD_FLG_DEVINIT	0x00002		/* Devices have been initialized	*/ + +extern gd_t *global_data; +#define DECLARE_GLOBAL_DATA_PTR     gd_t *gd = global_data + +#endif /* __ASM_GBL_DATA_H */ diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h new file mode 100644 index 000000000..79a9626b5 --- /dev/null +++ b/include/asm-m68k/io.h @@ -0,0 +1 @@ +/* */ diff --git a/include/asm-m68k/posix_types.h b/include/asm-m68k/posix_types.h new file mode 100644 index 000000000..4fbc0405f --- /dev/null +++ b/include/asm-m68k/posix_types.h @@ -0,0 +1,109 @@ +#ifndef _M68K_POSIX_TYPES_H +#define _M68K_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc.  Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned int	__kernel_dev_t; +typedef unsigned int	__kernel_ino_t; +typedef unsigned int	__kernel_mode_t; +typedef unsigned short	__kernel_nlink_t; +typedef long		__kernel_off_t; +typedef int		__kernel_pid_t; +typedef unsigned int	__kernel_uid_t; +typedef unsigned int	__kernel_gid_t; +typedef unsigned int	__kernel_size_t; +typedef int		__kernel_ssize_t; +typedef long		__kernel_ptrdiff_t; +typedef long		__kernel_time_t; +typedef long		__kernel_suseconds_t; +typedef long		__kernel_clock_t; +typedef int		__kernel_daddr_t; +typedef char *		__kernel_caddr_t; +typedef short             __kernel_ipc_pid_t; +typedef unsigned short	__kernel_uid16_t; +typedef unsigned short	__kernel_gid16_t; +typedef unsigned int	__kernel_uid32_t; +typedef unsigned int	__kernel_gid32_t; + +typedef unsigned int	__kernel_old_uid_t; +typedef unsigned int	__kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long	__kernel_loff_t; +#endif + +typedef struct { +	int	val[2]; +} __kernel_fsid_t; + +#ifndef __GNUC__ + +#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) +#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) +#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) +#define	__FD_ZERO(set)	\ +  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set))) + +#else /* __GNUC__ */ + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \ +    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) +/* With GNU C, use inline functions instead so args are evaluated only once: */ + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +{ +	unsigned long _tmp = fd / __NFDBITS; +	unsigned long _rem = fd % __NFDBITS; +	fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +{ +	unsigned long _tmp = fd / __NFDBITS; +	unsigned long _rem = fd % __NFDBITS; +	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p) +{ +	unsigned long _tmp = fd / __NFDBITS; +	unsigned long _rem = fd % __NFDBITS; +	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant case (8 ints, + * for a 256-bit fd_set) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *p) +{ +	unsigned int *tmp = (unsigned int *)p->fds_bits; +	int i; + +	if (__builtin_constant_p(__FDSET_LONGS)) { +		switch (__FDSET_LONGS) { +			case 8: +				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0; +				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0; +				return; +		} +	} +	i = __FDSET_LONGS; +	while (i) { +		i--; +		*tmp = 0; +		tmp++; +	} +} + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ +#endif /* __GNUC__ */ +#endif /* _M68K_POSIX_TYPES_H */ diff --git a/include/asm-m68k/ptrace.h b/include/asm-m68k/ptrace.h new file mode 100644 index 000000000..343a9f497 --- /dev/null +++ b/include/asm-m68k/ptrace.h @@ -0,0 +1,108 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +/* + * This struct defines the way the registers are stored on the + * kernel stack during a system call or other kernel entry. + * + * this should only contain volatile regs + * since we can keep non-volatile in the thread_struct + * should set this up when only volatiles are saved + * by intr code. + * + * Since this is going on the stack, *CARE MUST BE TAKEN* to insure + * that the overall structure is a multiple of 16 bytes in length. + * + * Note that the offsets of the fields in this struct correspond with + * the PT_* values below.  This simplifies arch/ppc/kernel/ptrace.c. + */ + +#include <linux/config.h> + +#ifndef __ASSEMBLY__ +#ifdef CONFIG_M68K64BRIDGE +#define M68K_REG unsigned long /*long*/ +#else +#define M68K_REG unsigned long +#endif +struct pt_regs { +	M68K_REG gpr[32]; +	M68K_REG nip; +	M68K_REG msr; +	M68K_REG orig_gpr3;	/* Used for restarting system calls */ +	M68K_REG ctr; +	M68K_REG link; +	M68K_REG xer; +	M68K_REG ccr; +	M68K_REG mq;		/* 601 only (not used at present) */ +				/* Used on APUS to hold IPL value. */ +	M68K_REG trap;		/* Reason for being here */ +	M68K_REG dar;		/* Fault registers */ +	M68K_REG dsisr; +	M68K_REG result; 	/* Result of a system call */ +}; +#endif + +#define STACK_FRAME_OVERHEAD	16	/* size of minimum stack frame */ + +/* Size of stack frame allocated when calling signal handler. */ +#define __SIGNAL_FRAMESIZE	64 + +#define instruction_pointer(regs) ((regs)->nip) +#define user_mode(regs) (((regs)->msr & MSR_PR) != 0) + +/* + * Offsets used by 'ptrace' system call interface. + * These can't be changed without breaking binary compatibility + * with MkLinux, etc. + */ +#define PT_R0	0 +#define PT_R1	1 +#define PT_R2	2 +#define PT_R3	3 +#define PT_R4	4 +#define PT_R5	5 +#define PT_R6	6 +#define PT_R7	7 +#define PT_R8	8 +#define PT_R9	9 +#define PT_R10	10 +#define PT_R11	11 +#define PT_R12	12 +#define PT_R13	13 +#define PT_R14	14 +#define PT_R15	15 +#define PT_R16	16 +#define PT_R17	17 +#define PT_R18	18 +#define PT_R19	19 +#define PT_R20	20 +#define PT_R21	21 +#define PT_R22	22 +#define PT_R23	23 +#define PT_R24	24 +#define PT_R25	25 +#define PT_R26	26 +#define PT_R27	27 +#define PT_R28	28 +#define PT_R29	29 +#define PT_R30	30 +#define PT_R31	31 + +#define PT_NIP	32 +#define PT_MSR	33 +#ifdef __KERNEL__ +#define PT_ORIG_R3 34 +#endif +#define PT_CTR	35 +#define PT_LNK	36 +#define PT_XER	37 +#define PT_CCR	38 +#define PT_MQ	39 + +#define PT_FPR0	48	/* each FP reg occupies 2 slots in this space */ +#define PT_FPR31 (PT_FPR0 + 2*31) +#define PT_FPSCR (PT_FPR0 + 2*32 + 1) + +#endif + diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h new file mode 100644 index 000000000..e0773a882 --- /dev/null +++ b/include/asm-m68k/string.h @@ -0,0 +1,31 @@ +#ifndef _M68K_STRING_H_ +#define _M68K_STRING_H_ + +#if 0 +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRLEN +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRCAT +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_BCOPY +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_MEMCHR +#endif + +extern int strcasecmp(const char *, const char *); +extern int strncasecmp(const char *, const char *, int); +extern char * strcpy(char *,const char *); +extern char * strncpy(char *,const char *, __kernel_size_t); +extern __kernel_size_t strlen(const char *); +extern int strcmp(const char *,const char *); +extern char * strcat(char *, const char *); +extern void * memset(void *,int,__kernel_size_t); +extern void * memcpy(void *,const void *,__kernel_size_t); +extern void * memmove(void *,const void *,__kernel_size_t); +extern int memcmp(const void *,const void *,__kernel_size_t); +extern void * memchr(const void *,int,__kernel_size_t); + +#endif diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h new file mode 100644 index 000000000..e673cb085 --- /dev/null +++ b/include/asm-m68k/types.h @@ -0,0 +1,50 @@ +#ifndef _M68K_TYPES_H +#define _M68K_TYPES_H + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +typedef struct { +	__u32 u[4]; +} __attribute((aligned(16))) vector128; + +#ifdef __KERNEL__ +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* DMA addresses are 32-bits wide */ +typedef u32 dma_addr_t; + +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-m68k/u-boot.h b/include/asm-m68k/u-boot.h new file mode 100644 index 000000000..eaf1de74e --- /dev/null +++ b/include/asm-m68k/u-boot.h @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2000 - 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 __U_BOOT_H__ +#define __U_BOOT_H__ + +/* + * Board information passed to Linux kernel from U-Boot + * + * include/asm-ppc/u-boot.h + */ + +#ifndef __ASSEMBLY__ +#include <linux/types.h> + +typedef struct bd_info { +	unsigned long	bi_memstart;	/* start of DRAM memory */ +	unsigned long	bi_memsize;	/* size	 of DRAM memory in bytes */ +	unsigned long	bi_flashstart;	/* start of FLASH memory */ +	unsigned long	bi_flashsize;	/* size	 of FLASH memory */ +	unsigned long	bi_flashoffset; /* reserved area for startup monitor */ +	unsigned long	bi_sramstart;	/* start of SRAM memory */ +	unsigned long	bi_sramsize;	/* size	 of SRAM memory */ +	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS) */ +        unsigned long   bi_boot_params; /* where this board expects params */ +	unsigned long	bi_ip_addr;	/* IP Address */ +	unsigned char	bi_enetaddr[6];	/* Ethernet adress */ +	unsigned short	bi_ethspeed;	/* Ethernet speed in Mbps */ +	unsigned long	bi_intfreq;	/* Internal Freq, in MHz */ +	unsigned long	bi_busfreq;	/* Bus Freq, in MHz */ +	unsigned long	bi_baudrate;	/* Console Baudrate */ +} bd_t; + +#endif /* __ASSEMBLY__ */ +/* The following data structure is placed in DPRAM to allow for a + * minimum set of global variables during system initialization + * (until we have set up the memory controller so that we can use + * RAM). + * + * Keep it *SMALL* and remember to set CFG_INIT_DATA_SIZE > sizeof(init_data_t) + */ +typedef	struct	init_data { +	unsigned long	cpu_clk;	/* VCOOUT = CPU clock in Hz!		*/ +	unsigned long	env_addr;	/* Address  of Environment struct	*/ +	unsigned long	env_valid;	/* Checksum of Environment valid?	*/ +	unsigned long	relocated;	/* Relocat. offset when running in RAM 	*/ +	unsigned long	have_console;	/* serial_init() was called		*/ +#ifdef CONFIG_LCD +	unsigned long	lcd_base;	/* Base address of LCD frambuffer mem	*/ +#endif +} init_data_t; +#endif	/* __U_BOOT_H__ */ diff --git a/include/configs/M5272C3.h b/include/configs/M5272C3.h new file mode 100644 index 000000000..8d200f318 --- /dev/null +++ b/include/configs/M5272C3.h @@ -0,0 +1,40 @@ +#ifndef _CONFIG_M5272C3_H +#define _CONFIG_M5272C3_H + +#define CONFIG_COMMANDS  ( CONFIG_CMD_DFL & ~(CFG_CMD_LOADS | CFG_CMD_LOADB) ) +#include <cmd_confdefs.h> +#define CONFIG_BOOTDELAY 5 + +#define CFG_MAX_FLASH_SECT 11 +#define CFG_CACHELINE_SIZE 16 +#define CFG_MALLOC_LEN (256 << 10) +#define CFG_INIT_RAM_ADDR 0x20000000 +#define CFG_INIT_RAM_SIZE 0x1000 +#define CFG_INIT_DATA_OFFSET 0 +#define CONFIG_BAUDRATE 19200 +#define CFG_MONITOR_BASE 0x3e0000 +#define CFG_MONITOR_LEN 0x20000 +#define CFG_SDRAM_BASE 0 +#define CFG_FLASH_BASE 0xffe00000 +#define CFG_PROMPT "MCF5272C3> " +#define CFG_CBSIZE 1024 +#define CFG_MAXARGS 64 +#define CFG_LOAD_ADDR 0x20000 +#define CFG_BOOTMAPSZ 0 +#define CFG_BARGSIZE CFG_CBSIZE +#define CFG_BAUDRATE_TABLE { 9600 , 19200 , 38400 , 57600, 115200 } +#define CFG_ENV_ADDR 0xffe04000 +#define CFG_ENV_SIZE 0x2000 +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_PBSIZE 1024 +#define CFG_MAX_FLASH_BANKS 1 +#define CFG_MEMTEST_START 0x400 +#define CFG_MEMTEST_END   0x380000 +#define CFG_HZ 1000000 +#define CFG_FLASH_ERASE_TOUT 10000000 + +#define FEC_ENET + +#define CONFIG_M5272 + +#endif	/* _CONFIG_M5272C3_H */ diff --git a/include/configs/M5282EVB.h b/include/configs/M5282EVB.h new file mode 100644 index 000000000..bbac7d183 --- /dev/null +++ b/include/configs/M5282EVB.h @@ -0,0 +1,40 @@ +#ifndef _CONFIG_M5282EVB_H +#define _CONFIG_M5282EVB_H + +#define CONFIG_COMMANDS  ( CONFIG_CMD_DFL & ~(CFG_CMD_LOADS | CFG_CMD_LOADB) ) +#include <cmd_confdefs.h> +#define CONFIG_BOOTDELAY 5 + +#define CFG_MAX_FLASH_SECT 35 +#define CFG_CACHELINE_SIZE 16 +#define CFG_MALLOC_LEN (256 << 10) +#define CFG_INIT_RAM_ADDR 0x20000000 +#define CFG_INIT_RAM_SIZE 0x1000 +#define CFG_INIT_DATA_OFFSET 0 +#define CONFIG_BAUDRATE 19200 +#define CFG_MONITOR_BASE 0x3e0000 +#define CFG_MONITOR_LEN 0x20000 +#define CFG_SDRAM_BASE 0 +#define CFG_FLASH_BASE 0xffe00000 +#define CFG_PROMPT "M5282EVB> " +#define CFG_CBSIZE 1024 +#define CFG_MAXARGS 64 +#define CFG_LOAD_ADDR 0x20000 +#define CFG_BOOTMAPSZ 0 +#define CFG_BARGSIZE CFG_CBSIZE +#define CFG_BAUDRATE_TABLE { 9600 , 19200 , 38400 , 57600, 115200 } +#define CFG_ENV_ADDR 0xffe04000 +#define CFG_ENV_SIZE 0x2000 +#define CFG_ENV_IS_IN_FLASH 1 +#define CFG_PBSIZE 1024 +#define CFG_MAX_FLASH_BANKS 1 +#define CFG_MEMTEST_START 0x400 +#define CFG_MEMTEST_END   0x380000 +#define CFG_HZ 1000000 +#define CFG_FLASH_ERASE_TOUT 10000000 + +#define FEC_ENET + +#define CONFIG_M5282 + +#endif	/* _CONFIG_M5282EVB_H */ diff --git a/include/flash.h b/include/flash.h index 32f4f4a3b..800fb4dcd 100644 --- a/include/flash.h +++ b/include/flash.h @@ -136,6 +136,8 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);  #define AMD_ID_LV116DT	0xC7		/* 29LV116DT   ( 2 M x 8, top boot sect) */  #define AMD_ID_LV016B	0xc8		/* 29LV016 ID  ( 2 M x 8)		*/ +#define AMD_ID_PL160CB  0x22452245      /* 29PL160CB ID (16 M, bottom boot sect */ +  #define AMD_ID_LV400T	0x22B922B9	/* 29LV400T ID ( 4 M, top boot sector)	*/  #define AMD_ID_LV400B	0x22BA22BA	/* 29LV400B ID ( 4 M, bottom boot sect) */ diff --git a/lib_m68k/board.c b/lib_m68k/board.c new file mode 100644 index 000000000..b4c61195a --- /dev/null +++ b/lib_m68k/board.c @@ -0,0 +1,493 @@ +/* + * (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> +#include <malloc.h> +#include <devices.h> +#include <syscall.h> +#if (CONFIG_COMMANDS & CFG_CMD_IDE) +#include <ide.h> +#endif +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) +#include <scsi.h> +#endif +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#include <kgdb.h> +#endif +#ifdef CONFIG_STATUS_LED +#include <status_led.h> +#endif +#include <net.h> +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +#include <cmd_bedbug.h> +#endif +#ifdef CFG_ALLOC_DPRAM +#include <commproc.h> +#endif +#include <version.h> + +static char *failed = "*** failed ***\n"; + +#ifdef	CONFIG_PCU_E +extern flash_info_t flash_info[]; +#endif + +#if defined(CFG_ENV_IS_IN_FLASH) +# ifndef  CFG_ENV_ADDR +#  define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET) +# endif +# ifndef  CFG_ENV_SIZE +#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE +# endif +# if (CFG_ENV_ADDR >= CFG_MONITOR_BASE) && \ +     (CFG_ENV_ADDR+CFG_ENV_SIZE) < (CFG_MONITOR_BASE + CFG_MONITOR_LEN) +#  define ENV_IS_EMBEDDED +# endif +#endif /* CFG_ENV_IS_IN_FLASH */ +#if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < CFG_MONITOR_BASE) || \ +      (CFG_ENV_ADDR >= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)) ) || \ +    defined(CFG_ENV_IS_IN_NVRAM) +#define	TOTAL_MALLOC_LEN	(CFG_MALLOC_LEN + CFG_ENV_SIZE) +#else +#define	TOTAL_MALLOC_LEN	CFG_MALLOC_LEN +#endif + +/* + * Begin and End of memory area for malloc(), and current "brk" + */ +static ulong mem_malloc_start = 0; +static ulong mem_malloc_end = 0; +static ulong mem_malloc_brk = 0; + +/************************************************************************ + * Utilities								* + ************************************************************************ + */ + +/* + * The Malloc area is immediately below the monitor copy in DRAM + */ +static void mem_malloc_init (ulong dest_addr) +{ +	mem_malloc_end = dest_addr; +	mem_malloc_start = dest_addr - TOTAL_MALLOC_LEN; +	mem_malloc_brk = mem_malloc_start; + +	memset ((void *) mem_malloc_start, 0, +		mem_malloc_end - mem_malloc_start); +} + +void *sbrk (ptrdiff_t increment) +{ +	ulong old = mem_malloc_brk; +	ulong new = old + increment; + +	if ((new < mem_malloc_start) || (new > mem_malloc_end)) { +		return (NULL); +	} +	mem_malloc_brk = new; +	return ((void *) old); +} + +char *strmhz (char *buf, long hz) +{ +	long l, n; +	long m; + +	n = hz / 1000000L; + +	l = sprintf (buf, "%ld", n); + +	m = (hz % 1000000L) / 1000L; + +	if (m != 0) +		sprintf (buf + l, ".%03ld", m); + +	return (buf); +} + +static void syscalls_init (int reloc_off) +{ +	ulong *addr; + +	addr = (ulong *) syscall_tbl; +	syscall_tbl[SYSCALL_MALLOC] = (void *) malloc; +	syscall_tbl[SYSCALL_FREE] = (void *) free; + +	syscall_tbl[SYSCALL_INSTALL_HDLR] = (void *) irq_install_handler; +	syscall_tbl[SYSCALL_FREE_HDLR] = (void *) irq_free_handler; + +	addr = (ulong *) 0xc00;	/* syscall ISR addr */ + +	/* patch ISR code */ +	*addr++ |= (ulong) syscall_tbl >> 16; +	*addr++ |= (ulong) syscall_tbl & 0xFFFF; +	*addr++ |= NR_SYSCALLS >> 16; +	*addr++ |= NR_SYSCALLS & 0xFFFF; +} + +/************************************************************************ + * + * This is the first part of the initialization sequence that is + * implemented in C, but still running from ROM. + * + * The main purpose is to provide a (serial) console interface as + * soon as possible (so we can see any error messages), and to + * initialize the RAM so that we can relocate the monitor code to + * RAM. + * + * Be aware of the restrictions: global data is read-only, BSS is not + * initialized, and stack space is limited to a few kB. + * + ************************************************************************ + */ + + +gd_t *global_data; +static gd_t gdata; +static bd_t bdata; + +void board_init_f (ulong bootflag) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	bd_t *bd; +	ulong reg, len, addr, addr_sp, dram_size; +	int i, baudrate, board_type; +	char *s, *e; +	uchar tmp[64];		/* long enough for environment variables */ + +	/* Pointer to initial global data area */ +	gd = global_data = &gdata; +	bd = gd->bd = &bdata; + +	init_timebase (); +	env_init (); + +	i = getenv_r ("baudrate", tmp, sizeof (tmp)); +	baudrate = +		(i > 0) ? (int) simple_strtoul (tmp, NULL, +						10) : CONFIG_BAUDRATE; +	bd->bi_baudrate = baudrate;	/* Console Baudrate             */ + +	/* set up serial port */ +	serial_init (); + +	/* Initialize the console (before the relocation) */ +	console_init_f (); + +#ifdef DEBUG +	if (sizeof (init_data_t) > CFG_INIT_DATA_SIZE) { +		printf ("PANIC: sizeof(init_data_t)=%d > CFG_INIT_DATA_SIZE=%d\n", sizeof (init_data_t), CFG_INIT_DATA_SIZE); +		hang (); +	} +#endif /* DEBUG */ + +	/* now we can use standard printf/puts/getc/tstc functions */ +	display_options (); + +	puts ("CPU:   ");	/* Check CPU            */ +	if (checkcpu () < 0) { +		puts (failed); +		hang (); +	} + +	puts ("Board: ");	/* Check Board          */ +	if ((board_type = checkboard ()) < 0) { +		puts (failed); +		hang (); +	} + +	puts ("DRAM:  "); +	if ((dram_size = initdram (board_type)) > 0) { +		printf ("%2ld MB\n", dram_size >> 20); +	} else { +		puts (failed); +		hang (); +	} + +#if defined(CFG_DRAM_TEST) +	if (testdram () != 0) { +		hang (); +	} +#endif /* CFG_DRAM_TEST */ + +	/* +	 * Now that we have DRAM mapped and working, we can +	 * relocate the code and continue running from DRAM. +	 * +	 * Reserve memory at end of RAM for (top down in that order): +	 *  - protected RAM +	 *  - LCD framebuffer +	 *  - monitor code +	 *  - board info struct +	 */ +	len = get_endaddr () - CFG_MONITOR_BASE; + +	if (len > CFG_MONITOR_LEN) { +		printf ("*** u-boot size %ld > reserved memory (%d)\n", +			len, CFG_MONITOR_LEN); +		hang (); +	} + +	if (CFG_MONITOR_LEN > len) +		len = CFG_MONITOR_LEN; + +	addr = CFG_SDRAM_BASE + dram_size; +	addr -= len; + +	/* +	 * Save local variables to board info struct +	 */ +	bd->bi_memstart = CFG_SDRAM_BASE;	/* start of  DRAM memory              */ +	bd->bi_memsize = dram_size;	/* size  of  DRAM memory in bytes     */ +	bd->bi_bootflags = bootflag;	/* boot / reboot flag (for LynxOS)    */ + +	i = getenv_r ("ethaddr", tmp, sizeof (tmp)); +	s = (i > 0) ? tmp : NULL; + +	for (reg = 0; reg < 6; ++reg) { +		bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0; +		if (s) +			s = (*e) ? e + 1 : e; +	} + +	bd->bi_intfreq = get_gclk_freq ();	/* Internal Freq, in Hz */ +	bd->bi_busfreq = get_bus_freq (get_gclk_freq ());	/* Bus Freq,      in Hz */ + +#ifdef CFG_EXTBDINFO +	strncpy (bd->bi_s_version, "1.2", sizeof (bd->bi_s_version)); +	strncpy (bd->bi_r_version, PPCBOOT_VERSION, +		 sizeof (bd->bi_r_version)); + +	bd->bi_procfreq = get_gclk_freq ();	/* Processor Speed, In Hz */ +	bd->bi_plb_busfreq = bd->bi_busfreq; +#endif + +	board_init_final (addr); + +} + + +/************************************************************************ + * + * This is the next part if the initialization sequence: we are now + * running from RAM and have a "normal" C environment, i. e. global + * data can be written, BSS has been cleared, the stack size in not + * that critical any more, etc. + * + ************************************************************************ + */ + +void board_init_final (ulong dest_addr) +{ +	DECLARE_GLOBAL_DATA_PTR; +	char *s; +	cmd_tbl_t *cmdtp; +	ulong flash_size; +	bd_t *bd; + +	bd = gd->bd; +	// icache_enable(); /* it's time to enable the instruction cache */ + +	/* +	 * Setup trap handlers +	 */ +	trap_init (dest_addr); + +	puts ("FLASH: "); + +	if ((flash_size = flash_init ()) > 0) { +#ifdef CFG_FLASH_CHECKSUM +		if (flash_size >= (1 << 20)) { +			printf ("%2ld MB", flash_size >> 20); +		} else { +			printf ("%2ld kB", flash_size >> 10); +		} +		/* +		 * Compute and print flash CRC if flashchecksum is set to 'y' +		 * +		 * NOTE: Maybe we should add some WATCHDOG_RESET()?     XXX +		 */ +		s = getenv ("flashchecksum"); +		if (s && (*s == 'y')) { +			printf ("  CRC: %08lX", +				crc32 (0, +				       (const unsigned char *) CFG_FLASH_BASE, +				       flash_size) +				); +		} +		putc ('\n'); +#else +		if (flash_size >= (1 << 20)) { +			printf ("%2ld MB\n", flash_size >> 20); +		} else { +			printf ("%2ld kB\n", flash_size >> 10); +		} +#endif /* CFG_FLASH_CHECKSUM */ +	} else { +		puts (failed); +		hang (); +	} + +	bd->bi_flashstart = CFG_FLASH_BASE;	/* update start of FLASH memory        */ +	bd->bi_flashsize = flash_size;	/* size of FLASH memory (final value)     */ +	bd->bi_flashoffset = 0x10000;	/* reserved area for startup monitor  */ + +	WATCHDOG_RESET (); + +	/* initialize higher level parts of CPU like time base and timers */ +	cpu_init_r (); + +	WATCHDOG_RESET (); + +	/* initialize malloc() area */ +	mem_malloc_init (dest_addr); + +#ifdef CONFIG_SPI +# if !defined(CFG_ENV_IS_IN_EEPROM) +	spi_init_f (); +# endif +	spi_init_r (); +#endif + +	/* relocate environment function pointers etc. */ +	env_relocate (); + +	/* IP Address */ +	bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); + +	WATCHDOG_RESET (); + +	/* allocate syscalls table (console_init_r will fill it in */ +	syscall_tbl = (void **) malloc (NR_SYSCALLS * sizeof (void *)); + +	/* Initialize the console (after the relocation and devices init) */ + + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && ( \ +    defined(CONFIG_CCM)		|| \ +    defined(CONFIG_EP8260)	|| \ +    defined(CONFIG_IP860)	|| \ +    defined(CONFIG_IVML24)	|| \ +    defined(CONFIG_IVMS8)	|| \ +    defined(CONFIG_LWMON)	|| \ +    defined(CONFIG_MPC8260ADS)	|| \ +    defined(CONFIG_PCU_E)	|| \ +    defined(CONFIG_RPXSUPER)	|| \ +    defined(CONFIG_SPD823TS)	) + +	WATCHDOG_RESET (); +# ifdef DEBUG +	puts ("Reset Ethernet PHY\n"); +# endif +	reset_phy (); +#endif + + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	WATCHDOG_RESET (); +	puts ("KGDB:  "); +	kgdb_init (); +#endif + +	/* +	 * Enable Interrupts +	 */ +	interrupt_init (); +	udelay (20); +	set_timer (0); + +	/* Insert function pointers now that we have relocated the code */ + +	/* Initialize from environment */ +	if ((s = getenv ("loadaddr")) != NULL) { +		load_addr = simple_strtoul (s, NULL, 16); +	} +#if (CONFIG_COMMANDS & CFG_CMD_NET) +	if ((s = getenv ("bootfile")) != NULL) { +		copy_filename (BootFile, s, sizeof (BootFile)); +	} +#endif /* CFG_CMD_NET */ + +	WATCHDOG_RESET (); + +#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) +	WATCHDOG_RESET (); +	puts ("Net:   "); +	eth_initialize (bd); +#endif + +#ifdef CONFIG_LAST_STAGE_INIT +	WATCHDOG_RESET (); +	/* +	 * Some parts can be only initialized if all others (like +	 * Interrupts) are up and running (i.e. the PC-style ISA +	 * keyboard). +	 */ +	last_stage_init (); +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +	WATCHDOG_RESET (); +	bedbug_init (); +#endif + +#ifdef CONFIG_PRAM +	/* +	 * Export available size of memory for Linux, +	 * taking into account the protected RAM at top of memory +	 */ +	{ +		ulong pram; +		char *s; +		uchar memsz[32]; + +		if ((s = getenv ("pram")) != NULL) { +			pram = simple_strtoul (s, NULL, 10); +		} else { +			pram = CONFIG_PRAM; +		} +		sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram); +		setenv ("mem", memsz); +	} +#endif + +	/* Initialization complete - start the monitor */ + +	/* main_loop() can return to retry autoboot, if so just run it again. */ +	for (;;) { +		WATCHDOG_RESET (); +		main_loop (); +	} + +	/* NOTREACHED - no way out of command loop except booting */ +} + +void hang (void) +{ +	puts ("### ERROR ### Please RESET the board ###\n"); +	for (;;); +} diff --git a/lib_m68k/extable.c b/lib_m68k/extable.c new file mode 100644 index 000000000..afbc1ebb8 --- /dev/null +++ b/lib_m68k/extable.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> + * + * (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> + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue.  No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path.  This means when everything is well, + * we don't even have to jump over them.  Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry { +	unsigned long insn, fixup; +}; + +extern const struct exception_table_entry __start___ex_table[]; +extern const struct exception_table_entry __stop___ex_table[]; + +static inline unsigned long +search_one_table (const struct exception_table_entry *first, +		  const struct exception_table_entry *last, +		  unsigned long value) +{ +	while (first <= last) { +		const struct exception_table_entry *mid; +		long diff; + +		mid = (last - first) / 2 + first; +		diff = mid->insn - value; +		if (diff == 0) +			return mid->fixup; +		else if (diff < 0) +			first = mid + 1; +		else +			last = mid - 1; +	} +	return 0; +} + +int ex_tab_message = 1; + +unsigned long search_exception_table (unsigned long addr) +{ +	unsigned long ret; + +	/* There is only the kernel to search.  */ +	ret = search_one_table (__start___ex_table, __stop___ex_table - 1, +				addr); +	if (ex_tab_message) +		printf ("Bus Fault @ 0x%08lx, fixup 0x%08lx\n", addr, ret); +	if (ret) +		return ret; + +	return 0; +} diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c new file mode 100644 index 000000000..b20393d01 --- /dev/null +++ b/lib_m68k/m68k_linux.c @@ -0,0 +1,274 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <common.h> +#include <command.h> +#include <cmd_boot.h> +#include <image.h> +#include <zlib.h> +#include <asm/byteorder.h> + +#define PHYSADDR(x) x + +#define	LINUX_MAX_ENVS		256 +#define	LINUX_MAX_ARGS		256 + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include <status_led.h> +# define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +extern image_header_t header;	/* from cmd_bootm.c */ + +static int linux_argc; +static char **linux_argv; + +static char **linux_env; +static char *linux_env_p; +static int linux_env_idx; + +static void linux_params_init (ulong start, char *commandline); +static void linux_env_set (char *env_name, char *env_val); + + +void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], +		     ulong addr, ulong * len_ptr, int verify) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	ulong len = 0, checksum; +	ulong initrd_start, initrd_end; +	ulong data; +	void (*theKernel) (int, char **, char **, int *); +	image_header_t *hdr = &header; +	char *commandline = getenv ("bootargs"); +	char env_buf[12]; + +	theKernel = +		(void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep); + +	/* +	 * Check if there is an initrd image +	 */ +	if (argc >= 3) { +		SHOW_BOOT_PROGRESS (9); + +		addr = simple_strtoul (argv[2], NULL, 16); + +		printf ("## Loading Ramdisk Image at %08lx ...\n", addr); + +		/* Copy header so we can blank CRC field for re-calculation */ +		memcpy (&header, (char *) addr, sizeof (image_header_t)); + +		if (ntohl (hdr->ih_magic) != IH_MAGIC) { +			printf ("Bad Magic Number\n"); +			SHOW_BOOT_PROGRESS (-10); +			do_reset (cmdtp, flag, argc, argv); +		} + +		data = (ulong) & header; +		len = sizeof (image_header_t); + +		checksum = ntohl (hdr->ih_hcrc); +		hdr->ih_hcrc = 0; + +		if (crc32 (0, (char *) data, len) != checksum) { +			printf ("Bad Header Checksum\n"); +			SHOW_BOOT_PROGRESS (-11); +			do_reset (cmdtp, flag, argc, argv); +		} + +		SHOW_BOOT_PROGRESS (10); + +		print_image_hdr (hdr); + +		data = addr + sizeof (image_header_t); +		len = ntohl (hdr->ih_size); + +		if (verify) { +			ulong csum = 0; + +			printf ("   Verifying Checksum ... "); +			csum = crc32 (0, (char *) data, len); +			if (csum != ntohl (hdr->ih_dcrc)) { +				printf ("Bad Data CRC\n"); +				SHOW_BOOT_PROGRESS (-12); +				do_reset (cmdtp, flag, argc, argv); +			} +			printf ("OK\n"); +		} + +		SHOW_BOOT_PROGRESS (11); + +		if ((hdr->ih_os != IH_OS_LINUX) || +		    (hdr->ih_arch != IH_CPU_MIPS) || +		    (hdr->ih_type != IH_TYPE_RAMDISK)) { +			printf ("No Linux MIPS Ramdisk Image\n"); +			SHOW_BOOT_PROGRESS (-13); +			do_reset (cmdtp, flag, argc, argv); +		} + +		/* +		 * Now check if we have a multifile image +		 */ +	} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { +		ulong tail = ntohl (len_ptr[0]) % 4; +		int i; + +		SHOW_BOOT_PROGRESS (13); + +		/* skip kernel length and terminator */ +		data = (ulong) (&len_ptr[2]); +		/* skip any additional image length fields */ +		for (i = 1; len_ptr[i]; ++i) +			data += 4; +		/* add kernel length, and align */ +		data += ntohl (len_ptr[0]); +		if (tail) { +			data += 4 - tail; +		} + +		len = ntohl (len_ptr[1]); + +	} else { +		/* +		 * no initrd image +		 */ +		SHOW_BOOT_PROGRESS (14); + +		data = 0; +	} + +#ifdef	DEBUG +	if (!data) { +		printf ("No initrd\n"); +	} +#endif + +	if (data) { +		initrd_start = data; +		initrd_end = initrd_start + len; +	} else { +		initrd_start = 0; +		initrd_end = 0; +	} + +	SHOW_BOOT_PROGRESS (15); + +#ifdef DEBUG +	printf ("## Transferring control to Linux (at address %08lx) ...\n", +		(ulong) theKernel); +#endif + +	linux_params_init (PHYSADDR (gd->bd->bi_boot_params), commandline); + +	sprintf (env_buf, "%lu", gd->ram_size >> 20); +	linux_env_set ("memsize", env_buf); + +	sprintf (env_buf, "0x%08X", (uint) PHYSADDR (initrd_start)); +	linux_env_set ("initrd_start", env_buf); + +	sprintf (env_buf, "0x%X", (uint) (initrd_end - initrd_start)); +	linux_env_set ("initrd_size", env_buf); + +	sprintf (env_buf, "0x%08X", (uint) (gd->bd->bi_flashstart)); +	linux_env_set ("flash_start", env_buf); + +	sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize)); +	linux_env_set ("flash_size", env_buf); + +	/* we assume that the kernel is in place */ +	printf ("\nStarting kernel ...\n\n"); + +	theKernel (linux_argc, linux_argv, linux_env, 0); +} + +static void linux_params_init (ulong start, char *line) +{ +	char *next, *quote, *argp; + +	linux_argc = 1; +	linux_argv = (char **) start; +	linux_argv[0] = 0; +	argp = (char *) (linux_argv + LINUX_MAX_ARGS); + +	next = line; + +	while (line && *line && linux_argc < LINUX_MAX_ARGS) { +		quote = strchr (line, '"'); +		next = strchr (line, ' '); + +		while (next != NULL && quote != NULL && quote < next) { +			/* we found a left quote before the next blank +			 * now we have to find the matching right quote +			 */ +			next = strchr (quote + 1, '"'); +			if (next != NULL) { +				quote = strchr (next + 1, '"'); +				next = strchr (next + 1, ' '); +			} +		} + +		if (next == NULL) { +			next = line + strlen (line); +		} + +		linux_argv[linux_argc] = argp; +		memcpy (argp, line, next - line); +		argp[next - line] = 0; + +		argp += next - line + 1; +		linux_argc++; + +		if (*next) +			next++; + +		line = next; +	} + +	linux_env = (char **) (((ulong) argp + 15) & ~15); +	linux_env[0] = 0; +	linux_env_p = (char *) (linux_env + LINUX_MAX_ENVS); +	linux_env_idx = 0; +} + +static void linux_env_set (char *env_name, char *env_val) +{ +	if (linux_env_idx < LINUX_MAX_ENVS - 1) { +		linux_env[linux_env_idx] = linux_env_p; + +		strcpy (linux_env_p, env_name); +		linux_env_p += strlen (env_name); + +		strcpy (linux_env_p, "="); +		linux_env_p += 1; + +		strcpy (linux_env_p, env_val); +		linux_env_p += strlen (env_val); + +		linux_env_p++; +		linux_env[++linux_env_idx] = 0; +	} +} diff --git a/lib_m68k/time.c b/lib_m68k/time.c new file mode 100644 index 000000000..5fc275121 --- /dev/null +++ b/lib_m68k/time.c @@ -0,0 +1,87 @@ +/* + * (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> + + +/* ------------------------------------------------------------------------- */ + +/* + * This function is intended for SHORT delays only. + * It will overflow at around 10 seconds @ 400MHz, + * or 20 seconds @ 200MHz. + */ +unsigned long usec2ticks(unsigned long usec) +{ +	ulong ticks; + +	if (usec < 1000) { +		ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; +	} else { +		ticks = ((usec / 10) * (get_tbclk() / 100000)); +	} + +	return (ticks); +} + +/* ------------------------------------------------------------------------- */ + +/* + * We implement the delay by converting the delay (the number of + * microseconds to wait) into a number of time base ticks; then we + * watch the time base until it has incremented by that amount. + */ +void udelay(unsigned long usec) +{ +	ulong ticks = usec2ticks (usec); + +	wait_ticks (ticks); +} + +/* ------------------------------------------------------------------------- */ + +unsigned long ticks2usec(unsigned long ticks) +{ +	ulong tbclk = get_tbclk(); + +	/* usec = ticks * 1000000 / tbclk +	 * Multiplication would overflow at ~4.2e3 ticks, +	 * so we break it up into +	 * usec = ( ( ticks * 1000) / tbclk ) * 1000; +	 */ +	ticks *= 1000L; +	ticks /= tbclk; +	ticks *= 1000L; + +	return ((ulong)ticks); +} + +/* ------------------------------------------------------------------------- */ + +int init_timebase (void) +{ +	/* FIXME!! */ +	return 0; +} + +/* ------------------------------------------------------------------------- */ diff --git a/m68k_config.mk b/m68k_config.mk new file mode 100644 index 000000000..12bd27cb7 --- /dev/null +++ b/m68k_config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2000-2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_CPPFLAGS += -DCONFIG_M68K -D__M68K__ +PLATFORM_LDFLAGS  += -n |