* Patch by Martin Winistoerfer, 23 Mar 2003

- Add port to MPC555/556 microcontrollers
  - Add support for cmi customer board with
    Intel 28F128J3A, 28F320J3A or 28F640J3A flash.

* Patch by Rick Bronson, 28 Mar 2003:
  - fix common/cmd_nand.c
This commit is contained in:
wdenk 2003-03-31 17:27:09 +00:00
parent 85ec0bcc1b
commit 0db5bca807
38 changed files with 3971 additions and 146 deletions

View File

@ -2,6 +2,14 @@
Changes since U-Boot 0.2.2:
======================================================================
* Patch by Martin Winistoerfer, 23 Mar 2003
- Add port to MPC555/556 microcontrollers
- Add support for cmi customer board with
Intel 28F128J3A, 28F320J3A or 28F640J3A flash.
* Patch by Rick Bronson, 28 Mar 2003:
- fix common/cmd_nand.c
* Patch by Arun Dharankar, 24 Mar 2003:
- add threads / scheduler example code

View File

@ -266,6 +266,10 @@ N: David Updegraff
E: dave@cray.com
D: Port to Cray L1 board; DHCP vendor extensions
N: Martin Winistoerfer
E: martinwinistoerfer@gmx.ch
D: Port to MPC555/556 microcontrollers and support for cmi board
N: Christian Vejlbo
E: christian.vejlbo@tellabs.com
D: FADS860T ethernet support

16
MAKEALL
View File

@ -10,6 +10,14 @@ fi
LIST=""
#########################################################################
## MPC5xx Systems
#########################################################################
LIST_5xx=" \
cmi_mpc5xx \
"
#########################################################################
## MPC8xx Systems
#########################################################################
@ -77,8 +85,10 @@ LIST_7xx=" \
BAB7xx ELPPC \
"
LIST_ppc="${LIST_8xx} ${LIST_824x} ${LIST_8260} \
${LIST_4xx} ${LIST_74xx} ${LIST_7xx}"
LIST_ppc="${LIST_5xx} ${LIST_8xx} \
${LIST_824x} ${LIST_8260} \
${LIST_4xx} \
${LIST_74xx} ${LIST_7xx}"
#########################################################################
## StrongARM Systems
@ -136,7 +146,7 @@ build_target() {
for arg in $@
do
case "$arg" in
8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale|mips)
5xx|8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|xscale|mips)
for target in `eval echo '$LIST_'${arg}`
do
build_target ${target}

View File

@ -168,6 +168,14 @@ unconfig:
#========================================================================
# PowerPC
#========================================================================
#########################################################################
## MPC5xx Systems
#########################################################################
cmi_mpc5xx_config: unconfig
@./mkconfig $(@:_config=) ppc mpc5xx cmi
#########################################################################
## MPC8xx Systems
#########################################################################
@ -621,6 +629,7 @@ BAB7xx_config: unconfig
ELPPC_config: unconfig
@./mkconfig $(@:_config=) ppc 74xx_7xx elppc eltec
#========================================================================
# ARM
#========================================================================

7
README
View File

@ -140,6 +140,7 @@ Directory Hierarchy:
- tools Tools to build S-Record or U-Boot images, etc.
- cpu/74xx_7xx Files specific to Motorola MPC74xx and 7xx CPUs
- cpu/mpc5xx Files specific to Motorola MPC5xx CPUs
- cpu/mpc8xx Files specific to Motorola MPC8xx CPUs
- cpu/mpc824x Files specific to Motorola MPC824x CPUs
- cpu/mpc8260 Files specific to Motorola MPC8260 CPU
@ -151,6 +152,7 @@ Directory Hierarchy:
Files specific to RPXClassic boards
- board/RPXlite Files specific to RPXlite boards
- board/c2mon Files specific to c2mon boards
- board/cmi Files specific to cmi boards
- board/cogent Files specific to Cogent boards
(need further configuration)
Files specific to CPCIISER4 boards
@ -292,6 +294,7 @@ The following options need to be configured:
PowerPC based CPUs:
-------------------
CONFIG_MPC823, CONFIG_MPC850, CONFIG_MPC855, CONFIG_MPC860
or CONFIG_MPC5xx
or CONFIG_MPC824X, CONFIG_MPC8260
or CONFIG_IOP480
or CONFIG_405GP
@ -340,7 +343,7 @@ The following options need to be configured:
CONFIG_GTH, CONFIG_RPXClassic, CONFIG_rsdproto,
CONFIG_IAD210, CONFIG_RPXlite, CONFIG_sbc8260,
CONFIG_EBONY, CONFIG_sacsng, CONFIG_FPS860L,
CONFIG_V37, CONFIG_ELPT860
CONFIG_V37, CONFIG_ELPT860, CONFIG_CMI
ARM based boards:
-----------------
@ -1716,7 +1719,7 @@ configurations; the following names are supported:
FPS850L_config Sandpoint8240_config sbc8260_config
GENIETV_config TQM823L_config PIP405_config
GEN860T_config EBONY_config FPS860L_config
ELPT860_config
ELPT860_config cmi_mpc5xx_config
Note: for some board special configuration names may exist; check if
additional information is available from the board vendor; for

47
board/cmi/Makefile Normal file
View File

@ -0,0 +1,47 @@
#
# (C) Copyright 2001 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 := flash.o cmi.o
SOBJS :=
$(LIB): $(OBJS)
$(AR) crv $@ $^
clean:
rm -f $(SOBJS) $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-include .depend
#########################################################################

73
board/cmi/cmi.c Normal file
View File

@ -0,0 +1,73 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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
*/
/*
* File: cmi.c
*
* Discription: For generic board specific functions
*
*/
#include <common.h>
#include <mpc5xx.h>
#define SRAM_SIZE 1024000L /* 1M RAM available*/
#if defined(__APPLE__)
/* Leading underscore on symbols */
# define SYM_CHAR "_"
#else /* No leading character on symbols */
# define SYM_CHAR
#endif
/*
* Macros to generate global absolutes.
*/
#define GEN_SYMNAME(str) SYM_CHAR #str
#define GEN_VALUE(str) #str
#define GEN_ABS(name, value) \
asm (".globl " GEN_SYMNAME(name)); \
asm (GEN_SYMNAME(name) " = " GEN_VALUE(value))
/*
* Check the board
*/
int checkboard(void)
{
puts ("Board: ### No HW ID - assuming CMI board\n");
return (0);
}
/*
* Get RAM size.
*/
long int initdram(int board_type)
{
return (SRAM_SIZE); /* We currently have a static size adapted for cmi board. */
}
/*
* Absolute environment address for linker file.
*/
GEN_ABS(env_start, CFG_ENV_OFFSET + CFG_FLASH_BASE);

31
board/cmi/config.mk Normal file
View File

@ -0,0 +1,31 @@
#
# (C) Copyright 2003
# Martin Winistoerfer, martinwinistoerfer@gmx.ch.
#
# 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
#
#
# EPQ Board Configuration
#
# Boot from flash at location 0x00000000
TEXT_BASE = 0x02000000
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)

517
board/cmi/flash.c Normal file
View File

@ -0,0 +1,517 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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
*/
/*
* File: flash.c
*
* Discription: This Driver is for 28F320J3A, 28F640J3A and
* 28F128J3A Intel flashs working in 16 Bit mode.
* They are single bank flashs.
*
* Most of this code is taken from existing u-boot
* source code.
*/
#include <common.h>
#include <mpc5xx.h>
#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
# ifndef CFG_ENV_SECT_SIZE
# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
# endif
#endif
#define FLASH_ID_MASK 0xFFFF
#define FLASH_BLOCK_SIZE 0x00010000
#define FLASH_CMD_READ_ID 0x0090
#define FLASH_CMD_RESET 0x00ff
#define FLASH_CMD_BLOCK_ERASE 0x0020
#define FLASH_CMD_ERASE_CONFIRM 0x00D0
#define FLASH_CMD_CLEAR_STATUS 0x0050
#define FLASH_CMD_SUSPEND_ERASE 0x00B0
#define FLASH_CMD_WRITE 0x0040
#define FLASH_CMD_PROTECT 0x0060
#define FLASH_CMD_PROTECT_SET 0x0001
#define FLASH_CMD_PROTECT_CLEAR 0x00D0
#define FLASH_STATUS_DONE 0x0080
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
/*
* Local function prototypes
*/
static ulong flash_get_size (vu_short *addr, flash_info_t *info);
static int write_short (flash_info_t *info, ulong dest, ushort data);
static void flash_get_offsets (ulong base, flash_info_t *info);
/*
* Initialize flash
*/
unsigned long flash_init (void)
{
unsigned long size_b0;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Static FLASH Bank configuration here - FIXME XXX */
#if 1
debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
#endif
size_b0 = flash_get_size((vu_short *)FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0: "
"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
flash_info[0].flash_id,
size_b0, size_b0<<20);
}
flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
flash_info[0].size = size_b0;
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
&flash_info[0]);
#endif
#ifdef CFG_ENV_IS_IN_FLASH
/* ENV protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
&flash_info[0]);
#endif
return size_b0;
}
/*
* Compute start adress of each sector (block)
*/
static void flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL:
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base + i * FLASH_BLOCK_SIZE;
}
return;
default:
printf ("Don't know sector offsets for flash type 0x%lx\n",
info->flash_id);
return;
}
}
/*
* Print flash information
*/
void flash_print_info (flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("Fujitsu "); break;
case FLASH_MAN_SST: printf ("SST "); break;
case FLASH_MAN_STM: printf ("STM "); break;
case FLASH_MAN_INTEL: printf ("Intel "); break;
case FLASH_MAN_MT: printf ("MT "); break;
default: printf ("Unknown Vendor "); break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F320J3A: printf ("28F320J3A (32Mbit) 16-Bit\n");
break;
case FLASH_28F640J3A: printf ("28F640J3A (64Mbit) 16-Bit\n");
break;
case FLASH_28F128J3A: printf ("28F128J3A (128Mbit) 16-Bit\n");
break;
default: printf ("Unknown Chip Type\n");
break;
}
if (info->size >= (1 << 20)) {
i = 20;
} else {
i = 10;
}
printf (" Size: %ld %cB in %d Sectors\n",
info->size >> i,
(i == 20) ? 'M' : 'k',
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");
return;
}
/*
* Get size of flash in bytes.
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (vu_short *addr, flash_info_t *info)
{
vu_short value;
/* Read Manufacturer ID */
addr[0] = FLASH_CMD_READ_ID;
value = addr[0];
switch (value) {
case (AMD_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_AMD;
break;
case (FUJ_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_FUJ;
break;
case (SST_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_SST;
break;
case (STM_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_STM;
break;
case (INTEL_MANUFACT & FLASH_ID_MASK):
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = FLASH_CMD_RESET; /* restore read mode */
return (0); /* no or unknown flash */
}
value = addr[1]; /* device ID */
switch (value) {
case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
info->flash_id += FLASH_28F320J3A;
info->sector_count = 32;
info->size = 0x00400000;
break; /* => 32 MBit */
case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
info->flash_id += FLASH_28F640J3A;
info->sector_count = 64;
info->size = 0x00800000;
break; /* => 64 MBit */
case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 0x01000000;
break; /* => 128 MBit */
default:
info->flash_id = FLASH_UNKNOWN;
addr[0] = FLASH_CMD_RESET; /* restore read mode */
return (0); /* => no or unknown flash */
}
if (info->sector_count > CFG_MAX_FLASH_SECT) {
printf ("** ERROR: sector count %d > max (%d) **\n",
info->sector_count, CFG_MAX_FLASH_SECT);
info->sector_count = CFG_MAX_FLASH_SECT;
}
addr[0] = FLASH_CMD_RESET; /* restore read mode */
return (info->size);
}
/*
* Erase unprotected sectors
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
printf ("Can erase only Intel flash types - aborted\n");
return 1;
}
prot = 0;
for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_short *addr = (vu_short *)(info->start[sect]);
unsigned long status;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
#ifdef DEBUG
printf("Erase sector %d at start addr 0x%08X", sect, (unsigned int)info->start[sect]);
#endif
*addr = FLASH_CMD_CLEAR_STATUS;
*addr = FLASH_CMD_BLOCK_ERASE;
*addr = FLASH_CMD_ERASE_CONFIRM;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* wait at least 80us - let's wait 1 ms */
udelay (1000);
while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE) {
if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf("Flash erase timeout at address %lx\n", info->start[sect]);
*addr = FLASH_CMD_SUSPEND_ERASE;
*addr = FLASH_CMD_RESET;
return 1;
}
/* show that we're waiting */
if ((now - last) > 1000) { /* every second */
putc ('.');
last = now;
}
}
*addr = FLASH_CMD_RESET;
}
}
printf (" done\n");
return 0;
}
/*
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 4 - Flash not identified
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
ulong cp, wp;
ushort data;
int i, rc;
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
wp = (addr & ~1); /* get lower word aligned address */
/*
* handle unaligned start byte
*/
if (addr - wp) {
data = 0;
data = (data << 8) | *src++;
--cnt;
if ((rc = write_short(info, wp, data)) != 0) {
return (rc);
}
wp += 2;
}
/*
* handle word aligned part
*/
while (cnt >= 2) {
data = 0;
for (i=0; i<2; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_short(info, wp, data)) != 0) {
return (rc);
}
wp += 2;
cnt -= 2;
}
if (cnt == 0) {
return (0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i<2; ++i, ++cp) {
data = (data << 8) | (*(uchar *)cp);
}
return (write_short(info, wp, data));
}
/*
* Write 16 bit (short) to flash
*/
static int write_short (flash_info_t *info, ulong dest, ushort data)
{
vu_short *addr = (vu_short*)(info->start[0]);
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*((vu_short *)dest) & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
if (!(info->flash_id & FLASH_VENDMASK)) {
return 4;
}
*addr = FLASH_CMD_ERASE_CONFIRM;
*addr = FLASH_CMD_WRITE;
*((vu_short *)dest) = data;
/* re-enable interrupts if necessary */
if (flag) {
enable_interrupts();
}
/* data polling for D7 */
start = get_timer (0);
/* wait for error or finish */
while(!(addr[0] & FLASH_STATUS_DONE)){
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
addr[0] = FLASH_CMD_RESET;
return (1);
}
}
*addr = FLASH_CMD_RESET;
return (0);
}
/*
* Protects a flash sector
*/
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
vu_short *addr = (vu_short*)(info->start[sector]);
ulong start;
*addr = FLASH_CMD_CLEAR_STATUS;
*addr = FLASH_CMD_PROTECT;
if(prot) {
*addr = FLASH_CMD_PROTECT_SET;
} else {
*addr = FLASH_CMD_PROTECT_CLEAR;
}
/* wait for error or finish */
start = get_timer (0);
while(!(addr[0] & FLASH_STATUS_DONE)){
if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {
printf("Flash protect timeout at address %lx\n", info->start[sector]);
addr[0] = FLASH_CMD_RESET;
return (1);
}
}
/* Set software protect flag */
info->protect[sector] = prot;
*addr = FLASH_CMD_RESET;
return (0);
}

131
board/cmi/u-boot.lds Normal file
View File

@ -0,0 +1,131 @@
/*
* (C) Copyright 2001 Wolfgang Denk, DENX Software Engineering, wd@denx.de
* (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch
*
* 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/mpc5xx/start.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) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
. = env_start;
.ppcenv :
{
common/environment.o (.ppcenv)
}
}

View File

@ -71,7 +71,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
print_num ("flashoffset", bd->bi_flashoffset );
print_num ("sramstart", bd->bi_sramstart );
print_num ("sramsize", bd->bi_sramsize );
#if defined(CONFIG_8xx) || defined(CONFIG_8260)
#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260)
print_num ("immr_base", bd->bi_immr_base );
#endif
print_num ("bootflags", bd->bi_bootflags );

View File

@ -302,7 +302,7 @@ static int nand_rw (struct nand_chip* nand, int cmd,
}
static void nand_print(struct nand_chip *nand)
{
{
printf("%s at 0x%lX,\n"
"\t %d chip%s %s, size %d MB, \n"
"\t total size %ld MB, sector size %ld kB\n",
@ -333,16 +333,17 @@ static void nand_print(struct nand_chip *nand)
/* ------------------------------------------------------------------------- */
/* This function is needed to avoid calls of the __ashrdi3 function. */
#if 0
static int shr(int val, int shift)
{
{
return val >> shift;
}
#endif
static int NanD_WaitReady(struct nand_chip *nand)
{
/* This is inline, to optimise the common case, where it's ready instantly */
int ret = 0;
NAND_WAIT_READY(nand);
NAND_WAIT_READY(nand);
return ret;
}
@ -368,42 +369,42 @@ static inline int NanD_Command(struct nand_chip *nand, unsigned char command)
/* NanD_Address: Set the current address for the flash chip */
static int NanD_Address(struct nand_chip *nand, int numbytes, unsigned long ofs)
{
unsigned long nandptr;
int i;
{
unsigned long nandptr;
int i;
nandptr = nand->IO_ADDR;
nandptr = nand->IO_ADDR;
/* Assert the ALE (Address Latch Enable) line to the flash chip */
NAND_CTL_SETALE(nandptr);
NAND_CTL_SETALE(nandptr);
/* Send the address */
/* Devices with 256-byte page are addressed as:
Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
* there is no device on the market with page256
and more than 24 bits.
Devices with 512-byte page are addressed as:
Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
* 25-31 is sent only if the chip support it.
* bit 8 changes the read command to be sent
(NAND_CMD_READ0 or NAND_CMD_READ1).
/* Send the address */
/* Devices with 256-byte page are addressed as:
* Column (bits 0-7), Page (bits 8-15, 16-23, 24-31)
* there is no device on the market with page256
* and more than 24 bits.
* Devices with 512-byte page are addressed as:
* Column (bits 0-7), Page (bits 9-16, 17-24, 25-31)
* 25-31 is sent only if the chip support it.
* bit 8 changes the read command to be sent
* (NAND_CMD_READ0 or NAND_CMD_READ1).
*/
if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
WRITE_NAND_ADDRESS(ofs, nandptr);
if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE)
WRITE_NAND_ADDRESS(ofs, nandptr);
ofs = ofs >> nand->page_shift;
ofs = ofs >> nand->page_shift;
if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8)
WRITE_NAND_ADDRESS(ofs, nandptr);
if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE)
for (i = 0; i < nand->pageadrlen; i++, ofs = ofs >> 8)
WRITE_NAND_ADDRESS(ofs, nandptr);
/* Lower the ALE line */
NAND_CTL_CLRALE(nandptr);
/* Lower the ALE line */
NAND_CTL_CLRALE(nandptr);
/* Wait for the chip to respond */
return NanD_WaitReady(nand);
}
/* Wait for the chip to respond */
return NanD_WaitReady(nand);
}
/* NanD_SelectChip: Select a given flash chip within the current floor */
@ -419,14 +420,14 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
{
int mfr, id, i;
NAND_ENABLE_CE(nand); /* set pin low */
NAND_ENABLE_CE(nand); /* set pin low */
/* Reset the chip */
if (NanD_Command(nand, NAND_CMD_RESET)) {
#ifdef NAND_DEBUG
printf("NanD_Command (reset) for %d,%d returned true\n",
floor, chip);
#endif
NAND_DISABLE_CE(nand); /* set pin high */
NAND_DISABLE_CE(nand); /* set pin high */
return 0;
}
@ -436,7 +437,7 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
printf("NanD_Command (ReadID) for %d,%d returned true\n",
floor, chip);
#endif
NAND_DISABLE_CE(nand); /* set pin high */
NAND_DISABLE_CE(nand); /* set pin high */
return 0;
}
@ -451,11 +452,10 @@ static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)
NAND_DISABLE_CE(nand); /* set pin high */
/* No response - return failure */
if (mfr == 0xff || mfr == 0)
{
printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
return 0;
}
if (mfr == 0xff || mfr == 0) {
printf("NanD_Command (ReadID) got %d %d\n", mfr, id);
return 0;
}
/* Check it's the same as the first chip we identified.
* M-Systems say that any given nand_chip device should only
@ -578,66 +578,66 @@ static void NanD_ScanChips(struct nand_chip *nand)
nand->numchips, nand->totlen >> 20);
#endif
}
#ifdef CONFIG_MTD_NAND_ECC
/* we need to be fast here, 1 us per read translates to 1 second per meg */
static void nand_fast_copy (unsigned char *source, unsigned char *dest, long cntr)
{
while (cntr > 16)
{
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
cntr -= 16;
}
while (cntr > 0)
{
*dest++ = *source++;
cntr--;
}
}
{
while (cntr > 16) {
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
*dest++ = *source++;
cntr -= 16;
}
while (cntr > 0) {
*dest++ = *source++;
cntr--;
}
}
#endif
/* we need to be fast here, 1 us per read translates to 1 second per meg */
static void nand_fast_read(unsigned char *data_buf, int cntr, unsigned long nandptr)
{
while (cntr > 16)
{
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
cntr -= 16;
}
while (cntr > 0)
{
*data_buf++ = READ_NAND(nandptr);
cntr--;
}
}
{
while (cntr > 16) {
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
*data_buf++ = READ_NAND(nandptr);
cntr -= 16;
}
while (cntr > 0) {
*data_buf++ = READ_NAND(nandptr);
cntr--;
}
}
/* This routine is made available to other mtd code via
* inter_module_register. It must only be accessed through
@ -665,13 +665,14 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
/* Do not allow reads past end of device */
if ((start + len) > nand->totlen) {
printf ("nand_read_ecc: Attempt read beyond end of device %x %x %x\n", (uint) start, (uint) len, (uint) nand->totlen);
printf ("%s: Attempt read beyond end of device %x %x %x\n", __FUNCTION__, (uint) start, (uint) len, (uint) nand->totlen);
*retlen = 0;
return -1;
}
/* First we calculate the starting page */
page = shr(start, nand->page_shift);
/*page = shr(start, nand->page_shift);*/
page = start >> nand->page_shift;
/* Get raw starting column */
col = start & (nand->oobblock - 1);
@ -713,7 +714,7 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
nand_calculate_ecc (&nand->data_buf[0], &ecc_calc[0]);
switch (nand_correct_data (&nand->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
case -1:
printf ("nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
ecc_failed++;
break;
case 1:
@ -729,7 +730,7 @@ static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,
nand_calculate_ecc (&nand->data_buf[256], &ecc_calc[3]);
switch (nand_correct_data (&nand->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
case -1:
printf ("nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
printf ("%s: Failed ECC read, page 0x%08x\n", __FUNCTION__, page);
ecc_failed++;
break;
case 1:
@ -778,7 +779,7 @@ readdata:
}
/* De-select the NAND device */
NAND_DISABLE_CE(nand); /* set pin high */
NAND_DISABLE_CE(nand); /* set pin high */
/*
* Return success, if no ECC failures, else -EIO
@ -788,7 +789,6 @@ readdata:
return ecc_status ? -1 : 0;
}
/*
* Nand_page_program function is used for write and writev !
*/
@ -815,7 +815,7 @@ static int nand_write_page (struct nand_chip *nand,
/* Read back previous written data, if col > 0 */
if (col) {
NanD_Command(nand, NAND_CMD_READ0);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
for (i = 0; i < col; i++)
nand->data_buf[i] = READ_NAND (nandptr);
}
@ -852,15 +852,15 @@ static int nand_write_page (struct nand_chip *nand,
/* Write out complete page of data */
for (i = 0; i < (nand->oobblock + nand->oobsize); i++)
WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
WRITE_NAND(nand->data_buf[i], nand->IO_ADDR);
/* Send command to actually program the data */
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
/* See if device thinks it succeeded */
if (READ_NAND(nand->IO_ADDR) & 0x01) {
printf ("nand_write_ecc: " "Failed write, page 0x%08x, ", page);
printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
return -1;
}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
@ -879,15 +879,15 @@ static int nand_write_page (struct nand_chip *nand,
/* Send command to read back the page */
if (col < nand->eccsize)
NanD_Command(nand, NAND_CMD_READ0);
NanD_Command(nand, NAND_CMD_READ0);
else
NanD_Command(nand, NAND_CMD_READ1);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
NanD_Command(nand, NAND_CMD_READ1);
NanD_Address(nand, ADDR_COLUMN_PAGE, (page << nand->page_shift) + col);
/* Loop through and verify the data */
for (i = col; i < last; i++) {
if (nand->data_buf[i] != readb (nand->IO_ADDR)) {
printf ("nand_write_ecc: " "Failed write verify, page 0x%08x ", page);
printf ("%s: Failed write verify, page 0x%08x ", __FUNCTION__, page);
return -1;
}
}
@ -903,8 +903,8 @@ static int nand_write_page (struct nand_chip *nand,
nand->data_buf[i] = readb (nand->IO_ADDR);
for (i = 0; i < ecc_bytes; i++) {
if ((nand->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
printf ("nand_write_ecc: Failed ECC write "
"verify, page 0x%08x, " "%6i bytes were succesful\n", page, i);
printf ("%s: Failed ECC write "
"verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
return -1;
}
}
@ -912,6 +912,7 @@ static int nand_write_page (struct nand_chip *nand,
#endif
return 0;
}
static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
size_t * retlen, const u_char * buf, u_char * ecc_code)
{
@ -919,7 +920,7 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
/* Do not allow write past end of device */
if ((to + len) > nand->totlen) {
printf ("nand_write_oob: Attempt to write past end of page\n");
printf ("%s: Attempt to write past end of page\n", __FUNCTION__);
return -1;
}
@ -933,12 +934,12 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
*retlen = 0;
/* Select the NAND device */
NAND_ENABLE_CE(nand); /* set pin low */
NAND_ENABLE_CE(nand); /* set pin low */
/* Check the WP bit */
NanD_Command(nand, NAND_CMD_STATUS);
NanD_Command(nand, NAND_CMD_STATUS);
if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
printf ("nand_write_ecc: Device is write protected!!!\n");
printf ("%s: Device is write protected!!!\n", __FUNCTION__);
ret = -1;
goto out;
}
@ -976,7 +977,7 @@ static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,
out:
/* De-select the NAND device */
NAND_DISABLE_CE(nand); /* set pin high */
NAND_DISABLE_CE(nand); /* set pin high */
return ret;
}
@ -1150,6 +1151,7 @@ static int nand_read_oob(struct nand_chip* nand, size_t ofs, size_t len,
int len256 = 0, ret;
unsigned long nandptr;
struct Nand *mychip;
int ret = 0;
nandptr = nand->IO_ADDR;
@ -1287,9 +1289,21 @@ static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len)
goto out;
}
/* Select the NAND device */
NAND_ENABLE_CE(nand); /* set pin low */
/* Check the WP bit */
NanD_Command(nand, NAND_CMD_STATUS);
if (!(READ_NAND(nand->IO_ADDR) & 0x80)) {
printf ("%s: Device is write protected!!!\n", __FUNCTION__);
ret = -1;
goto out;
}
/* FIXME: Do nand in the background. Use timers or schedule_task() */
while(len) {
mychip = &nand->chips[shr(ofs, nand->chipshift)];
/*mychip = &nand->chips[shr(ofs, nand->chipshift)];*/
mychip = &nand->chips[ofs >> nand->chipshift];
NanD_Command(nand, NAND_CMD_ERASE1);
NanD_Address(nand, ADDR_PAGE, ofs);
@ -1298,7 +1312,8 @@ static int nand_erase(struct nand_chip* nand, size_t ofs, size_t len)
NanD_Command(nand, NAND_CMD_STATUS);
if (READ_NAND(nandptr) & 1) {
printf("Error erasing at 0x%lx\n", (long)ofs);
printf ("%s: Error erasing at 0x%lx\n",
__FUNCTION__, (long)ofs);
/* There was an error */
ret = -1;
goto out;
@ -1351,20 +1366,20 @@ void nand_probe(unsigned long physadr)
}
}
if (curr_device == -1)
curr_device = i;
if (curr_device == -1)
curr_device = i;
memset((char *)nand, 0, sizeof(struct nand_chip));
memset((char *)nand, 0, sizeof(struct nand_chip));
nand->cache_page = -1; /* init the cache page */
nand->IO_ADDR = physadr;
nand->ChipID = ChipID;
NanD_ScanChips(nand);
nand->data_buf = malloc (nand->oobblock + nand->oobsize);
if (!nand->data_buf) {
puts ("Cannot allocate memory for data structures.\n");
return;
}
nand->cache_page = -1; /* init the cache page */
nand->IO_ADDR = physadr;
nand->ChipID = ChipID;
NanD_ScanChips(nand);
nand->data_buf = malloc (nand->oobblock + nand->oobsize);
if (!nand->data_buf) {
puts ("Cannot allocate memory for data structures.\n");
return;
}
}
#ifdef CONFIG_MTD_NAND_ECC

View File

@ -28,6 +28,8 @@
#include <mpc8xx.h>
#elif defined (CONFIG_405GP)
#include <asm/processor.h>
#elif defined (CONFIG_5xx)
#include <mpc5xx.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_REGINFO)
@ -172,9 +174,42 @@ mfdcr(dmacr3), mfdcr(dmact3),mfdcr(dmada3), mfdcr(dmasa3), mfdcr(dmasb3) );
mtdcr(ebccfga,pb7ap); printf ("%08x ", mfdcr(ebccfgd));
printf ("\n\n");
#endif /*(CONFIG_405GP)*/
#elif defined(CONFIG_5xx)
volatile immap_t *immap = (immap_t *)CFG_IMMR;
volatile memctl5xx_t *memctl = &immap->im_memctl;
volatile sysconf5xx_t *sysconf = &immap->im_siu_conf;
volatile sit5xx_t *timers = &immap->im_sit;
volatile car5xx_t *car = &immap->im_clkrst;
volatile uimb5xx_t *uimb = &immap->im_uimb;
printf("\nSystem Configuration registers\n");
printf("\tIMMR\t0x%08X\tSIUMCR\t0x%08X \n", get_immr(0), sysconf->sc_siumcr);
printf("\tSYPCR\t0x%08X\tSWSR\t0x%04X \n" ,sysconf->sc_sypcr, sysconf->sc_swsr);
printf("\tSIPEND\t0x%08X\tSIMASK\t0x%08X \n", sysconf->sc_sipend, sysconf->sc_simask);
printf("\tSIEL\t0x%08X\tSIVEC\t0x%08X \n", sysconf->sc_siel, sysconf->sc_sivec);
printf("\tTESR\t0x%08X\n", sysconf->sc_tesr);
printf("\nMemory Controller Registers\n");
printf("\tBR0\t0x%08X\tOR0\t0x%08X \n", memctl->memc_br0, memctl->memc_or0);
printf("\tBR1\t0x%08X\tOR1\t0x%08X \n", memctl->memc_br1, memctl->memc_or1);
printf("\tBR2\t0x%08X\tOR2\t0x%08X \n", memctl->memc_br2, memctl->memc_or2);
printf("\tBR3\t0x%08X\tOR3\t0x%08X \n", memctl->memc_br3, memctl->memc_or3);
printf("\tDMBR\t0x%08X\tDMOR\t0x%08X \n", memctl->memc_dmbr, memctl->memc_dmor );
printf("\tMSTAT\t0x%08X\n", memctl->memc_mstat);
printf("\nSystem Integration Timers\n");
printf("\tTBSCR\t0x%08X\tRTCSC\t0x%08X \n", timers->sit_tbscr, timers->sit_rtcsc);
printf("\tPISCR\t0x%08X \n", timers->sit_piscr);
printf("\nClocks and Reset\n");
printf("\tSCCR\t0x%08X\tPLPRCR\t0x%08X \n", car->car_sccr, car->car_plprcr);
printf("\nU-Bus to IMB3 Bus Interface\n");
printf("\tUMCR\t0x%08X\tUIPEND\t0x%08X \n", uimb->uimb_umcr, uimb->uimb_uipend);
printf ("\n\n");
#endif /* CONFIG_5xx */
return 0;
}
#endif /* CONFIG_8xx && CFG_CMD_REGINFO */
#endif /* CONFIG_COMMANDS & CFG_CMD_REGINFO */

View File

@ -46,7 +46,8 @@
* a seperate section. Note that ENV_CRC is only defined when building
* U-Boot itself.
*/
#if (defined(CONFIG_FADS) || \
#if (defined(CONFIG_CMI) || \
defined(CONFIG_FADS) || \
defined(CONFIG_HYMOD) || \
defined(CONFIG_ICU862) || \
defined(CONFIG_R360MPI) || \

52
cpu/mpc5xx/Makefile Normal file
View File

@ -0,0 +1,52 @@
#
# (C) Copyright 2003
# Martin Winistoerfer, martinwinistoerfer@gmx.ch.
#
# 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
#
#
# File: cpu/mpc5xx/Makefile
#
# Discription: Makefile to build mpc5xx cpu configuration.
# Will include top config.mk which itselfs
# uses the definitions made in cpu/mpc5xx/config.mk
#
include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.S
OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o status_led.o
all: .depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

34
cpu/mpc5xx/config.mk Normal file
View File

@ -0,0 +1,34 @@
#
# (C) Copyright 2003
# Martin Winistoerfer, martinwinistoerfer@gmx.ch.
#
# 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
#
#
# File: config.mk
#
# Discription: compiler flags and make definitions
#
PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14 -meabi
PLATFORM_CPPFLAGS += -DCONFIG_5xx -ffixed-r2 -ffixed-r29 -mpowerpc -msoft-float

155
cpu/mpc5xx/cpu.c Normal file
View File

@ -0,0 +1,155 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: cpu.c
*
* Discription: Some cpu specific function for watchdog,
* cpu version test, clock setting ...
*
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <mpc5xx.h>
#if (defined(CONFIG_MPC555))
# define ID_STR "MPC555/556"
/*
* Check version of cpu with Processor Version Register (PVR)
*/
static int check_cpu_version (long clock, uint pvr, uint immr)
{
char buf[32];
/* The highest 16 bits should be 0x0002 for a MPC555/556 */
if ((pvr >> 16) == 0x0002) {
printf (" " ID_STR " Version %x", (pvr >> 16));
printf (" at %s MHz:", strmhz (buf, clock));
} else {
printf ("Not supported cpu version");
return -1;
}
return 0;
}
#endif /* CONFIG_MPC555 */
/*
* Check version of mpc5xx
*/
int checkcpu (void)
{
DECLARE_GLOBAL_DATA_PTR;
ulong clock = gd->cpu_clk;
uint immr = get_immr (0); /* Return full IMMR contents */
uint pvr = get_pvr (); /* Retrieve PVR register */
puts ("CPU: ");
return check_cpu_version (clock, pvr, immr);
}
/*
* Called by macro WATCHDOG_RESET
*/
#if defined(CONFIG_WATCHDOG)
void watchdog_reset (void)
{
int re_enable = disable_interrupts ();
reset_5xx_watchdog ((immap_t *) CFG_IMMR);
if (re_enable)
enable_interrupts ();
}
/*
* Will clear software reset
*/
void reset_5xx_watchdog (volatile immap_t * immr)
{
/* Use the MPC5xx Internal Watchdog */
immr->im_siu_conf.sc_swsr = 0x556c; /* Prevent SW time-out */
immr->im_siu_conf.sc_swsr = 0xaa39;
}
#endif /* CONFIG_WATCHDOG */
/*
* Get timebase clock frequency
*/
unsigned long get_tbclk (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile immap_t *immr = (volatile immap_t *) CFG_IMMR;
ulong oscclk, factor;
if (immr->im_clkrst.car_sccr & SCCR_TBS) {
return (gd->cpu_clk / 16);
}
factor = (((CFG_PLPRCR) & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT) + 1;
oscclk = gd->cpu_clk / factor;
if ((immr->im_clkrst.car_sccr & SCCR_RTSEL) == 0 || factor > 2) {
return (oscclk / 4);
}
return (oscclk / 16);
}
/*
* Reset board
*/
int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
ulong addr;
/* Interrupts off, enable reset */
__asm__ volatile (" mtspr 81, %r0 \n\t
mfmsr %r3 \n\t
rlwinm %r31,%r3,0,25,23\n\t
mtmsr %r31 \n\t");
/*
* Trying to execute the next instruction at a non-existing address
* should cause a machine check, resulting in reset
*/
#ifdef CFG_RESET_ADDRESS
addr = CFG_RESET_ADDRESS;
#else
/*
* note: when CFG_MONITOR_BASE points to a RAM address, CFG_MONITOR_BASE * - sizeof (ulong) is usually a valid address. Better pick an address
* known to be invalid on your system and assign it to CFG_RESET_ADDRESS.
* "(ulong)-1" used to be a good choice for many systems...
*/
addr = CFG_MONITOR_BASE - sizeof (ulong);
#endif
((void (*) (void)) addr) ();
return 1;
}

119
cpu/mpc5xx/cpu_init.c Normal file
View File

@ -0,0 +1,119 @@
/*
* (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: cpu_init.c
*
* Discription: Contains initialisation functions to setup
* the cpu properly
*
*/
#include <common.h>
#include <mpc5xx.h>
#include <watchdog.h>
/*
* Setup essential cpu registers to run
*/
void cpu_init_f (volatile immap_t * immr)
{
volatile memctl5xx_t *memctl = &immr->im_memctl;
ulong reg;
/* SYPCR - contains watchdog control. This will enable watchdog */
/* if CONFIG_WATCHDOG is set */
immr->im_siu_conf.sc_sypcr = CFG_SYPCR;
#if defined(CONFIG_WATCHDOG)
reset_5xx_watchdog (immr);
#endif
/* SIUMCR - contains debug pin configuration */
immr->im_siu_conf.sc_siumcr |= CFG_SIUMCR;
/* Initialize timebase. Unlock TBSCRK */
immr->im_sitk.sitk_tbscrk = KAPWR_KEY;
immr->im_sit.sit_tbscr = CFG_TBSCR;
/* Full IMB bus speed */
immr->im_uimb.uimb_umcr = CFG_UMCR;
/* Time base and decrementer will be enables (TBE) */
/* in init_timebase() in time.c called from board_init_f(). */
/* Initialize the PIT. Unlock PISCRK */
immr->im_sitk.sitk_piscrk = KAPWR_KEY;
immr->im_sit.sit_piscr = CFG_PISCR;
/* PLL (CPU clock) settings */
immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
/* If CFG_PLPRCR (set in the various *_config.h files) tries to
* set the MF field, then just copy CFG_PLPRCR over car_plprcr,
* otherwise OR in CFG_PLPRCR so we do not change the currentMF
* field value.
*/
#if ((CFG_PLPRCR & PLPRCR_MF_MSK) != 0)
reg = CFG_PLPRCR; /* reset control bits */
#else
reg = immr->im_clkrst.car_plprcr;
reg &= PLPRCR_MF_MSK; /* isolate MF field */
reg |= CFG_PLPRCR; /* reset control bits */
#endif
immr->im_clkrst.car_plprcr = reg;
/* System integration timers. CFG_MASK has EBDF configuration */
immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
reg = immr->im_clkrst.car_sccr;
reg &= SCCR_MASK;
reg |= CFG_SCCR;
immr->im_clkrst.car_sccr = reg;
/* Memory Controller */
memctl->memc_br0 = CFG_BR0_PRELIM;
memctl->memc_or0 = CFG_OR0_PRELIM;
#if (defined(CFG_OR1_PRELIM) && defined(CFG_BR1_PRELIM))
memctl->memc_or1 = CFG_OR1_PRELIM;
memctl->memc_br1 = CFG_BR1_PRELIM;
#endif
#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM)
memctl->memc_or2 = CFG_OR2_PRELIM;
memctl->memc_br2 = CFG_BR2_PRELIM;
#endif
#if defined(CFG_OR3_PRELIM) && defined(CFG_BR3_PRELIM)
memctl->memc_or3 = CFG_OR3_PRELIM;
memctl->memc_br3 = CFG_BR3_PRELIM;
#endif
}
/*
* Initialize higher level parts of cpu
*/
int cpu_init_r (void)
{
/* Nothing to do at the moment */
return (0);
}

273
cpu/mpc5xx/interrupts.c Normal file
View File

@ -0,0 +1,273 @@
/*
* (C) Copyright 2000-2002 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: interrupt.c
*
* Discription: Contains interrupt routines needed by U-Boot
*
*/
#include <common.h>
#include <watchdog.h>
#include <mpc5xx.h>
#include <asm/processor.h>
/************************************************************************/
unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
/************************************************************************/
struct interrupt_action {
interrupt_handler_t *handler;
void *arg;
};
static struct interrupt_action irq_vecs[NR_IRQS];
/*
* Local function prototypes
*/
static __inline__ unsigned long get_msr (void)
{
unsigned long msr;
asm volatile ("mfmsr %0":"=r" (msr):);
return msr;
}
static __inline__ void set_msr (unsigned long msr)
{
asm volatile ("mtmsr %0"::"r" (msr));
}
static __inline__ unsigned long get_dec (void)
{
unsigned long val;
asm volatile ("mfdec %0":"=r" (val):);
return val;
}
static __inline__ void set_dec (unsigned long val)
{
asm volatile ("mtdec %0"::"r" (val));
}
/*
* Enable interrupts
*/
void enable_interrupts (void)
{
set_msr (get_msr () | MSR_EE);
}
/*
* Returns flag if MSR_EE was set before
*/
int disable_interrupts (void)
{
ulong msr = get_msr ();
set_msr (msr & ~MSR_EE);
return ((msr & MSR_EE) != 0);
}
/*
* Initialise interrupts
*/
int interrupt_init (void)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
/* Decrementer used here for status led */
decrementer_count = get_tbclk () / CFG_HZ;
/* Disable all interrupts */
immr->im_siu_conf.sc_simask = 0;
set_dec (decrementer_count);
set_msr (get_msr () | MSR_EE);
return (0);
}
/*
* Handle external interrupts
*/
void external_interrupt (struct pt_regs *regs)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
int irq;
ulong simask, newmask;
ulong vec, v_bit;
/*
* read the SIVEC register and shift the bits down
* to get the irq number
*/
vec = immr->im_siu_conf.sc_sivec;
irq = vec >> 26;
v_bit = 0x80000000UL >> irq;
/*
* Read Interrupt Mask Register and Mask Interrupts
*/
simask = immr->im_siu_conf.sc_simask;
newmask = simask & (~(0xFFFF0000 >> irq));
immr->im_siu_conf.sc_simask = newmask;
if (!(irq & 0x1)) { /* External Interrupt ? */
ulong siel;
/*
* Read Interrupt Edge/Level Register
*/
siel = immr->im_siu_conf.sc_siel;
if (siel & v_bit) { /* edge triggered interrupt ? */
/*
* Rewrite SIPEND Register to clear interrupt
*/
immr->im_siu_conf.sc_sipend = v_bit;
}
}
if (irq_vecs[irq].handler != NULL) {
irq_vecs[irq].handler (irq_vecs[irq].arg);
} else {
printf ("\nBogus External Interrupt IRQ %d Vector %ld\n",
irq, vec);
/* turn off the bogus interrupt to avoid it from now */
simask &= ~v_bit;
}
/*
* Re-Enable old Interrupt Mask
*/
immr->im_siu_conf.sc_simask = simask;
}
/*
* Install and free an interrupt handler
*/
void irq_install_handler (int vec, interrupt_handler_t * handler,
void *arg)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
/* SIU interrupt */
if (irq_vecs[vec].handler != NULL) {
printf ("SIU interrupt %d 0x%x\n",
vec,
(uint) handler);
}
irq_vecs[vec].handler = handler;
irq_vecs[vec].arg = arg;
immr->im_siu_conf.sc_simask |= 1 << (31 - vec);
#if 0
printf ("Install SIU interrupt for vector %d ==> %p\n",
vec, handler);
#endif
}
void irq_free_handler (int vec)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
/* SIU interrupt */
#if 0
printf ("Free CPM interrupt for vector %d\n",
vec);
#endif
immr->im_siu_conf.sc_simask &= ~(1 << (31 - vec));
irq_vecs[vec].handler = NULL;
irq_vecs[vec].arg = NULL;
}
volatile ulong timestamp = 0;
/*
* Timer interrupt - gets called when bit 0 of DEC changes from
* 0. Decrementer is enabled with bit TBE in TBSCR.
*/
void timer_interrupt (struct pt_regs *regs)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
#ifdef CONFIG_STATUS_LED
extern void status_led_tick (ulong);
#endif
#if 0
printf ("*** Timer Interrupt *** ");
#endif
/* Reset Timer Status Bit and Timers Interrupt Status */
immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
__asm__ ("nop");
immr->im_clkrst.car_plprcr |= PLPRCR_TEXPS | PLPRCR_TMIST;
/* Restore Decrementer Count */
set_dec (decrementer_count);
timestamp++;
#ifdef CONFIG_STATUS_LED
status_led_tick (timestamp);
#endif /* CONFIG_STATUS_LED */
#if defined(CONFIG_WATCHDOG)
/*
* The shortest watchdog period of all boards
* is approx. 1 sec, thus re-trigger watchdog at least
* every 500 ms = CFG_HZ / 2
*/
if ((timestamp % (CFG_HZ / 2)) == 0) {
reset_5xx_watchdog (immr);
}
#endif /* CONFIG_WATCHDOG */
}
/*
* Reset timer
*/
void reset_timer (void)
{
timestamp = 0;
}
/*
* Get Timer
*/
ulong get_timer (ulong base)
{
return (timestamp - base);
}
/*
* Set timer
*/
void set_timer (ulong t)
{
timestamp = t;
}

171
cpu/mpc5xx/serial.c Normal file
View File

@ -0,0 +1,171 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: serial.c
*
* Discription: Serial interface driver for SCI1 and SCI2.
* Since this code will be called from ROM use
* only non-static local variables.
*
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <mpc5xx.h>
/*
* Local function prototypes
*/
static int ready_to_send(void);
/*
* Minimal global serial functions needed to use one of the SCI modules.
*/
int serial_init (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
serial_setbrg();
#if defined(CONFIG_5xx_CONS_SCI1)
/* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */
immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10;
immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE;
#else
immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10;
immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE;
#endif
return 0;
}
void serial_putc(const char c)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
/* Test for completition */
if(ready_to_send()) {
#if defined(CONFIG_5xx_CONS_SCI1)
immr->im_qsmcm.qsmcm_sc1dr = (short)c;
#else
immr->im_qsmcm.qsmcm_sc2dr = (short)c;
#endif
if(c == '\n') {
if(ready_to_send());
#if defined(CONFIG_5xx_CONS_SCI1)
immr->im_qsmcm.qsmcm_sc1dr = (short)'\r';
#else
immr->im_qsmcm.qsmcm_sc2dr = (short)'\r';
#endif
}
}
}
int serial_getc(void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
volatile short status;
unsigned char tmp;
/* New data ? */
do {
#if defined(CONFIG_5xx_CONS_SCI1)
status = immr->im_qsmcm.qsmcm_sc1sr;
#else
status = immr->im_qsmcm.qsmcm_sc2sr;
#endif
#if defined(CONFIG_WATCHDOG)
reset_5xx_watchdog (immr);
#endif
} while ((status & SCI_RDRF) == 0);
/* Read data */
#if defined(CONFIG_5xx_CONS_SCI1)
tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK);
#else
tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK);
#endif
return tmp;
}
int serial_tstc()
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
short status;
/* New data character ? */
#if defined(CONFIG_5xx_CONS_SCI1)
status = immr->im_qsmcm.qsmcm_sc1sr;
#else
status = immr->im_qsmcm.qsmcm_sc2sr;
#endif
return (status & SCI_RDRF);
}
void serial_setbrg (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile immap_t *immr = (immap_t *)CFG_IMMR;
short scxbr;
/* Set baudrate */
scxbr = (gd->cpu_clk / (32 * gd->baudrate));
#if defined(CONFIG_5xx_CONS_SCI1)
immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK);
#else
immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK);
#endif
}
void serial_puts (const char *s)
{
while (*s) {
serial_putc(*s);
++s;
}
}
int ready_to_send(void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
volatile short status;
do {
#if defined(CONFIG_5xx_CONS_SCI1)
status = immr->im_qsmcm.qsmcm_sc1sr;
#else
status = immr->im_qsmcm.qsmcm_sc2sr;
#endif
#if defined(CONFIG_WATCHDOG)
reset_5xx_watchdog (immr);
#endif
} while ((status & SCI_TDRE) == 0);
return 1;
}

66
cpu/mpc5xx/speed.c Normal file
View File

@ -0,0 +1,66 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: speed.c
*
* Discription: Provides cpu speed calculation
*
*/
#include <common.h>
#include <mpc5xx.h>
#include <asm/processor.h>
/*
* Get cpu and bus clock
*/
int get_clocks (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile immap_t *immr = (immap_t *) CFG_IMMR;
#ifndef CONFIG_5xx_GCLK_FREQ
uint divf = (immr->im_clkrst.car_plprcr & PLPRCR_DIVF_MSK);
uint mf = ((immr->im_clkrst.car_plprcr & PLPRCR_MF_MSK) >> PLPRCR_MF_SHIFT);
ulong vcoout;
vcoout = (CFG_OSC_CLK / (divf + 1)) * (mf + 1) * 2;
if(immr->im_clkrst.car_plprcr & PLPRCR_CSRC_MSK) {
gd->cpu_clk = vcoout / (2^(((immr->im_clkrst.car_sccr & SCCR_DFNL_MSK) >> SCCR_DFNL_SHIFT) + 1));
} else {
gd->cpu_clk = vcoout / (2^(immr->im_clkrst.car_sccr & SCCR_DFNH_MSK));
}
#else /* CONFIG_5xx_GCLK_FREQ */
gd->bus_clk = CONFIG_5xx_GCLK_FREQ;
#endif /* CONFIG_5xx_GCLK_FREQ */
if ((immr->im_clkrst.car_sccr & SCCR_EBDF11) == 0) {
/* No Bus Divider active */
gd->bus_clk = gd->cpu_clk;
} else {
/* CLKOUT is GCLK / 2 */
gd->bus_clk = gd->cpu_clk / 2;
}
return (0);
}

629
cpu/mpc5xx/start.S Normal file
View File

@ -0,0 +1,629 @@
/*
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000, 2001, 2002 Wolfgang Denk <wd@denx.de>
* Copyright (C) 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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
*/
/*
* File: start.S
*
* Discription: startup code
*
*/
#include <config.h>
#include <mpc5xx.h>
#include <version.h>
#define CONFIG_5xx 1 /* needed for Linux kernel header files */
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <linux/config.h>
#include <asm/processor.h>
#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
#endif
/* We don't have a MMU.
*/
#undef MSR_KERNEL
#define MSR_KERNEL ( MSR_ME | MSR_RI ) /* Machine Check and Recoverable Interr. */
/*
* Set up GOT: Global Offset Table
*
* Use r14 to access the GOT
*/
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
GOT_ENTRY(_start)
GOT_ENTRY(_start_of_vectors)
GOT_ENTRY(_end_of_vectors)
GOT_ENTRY(transfer_to_handler)
GOT_ENTRY(_end)
GOT_ENTRY(.bss)
END_GOT
/*
* r3 - 1st arg to board_init(): IMMP pointer
* r4 - 2nd arg to board_init(): boot flag
*/
.text
.long 0x27051956 /* U-Boot Magic Number */
.globl version_string
version_string:
.ascii U_BOOT_VERSION
.ascii " (", __DATE__, " - ", __TIME__, ")"
.ascii CONFIG_IDENT_STRING, "\0"
. = EXC_OFF_SYS_RESET
.globl _start
_start:
mfspr r3, 638
li r4, CFG_ISB /* Set ISB bit */
or r3, r3, r4
mtspr 638, r3
li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
b boot_cold
. = EXC_OFF_SYS_RESET + 0x20
.globl _start_warm
_start_warm:
li r21, BOOTFLAG_WARM /* Software reboot */
b boot_warm
boot_cold:
boot_warm:
/* Initialize machine status; enable machine check interrupt */
/*----------------------------------------------------------------------*/
li r3, MSR_KERNEL /* Set ME, RI flags */
mtmsr r3
mtspr SRR1, r3 /* Make SRR1 match MSR */
/* Initialize debug port registers */
/*----------------------------------------------------------------------*/
xor r0, r0, r0 /* Clear R0 */
mtspr LCTRL1, r0 /* Initialize debug port regs */
mtspr LCTRL2, r0
mtspr COUNTA, r0
mtspr COUNTB, r0
/*
* Calculate absolute address in FLASH and jump there
*----------------------------------------------------------------------*/
lis r3, CFG_MONITOR_BASE@h
ori r3, r3, CFG_MONITOR_BASE@l
addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
mtlr r3
blr
in_flash:
/* Initialize some SPRs that are hard to access from C */
/*----------------------------------------------------------------------*/
lis r3, CFG_IMMR@h /* Pass IMMR as arg1 to C routine */
lis r2, CFG_INIT_SP_ADDR@h
ori r1, r2, CFG_INIT_SP_ADDR@l /* Set up the stack in internal SRAM */
/* Note: R0 is still 0 here */
stwu r0, -4(r1) /* Clear final stack frame so that */
stwu r0, -4(r1) /* stack backtraces terminate cleanly */
/*
* Disable serialized ifetch and show cycles
* (i.e. set processor to normal mode) for maximum
* performance.
*/
li r2, 0x0007
mtspr ICTRL, r2
/* Set up debug mode entry */
lis r2, CFG_DER@h
ori r2, r2, CFG_DER@l
mtspr DER, r2
/* Let the C-code set up the rest */
/* */
/* Be careful to keep code relocatable ! */
/*----------------------------------------------------------------------*/
GET_GOT /* initialize GOT access */
/* r3: IMMR */
bl cpu_init_f /* run low-level CPU init code (from Flash) */
mr r3, r21
/* r3: BOOTFLAG */
bl board_init_f /* run 1st part of board init code (from Flash) */
.globl _start_of_vectors
_start_of_vectors:
/* Machine check */
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
/* Data Storage exception. "Never" generated on the 860. */
STD_EXCEPTION(0x300, DataStorage, UnknownException)
/* Instruction Storage exception. "Never" generated on the 860. */
STD_EXCEPTION(0x400, InstStorage, UnknownException)
/* External Interrupt exception. */
STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
/* Alignment exception. */
. = 0x600
Alignment:
EXCEPTION_PROLOG
mfspr r4,DAR
stw r4,_DAR(r21)
mfspr r5,DSISR
stw r5,_DSISR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
lwz r6,GOT(transfer_to_handler)
mtlr r6
blrl
.L_Alignment:
.long AlignmentException - _start + EXC_OFF_SYS_RESET
.long int_return - _start + EXC_OFF_SYS_RESET
/* Program check exception */
. = 0x700
ProgramCheck:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
lwz r6,GOT(transfer_to_handler)
mtlr r6
blrl
.L_ProgramCheck:
.long ProgramCheckException - _start + EXC_OFF_SYS_RESET
.long int_return - _start + EXC_OFF_SYS_RESET
/* FPU on MPC5xx available. We will use it later.
*/
STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
/* I guess we could implement decrementer, and may have
* to someday for timekeeping.
*/
STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
. = 0xc00
/*
* r0 - SYSCALL number
* r3-... arguments
*/
SystemCall:
addis r11,r0,0 /* get functions table addr */
ori r11,r11,0 /* Note: this code is patched in trap_init */
addis r12,r0,0 /* get number of functions */
ori r12,r12,0
cmplw 0, r0, r12
bge 1f
rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
add r11,r11,r0
lwz r11,0(r11)
li r20,0xd00-4 /* Get stack pointer */
lwz r12,0(r20)
subi r12,r12,12 /* Adjust stack pointer */
li r0,0xc00+_end_back-SystemCall
cmplw 0, r0, r12 /* Check stack overflow */
bgt 1f
stw r12,0(r20)
mflr r0
stw r0,0(r12)
mfspr r0,SRR0
stw r0,4(r12)
mfspr r0,SRR1
stw r0,8(r12)
li r12,0xc00+_back-SystemCall
mtlr r12
mtspr SRR0,r11
1: SYNC
rfi
_back:
mfmsr r11 /* Disable interrupts */
li r12,0
ori r12,r12,MSR_EE
andc r11,r11,r12
SYNC /* Some chip revs need this... */
mtmsr r11
SYNC
li r12,0xd00-4 /* restore regs */
lwz r12,0(r12)
lwz r11,0(r12)
mtlr r11
lwz r11,4(r12)
mtspr SRR0,r11
lwz r11,8(r12)
mtspr SRR1,r11
addi r12,r12,12 /* Adjust stack pointer */
li r20,0xd00-4
stw r12,0(r20)
SYNC
rfi
_end_back:
STD_EXCEPTION(0xd00, SingleStep, UnknownException)
STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
/* On the MPC8xx, this is a software emulation interrupt. It occurs
* for all unimplemented and illegal instructions.
*/
STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
STD_EXCEPTION(0x1500, Reserved5, UnknownException)
STD_EXCEPTION(0x1600, Reserved6, UnknownException)
STD_EXCEPTION(0x1700, Reserved7, UnknownException)
STD_EXCEPTION(0x1800, Reserved8, UnknownException)
STD_EXCEPTION(0x1900, Reserved9, UnknownException)
STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
STD_EXCEPTION(0x1d00, InstructionBreakpoint, DebugException)
STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
.globl _end_of_vectors
_end_of_vectors:
. = 0x2000
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception.
* Register r21 is pointer into trap frame, r1 has new stack pointer.
*/
.globl transfer_to_handler
transfer_to_handler:
stw r22,_NIP(r21)
lis r22,MSR_POW@h
andc r23,r23,r22
stw r23,_MSR(r21)
SAVE_GPR(7, r21)
SAVE_4GPRS(8, r21)
SAVE_8GPRS(12, r21)
SAVE_8GPRS(24, r21)
mflr r23
andi. r24,r23,0x3f00 /* get vector offset */
stw r24,TRAP(r21)
li r22,0
stw r22,RESULT(r21)
mtspr SPRG2,r22 /* r1 is now kernel sp */
lwz r24,0(r23) /* virtual address of handler */
lwz r23,4(r23) /* where to go when done */
mtspr SRR0,r24
mtspr SRR1,r20
mtlr r23
SYNC
rfi /* jump to handler, enable MMU */
int_return:
mfmsr r28 /* Disable interrupts */
li r4,0
ori r4,r4,MSR_EE
andc r28,r28,r4
SYNC /* Some chip revs need this... */
mtmsr r28
SYNC
lwz r2,_CTR(r1)
lwz r0,_LINK(r1)
mtctr r2
mtlr r0
lwz r2,_XER(r1)
lwz r0,_CCR(r1)
mtspr XER,r2
mtcrf 0xFF,r0
REST_10GPRS(3, r1)
REST_10GPRS(13, r1)
REST_8GPRS(23, r1)
REST_GPR(31, r1)
lwz r2,_NIP(r1) /* Restore environment */
lwz r0,_MSR(r1)
mtspr SRR0,r2
mtspr SRR1,r0
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
SYNC
rfi
/*
* unsigned int get_immr (unsigned int mask)
*
* return (mask ? (IMMR & mask) : IMMR);
*/
.globl get_immr
get_immr:
mr r4,r3 /* save mask */
mfspr r3, IMMR /* IMMR */
cmpwi 0,r4,0 /* mask != 0 ? */
beq 4f
and r3,r3,r4 /* IMMR & mask */
4:
blr
.globl get_pvr
get_pvr:
mfspr r3, PVR
blr
/*------------------------------------------------------------------------------*/
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
* r3 = dest
* r4 = src
* r5 = length in bytes
* r6 = cachelinesize
*/
.globl relocate_code
relocate_code:
mr r1, r3 /* Set new stack pointer in SRAM */
mr r9, r4 /* Save copy of global data pointer in SRAM */
mr r10, r5 /* Save copy of monitor destination Address in SRAM */
mr r3, r5 /* Destination Address */
lis r4, CFG_MONITOR_BASE@h /* Source Address */
ori r4, r4, CFG_MONITOR_BASE@l
lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
ori r5, r5, CFG_MONITOR_LEN@l
/*
* Fix GOT pointer:
*
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
*
* Offset:
*/
sub r15, r10, r4
/* First our own GOT */
add r14, r14, r15
/* the the one used by the C code */
add r30, r30, r15
/*
* Now relocate code
*/
cmplw cr1,r3,r4
addi r0,r5,3
srwi. r0,r0,2
beq cr1,4f /* In place copy is not necessary */
beq 4f /* Protect against 0 count */
mtctr r0
bge cr1,2f
la r8,-4(r4)
la r7,-4(r3)
1: lwzu r0,4(r8)
stwu r0,4(r7)
bdnz 1b
b 4f
2: slwi r0,r0,2
add r8,r4,r0
add r7,r3,r0
3: lwzu r0,-4(r8)
stwu r0,-4(r7)
bdnz 3b
4: sync
isync
/*
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
mtlr r0
blr
in_ram:
/*
* Relocation Function, r14 point to got2+0x8000
*
* Adjust got2 pointers, no need to check for 0, this code
* already puts a few entries in the table.
*/
li r0,__got2_entries@sectoff@l
la r3,GOT(_GOT2_TABLE_)
lwz r11,GOT(_GOT2_TABLE_)
mtctr r0
sub r11,r3,r11
addi r3,r3,-4
1: lwzu r0,4(r3)
add r0,r0,r11
stw r0,0(r3)
bdnz 1b
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
*/
2: li r0,__fixup_entries@sectoff@l
lwz r3,GOT(_FIXUP_TABLE_)
cmpwi r0,0
mtctr r0
addi r3,r3,-4
beq 4f
3: lwzu r4,4(r3)
lwzux r0,r4,r11
add r0,r0,r11
stw r10,0(r3)
stw r0,0(r4)
bdnz 3b
4:
clear_bss:
/*
* Now clear BSS segment
*/
lwz r3,GOT(.bss)
lwz r4,GOT(_end)
cmplw 0, r3, r4
beq 6f
li r0, 0
5:
stw r0, 0(r3)
addi r3, r3, 4
cmplw 0, r3, r4
bne 5b
6:
mr r3, r9 /* Global Data pointer */
mr r4, r10 /* Destination Address */
bl board_init_r
/* Problems accessing "end" in C, so do it here */
.globl get_endaddr
get_endaddr:
lwz r3,GOT(_end)
blr
/*
* Copy exception vector code to low memory
*
* r3: dest_addr
* r7: source address, r8: end address, r9: target address
*/
.globl trap_init
trap_init:
lwz r7, GOT(_start)
lwz r8, GOT(_end_of_vectors)
rlwinm r9, r7, 0, 22, 31 /* _start & 0x3FF */
cmplw 0, r7, r8
bgelr /* return if r7>=r8 - just in case */
mflr r4 /* save link register */
1:
lwz r0, 0(r7)
stw r0, 0(r9)
addi r7, r7, 4
addi r9, r9, 4
cmplw 0, r7, r8
bne 1b
/*
* relocate `hdlr' and `int_return' entries
*/
li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
li r8, Alignment - _start + EXC_OFF_SYS_RESET
2:
bl trap_reloc
addi r7, r7, 0x100 /* next exception vector */
cmplw 0, r7, r8
blt 2b
li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
bl trap_reloc
li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
bl trap_reloc
li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
li r8, SystemCall - _start + EXC_OFF_SYS_RESET
3:
bl trap_reloc
addi r7, r7, 0x100 /* next exception vector */
cmplw 0, r7, r8
blt 3b
li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
4:
bl trap_reloc
addi r7, r7, 0x100 /* next exception vector */
cmplw 0, r7, r8
blt 4b
mtlr r4 /* restore link register */
blr
/*
* Function: relocate entries for one exception vector
*/
trap_reloc:
lwz r0, 0(r7) /* hdlr ... */
add r0, r0, r3 /* ... += dest_addr */
stw r0, 0(r7)
lwz r0, 4(r7) /* int_return ... */
add r0, r0, r3 /* ... += dest_addr */
stw r0, 4(r7)
sync
isync
blr

161
cpu/mpc5xx/status_led.c Normal file
View File

@ -0,0 +1,161 @@
/*
* (C) Copyright 2000-2002 Wolfgang Denk, DENX Software Engineering, wd@denx.de
* (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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
*/
/*
* File: status_led.c
*
* Discription: Blink a board led to show boot progress. Led's
* are connected via the MIOS module.
*/
#include <common.h>
#include <mpc5xx.h>
#include <status_led.h>
#ifdef CONFIG_STATUS_LED
typedef struct {
ulong mask;
int state;
int period;
int cnt;
} led_dev_t;
led_dev_t led_dev[] = {
{ STATUS_LED_BIT,
STATUS_LED_STATE,
STATUS_LED_PERIOD,
0,
},
#if defined(STATUS_LED_BIT1)
{ STATUS_LED_BIT1,
STATUS_LED_STATE1,
STATUS_LED_PERIOD1,
0,
},
#endif
#if defined(STATUS_LED_BIT2)
{ STATUS_LED_BIT2,
STATUS_LED_STATE2,
STATUS_LED_PERIOD2,
0,
},
#endif
#if defined(STATUS_LED_BIT3)
{ STATUS_LED_BIT3,
STATUS_LED_STATE3,
STATUS_LED_PERIOD3,
0,
},
#endif
};
#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
static int status_led_init_done = 0;
static void status_led_init (void)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
immr->STATUS_LED_DIR = STATUS_LED_BIT;
#if (STATUS_LED_ACTIVE == 0)
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT &= ~(ld->mask);
else
immr->STATUS_LED_DAT |= ld->mask ;
#else
if (ld->state == STATUS_LED_ON)
immr->STATUS_LED_DAT |= ld->mask ;
else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
}
status_led_init_done = 1;
}
void status_led_tick (ulong timestamp)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
int i;
if (!status_led_init_done)
status_led_init();
for (i=0; i<MAX_LED_DEV; ++i) {
led_dev_t *ld = &led_dev[i];
if (ld->state != STATUS_LED_BLINKING)
continue;
if (++(ld->cnt) >= ld->period) {
immr->STATUS_LED_DAT ^= ld->mask;
ld->cnt -= ld->period;
}
}
}
void status_led_set (int led, int state)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
led_dev_t *ld;
if (led < 0 || led >= MAX_LED_DEV)
return;
if (!status_led_init_done)
status_led_init();
ld = &led_dev[led];
switch (state) {
default:
return;
case STATUS_LED_BLINKING:
ld->cnt = 0; /* always start with full period */
/* fall through */ /* always start with LED _ON_ */
case STATUS_LED_ON:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT &= ~(ld->mask);
#else
immr->STATUS_LED_DAT |= ld->mask ;
#endif
break;
case STATUS_LED_OFF:
#if (STATUS_LED_ACTIVE == 0)
immr->STATUS_LED_DAT |= ld->mask ;
#else
immr->STATUS_LED_DAT &= ~(ld->mask);
#endif
break;
}
ld->state = state;
}
#endif /* CONFIG_STATUS_LED */

231
cpu/mpc5xx/traps.c Normal file
View File

@ -0,0 +1,231 @@
/*
* linux/arch/ppc/kernel/traps.c
*
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Modified by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras (paulus@cs.anu.edu.au)
*
* (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
*/
/*
* This file handles the architecture-dependent parts of hardware exceptions
*/
#include <common.h>
#include <command.h>
#include <asm/processor.h>
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
int (*debugger_exception_handler)(struct pt_regs *) = 0;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
extern void do_bedbug_breakpoint(struct pt_regs *);
#endif
/* Returns 0 if exception not found and fixup otherwise. */
extern unsigned long search_exception_table(unsigned long);
/* THIS NEEDS CHANGING to use the board info structure.
*/
#define END_OF_MEM 0x0001000
/*
* Print stack backtrace
*/
void print_backtrace(unsigned long *sp)
{
int cnt = 0;
unsigned long i;
printf("Call backtrace: ");
while (sp) {
if ((uint)sp > END_OF_MEM)
break;
i = sp[1];
if (cnt++ % 7 == 0)
printf("\n");
printf("%08lX ", i);
if (cnt > 32) break;
sp = (unsigned long *)*sp;
}
printf("\n");
}
/*
* Print current registers
*/
void show_regs(struct pt_regs * regs)
{
int i;
printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
regs->msr&MSR_IR ? 1 : 0,
regs->msr&MSR_DR ? 1 : 0);
printf("\n");
for (i = 0; i < 32; i++) {
if ((i % 8) == 0)
{
printf("GPR%02d: ", i);
}
printf("%08lX ", regs->gpr[i]);
if ((i % 8) == 7)
{
printf("\n");
}
}
}
/*
* General exception handler routine
*/
void _exception(int signr, struct pt_regs *regs)
{
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
}
/*
* Machine check exception handler routine
*/
void MachineCheckException(struct pt_regs *regs)
{
unsigned long fixup;
/* Probing PCI using config cycles cause this exception
* when a device is not present. Catch it and return to
* the PCI exception handler.
*/
if ((fixup = search_exception_table(regs->nip)) != 0) {
regs->nip = fixup;
return;
}
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
printf("Machine check in kernel mode.\n");
printf("Caused by (from msr): ");
printf("regs %p ",regs);
switch( regs->msr & 0x0000F000)
{
case (1<<12) :
printf("Machine check signal\n");
break;
case (1<<13) :
printf("Transfer error ack signal\n");
break;
case (1<<14) :
printf("Data parity signal\n");
break;
case (1<<15) :
printf("Address parity signal\n");
break;
default:
printf("Unknown values in msr\n");
}
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
}
/*
* Alignment exception handler routine
*/
void AlignmentException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Alignment Exception");
}
/*
* Program check exception handler routine
*/
void ProgramCheckException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Program Check Exception");
}
/*
* Software emulation exception handler routine
*/
void SoftEmuException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Software Emulation Exception");
}
/*
* Unknown exception handler routine
*/
void UnknownException(struct pt_regs *regs)
{
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
regs->nip, regs->msr, regs->trap);
_exception(0, regs);
}
/*
* Debug exception handler routine
*/
void DebugException(struct pt_regs *regs)
{
printf("Debugger trap at @ %lx\n", regs->nip );
show_regs(regs);
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
do_bedbug_breakpoint( regs );
#endif
}

84
doc/README.cmi Normal file
View File

@ -0,0 +1,84 @@
Summary:
========
This file contains information about the cmi board configuration.
Please see cmi_mpc5xx_config for further details. The cmi board is
a customer specific board but should work with small modifications
on every board which has a MPC5xx and either a 28F128J3A,
28F320J3A or 28F640J3A Intel flash mounted.
Board Discription:
==================
* Motorola MPC555
* RS232 connection
* Intel flash 28F640J3A
* Micron SRAM 1M
* Altera PLD
Bootstrap:
==========
In contrast to the usual boot sequence used in U-Boot, on the
cmi board we don't boot from the external flash directly.
Because of we use a 16-bit flash and don't sample a RCW
from the data bus to set the startup buswidth to 16-bit.
Unfortunatly the default width, sampled from the default RCW
is 32-bit. For this reason we burn the proper RCW into the
internal flash shadow location and boot after power-on or
reset from the internal flash and then branch to 0x02000100
where the U-Boot reset vector handler is located.
Memory Map:
===========
Memory Map after relocation:
0x0000 0000 CFG_SDRAM_BASE
:
0x000F 9FFF
:
:
0x0100 0000 CFG_IMMR (Internal memory map base adress)
:
0x0130 7FFF
:
:
0x0200 0000 CFG_FLASH_BASE
:
0x027C FFFF
:
:
0x0300 0000 PLD_BASE
Flash Partition:
0x0200 0000 Block 0 and 1 contain U-Boot except
: environment
:
0x0201 FFFF
0x0202 0000 Block 2 contains environment (.ppcenv)
:
0x0202 FFFF
See README file for futher information about U-Boot relocation
and partitioning.
Tested Features:
================
* U-Boot commands: go, loads, loadb, all memory features, printenv,
setenv, saveenv, protect, erase, fli, bdi, mtest, reset, version,
coninfo, help (see configuration file for available commands)
* Blinking led to indicate boot process
Added or Changed Files:
=======================
u-boot-0.2.0/board/cmi/*
u-boot-0.2.0/include/configs/cmi_mpc5xx.h
Regards,
Martin

48
doc/README.mpc5xx Normal file
View File

@ -0,0 +1,48 @@
Summary:
========
This file contains information about the port of U-Boot to the
Motorola mpc5xx series of CPUs. Most of this code is taken from
existing code mainly from the mpc8xx port. In contrast to mpc8xx,
the mpc5xx has no CPM, MMU and cache facilities.
The implemented features have been tested on the cmi board, a
customer specific board (see README.cmi).
Hence this port is only tested on the cmi board further possible
tests on other boards will be very valuable.
Not Tested Features:
====================
* System calls
* Interrupts
Added or Changed Files:
=======================
u-boot-0.2.0/common/cmd_boot.c
u-boot-0.2.0/common/cmd_reginfo.c
u-boot-0.2.0/common/environment.c
u-boot-0.2.0/cpu/mpc5xx/*
u-boot-0.2.0/include/cmd_reginfo.h
u-boot-0.2.0/include/common.h
u-boot-0.2.0/include/ppc_asm.tmpl
u-boot-0.2.0/include/watchdog.h
u-boot-0.2.0/include/mpc5xx.h
u-boot-0.2.0/include/status_led.h
u-boot-0.2.0/include/asm-ppc/u-boot.h
u-boot-0.2.0/include/asm-ppc/5xx_immap.h
u-boot-0.2.0/lib_ppc/board.c
u-boot-0.2.0/lib_ppc/cache.c
u-boot-0.2.0/lib_ppc/time.c
u-boot-0.2.0/Makefile
u-boot-0.2.0/CREDITS
u-boot-0.2.0/doc/README.mpc5xx
u-boot-0.2.0/doc/README.cmi
u-boot-0.2.0/README
u-boot-0.2.0/MAKEALL
Regards,
Martin

440
include/asm-ppc/5xx_immap.h Normal file
View File

@ -0,0 +1,440 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: 5xx_immap.h
*
* Discription: MPC555 Internal Memory Map
*
*/
#ifndef __IMMAP_5XX__
#define __IMMAP_5XX__
/* System Configuration Registers.
*/
typedef struct sys_conf {
uint sc_siumcr;
uint sc_sypcr;
char res1[6];
ushort sc_swsr;
uint sc_sipend;
uint sc_simask;
uint sc_siel;
uint sc_sivec;
uint sc_tesr;
uint sc_sgpiodt1;
uint sc_sgpiodt2;
uint sc_sgpiocr;
uint sc_emcr;
uint sc_res1aa;
uint sc_res1ab;
uint sc_pdmcr;
char res3[192];
} sysconf5xx_t;
/* Memory Controller Registers.
*/
typedef struct mem_ctlr {
uint memc_br0;
uint memc_or0;
uint memc_br1;
uint memc_or1;
uint memc_br2;
uint memc_or2;
uint memc_br3;
uint memc_or3;
char res1[32];
uint memc_dmbr;
uint memc_dmor;
char res2[48];
ushort memc_mstat;
ushort memc_res4a;
char res3[132];
} memctl5xx_t;
/* System Integration Timers.
*/
typedef struct sys_int_timers {
ushort sit_tbscr;
char res1[2];
uint sit_tbref0;
uint sit_tbref1;
char res2[20];
ushort sit_rtcsc;
char res3[2];
uint sit_rtc;
uint sit_rtsec;
uint sit_rtcal;
char res4[16];
ushort sit_piscr;
char res5[2];
uint sit_pitc;
uint sit_pitr;
char res6[52];
} sit5xx_t;
/* Clocks and Reset
*/
typedef struct clk_and_reset {
uint car_sccr;
uint car_plprcr;
ushort car_rsr;
ushort car_res7a;
ushort car_colir;
ushort car_res7b;
ushort car_vsrmcr;
ushort car_res7c;
char res1[108];
} car5xx_t;
#define TBSCR_TBE ((ushort)0x0001)
/* System Integration Timer Keys
*/
typedef struct sitk {
uint sitk_tbscrk;
uint sitk_tbref0k;
uint sitk_tbref1k;
uint sitk_tbk;
char res1[16];
uint sitk_rtcsck;
uint sitk_rtck;
uint sitk_rtseck;
uint sitk_rtcalk;
char res2[16];
uint sitk_piscrk;
uint sitk_pitck;
char res3[56];
} sitk5xx_t;
/* Clocks and Reset Keys.
*/
typedef struct cark {
uint cark_sccrk;
uint cark_plprcrk;
uint cark_rsrk;
char res1[1140];
} cark8xx_t;
/* The key to unlock registers maintained by keep-alive power.
*/
#define KAPWR_KEY ((unsigned int)0x55ccaa33)
/* Flash Configuration
*/
typedef struct fl {
uint fl_cmfmcr;
uint fl_cmftst;
uint fl_cmfctl;
char res1[52];
} fl5xx_t;
/* Dpram Control
*/
typedef struct dprc {
ushort dprc_dptmcr;
ushort dprc_ramtst;
ushort dprc_rambar;
ushort dprc_misrh;
ushort dprc_misrl;
ushort dprc_miscnt;
} dprc5xx_t;
/* Time Processor Unit
*/
typedef struct tpu {
ushort tpu_tpumcr;
ushort tpu_tcr;
ushort tpu_dscr;
ushort tpu_dssr;
ushort tpu_ticr;
ushort tpu_cier;
ushort tpu_cfsr0;
ushort tpu_cfsr1;
ushort tpu_cfsr2;
ushort tpu_cfsr3;
ushort tpu_hsqr0;
ushort tpu_hsqr1;
ushort tpu_hsrr0;
ushort tpu_hsrr1;
ushort tpu_cpr0;
ushort tpu_cpr1;
ushort tpu_cisr;
ushort tpu_lr;
ushort tpu_sglr;
ushort tpu_dcnr;
ushort tpu_tpumcr2;
ushort tpu_tpumcr3;
ushort tpu_isdr;
ushort tpu_iscr;
char res1[208];
char tpu[16][16];
char res2[512];
} tpu5xx_t;
/* QADC
*/
typedef struct qadc {
ushort qadc_64mcr;
ushort qadc_64test;
ushort qadc_64int;
u_char qadc_portqa;
u_char qadc_portqb;
ushort qadc_ddrqa;
ushort qadc_qacr0;
ushort qadc_qacr1;
ushort qadc_qacr2;
ushort qadc_qasr0;
ushort qadc_qasr1;
char res1[492];
/* command convertion word table */
ushort qadc_ccw[64];
/* result word table, unsigned right justified */
ushort qadc_rjurr[64];
/* result word table, signed left justified */
ushort qadc_ljsrr[64];
/* result word table, unsigned left justified */
ushort qadc_ljurr[64];
} qadc5xx_t;
/* QSMCM
*/
typedef struct qsmcm {
ushort qsmcm_qsmcr;
ushort qsmcm_qtest;
ushort qsmcm_qdsci_il;
ushort qsmcm_qspi_il;
ushort qsmcm_scc1r0;
ushort qsmcm_scc1r1;
ushort qsmcm_sc1sr;
ushort qsmcm_sc1dr;
char res1[2];
char res2[2];
ushort qsmcm_portqs;
u_char qsmcm_pqspar;
u_char qsmcm_ddrqs;
ushort qsmcm_spcr0;
ushort qsmcm_spcr1;
ushort qsmcm_spcr2;
u_char qsmcm_spcr3;
u_char qsmcm_spsr;
ushort qsmcm_scc2r0;
ushort qsmcm_scc2r1;
ushort qsmcm_sc2sr;
ushort qsmcm_sc2dr;
ushort qsmcm_qsci1cr;
ushort qsmcm_qsci1sr;
ushort qsmcm_sctq[16];
ushort qsmcm_scrq[16];
char res3[212];
ushort qsmcm_recram[32];
ushort qsmcm_tranram[32];
u_char qsmcm_comdram[32];
char res[3616];
} qsmcm5xx_t;
/* MIOS
*/
typedef struct mios {
ushort mios_mpwmsm0perr; /* mpwmsm0 */
ushort mios_mpwmsm0pulr;
ushort mios_mpwmsm0cntr;
ushort mios_mpwmsm0scr;
ushort mios_mpwmsm1perr; /* mpwmsm1 */
ushort mios_mpwmsm1pulr;
ushort mios_mpwmsm1cntr;
ushort mios_mpwmsm1scr;
ushort mios_mpwmsm2perr; /* mpwmsm2 */
ushort mios_mpwmsm2pulr;
ushort mios_mpwmsm2cntr;
ushort mios_mpwmsm2scr;
ushort mios_mpwmsm3perr; /* mpwmsm3 */
ushort mios_mpwmsm3pulr;
ushort mios_mpwmsm3cntr;
ushort mios_mpwmsm3scr;
char res1[16];
ushort mios_mmcsm6cnt; /* mmcsm6 */
ushort mios_mmcsm6mlr;
ushort mios_mmcsm6scrd, mmcsm6scr;
char res2[32];
ushort mios_mdasm11ar; /* mdasm11 */
ushort mios_mdasm11br;
ushort mios_mdasm11scrd, mdasm11scr;
ushort mios_mdasm12ar; /* mdasm12 */
ushort mios_mdasm12br;
ushort mios_mdasm12scrd, mdasm12scr;
ushort mios_mdasm13ar; /* mdasm13 */
ushort mios_mdasm13br;
ushort mios_mdasm13scrd, mdasm13scr;
ushort mios_mdasm14ar; /* mdasm14 */
ushort mios_mdasm14br;
ushort mios_mdasm14scrd, mdasm14scr;
ushort mios_mdasm15ar; /* mdasm15 */
ushort mios_mdasm15br;
ushort mios_mdasm15scrd, mdasm15scr;
ushort mios_mpwmsm16perr; /* mpwmsm16 */
ushort mios_mpwmsm16pulr;
ushort mios_mpwmsm16cntr;
ushort mios_mpwmsm16scr;
ushort mios_mpwmsm17perr; /* mpwmsm17 */
ushort mios_mpwmsm17pulr;
ushort mios_mpwmsm17cntr;
ushort mios_mpwmsm17scr;
ushort mios_mpwmsm18perr; /* mpwmsm18 */
ushort mios_mpwmsm18pulr;
ushort mios_mpwmsm18cntr;
ushort mios_mpwmsm18scr;
ushort mios_mpwmsm19perr; /* mpwmsm19 */
ushort mios_mpwmsm19pulr;
ushort mios_mpwmsm19cntr;
ushort mios_mpwmsm19scr;
char res3[16];
ushort mios_mmcsm22cnt; /* mmcsm22 */
ushort mios_mmcsm22mlr;
ushort mios_mmcsm22scrd, mmcsm22scr;
char res4[32];
ushort mios_mdasm27ar; /* mdasm27 */
ushort mios_mdasm27br;
ushort mios_mdasm27scrd, mdasm27scr;
ushort mios_mdasm28ar; /*mdasm28 */
ushort mios_mdasm28br;
ushort mios_mdasm28scrd, mdasm28scr;
ushort mios_mdasm29ar; /* mdasm29 */
ushort mios_mdasm29br;
ushort mios_mdasm29scrd, mdasm29scr;
ushort mios_mdasm30ar; /* mdasm30 */
ushort mios_mdasm30br;
ushort mios_mdasm30scrd, mdasm30scr;
ushort mios_mdasm31ar; /* mdasm31 */
ushort mios_mdasm31br;
ushort mios_mdasm31scrd, mdasm31scr;
ushort mios_mpiosm32dr;
ushort mios_mpiosm32ddr;
char res5[1788];
ushort mios_mios1tpcr;
char mios_res13[2];
ushort mios_mios1vnr;
ushort mios_mios1mcr;
char res6[12];
ushort mios_res42z;
ushort mios_mcpsmscr;
char res7[1000];
ushort mios_mios1sr0;
char res12[2];
ushort mios_mios1er0;
ushort mios_mios1rpr0;
char res8[40];
ushort mios_mios1lvl0;
char res9[14];
ushort mios_mios1sr1;
char res10[2];
ushort mios_mios1er1;
ushort mios_mios1rpr1;
char res11[40];
ushort mios_mios1lvl1;
char res13[1038];
} mios5xx_t;
/* Toucan Module
*/
typedef struct tcan {
ushort tcan_tcnmcr;
ushort tcan_cantcr;
ushort tcan_canicr;
u_char tcan_canctrl0;
u_char tcan_canctrl1;
u_char tcan_presdiv;
u_char tcan_canctrl2;
ushort tcan_timer;
char res1[4];
ushort tcan_rxgmskhi;
ushort tcan_rxgmsklo;
ushort tcan_rx14mskhi;
ushort tcan_rx14msklo;
ushort tcan_rx15mskhi;
ushort tcan_rx15msklo;
char res2[4];
ushort tcan_estat;
ushort tcan_imask;
ushort tcan_iflag;
u_char tcan_rxectr;
u_char tcan_txectr;
char res3[88];
struct {
ushort scr;
ushort id_high;
ushort id_low;
u_char data[8];
char res4[2];
} tcan_mbuff[16];
char res5[640];
} tcan5xx_t;
/* UIMB
*/
typedef struct uimb {
uint uimb_umcr;
char res1[12];
uint uimb_utstcreg;
char res2[12];
uint uimb_uipend;
} uimb5xx_t;
/* Internal Memory Map MPC555
*/
typedef struct immap {
char res1[262144]; /* CMF Flash A 256 Kbytes */
char res2[196608]; /* CMF Flash B 192 Kbytes */
char res3[2670592]; /* Reserved for Flash */
sysconf5xx_t im_siu_conf; /* SIU Configuration */
memctl5xx_t im_memctl; /* Memory Controller */
sit5xx_t im_sit; /* System Integration Timers */
car5xx_t im_clkrst; /* Clocks and Reset */
sitk5xx_t im_sitk; /* System Integration Timer Keys*/
cark8xx_t im_clkrstk; /* Clocks and Resert Keys */
fl5xx_t im_fla; /* Flash Module A */
fl5xx_t im_flb; /* Flash Module B */
char res4[14208]; /* Reserved for SIU */
dprc5xx_t im_dprc; /* Dpram Control Register */
char res5[8180]; /* Reserved */
char dptram[6144]; /* Dptram */
char res6[2048]; /* Reserved */
tpu5xx_t im_tpua; /* Time Proessing Unit A */
tpu5xx_t im_tpub; /* Time Processing Unit B */
qadc5xx_t im_qadca; /* QADC A */
qadc5xx_t im_qadcb; /* QADC B */
qsmcm5xx_t im_qsmcm; /* SCI and SPI */
mios5xx_t im_mios; /* MIOS */
tcan5xx_t im_tcana; /* Toucan A */
tcan5xx_t im_tcanb; /* Toucan B */
char res7[1792]; /* Reserved */
uimb5xx_t im_uimb; /* UIMB */
} immap_t;
#endif /* __IMMAP_5XX__ */

View File

@ -38,7 +38,7 @@ typedef struct bd_info {
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 */
#if defined(CONFIG_8xx) || defined(CONFIG_8260)
#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260)
unsigned long bi_immr_base; /* base of IMMR register */
#endif
unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */

View File

@ -24,7 +24,7 @@
#ifndef _CMD_REGINFO_H_
#define _CMD_REGINFO_H_
#if (defined(CONFIG_8xx) || defined(CONFIG_405GP)) && \
#if (defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_405GP)) && \
(CONFIG_COMMANDS & CFG_CMD_REGINFO)
#define CMD_TBL_REGINFO MK_CMD_TBL_ENTRY( \
"reginfo", 3, 2, 1, do_reginfo, \
@ -35,6 +35,6 @@ int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#else
#define CMD_TBL_REGINFO
#endif /* CONFIG_8xx && CFG_CMD_REGINFO */
#endif /* CONFIG_COMMANDS && CFG_CMD_REGINFO */
#endif /* _CMD_REGINFO_H_ */

View File

@ -43,6 +43,8 @@ typedef volatile unsigned char vu_char;
#endif
#ifdef CONFIG_8xx
#include <asm/8xx_immap.h>
#elif defined(CONFIG_5xx)
#include <asm/5xx_immap.h>
#elif defined(CONFIG_8260)
#include <asm/immap_8260.h>
#endif
@ -241,7 +243,8 @@ int testdram(void);
#endif /* CFG_DRAM_TEST */
/* $(CPU)/start.S */
#ifdef CONFIG_8xx
#if defined(CONFIG_5xx) || \
defined(CONFIG_8xx)
uint get_immr (uint);
#endif
uint get_pvr (void);
@ -370,6 +373,7 @@ ulong video_setmem (ulong);
/* ppc/cache.c */
void flush_cache (unsigned long, unsigned long);
/* ppc/ticks.S */
unsigned long long get_ticks(void);
void wait_ticks (unsigned long);

View File

@ -0,0 +1,256 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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,
*/
/*
* File: cmi_mpc5xx.h
*
* Discription: Config header file for cmi
* board using an MPC5xx CPU
*
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
*/
#define CONFIG_MPC555 1 /* This is an MPC555 CPU */
#define CONFIG_CMI 1 /* Using the customized cmi board */
/* Serial Console Configuration */
#define CONFIG_5xx_CONS_SCI1
#undef CONFIG_5xx_CONS_SCI2
#define CONFIG_BAUDRATE 57600
#define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_LOADB | CFG_CMD_REGINFO | \
CFG_CMD_FLASH | CFG_CMD_LOADS | CFG_CMD_ASKENV | \
CFG_CMD_BDI | CFG_CMD_CONSOLE | CFG_CMD_ENV | CFG_CMD_RUN | \
CFG_CMD_IMI)
/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#if 0
#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
#else
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#endif
#define CONFIG_BOOTCOMMAND "go 02034004" /* autoboot command */
#define CONFIG_BOOTARGS "" /* Assuming OS Image in 4 flash sector at offset 4004 */
#define CONFIG_WATCHDOG /* turn on platform specific watchdog */
#define CONFIG_STATUS_LED 1 /* Enable status led */
#define CONFIG_LOADS_ECHO 1 /* Echo on for serial download */
/*
* Miscellaneous configurable options
*/
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT "=> " /* Monitor Command Prompt */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
#else
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#endif
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x00000000 /* memtest works on */
#define CFG_MEMTEST_END 0x000fa000 /* 1 MB in SRAM */
#define CFG_LOAD_ADDR 0x100000 /* default load address */
#define CFG_HZ 1000 /* Decrementer freq: 1 ms ticks */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 1250000 }
/*
* Low Level Configuration Settings
*/
/*
* Internal Memory Mapped (This is not the IMMR content)
*/
#define CFG_IMMR 0x01000000 /* Physical start adress of internal memory map */
/*
* Definitions for initial stack pointer and data area
*/
#define CFG_INIT_RAM_ADDR (CFG_IMMR + 0x003f9800) /* Physical start adress of internal MPC555 writable RAM */
#define CFG_INIT_RAM_END (CFG_IMMR + 0x003fffff) /* Physical end adress of internal MPC555 used RAM area */
#define CFG_GBL_DATA_SIZE 64 /* Size in bytes reserved for initial global data */
#define CFG_GBL_DATA_OFFSET ((CFG_INIT_RAM_END - CFG_INIT_RAM_ADDR) - CFG_GBL_DATA_SIZE) /* Offset from the beginning of ram */
#define CFG_INIT_SP_ADDR 0x013fa000 /* Physical start adress of inital stack */
/*
* Start addresses for the final memory configuration
* Please note that CFG_SDRAM_BASE _must_ start at 0
*/
#define CFG_SDRAM_BASE 0x00000000 /* Monitor won't change memory map */
#define CFG_FLASH_BASE 0x02000000 /* External flash */
#define PLD_BASE 0x03000000 /* PLD */
#define ANYBUS_BASE 0x03010000 /* Anybus Module */
#define CFG_RESET_ADRESS 0x01000000 /* Adress which causes reset */
#define CFG_MONITOR_BASE CFG_FLASH_BASE /* TEXT_BASE is defined in the board config.mk file. */
/* This adress is given to the linker with -Ttext to */
/* locate the text section at this adress. */
#define CFG_MONITOR_LEN (192 << 10) /* Reserve 192 kB for Monitor */
#define CFG_MALLOC_LEN (64 << 10) /* Reserve 128 kB for malloc() */
/*
* For booting Linux, the board info and command line data
* have to be in the first 8 MB of memory, since this is
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*-----------------------------------------------------------------------
* FLASH organization
*-----------------------------------------------------------------------
*
*/
#define CFG_MAX_FLASH_BANKS 1 /* Max number of memory banks */
#define CFG_MAX_FLASH_SECT 64 /* Max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 180000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 600 /* Timeout for Flash Write (in ms) */
#define CFG_FLASH_PROTECTION 1 /* Physically section protection on */
#define CFG_ENV_IS_IN_FLASH 1
#ifdef CFG_ENV_IS_IN_FLASH
#define CFG_ENV_OFFSET 0x00020000 /* Environment starts at this adress */
#define CFG_ENV_SIZE 0x00010000 /* Set whole sector as env */
#endif
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control
* SYPCR can only be written once after reset!
*-----------------------------------------------------------------------
* SW Watchdog freeze
*/
#if defined(CONFIG_WATCHDOG)
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
SYPCR_SWE | SYPCR_SWRI| SYPCR_SWP)
#else
#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
SYPCR_SWP)
#endif /* CONFIG_WATCHDOG */
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control
*-----------------------------------------------------------------------
* Clear Reference Interrupt Status, Timebase freezing enabled
*/
#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF)
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control
*-----------------------------------------------------------------------
* Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
*/
#define CFG_PISCR (PISCR_PITF)
/*-----------------------------------------------------------------------
* SCCR - System Clock and reset Control Register
*-----------------------------------------------------------------------
* Set clock output, timebase and RTC source and divider,
* power management and some other internal clocks
*/
#define SCCR_MASK SCCR_EBDF00
#define CFG_SCCR (SCCR_TBS | SCCR_RTDIV | SCCR_RTSEL | \
SCCR_COM00 | SCCR_DFNL000 | SCCR_DFNH000)
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration
*-----------------------------------------------------------------------
* Data show cycle
*/
#define CFG_SIUMCR (SIUMCR_DBGC00) /* Disable data show cycle */
/*-----------------------------------------------------------------------
* PLPRCR - PLL, Low-Power, and Reset Control Register
*-----------------------------------------------------------------------
* Set all bits to 40 Mhz
*
*/
#define CFG_OSC_CLK ((uint)4000000) /* Oscillator clock is 4MHz */
#define CFG_PLPRCR (PLPRCR_MF_9 | PLPRCR_DIVF_0)
/*-----------------------------------------------------------------------
* UMCR - UIMB Module Configuration Register
*-----------------------------------------------------------------------
*
*/
#define CFG_UMCR (UMCR_FSPEED) /* IMB clock same as U-bus */
/*-----------------------------------------------------------------------
* ICTRL - I-Bus Support Control Register
*/
#define CFG_ICTRL (ICTRL_ISCT_SER_7) /* Take out of serialized mode */
/*-----------------------------------------------------------------------
* USIU - Memory Controller Register
*-----------------------------------------------------------------------
*/
#define CFG_BR0_PRELIM (CFG_FLASH_BASE | BR_V | BR_BI | BR_PS_16)
#define CFG_OR0_PRELIM (OR_ADDR_MK_FF | OR_SCY_3)
#define CFG_BR1_PRELIM (ANYBUS_BASE)
#define CFG_OR1_PRELIM (OR_ADDR_MK_FFFF | OR_SCY_1 | OR_ETHR)
#define CFG_BR2_PRELIM (CFG_SDRAM_BASE | BR_V | BR_PS_32)
#define CFG_OR2_PRELIM (OR_ADDR_MK_FF)
#define CFG_BR3_PRELIM (PLD_BASE | BR_V | BR_BI | BR_LBDIR | BR_PS_8)
#define CFG_OR3_PRELIM (OR_ADDR_MK_FF | OR_TRLX | OR_BSCY | OR_SCY_8 | \
OR_ACS_10 | OR_ETHR | OR_CSNT)
#define FLASH_BASE0_PRELIM CFG_FLASH_BASE /* We don't realign the flash */
/*-----------------------------------------------------------------------
* DER - Timer Decrementer
*-----------------------------------------------------------------------
* Initialise to zero
*/
#define CFG_DER 0x00000000
/*
* Internal Definitions
*
* Boot Flags
*/
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#endif /* __CONFIG_H */

180
include/mpc5xx.h Normal file
View File

@ -0,0 +1,180 @@
/*
* (C) Copyright 2003
* Martin Winistoerfer, martinwinistoerfer@gmx.ch.
*
* 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
*/
/*
* File: mpc5xx.h
*
* Discription: mpc5xx specific definitions
*
*/
#ifndef __MPC5XX_H__
#define __MPC5XX_H__
/*-----------------------------------------------------------------------
* Exception offsets (PowerPC standard)
*/
#define EXC_OFF_SYS_RESET 0x0100 /* System reset */
/*-----------------------------------------------------------------------
* ISB bit in IMMR to set internal memory map
*/
#define CFG_ISB ((CFG_IMMR / 0x00400000) << 1)
/*-----------------------------------------------------------------------
* SYPCR - System Protection Control Register
*/
#define SYPCR_SWTC 0xffff0000 /* Software Watchdog Timer Count */
#define SYPCR_BMT 0x0000ff00 /* Bus Monitor Timing */
#define SYPCR_BME 0x00000080 /* Bus Monitor Enable */
#define SYPCR_SWF 0x00000008 /* Software Watchdog Freeze */
#define SYPCR_SWE 0x00000004 /* Software Watchdog Enable */
#define SYPCR_SWRI 0x00000002 /* Software Watchdog Reset/Int Select */
#define SYPCR_SWP 0x00000001 /* Software Watchdog Prescale */
/*-----------------------------------------------------------------------
* SIUMCR - SIU Module Configuration Register
*/
#define SIUMCR_EARB 0x80000000 /* External Arbitration */
#define SIUMCR_EARP0 0x00000000 /* External Arbi. Request priority 0 */
#define SIUMCR_EARP1 0x10000000 /* External Arbi. Request priority 1 */
#define SIUMCR_EARP2 0x20000000 /* External Arbi. Request priority 2 */
#define SIUMCR_EARP3 0x30000000 /* External Arbi. Request priority 3 */
#define SIUMCR_EARP4 0x40000000 /* External Arbi. Request priority 4 */
#define SIUMCR_EARP5 0x50000000 /* External Arbi. Request priority 5 */
#define SIUMCR_EARP6 0x60000000 /* External Arbi. Request priority 6 */
#define SIUMCR_EARP7 0x70000000 /* External Arbi. Request priority 7 */
#define SIUMCR_DSHW 0x00800000 /* Data Showcycles */
#define SIUMCR_DBGC00 0x00000000 /* Debug pins configuration */
#define SIUMCR_DBGC01 0x00200000 /* - " - */
#define SIUMCR_DBGC10 0x00400000 /* - " - */
#define SIUMCR_DBGC11 0x00600000 /* - " - */
#define SIUMCR_DBPC00 0x00000000 /* Debug Port pins Config. */
#define SIUMCR_DBPC01 0x00080000 /* - " - */
#define SIUMCR_DBPC10 0x00100000 /* - " - */
#define SIUMCR_DBPC11 0x00180000 /* - " - */
#define SIUMCR_DLK 0x00010000 /* Debug Register Lock */
#define SIUMCR_SC00 0x00000000 /* Multi Chip 32 bit */
#define SIUMCR_SC01 0x00004000 /* Muilt Chip 16 bit */
#define SIUMCR_SC10 0x00004000 /* Single adress show */
#define SIUMCR_SC11 0x00006000 /* Single adress */
#define SIUMCR_RCTX 0x00001000 /* Data Parity pins Config. */
#define SIUMCR_MLRC00 0x00000000 /* Multi Level Reserva. Ctrl */
#define SIUMCR_MLRC01 0x00000400 /* - " - */
#define SIUMCR_MLRC10 0x00000800 /* - " - */
#define SIUMCR_MLRC11 0x00000c00 /* - " - */
#define SIUMCR_MTSC 0x00000100 /* Memory transfer */
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control Register
*/
#define TBSCR_REFA ((ushort)0x0080) /* Reference Interrupt Status A */
#define TBSCR_REFB ((ushort)0x0040) /* Reference Interrupt Status B */
#define TBSCR_TBF ((ushort)0x0002) /* Time Base stops while FREEZE */
/*-----------------------------------------------------------------------
* PISCR - Periodic Interrupt Status and Control Register
*/
#define PISCR_PITF ((ushort)0x0002) /* PIT stops when FREEZE */
/*-----------------------------------------------------------------------
* PLPRCR - PLL, Low-Power, and Reset Control Register
*/
#define PLPRCR_MF_MSK 0xfff00000 /* MF mask */
#define PLPRCR_DIVF_MSK 0x0000001f /* DIVF mask */
#define PLPRCR_CSRC_MSK 0x00000400 /* CSRC mask */
#define PLPRCR_MF_SHIFT 0x00000014 /* Multiplication factor shift value */
#define PLPRCR_DIVF_0 0x00900000 /* Division factor 0 */
#define PLPRCR_MF_9 0x00000000 /* Mulitipliaction factor 9 */
#define PLPRCR_TEXPS 0x00004000 /* TEXP Status */
#define PLPRCR_TMIST 0x00001000 /* Timers Interrupt Status */
#define PLPRCR_CSR 0x00000080 /* CheskStop Reset value */
/*-----------------------------------------------------------------------
* SCCR - System Clock and reset Control Register
*/
#define SCCR_DFNL_MSK 0x00000070 /* DFNL mask */
#define SCCR_DFNH_MSK 0x00000007 /* DFNH mask */
#define SCCR_DFNL_SHIFT 0x0000004 /* DFNL shift value */
#define SCCR_RTSEL 0x00100000 /* RTC circuit input source select */
#define SCCR_EBDF00 0x00000000 /* Division factor 1. CLKOUT is GCLK2 */
#define SCCR_EBDF11 0x00060000 /* reserved */
#define SCCR_TBS 0x02000000 /* Time Base Source */
#define SCCR_RTDIV 0x01000000 /* RTC Clock Divide */
#define SCCR_COM00 0x00000000 /* full strength CLKOUT output buffer */
#define SCCR_DFNL000 0x00000000 /* Division by 2 (default = minimum) */
#define SCCR_DFNH000 0x00000000 /* Division by 1 (default = minimum) */
/*-----------------------------------------------------------------------
* MC - Memory Controller
*/
#define BR_V 0x00000001 /* Bank valid */
#define BR_BI 0x00000002 /* Burst inhibit */
#define BR_PS_8 0x00000400 /* 8 bit port size */
#define BR_PS_16 0x00000800 /* 16 bit port size */
#define BR_PS_32 0x00000000 /* 32 bit port size */
#define BR_LBDIR 0x00000008 /* Late burst data in progess */
#define OR_SCY_3 0x00000030 /* 3 clock cycles wait states */
#define OR_SCY_1 0x00000000 /* 1 clock cycle wait state */
#define OR_SCY_8 0x00000080 /* 8 clock cycles wait states */
#define OR_TRLX 0x00000001 /* Timing relaxed */
#define OR_BSCY 0x00000060 /* Burst beats length in clocks */
#define OR_ACS_10 0x00000600 /* Adress to chip-select setup */
#define OR_CSNT 0x00000800 /* Chip-select negotation time */
#define OR_ETHR 0x00000000 /* Extended hold time on read */
#define OR_ADDR_MK_FF 0xFF000000
#define OR_ADDR_MK_FFFF 0xFFFF0000
/*-----------------------------------------------------------------------
* UMCR - UIMB Module Configuration Register
*/
#define UMCR_FSPEED 0x00000000 /* Full speed. Opposit of UMCR_HSPEED */
#define UMCR_HSPEED 0x10000000 /* Half speed */
/*-----------------------------------------------------------------------
* ICTRL - I-Bus Support Control Register
*/
#define ICTRL_ISCT_SER_7 0x00000007 /* All indirect change of flow */
#define NR_IRQS 0 /* Place this later in a separate file */
/*-----------------------------------------------------------------------
* SCI - Serial communication interface
*/
#define SCI_TDRE 0x0100 /* Transmit data register empty */
#define SCI_TE 0x0008 /* Transmitter enabled */
#define SCI_RE 0x0004 /* Receiver enabled */
#define SCI_RDRF 0x0040 /* Receive data register full */
#define SCI_PE 0x0400 /* Parity enable */
#define SCI_SCXBR_MK 0x1fff /* Baudrate mask */
#define SCI_SCXDR_MK 0x00ff /* Data register mask */
#define SCI_M_11 0x0200 /* Frame size is 11 bit */
#define SCI_M_10 0x0000 /* Frame size is 10 bit */
#define SCI_PORT_1 ((int)1) /* Place this later somewhere better */
#define SCI_PORT_2 ((int)2)
#endif /* __MPC5XX_H__ */

View File

@ -110,6 +110,18 @@
#endif /* CONFIG_8xx, CONFIG_MPC824X */
#if defined(CONFIG_5xx)
/* Some special purpose registers */
#define DER 149 /* Debug Enable Register */
#define COUNTA 150 /* Breakpoint Counter */
#define COUNTB 151 /* Breakpoint Counter */
#define LCTRL1 156 /* Load/Store Support */
#define LCTRL2 157 /* Load/Store Support */
#define ICTRL 158 /* I-Bus Support Control Register */
#define EID 81
#endif /* CONFIG_5xx */
#if defined(CONFIG_8xx)
/* Registers in the processor's internal memory map that we use.

View File

@ -253,6 +253,19 @@ void status_led_set (int led, int state);
# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
/***** CMI ********************************************************/
#elif defined(CONFIG_CMI)
# define STATUS_LED_DIR im_mios.mios_mpiosm32ddr
# define STATUS_LED_DAT im_mios.mios_mpiosm32dr
# define STATUS_LED_BIT 0x2000 /* Select one of the 16 possible*/
/* MIOS outputs */
# define STATUS_LED_PERIOD (CFG_HZ / 2) /* Blinking periode is 500 ms */
# define STATUS_LED_STATE STATUS_LED_BLINKING
# define STATUS_LED_ACTIVE 1 /* LED on for bit == 0 */
# define STATUS_LED_BOOT 0 /* LED 0 used for boot status */
/***** KUP4K ********************************************************/
#elif defined(CONFIG_KUP4K)

View File

@ -75,6 +75,11 @@
void reset_8xx_watchdog(volatile immap_t *immr);
#endif
/* MPC 5xx */
#if defined(CONFIG_5xx) && !defined(__ASSEMBLY__)
void reset_5xx_watchdog(volatile immap_t *immr);
#endif
/* IBM 4xx */
#if defined(CONFIG_4xx) && !defined(__ASSEMBLY__)
void reset_4xx_watchdog(void);

View File

@ -30,6 +30,9 @@
#ifdef CONFIG_8xx
#include <mpc8xx.h>
#endif
#ifdef CONFIG_5xx
#include <mpc5xx.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
#include <ide.h>
#endif
@ -160,12 +163,15 @@ static void syscalls_init (void)
*addr++ |= NR_SYSCALLS >> 16;
*addr++ |= NR_SYSCALLS & 0xFFFF;
#ifndef CONFIG_5XX
flush_cache (0x0C00, 0x10);
#endif
/* Initialize syscalls stack pointer */
addr = (ulong *) 0xCFC;
*addr = (ulong)addr;
#ifndef CONFIG_5xx
flush_cache ((ulong)addr, 0x10);
#endif
}
/*
@ -199,7 +205,6 @@ static int init_baudrate (void)
gd->baudrate = (i > 0)
? (int) simple_strtoul (tmp, NULL, 10)
: CONFIG_BAUDRATE;
return (0);
}
@ -496,7 +501,7 @@ void board_init_f (ulong bootflag)
bd->bi_sramsize = 0; /* FIXME */ /* size of SRAM memory */
#endif
#if defined(CONFIG_8xx) || defined(CONFIG_8260)
#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx)
bd->bi_immr_base = CFG_IMMR; /* base of IMMR register */
#endif

View File

@ -23,8 +23,10 @@
#include <common.h>
void flush_cache (ulong start_addr, ulong size)
{
#ifndef CONFIG_5xx
ulong addr, end_addr = start_addr + size;
if (CFG_CACHELINE_SIZE) {
@ -44,4 +46,5 @@ void flush_cache (ulong start_addr, ulong size)
}
asm ("sync"); /* Always flush prefetch queue in any case */
asm ("isync");
#endif
}

View File

@ -80,7 +80,7 @@ unsigned long ticks2usec(unsigned long ticks)
int init_timebase (void)
{
#ifdef CONFIG_8xx
#if defined(CONFIG_5xx) || defined(CONFIG_8xx)
volatile immap_t *immap = (immap_t *) CFG_IMMR;
/* unlock */
@ -90,7 +90,7 @@ int init_timebase (void)
/* reset */
asm ("li 3,0 ; mttbu 3 ; mttbl 3 ;");
#ifdef CONFIG_8xx
#if defined(CONFIG_5xx) || defined(CONFIG_8xx)
/* enable */
immap->im_sit.sit_tbscr |= TBSCR_TBE;
#endif