* Add support for MGT5100 and MPC5200 processorsmaster
parent
cb4dbb7bbc
commit
945af8d723
@ -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 = .); |
||||
} |
@ -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; |
||||
} |
@ -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 */ |
@ -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 */ |
Loading…
Reference in new issue