From 4e5ca3eb670460cd5ad9b07fa4aafc0dee6178be Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 8 Dec 2003 01:34:36 +0000 Subject: * Patch by Bernhard Kuhn, 28 Nov 2003: add support for Coldfire CPU add support for Motorola M5272C3 and M5282EVB boards --- CHANGELOG | 4 + CREDITS | 4 + Makefile | 16 ++ board/m5272c3/Makefile | 40 ++++ board/m5272c3/config.mk | 25 ++ board/m5272c3/flash.c | 378 ++++++++++++++++++++++++++++++ board/m5272c3/m5272c3.c | 35 +++ board/m5272c3/u-boot.lds | 135 +++++++++++ board/m5272c3/u-boot.lds.debug | 130 +++++++++++ board/m5282evb/Makefile | 40 ++++ board/m5282evb/config.mk | 25 ++ board/m5282evb/flash.c | 378 ++++++++++++++++++++++++++++++ board/m5282evb/m5282evb.c | 35 +++ board/m5282evb/u-boot.lds | 135 +++++++++++ board/m5282evb/u-boot.lds.debug | 130 +++++++++++ common/cmd_bootm.c | 2 + cpu/coldfire/Makefile | 45 ++++ cpu/coldfire/config.mk | 26 +++ cpu/coldfire/cpu.c | 87 +++++++ cpu/coldfire/fec.c | 300 ++++++++++++++++++++++++ cpu/coldfire/fec.h | 28 +++ cpu/coldfire/interrupts.c | 127 +++++++++++ cpu/coldfire/serial.c | 168 ++++++++++++++ cpu/coldfire/speed.c | 35 +++ cpu/coldfire/start.S | 165 ++++++++++++++ examples/Makefile | 5 + include/asm-m68k/global_data.h | 62 +++++ include/asm-m68k/io.h | 1 + include/asm-m68k/posix_types.h | 109 +++++++++ include/asm-m68k/ptrace.h | 108 +++++++++ include/asm-m68k/string.h | 31 +++ include/asm-m68k/types.h | 50 ++++ include/asm-m68k/u-boot.h | 69 ++++++ include/configs/M5272C3.h | 40 ++++ include/configs/M5282EVB.h | 40 ++++ include/flash.h | 2 + lib_m68k/board.c | 493 ++++++++++++++++++++++++++++++++++++++++ lib_m68k/extable.c | 83 +++++++ lib_m68k/m68k_linux.c | 274 ++++++++++++++++++++++ lib_m68k/time.c | 87 +++++++ m68k_config.mk | 25 ++ 41 files changed, 3972 insertions(+) create mode 100644 board/m5272c3/Makefile create mode 100644 board/m5272c3/config.mk create mode 100644 board/m5272c3/flash.c create mode 100644 board/m5272c3/m5272c3.c create mode 100644 board/m5272c3/u-boot.lds create mode 100644 board/m5272c3/u-boot.lds.debug create mode 100644 board/m5282evb/Makefile create mode 100644 board/m5282evb/config.mk create mode 100644 board/m5282evb/flash.c create mode 100644 board/m5282evb/m5282evb.c create mode 100644 board/m5282evb/u-boot.lds create mode 100644 board/m5282evb/u-boot.lds.debug create mode 100644 cpu/coldfire/Makefile create mode 100644 cpu/coldfire/config.mk create mode 100644 cpu/coldfire/cpu.c create mode 100644 cpu/coldfire/fec.c create mode 100644 cpu/coldfire/fec.h create mode 100644 cpu/coldfire/interrupts.c create mode 100644 cpu/coldfire/serial.c create mode 100644 cpu/coldfire/speed.c create mode 100644 cpu/coldfire/start.S create mode 100644 include/asm-m68k/global_data.h create mode 100644 include/asm-m68k/io.h create mode 100644 include/asm-m68k/posix_types.h create mode 100644 include/asm-m68k/ptrace.h create mode 100644 include/asm-m68k/string.h create mode 100644 include/asm-m68k/types.h create mode 100644 include/asm-m68k/u-boot.h create mode 100644 include/configs/M5272C3.h create mode 100644 include/configs/M5282EVB.h create mode 100644 lib_m68k/board.c create mode 100644 lib_m68k/extable.c create mode 100644 lib_m68k/m68k_linux.c create mode 100644 lib_m68k/time.c create mode 100644 m68k_config.mk diff --git a/CHANGELOG b/CHANGELOG index 9d1d84bb17..c30172b65e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/CREDITS b/CREDITS index 961d442321..0b0086d6cc 100644 --- a/CREDITS +++ b/CREDITS @@ -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 diff --git a/Makefile b/Makefile index 5defc8772d..6af2665307 100644 --- a/Makefile +++ b/Makefile @@ -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 0000000000..378428e31f --- /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 0000000000..e0cd8dafa8 --- /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 +# +# 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 0000000000..fb918435c8 --- /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 + +#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 0000000000..91ec9a12d7 --- /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 + +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 0000000000..0d3829ab2c --- /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 0000000000..cb2a729fef --- /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 0000000000..378428e31f --- /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 0000000000..e0cd8dafa8 --- /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 +# +# 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 0000000000..ff70783bda --- /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 + +#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 0000000000..a08af68ae3 --- /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 + +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 0000000000..0d3829ab2c --- /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 0000000000..cb2a729fef --- /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 78d4612c88..5e31400c9e 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 0000000000..085d840c0f --- /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 0000000000..72b33cea21 --- /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 0000000000..5ce0639909 --- /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 +#include +#include +#ifdef CONFIG_M5272 +#include +#endif +#ifdef CONFIG_M5282 +#include +#endif +#include + +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 0000000000..53a93c1ceb --- /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 +#include +#include +#include + + + +/************************************************************** + * + * 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) { + 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) { + 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 0000000000..a49417c666 --- /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 0000000000..3861ff1019 --- /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 +#include +#ifdef CONFIG_M5272 +#include +#endif +#ifdef CONFIG_M5282 +#include +#endif +#include +#include +#include + +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 0000000000..a140fe3dba --- /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 +#include +#include + +#ifdef CONFIG_M5272 +#include +#endif +#ifdef CONFIG_M5282 +#include +#endif +#include + +#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 0000000000..0fe0925d10 --- /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 +#include + +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 0000000000..7e02661e0a --- /dev/null +++ b/cpu/coldfire/start.S @@ -0,0 +1,165 @@ +/* + * Copyright (C) 1998 Dan Malek + * Copyright (C) 1999 Magnus Damm + * Copyright (C) 2000-2003 Wolfgang Denk + * Coldfire contribution by Bernhard Kuhn + * + * 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 +#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 1e40c829ee..7a7739f6d8 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 0000000000..89bc0ad3fa --- /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 0000000000..79a9626b55 --- /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 0000000000..4fbc0405f7 --- /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 0000000000..343a9f497d --- /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 + +#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 0000000000..e0773a8828 --- /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 0000000000..e673cb085d --- /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 0000000000..eaf1de74e6 --- /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 + +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 0000000000..8d200f3181 --- /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 +#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 0000000000..bbac7d1833 --- /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 +#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 32f4f4a3b4..800fb4dcdd 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 0000000000..b4c61195a1 --- /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 +#include +#include +#include +#include +#include +#if (CONFIG_COMMANDS & CFG_CMD_IDE) +#include +#endif +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) +#include +#endif +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#include +#endif +#ifdef CONFIG_STATUS_LED +#include +#endif +#include +#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +#include +#endif +#ifdef CFG_ALLOC_DPRAM +#include +#endif +#include + +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 0000000000..afbc1ebb85 --- /dev/null +++ b/lib_m68k/extable.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 1999 Magnus Damm + * + * (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 + +/* + * 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 0000000000..b20393d011 --- /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 +#include +#include +#include +#include +#include + +#define PHYSADDR(x) x + +#define LINUX_MAX_ENVS 256 +#define LINUX_MAX_ARGS 256 + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +# 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 0000000000..5fc2751216 --- /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 + + +/* ------------------------------------------------------------------------- */ + +/* + * 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 0000000000..12bd27cb77 --- /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 -- cgit v1.2.3