* Add support for IceCube board (with MGT5100 and MPC5200 CPUs)

* Add support for MGT5100 and MPC5200 processors
master
wdenk 21 years ago
parent cb4dbb7bbc
commit 945af8d723
  1. 11
      CHANGELOG
  2. 2
      MAINTAINERS
  3. 13
      MAKEALL
  4. 16
      Makefile
  5. 47
      board/icecube/Makefile
  6. 31
      board/icecube/config.mk
  7. 480
      board/icecube/flash.c
  8. 116
      board/icecube/icecube.c
  9. 122
      board/icecube/u-boot.lds
  10. 1
      board/sl8245/u-boot.lds
  11. 1
      common/cmd_bdinfo.c
  12. 4
      common/cmd_bootm.c
  13. 1
      cpu/arm925t/interrupts.c
  14. 1
      cpu/arm925t/start.S
  15. 45
      cpu/mpc5xxx/Makefile
  16. 27
      cpu/mpc5xxx/config.mk
  17. 103
      cpu/mpc5xxx/cpu.c
  18. 185
      cpu/mpc5xxx/cpu_init.c
  19. 944
      cpu/mpc5xxx/fec.c
  20. 286
      cpu/mpc5xxx/fec.h
  21. 364
      cpu/mpc5xxx/firmware_sc_task.impl.S
  22. 363
      cpu/mpc5xxx/firmware_sc_task_bestcomm.impl.S
  23. 180
      cpu/mpc5xxx/interrupts.c
  24. 128
      cpu/mpc5xxx/io.S
  25. 76
      cpu/mpc5xxx/loadtask.c
  26. 93
      cpu/mpc5xxx/sdma.h
  27. 165
      cpu/mpc5xxx/serial.c
  28. 93
      cpu/mpc5xxx/speed.c
  29. 817
      cpu/mpc5xxx/start.S
  30. 246
      cpu/mpc5xxx/traps.c
  31. 4
      include/asm-ppc/global_data.h
  32. 7
      include/asm-ppc/u-boot.h
  33. 3
      include/common.h
  34. 173
      include/configs/IceCube.h
  35. 1
      include/configs/omap1510.h
  36. 467
      include/mpc5xxx.h
  37. 5
      include/ppc_asm.tmpl
  38. 14
      lib_ppc/board.c
  39. 4
      net/eth.c

@ -1,4 +1,15 @@
======================================================================
Changes for U-Boot 0.4.4:
======================================================================
* Add support for IceCube board (with MGT5100 and MPC5200 CPUs)
* Add support for MGT5100 and MPC5200 processors
* Patch by Lutz Dennig, 15 Jul 2003:
update for R360MPI board
======================================================================
Changes for U-Boot 0.4.3:
======================================================================

@ -52,6 +52,8 @@ Wolfgang Denk <wd@denx.de>
FPS850L MPC850
FPS860L MPC860
ICU862 MPC862
IceCube_5100 MGT5100
IceCube_5200 MPC5200
IP860 MPC860
IVML24 MPC860
IVML24_128 MPC860

@ -19,6 +19,14 @@ LIST_5xx=" \
"
#########################################################################
## MPC5xxx Systems
#########################################################################
LIST_5xxx=" \
IceCube_5100 IceCube_5200 \
"
#########################################################################
## MPC8xx Systems
#########################################################################
@ -87,7 +95,8 @@ LIST_7xx=" \
BAB7xx ELPPC \
"
LIST_ppc="${LIST_5xx} ${LIST_8xx} \
LIST_ppc="${LIST_5xx} ${LIST_5xxx} \
${LIST_8xx} \
${LIST_824x} ${LIST_8260} \
${LIST_4xx} \
${LIST_74xx} ${LIST_7xx}"
@ -159,7 +168,7 @@ build_target() {
for arg in $@
do
case "$arg" in
5xx|8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|pxa|mips|I486|x86)
5xx|5xxx|8xx|824x|8260|4xx|7xx|74xx|SA|ARM7|ARM9|ppc|arm|pxa|mips|I486|x86)
for target in `eval echo '$LIST_'${arg}`
do
build_target ${target}

@ -182,6 +182,22 @@ cmi_mpc5xx_config: unconfig
@./mkconfig $(@:_config=) ppc mpc5xx cmi
#########################################################################
## MPC5xxx Systems
#########################################################################
IceCube_5200_config \
IceCube_5100_config: unconfig
@ >include/config.h
@[ -z "$(findstring _5200,$@)" ] || \
{ echo "#define CONFIG_MPC5200" >>include/config.h ; \
echo "... with MPC5200 processor" ; \
}
@[ -z "$(findstring _5100,$@)" ] || \
{ echo "#define CONFIG_MGT5100" >>include/config.h ; \
echo "... with MGT5100 processor" ; \
}
@./mkconfig -a IceCube ppc mpc5xxx icecube
#########################################################################
## MPC8xx Systems
#########################################################################

@ -0,0 +1,47 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := $(BOARD).o flash.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS)
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
#########################################################################

@ -0,0 +1,31 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
#
# IceCube board
#
TEXT_BASE = 0xfff00000
# TEXT_BASE = 0x00100000
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board

@ -0,0 +1,480 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
* has nothing to do with the flash chip being 8-bit or 16-bit.
*/
#ifdef CONFIG_FLASH_16BIT
typedef unsigned short FLASH_PORT_WIDTH;
typedef volatile unsigned short FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFFFF
#else
typedef unsigned char FLASH_PORT_WIDTH;
typedef volatile unsigned char FLASH_PORT_WIDTHV;
#define FLASH_ID_MASK 0xFF
#endif
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define ORMASK(size) ((-size) & OR_AM_MSK)
#define FLASH_CYCLE1 0x0555
#define FLASH_CYCLE2 0x02aa
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size(FPWV *addr, flash_info_t *info);
static void flash_reset(flash_info_t *info);
static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
static flash_info_t *flash_get_info(ulong base);
/*-----------------------------------------------------------------------
* flash_init()
*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long flash_init (void)
{
unsigned long size = 0;
int i;
extern void flash_preinit(void);
flash_preinit();
/* Init: no FLASHes known */
for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
ulong flashbase = CFG_FLASH_BASE;
memset(&flash_info[i], 0, sizeof(flash_info_t));
flash_info[i].size =
flash_get_size((FPW *)flashbase, &flash_info[i]);
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
i, flash_info[i].size);
}
size += flash_info[i].size;
}
#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
/* monitor protection ON by default */
flash_protect(FLAG_PROTECT_SET,
CFG_MONITOR_BASE,
CFG_MONITOR_BASE+monitor_flash_len-1,
flash_get_info(CFG_MONITOR_BASE));
#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_SIZE-1,
flash_get_info(CFG_ENV_ADDR));
#endif
return size ? size : 1;
}
/*-----------------------------------------------------------------------
*/
static void flash_reset(flash_info_t *info)
{
FPWV *base = (FPWV *)(info->start[0]);
/* Put FLASH back in read mode */
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
*base = (FPW)0x00FF00FF; /* Intel Read Mode */
else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
*base = (FPW)0x00F000F0; /* AMD Read Mode */
}
/*-----------------------------------------------------------------------
*/
static flash_info_t *flash_get_info(ulong base)
{
int i;
flash_info_t * info;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
info = & flash_info[i];
if (info->start[0] <= base && base <= info->start[0] + info->size - 1)
break;
}
return i == CFG_MAX_FLASH_BANKS ? 0 : info;
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t *info)
{
int i;
uchar *boottype;
uchar *bootletter;
uchar *fmt;
uchar botbootletter[] = "B";
uchar topbootletter[] = "T";
uchar botboottype[] = "bottom boot sector";
uchar topboottype[] = "top boot sector";
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_BM: printf ("BRIGHT MICRO "); 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;
default: printf ("Unknown Vendor "); break;
}
/* check for top or bottom boot, if it applies */
if (info->flash_id & FLASH_BTYPE) {
boottype = botboottype;
bootletter = botbootletter;
}
else {
boottype = topboottype;
bootletter = topbootletter;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AMDLV065D:
fmt = "29LV065 (64 Mbit, uniform sectors)\n";
break;
default:
fmt = "Unknown Chip Type\n";
break;
}
printf (fmt, bootletter, boottype);
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20,
info->sector_count);
printf (" Sector Start Addresses:");
for (i=0; i<info->sector_count; ++i) {
if ((i % 5) == 0) {
printf ("\n ");
}
printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
}
/*-----------------------------------------------------------------------
*/
/*
* The following code cannot be run from FLASH!
*/
ulong flash_get_size (FPWV *addr, flash_info_t *info)
{
int i;
/* Write auto select command: read Manufacturer ID */
/* Write auto select command sequence and test FLASH answer */
addr[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE2] = (FPW)0x00550055; /* for AMD, Intel ignores this */
addr[FLASH_CYCLE1] = (FPW)0x00900090; /* selects Intel or AMD */
/* The manufacturer codes are only 1 byte, so just use 1 byte.
* This works for any bus width and any FLASH device width.
*/
udelay(100);
switch (addr[0] & 0xff) {
case (uchar)AMD_MANUFACT:
info->flash_id = FLASH_MAN_AMD;
break;
case (uchar)INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
break;
}
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN) switch ((FPW)addr[1]) {
case (FPW)AMD_ID_LV065D:
info->flash_id += FLASH_AMDLV065D;
info->sector_count = 128;
info->size = 0x00800000;
for( i = 0; i < info->sector_count; i++ )
info->start[i] = (ulong)addr + (i * 0x10000);
break; /* => 8 or 16 MB */
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (0); /* => no or unknown flash */
}
/* Put FLASH back in read mode */
flash_reset(info);
return (info->size);
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
FPWV *addr;
int flag, prot, sect;
int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
ulong start, now, last;
int rcode = 0;
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;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_AMDLV065D:
break;
case FLASH_UNKNOWN:
default:
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
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");
}
last = get_timer(0);
/* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
if (info->protect[sect] != 0) /* protected, skip it */
continue;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
addr = (FPWV *)(info->start[sect]);
if (intel) {
*addr = (FPW)0x00500050; /* clear status register */
*addr = (FPW)0x00200020; /* erase setup */
*addr = (FPW)0x00D000D0; /* erase confirm */
}
else {
/* must be AMD style if not Intel */
FPWV *base; /* first address in bank */
base = (FPWV *)(info->start[0]);
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00800080; /* erase mode */
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
*addr = (FPW)0x00300030; /* erase sector */
}
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer(0);
/* wait at least 50us for AMD, 80us for Intel.
* Let's wait 1 ms.
*/
udelay (1000);
while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
if (intel) {
/* suspend erase */
*addr = (FPW)0x00B000B0;
}
flash_reset(info); /* reset to read mode */
rcode = 1; /* failed */
break;
}
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) {/* every second */
putc ('.');
last = get_timer(0);
}
}
/* show that we're waiting */
if ((get_timer(last)) > CFG_HZ) { /* every second */
putc ('.');
last = get_timer(0);
}
flash_reset(info); /* reset to read mode */
}
printf (" done\n");
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
int bytes; /* number of bytes to program in current word */
int left; /* number of bytes left to program */
int i, res;
for (left = cnt, res = 0;
left > 0 && res == 0;
addr += sizeof(data), left -= sizeof(data) - bytes) {
bytes = addr & (sizeof(data) - 1);
addr &= ~(sizeof(data) - 1);
/* combine source and destination data so can program
* an entire word of 16 or 32 bits
*/
for (i = 0; i < sizeof(data); i++) {
data <<= 8;
if (i < bytes || i - bytes >= left )
data += *((uchar *)addr + i);
else
data += *src++;
}
/* write one word to the flash */
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_AMD:
res = write_word_amd(info, (FPWV *)addr, data);
break;
default:
/* unknown flash type, error! */
printf ("missing or unknown FLASH type\n");
res = 1; /* not really a timeout, but gives error */
break;
}
}
return (res);
}
/*-----------------------------------------------------------------------
* Write a word to Flash for AMD FLASH
* A word is 16 or 32 bits, whichever the bus width of the flash bank
* (not an individual chip) is.
*
* returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
{
ulong start;
int flag;
int res = 0; /* result, assume success */
FPWV *base; /* first address in flash bank */
/* Check if Flash is (sufficiently) erased */
if ((*dest & data) != data) {
return (2);
}
base = (FPWV *)(info->start[0]);
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
base[FLASH_CYCLE1] = (FPW)0x00AA00AA; /* unlock */
base[FLASH_CYCLE2] = (FPW)0x00550055; /* unlock */
base[FLASH_CYCLE1] = (FPW)0x00A000A0; /* selects program mode */
*dest = data; /* start programming the data */
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
/* data polling for D7 */
while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
*dest = (FPW)0x00F000F0; /* reset bank */
res = 1;
}
}
return (res);
}

@ -0,0 +1,116 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc5xxx.h>
long int initdram (int board_type)
{
#ifndef CFG_RAMBOOT
/* configure SDRAM start/end */
#if defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x00000018;/* 32M at 0x0 */
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x02000000;/* disabled */
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
/* unlock mode register */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x408d0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002;
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
/* normal operation */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000;
#elif defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
*(vu_long *)MPC5XXX_SDRAM_STOP = 0x000007ff;/* 64M */
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
/* setup config registers */
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2222600;
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
/* address select register */
*(vu_long *)MPC5XXX_SDRAM_XLBSEL = 0x03000000;
/* unlock mode register */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0002;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
/* precharge all banks */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0002;
/* auto refresh */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd14f0004;
/* set mode register */
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
/* normal operation */
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x514f0000;
#endif
#else
#ifdef CONFIG_MGT5100
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
#endif
#endif
/* return total ram size */
#if defined(CONFIG_MGT5100)
return (64 * 1024 * 1024);
#elif defined(CONFIG_MPC5200)
return (32 * 1024 * 1024);
#endif
}
int checkboard (void)
{
#if defined(CONFIG_MPC5200)
puts ("Board: Motorola MPC5200 (IceCube)\n");
#elif defined(CONFIG_MGT5100)
puts ("Board: Motorola MGT5100 (IceCube)\n");
#endif
return 0;
}
void flash_preinit(void)
{
/*
* Now, when we are in RAM, enable flash write
* access for detection process.
* Note that CS_BOOT cannot be cleared when
* executing in flash.
*/
#if defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
*(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
#endif
*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
}

@ -0,0 +1,122 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
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 :
{
cpu/mpc5xxx/start.o (.text)
*(.text)
*(.fixup)
*(.got1)
. = ALIGN(16);
*(.rodata)
*(.rodata1)
*(.rodata.str1.4)
}
.fini : { *(.fini) } =0
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
*(.got)
_GOT2_TABLE_ = .;
*(.got2)
_FIXUP_TABLE_ = .;
*(.fixup)
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data)
*(.data1)
*(.sdata)
*(.sdata2)
*(.dynamic)
CONSTRUCTORS
}
_edata = .;
PROVIDE (edata = .);
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(4096);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
__bss_start = .;
.bss :
{
*(.sbss) *(.scommon)
*(.dynbss)
*(.bss)
*(COMMON)
}
_end = . ;
PROVIDE (end = .);
}

@ -129,4 +129,3 @@ SECTIONS
_end = . ;
PROVIDE (end = .);
}

@ -178,4 +178,3 @@ U_BOOT_CMD(
NULL
);
#endif /* CFG_CMD_BDI */

@ -481,6 +481,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
kbd->bi_sccfreq /= 1000000L;
kbd->bi_vco /= 1000000L;
#endif /* CONFIG_8260 */
#if defined(CONFIG_MPC5XXXX)
kbd->bi_ipbfreq /= 1000000L;
kbd->bi_pcifreq /= 1000000L;
#endif /* CONFIG_MPC5XXXX */
}
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))hdr->ih_ep;

@ -85,7 +85,6 @@ int disable_interrupts (void)
#endif
void bad_mode (void)
{
panic ("Resetting CPU ...\n");

@ -31,7 +31,6 @@
*/
#include <config.h>
#include <version.h>

@ -0,0 +1,45 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.o
ASOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
OBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \
loadtask.o fec.o
all: .depend $(START) $(ASOBJS) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(ASOBJS) $(OBJS)
#########################################################################
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

@ -0,0 +1,27 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14 -meabi
PLATFORM_CPPFLAGS += -DCONFIG_MPC5XXX -ffixed-r2 -ffixed-r29 \
-mstring -mcpu=603e -mmultiple

@ -0,0 +1,103 @@
/*
* (C) Copyright 2000-2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* CPU specific code for the MPC5xxx CPUs
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <mpc5xxx.h>
#include <asm/processor.h>
int checkcpu (void)
{
DECLARE_GLOBAL_DATA_PTR;
ulong clock = gd->cpu_clk;
char buf[32];
puts ("CPU: ");
printf (CPU_ID_STR);
printf (" (JTAG ID %08lx)", *(vu_long *)MPC5XXX_CDM_JTAGID);
printf (" at %s MHz\n", strmhz (buf, clock));
return 0;
}
/* ------------------------------------------------------------------------- */
int
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
ulong msr, addr;
*(vu_long *)MPC5XXX_CDM_SRESET &= ~(1 << 16); /* Checkstop Reset enable */
/* Interrupts and MMU off */
__asm__ __volatile__ ("mfmsr %0":"=r" (msr):);
msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
__asm__ __volatile__ ("mtmsr %0"::"r" (msr));
/*
* 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.
*/
addr = CFG_MONITOR_BASE - sizeof (ulong);
#endif
((void (*)(void)) addr) ();
return 1;
}
/* ------------------------------------------------------------------------- */
/*
* Get timebase clock frequency (like cpu_clk in Hz)
*
*/
unsigned long get_tbclk (void)
{
DECLARE_GLOBAL_DATA_PTR;
ulong tbclk;
tbclk = (gd->bus_clk + 3L) / 4L;
return (tbclk);
}
/* ------------------------------------------------------------------------- */

@ -0,0 +1,185 @@
/*
* (C) Copyright 2000-2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc5xxx.h>
#if defined(CONFIG_MGT5100)
#define START_REG(start) ((start) >> 15)
#define STOP_REG(start, size) (((start) + (size) - 1) >> 15)
#elif defined(CONFIG_MPC5200)
#define START_REG(start) ((start) >> 16)
#define STOP_REG(start, size) (((start) + (size) - 1) >> 16)
#endif
/*
* Breath some life into the CPU...
*
* Set up the memory map,
* initialize a bunch of registers.
*/
void cpu_init_f (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned long addecr = (1 << 25); /* Boot_CS */
#if defined(CFG_RAMBOOT) && defined(CONFIG_MGT5100)
addecr |= (1 << 22); /* SDRAM enable */
#endif
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
/* Clear initial global data */
memset ((void *) gd, 0, sizeof (gd_t));
/*
* Memory Controller: configure chip selects and enable them
*/
#if defined(CFG_BOOTCS_START) && defined(CFG_BOOTCS_SIZE)
*(vu_long *)MPC5XXX_BOOTCS_START = START_REG(CFG_BOOTCS_START);
*(vu_long *)MPC5XXX_BOOTCS_STOP = STOP_REG(CFG_BOOTCS_START,
CFG_BOOTCS_SIZE);
#endif
#if defined(CFG_BOOTCS_CFG)
*(vu_long *)MPC5XXX_BOOTCS_CFG = CFG_BOOTCS_CFG;
#endif
#if defined(CFG_CS0_START) && defined(CFG_CS0_SIZE)
*(vu_long *)MPC5XXX_CS0_START = START_REG(CFG_CS0_START);
*(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(CFG_CS0_START, CFG_CS0_SIZE);
/* CS0 and BOOT_CS cannot be enabled at once. */
/* addecr |= (1 << 16); */
#endif
#if defined(CFG_CS0_CFG)
*(vu_long *)MPC5XXX_CS0_CFG = CFG_CS0_CFG;
#endif
#if defined(CFG_CS1_START) && defined(CFG_CS1_SIZE)
*(vu_long *)MPC5XXX_CS1_START = START_REG(CFG_CS1_START);
*(vu_long *)MPC5XXX_CS1_STOP = STOP_REG(CFG_CS1_START, CFG_CS1_SIZE);
addecr |= (1 << 17);
#endif
#if defined(CFG_CS1_CFG)
*(vu_long *)MPC5XXX_CS1_CFG = CFG_CS1_CFG;
#endif
#if defined(CFG_CS2_START) && defined(CFG_CS2_SIZE)
*(vu_long *)MPC5XXX_CS2_START = START_REG(CFG_CS2_START);
*(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CFG_CS2_START, CFG_CS2_SIZE);
addecr |= (1 << 18);
#endif
#if defined(CFG_CS2_CFG)
*(vu_long *)MPC5XXX_CS2_CFG = CFG_CS2_CFG;
#endif
#if defined(CFG_CS3_START) && defined(CFG_CS3_SIZE)
*(vu_long *)MPC5XXX_CS3_START = START_REG(CFG_CS3_START);
*(vu_long *)MPC5XXX_CS3_STOP = STOP_REG(CFG_CS3_START, CFG_CS3_SIZE);
addecr |= (1 << 19);
#endif
#if defined(CFG_CS3_CFG)
*(vu_long *)MPC5XXX_CS3_CFG = CFG_CS3_CFG;
#endif
#if defined(CFG_CS4_START) && defined(CFG_CS4_SIZE)
*(vu_long *)MPC5XXX_CS4_START = START_REG(CFG_CS4_START);
*(vu_long *)MPC5XXX_CS4_STOP = STOP_REG(CFG_CS4_START, CFG_CS4_SIZE);
addecr |= (1 << 20);
#endif
#if defined(CFG_CS4_CFG)
*(vu_long *)MPC5XXX_CS4_CFG = CFG_CS4_CFG;
#endif
#if defined(CFG_CS5_START) && defined(CFG_CS5_SIZE)
*(vu_long *)MPC5XXX_CS5_START = START_REG(CFG_CS5_START);
*(vu_long *)MPC5XXX_CS5_STOP = STOP_REG(CFG_CS5_START, CFG_CS5_SIZE);
addecr |= (1 << 21);
#endif
#if defined(CFG_CS5_CFG)
*(vu_long *)MPC5XXX_CS5_CFG = CFG_CS5_CFG;
#endif
#if defined(CONFIG_MPC5200)
addecr |= 1;
#if defined(CFG_CS6_START) && defined(CFG_CS6_SIZE)
*(vu_long *)MPC5XXX_CS6_START = START_REG(CFG_CS6_START);
*(vu_long *)MPC5XXX_CS6_STOP = STOP_REG(CFG_CS6_START, CFG_CS6_SIZE);
addecr |= (1 << 26);
#endif
#if defined(CFG_CS6_CFG)
*(vu_long *)MPC5XXX_CS6_CFG = CFG_CS6_CFG;
#endif
#if defined(CFG_CS7_START) && defined(CFG_CS7_SIZE)
*(vu_long *)MPC5XXX_CS7_START = START_REG(CFG_CS5_START);
*(vu_long *)MPC5XXX_CS7_STOP = STOP_REG(CFG_CS7_START, CFG_CS7_SIZE);
addecr |= (1 << 27);
#endif
#if defined(CFG_CS7_CFG)
*(vu_long *)MPC5XXX_CS7_CFG = CFG_CS7_CFG;
#endif
#if defined(CFG_CS_BURST)
*(vu_long *)MPC5XXX_CS_BURST = CFG_CS_BURST;
#endif
#if defined(CFG_CS_DEADCYCLE)
*(vu_long *)MPC5XXX_CS_DEADCYCLE = CFG_CS_DEADCYCLE;
#endif
#endif /* CONFIG_MPC5200 */
/* Enable chip selects */
*(vu_long *)MPC5XXX_ADDECR = addecr;
*(vu_long *)MPC5XXX_CS_CTRL = (1 << 24);
/* Setup pin multiplexing */
#if defined(CFG_GPS_PORT_CONFIG)
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG = CFG_GPS_PORT_CONFIG;
#endif
}
/*
* initialize higher level parts of CPU like time base and timers
*/
int cpu_init_r (void)
{
/* mask all interrupts */
#if defined(CONFIG_MGT5100)
*(vu_long *)MPC5XXX_ICTL_PER_MASK = 0xfffffc00;
#elif defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_ICTL_PER_MASK = 0xffffff00;
#endif
*(vu_long *)MPC5XXX_ICTL_CRIT |= 0x0001ffff;
*(vu_long *)MPC5XXX_ICTL_EXT &= ~0x00000f00;
#if defined(CONFIG_MPC5200)
/* enable timebase */
*(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 13);
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC5XXX_FEC)
/* load FEC microcode */
loadtask(0, 2);
#endif
return (0);
}

@ -0,0 +1,944 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* This file is based on mpc4200fec.c,
* (C) Copyright Motorola, Inc., 2000
*/
#include <common.h>
#include <mpc5xxx.h>
#include <malloc.h>
#include <net.h>
#include <miiphy.h>
#include "sdma.h"
#include "fec.h"
#define DEBUG 0x8
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_MPC5XXX_FEC)
#if (DEBUG & 0x60)
static void tfifo_print(mpc5xxx_fec_priv *fec);
static void rfifo_print(mpc5xxx_fec_priv *fec);
#endif /* DEBUG */
#if (DEBUG & 0x40)
static uint32 local_crc32(char *string, unsigned int crc_value, int len);
#endif
/********************************************************************/
static int mpc5xxx_fec_rbd_init(mpc5xxx_fec_priv *fec)
{
int ix;
char *data;
/*
* the receive ring is located right after the transmit one
*/
for (ix = 0; ix < FEC_RBD_NUM; ix++) {
data = (char *)malloc(FEC_MAX_PKT_SIZE);
if (data == NULL) {
printf ("RBD INIT FAILED\n");
return -1;
}
fec->rbdBase[ix].status = FEC_RBD_EMPTY;
fec->rbdBase[ix].dataLength = 0;
fec->rbdBase[ix].dataPointer = (uint32)data;
}
/*
* have the last RBD to close the ring
*/
fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP;
fec->rbdIndex = 0;
return 0;
}
/********************************************************************/
static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec)
{
int ix;
for (ix = 0; ix < FEC_TBD_NUM; ix++) {
fec->tbdBase[ix].status = 0;
}
/*
* Have the last TBD to close the ring
*/
fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP;
/*
* Initialize some indices
*/
fec->tbdIndex = 0;
fec->usedTbdIndex = 0;
fec->cleanTbdNum = FEC_TBD_NUM;
}
/********************************************************************/
static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, FEC_RBD * pRbd)
{
/*
* Reset buffer descriptor as empty
*/
if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
else
pRbd->status = FEC_RBD_EMPTY;
pRbd->dataLength = 0;
/*
* Now, we have an empty RxBD, restart the SmartDMA receive task
*/
SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
/*
* Increment BD count
*/
fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
}
/********************************************************************/
static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec)
{
FEC_TBD *pUsedTbd;
#if (DEBUG & 0x1)
printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
fec->cleanTbdNum, fec->usedTbdIndex);
#endif
/*
* process all the consumed TBDs
*/
while (fec->cleanTbdNum < FEC_TBD_NUM) {
pUsedTbd = &fec->tbdBase[fec->usedTbdIndex];
if (pUsedTbd->status & FEC_TBD_READY) {
#if (DEBUG & 0x20)
printf("Cannot clean TBD %d, in use\n", fec->cleanTbdNum);
#endif
return;
}
/*
* clean this buffer descriptor
*/
if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
pUsedTbd->status = FEC_TBD_WRAP;
else
pUsedTbd->status = 0;
/*
* update some indeces for a correct handling of the TBD ring
*/
fec->cleanTbdNum++;
fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
}
}
/********************************************************************/
static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac)
{
uint8 currByte; /* byte for which to compute the CRC */
int byte; /* loop - counter */
int bit; /* loop - counter */
uint32 crc = 0xffffffff; /* initial value */
/*
* The algorithm used is the following:
* we loop on each of the six bytes of the provided address,
* and we compute the CRC by left-shifting the previous
* value by one position, so that each bit in the current
* byte of the address may contribute the calculation. If
* the latter and the MSB in the CRC are different, then
* the CRC value so computed is also ex-ored with the
* "polynomium generator". The current byte of the address
* is also shifted right by one bit at each iteration.
* This is because the CRC generatore in hardware is implemented
* as a shift-register with as many ex-ores as the radixes
* in the polynomium. This suggests that we represent the
* polynomiumm itself as a 32-bit constant.
*/
for (byte = 0; byte < 6; byte++) {
currByte = mac[byte];
for (bit = 0; bit < 8; bit++) {
if ((currByte & 0x01) ^ (crc & 0x01)) {
crc >>= 1;
crc = crc ^ 0xedb88320;
} else {
crc >>= 1;
}
currByte >>= 1;
}
}
crc = crc >> 26;
/*
* Set individual hash table register
*/
if (crc >= 32) {
fec->eth->iaddr1 = (1 << (crc - 32));
fec->eth->iaddr2 = 0;
} else {
fec->eth->iaddr1 = 0;
fec->eth->iaddr2 = (1 << crc);
}
/*
* Set physical address
*/
fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
}
/********************************************************************/
static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
{
mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
const uint8 phyAddr = 0; /* Only one PHY */
#if (DEBUG & 0x1)
printf ("mpc5xxx_fec_init... Begin\n");
#endif
/*
* Initialize RxBD/TxBD rings
*/
mpc5xxx_fec_rbd_init(fec);
mpc5xxx_fec_tbd_init(fec);
/*
* Initialize GPIO pins
*/
if (fec->xcv_type == SEVENWIRE) {
/* 10MBit with 7-wire operation */
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000;
} else {
/* 100MBit with MD operation */
*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000;
}
/*
* Clear FEC-Lite interrupt event register(IEVENT)
*/
fec->eth->ievent = 0xffffffff;
/*
* Set interrupt mask register
*/
fec->eth->imask = 0x00000000;
/*
* Set FEC-Lite receive control register(R_CNTRL):
*/
if (fec->xcv_type == SEVENWIRE) {
/*
* Frame length=1518; 7-wire mode
*/
fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */
} else {
/*
* Frame length=1518; MII mode;
*/
fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */
}
if (fec->xcv_type == SEVENWIRE) {
/*
* Set FEC-Lite transmit control register(X_CNTRL):
*/
/*fec->eth->x_cntrl = 0x00000002; */ /* half-duplex, heartbeat */
fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
} else {
/*fec->eth->x_cntrl = 0x00000006; */ /* full-duplex, heartbeat */
fec->eth->x_cntrl = 0x00000004; /* full-duplex, heartbeat disabled */
/*
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock(25Mhz)
* and do not drop the Preamble.
*/
fec->eth->mii_speed = (0x5 << 1); /* No MII for 7-wire mode */
}
/*
* Set Opcode/Pause Duration Register
*/
fec->eth->op_pause = 0x00010020; /*FIXME0xffff0020; */
/*
* Set Rx FIFO alarm and granularity value
*/
fec->eth->rfifo_cntrl = 0x0c000000;
fec->eth->rfifo_alarm = 0x0000030c;
#if (DEBUG & 0x22)
if (fec->eth->rfifo_status & 0x00700000 ) {
printf("mpc5xxx_fec_init() RFIFO error\n");
}
#endif
/*
* Set Tx FIFO granularity value
*/
fec->eth->tfifo_cntrl = 0x0c000000;
#if (DEBUG & 0x2)
printf("tfifo_status: 0x%08x\n", fec->eth->tfifo_status);
printf("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm);
#endif
/*
* Set transmit fifo watermark register(X_WMRK), default = 64
*/
fec->eth->tfifo_alarm = 0x00000080;
fec->eth->x_wmrk = 0x2;
/*
* Set individual address filter for unicast address
* and set physical address registers.
*/
mpc5xxx_fec_set_hwaddr(fec, dev->enetaddr);
/*
* Set multicast address filter
*/
fec->eth->gaddr1 = 0x00000000;
fec->eth->gaddr2 = 0x00000000;
/*
* Turn ON cheater FSM: ????
*/
fec->eth->xmit_fsm = 0x03000000;
#if defined(CONFIG_MPC5200)
/*
* Turn off COMM bus prefetch in the MGT5200 BestComm. It doesn't
* work w/ the current receive task.
*/
sdma->PtdCntrl |= 0x00000001;
#endif
/*
* Set priority of different initiators
*/
sdma->IPR0 = 7; /* always */
sdma->IPR3 = 6; /* Eth RX */
sdma->IPR4 = 5; /* Eth Tx */
/*
* Clear SmartDMA task interrupt pending bits
*/
SDMA_CLEAR_IEVENT(FEC_RECV_TASK_NO);
/*
* Set SmartDMA intMask register to enable SmartDMA task interrupts
*/
SDMA_INT_ENABLE(FEC_RECV_TASK_NO);
/*
* Initialize SmartDMA parameters stored in SRAM
*/
*(int *)FEC_TBD_BASE = (int)fec->tbdBase;
*(int *)FEC_RBD_BASE = (int)fec->rbdBase;
*(int *)FEC_TBD_NEXT = (int)fec->tbdBase;
*(int *)FEC_RBD_NEXT = (int)fec->rbdBase;
if (fec->xcv_type != SEVENWIRE) {
/*
* Initialize PHY(LXT971A):
*
* Generally, on power up, the LXT971A reads its configuration
* pins to check for forced operation, If not cofigured for
* forced operation, it uses auto-negotiation/parallel detection
* to automatically determine line operating conditions.
* If the PHY device on the other side of the link supports
* auto-negotiation, the LXT971A auto-negotiates with it
* using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
* support auto-negotiation, the LXT971A automatically detects
* the presence of either link pulses(10Mbps PHY) or Idle
* symbols(100Mbps) and sets its operating conditions accordingly.
*
* When auto-negotiation is controlled by software, the following
* steps are recommended.
*
* Note:
* The physical address is dependent on hardware configuration.
*
*/
int timeout = 1;
uint16 phyStatus;
/*
* Reset PHY, then delay 300ns
*/
miiphy_write(phyAddr, 0x0, 0x8000);
udelay(1000);
if (fec->xcv_type == MII10) {
/*
* Force 10Base-T, FDX operation
*/
printf("Forcing 10 Mbps ethernet link... ");
miiphy_read(phyAddr, 0x1, &phyStatus);
/*
miiphy_write(fec, phyAddr, 0x0, 0x0100);
*/
miiphy_write(phyAddr, 0x0, 0x0180);
timeout = 20;
do { /* wait for link status to go down */
udelay(10000);
if ((timeout--) == 0) {
#if (DEBUG & 0x2)
printf("hmmm, should not have waited...");
#endif
break;
}
miiphy_read(phyAddr, 0x1, &phyStatus);
#if (DEBUG & 0x2)
printf("=");
#endif
} while ((phyStatus & 0x0004)); /* !link up */
timeout = 1000;
do { /* wait for link status to come back up */
udelay(10000);
if ((timeout--) == 0) {
printf("failed. Link is down.\n");
break;
}
miiphy_read(phyAddr, 0x1, &phyStatus);
#if (DEBUG & 0x2)
printf("+");
#endif
} while (!(phyStatus & 0x0004)); /* !link up */
printf ("done.\n");
} else { /* MII100 */
/*
* Set the auto-negotiation advertisement register bits
*/
miiphy_write(phyAddr, 0x4, 0x01e1);
/*
* Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
*/
miiphy_write(phyAddr, 0x0, 0x1200);
/*
* Wait for AN completion
*/
timeout = 5000;
do {
udelay(1000);
if ((timeout--) == 0) {
#if (DEBUG & 0x2)
printf("PHY auto neg 0 failed...\n");
#endif
return -1;
}
if (miiphy_read(phyAddr, 0x1, &phyStatus) != 0) {
#if (DEBUG & 0x2)
printf("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
#endif
return -1;
}
} while ((phyStatus & 0x0020) != 0x0020);
#if (DEBUG & 0x2)
printf("PHY auto neg complete! \n");
#endif
}
}
/*
* Enable FEC-Lite controller
*/
fec->eth->ecntrl |= 0x00000006;
if (fec->xcv_type != SEVENWIRE) {
#if (DEBUG & 0x2)
uint16 phyStatus, i;
uint8 phyAddr = 0;
for (i = 0; i < 9; i++) {
miiphy_read(phyAddr, i, &phyStatus);
printf("Mii reg %d: 0x%04x\n", i, phyStatus);
}
for (i = 16; i < 21; i++) {
miiphy_read(phyAddr, i, &phyStatus);
printf("Mii reg %d: 0x%04x\n", i, phyStatus);
}
#endif
}
/*
* Enable SmartDMA receive task
*/
SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
#if (DEBUG & 0x1)
printf("mpc5xxx_fec_init... Done \n");
#endif
return 0;
}
/********************************************************************/
static void mpc5xxx_fec_halt(struct eth_device *dev)
{
mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
int counter = 0xffff;
#if (DEBUG & 0x2)
if (fec->xcv_type != SEVENWIRE) {
uint16 phyStatus, i;
uint8 phyAddr = 0;
for (i = 0; i < 9; i++) {
miiphy_read(phyAddr, i, &phyStatus);
printf("Mii reg %d: 0x%04x\n", i, phyStatus);
}
for (i = 16; i < 21; i++) {
miiphy_read(phyAddr, i, &phyStatus);
printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
}
}
#endif
/*
* mask FEC chip interrupts
*/
fec->eth->imask = 0;
/*
* issue graceful stop command to the FEC transmitter if necessary
*/
fec->eth->x_cntrl |= 0x00000001;
/*
* wait for graceful stop to register
*/
while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ;
SDMA_INT_DISABLE (FEC_RECV_TASK_NO);
/*
* Disable SmartDMA tasks
*/
SDMA_TASK_DISABLE (FEC_XMIT_TASK_NO);
SDMA_TASK_DISABLE (FEC_RECV_TASK_NO);
#if defined(CONFIG_MPC5200)
/*
* Turn on COMM bus prefetch in the MGT5200 BestComm after we're
* done. It doesn't work w/ the current receive task.
*/
sdma->PtdCntrl &= ~0x00000001;
#endif
/*
* Disable the Ethernet Controller
*/
fec->eth->ecntrl &= 0xfffffffd;
/*
* Clear FIFO status registers
*/
fec->eth->rfifo_status &= 0x00700000;
fec->eth->tfifo_status &= 0x00700000;
fec->eth->reset_cntrl = 0x01000000;
/*
* Issue a reset command to the FEC chip
*/
fec->eth->ecntrl |= 0x1;
/*
* wait at least 16 clock cycles
*/
udelay(10);
#if (DEBUG & 0x3)
printf("Ethernet task stopped\n");
#endif
}
#if (DEBUG & 0x60)
/********************************************************************/
static void tfifo_print(mpc5xxx_fec_priv *fec)
{
uint16 phyAddr = 0;
uint16 phyStatus;
if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
|| (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
miiphy_read(phyAddr, 0x1, &phyStatus);
printf("\nphyStatus: 0x%04x\n", phyStatus);
printf("ecntrl: 0x%08x\n", fec->eth->ecntrl);
printf("ievent: 0x%08x\n", fec->eth->ievent);
printf("x_status: 0x%08x\n", fec->eth->x_status);
printf("tfifo: status 0x%08x\n", fec->eth->tfifo_status);
printf(" control 0x%08x\n", fec->eth->tfifo_cntrl);
printf(" lrfp 0x%08x\n", fec->eth->tfifo_lrf_ptr);
printf(" lwfp 0x%08x\n", fec->eth->tfifo_lwf_ptr);
printf(" alarm 0x%08x\n", fec->eth->tfifo_alarm);
printf(" readptr 0x%08x\n", fec->eth->tfifo_rdptr);
printf(" writptr 0x%08x\n", fec->eth->tfifo_wrptr);
}
}
static void rfifo_print(mpc5xxx_fec_priv *fec)
{
uint16 phyAddr = 0;
uint16 phyStatus;
if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
|| (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
miiphy_read(phyAddr, 0x1, &phyStatus);
printf("\nphyStatus: 0x%04x\n", phyStatus);
printf("ecntrl: 0x%08x\n", fec->eth->ecntrl);
printf("ievent: 0x%08x\n", fec->eth->ievent);
printf("x_status: 0x%08x\n", fec->eth->x_status);
printf("rfifo: status 0x%08x\n", fec->eth->rfifo_status);
printf(" control 0x%08x\n", fec->eth->rfifo_cntrl);
printf(" lrfp 0x%08x\n", fec->eth->rfifo_lrf_ptr);
printf(" lwfp 0x%08x\n", fec->eth->rfifo_lwf_ptr);
printf(" alarm 0x%08x\n", fec->eth->rfifo_alarm);
printf(" readptr 0x%08x\n", fec->eth->rfifo_rdptr);
printf(" writptr 0x%08x\n", fec->eth->rfifo_wrptr);
}
}
#endif /* DEBUG */
/********************************************************************/
static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data,
int data_length)
{
/*
* This routine transmits one frame. This routine only accepts
* 6-byte Ethernet addresses.
*/
mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
FEC_TBD *pTbd;
#if (DEBUG & 0x20)
printf("tbd status: 0x%04x\n", fec->tbdBase[0].status);
tfifo_print(fec);
#endif
/*
* Clear Tx BD ring at first
*/
mpc5xxx_fec_tbd_scrub(fec);
/*
* Check for valid length of data.
*/
if ((data_length > 1500) || (data_length <= 0)) {
return -1;
}
/*
* Check the number of vacant TxBDs.
*/
if (fec->cleanTbdNum < 1) {
#if (DEBUG & 0x20)
printf("No available TxBDs ...\n");
#endif
return -1;
}
/*
* Get the first TxBD to send the mac header
*/
pTbd = &fec->tbdBase[fec->tbdIndex];
pTbd->dataLength = data_length;
pTbd->dataPointer = (uint32)eth_data;
pTbd->status |= FEC_TBD_READY;
fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
#if (DEBUG & 0x100)
printf("SDMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex);
#endif
/*
* Kick the MII i/f
*/
if (fec->xcv_type != SEVENWIRE) {
uint16 phyStatus;
miiphy_read(0, 0x1, &phyStatus);
}
/*
* Enable SmartDMA transmit task
*/
#if (DEBUG & 0x20)
tfifo_print(fec);
#endif
SDMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
#if (DEBUG & 0x20)
tfifo_print(fec);
#endif
#if (DEBUG & 0x8)
printf( "+" );
#endif
fec->cleanTbdNum -= 1;
#if (DEBUG & 0x129) && (DEBUG & 0x80000000)
printf ("smartDMA ethernet Tx task enabled\n");
#endif
/*
* wait until frame is sent .
*/
while (pTbd->status & FEC_TBD_READY) {
udelay(10);
#if (DEBUG & 0x8)
printf ("TDB status = %04x\n", pTbd->status);
#endif
}
return 0;
}
/********************************************************************/
static int mpc5xxx_fec_recv(struct eth_device *dev)
{
/*
* This command pulls one frame from the card
*/
mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
unsigned long ievent;
int frame_length;
char *frame;
#if (DEBUG & 0x1)
printf ("mpc5xxx_fec_recv %d Start...\n", fec->rbdIndex);
#endif
#if (DEBUG & 0x8)
printf( "-" );
#endif
/*
* Check if any critical events have happened
*/
ievent = fec->eth->ievent;
fec->eth->ievent = ievent;
if (ievent & 0x20060000) {
/* BABT, Rx/Tx FIFO errors */
mpc5xxx_fec_halt(dev);
mpc5xxx_fec_init(dev, NULL);
return 0;
}
if (ievent & 0x80000000) {
/* Heartbeat error */
fec->eth->x_cntrl |= 0x00000001;
}
if (ievent & 0x10000000) {
/* Graceful stop complete */
if (fec->eth->x_cntrl & 0x00000001) {
mpc5xxx_fec_halt(dev);
fec->eth->x_cntrl &= ~0x00000001;
mpc5xxx_fec_init(dev, NULL);
}
}
/*
* Do we have data in Rx FIFO?
*/
if ((pRbd->status & FEC_RBD_EMPTY) || !(pRbd->status & FEC_RBD_LAST)){
return 0;
}
/*
* Pass the packet up only if reception was Ok
*/
if ((pRbd->dataLength <= 14) || (pRbd->status & FEC_RBD_ERR)) {
mpc5xxx_fec_rbd_clean(fec, pRbd);
#if (DEBUG & 0x8)
printf( "X0" );
#endif
return 0;
}
/*
* Get buffer address and size
*/
frame = (char *)pRbd->dataPointer;
frame_length = pRbd->dataLength;
/*
* Pass the buffer to upper layers
*/
NetReceive(frame, frame_length);
/*
* Reset buffer descriptor as empty
*/
mpc5xxx_fec_rbd_clean(fec, pRbd);
return frame_length;
}
/********************************************************************/
int mpc5xxx_fec_initialize(bd_t * bis)
{
mpc5xxx_fec_priv *fec;
struct eth_device *dev;
fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
dev = (struct eth_device *)malloc(sizeof(*dev));
fec->eth = (ethernet_regs *)MPC5XXX_FEC;
fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
#ifdef CONFIG_ICECUBE
fec->xcv_type = MII100;
#endif
dev->priv = (void *)fec;
dev->iobase = MPC5XXX_FEC;
dev->init = mpc5xxx_fec_init;
dev->halt = mpc5xxx_fec_halt;
dev->send = mpc5xxx_fec_send;
dev->recv = mpc5xxx_fec_recv;
eth_register(dev);
return 1;
}
/* MII-interface related functions */
/********************************************************************/
int miiphy_read(uint8 phyAddr, uint8 regAddr, uint16 * retVal)
{
ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
uint32 reg; /* convenient holder for the PHY register */
uint32 phy; /* convenient holder for the PHY */
int timeout = 0xffff;
/*
* reading from any PHY's register is done by properly
* programming the FEC's MII data register.
*/
reg = regAddr << FEC_MII_DATA_RA_SHIFT;
phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg);
/*
* wait for the related interrupt
*/
while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
if (timeout == 0) {
#if (DEBUG & 0x2)
printf ("Read MDIO failed...\n");
#endif
return -1;
}
/*
* clear mii interrupt bit
*/
eth->ievent = 0x00800000;
/*
* it's now safe to read the PHY's register
*/
*retVal = (uint16) eth->mii_data;
return 0;
}
/********************************************************************/
int miiphy_write(uint8 phyAddr, uint8 regAddr, uint16 data)
{
ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
uint32 reg; /* convenient holder for the PHY register */
uint32 phy; /* convenient holder for the PHY */
int timeout = 0xffff;
reg = regAddr << FEC_MII_DATA_RA_SHIFT;
phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
FEC_MII_DATA_TA | phy | reg | data);
/*
* wait for the MII interrupt
*/
while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
if (timeout == 0) {
#if (DEBUG & 0x2)
printf ("Write MDIO failed...\n");
#endif
return -1;
}
/*
* clear MII interrupt bit
*/
eth->ievent = 0x00800000;
return 0;
}
#if (DEBUG & 0x40)
static uint32 local_crc32(char *string, unsigned int crc_value, int len)
{
int i;
char c;
unsigned int crc, count;
/*
* crc32 algorithm
*/
/*
* crc = 0xffffffff; * The initialized value should be 0xffffffff
*/
crc = crc_value;
for (i = len; --i >= 0;) {
c = *string++;
for (count = 0; count < 8; count++) {
if ((c & 0x01) ^ (crc & 0x01)) {
crc >>= 1;
crc = crc ^ 0xedb88320;
} else {
crc >>= 1;
}
c >>= 1;
}
}
/*
* In big endian system, do byte swaping for crc value
*/
/**/ return crc;
}
#endif /* DEBUG */
#endif /* CONFIG_MPC5XXX_FEC */

@ -0,0 +1,286 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* This file is based on mpc4200fec.h
* (C) Copyright Motorola, Inc., 2000
*
* odin ethernet header file
*/
#ifndef __MPC5XXX_FEC_H
#define __MPC5XXX_FEC_H
#include <common.h>
#include <mpc5xxx.h>
#include "sdma.h"
typedef unsigned long uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef struct ethernet_register_set {
/* [10:2]addr = 00 */
/* Control and status Registers (offset 000-1FF) */
volatile uint32 fec_id; /* MBAR_ETH + 0x000 */
volatile uint32 ievent; /* MBAR_ETH + 0x004 */
volatile uint32 imask; /* MBAR_ETH + 0x008 */
volatile uint32 RES0[1]; /* MBAR_ETH + 0x00C */
volatile uint32 r_des_active; /* MBAR_ETH + 0x010 */
volatile uint32 x_des_active; /* MBAR_ETH + 0x014 */
volatile uint32 r_des_active_cl; /* MBAR_ETH + 0x018 */
volatile uint32 x_des_active_cl; /* MBAR_ETH + 0x01C */
volatile uint32 ivent_set; /* MBAR_ETH + 0x020 */
volatile uint32 ecntrl; /* MBAR_ETH + 0x024 */
volatile uint32 RES1[6]; /* MBAR_ETH + 0x028-03C */
volatile uint32 mii_data; /* MBAR_ETH + 0x040 */
volatile uint32 mii_speed; /* MBAR_ETH + 0x044 */
volatile uint32 mii_status; /* MBAR_ETH + 0x048 */
volatile uint32 RES2[5]; /* MBAR_ETH + 0x04C-05C */
volatile uint32 mib_data; /* MBAR_ETH + 0x060 */
volatile uint32 mib_control; /* MBAR_ETH + 0x064 */
volatile uint32 RES3[6]; /* MBAR_ETH + 0x068-7C */
volatile uint32 r_activate; /* MBAR_ETH + 0x080 */
volatile uint32 r_cntrl; /* MBAR_ETH + 0x084 */
volatile uint32 r_hash; /* MBAR_ETH + 0x088 */
volatile uint32 r_data; /* MBAR_ETH + 0x08C */
volatile uint32 ar_done; /* MBAR_ETH + 0x090 */
volatile uint32 r_test; /* MBAR_ETH + 0x094 */
volatile uint32 r_mib; /* MBAR_ETH + 0x098 */
volatile uint32 r_da_low; /* MBAR_ETH + 0x09C */
volatile uint32 r_da_high; /* MBAR_ETH + 0x0A0 */
volatile uint32 RES4[7]; /* MBAR_ETH + 0x0A4-0BC */
volatile uint32 x_activate; /* MBAR_ETH + 0x0C0 */
volatile uint32 x_cntrl; /* MBAR_ETH + 0x0C4 */
volatile uint32 backoff; /* MBAR_ETH + 0x0C8 */
volatile uint32 x_data; /* MBAR_ETH + 0x0CC */
volatile uint32 x_status; /* MBAR_ETH + 0x0D0 */
volatile uint32 x_mib; /* MBAR_ETH + 0x0D4 */
volatile uint32 x_test; /* MBAR_ETH + 0x0D8 */
volatile uint32 fdxfc_da1; /* MBAR_ETH + 0x0DC */
volatile uint32 fdxfc_da2; /* MBAR_ETH + 0x0E0 */
volatile uint32 paddr1; /* MBAR_ETH + 0x0E4 */
volatile uint32 paddr2; /* MBAR_ETH + 0x0E8 */
volatile uint32 op_pause; /* MBAR_ETH + 0x0EC */
volatile uint32 RES5[4]; /* MBAR_ETH + 0x0F0-0FC */
volatile uint32 instr_reg; /* MBAR_ETH + 0x100 */
volatile uint32 context_reg; /* MBAR_ETH + 0x104 */
volatile uint32 test_cntrl; /* MBAR_ETH + 0x108 */
volatile uint32 acc_reg; /* MBAR_ETH + 0x10C */
volatile uint32 ones; /* MBAR_ETH + 0x110 */
volatile uint32 zeros; /* MBAR_ETH + 0x114 */
volatile uint32 iaddr1; /* MBAR_ETH + 0x118 */
volatile uint32 iaddr2; /* MBAR_ETH + 0x11C */
volatile uint32 gaddr1; /* MBAR_ETH + 0x120 */
volatile uint32 gaddr2; /* MBAR_ETH + 0x124 */
volatile uint32 random; /* MBAR_ETH + 0x128 */
volatile uint32 rand1; /* MBAR_ETH + 0x12C */
volatile uint32 tmp; /* MBAR_ETH + 0x130 */
volatile uint32 RES6[3]; /* MBAR_ETH + 0x134-13C */
volatile uint32 fifo_id; /* MBAR_ETH + 0x140 */
volatile uint32 x_wmrk; /* MBAR_ETH + 0x144 */
volatile uint32 fcntrl; /* MBAR_ETH + 0x148 */
volatile uint32 r_bound; /* MBAR_ETH + 0x14C */
volatile uint32 r_fstart; /* MBAR_ETH + 0x150 */
volatile uint32 r_count; /* MBAR_ETH + 0x154 */
volatile uint32 r_lag; /* MBAR_ETH + 0x158 */
volatile uint32 r_read; /* MBAR_ETH + 0x15C */
volatile uint32 r_write; /* MBAR_ETH + 0x160 */
volatile uint32 x_count; /* MBAR_ETH + 0x164 */
volatile uint32 x_lag; /* MBAR_ETH + 0x168 */
volatile uint32 x_retry; /* MBAR_ETH + 0x16C */
volatile uint32 x_write; /* MBAR_ETH + 0x170 */
volatile uint32 x_read; /* MBAR_ETH + 0x174 */
volatile uint32 RES7[2]; /* MBAR_ETH + 0x178-17C */
volatile uint32 fm_cntrl; /* MBAR_ETH + 0x180 */
volatile uint32 rfifo_data; /* MBAR_ETH + 0x184 */
volatile uint32 rfifo_status; /* MBAR_ETH + 0x188 */
volatile uint32 rfifo_cntrl; /* MBAR_ETH + 0x18C */
volatile uint32 rfifo_lrf_ptr; /* MBAR_ETH + 0x190 */
volatile uint32 rfifo_lwf_ptr; /* MBAR_ETH + 0x194 */
volatile uint32 rfifo_alarm; /* MBAR_ETH + 0x198 */
volatile uint32 rfifo_rdptr; /* MBAR_ETH + 0x19C */
volatile uint32 rfifo_wrptr; /* MBAR_ETH + 0x1A0 */
volatile uint32 tfifo_data; /* MBAR_ETH + 0x1A4 */
volatile uint32 tfifo_status; /* MBAR_ETH + 0x1A8 */
volatile uint32 tfifo_cntrl; /* MBAR_ETH + 0x1AC */
volatile uint32 tfifo_lrf_ptr; /* MBAR_ETH + 0x1B0 */
volatile uint32 tfifo_lwf_ptr; /* MBAR_ETH + 0x1B4 */
volatile uint32 tfifo_alarm; /* MBAR_ETH + 0x1B8 */
volatile uint32 tfifo_rdptr; /* MBAR_ETH + 0x1BC */
volatile uint32 tfifo_wrptr; /* MBAR_ETH + 0x1C0 */
volatile uint32 reset_cntrl; /* MBAR_ETH + 0x1C4 */
volatile uint32 xmit_fsm; /* MBAR_ETH + 0x1C8 */
volatile uint32 RES8[3]; /* MBAR_ETH + 0x1CC-1D4 */
volatile uint32 rdes_data0; /* MBAR_ETH + 0x1D8 */
volatile uint32 rdes_data1; /* MBAR_ETH + 0x1DC */
volatile uint32 r_length; /* MBAR_ETH + 0x1E0 */
volatile uint32 x_length; /* MBAR_ETH + 0x1E4 */
volatile uint32 x_addr; /* MBAR_ETH + 0x1E8 */
volatile uint32 cdes_data; /* MBAR_ETH + 0x1EC */
volatile uint32 status; /* MBAR_ETH + 0x1F0 */
volatile uint32 dma_control; /* MBAR_ETH + 0x1F4 */
volatile uint32 des_cmnd; /* MBAR_ETH + 0x1F8 */
volatile uint32 data; /* MBAR_ETH + 0x1FC */
/* MIB COUNTERS (Offset 200-2FF) */
volatile uint32 rmon_t_drop; /* MBAR_ETH + 0x200 */
volatile uint32 rmon_t_packets; /* MBAR_ETH + 0x204 */
volatile uint32 rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */
volatile uint32 rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */
volatile uint32 rmon_t_crc_align; /* MBAR_ETH + 0x210 */
volatile uint32 rmon_t_undersize; /* MBAR_ETH + 0x214 */
volatile uint32 rmon_t_oversize; /* MBAR_ETH + 0x218 */
volatile uint32 rmon_t_frag; /* MBAR_ETH + 0x21C */
volatile uint32 rmon_t_jab; /* MBAR_ETH + 0x220 */
volatile uint32 rmon_t_col; /* MBAR_ETH + 0x224 */
volatile uint32 rmon_t_p64; /* MBAR_ETH + 0x228 */
volatile uint32 rmon_t_p65to127; /* MBAR_ETH + 0x22C */
volatile uint32 rmon_t_p128to255; /* MBAR_ETH + 0x230 */
volatile uint32 rmon_t_p256to511; /* MBAR_ETH + 0x234 */
volatile uint32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */
volatile uint32 rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */
volatile uint32 rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */
volatile uint32 rmon_t_octets; /* MBAR_ETH + 0x244 */
volatile uint32 ieee_t_drop; /* MBAR_ETH + 0x248 */
volatile uint32 ieee_t_frame_ok; /* MBAR_ETH + 0x24C */
volatile uint32 ieee_t_1col; /* MBAR_ETH + 0x250 */
volatile uint32 ieee_t_mcol; /* MBAR_ETH + 0x254 */
volatile uint32 ieee_t_def; /* MBAR_ETH + 0x258 */
volatile uint32 ieee_t_lcol; /* MBAR_ETH + 0x25C */
volatile uint32 ieee_t_excol; /* MBAR_ETH + 0x260 */
volatile uint32 ieee_t_macerr; /* MBAR_ETH + 0x264 */
volatile uint32 ieee_t_cserr; /* MBAR_ETH + 0x268 */
volatile uint32 ieee_t_sqe; /* MBAR_ETH + 0x26C */
volatile uint32 t_fdxfc; /* MBAR_ETH + 0x270 */
volatile uint32 ieee_t_octets_ok; /* MBAR_ETH + 0x274 */
volatile uint32 RES9[2]; /* MBAR_ETH + 0x278-27C */
volatile uint32 rmon_r_drop; /* MBAR_ETH + 0x280 */
volatile uint32 rmon_r_packets; /* MBAR_ETH + 0x284 */
volatile uint32 rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */
volatile uint32 rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */
volatile uint32 rmon_r_crc_align; /* MBAR_ETH + 0x290 */
volatile uint32 rmon_r_undersize; /* MBAR_ETH + 0x294 */
volatile uint32 rmon_r_oversize; /* MBAR_ETH + 0x298 */
volatile uint32 rmon_r_frag; /* MBAR_ETH + 0x29C */
volatile uint32 rmon_r_jab; /* MBAR_ETH + 0x2A0 */
volatile uint32 rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */
volatile uint32 rmon_r_p64; /* MBAR_ETH + 0x2A8 */
volatile uint32 rmon_r_p65to127; /* MBAR_ETH + 0x2AC */
volatile uint32 rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */
volatile uint32 rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */
volatile uint32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */
volatile uint32 rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */
volatile uint32 rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */
volatile uint32 rmon_r_octets; /* MBAR_ETH + 0x2C4 */
volatile uint32 ieee_r_drop; /* MBAR_ETH + 0x2C8 */
volatile uint32 ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */
volatile uint32 ieee_r_crc; /* MBAR_ETH + 0x2D0 */
volatile uint32 ieee_r_align; /* MBAR_ETH + 0x2D4 */
volatile uint32 r_macerr; /* MBAR_ETH + 0x2D8 */
volatile uint32 r_fdxfc; /* MBAR_ETH + 0x2DC */
volatile uint32 ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */
volatile uint32 RES10[6]; /* MBAR_ETH + 0x2E4-2FC */
volatile uint32 RES11[64]; /* MBAR_ETH + 0x300-3FF */
} ethernet_regs;
/* Receive & Transmit Buffer Descriptor definitions */
typedef struct BufferDescriptor {
uint16 status;
uint16 dataLength;
uint32 dataPointer;
} FEC_RBD;
typedef struct {
uint16 status;
uint16 dataLength;
uint32 dataPointer;
} FEC_TBD;
/* private structure */
typedef enum {
SEVENWIRE, /* 7-wire */
MII10, /* MII 10Mbps */
MII100 /* MII 100Mbps */
} xceiver_type;
typedef struct {
ethernet_regs *eth;
xceiver_type xcv_type; /* transceiver type */
FEC_RBD *rbdBase; /* RBD ring */
FEC_TBD *tbdBase; /* TBD ring */
uint16 rbdIndex; /* next receive BD to read */
uint16 tbdIndex; /* next transmit BD to send */
uint16 usedTbdIndex; /* next transmit BD to clean */
uint16 cleanTbdNum; /* the number of available transmit BDs */
} mpc5xxx_fec_priv;
/* Ethernet parameter area */
#define FEC_TBD_BASE (FEC_PARAM_BASE + 0x00)
#define FEC_TBD_NEXT (FEC_PARAM_BASE + 0x04)
#define FEC_RBD_BASE (FEC_PARAM_BASE + 0x08)
#define FEC_RBD_NEXT (FEC_PARAM_BASE + 0x0c)
/* BD Numer definitions */
#define FEC_TBD_NUM 48 /* The user can adjust this value */
#define FEC_RBD_NUM 32 /* The user can adjust this value */
/* packet size limit */
#define FEC_MAX_PKT_SIZE 1536
/* RBD bits definitions */
#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */
#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */
#define FEC_RBD_INT 0x1000 /* Interrupt */
#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */
#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */
#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */
#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */
#define FEC_RBD_LG 0x0020 /* Frame length violation */
#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */
#define FEC_RBD_SH 0x0008 /* Short frame */
#define FEC_RBD_CR 0x0004 /* CRC error */
#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */
#define FEC_RBD_TR 0x0001 /* Frame is truncated */
#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
FEC_RBD_OV | FEC_RBD_TR)
/* TBD bits definitions */
#define FEC_TBD_READY 0x8000 /* Buffer is ready */
#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */
#define FEC_TBD_INT 0x1000 /* Interrupt */
#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */
#define FEC_TBD_TC 0x0400 /* Transmit the CRC */
#define FEC_TBD_ABC 0x0200 /* Append bad CRC */
/* MII-related definitios */
#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */
#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */
#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */
#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */
#endif /* __MPC5XXX_FEC_H */

@ -0,0 +1,364 @@
/*
* Copyright (C) 2001, Software Center, Motorola China.
*
* This file contains microcode for the FEC controller of the MGT5100 CPU.
*/
#include <config.h>
#if defined(CONFIG_MGT5100)
/* sas/sccg, gas target */
.section smartdmaInitData,"aw",@progbits /* Initialized data for task variables */
.section smartdmaTaskTable,"aw",@progbits /* Task tables */
.globl taskTable
taskTable:
.globl scEthernetRecv_Entry
scEthernetRecv_Entry: /* Task 0 */
.long scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */
.long scEthernetRecv_TDT - taskTable + 0x000000a4
.long scEthernetRecv_VarTab - taskTable /* Task 0 Variable Table */
.long scEthernetRecv_FDT - taskTable + 0x03 /* Task 0 Function Descriptor Table & Flags */
.long 0x00000000
.long 0x00000000
.long scEthernetRecv_CSave - taskTable /* Task 0 context save space */
.long 0xf0000000
.globl scEthernetXmit_Entry
scEthernetXmit_Entry: /* Task 1 */
.long scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */
.long scEthernetXmit_TDT - taskTable + 0x000000d0
.long scEthernetXmit_VarTab - taskTable /* Task 1 Variable Table */
.long scEthernetXmit_FDT - taskTable + 0x03 /* Task 1 Function Descriptor Table & Flags */
.long 0x00000000
.long 0x00000000
.long scEthernetXmit_CSave - taskTable /* Task 1 context save space */
.long 0xf0000000
.globl scEthernetRecv_TDT
scEthernetRecv_TDT: /* Task 0 Descriptor Table */
.long 0xc4c50000 /* 0000: LCDEXT: idx0 = var9 + var10; idx0 once var0; idx0 += inc0 */
.long 0x84c5e000 /* 0004: LCD: idx1 = var9 + var11; ; idx1 += inc0 */
.long 0x10001f08 /* 0008: DRD1A: var7 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x10000380 /* 000C: DRD1A: var0 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000f88 /* 0010: DRD1A: var3 = *idx1; FN=0 init=0 WS=0 RS=0 */
.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x010c504c /* 0020: DRD2B1: var4 = EU1(); EU1(var1,var12) */
.long 0x82180349 /* 0024: LCD: idx0 = var4; idx0 != var13; idx0 += inc1 */
.long 0x81c68004 /* 0028: LCD: idx1 = var3 + var13 + 4; idx1 once var0; idx1 += inc0 */
.long 0x70000000 /* 002C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x018c504e /* 0030: DRD2B1: var6 = EU1(); EU1(var1,var14) */
.long 0x70000000 /* 0034: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x020c504f /* 0038: DRD2B1: var8 = EU1(); EU1(var1,var15) */
.long 0x00000b88 /* 003C: DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */
.long 0x8000d184 /* 0040: LCDEXT: idx1 = 0xf0003184; ; */
.long 0xc6990452 /* 0044: LCDEXT: idx2 = var13; idx2 < var17; idx2 += inc2 */
.long 0x81486010 /* 0048: LCD: idx3 = var2 + var16; ; idx3 += inc2 */
.long 0x006acf88 /* 004C: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */
.long 0x8000d184 /* 0050: LCDEXT: idx1 = 0xf0003184; ; */
.long 0x86810492 /* 0054: LCD: idx2 = var13, idx3 = var2; idx2 < var18; idx2 += inc2, idx3 += inc2 */
.long 0x006acf88 /* 0058: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */
.long 0x8000d184 /* 005C: LCDEXT: idx1 = 0xf0003184; ; */
.long 0x868184d2 /* 0060: LCD: idx2 = var13, idx3 = var3; idx2 < var19; idx2 += inc2, idx3 += inc2 */
.long 0x000acf88 /* 0064: DRD1A: *idx3 = *idx1; FN=0 init=0 WS=1 RS=1 */
.long 0xc318839b /* 0068: LCDEXT: idx1 = var6; idx1 == var14; idx1 += inc3 */
.long 0x80190000 /* 006C: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
.long 0x04008468 /* 0070: DRD1A: idx1 = var13; FN=0 INT init=0 WS=0 RS=0 */
.long 0xc4038358 /* 0074: LCDEXT: idx1 = var8, idx2 = var7; idx1 == var13; idx1 += inc3, idx2 += inc0 */
.long 0x81c50000 /* 0078: LCD: idx3 = var3 + var10; idx3 once var0; idx3 += inc0 */
.long 0x1000cb18 /* 007C: DRD1A: *idx2 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000f18 /* 0080: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
.long 0xc4188364 /* 0084: LCDEXT: idx1 = var8; idx1 > var13; idx1 += inc4 */
.long 0x83990000 /* 0088: LCD: idx2 = var7; idx2 once var0; idx2 += inc0 */
.long 0x10000c00 /* 008C: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x0000c800 /* 0090: DRD1A: *idx2 = var0; FN=0 init=0 WS=0 RS=0 */
.long 0x81988000 /* 0094: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
.long 0x10000788 /* 0098: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 009C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x080c504c /* 00A0: DRD2B1: idx0 = EU1(); EU1(var1,var12) */
.long 0x000001f8 /* 00A4(:0): NOP */
.globl scEthernetXmit_TDT
scEthernetXmit_TDT: /* Task 1 Descriptor Table */
.long 0x80014800 /* 0000: LCDEXT: idx0 = 0xf0004800; ; */
.long 0x85c60004 /* 0004: LCD: idx1 = var11 + var12 + 4; idx1 once var0; idx1 += inc0 */
.long 0x10002308 /* 0008: DRD1A: var8 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x10000f88 /* 000C: DRD1A: var3 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000380 /* 0010: DRD1A: var0 = *idx0; FN=0 init=0 WS=0 RS=0 */
.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x024c504d /* 0020: DRD2B1: var9 = EU1(); EU1(var1,var13) */
.long 0x84980309 /* 0024: LCD: idx0 = var9; idx0 != var12; idx0 += inc1 */
.long 0xc0004003 /* 0028: LCDEXT: idx1 = 0x00000003; ; */
.long 0x81c60004 /* 002C: LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */
.long 0x70000000 /* 0030: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x010c504e /* 0034: DRD2B1: var4 = EU1(); EU1(var1,var14) */
.long 0x70000000 /* 0038: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x014c504f /* 003C: DRD2B1: var5 = EU1(); EU1(var1,var15) */
.long 0x70000000 /* 0040: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x028c5050 /* 0044: DRD2B1: var10 = EU1(); EU1(var1,var16) */
.long 0x70000000 /* 0048: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x018c5051 /* 004C: DRD2B1: var6 = EU1(); EU1(var1,var17) */
.long 0x10000b90 /* 0050: DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 0054: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x01cc50a1 /* 0058: DRD2B1: var7 = EU1(); EU1(var2,idx1) */
.long 0xc2988312 /* 005C: LCDEXT: idx1 = var5; idx1 > var12; idx1 += inc2 */
.long 0x83490000 /* 0060: LCD: idx2 = var6 + var18; idx2 once var0; idx2 += inc0 */
.long 0x00001b10 /* 0064: DRD1A: var6 = idx2; FN=0 init=0 WS=0 RS=0 */
.long 0x8000d1a4 /* 0068: LCDEXT: idx1 = 0xf00031a4; ; */
.long 0x8301031c /* 006C: LCD: idx2 = var6, idx3 = var2; idx2 > var12; idx2 += inc3, idx3 += inc4 */
.long 0x008ac798 /* 0070: DRD1A: *idx1 = *idx3; FN=0 init=4 WS=1 RS=1 */
.long 0x8000d1a4 /* 0074: LCDEXT: idx1 = 0xf00031a4; ; */
.long 0xc1430000 /* 0078: LCDEXT: idx2 = var2 + var6; idx2 once var0; idx2 += inc0 */
.long 0x82998312 /* 007C: LCD: idx3 = var5; idx3 > var12; idx3 += inc2 */
.long 0x088ac790 /* 0080: DRD1A: *idx1 = *idx2; FN=0 TFD init=4 WS=1 RS=1 */
.long 0x81988000 /* 0084: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
.long 0x60000100 /* 0088: DRD2A: EU0=0 EU1=1 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x0c4c5c4d /* 008C: DRD2B1: *idx1 = EU1(); EU1(*idx1,var13) */
.long 0xc21883ad /* 0090: LCDEXT: idx1 = var4; idx1 == var14; idx1 += inc5 */
.long 0x80190000 /* 0094: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
.long 0x04008460 /* 0098: DRD1A: idx1 = var12; FN=0 INT init=0 WS=0 RS=0 */
.long 0xc4052305 /* 009C: LCDEXT: idx1 = var8, idx2 = var10; idx2 == var12; idx1 += inc0, idx2 += inc5 */
.long 0x81c98000 /* 00A0: LCD: idx3 = var3 + var19; idx3 once var0; idx3 += inc0 */
.long 0x1000c718 /* 00A4: DRD1A: *idx1 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000f18 /* 00A8: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
.long 0xc4188000 /* 00AC: LCDEXT: idx1 = var8; idx1 once var0; idx1 += inc0 */
.long 0x85190312 /* 00B0: LCD: idx2 = var10; idx2 > var12; idx2 += inc2 */
.long 0x10000c00 /* 00B4: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x1000c400 /* 00B8: DRD1A: *idx1 = var0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00008860 /* 00BC: DRD1A: idx2 = var12; FN=0 init=0 WS=0 RS=0 */
.long 0x81988000 /* 00C0: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
.long 0x10000788 /* 00C4: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 00C8: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x080c504d /* 00CC: DRD2B1: idx0 = EU1(); EU1(var1,var13) */
.long 0x000001f8 /* 00D0(:0): NOP */
.align 8
.globl scEthernetRecv_VarTab
scEthernetRecv_VarTab: /* Task 0 Variable Table */
.long 0x00000000 /* var[0] */
.long 0x00000000 /* var[1] */
.long 0x00000000 /* var[2] */
.long 0x00000000 /* var[3] */
.long 0x00000000 /* var[4] */
.long 0x00000000 /* var[5] */
.long 0x00000000 /* var[6] */
.long 0x00000000 /* var[7] */
.long 0x00000000 /* var[8] */
.long 0xf0004800 /* var[9] */
.long 0x00000008 /* var[10] */
.long 0x0000000c /* var[11] */
.long 0x80000000 /* var[12] */
.long 0x00000000 /* var[13] */
.long 0x10000000 /* var[14] */
.long 0x20000000 /* var[15] */
.long 0x000005e4 /* var[16] */
.long 0x0000000e /* var[17] */
.long 0x000005e0 /* var[18] */
.long 0x00000004 /* var[19] */
.long 0x00000000 /* var[20] */
.long 0x00000000 /* var[21] */
.long 0x00000000 /* var[22] */
.long 0x00000000 /* var[23] */
.long 0x00000000 /* inc[0] */
.long 0x60000000 /* inc[1] */
.long 0x20000001 /* inc[2] */
.long 0x80000000 /* inc[3] */
.long 0x40000000 /* inc[4] */
.long 0x00000000 /* inc[5] */
.long 0x00000000 /* inc[6] */
.long 0x00000000 /* inc[7] */
.align 8
.globl scEthernetXmit_VarTab
scEthernetXmit_VarTab: /* Task 1 Variable Table */
.long 0x00000000 /* var[0] */
.long 0x00000000 /* var[1] */
.long 0x00000000 /* var[2] */
.long 0x00000000 /* var[3] */
.long 0x00000000 /* var[4] */
.long 0x00000000 /* var[5] */
.long 0x00000000 /* var[6] */
.long 0x00000000 /* var[7] */
.long 0x00000000 /* var[8] */
.long 0x00000000 /* var[9] */
.long 0x00000000 /* var[10] */
.long 0xf0004800 /* var[11] */
.long 0x00000000 /* var[12] */
.long 0x80000000 /* var[13] */
.long 0x10000000 /* var[14] */
.long 0x08000000 /* var[15] */
.long 0x20000000 /* var[16] */
.long 0x0000ffff /* var[17] */
.long 0xffffffff /* var[18] */
.long 0x00000008 /* var[19] */
.long 0x00000000 /* var[20] */
.long 0x00000000 /* var[21] */
.long 0x00000000 /* var[22] */
.long 0x00000000 /* var[23] */
.long 0x00000000 /* inc[0] */
.long 0x60000000 /* inc[1] */
.long 0x40000000 /* inc[2] */
.long 0x4000ffff /* inc[3] */
.long 0xe0000001 /* inc[4] */
.long 0x80000000 /* inc[5] */
.long 0x00000000 /* inc[6] */
.long 0x00000000 /* inc[7] */
.align 8
.globl scEthernetRecv_FDT
scEthernetRecv_FDT: /* Task 0 Function Descriptor Table */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x05800000 /* and(), EU# 1 */
.long 0x05400000 /* andn(), EU# 1 */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.align 8
.globl scEthernetXmit_FDT
scEthernetXmit_FDT: /* Task 1 Function Descriptor Table */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x05800000 /* and(), EU# 1 */
.long 0x05400000 /* andn(), EU# 1 */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.align 8
.globl scEthernetRecv_CSave
scEthernetRecv_CSave: /* Task 0 context save space */
.space 256, 0x0
.align 8
.globl scEthernetXmit_CSave
scEthernetXmit_CSave: /* Task 1 context save space */
.space 256, 0x0
#endif /* CONFIG_MGT5100 */

@ -0,0 +1,363 @@
/*
* Copyright (C) 2001, Software Center, Motorola China.
*
* This file contains microcode for the FEC controller of the MPC5200 CPU.
*/
#include <config.h>
#if defined(CONFIG_MPC5200)
/* sas/sccg, gas target */
.section smartdmaInitData,"aw",@progbits /* Initialized data for task variables */
.section smartdmaTaskTable,"aw",@progbits /* Task tables */
.align 9
.globl taskTable
taskTable:
.globl scEthernetRecv_Entry
scEthernetRecv_Entry: /* Task 0 */
.long scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */
.long scEthernetRecv_TDT - taskTable + 0x000000a4
.long scEthernetRecv_VarTab - taskTable /* Task 0 Variable Table */
.long scEthernetRecv_FDT - taskTable + 0x03 /* Task 0 Function Descriptor Table & Flags */
.long 0x00000000
.long 0x00000000
.long scEthernetRecv_CSave - taskTable /* Task 0 context save space */
.long 0xf0000000
.globl scEthernetXmit_Entry
scEthernetXmit_Entry: /* Task 1 */
.long scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */
.long scEthernetXmit_TDT - taskTable + 0x000000d0
.long scEthernetXmit_VarTab - taskTable /* Task 1 Variable Table */
.long scEthernetXmit_FDT - taskTable + 0x03 /* Task 1 Function Descriptor Table & Flags */
.long 0x00000000
.long 0x00000000
.long scEthernetXmit_CSave - taskTable /* Task 1 context save space */
.long 0xf0000000
.globl scEthernetRecv_TDT
scEthernetRecv_TDT: /* Task 0 Descriptor Table */
.long 0xc4c50000 /* 0000: LCDEXT: idx0 = var9 + var10; idx0 once var0; idx0 += inc0 */
.long 0x84c5e000 /* 0004: LCD: idx1 = var9 + var11; ; idx1 += inc0 */
.long 0x10001f08 /* 0008: DRD1A: var7 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x10000380 /* 000C: DRD1A: var0 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000f88 /* 0010: DRD1A: var3 = *idx1; FN=0 init=0 WS=0 RS=0 */
.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x010cf04c /* 0020: DRD2B1: var4 = EU3(); EU3(var1,var12) */
.long 0x82180349 /* 0024: LCD: idx0 = var4; idx0 != var13; idx0 += inc1 */
.long 0x81c68004 /* 0028: LCD: idx1 = var3 + var13 + 4; idx1 once var0; idx1 += inc0 */
.long 0x70000000 /* 002C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x018cf04e /* 0030: DRD2B1: var6 = EU3(); EU3(var1,var14) */
.long 0x70000000 /* 0034: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x020cf04f /* 0038: DRD2B1: var8 = EU3(); EU3(var1,var15) */
.long 0x00000b88 /* 003C: DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */
.long 0x8000d184 /* 0040: LCDEXT: idx1 = 0xf0003184; ; */
.long 0xc6990452 /* 0044: LCDEXT: idx2 = var13; idx2 < var17; idx2 += inc2 */
.long 0x81486010 /* 0048: LCD: idx3 = var2 + var16; ; idx3 += inc2 */
.long 0x006acf88 /* 004C: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */
.long 0x8000d184 /* 0050: LCDEXT: idx1 = 0xf0003184; ; */
.long 0x86810492 /* 0054: LCD: idx2 = var13, idx3 = var2; idx2 < var18; idx2 += inc2, idx3 += inc2 */
.long 0x006acf88 /* 0058: DRD1A: *idx3 = *idx1; FN=0 init=3 WS=1 RS=1 */
.long 0x8000d184 /* 005C: LCDEXT: idx1 = 0xf0003184; ; */
.long 0x868184d2 /* 0060: LCD: idx2 = var13, idx3 = var3; idx2 < var19; idx2 += inc2, idx3 += inc2 */
.long 0x000acf88 /* 0064: DRD1A: *idx3 = *idx1; FN=0 init=0 WS=1 RS=1 */
.long 0xc318839b /* 0068: LCDEXT: idx1 = var6; idx1 == var14; idx1 += inc3 */
.long 0x80190000 /* 006C: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
.long 0x04008468 /* 0070: DRD1A: idx1 = var13; FN=0 INT init=0 WS=0 RS=0 */
.long 0xc4038358 /* 0074: LCDEXT: idx1 = var8, idx2 = var7; idx1 == var13; idx1 += inc3, idx2 += inc0 */
.long 0x81c50000 /* 0078: LCD: idx3 = var3 + var10; idx3 once var0; idx3 += inc0 */
.long 0x1000cb18 /* 007C: DRD1A: *idx2 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000f18 /* 0080: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
.long 0xc4188364 /* 0084: LCDEXT: idx1 = var8; idx1 > var13; idx1 += inc4 */
.long 0x83990000 /* 0088: LCD: idx2 = var7; idx2 once var0; idx2 += inc0 */
.long 0x10000c00 /* 008C: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x0000c800 /* 0090: DRD1A: *idx2 = var0; FN=0 init=0 WS=0 RS=0 */
.long 0x81988000 /* 0094: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
.long 0x10000788 /* 0098: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 009C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x080cf04c /* 00A0: DRD2B1: idx0 = EU3(); EU3(var1,var12) */
.long 0x000001f8 /* 00A4(:0): NOP */
.globl scEthernetXmit_TDT
scEthernetXmit_TDT: /* Task 1 Descriptor Table */
.long 0x80024800 /* 0000: LCDEXT: idx0 = 0xf0008800; ; */
.long 0x85c60004 /* 0004: LCD: idx1 = var11 + var12 + 4; idx1 once var0; idx1 += inc0 */
.long 0x10002308 /* 0008: DRD1A: var8 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x10000f88 /* 000C: DRD1A: var3 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000380 /* 0010: DRD1A: var0 = *idx0; FN=0 init=0 WS=0 RS=0 */
.long 0x81980000 /* 0014: LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */
.long 0x10000780 /* 0018: DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 001C: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x024cf04d /* 0020: DRD2B1: var9 = EU3(); EU3(var1,var13) */
.long 0x84980309 /* 0024: LCD: idx0 = var9; idx0 != var12; idx0 += inc1 */
.long 0xc0004003 /* 0028: LCDEXT: idx1 = 0x00000003; ; */
.long 0x81c60004 /* 002C: LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */
.long 0x70000000 /* 0030: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x010cf04e /* 0034: DRD2B1: var4 = EU3(); EU3(var1,var14) */
.long 0x70000000 /* 0038: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x014cf04f /* 003C: DRD2B1: var5 = EU3(); EU3(var1,var15) */
.long 0x70000000 /* 0040: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x028cf050 /* 0044: DRD2B1: var10 = EU3(); EU3(var1,var16) */
.long 0x70000000 /* 0048: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */
.long 0x018cf051 /* 004C: DRD2B1: var6 = EU3(); EU3(var1,var17) */
.long 0x10000b90 /* 0050: DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 0054: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x01ccf0a1 /* 0058: DRD2B1: var7 = EU3(); EU3(var2,idx1) */
.long 0xc2988312 /* 005C: LCDEXT: idx1 = var5; idx1 > var12; idx1 += inc2 */
.long 0x83490000 /* 0060: LCD: idx2 = var6 + var18; idx2 once var0; idx2 += inc0 */
.long 0x00001b10 /* 0064: DRD1A: var6 = idx2; FN=0 init=0 WS=0 RS=0 */
.long 0x8000d1a4 /* 0068: LCDEXT: idx1 = 0xf00031a4; ; */
.long 0x8301031c /* 006C: LCD: idx2 = var6, idx3 = var2; idx2 > var12; idx2 += inc3, idx3 += inc4 */
.long 0x008ac798 /* 0070: DRD1A: *idx1 = *idx3; FN=0 init=4 WS=1 RS=1 */
.long 0x8000d1a4 /* 0074: LCDEXT: idx1 = 0xf00031a4; ; */
.long 0xc1430000 /* 0078: LCDEXT: idx2 = var2 + var6; idx2 once var0; idx2 += inc0 */
.long 0x82998312 /* 007C: LCD: idx3 = var5; idx3 > var12; idx3 += inc2 */
.long 0x088ac790 /* 0080: DRD1A: *idx1 = *idx2; FN=0 TFD init=4 WS=1 RS=1 */
.long 0x81988000 /* 0084: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
.long 0x60000001 /* 0088: DRD2A: EU0=0 EU1=0 EU2=0 EU3=1 EXT init=0 WS=0 RS=0 */
.long 0x0c4cfc4d /* 008C: DRD2B1: *idx1 = EU3(); EU3(*idx1,var13) */
.long 0xc21883ad /* 0090: LCDEXT: idx1 = var4; idx1 == var14; idx1 += inc5 */
.long 0x80190000 /* 0094: LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */
.long 0x04008460 /* 0098: DRD1A: idx1 = var12; FN=0 INT init=0 WS=0 RS=0 */
.long 0xc4052305 /* 009C: LCDEXT: idx1 = var8, idx2 = var10; idx2 == var12; idx1 += inc0, idx2 += inc5 */
.long 0x81c98000 /* 00A0: LCD: idx3 = var3 + var19; idx3 once var0; idx3 += inc0 */
.long 0x1000c718 /* 00A4: DRD1A: *idx1 = idx3; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00000f18 /* 00A8: DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */
.long 0xc4188000 /* 00AC: LCDEXT: idx1 = var8; idx1 once var0; idx1 += inc0 */
.long 0x85190312 /* 00B0: LCD: idx2 = var10; idx2 > var12; idx2 += inc2 */
.long 0x10000c00 /* 00B4: DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x1000c400 /* 00B8: DRD1A: *idx1 = var0; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x00008860 /* 00BC: DRD1A: idx2 = var12; FN=0 init=0 WS=0 RS=0 */
.long 0x81988000 /* 00C0: LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */
.long 0x10000788 /* 00C4: DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */
.long 0x60000000 /* 00C8: DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */
.long 0x080cf04d /* 00CC: DRD2B1: idx0 = EU3(); EU3(var1,var13) */
.long 0x000001f8 /* 00D0(:0): NOP */
.align 8
.globl scEthernetRecv_VarTab
scEthernetRecv_VarTab: /* Task 0 Variable Table */
.long 0x00000000 /* var[0] */
.long 0x00000000 /* var[1] */
.long 0x00000000 /* var[2] */
.long 0x00000000 /* var[3] */
.long 0x00000000 /* var[4] */
.long 0x00000000 /* var[5] */
.long 0x00000000 /* var[6] */
.long 0x00000000 /* var[7] */
.long 0x00000000 /* var[8] */
.long 0xf0008800 /* var[9] */
.long 0x00000008 /* var[10] */
.long 0x0000000c /* var[11] */
.long 0x80000000 /* var[12] */
.long 0x00000000 /* var[13] */
.long 0x10000000 /* var[14] */
.long 0x20000000 /* var[15] */
.long 0x000005e4 /* var[16] */
.long 0x0000000e /* var[17] */
.long 0x000005e0 /* var[18] */
.long 0x00000004 /* var[19] */
.long 0x00000000 /* var[20] */
.long 0x00000000 /* var[21] */
.long 0x00000000 /* var[22] */
.long 0x00000000 /* var[23] */
.long 0x00000000 /* inc[0] */
.long 0x60000000 /* inc[1] */
.long 0x20000001 /* inc[2] */
.long 0x80000000 /* inc[3] */
.long 0x40000000 /* inc[4] */
.long 0x00000000 /* inc[5] */
.long 0x00000000 /* inc[6] */
.long 0x00000000 /* inc[7] */
.align 8
.globl scEthernetXmit_VarTab
scEthernetXmit_VarTab: /* Task 1 Variable Table */
.long 0x00000000 /* var[0] */
.long 0x00000000 /* var[1] */
.long 0x00000000 /* var[2] */
.long 0x00000000 /* var[3] */
.long 0x00000000 /* var[4] */
.long 0x00000000 /* var[5] */
.long 0x00000000 /* var[6] */
.long 0x00000000 /* var[7] */
.long 0x00000000 /* var[8] */
.long 0x00000000 /* var[9] */
.long 0x00000000 /* var[10] */
.long 0xf0008800 /* var[11] */
.long 0x00000000 /* var[12] */
.long 0x80000000 /* var[13] */
.long 0x10000000 /* var[14] */
.long 0x08000000 /* var[15] */
.long 0x20000000 /* var[16] */
.long 0x0000ffff /* var[17] */
.long 0xffffffff /* var[18] */
.long 0x00000008 /* var[19] */
.long 0x00000000 /* var[20] */
.long 0x00000000 /* var[21] */
.long 0x00000000 /* var[22] */
.long 0x00000000 /* var[23] */
.long 0x00000000 /* inc[0] */
.long 0x60000000 /* inc[1] */
.long 0x40000000 /* inc[2] */
.long 0x4000ffff /* inc[3] */
.long 0xe0000001 /* inc[4] */
.long 0x80000000 /* inc[5] */
.long 0x00000000 /* inc[6] */
.long 0x00000000 /* inc[7] */
.align 8
.globl scEthernetRecv_FDT
scEthernetRecv_FDT: /* Task 0 Function Descriptor Table */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x21800000 /* and(), EU# 3 */
.long 0x21400000 /* andn(), EU# 3 */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.align 8
.globl scEthernetXmit_FDT
scEthernetXmit_FDT: /* Task 1 Function Descriptor Table */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x21800000 /* and(), EU# 3 */
.long 0x21400000 /* andn(), EU# 3 */
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.globl scEthernetRecv_CSave
scEthernetRecv_CSave: /* Task 0 context save space */
.space 128, 0x0
.globl scEthernetXmit_CSave
scEthernetXmit_CSave: /* Task 1 context save space */
.space 128, 0x0
#endif /* CONFIG_MPC5200 */

@ -0,0 +1,180 @@
/*
* (C) Copyright -2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* 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
*/
/*
* interrupts.c - just enough support for the decrementer/timer
*/
#include <common.h>
#include <asm/processor.h>
#include <command.h>
/****************************************************************************/
unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
/****************************************************************************/
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));
}
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);
}
/****************************************************************************/
int interrupt_init(void)
{
decrementer_count = get_tbclk() / CFG_HZ;
#ifdef DEBUG
puts("interrupt_init: setting actual decremter\n");
#endif
set_dec (get_tbclk() / CFG_HZ);
#ifdef DEBUG
printf("interrupt_init: enabling interrupts (msr = %08lx)\n",
get_msr());
#endif
set_msr (get_msr() | MSR_EE);
#ifdef DEBUG
printf("interrupt_init: done. (msr = %08lx)\n", get_msr());
#endif
return (0);
}
/****************************************************************************/
/*
* Handle external interrupts
*/
void
external_interrupt(struct pt_regs *regs)
{
puts("external_interrupt (oops!)\n");
}
volatile ulong timestamp = 0;
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
* Trivial implementation - no need to be really accurate.
*/
void
timer_interrupt(struct pt_regs *regs)
{
set_dec(decrementer_count);
timestamp++;
}
/****************************************************************************/
void
reset_timer(void)
{
timestamp = 0;
}
ulong
get_timer(ulong base)
{
return (timestamp - base);
}
void
set_timer(ulong t)
{
timestamp = t;
}
/****************************************************************************/
/*
* Install and free a interrupt handler.
*/
void
irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
{
}
void
irq_free_handler(int vec)
{
}
/****************************************************************************/
void
do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
puts("IRQ related functions are unimplemented currently.\n");
}

@ -0,0 +1,128 @@
/*
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Andreas Heppel <aheppel@sysgo.de>
* Copyright (C) 2003 Wolfgang Denk <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 <config.h>
#include <ppc_asm.tmpl>
/* ------------------------------------------------------------------------------- */
/* Function: in8 */
/* Description: Input 8 bits */
/* ------------------------------------------------------------------------------- */
.globl in8
in8:
lbz r3,0(r3)
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: in16 */
/* Description: Input 16 bits */
/* ------------------------------------------------------------------------------- */
.globl in16
in16:
lhz r3,0(r3)
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: in16r */
/* Description: Input 16 bits and byte reverse */
/* ------------------------------------------------------------------------------- */
.globl in16r
in16r:
lhbrx r3,0,r3
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: in32 */
/* Description: Input 32 bits */
/* ------------------------------------------------------------------------------- */
.globl in32
in32:
lwz 3,0(3)
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: in32r */
/* Description: Input 32 bits and byte reverse */
/* ------------------------------------------------------------------------------- */
.globl in32r
in32r:
lwbrx r3,0,r3
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: out8 */
/* Description: Output 8 bits */
/* ------------------------------------------------------------------------------- */
.globl out8
out8:
stb r4,0(r3)
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: out16 */
/* Description: Output 16 bits */
/* ------------------------------------------------------------------------------- */
.globl out16
out16:
sth r4,0(r3)
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: out16r */
/* Description: Byte reverse and output 16 bits */
/* ------------------------------------------------------------------------------- */
.globl out16r
out16r:
sthbrx r4,0,r3
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: out32 */
/* Description: Output 32 bits */
/* ------------------------------------------------------------------------------- */
.globl out32
out32:
stw r4,0(r3)
sync
blr
/* ------------------------------------------------------------------------------- */
/* Function: out32r */
/* Description: Byte reverse and output 32 bits */
/* ------------------------------------------------------------------------------- */
.globl out32r
out32r:
stwbrx r4,0,r3
sync
blr

@ -0,0 +1,76 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* This file is based on code
* (C) Copyright Motorola, Inc., 2000
*/
#include <common.h>
#include <mpc5xxx.h>
/* BestComm/SmartComm microcode */
extern int taskTable;
void loadtask(int basetask, int tasks)
{
int *sram = (int *)MPC5XXX_SRAM;
int *task_org = &taskTable;
unsigned int start, offset, end;
int i;
#ifdef DEBUG
printf("basetask = %d, tasks = %d\n", basetask, tasks);
printf("task_org = 0x%08x\n", (unsigned int)task_org);
#endif
/* setup TaskBAR register */
*(vu_long *)MPC5XXX_SDMA = MPC5XXX_SRAM;
/* relocate task table entries */
offset = (unsigned int)sram;
for (i = basetask; i < basetask + tasks; i++) {
sram[i * 8 + 0] = task_org[i * 8 + 0] + offset;
sram[i * 8 + 1] = task_org[i * 8 + 1] + offset;
sram[i * 8 + 2] = task_org[i * 8 + 2] + offset;
sram[i * 8 + 3] = task_org[i * 8 + 3] + offset;
sram[i * 8 + 4] = task_org[i * 8 + 4];
sram[i * 8 + 5] = task_org[i * 8 + 5];
sram[i * 8 + 6] = task_org[i * 8 + 6] + offset;
sram[i * 8 + 7] = task_org[i * 8 + 7];
}
/* relocate task descriptors */
start = (sram[basetask * 8] - (unsigned int)sram);
end = (sram[(basetask + tasks - 1) * 8 + 1] - (unsigned int)sram);
#ifdef DEBUG
printf ("TDT start = 0x%08x, end = 0x%08x\n", start, end);
#endif
start /= 4;
end /= 4;
for (i = start; i <= end; i++) {
sram[i] = task_org[i];
}
/* relocate variables */
start = (sram[basetask * 8 + 2] - (unsigned int)sram);
end = (sram[(basetask + tasks - 1) * 8 + 2] + 256 - (unsigned int)sram);
start /= 4;
end /= 4;
for (i = start; i < end; i++) {
sram[i] = task_org[i];
}
/* relocate function decriptors */
start = ((sram[basetask * 8 + 3] & 0xfffffffc) - (unsigned int)sram);
end = ((sram[(basetask + tasks - 1) * 8 + 3] & 0xfffffffc) + 256 - (unsigned int)sram);
start /= 4;
end /= 4;
for (i = start; i < end; i++) {
sram[i] = task_org[i];
}
asm volatile ("sync");
}

@ -0,0 +1,93 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* This file is based on code
* (C) Copyright Motorola, Inc., 2000
*
* odin smartdma header file
*/
#ifndef __MPC5XXX_SDMA_H
#define __MPC5XXX_SDMA_H
#include <common.h>
#include <mpc5xxx.h>
/* Task number assignment */
#define FEC_RECV_TASK_NO 0
#define FEC_XMIT_TASK_NO 1
/*---------------------------------------------------------------------*/
/* Stuff for Ethernet Tx/Rx tasks */
/*---------------------------------------------------------------------*/
/* Layout of Ethernet controller Parameter SRAM area:
----------------------------------------------------------------
0x00: TBD_BASE, base address of TX BD ring
0x04: TBD_NEXT, address of next TX BD to be processed
0x08: RBD_BASE, base address of RX BD ring
0x0C: RBD_NEXT, address of next RX BD to be processed
---------------------------------------------------------------
ALL PARAMETERS ARE ALL LONGWORDS (FOUR BYTES EACH).
*/
/* base address of SRAM area to store parameters used by Ethernet tasks */
#define FEC_PARAM_BASE (MPC5XXX_SRAM + 0x0800)
/* base address of SRAM area for buffer descriptors */
#define FEC_BD_BASE (MPC5XXX_SRAM + 0x0820)
/*---------------------------------------------------------------------*/
/* common shortcuts used by driver C code */
/*---------------------------------------------------------------------*/
/* Disable SmartDMA task */
#define SDMA_TASK_DISABLE(tasknum) \
{ \
volatile ushort *tcr = (ushort *)(MPC5XXX_SDMA + 0x0000001c + 2 * tasknum); \
*tcr = (*tcr) & (~0x8000); \
}
/* Enable SmartDMA task */
#define SDMA_TASK_ENABLE(tasknum) \
{ \
volatile ushort *tcr = (ushort *) (MPC5XXX_SDMA + 0x0000001c + 2 * tasknum); \
*tcr = (*tcr) | 0x8000; \
}
/* Enable interrupt */
#define SDMA_INT_ENABLE(tasknum) \
{ \
struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; \
sdma->IntMask &= ~(1 << tasknum); \
}
/* Disable interrupt */
#define SDMA_INT_DISABLE(tasknum) \
{ \
struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; \
sdma->IntMask |= (1 << tasknum); \
}
/* Clear interrupt pending bits */
#define SDMA_CLEAR_IEVENT(tasknum) \
{ \
struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; \
sdma->IntPend = (1 << tasknum); \
}
/* get interupt pending bit of a task */
#define SDMA_GET_PENDINGBIT(tasknum) \
((*(vu_long *)(MPC5XXX_SDMA + 0x14)) & (1<<(tasknum)))
/* get interupt mask bit of a task */
#define SDMA_GET_MASKBIT(tasknum) \
((*(vu_long *)(MPC5XXX_SDMA + 0x18)) & (1<<(tasknum)))
#endif /* __MPC5XXX_SDMA_H */

@ -0,0 +1,165 @@
/*
* (C) Copyright 2000 - 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Hacked for MPC8260 by Murray.Jensen@cmst.csiro.au, 19-Oct-00, with
* changes based on the file arch/ppc/mbxboot/m8260_tty.c from the
* Linux/PPC sources (m8260_tty.c had no copyright info in it).
*/
/*
* Minimal serial functions needed to use one of the PSC ports
* as serial console interface.
*/
#include <common.h>
#include <mpc5xxx.h>
#if defined(CONFIG_PSC_CONSOLE)
#if CONFIG_PSC_CONSOLE == 1
#define PSC_BASE MPC5XXX_PSC1
#elif CONFIG_PSC_CONSOLE == 2
#define PSC_BASE MPC5XXX_PSC2
#elif CONFIG_PSC_CONSOLE == 3
#define PSC_BASE MPC5XXX_PSC3
#elif defined(CONFIG_MGT5100)
#error CONFIG_PSC_CONSOLE must be in 1, 2 or 3
#elif CONFIG_PSC_CONSOLE == 4
#define PSC_BASE MPC5XXX_PSC4
#elif CONFIG_PSC_CONSOLE == 5
#define PSC_BASE MPC5XXX_PSC5
#elif CONFIG_PSC_CONSOLE == 6
#define PSC_BASE MPC5XXX_PSC6
#else
#error CONFIG_PSC_CONSOLE must be in 1 ... 6
#endif
int serial_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
unsigned long baseclk;
int div;
/* reset PSC */
psc->command = PSC_SEL_MODE_REG_1;
/* select clock sources */
#if defined(CONFIG_MGT5100)
psc->psc_clock_select = 0xdd00;
baseclk = CFG_MPC5XXX_CLKIN / 32;
#elif defined(CONFIG_MPC5200)
psc->psc_clock_select = 0;
baseclk = gd->ipb_clk / 32;
#endif
/* switch to UART mode */
psc->sicr = 0;
/* configure parity, bit length and so on */
#if defined(CONFIG_MGT5100)
psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE;
#elif defined(CONFIG_MPC5200)
psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
#endif
psc->mode = PSC_MODE_ONE_STOP;
/* set up UART divisor */
div = baseclk / gd->baudrate;
psc->ctur = div >> 8;
psc->ctlr = div & 0xff;
/* disable all interrupts */
psc->psc_imr = 0;
/* reset and enable Rx/Tx */
psc->command = PSC_RST_RX;
psc->command = PSC_RST_TX;
psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
return (0);
}
void
serial_putc(const char c)
{
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
if (c == '\n')
serial_putc('\r');
/* Wait for last character to go. */
while (!(psc->psc_status & PSC_SR_TXEMP))
;
psc->psc_buffer_8 = c;
}
void
serial_puts (const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
int
serial_getc(void)
{
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
/* Wait for a character to arrive. */
while (!(psc->psc_status & PSC_SR_RXRDY))
;
return psc->psc_buffer_8;
}
int
serial_tstc(void)
{
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
return (psc->psc_status & PSC_SR_RXRDY);
}
void
serial_setbrg(void)
{
DECLARE_GLOBAL_DATA_PTR;
volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
unsigned long baseclk, div;
#if defined(CONFIG_MGT5100)
baseclk = CFG_MPC5XXX_CLKIN / 32;
#elif defined(CONFIG_MPC5200)
baseclk = gd->ipb_clk / 32;
#endif
/* set up UART divisor */
div = baseclk / gd->baudrate;
psc->ctur = div >> 8;
psc->ctlr = div & 0xff;
}
#endif /* CONFIG_PSC_CONSOLE */

@ -0,0 +1,93 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <mpc5xxx.h>
#include <asm/processor.h>
/* ------------------------------------------------------------------------- */
/* Bus-to-Core Multipliers */
static int bus2core[] = {
0, 0, 0, 10, 20, 20, 25, 45,
30, 55, 40, 50, 0, 60, 35, 0,
30, 25, 65, 10, 70, 20, 75, 45,
0, 55, 40, 50, 80, 60, 35, 0
};
/* ------------------------------------------------------------------------- */
/*
*
*/
int get_clocks (void)
{
DECLARE_GLOBAL_DATA_PTR;
ulong val, vco;
#if !defined(CFG_MPC5XXX_CLKIN)
#error clock measuring not implemented yet - define CFG_MPC5XXX_CLKIN
#endif
val = *(vu_long *)MPC5XXX_CDM_PORCFG;
if (val & (1 << 6)) {
vco = CFG_MPC5XXX_CLKIN * 12;
} else {
vco = CFG_MPC5XXX_CLKIN * 16;
}
if (val & (1 << 5)) {
gd->bus_clk = vco / 8;
} else {
gd->bus_clk = vco / 4;
}
gd->cpu_clk = gd->bus_clk * bus2core[val & 0x1f] / 10;
val = *(vu_long *)MPC5XXX_CDM_CFG;
if (val & (1 << 8)) {
gd->ipb_clk = gd->bus_clk / 2;
} else {
gd->ipb_clk = gd->bus_clk;
}
switch (val & 3) {
case 0: gd->pci_clk = gd->ipb_clk; break;
case 1: gd->pci_clk = gd->ipb_clk / 2; break;
default: gd->pci_clk = gd->bus_clk / 4; break;
}
return (0);
}
int prt_mpc5xxx_clks (void)
{
DECLARE_GLOBAL_DATA_PTR;
printf(" Bus %ld MHz, IPB %ld MHz, PCI %ld MHz\n",
gd->bus_clk / 1000000, gd->ipb_clk / 1000000,
gd->pci_clk / 1000000);
return (0);
}
/* ------------------------------------------------------------------------- */

@ -0,0 +1,817 @@
/*
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000 - 2003 Wolfgang Denk <wd@denx.de>
*
* 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
*/
/*
* U-Boot - Startup Code for MPC5xxx CPUs
*/
#include <config.h>
#include <mpc5xxx.h>
#include <version.h>
#define CONFIG_MPC5XXX 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 <asm/cache.h>
#include <asm/mmu.h>
#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
#endif
/* We don't want the MMU yet.
*/
#undef MSR_KERNEL
/* Floating Point enable, Machine Check and Recoverable Interr. */
#ifdef DEBUG
#define MSR_KERNEL (MSR_FP|MSR_RI)
#else
#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
#endif
/*
* 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(__init_end)
GOT_ENTRY(_end)
GOT_ENTRY(__bss_start)
END_GOT
/*
* Version string
*/
.data
.globl version_string
version_string:
.ascii U_BOOT_VERSION
.ascii " (", __DATE__, " - ", __TIME__, ")"
.ascii CONFIG_IDENT_STRING, "\0"
/*
* Exception vectors
*/
.text
. = EXC_OFF_SYS_RESET
.globl _start
_start:
li r21, BOOTFLAG_COLD /* Normal Power-On */
nop
b boot_cold
. = EXC_OFF_SYS_RESET + 0x10
.globl _start_warm
_start_warm:
li r21, BOOTFLAG_WARM /* Software reboot */
b boot_warm
boot_cold:
boot_warm:
mfmsr r5 /* save msr contents */
#if defined(CFG_DEFAULT_MBAR)
lis r3, CFG_MBAR@h
ori r3, r3, CFG_MBAR@l
#if defined(CONFIG_MPC5200)
rlwinm r3, r3, 16, 16, 31
#endif
#if defined(CONFIG_MGT5100)
rlwinm r3, r3, 17, 15, 31
#endif
lis r4, CFG_DEFAULT_MBAR@h
stw r3, 0(r4)
#endif /* CFG_DEFAULT_MBAR */
/* Initialise the MPC5xxx processor core */
/*--------------------------------------------------------------*/
bl init_5xxx_core
/* initialize some things that are hard to access from C */
/*--------------------------------------------------------------*/
/* set up stack in on-chip SRAM */
lis r3, CFG_INIT_RAM_ADDR@h
ori r3, r3, CFG_INIT_RAM_ADDR@l
ori r1, r3, CFG_INIT_SP_OFFSET
li r0, 0 /* Make room for stack frame header and */
stwu r0, -4(r1) /* clear final stack frame so that */
stwu r0, -4(r1) /* stack backtraces terminate cleanly */
/* 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 (in Flash)*/
mr r3, r21
/* r3: BOOTFLAG */
bl board_init_f /* run 1st part of board init code (in Flash)*/
/*
* Vector Table
*/
.globl _start_of_vectors
_start_of_vectors:
/* Machine check */
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
/* Data Storage exception. */
STD_EXCEPTION(0x300, DataStorage, UnknownException)
/* Instruction Storage exception. */
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 */
rlwimi r20,r23,0,25,25 /* copy IP 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 */
rlwimi r20,r23,0,25,25 /* copy IP 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
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)
STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
#ifdef DEBUG
. = 0x1300
/*
* This exception occurs when the program counter matches the
* Instruction Address Breakpoint Register (IABR).
*
* I want the cpu to halt if this occurs so I can hunt around
* with the debugger and look at things.
*
* When DEBUG is defined, both machine check enable (in the MSR)
* and checkstop reset enable (in the reset mode register) are
* turned off and so a checkstop condition will result in the cpu
* halting.
*
* I force the cpu into a checkstop condition by putting an illegal
* instruction here (at least this is the theory).
*
* well - that didnt work, so just do an infinite loop!
*/
1: b 1b
#else
STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
#endif
STD_EXCEPTION(0x1400, SMI, UnknownException)
STD_EXCEPTION(0x1500, Trap_15, UnknownException)
STD_EXCEPTION(0x1600, Trap_16, UnknownException)
STD_EXCEPTION(0x1700, Trap_17, UnknownException)
STD_EXCEPTION(0x1800, Trap_18, UnknownException)
STD_EXCEPTION(0x1900, Trap_19, UnknownException)
STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
STD_EXCEPTION(0x2000, Trap_20, UnknownException)
STD_EXCEPTION(0x2100, Trap_21, UnknownException)
STD_EXCEPTION(0x2200, Trap_22, UnknownException)
STD_EXCEPTION(0x2300, Trap_23, UnknownException)
STD_EXCEPTION(0x2400, Trap_24, UnknownException)
STD_EXCEPTION(0x2500, Trap_25, UnknownException)
STD_EXCEPTION(0x2600, Trap_26, UnknownException)
STD_EXCEPTION(0x2700, Trap_27, UnknownException)
STD_EXCEPTION(0x2800, Trap_28, UnknownException)
STD_EXCEPTION(0x2900, Trap_29, UnknownException)
STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
.globl _end_of_vectors
_end_of_vectors:
. = 0x3000
/*
* 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)
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
/*
* This code initialises the MPC5xxx processor core
* (conforms to PowerPC 603e spec)
* Note: expects original MSR contents to be in r5.
*/
.globl init_5xx_core
init_5xxx_core:
/* Initialize machine status; enable machine check interrupt */
/*--------------------------------------------------------------*/
li r3, MSR_KERNEL /* Set ME and RI flags */
rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
#ifdef DEBUG
rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
#endif
SYNC /* Some chip revs need this... */
mtmsr r3
SYNC
mtspr SRR1, r3 /* Make SRR1 match MSR */
/* Initialize the Hardware Implementation-dependent Registers */
/* HID0 also contains cache control */
/*--------------------------------------------------------------*/
lis r3, CFG_HID0_INIT@h
ori r3, r3, CFG_HID0_INIT@l
SYNC
mtspr HID0, r3
lis r3, CFG_HID0_FINAL@h
ori r3, r3, CFG_HID0_FINAL@l
SYNC
mtspr HID0, r3
/* clear all BAT's */
/*--------------------------------------------------------------*/
li r0, 0
mtspr DBAT0U, r0
mtspr DBAT0L, r0
mtspr DBAT1U, r0
mtspr DBAT1L, r0
mtspr DBAT2U, r0
mtspr DBAT2L, r0
mtspr DBAT3U, r0
mtspr DBAT3L, r0
mtspr IBAT0U, r0
mtspr IBAT0L, r0
mtspr IBAT1U, r0
mtspr IBAT1L, r0
mtspr IBAT2U, r0
mtspr IBAT2L, r0
mtspr IBAT3U, r0
mtspr IBAT3L, r0
SYNC
/* invalidate all tlb's */
/* */
/* From the 603e User Manual: "The 603e provides the ability to */
/* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
/* instruction invalidates the TLB entry indexed by the EA, and */
/* operates on both the instruction and data TLBs simultaneously*/
/* invalidating four TLB entries (both sets in each TLB). The */
/* index corresponds to bits 15-19 of the EA. To invalidate all */
/* entries within both TLBs, 32 tlbie instructions should be */
/* issued, incrementing this field by one each time." */
/* */
/* "Note that the tlbia instruction is not implemented on the */
/* 603e." */
/* */
/* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
/* incrementing by 0x1000 each time. The code below is sort of */
/* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */
/* */
/*--------------------------------------------------------------*/
li r3, 32
mtctr r3
li r3, 0
1: tlbie r3
addi r3, r3, 0x1000
bdnz 1b
SYNC
/* Done! */
/*--------------------------------------------------------------*/
blr
/* Cache functions.
*
* Note: requires that all cache bits in
* HID0 are in the low half word.
*/
.globl icache_enable
icache_enable:
mfspr r3, HID0
ori r3, r3, HID0_ICE
lis r4, 0
ori r4, r4, HID0_ILOCK
andc r3, r3, r4
ori r4, r3, HID0_ICFI
isync
mtspr HID0, r4 /* sets enable and invalidate, clears lock */
isync
mtspr HID0, r3 /* clears invalidate */
blr
.globl icache_disable
icache_disable:
mfspr r3, HID0
lis r4, 0
ori r4, r4, HID0_ICE|HID0_ILOCK
andc r3, r3, r4
ori r4, r3, HID0_ICFI
isync
mtspr HID0, r4 /* sets invalidate, clears enable and lock */
isync
mtspr HID0, r3 /* clears invalidate */
blr
.globl icache_status
icache_status:
mfspr r3, HID0
rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
blr
.globl dcache_enable
dcache_enable:
mfspr r3, HID0
ori r3, r3, HID0_DCE
lis r4, 0
ori r4, r4, HID0_DLOCK
andc r3, r3, r4
ori r4, r3, HID0_DCI
sync
mtspr HID0, r4 /* sets enable and invalidate, clears lock */
sync
mtspr HID0, r3 /* clears invalidate */
blr
.globl dcache_disable
dcache_disable:
mfspr r3, HID0
lis r4, 0
ori r4, r4, HID0_DCE|HID0_DLOCK
andc r3, r3, r4
ori r4, r3, HID0_DCI
sync
mtspr HID0, r4 /* sets invalidate, clears enable and lock */
sync
mtspr HID0, r3 /* clears invalidate */
blr
.globl dcache_status
dcache_status:
mfspr r3, HID0
rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
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 */
mr r9, r4 /* Save copy of Global Data pointer */
mr r10, r5 /* Save copy of Destination Address */
mr r3, r5 /* Destination Address */
lis r4, CFG_MONITOR_BASE@h /* Source Address */
ori r4, r4, CFG_MONITOR_BASE@l
lwz r5, GOT(__init_end)
sub r5, r5, r4
li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
/*
* 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
/* then 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 7f /* 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
/*
* Now flush the cache: note that we must start from a cache aligned
* address. Otherwise we might miss one cache line.
*/
4: cmpwi r6,0
add r5,r3,r5
beq 7f /* Always flush prefetch queue in any case */
subi r0,r6,1
andc r3,r3,r0
mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
cmpwi r7,0
beq 9f
mr r4,r3
5: dcbst 0,r4
add r4,r4,r6
cmplw r4,r5
blt 5b
sync /* Wait for all dcbst to complete on bus */
9: mfspr r7,HID0 /* don't do icbi if icache is disabled */
rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
cmpwi r7,0
beq 7f
mr r4,r3
6: icbi 0,r4
add r4,r4,r6
cmplw r4,r5
blt 6b
7: sync /* Wait for all icbi to complete on bus */
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_start)
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
/*
* 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)
li r9, 0x100 /* reset vector always at 0x100 */
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
mfmsr r3 /* now that the vectors have */
lis r7, MSR_IP@h /* relocated into low memory */
ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
andc r3, r3, r7 /* (if it was on) */
SYNC /* Some chip revs need this... */
mtmsr r3
SYNC
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)
blr

@ -0,0 +1,246 @@
/*
* 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-2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* 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
/* 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 0x02000000
/*
* Trap & Exception support
*/
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");
}
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");
}
}
}
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);
}
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 - probably due to mm fault\n"
"with mmu off\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");
}
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");
}
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");
}
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");
}
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);
}
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
extern void do_bedbug_breakpoint(struct pt_regs *);
#endif
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
}
/* Probe an address by reading. If not present, return -1, otherwise
* return 0.
*/
int
addr_probe(uint *addr)
{
#if 0
int retval;
__asm__ __volatile__( \
"1: lwz %0,0(%1)\n" \
" eieio\n" \
" li %0,0\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,-1\n" \
" b 2b\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
" .long 1b,3b\n" \
".text" \
: "=r" (retval) : "r"(addr));
return (retval);
#endif
return 0;
}

@ -46,6 +46,10 @@ typedef struct global_data {
unsigned long scc_clk;
unsigned long brg_clk;
#endif
#if defined(CONFIG_MPC5XXX)
unsigned long ipb_clk;
unsigned long pci_clk;
#endif
unsigned long ram_size; /* RAM size */
unsigned long reloc_off; /* Relocation Offset */
unsigned long reset_status; /* reset status register at boot */

@ -41,6 +41,9 @@ typedef struct bd_info {
#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260)
unsigned long bi_immr_base; /* base of IMMR register */
#endif
#if defined(CONFIG_MPC5XXX)
unsigned long bi_mbar_base; /* base of internal registers */
#endif
unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
unsigned long bi_ip_addr; /* IP Address */
unsigned char bi_enetaddr[6]; /* Ethernet adress */
@ -53,6 +56,10 @@ typedef struct bd_info {
unsigned long bi_sccfreq; /* SCC_CLK Freq, in MHz */
unsigned long bi_vco; /* VCO Out from PLL, in MHz */
#endif
#if defined(CONFIG_MPC5XXX)
unsigned long bi_ipbfreq; /* IPB Bus Freq, in MHz */
unsigned long bi_pcifreq; /* PCI Bus Freq, in MHz */
#endif
unsigned long bi_baudrate; /* Console Baudrate */
#if defined(CONFIG_405GP) || \
defined(CONFIG_405CR) || \

@ -327,6 +327,9 @@ int get_clocks (void);
#if defined(CONFIG_8260)
int prt_8260_clks (void);
#endif
#if defined(CONFIG_MPC5XXX)
int prt_mpc5xxx_clks (void);
#endif
#ifdef CONFIG_4xx
ulong get_OPB_freq (void);
ulong get_PCI_freq (void);

@ -0,0 +1,173 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_MPC5XXX 1 /* This is an MPC5xxx CPU */
#define CONFIG_ICECUBE 1 /* ... on IceCube board */
#define CFG_MPC5XXX_CLKIN 33333333 /* ... running at 33MHz */
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
#define CFG_CACHELINE_SIZE 32 /* For MPC8260 CPU */
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */
#endif
/*
* Serial console configuration
*/
#define CONFIG_PSC_CONSOLE 1 /* console is on PSC1 */
#define CONFIG_BAUDRATE 115200 /* ... at 115200 bps */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 }
/*
* Supported commands
*/
#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~(CFG_CMD_NET))
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
/*
* Autobooting
*/
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
#define CONFIG_BOOTCOMMAND "bootm 100000" /* autoboot command */
#define CONFIG_BOOTARGS "root=/dev/ram rw"
/*
* I2C configuration
*/
/*
* Flash configuration
*/
#define CFG_FLASH_BASE 0xff800000
#define CFG_FLASH_SIZE 0x00800000
/*
* Flash organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */
#define CFG_MAX_FLASH_SECT 128 /* max num of sects on one chip */
#define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */
#undef CONFIG_FLASH_16BIT /* Flash is 8-bit */
/*
* Environment settings
*/
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x10000
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x740000)
#define CFG_ENV_SECT_SIZE 0x10000
/*
* Memory map
*/
#define CFG_MBAR 0xf0000000
#define CFG_SDRAM_BASE 0x00000000
/* Use SRAM until RAM will be available */
#define CFG_INIT_RAM_ADDR MPC5XXX_SRAM
#define CFG_INIT_RAM_END MPC5XXX_SRAM_SIZE /* End of used area in DPRAM */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
#define CFG_MONITOR_BASE TEXT_BASE
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
# define CFG_RAMBOOT 1
#endif
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
/*
* Ethernet configuration
*/
#if 0
#define CONFIG_NET_MULTI 1
#define CONFIG_MPC5XXX_FEC 1
#endif
/*
* GPIO configuration
*/
#define CFG_GPS_PORT_CONFIG 0x00000004
/*
* 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 0x00100000 /* memtest works on */
#define CFG_MEMTEST_END 0x00f00000 /* 1 ... 15 MB in DRAM */
#define CFG_LOAD_ADDR 0x100000 /* default load address */
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
/*
* Various low-level settings
*/
#define CFG_HID0_INIT 0
#define CFG_HID0_FINAL 0
#define CFG_BOOTCS_START CFG_FLASH_BASE
#define CFG_BOOTCS_SIZE CFG_FLASH_SIZE
#define CFG_BOOTCS_CFG 0x00047801
#define CFG_CS0_START CFG_FLASH_BASE
#define CFG_CS0_SIZE CFG_FLASH_SIZE
#define CFG_CS_BURST 0x00000000
#define CFG_CS_DEADCYCLE 0x33333333
#define CFG_RESET_ADDRESS 0xff000000
#endif /* __CONFIG_H */

@ -521,7 +521,6 @@ typedef struct {
#define WDTIM_CONTROL_ST BIT7
/* ---------------------------------------------------------------------------
* Differentiating processor versions for those who care.
* ---------------------------------------------------------------------------

@ -0,0 +1,467 @@
/*
* include/asm-ppc/mpc5xxx.h
*
* Prototypes, etc. for the Motorola MGT5xxx/MPC5xxx
* embedded cpu chips
*
* 2003 (c) MontaVista, Software, Inc.
* Author: Dale Farnsworth <dfarnsworth@mvista.com>
*
* 2003 (C) Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __ASMPPC_MPC5XXX_H
#define __ASMPPC_MPC5XXX_H
/* Processor name */
#if defined(CONFIG_MPC5200)
#define CPU_ID_STR "MPC5200"
#elif defined(CONFIG_MGT5100)
#define CPU_ID_STR "MGT5100"
#endif
/* Exception offsets (PowerPC standard) */
#define EXC_OFF_SYS_RESET 0x0100
/* Internal memory map */
#define MPC5XXX_CS0_START (CFG_MBAR + 0x0004)
#define MPC5XXX_CS0_STOP (CFG_MBAR + 0x0008)
#define MPC5XXX_CS1_START (CFG_MBAR + 0x000c)
#define MPC5XXX_CS1_STOP (CFG_MBAR + 0x0010)
#define MPC5XXX_CS2_START (CFG_MBAR + 0x0014)
#define MPC5XXX_CS2_STOP (CFG_MBAR + 0x0018)
#define MPC5XXX_CS3_START (CFG_MBAR + 0x001c)
#define MPC5XXX_CS3_STOP (CFG_MBAR + 0x0020)
#define MPC5XXX_CS4_START (CFG_MBAR + 0x0024)
#define MPC5XXX_CS4_STOP (CFG_MBAR + 0x0028)
#define MPC5XXX_CS5_START (CFG_MBAR + 0x002c)
#define MPC5XXX_CS5_STOP (CFG_MBAR + 0x0030)
#define MPC5XXX_BOOTCS_START (CFG_MBAR + 0x004c)
#define MPC5XXX_BOOTCS_STOP (CFG_MBAR + 0x0050)
#define MPC5XXX_ADDECR (CFG_MBAR + 0x0054)
#if defined(CONFIG_MGT5100)
#define MPC5XXX_SDRAM_START (CFG_MBAR + 0x0034)
#define MPC5XXX_SDRAM_STOP (CFG_MBAR + 0x0038)
#elif defined(CONFIG_MPC5200)
#define MPC5XXX_CS6_START (CFG_MBAR + 0x0058)
#define MPC5XXX_CS6_STOP (CFG_MBAR + 0x005c)
#define MPC5XXX_CS7_START (CFG_MBAR + 0x0060)
#define MPC5XXX_CS7_STOP (CFG_MBAR + 0x0064)
#define MPC5XXX_SDRAM_CS0CFG (CFG_MBAR + 0x0034)
#define MPC5XXX_SDRAM_CS1CFG (CFG_MBAR + 0x0038)
#endif
#define MPC5XXX_SDRAM (CFG_MBAR + 0x0100)
#define MPC5XXX_CDM (CFG_MBAR + 0x0200)
#define MPC5XXX_LPB (CFG_MBAR + 0x0300)
#define MPC5XXX_ICTL (CFG_MBAR + 0x0500)
#define MPC5XXX_GPIO (CFG_MBAR + 0x0b00)
#define MPC5XXX_SDMA (CFG_MBAR + 0x1200)
#define MPC5XXX_XLBARB (CFG_MBAR + 0x1f00)
#if defined(CONFIG_MGT5100)
#define MPC5XXX_PSC1 (CFG_MBAR + 0x2000)
#define MPC5XXX_PSC2 (CFG_MBAR + 0x2400)
#define MPC5XXX_PSC3 (CFG_MBAR + 0x2800)
#elif defined(CONFIG_MPC5200)
#define MPC5XXX_PSC1 (CFG_MBAR + 0x2000)
#define MPC5XXX_PSC2 (CFG_MBAR + 0x2200)
#define MPC5XXX_PSC3 (CFG_MBAR + 0x2400)
#define MPC5XXX_PSC4 (CFG_MBAR + 0x2600)
#define MPC5XXX_PSC5 (CFG_MBAR + 0x2800)
#define MPC5XXX_PSC6 (CFG_MBAR + 0x2c00)
#endif
#define MPC5XXX_FEC (CFG_MBAR + 0x3000)
#if defined(CONFIG_MGT5100)
#define MPC5XXX_SRAM (CFG_MBAR + 0x4000)
#define MPC5XXX_SRAM_SIZE (8*1024)
#elif defined(CONFIG_MPC5200)
#define MPC5XXX_SRAM (CFG_MBAR + 0x8000)
#define MPC5XXX_SRAM_SIZE (16*1024)
#endif
/* SDRAM Controller */
#define MPC5XXX_SDRAM_MODE (MPC5XXX_SDRAM + 0x0000)
#define MPC5XXX_SDRAM_CTRL (MPC5XXX_SDRAM + 0x0004)
#define MPC5XXX_SDRAM_CONFIG1 (MPC5XXX_SDRAM + 0x0008)
#define MPC5XXX_SDRAM_CONFIG2 (MPC5XXX_SDRAM + 0x000c)
#if defined(CONFIG_MGT5100)
#define MPC5XXX_SDRAM_XLBSEL (MPC5XXX_SDRAM + 0x0010)
#endif
/* Clock Distribution Module */
#define MPC5XXX_CDM_JTAGID (MPC5XXX_CDM + 0x0000)
#define MPC5XXX_CDM_PORCFG (MPC5XXX_CDM + 0x0004)
#define MPC5XXX_CDM_CFG (MPC5XXX_CDM + 0x000c)
#define MPC5XXX_CDM_SRESET (MPC5XXX_CDM + 0x0020)
/* Local Plus Bus interface */
#define MPC5XXX_CS0_CFG (MPC5XXX_LPB + 0x0000)
#define MPC5XXX_CS1_CFG (MPC5XXX_LPB + 0x0004)
#define MPC5XXX_CS2_CFG (MPC5XXX_LPB + 0x0008)
#define MPC5XXX_CS3_CFG (MPC5XXX_LPB + 0x000c)
#define MPC5XXX_CS4_CFG (MPC5XXX_LPB + 0x0010)
#define MPC5XXX_CS5_CFG (MPC5XXX_LPB + 0x0014)
#define MPC5XXX_BOOTCS_CFG MPC5XXX_CS0_CFG
#define MPC5XXX_CS_CTRL (MPC5XXX_LPB + 0x0018)
#define MPC5XXX_CS_STATUS (MPC5XXX_LPB + 0x001c)
#if defined(CONFIG_MPC5200)
#define MPC5XXX_CS6_CFG (MPC5XXX_LPB + 0x0020)
#define MPC5XXX_CS7_CFG (MPC5XXX_LPB + 0x0024)
#define MPC5XXX_CS_BURST (MPC5XXX_LPB + 0x0028)
#define MPC5XXX_CS_DEADCYCLE (MPC5XXX_LPB + 0x002c)
#endif
/* GPIO registers */
#define MPC5XXX_GPS_PORT_CONFIG (MPC5XXX_GPIO + 0x0000)
/* Interrupt Controller registers */
#define MPC5XXX_ICTL_PER_MASK (MPC5XXX_ICTL + 0x0000)
#define MPC5XXX_ICTL_PER_PRIO1 (MPC5XXX_ICTL + 0x0004)
#define MPC5XXX_ICTL_PER_PRIO2 (MPC5XXX_ICTL + 0x0008)
#define MPC5XXX_ICTL_PER_PRIO3 (MPC5XXX_ICTL + 0x000c)
#define MPC5XXX_ICTL_EXT (MPC5XXX_ICTL + 0x0010)
#define MPC5XXX_ICTL_CRIT (MPC5XXX_ICTL + 0x0014)
#define MPC5XXX_ICTL_MAIN_PRIO1 (MPC5XXX_ICTL + 0x0018)
#define MPC5XXX_ICTL_MAIN_PRIO2 (MPC5XXX_ICTL + 0x001c)
#define MPC5XXX_ICTL_STS (MPC5XXX_ICTL + 0x0024)
#define MPC5XXX_ICTL_CRIT_STS (MPC5XXX_ICTL + 0x0028)
#define MPC5XXX_ICTL_MAIN_STS (MPC5XXX_ICTL + 0x002c)
#define MPC5XXX_ICTL_PER_STS (MPC5XXX_ICTL + 0x0030)
#define MPC5XXX_ICTL_BUS_STS (MPC5XXX_ICTL + 0x0038)
/* Programmable Serial Controller (PSC) status register bits */
#define PSC_SR_CDE 0x0080
#define PSC_SR_RXRDY 0x0100
#define PSC_SR_RXFULL 0x0200
#define PSC_SR_TXRDY 0x0400
#define PSC_SR_TXEMP 0x0800
#define PSC_SR_OE 0x1000
#define PSC_SR_PE 0x2000
#define PSC_SR_FE 0x4000
#define PSC_SR_RB 0x8000
/* PSC Command values */
#define PSC_RX_ENABLE 0x0001
#define PSC_RX_DISABLE 0x0002
#define PSC_TX_ENABLE 0x0004
#define PSC_TX_DISABLE 0x0008
#define PSC_SEL_MODE_REG_1 0x0010
#define PSC_RST_RX 0x0020
#define PSC_RST_TX 0x0030
#define PSC_RST_ERR_STAT 0x0040
#define PSC_RST_BRK_CHG_INT 0x0050
#define PSC_START_BRK 0x0060
#define PSC_STOP_BRK 0x0070
/* PSC Rx FIFO status bits */
#define PSC_RX_FIFO_ERR 0x0040
#define PSC_RX_FIFO_UF 0x0020
#define PSC_RX_FIFO_OF 0x0010
#define PSC_RX_FIFO_FR 0x0008
#define PSC_RX_FIFO_FULL 0x0004
#define PSC_RX_FIFO_ALARM 0x0002
#define PSC_RX_FIFO_EMPTY 0x0001
/* PSC interrupt mask bits */
#define PSC_IMR_TXRDY 0x0100
#define PSC_IMR_RXRDY 0x0200
#define PSC_IMR_DB 0x0400
#define PSC_IMR_IPC 0x8000
/* PSC input port change bits */
#define PSC_IPCR_CTS 0x01
#define PSC_IPCR_DCD 0x02
/* PSC mode fields */
#define PSC_MODE_5_BITS 0x00
#define PSC_MODE_6_BITS 0x01
#define PSC_MODE_7_BITS 0x02
#define PSC_MODE_8_BITS 0x03
#define PSC_MODE_PAREVEN 0x00
#define PSC_MODE_PARODD 0x04
#define PSC_MODE_PARFORCE 0x08
#define PSC_MODE_PARNONE 0x10
#define PSC_MODE_ERR 0x20
#define PSC_MODE_FFULL 0x40
#define PSC_MODE_RXRTS 0x80
#define PSC_MODE_ONE_STOP_5_BITS 0x00
#define PSC_MODE_ONE_STOP 0x07
#define PSC_MODE_TWO_STOP 0x0f
#ifndef __ASSEMBLY__
struct mpc5xxx_psc {
volatile u8 mode; /* PSC + 0x00 */
volatile u8 reserved0[3];
union { /* PSC + 0x04 */
volatile u16 status;
volatile u16 clock_select;
} sr_csr;
#define psc_status sr_csr.status
#define psc_clock_select sr_csr.clock_select
volatile u16 reserved1;
volatile u8 command; /* PSC + 0x08 */
volatile u8 reserved2[3];
union { /* PSC + 0x0c */
volatile u8 buffer_8;
volatile u16 buffer_16;
volatile u32 buffer_32;
} buffer;
#define psc_buffer_8 buffer.buffer_8
#define psc_buffer_16 buffer.buffer_16
#define psc_buffer_32 buffer.buffer_32
union { /* PSC + 0x10 */
volatile u8 ipcr;
volatile u8 acr;
} ipcr_acr;
#define psc_ipcr ipcr_acr.ipcr
#define psc_acr ipcr_acr.acr
volatile u8 reserved3[3];
union { /* PSC + 0x14 */
volatile u16 isr;
volatile u16 imr;
} isr_imr;
#define psc_isr isr_imr.isr
#define psc_imr isr_imr.imr
volatile u16 reserved4;
volatile u8 ctur; /* PSC + 0x18 */
volatile u8 reserved5[3];
volatile u8 ctlr; /* PSC + 0x1c */
volatile u8 reserved6[19];
volatile u8 ivr; /* PSC + 0x30 */
volatile u8 reserved7[3];
volatile u8 ip; /* PSC + 0x34 */
volatile u8 reserved8[3];
volatile u8 op1; /* PSC + 0x38 */
volatile u8 reserved9[3];
volatile u8 op0; /* PSC + 0x3c */
volatile u8 reserved10[3];
volatile u8 sicr; /* PSC + 0x40 */
volatile u8 reserved11[3];
volatile u8 ircr1; /* PSC + 0x44 */
volatile u8 reserved12[3];
volatile u8 ircr2; /* PSC + 0x44 */
volatile u8 reserved13[3];
volatile u8 irsdr; /* PSC + 0x4c */
volatile u8 reserved14[3];
volatile u8 irmdr; /* PSC + 0x50 */
volatile u8 reserved15[3];
volatile u8 irfdr; /* PSC + 0x54 */
volatile u8 reserved16[3];
volatile u16 rfnum; /* PSC + 0x58 */
volatile u16 reserved17;
volatile u16 tfnum; /* PSC + 0x5c */
volatile u16 reserved18;
volatile u32 rfdata; /* PSC + 0x60 */
volatile u16 rfstat; /* PSC + 0x64 */
volatile u16 reserved20;
volatile u8 rfcntl; /* PSC + 0x68 */
volatile u8 reserved21[5];
volatile u16 rfalarm; /* PSC + 0x6e */
volatile u16 reserved22;
volatile u16 rfrptr; /* PSC + 0x72 */
volatile u16 reserved23;
volatile u16 rfwptr; /* PSC + 0x76 */
volatile u16 reserved24;
volatile u16 rflrfptr; /* PSC + 0x7a */
volatile u16 reserved25;
volatile u16 rflwfptr; /* PSC + 0x7e */
volatile u32 tfdata; /* PSC + 0x80 */
volatile u16 tfstat; /* PSC + 0x84 */
volatile u16 reserved26;
volatile u8 tfcntl; /* PSC + 0x88 */
volatile u8 reserved27[5];
volatile u16 tfalarm; /* PSC + 0x8e */
volatile u16 reserved28;
volatile u16 tfrptr; /* PSC + 0x92 */
volatile u16 reserved29;
volatile u16 tfwptr; /* PSC + 0x96 */
volatile u16 reserved30;
volatile u16 tflrfptr; /* PSC + 0x9a */
volatile u16 reserved31;
volatile u16 tflwfptr; /* PSC + 0x9e */
};
struct mpc5xxx_intr {
volatile u32 per_mask; /* INTR + 0x00 */
volatile u32 per_pri1; /* INTR + 0x04 */
volatile u32 per_pri2; /* INTR + 0x08 */
volatile u32 per_pri3; /* INTR + 0x0c */
volatile u32 ctrl; /* INTR + 0x10 */
volatile u32 main_mask; /* INTR + 0x14 */
volatile u32 main_pri1; /* INTR + 0x18 */
volatile u32 main_pri2; /* INTR + 0x1c */
volatile u32 reserved1; /* INTR + 0x20 */
volatile u32 enc_status; /* INTR + 0x24 */
volatile u32 crit_status; /* INTR + 0x28 */
volatile u32 main_status; /* INTR + 0x2c */
volatile u32 per_status; /* INTR + 0x30 */
volatile u32 reserved2; /* INTR + 0x34 */
volatile u32 per_error; /* INTR + 0x38 */
};
struct mpc5xxx_gpio {
volatile u32 port_config; /* GPIO + 0x00 */
volatile u32 simple_gpioe; /* GPIO + 0x04 */
volatile u32 simple_ode; /* GPIO + 0x08 */
volatile u32 simple_ddr; /* GPIO + 0x0c */
volatile u32 simple_dvo; /* GPIO + 0x10 */
volatile u32 simple_ival; /* GPIO + 0x14 */
volatile u8 outo_gpioe; /* GPIO + 0x18 */
volatile u8 reserved1[3]; /* GPIO + 0x19 */
volatile u8 outo_dvo; /* GPIO + 0x1c */
volatile u8 reserved2[3]; /* GPIO + 0x1d */
volatile u8 sint_gpioe; /* GPIO + 0x20 */
volatile u8 reserved3[3]; /* GPIO + 0x21 */
volatile u8 sint_ode; /* GPIO + 0x24 */
volatile u8 reserved4[3]; /* GPIO + 0x25 */
volatile u8 sint_ddr; /* GPIO + 0x28 */
volatile u8 reserved5[3]; /* GPIO + 0x29 */
volatile u8 sint_dvo; /* GPIO + 0x2c */
volatile u8 reserved6[3]; /* GPIO + 0x2d */
volatile u8 sint_inten; /* GPIO + 0x30 */
volatile u8 reserved7[3]; /* GPIO + 0x31 */
volatile u16 sint_itype; /* GPIO + 0x34 */
volatile u16 reserved8; /* GPIO + 0x36 */
volatile u8 gpio_control; /* GPIO + 0x38 */
volatile u8 reserved9[3]; /* GPIO + 0x39 */
volatile u8 sint_istat; /* GPIO + 0x3c */
volatile u8 sint_ival; /* GPIO + 0x3d */
volatile u8 bus_errs; /* GPIO + 0x3e */
volatile u8 reserved10; /* GPIO + 0x3f */
};
struct mpc5xxx_sdma {
volatile u32 taskBar; /* SDMA + 0x00 */
volatile u32 currentPointer; /* SDMA + 0x04 */
volatile u32 endPointer; /* SDMA + 0x08 */
volatile u32 variablePointer; /* SDMA + 0x0c */
volatile u8 IntVect1; /* SDMA + 0x10 */
volatile u8 IntVect2; /* SDMA + 0x11 */
volatile u16 PtdCntrl; /* SDMA + 0x12 */
volatile u32 IntPend; /* SDMA + 0x14 */
volatile u32 IntMask; /* SDMA + 0x18 */
volatile u16 tcr_0; /* SDMA + 0x1c */
volatile u16 tcr_1; /* SDMA + 0x1e */
volatile u16 tcr_2; /* SDMA + 0x20 */
volatile u16 tcr_3; /* SDMA + 0x22 */
volatile u16 tcr_4; /* SDMA + 0x24 */
volatile u16 tcr_5; /* SDMA + 0x26 */
volatile u16 tcr_6; /* SDMA + 0x28 */
volatile u16 tcr_7; /* SDMA + 0x2a */
volatile u16 tcr_8; /* SDMA + 0x2c */
volatile u16 tcr_9; /* SDMA + 0x2e */
volatile u16 tcr_a; /* SDMA + 0x30 */
volatile u16 tcr_b; /* SDMA + 0x32 */
volatile u16 tcr_c; /* SDMA + 0x34 */
volatile u16 tcr_d; /* SDMA + 0x36 */
volatile u16 tcr_e; /* SDMA + 0x38 */
volatile u16 tcr_f; /* SDMA + 0x3a */
volatile u8 IPR0; /* SDMA + 0x3c */
volatile u8 IPR1; /* SDMA + 0x3d */
volatile u8 IPR2; /* SDMA + 0x3e */
volatile u8 IPR3; /* SDMA + 0x3f */
volatile u8 IPR4; /* SDMA + 0x40 */
volatile u8 IPR5; /* SDMA + 0x41 */
volatile u8 IPR6; /* SDMA + 0x42 */
volatile u8 IPR7; /* SDMA + 0x43 */
volatile u8 IPR8; /* SDMA + 0x44 */
volatile u8 IPR9; /* SDMA + 0x45 */
volatile u8 IPR10; /* SDMA + 0x46 */
volatile u8 IPR11; /* SDMA + 0x47 */
volatile u8 IPR12; /* SDMA + 0x48 */
volatile u8 IPR13; /* SDMA + 0x49 */
volatile u8 IPR14; /* SDMA + 0x4a */
volatile u8 IPR15; /* SDMA + 0x4b */
volatile u8 IPR16; /* SDMA + 0x4c */
volatile u8 IPR17; /* SDMA + 0x4d */
volatile u8 IPR18; /* SDMA + 0x4e */
volatile u8 IPR19; /* SDMA + 0x4f */
volatile u8 IPR20; /* SDMA + 0x50 */
volatile u8 IPR21; /* SDMA + 0x51 */
volatile u8 IPR22; /* SDMA + 0x52 */
volatile u8 IPR23; /* SDMA + 0x53 */
volatile u8 IPR24; /* SDMA + 0x54 */
volatile u8 IPR25; /* SDMA + 0x55 */
volatile u8 IPR26; /* SDMA + 0x56 */
volatile u8 IPR27; /* SDMA + 0x57 */
volatile u8 IPR28; /* SDMA + 0x58 */
volatile u8 IPR29; /* SDMA + 0x59 */
volatile u8 IPR30; /* SDMA + 0x5a */
volatile u8 IPR31; /* SDMA + 0x5b */
volatile u32 res1; /* SDMA + 0x5c */
volatile u32 res2; /* SDMA + 0x60 */
volatile u32 res3; /* SDMA + 0x64 */
volatile u32 MDEDebug; /* SDMA + 0x68 */
volatile u32 ADSDebug; /* SDMA + 0x6c */
volatile u32 Value1; /* SDMA + 0x70 */
volatile u32 Value2; /* SDMA + 0x74 */
volatile u32 Control; /* SDMA + 0x78 */
volatile u32 Status; /* SDMA + 0x7c */
volatile u32 EU00; /* SDMA + 0x80 */
volatile u32 EU01; /* SDMA + 0x84 */
volatile u32 EU02; /* SDMA + 0x88 */
volatile u32 EU03; /* SDMA + 0x8c */
volatile u32 EU04; /* SDMA + 0x90 */
volatile u32 EU05; /* SDMA + 0x94 */
volatile u32 EU06; /* SDMA + 0x98 */
volatile u32 EU07; /* SDMA + 0x9c */
volatile u32 EU10; /* SDMA + 0xa0 */
volatile u32 EU11; /* SDMA + 0xa4 */
volatile u32 EU12; /* SDMA + 0xa8 */
volatile u32 EU13; /* SDMA + 0xac */
volatile u32 EU14; /* SDMA + 0xb0 */
volatile u32 EU15; /* SDMA + 0xb4 */
volatile u32 EU16; /* SDMA + 0xb8 */
volatile u32 EU17; /* SDMA + 0xbc */
volatile u32 EU20; /* SDMA + 0xc0 */
volatile u32 EU21; /* SDMA + 0xc4 */
volatile u32 EU22; /* SDMA + 0xc8 */
volatile u32 EU23; /* SDMA + 0xcc */
volatile u32 EU24; /* SDMA + 0xd0 */
volatile u32 EU25; /* SDMA + 0xd4 */
volatile u32 EU26; /* SDMA + 0xd8 */
volatile u32 EU27; /* SDMA + 0xdc */
volatile u32 EU30; /* SDMA + 0xe0 */
volatile u32 EU31; /* SDMA + 0xe4 */
volatile u32 EU32; /* SDMA + 0xe8 */
volatile u32 EU33; /* SDMA + 0xec */
volatile u32 EU34; /* SDMA + 0xf0 */
volatile u32 EU35; /* SDMA + 0xf4 */
volatile u32 EU36; /* SDMA + 0xf8 */
volatile u32 EU37; /* SDMA + 0xfc */
};
/* function prototypes */
void loadtask(int basetask, int tasks);
#endif /* __ASSEMBLY__ */
#endif /* __ASMPPC_MPC5XXX_H */

@ -175,6 +175,11 @@
#define IM_IMMR (IM_REGBASE+0x01a8)
#define IM_SCCR (IM_REGBASE+0x0c80)
#elif defined(CONFIG_MPC5XXX)
#define HID0_ICE_BITPOS 16
#define HID0_DCE_BITPOS 17
#endif
#define curptr r2

@ -33,6 +33,9 @@
#ifdef CONFIG_5xx
#include <mpc5xx.h>
#endif
#ifdef CONFIG_MPC5XXX
#include <mpc5xxx.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
#include <ide.h>
#endif
@ -304,6 +307,9 @@ init_fnc_t *init_sequence[] = {
prt_8260_clks,
#endif /* CONFIG_8260 */
checkcpu,
#if defined(CONFIG_MPC5XXX)
prt_mpc5xxx_clks,
#endif /* CONFIG_MPC5XXX */
checkboard,
INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_BMW) || \
@ -494,6 +500,9 @@ void board_init_f (ulong bootflag)
#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx)
bd->bi_immr_base = CFG_IMMR; /* base of IMMR register */
#endif
#if defined(CONFIG_MPC5XXX)
bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */
#endif
bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */
@ -506,7 +515,10 @@ void board_init_f (ulong bootflag)
bd->bi_sccfreq = gd->scc_clk;
bd->bi_vco = gd->vco_out;
#endif /* CONFIG_8260 */
#if defined(CONFIG_MPC5XXX)
bd->bi_ipbfreq = gd->ipb_clk;
bd->bi_pcifreq = gd->pci_clk;
#endif /* CONFIG_MPC5XXX */
bd->bi_baudrate = gd->baudrate; /* Console Baudrate */
#ifdef CFG_EXTBDINFO

@ -43,6 +43,7 @@ extern int scc_initialize(bd_t*);
extern int inca_switch_initialize(bd_t*);
extern int ppc_4xx_eth_initialize(bd_t *);
extern int plb2800_eth_initialize(bd_t*);
extern int mpc5xxx_fec_initialize(bd_t*);
static struct eth_device *eth_devices, *eth_current;
@ -138,6 +139,9 @@ int eth_initialize(bd_t *bis)
#if defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FCC)
fec_initialize(bis);
#endif
#if defined(CONFIG_MPC5XXX_FEC)
mpc5xxx_fec_initialize(bis);
#endif
if (!eth_devices) {
puts ("No ethernet found.\n");

Loading…
Cancel
Save