Modifications for 1.2.0:
======================================================================
-* Fix problems in the password authorization mechanism
-
-* Fix problem on PCIPPC2 board: reading /dev/flasha and copying the
- data over NFS immediately hangs the system
-
*********************** This version of PPCBoot is Work In Progress.
*********************** It is *not* (yet) intended to be used by
** BIG FAT WARNING ** anybody else but proggrammers who know how
For details about the current modifications, please see README-WIP
+
+* Added keyboard and flash support for R360MPI board [19 Aug 2002 13:26:22]
+
+* Added POST stuff [13 Aug 2002 14:21:12]
+ Commented test routines [2 Sep 2002 19:27:01]
+
+* Patch by Josef Wagner, 12 Sep 2002:
+ Fix I2C on IP860 Board
+
+* Modified LWMON configuration: use FRAM instead of EEPROM,
+ use hardware (CPM) I2C for higher speed
+
+* Removed udelay() which broke CPM I2C code on MPC8xx
+ (We cannot use udelay() if I2C is used to hold the environment,
+ since timers are not yet running when we need I2C then.)
+
+* Patch by Ranjit Deshpande, 11 Sep 2002:
+ Fixed CONFIG_[READ|WRITE]_WORD and CONFIG_[READ|WRITE]_HALFWORD
+ macros in mpc824x.h to use "base" registers instead of any GPR
+ (avoiding the use of R0) for indexing in indexed load and store
+ instructions.
+
+* Fix problems in the password authorization mechanism
+
+* Fix problem on PCIPPC2 board: reading /dev/flasha and copying the
+ data over NFS immediately hangs the system
+
* Patch by Keith Outwate, 21 Aug 2002:
- fix/add debug messages in soft_i2c.c
- added better memory test (optional)
- README fixes / extensions
- FPGA device configuration driver (Rich Ireland)
-* Patch by Scott McNutt,, 14 Aug 2002:
+* Patch by Scott McNutt, 14 Aug 2002:
IBM 440GP Ethernet support
* Patch by Kenneth Johansson, 14 Aug 2002:
N: Wolfgang Denk
E: wd@denx.de
-D: PPCBOOT initial version, continuing maintenance
+D: PPCBOOT initial version, continuing maintenance, ARMBoot merge
W: http://www.denx.de
N: Dan A. Dickey
N: Dr. Wolfgang Grandegger
E: wg@denx.de
-D: Support for Interphase 4539 T1/E1/J1 PMC Communications Controller
+D: Support for Interphase 4539 T1/E1/J1 PMC, PN62, CCM, SCM boards
+W: www.denx.de
N: Frank Gottschling
E: fgottschling@eltec.de
N: Marius Groeger
E: mgroeger@sysgo.de
-D: MBX Support, board specific function interface, EST SBC8260 support
+D: MBX Support, board specific function interface, EST SBC8260 support; initial support for StrongARM (LART), ARM720TDMI (implementa A7)
W: www.elinos.com
N: Kirk Haderlie
E: r.ireland@computer.org
D: FPGA device configuration driver
+N: Gary Jennejohn
+E: garyj@jennejohn.org, gj@denx.de
+D: Support for Samsung ARM920T S3C2400X, ARM920T "TRAB"
+W: www.denx.de
+
N: Murray Jensen
E: Murray.Jensen@cmst.csiro.au
D: Initial 8260 support; GDB support
E: frank.morauf@salzbrenner.com
D: Support for Embedded Planet RPX Super Board
+N: David Müller
+E: d.mueller@elsoft.ch
+D: Support for Samsung ARM920T SMDK2410 eval board
+
+N: Rolf Offermanns
+E: rof@sysgo.de
+D: Initial support for SSV-DNP1110, SMC91111 driver
+W: www.elinos.com
+
N: Keith Outwater
E: Keith_Outwater@mvis.com
D: Support for GEN860T board
N: Christian Vejlbo
E: christian.vejlbo@tellabs.com
D: FADS860T ethernet support
+
+N: Alex Zuepke
+E: azu@sysgo.de
+D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM
+W: www.elinos.com
Wolfgang Denk <wd@denx.de>
AMX860 MPC860
- CCM MPC855
ETX094 MPC850
FPS850L MPC850
ICU862 MPC862
Wolfgang Grandegger <wg@denx.de>
+ CCM MPC855
+
PN62 MPC8240
IPHASE4539 MPC8260
+ SCM MPC8260
Howard Gray <mvsensor@matrix-vision.de>
LIST_824x=" \
BMW CU824 MOUSSE MUSENKI \
- OXC Sandpoint8240 Sandpoint8245 utx8245 \
+ OXC PN62 Sandpoint8240 Sandpoint8245 \
+ utx8245 \
"
#########################################################################
cogent_mpc8260 CPU86 ep8260 gw8260 \
hymod IPHASE4539 MPC8260ADS PM826 \
ppmc8260 RPXsuper rsdproto sbc8260 \
- TQM8260 \
+ SCM TQM8260 \
"
#########################################################################
rtc \
dtt \
drivers \
+ post \
+ post/cpu \
examples
#########################################################################
LIBS += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
+LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += lib_generic/libgeneric.a
#include <command.h>
#include <cmd_bsp.h>
#include <malloc.h>
+#include <post.h>
#include <linux/types.h>
#include <linux/string.h> /* for strdup */
}
}
#endif /* KEYBD_SET_DEBUGMODE */
-#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */
+#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */
setenv ("preboot", str); /* set or delete definition */
#endif /* CONFIG_PREBOOT */
if (str != NULL) {
{
i2c_reg_write (CFG_I2C_PICIO_ADDR, reg, val);
}
+
+/*-----------------------------------------------------------------------
+ * Board Control Functions
+ */
+void board_poweroff (void)
+{
+ /* Turn battery off */
+ ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pcdat &= ~(1 << (31 - 13));
+
+ while (1);
+}
#if (CONFIG_COMMANDS & CFG_CMD_BSP)
-extern int do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]);
+extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
/*
* Command led: controls the various LEDs 0..11 on the PN62 card.
*/
-int do_led (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unsigned int number, function;
#define CMD_MOVE_WINDOW 0x1
#define CMD_BOOT_IMAGE 0x2
-int do_loadpci (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *s;
ulong addr = 0, count = 0;
printf ("Automatic boot of image at addr 0x%08lX ...\n",
load_addr);
- rcode = do_bootm (cmdtp, bd, 0, 1, local_args);
+ rcode = do_bootm (cmdtp, 0, 1, local_args);
}
#ifdef CONFIG_AUTOSCRIPT
int misc_init_r (void)
{
+ DECLARE_GLOBAL_DATA_PTR;
+
char str[20];
u8 mac[6];
if (getenv ("ethaddr") == NULL &&
get_mac_address (0, mac, str, sizeof (str)) > 0) {
setenv ("ethaddr", str);
- memcpy (bd->bi_enetaddr, mac, 6);
+ memcpy (gd->bd->bi_enetaddr, mac, 6);
}
show_startup_phase (10);
if (getenv ("eth1addr") == NULL &&
get_mac_address (1, mac, str, sizeof (str)) > 0) {
setenv ("eth1addr", str);
- memcpy (bd->bi_enet1addr, mac, 6);
+ memcpy (gd->bd->bi_enet1addr, mac, 6);
}
show_startup_phase (11);
#include <mpc8xx.h>
#include <i2c.h>
+#include <commproc.h>
+#include <command.h>
+#include <cmd_bsp.h>
+#include <malloc.h>
+
+#include <linux/types.h>
+#include <linux/string.h> /* for strdup */
+
+
/*
* Memory Controller Using
*
printf ("Can't write PWM register 0x%02X.\n", reg);
}
}
+
+/* ------------------------------------------------------------------------- */
+
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+
+/* Number of bytes returned from Keyboard Controller */
+#define KEYBD_KEY_MAX 20 /* maximum key number */
+#define KEYBD_DATALEN ((KEYBD_KEY_MAX + 7) / 8) /* normal key scan data */
+
+static uchar kbd_addr = CFG_I2C_KBD_ADDR;
+
+static uchar *key_match (uchar *);
+
+int misc_init_r (void)
+{
+ uchar kbd_data[KEYBD_DATALEN];
+ uchar keybd_env[2 * KEYBD_DATALEN + 1];
+ uchar *str;
+ int i;
+
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+ for (i = 0; i < KEYBD_DATALEN; ++i) {
+ sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+ }
+ setenv ("keybd", keybd_env);
+
+ str = strdup (key_match (kbd_data)); /* decode keys */
+
+#ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */
+ setenv ("preboot", str); /* set or delete definition */
+#endif /* CONFIG_PREBOOT */
+ if (str != NULL) {
+ free (str);
+ }
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Check if pressed key(s) match magic sequence,
+ * and return the command string associated with that key(s).
+ *
+ * If no key press was decoded, NULL is returned.
+ *
+ * Note: the first character of the argument will be overwritten with
+ * the "magic charcter code" of the decoded key(s), or '\0'.
+ *
+ *
+ * Note: the string points to static environment data and must be
+ * saved before you call any function that modifies the environment.
+ */
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+static uchar *key_match (uchar * kbd_data)
+{
+ uchar compare[KEYBD_DATALEN];
+ uchar magic[sizeof (kbd_magic_prefix) + 1];
+ uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+ uchar key_mask;
+ uchar *str, *nxt, *suffix;
+ uchar *kbd_magic_keys;
+ char *cmd;
+ int i;
+
+ /*
+ * The following string defines the characters that can pe appended
+ * to "key_magic" to form the names of environment variables that
+ * hold "magic" key codes, i. e. such key codes that can cause
+ * pre-boot actions. If the string is empty (""), then only
+ * "key_magic" is checked (old behaviour); the string "125" causes
+ * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+ */
+ if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+ kbd_magic_keys = "";
+
+ /* loop over all magic keys;
+ * use '\0' suffix in case of empty string
+ */
+ for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) {
+ sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+#if 0
+ printf ("### Check magic \"%s\"\n", magic);
+#endif
+
+ memcpy(compare, kbd_data, KEYBD_DATALEN);
+
+ for (str = getenv(magic); str != NULL; str = (*nxt) ? nxt+1 : nxt) {
+ uchar c;
+
+ c = (uchar) simple_strtoul (str, (char **) (&nxt), 16);
+
+ if (str == nxt) /* invalid character */
+ break;
+
+ if (c >= KEYBD_KEY_MAX) /* bad key number */
+ goto next_magic;
+
+ key_mask = 0x80 >> (c % 8);
+
+ if (!(compare[c / 8] & key_mask)) /* key not pressed */
+ goto next_magic;
+
+ compare[c / 8] &= ~key_mask;
+ }
+
+ for (i=0; i<KEYBD_DATALEN; i++)
+ if (compare[i]) /* key(s) not released */
+ goto next_magic;
+
+ sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+
+ cmd = getenv (cmd_name);
+#if 0
+ printf ("### Set PREBOOT to $(%s): \"%s\"\n",
+ cmd_name, cmd ? cmd : "<<NULL>>");
+#endif
+ *kbd_data = *suffix;
+ return (cmd);
+
+ next_magic:;
+ }
+#if 0
+ printf ("### Delete PREBOOT\n");
+#endif
+ *kbd_data = '\0';
+ return (NULL);
+}
+#endif /* CONFIG_PREBOOT */
+
+/* Read Keyboard status */
+int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ uchar kbd_data[KEYBD_DATALEN];
+ uchar keybd_env[2 * KEYBD_DATALEN + 1];
+ int i;
+
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ /* Read keys */
+ i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+ puts ("Keys:");
+ for (i = 0; i < KEYBD_DATALEN; ++i) {
+ sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
+ printf (" %02x", kbd_data[i]);
+ }
+ putc ('\n');
+ setenv ("keybd", keybd_env);
+ return 0;
+}
rOPENCR = 0x0;
/* arch number of SAMSUNG-Board */
- /* I have no idea what this means, so I just picked an unused value */
- gd->bd->bi_arch_number = 28;
+ gd->bd->bi_arch_number = 145;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x0C000100;
LIB = libcommon.a
AOBJS =
-COBJS = main.o altera.o command.o environment.o bedbug.o \
- cmd_autoscript.o cmd_bedbug.o cmd_boot.o cmd_bootm.o \
- cmd_cache.o cmd_console.o cmd_date.o cmd_dcr.o cmd_doc.o \
- cmd_dtt.o cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_flash.o \
- cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o cmd_jffs2.o \
- cmd_mem.o cmd_mii.o cmd_misc.o cmd_net.o cmd_nvedit.o \
- cmd_pcmcia.o cmd_reginfo.o cmd_scsi.o cmd_usb.o cmd_pci.o \
- console.o devices.o dlmalloc.o docecc.o flash.o fpga.o \
- hush.o kgdb.o lists.o miiphybb.o miiphyutil.o s_record.o \
- soft_i2c.o spartan2.o usb.o usb_kbd.o usb_storage.o \
- virtex2.o xilinx.o
-# Temporary hack to get ARM working quickly
-ifeq ($(ARCH),ppc)
-COBJS += cmd_nvedit.o
-endif
+COBJS = main.o altera.o bedbug.o \
+ cmd_autoscript.o cmd_bedbug.o cmd_boot.o \
+ cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o \
+ cmd_dcr.o cmd_diag.o cmd_doc.o cmd_dtt.o \
+ cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_flash.o \
+ cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o \
+ cmd_jffs2.o cmd_mem.o cmd_mii.o cmd_misc.o \
+ cmd_net.o cmd_nvedit.o cmd_pci.o cmd_pcmcia.o \
+ cmd_reginfo.o cmd_scsi.o cmd_usb.o \
+ command.o console.o devices.o dlmalloc.o \
+ docecc.o environment.o flash.o fpga.o \
+ hush.o kgdb.o lists.o miiphybb.o miiphyutil.o \
+ s_record.o soft_i2c.o spartan2.o \
+ usb.o usb_kbd.o usb_storage.o \
+ virtex2.o xilinx.o
OBJS = $(AOBJS) $(COBJS)
#include <image.h>
#include <malloc.h>
#include <zlib.h>
+#include <asm/byteorder.h>
#if (CONFIG_COMMANDS & CFG_CMD_DATE)
#include <rtc.h>
#endif
ulong *len_ptr, /* multi-file image length table */
int verify); /* getenv("verify")[0] != 'n' */
+#ifndef CONFIG_ARM
static boot_os_Fcn do_bootm_linux;
+#else
+extern boot_os_Fcn do_bootm_linux;
+#endif
static boot_os_Fcn do_bootm_netbsd;
#if (CONFIG_COMMANDS & CFG_CMD_ELF)
static boot_os_Fcn do_bootm_vxworks;
/* Copy header so we can blank CRC field for re-calculation */
memcpy (&header, (char *)addr, sizeof(image_header_t));
- if (hdr->ih_magic != IH_MAGIC) {
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf ("Bad Magic Number\n");
SHOW_BOOT_PROGRESS (-1);
return 1;
data = (ulong)&header;
len = sizeof(image_header_t);
- checksum = hdr->ih_hcrc;
+ checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)data, len) != checksum) {
print_image_hdr ((image_header_t *)addr);
data = addr + sizeof(image_header_t);
- len = hdr->ih_size;
+ len = ntohl(hdr->ih_size);
if (verify) {
printf (" Verifying Checksum ... ");
- if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
+ if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf ("Bad Data CRC\n");
SHOW_BOOT_PROGRESS (-3);
return 1;
len_ptr = (ulong *)data;
- if (hdr->ih_arch != IH_CPU_PPC) {
+ if (hdr->ih_arch != IH_CPU_PPC && hdr->ih_arch != IH_CPU_ARM) {
printf ("Unsupported Architecture\n");
SHOW_BOOT_PROGRESS (-4);
return 1;
case IH_TYPE_KERNEL: name = "Kernel Image";
break;
case IH_TYPE_MULTI: name = "Multi-File Image";
- len = len_ptr[0];
+ len = ntohl(len_ptr[0]);
/* OS kernel is always the first image */
data += 8; /* kernel_len + terminator */
for (i=1; len_ptr[i]; ++i)
printf (" XIP %s ... ", name);
} else {
printf (" Loading %s ... ", name);
- memcpy ((void *)hdr->ih_load, (uchar *)data, len);
+ memcpy ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
}
break;
case IH_COMP_GZIP:
printf (" Uncompressing %s ... ", name);
- if (gunzip ((void *)hdr->ih_load, 0x400000,
+ if (gunzip ((void *)ntohl(hdr->ih_load), 0x400000,
(uchar *)data, (int *)&len) != 0) {
printf ("GUNZIP ERROR - must RESET board to recover\n");
SHOW_BOOT_PROGRESS (-6);
switch (hdr->ih_type) {
case IH_TYPE_STANDALONE:
- appl = (int (*)(cmd_tbl_t *, int, int, char *[]))hdr->ih_ep;
+ appl = (int (*)(cmd_tbl_t *, int, int, char *[]))ntohl(hdr->ih_ep);
if (iflag)
enable_interrupts();
return 1;
}
+#ifndef CONFIG_ARM
static void
do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
int argc, char *argv[],
ulong *len_ptr,
int verify)
{
-#ifdef CONFIG_ARM /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
-#warning ARM version not implemented yet /* XXXXXXXXXXXXXXXXXXXXXXXXXXXX */
- return;
-#else /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
DECLARE_GLOBAL_DATA_PTR;
ulong sp;
* r7: End of command line string
*/
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
-#endif /* CONFIG_ARM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
}
+#endif /* CONFIG_ARM */
static void
do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag,
/* Copy header so we can blank CRC field for re-calculation */
memcpy (&header, (char *)addr, sizeof(image_header_t));
- if (hdr->ih_magic != IH_MAGIC) {
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
printf (" Bad Magic Number\n");
return 1;
}
data = (ulong)&header;
len = sizeof(image_header_t);
- checksum = hdr->ih_hcrc;
+ checksum = ntohl(hdr->ih_hcrc);
hdr->ih_hcrc = 0;
if (crc32 (0, (char *)data, len) != checksum) {
print_image_hdr ((image_header_t *)addr);
data = addr + sizeof(image_header_t);
- len = hdr->ih_size;
+ len = ntohl(hdr->ih_size);
printf (" Verifying Checksum ... ");
- if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
+ if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
printf (" Bad Data CRC\n");
return 1;
}
tm.tm_hour, tm.tm_min, tm.tm_sec);
#endif /* CFG_CMD_DATE */
printf (" Image Type: "); print_type(hdr); printf ("\n");
- printf (" Data Size: %d Bytes = ", hdr->ih_size);
- print_size (hdr->ih_size, "\n");
- printf (" Load Address: %08x\n", hdr->ih_load);
- printf (" Entry Point: %08x\n", hdr->ih_ep);
+ printf (" Data Size: %d Bytes = ", ntohl(hdr->ih_size));
+ print_size (ntohl(hdr->ih_size), "\n");
+ printf (" Load Address: %08x\n", ntohl(hdr->ih_load));
+ printf (" Entry Point: %08x\n", ntohl(hdr->ih_ep));
if (hdr->ih_type == IH_TYPE_MULTI) {
int i;
+ ulong len;
ulong *len_ptr = (ulong *)((ulong)hdr + sizeof(image_header_t));
printf (" Contents:\n");
- for (i=0; *len_ptr; ++i, ++len_ptr) {
- printf (" Image %d: %8ld Bytes = ", i, *len_ptr);
- print_size (*len_ptr, "\n");
+ for (i=0; (len = ntohl(*len_ptr)); ++i, ++len_ptr) {
+ printf (" Image %d: %8ld Bytes = ", i, len);
+ print_size (len, "\n");
}
}
}
--- /dev/null
+/*
+ * (C) Copyright 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
+ */
+
+/*
+ * Diagnostics support
+ */
+#include <common.h>
+#include <command.h>
+#include <cmd_diag.h>
+#include <post.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_DIAG) && defined(CONFIG_POST)
+
+int do_diag (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ unsigned int i;
+
+ if (argc == 1 || strcmp (argv[1], "run") != 0) {
+ /* List test info */
+ if (argc == 1) {
+ printf ("Available hardware tests:\n");
+ post_info (NULL);
+ printf ("Use 'diag [<test1> [<test2> ...]]'"
+ " to get more info.\n");
+ printf ("Use 'diag run [<test1> [<test2> ...]]'"
+ " to run tests.\n");
+ } else {
+ for (i = 1; i < argc; i++) {
+ if (post_info (argv[i]) != 0)
+ printf ("%s - no such test\n", argv[i]);
+ }
+ }
+ } else {
+ /* Run tests */
+ if (argc == 2) {
+ post_run (NULL, POST_RAM | POST_MANUAL);
+ } else {
+ for (i = 2; i < argc; i++) {
+ if (post_run (argv[i], POST_RAM | POST_MANUAL) != 0)
+ printf ("%s - unable to execute the test\n",
+ argv[i]);
+ }
+ }
+ }
+
+ return 0;
+}
+
+#endif /* CFG_CMD_DIAG */
# if defined(CFG_ENV_IS_IN_EEPROM)
DEBUGF ("%s[%d] read ENV from EEPROM\n", __FUNCTION__,__LINE__);
eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET,
- env_ptr,
+ (uchar *)env_ptr,
CFG_ENV_SIZE);
# elif defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE)
DEBUGF ("%s[%d] read ENV from NVRAM\n", __FUNCTION__,__LINE__);
#endif /* C2MON */
+/* ---------------------------------------------------------------------------- */
+/* R360MPI Board */
+/* ---------------------------------------------------------------------------- */
+
+#if defined(CONFIG_R360MPI)
+
+#define PCMCIA_BOARD_MSG "R360MPI"
+
+
+static int hardware_enable(int slot)
+{
+ volatile immap_t *immap;
+ volatile cpm8xx_t *cp;
+ volatile pcmconf8xx_t *pcmp;
+ volatile sysconf8xx_t *sysp;
+ uint reg, mask;
+
+ PCMCIA_DEBUG ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+ udelay(10000);
+
+ immap = (immap_t *)CFG_IMMR;
+ sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+ cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
+
+ /*
+ * Configure SIUMCR to enable PCMCIA port B
+ * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
+ */
+ sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
+
+ /* clear interrupt state, and disable interrupts */
+ pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
+ pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
+
+ /* disable interrupts & DMA */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ /*
+ * Disable PCMCIA buffers (isolate the interface)
+ * and assert RESET signal
+ */
+ PCMCIA_DEBUG ("Disable PCMCIA buffers and assert RESET\n");
+ reg = PCMCIA_PGCRX(_slot_);
+ reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
+ reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
+ PCMCIA_PGCRX(_slot_) = reg;
+ udelay(500);
+
+ /*
+ * Configure Ports A, B & C pins for
+ * 5 Volts Enable and 3 Volts enable
+ */
+ immap->im_ioport.iop_pcpar &= ~(0x0400);
+ immap->im_ioport.iop_pcso &= ~(0x0400);/*
+ immap->im_ioport.iop_pcdir |= 0x0400;*/
+
+ immap->im_ioport.iop_papar &= ~(0x0200);/*
+ immap->im_ioport.iop_padir |= 0x0200;*/
+#if 0
+ immap->im_ioport.iop_pbpar &= ~(0xC000);
+ immap->im_ioport.iop_pbdir &= ~(0xC000);
+#endif
+ /* remove all power */
+
+ immap->im_ioport.iop_pcdat |= 0x0400;
+ immap->im_ioport.iop_padat |= 0x0200;
+
+ /*
+ * Make sure there is a card in the slot, then configure the interface.
+ */
+ udelay(10000);
+ PCMCIA_DEBUG ("[%d] %s: PIPR(%p)=0x%x\n",
+ __LINE__,__FUNCTION__,
+ &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
+ if (pcmp->pcmc_pipr & 0x00001800) {
+ printf (" No Card found\n");
+ return (1);
+ }
+
+ /*
+ * Power On.
+ */
+ mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
+ reg = pcmp->pcmc_pipr;
+ PCMCIA_DEBUG ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
+ reg,
+ (reg&PCMCIA_VS1(slot))?"n":"ff",
+ (reg&PCMCIA_VS2(slot))?"n":"ff");
+ if ((reg & mask) == mask) {
+ immap->im_ioport.iop_pcdat &= ~(0x4000);
+ puts (" 5.0V card found: ");
+ } else {
+ immap->im_ioport.iop_padat &= ~(0x0002);
+ puts (" 3.3V card found: ");
+ }
+ immap->im_ioport.iop_pcdir |= 0x0400;
+ immap->im_ioport.iop_padir |= 0x0200;
+#if 0
+ /* VCC switch error flag, PCMCIA slot INPACK_ pin */
+ cp->cp_pbdir &= ~(0x0020 | 0x0010);
+ cp->cp_pbpar &= ~(0x0020 | 0x0010);
+ udelay(500000);
+#endif
+ PCMCIA_DEBUG ("Enable PCMCIA buffers and stop RESET\n");
+ reg = PCMCIA_PGCRX(_slot_);
+ reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
+ reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
+ PCMCIA_PGCRX(_slot_) = reg;
+
+ udelay(250000); /* some cards need >150 ms to come up :-( */
+
+ PCMCIA_DEBUG ("# hardware_enable done\n");
+
+ return (0);
+}
+
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
+static int hardware_disable(int slot)
+{
+ volatile immap_t *immap;
+ volatile pcmconf8xx_t *pcmp;
+ u_long reg;
+
+ PCMCIA_DEBUG ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
+
+ immap = (immap_t *)CFG_IMMR;
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+
+ /* remove all power */
+ immap->im_ioport.iop_pcdat |= 0x0400;
+ immap->im_ioport.iop_padat |= 0x0200;
+
+ /* Configure PCMCIA General Control Register */
+ PCMCIA_PGCRX(_slot_) = 0;
+
+ PCMCIA_DEBUG ("Disable PCMCIA buffers and assert RESET\n");
+ reg = PCMCIA_PGCRX(_slot_);
+ reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
+ reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
+ PCMCIA_PGCRX(_slot_) = reg;
+
+ udelay(10000);
+
+ return (0);
+}
+#endif /* CFG_CMD_PCMCIA */
+
+
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ volatile immap_t *immap;
+ volatile pcmconf8xx_t *pcmp;
+ u_long reg;
+
+ PCMCIA_DEBUG ("voltage_set: " \
+ PCMCIA_BOARD_MSG \
+ " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
+ 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
+
+ immap = (immap_t *)CFG_IMMR;
+ pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
+ /*
+ * Disable PCMCIA buffers (isolate the interface)
+ * and assert RESET signal
+ */
+ PCMCIA_DEBUG ("Disable PCMCIA buffers and assert RESET\n");
+ reg = PCMCIA_PGCRX(_slot_);
+ reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
+ reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
+ PCMCIA_PGCRX(_slot_) = reg;
+ udelay(500);
+
+ /*
+ * Configure Ports A & C pins for
+ * 5 Volts Enable and 3 Volts enable,
+ * Turn off all power
+ */
+ PCMCIA_DEBUG ("PCMCIA power OFF\n");
+ immap->im_ioport.iop_pcpar &= ~(0x0400);
+ immap->im_ioport.iop_pcso &= ~(0x0400);/*
+ immap->im_ioport.iop_pcdir |= 0x0400;*/
+
+ immap->im_ioport.iop_papar &= ~(0x0200);/*
+ immap->im_ioport.iop_padir |= 0x0200;*/
+
+ immap->im_ioport.iop_pcdat |= 0x0400;
+ immap->im_ioport.iop_padat |= 0x0200;
+
+ reg = 0;
+ switch(vcc) {
+ case 0: break;
+ case 33: reg |= 0x0200; break;
+ case 50: reg |= 0x0400; break;
+ default: goto done;
+ }
+
+ /* Checking supported voltages */
+
+ PCMCIA_DEBUG ("PIPR: 0x%x --> %s\n",
+ pcmp->pcmc_pipr,
+ (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
+
+ if (reg & 0x0200)
+ immap->im_ioport.iop_pcdat &= !reg;
+ if (reg & 0x0400)
+ immap->im_ioport.iop_padat &= !reg;
+ immap->im_ioport.iop_pcdir |= 0x0200;
+ immap->im_ioport.iop_padir |= 0x0400;
+ if (reg) {
+ PCMCIA_DEBUG ("PCMCIA powered at %sV\n",
+ (reg&0x0400) ? "5.0" : "3.3");
+ } else {
+ PCMCIA_DEBUG ("PCMCIA powered down\n");
+ }
+
+done:
+ PCMCIA_DEBUG ("Enable PCMCIA buffers and stop RESET\n");
+ reg = PCMCIA_PGCRX(_slot_);
+ reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
+ reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
+ PCMCIA_PGCRX(_slot_) = reg;
+ udelay(500);
+
+ PCMCIA_DEBUG ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
+ slot+'A');
+ return (0);
+}
+
+#endif /* R360MPI */
+
+
/* ---------------------------------------------------------------------------- */
/* End of Board Specific Stuff */
/* ---------------------------------------------------------------------------- */
#include <cmd_reginfo.h>
#include <cmd_pcmcia.h>
#include <cmd_autoscript.h>
+#include <cmd_diag.h>
#include <cmd_eeprom.h>
#include <cmd_i2c.h>
CMD_TBL_VERS
CMD_TBL_BSP
CMD_TBL_QUES
+ CMD_TBL_DIAG
/* the following entry terminates this table */
MK_CMD_TBL_ENTRY( NULL, 0, 0, 0, NULL, NULL, NULL )
};
+++ /dev/null
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <asm/cpm_8260.h>
-#include <i2c.h>
-
-#if defined(CONFIG_SOFT_I2C)
-
-/*-----------------------------------------------------------------------
- * Set default values
- */
-#ifndef CFG_I2C_SPEED
-#define CFG_I2C_SPEED 50000
-#endif
-
-#ifndef CFG_I2C_SLAVE
-#define CFG_I2C_SLAVE 0xFE
-#endif
-
-/*-----------------------------------------------------------------------
- * Definitions
- */
-
-/* TQM8260 Rev.100 has the clock and data pins swapped (!!!) on EEPROM
- */
-#if defined (CONFIG_TQM8260) && (CONFIG_TQM8260 <= 100)
-#define PD_SCL 0x00010000 /* PD 15 */
-#define PD_SDA 0x00020000 /* PD 14 */
-#else
-#define PD_SCL 0x00020000 /* PD 14 */
-#define PD_SDA 0x00010000 /* PD 15 */
-#endif
-
-#define I2C_ACK 0 /* PD_SDA level to ack a byte */
-#define I2C_NOACK 1 /* PD_SDA level to noack a byte */
-
-#define SET_PD_BIT(bit) do { \
- immr->im_ioport.iop_pdird |= bit;/* output */ \
- immr->im_ioport.iop_pdatd |= bit;/* set 1 */ \
- udelay (5); \
- } while (0)
-
-#define RESET_PD_BIT(bit) do { \
- immr->im_ioport.iop_pdird |= bit;/* output */ \
- immr->im_ioport.iop_pdatd &= ~bit;/* set 0 */ \
- udelay (5); \
- } while (0)
-
-#define RESET_PD_BIT1(bit) do { \
- immr->im_ioport.iop_pdird |= bit;/* output */ \
- immr->im_ioport.iop_pdatd &= ~bit;/* set 0 */ \
- udelay (1); \
- } while (0)
-
-/*-----------------------------------------------------------------------
- * Functions
- */
-static void send_start (void);
-static void send_stop (void);
-static void send_ack (int);
-static void rcv_ack (void);
-static void send_data_1 (void);
-static void send_data_0 (void);
-static void read_addr (uchar addr);
-static void write_addr (uchar addr);
-static int read_bit (void);
-static uchar read_byte (int);
-static void write_byte (uchar byte);
-
-/*-----------------------------------------------------------------------
- * START: High -> Low on SDA while SCL is High
- */
-static void send_start (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- SET_PD_BIT (PD_SCL);
- RESET_PD_BIT (PD_SDA);
-}
-
-/*-----------------------------------------------------------------------
- * STOP: Low -> High on SDA while SCL is High
- */
-static void send_stop (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PD_BIT (PD_SDA);
- SET_PD_BIT (PD_SCL);
- SET_PD_BIT (PD_SDA);
- udelay (5);
-}
-
-/*-----------------------------------------------------------------------
- * ack should be I2C_ACK or I2C_NOACK
- */
-static void send_ack (int ack)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PD_BIT (PD_SCL);
- if (ack == I2C_ACK)
- RESET_PD_BIT (PD_SDA);
- else
- SET_PD_BIT (PD_SDA);
- SET_PD_BIT (PD_SCL);
- udelay (5);
- RESET_PD_BIT (PD_SCL);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void rcv_ack (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PD_BIT (PD_SCL);
-
- immr->im_ioport.iop_pdird &= ~PD_SDA; /* input */
- udelay (10);
- while (immr->im_ioport.iop_pdatd & PD_SDA)
- ;
- udelay (5);
- SET_PD_BIT (PD_SCL);
- RESET_PD_BIT (PD_SCL);
- SET_PD_BIT (PD_SDA);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void send_data_1 (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PD_BIT1(PD_SCL);
- SET_PD_BIT (PD_SDA);
- SET_PD_BIT (PD_SCL);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void send_data_0 (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PD_BIT1(PD_SCL);
- RESET_PD_BIT (PD_SDA);
- SET_PD_BIT (PD_SCL);
-}
-
-
-/*-----------------------------------------------------------------------
- */
-static void read_addr (uchar addr)
-{
- int i;
-
- addr = (addr << 1) | 0x01;
-
- for (i=0; i<8; ++i) {
- if (addr & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- addr <<= 1;
- }
-
- rcv_ack ();
-}
-
-/*-----------------------------------------------------------------------
- * addr & 0xF0 -> Device Identifier
- * addr & 0x0E -> bank_num or device address << 1
- * addr & 0x01 -> 1 = read, 0 = write
- */
-static void write_addr (uchar addr)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- addr <<= 1;
-
- for (;;) {
- uchar a = addr;
- uint i;
-
- send_start ();
-
- for (i=0; i<8; ++i) {
- if (a & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- a <<= 1;
- }
-
- RESET_PD_BIT (PD_SCL);
-
- immr->im_ioport.iop_pdird &= ~PD_SDA; /* input */
- udelay (10);
-
- i = immr->im_ioport.iop_pdatd;
- udelay (5);
- SET_PD_BIT (PD_SCL);
- RESET_PD_BIT (PD_SCL);
- SET_PD_BIT (PD_SDA);
-
- if ((i & PD_SDA) == 0)
- break;
-
- send_stop();
- }
-}
-
-/*-----------------------------------------------------------------------
- */
-static int read_bit (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- int bit;
-
- RESET_PD_BIT (PD_SCL);
- SET_PD_BIT (PD_SCL);
- bit = (immr->im_ioport.iop_pdatd & PD_SDA) ? 1 : 0;
- return (bit);
-}
-
-/*-----------------------------------------------------------------------
- * if last == 0, ACK the byte so can continue reading
- * else NO ACK to end the read
- */
-static uchar read_byte (int last)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- uchar byte = 0;
- int i;
-
- immr->im_ioport.iop_pdird &= ~PD_SDA; /* input */
- udelay (5);
-
- for (i=0; i<8; ++i) {
- byte = (byte << 1) | read_bit();
- }
- send_ack (last ? I2C_NOACK : I2C_ACK);
-
- return byte;
-}
-
-/*-----------------------------------------------------------------------
- */
-static void write_byte (uchar byte)
-{
- int i;
- for (i=0; i<8; ++i) {
- if (byte & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- byte <<= 1;
- }
- rcv_ack();
-}
-
-/*=====================================================================*/
-/*=====================================================================*/
-
-/*-----------------------------------------------------------------------
- * `speed' and `slaveaddr' not implemented
- */
-void i2c_init (int speed, int slaveaddr)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- immr->im_ioport.iop_ppard &= ~(PD_SCL | PD_SDA);/* GPIO */
- immr->im_ioport.iop_podrd |= (PD_SCL | PD_SDA);/* Open Drain Output */
-
- RESET_PD_BIT (PD_SCL);
- RESET_PD_BIT (PD_SDA);
- SET_PD_BIT (PD_SCL);
- SET_PD_BIT (PD_SDA); /* stop condition */
- udelay (25);
-}
-
-/*-----------------------------------------------------------------------
- *
- * addr: Array of address bytes; for instance, to read from
- * EEPROM with 8 bit page addresses you have to write 2
- * address bytes: the block number, and the block
- * offset.
- * alen: Number of address bytes in "addr"
- * buffer: where to store the read data in
- * len: number of bytes to read
- * Warning: it is expected that the device is really
- * capable of reading `len' sequential bytes; no
- * checking is doen here
- */
-int i2c_read (uchar *addr, int alen, uchar *buffer, int len)
-{
- uchar *ap = addr;
-
- write_addr (*ap);
- while (--alen > 0) {
- write_byte (*++ap);
- }
- send_start ();
-
- read_addr (*addr);
- while (len-- > 0) {
- *buffer++ = read_byte (len==0);
- }
- send_stop ();
- return (0); /* No error handling yet */
-}
-
-int i2c_write (uchar *addr, int alen, uchar *buffer, int len)
-{
- uchar *ap = addr;
-
- write_addr (*ap);
- while (--alen > 0) {
- write_byte (*++ap);
- }
-
- while (len-- > 0) {
- write_byte (*buffer++);
- }
- send_stop ();
- return (0); /* No error handling yet */
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
- char addr[2];
- char buf [1];
-
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-
- addr[0] = i2c_addr;
- addr[1] = reg;
-
- i2c_read (addr, 2, buf, 1);
-
- return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
- char addr[2];
-
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-
- addr[0] = i2c_addr;
- addr[1] = reg;
-
- i2c_write (addr, 2, &val, 1);
-}
-
-#endif /* CONFIG_SOFT_I2C */
-/*-----------------------------------------------------------------------
- */
return (gd->dp_alloc_base + mask) & ~mask;
}
+#endif /* CFG_ALLOC_DPRAM */
-#endif /* CFG_ALLOC_DPRAM */
+#ifdef CONFIG_POST
+
+void post_word_store (ulong a)
+{
+ volatile void *save_addr =
+ ((immap_t *) CFG_IMMR)->im_cpm.cp_dpmem + CPM_POST_WORD_ADDR;
+
+ *(volatile ulong *) save_addr = a;
+}
+
+ulong post_word_load (void)
+{
+ volatile void *save_addr =
+ ((immap_t *) CFG_IMMR)->im_cpm.cp_dpmem + CPM_POST_WORD_ADDR;
+
+ return *(volatile ulong *) save_addr;
+}
+
+#endif /* CONFIG_POST */
/* define to enable debug messages */
#undef DEBUG_I2C
-/* us to wait before checking the i2c */
-#define DELAY_US 100000
-
/*-----------------------------------------------------------------------
* Set default values
*/
PRINTD(("\t\tmoddiv=%d, brgdiv=%d\n", moddiv, brgdiv));
- *brgval = (brgdiv / 2) - 3 - (2*filter);
+ *brgval = ((brgdiv + 1) / 2) - 3 - (2*filter);
if ((*brgval < 0) || (*brgval > 255)) {
PRINTD(("\t\trejected brgval=%d\n", *brgval));
brgdiv = 2 * (*brgval + 3 + (2 * filter));
div = moddiv * brgdiv ;
- *totspeed = (hz + div - 1) / div;
+ *totspeed = hz / div;
PRINTD(("\t\taccepted brgval=%d, totspeed=%d\n", *brgval, *totspeed));
/* Begin transmission */
i2c->i2c_i2com |= 0x80;
- /* This is a patch! */
- udelay (DELAY_US)
- ;
-
/* Loop until transmit & receive completed */
if (state->tx_idx > 0) {
+++ /dev/null
-/*
- * (C) Copyright 2001
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <mpc8xx.h>
-#include <i2c.h>
-
-#if defined(CONFIG_SOFT_I2C)
-
-/*-----------------------------------------------------------------------
- * Set default values
- */
-#ifndef CFG_I2C_SPEED
-#define CFG_I2C_SPEED 50000
-#endif
-
-#ifndef CFG_I2C_SLAVE
-#define CFG_I2C_SLAVE 0xFE
-#endif
-
-/*-----------------------------------------------------------------------
- * Definitions
- */
-
-#define PB_SCL 0x00000020 /* PB 26 */
-#define PB_SDA 0x00000010 /* PB 27 */
-#define I2C_ACK 0 /* PB_SDA level to ack a byte */
-#define I2C_NOACK 1 /* PB_SDA level to noack a byte */
-
-#define SET_PB_BIT(bit) do { \
- immr->im_cpm.cp_pbdir |= bit; /* output */ \
- immr->im_cpm.cp_pbdat |= bit; /* set 1 */ \
- udelay (5); \
- } while (0)
-
-#define RESET_PB_BIT(bit) do { \
- immr->im_cpm.cp_pbdir |= bit; /* output */ \
- immr->im_cpm.cp_pbdat &= ~bit; /* set 0 */ \
- udelay (5); \
- } while (0)
-
-#define RESET_PB_BIT1(bit) do { \
- immr->im_cpm.cp_pbdir |= bit; /* output */ \
- immr->im_cpm.cp_pbdat &= ~bit; /* set 0 */ \
- udelay (1); \
- } while (0)
-
-/*-----------------------------------------------------------------------
- * Functions
- */
-static void send_start (void);
-static void send_stop (void);
-static void send_ack (int);
-static void rcv_ack (void);
-static void send_data_1 (void);
-static void send_data_0 (void);
-static void read_addr (uchar addr);
-static void write_addr (uchar addr);
-static int read_bit (void);
-static uchar read_byte (int);
-static void write_byte (uchar byte);
-
-/*-----------------------------------------------------------------------
- * START: High -> Low on SDA while SCL is High
- */
-static void send_start (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- SET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SDA);
-}
-
-/*-----------------------------------------------------------------------
- * STOP: Low -> High on SDA while SCL is High
- */
-static void send_stop (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA);
- udelay (5);
-}
-
-/*-----------------------------------------------------------------------
- * ack should be I2C_ACK or I2C_NOACK
- */
-static void send_ack (int ack)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT (PB_SCL);
- if (ack == I2C_ACK)
- RESET_PB_BIT (PB_SDA);
- else
- SET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
- udelay (5);
- RESET_PB_BIT (PB_SCL);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void rcv_ack (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT (PB_SCL);
-
- immr->im_cpm.cp_pbdir &= ~PB_SDA; /* input */
- udelay (10);
- while (immr->im_cpm.cp_pbdat & PB_SDA)
- ;
- udelay (5);
- SET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void send_data_1 (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT1(PB_SCL);
- SET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void send_data_0 (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT1(PB_SCL);
- RESET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
-}
-
-
-/*-----------------------------------------------------------------------
- */
-static void read_addr (uchar addr)
-{
- int i;
-
- addr = (addr << 1) | 0x01;
-
- for (i=0; i<8; ++i) {
- if (addr & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- addr <<= 1;
- }
-
- rcv_ack ();
-}
-
-/*-----------------------------------------------------------------------
- * addr & 0xF0 -> Device Identifier
- * addr & 0x0E -> bank_num or device address << 1
- * addr & 0x01 -> 1 = read, 0 = write
- */
-static void write_addr (uchar addr)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- addr <<= 1;
-
- for (;;) {
- uchar a = addr;
- uint i;
-
- send_start ();
-
- for (i=0; i<8; ++i) {
- if (a & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- a <<= 1;
- }
-
- RESET_PB_BIT (PB_SCL);
-
- immr->im_cpm.cp_pbdir &= ~PB_SDA; /* input */
- udelay (10);
-
- i = immr->im_cpm.cp_pbdat;
- udelay (5);
- SET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA);
-
- if ((i & PB_SDA) == 0)
- break;
-
- send_stop();
- }
-}
-
-/*-----------------------------------------------------------------------
- */
-static int read_bit (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- int bit;
-
- RESET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SCL);
- bit = (immr->im_cpm.cp_pbdat & PB_SDA) ? 1 : 0;
- return (bit);
-}
-
-/*-----------------------------------------------------------------------
- * if last == 0, ACK the byte so can continue reading
- * else NO ACK to end the read
- */
-static uchar read_byte (int last)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- uchar byte = 0;
- int i;
-
- immr->im_cpm.cp_pbdir &= ~PB_SDA; /* input */
- udelay (5);
-
- for (i=0; i<8; ++i) {
- byte = (byte << 1) | read_bit();
- }
- send_ack (last ? I2C_NOACK : I2C_ACK);
-
- return byte;
-}
-
-/*-----------------------------------------------------------------------
- */
-static void write_byte (uchar byte)
-{
- int i;
- for (i=0; i<8; ++i) {
- if (byte & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- byte <<= 1;
- }
- rcv_ack();
-}
-
-/*=====================================================================*/
-/*=====================================================================*/
-
-/*-----------------------------------------------------------------------
- * `speed' and `slaveaddr' not implemented
- */
-void i2c_init (int speed, int slaveaddr)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- immr->im_cpm.cp_pbpar &= ~(PB_SCL | PB_SDA); /* GPIO */
- immr->im_cpm.cp_pbodr |= (PB_SCL | PB_SDA); /* Open Drain Output */
-
- RESET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA); /* stop condition */
- udelay (25);
-}
-
-/*-----------------------------------------------------------------------
- *
- * addr: Array of address bytes; for instance, to read from
- * EEPROM with 8 bit page addresses you have to write 2
- * address bytes: the block number, and the block
- * offset.
- * alen: Number of address bytes in "addr"
- * buffer: where to store the read data in
- * len: number of bytes to read
- * Warning: it is expected that the device is really
- * capable of reading `len' sequential bytes; no
- * checking is done here
- */
-int i2c_read (uchar *addr, int alen, uchar *buffer, int len)
-{
- uchar *ap = addr;
-
- write_addr (*ap);
- while (--alen > 0) {
- write_byte (*++ap);
- }
- send_start ();
-
- read_addr (*addr);
- while (len-- > 0) {
- *buffer++ = read_byte (len==0);
- }
- send_stop ();
- return (0); /* No error handling yet */
-}
-
-int i2c_write (uchar *addr, int alen, uchar *buffer, int len)
-{
- uchar *ap = addr;
-
- write_addr (*ap);
- while (--alen > 0) {
- write_byte (*++ap);
- }
-
- while (len-- > 0) {
- write_byte (*buffer++);
- }
- send_stop ();
- return (0); /* No error handling yet */
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
- char addr[2];
- char buf [1];
-
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-
- addr[0] = i2c_addr;
- addr[1] = reg;
-
- i2c_read (addr, 2, buf, 1);
-
- return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
- char addr[2];
-
- i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
-
- addr[0] = i2c_addr;
- addr[1] = reg;
-
- i2c_write (addr, 2, &val, 1);
-}
-
-#endif /* CONFIG_SOFT_I2C */
-/*-----------------------------------------------------------------------
- */
#include <commproc.h>
#include <linux/ctype.h>
#include <malloc.h>
+#include <post.h>
+#include <net.h>
-#ifdef CONFIG_SPI
+#if (defined(CONFIG_SPI)) || (CONFIG_POST & CFG_POST_SPI)
/* Warning:
* You cannot enable DEBUG for early system initalization, i. e. when
volatile cpm8xx_t *cp;
volatile spi_t *spi;
cbd_t *tbdf, *rbdf;
+ ushort loop;
int tm;
DPRINT (("*** spi_xfer entered ***\n"));
rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
rbdf->cbd_datlen = 0; /* rx length has no significance */
+ loop = cp->cp_spmode & SPMODE_LOOP;
cp->cp_spmode = /*SPMODE_DIV16 |*/ /* BRG/16 mode not used here */
+ loop |
SPMODE_REV |
SPMODE_MSTR |
SPMODE_EN |
return count;
}
+#endif /* CONFIG_SPI || (CONFIG_POST & CFG_POST_SPI) */
-#endif /* CONFIG_SPI */
+/*
+ * SPI test
+ *
+ * The Serial Peripheral Interface (SPI) is tested in the local loopback mode.
+ * The interface is configured accordingly and several packets
+ * are transfered. The configurable test parameters are:
+ * TEST_MIN_LENGTH - minimum size of packet to transfer
+ * TEST_MAX_LENGTH - maximum size of packet to transfer
+ * TEST_NUM - number of tests
+ */
+
+#if CONFIG_POST & CFG_POST_SPI
+
+#define TEST_MIN_LENGTH 1
+#define TEST_MAX_LENGTH MAX_BUFFER
+#define TEST_NUM 1
+
+static void packet_fill (char * packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ packet[i] = c++;
+ }
+}
+
+static int packet_check (char * packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ if (packet[i] != c++) return -1;
+ }
+
+ return 0;
+}
+
+int spi_post_test (int flags)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int res = -1;
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = (cpm8xx_t *) &immr->im_cpm;
+ int i;
+ int l;
+
+ spi_init_f();
+ spi_init_r();
+
+ cp->cp_spmode |= SPMODE_LOOP;
+
+ for (i = 0; i < TEST_NUM; i++)
+ {
+ for (l = TEST_MIN_LENGTH; l <= TEST_MAX_LENGTH; l += 8)
+ {
+ packet_fill(txbuf, l);
+
+ spi_xfer(l);
+
+ if (packet_check(rxbuf, l) < 0)
+ {
+ goto Done;
+ }
+ }
+ }
+
+ res = 0;
+
+ Done:
+
+ cp->cp_spmode &= ~SPMODE_LOOP;
+
+ /*
+ * SCC2 Ethernet parameter RAM space overlaps
+ * the SPI parameter RAM space. So we need to restore
+ * the SCC2 configuration if it is used by UART or Ethernet.
+ */
+
+#if defined(CONFIG_8xx_CONS_SCC2)
+ serial_init();
+#endif
+#if defined(SCC_ENET) && (SCC_ENET == 1)
+ eth_init(gd->bd);
+#endif
+
+ if (res != 0)
+ {
+ post_log("SPI test failed\n");
+ }
+
+ return res;
+}
+#endif /* CONFIG_POST & CFG_POST_SPI */
--- /dev/null
+/*
+ * linux/include/asm-arm/arch-pxa/pxa-regs.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+// FIXME hack so that SA-1111.h will work [cb]
+
+#ifndef __ASSEMBLY__
+typedef unsigned short Word16 ;
+typedef unsigned int Word32 ;
+typedef Word32 Word ;
+typedef Word Quad [4] ;
+typedef void *Address ;
+typedef void (*ExcpHndlr) (void) ;
+#endif
+
+#ifndef __ASSEMBLY__
+#define io_p2v(PhAdd) (PhAdd)
+#define __REG(x) (*((volatile u32 *)io_p2v(x)))
+#else
+#define __REG(x) (x)
+#endif
+
+/*
+ * PXA Chip selects
+ */
+
+#define PXA_CS0_PHYS 0x00000000
+#define PXA_CS1_PHYS 0x04000000
+#define PXA_CS2_PHYS 0x08000000
+#define PXA_CS3_PHYS 0x0C000000
+#define PXA_CS4_PHYS 0x10000000
+#define PXA_CS5_PHYS 0x14000000
+
+
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) sockets
+ */
+
+#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
+
+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
+
+#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
+#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
+#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
+#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
+
+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ (0x20000000 + (Nb)*PCMCIASp)
+#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */
+#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
+ (_PCMCIA (Nb) + 2*PCMCIAPrtSp)
+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
+ (_PCMCIA (Nb) + 3*PCMCIAPrtSp)
+
+#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */
+#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */
+#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */
+#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */
+
+#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */
+#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */
+#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */
+#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */
+
+
+
+/*
+ * DMA Controller
+ */
+
+#define DCSR0 __REG(0x40000000) /* DMA Control / Status Register for Channel 0 */
+#define DCSR1 __REG(0x40000004) /* DMA Control / Status Register for Channel 1 */
+#define DCSR2 __REG(0x40000008) /* DMA Control / Status Register for Channel 2 */
+#define DCSR3 __REG(0x4000000c) /* DMA Control / Status Register for Channel 3 */
+#define DCSR4 __REG(0x40000010) /* DMA Control / Status Register for Channel 4 */
+#define DCSR5 __REG(0x40000014) /* DMA Control / Status Register for Channel 5 */
+#define DCSR6 __REG(0x40000018) /* DMA Control / Status Register for Channel 6 */
+#define DCSR7 __REG(0x4000001c) /* DMA Control / Status Register for Channel 7 */
+#define DCSR8 __REG(0x40000020) /* DMA Control / Status Register for Channel 8 */
+#define DCSR9 __REG(0x40000024) /* DMA Control / Status Register for Channel 9 */
+#define DCSR10 __REG(0x40000028) /* DMA Control / Status Register for Channel 10 */
+#define DCSR11 __REG(0x4000002c) /* DMA Control / Status Register for Channel 11 */
+#define DCSR12 __REG(0x40000030) /* DMA Control / Status Register for Channel 12 */
+#define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */
+#define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */
+#define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */
+
+#define DCSR(x) __REG2(0x40000000, (x) << 2)
+
+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
+
+#define DINT __REG(0x400000f0) /* DMA Interrupt Register */
+
+#define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */
+#define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */
+#define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */
+#define DRCMR3 __REG(0x4000010c) /* Request to Channel Map Register for I2S transmit Request */
+#define DRCMR4 __REG(0x40000110) /* Request to Channel Map Register for BTUART receive Request */
+#define DRCMR5 __REG(0x40000114) /* Request to Channel Map Register for BTUART transmit Request. */
+#define DRCMR6 __REG(0x40000118) /* Request to Channel Map Register for FFUART receive Request */
+#define DRCMR7 __REG(0x4000011c) /* Request to Channel Map Register for FFUART transmit Request */
+#define DRCMR8 __REG(0x40000120) /* Request to Channel Map Register for AC97 microphone Request */
+#define DRCMR9 __REG(0x40000124) /* Request to Channel Map Register for AC97 modem receive Request */
+#define DRCMR10 __REG(0x40000128) /* Request to Channel Map Register for AC97 modem transmit Request */
+#define DRCMR11 __REG(0x4000012c) /* Request to Channel Map Register for AC97 audio receive Request */
+#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
+#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
+#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
+#define DRCMR15 __REG(0x4000013c) /* Reserved */
+#define DRCMR16 __REG(0x40000140) /* Reserved */
+#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
+#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
+#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
+#define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */
+#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */
+#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */
+#define DRCMR23 __REG(0x4000015c) /* Reserved */
+#define DRCMR24 __REG(0x40000160) /* Reserved */
+#define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */
+#define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */
+#define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */
+#define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */
+#define DRCMR29 __REG(0x40000174) /* Reserved */
+#define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */
+#define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */
+#define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */
+#define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */
+#define DRCMR34 __REG(0x40000188) /* Reserved */
+#define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */
+#define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */
+#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
+#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */
+#define DRCMR39 __REG(0x4000019C) /* Reserved */
+
+#define DRCMRRXSADR DRCMR2
+#define DRCMRTXSADR DRCMR3
+#define DRCMRRXBTRBR DRCMR4
+#define DRCMRTXBTTHR DRCMR5
+#define DRCMRRXFFRBR DRCMR6
+#define DRCMRTXFFTHR DRCMR7
+#define DRCMRRXMCDR DRCMR8
+#define DRCMRRXMODR DRCMR9
+#define DRCMRTXMODR DRCMR10
+#define DRCMRRXPCDR DRCMR11
+#define DRCMRTXPCDR DRCMR12
+#define DRCMRRXSSDR DRCMR13
+#define DRCMRTXSSDR DRCMR14
+#define DRCMRRXICDR DRCMR17
+#define DRCMRTXICDR DRCMR18
+#define DRCMRRXSTRBR DRCMR19
+#define DRCMRTXSTTHR DRCMR20
+#define DRCMRRXMMC DRCMR21
+#define DRCMRTXMMC DRCMR22
+
+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
+#define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */
+
+#define DDADR0 __REG(0x40000200) /* DMA Descriptor Address Register Channel 0 */
+#define DSADR0 __REG(0x40000204) /* DMA Source Address Register Channel 0 */
+#define DTADR0 __REG(0x40000208) /* DMA Target Address Register Channel 0 */
+#define DCMD0 __REG(0x4000020c) /* DMA Command Address Register Channel 0 */
+#define DDADR1 __REG(0x40000210) /* DMA Descriptor Address Register Channel 1 */
+#define DSADR1 __REG(0x40000214) /* DMA Source Address Register Channel 1 */
+#define DTADR1 __REG(0x40000218) /* DMA Target Address Register Channel 1 */
+#define DCMD1 __REG(0x4000021c) /* DMA Command Address Register Channel 1 */
+#define DDADR2 __REG(0x40000220) /* DMA Descriptor Address Register Channel 2 */
+#define DSADR2 __REG(0x40000224) /* DMA Source Address Register Channel 2 */
+#define DTADR2 __REG(0x40000228) /* DMA Target Address Register Channel 2 */
+#define DCMD2 __REG(0x4000022c) /* DMA Command Address Register Channel 2 */
+#define DDADR3 __REG(0x40000230) /* DMA Descriptor Address Register Channel 3 */
+#define DSADR3 __REG(0x40000234) /* DMA Source Address Register Channel 3 */
+#define DTADR3 __REG(0x40000238) /* DMA Target Address Register Channel 3 */
+#define DCMD3 __REG(0x4000023c) /* DMA Command Address Register Channel 3 */
+#define DDADR4 __REG(0x40000240) /* DMA Descriptor Address Register Channel 4 */
+#define DSADR4 __REG(0x40000244) /* DMA Source Address Register Channel 4 */
+#define DTADR4 __REG(0x40000248) /* DMA Target Address Register Channel 4 */
+#define DCMD4 __REG(0x4000024c) /* DMA Command Address Register Channel 4 */
+#define DDADR5 __REG(0x40000250) /* DMA Descriptor Address Register Channel 5 */
+#define DSADR5 __REG(0x40000254) /* DMA Source Address Register Channel 5 */
+#define DTADR5 __REG(0x40000258) /* DMA Target Address Register Channel 5 */
+#define DCMD5 __REG(0x4000025c) /* DMA Command Address Register Channel 5 */
+#define DDADR6 __REG(0x40000260) /* DMA Descriptor Address Register Channel 6 */
+#define DSADR6 __REG(0x40000264) /* DMA Source Address Register Channel 6 */
+#define DTADR6 __REG(0x40000268) /* DMA Target Address Register Channel 6 */
+#define DCMD6 __REG(0x4000026c) /* DMA Command Address Register Channel 6 */
+#define DDADR7 __REG(0x40000270) /* DMA Descriptor Address Register Channel 7 */
+#define DSADR7 __REG(0x40000274) /* DMA Source Address Register Channel 7 */
+#define DTADR7 __REG(0x40000278) /* DMA Target Address Register Channel 7 */
+#define DCMD7 __REG(0x4000027c) /* DMA Command Address Register Channel 7 */
+#define DDADR8 __REG(0x40000280) /* DMA Descriptor Address Register Channel 8 */
+#define DSADR8 __REG(0x40000284) /* DMA Source Address Register Channel 8 */
+#define DTADR8 __REG(0x40000288) /* DMA Target Address Register Channel 8 */
+#define DCMD8 __REG(0x4000028c) /* DMA Command Address Register Channel 8 */
+#define DDADR9 __REG(0x40000290) /* DMA Descriptor Address Register Channel 9 */
+#define DSADR9 __REG(0x40000294) /* DMA Source Address Register Channel 9 */
+#define DTADR9 __REG(0x40000298) /* DMA Target Address Register Channel 9 */
+#define DCMD9 __REG(0x4000029c) /* DMA Command Address Register Channel 9 */
+#define DDADR10 __REG(0x400002a0) /* DMA Descriptor Address Register Channel 10 */
+#define DSADR10 __REG(0x400002a4) /* DMA Source Address Register Channel 10 */
+#define DTADR10 __REG(0x400002a8) /* DMA Target Address Register Channel 10 */
+#define DCMD10 __REG(0x400002ac) /* DMA Command Address Register Channel 10 */
+#define DDADR11 __REG(0x400002b0) /* DMA Descriptor Address Register Channel 11 */
+#define DSADR11 __REG(0x400002b4) /* DMA Source Address Register Channel 11 */
+#define DTADR11 __REG(0x400002b8) /* DMA Target Address Register Channel 11 */
+#define DCMD11 __REG(0x400002bc) /* DMA Command Address Register Channel 11 */
+#define DDADR12 __REG(0x400002c0) /* DMA Descriptor Address Register Channel 12 */
+#define DSADR12 __REG(0x400002c4) /* DMA Source Address Register Channel 12 */
+#define DTADR12 __REG(0x400002c8) /* DMA Target Address Register Channel 12 */
+#define DCMD12 __REG(0x400002cc) /* DMA Command Address Register Channel 12 */
+#define DDADR13 __REG(0x400002d0) /* DMA Descriptor Address Register Channel 13 */
+#define DSADR13 __REG(0x400002d4) /* DMA Source Address Register Channel 13 */
+#define DTADR13 __REG(0x400002d8) /* DMA Target Address Register Channel 13 */
+#define DCMD13 __REG(0x400002dc) /* DMA Command Address Register Channel 13 */
+#define DDADR14 __REG(0x400002e0) /* DMA Descriptor Address Register Channel 14 */
+#define DSADR14 __REG(0x400002e4) /* DMA Source Address Register Channel 14 */
+#define DTADR14 __REG(0x400002e8) /* DMA Target Address Register Channel 14 */
+#define DCMD14 __REG(0x400002ec) /* DMA Command Address Register Channel 14 */
+#define DDADR15 __REG(0x400002f0) /* DMA Descriptor Address Register Channel 15 */
+#define DSADR15 __REG(0x400002f4) /* DMA Source Address Register Channel 15 */
+#define DTADR15 __REG(0x400002f8) /* DMA Target Address Register Channel 15 */
+#define DCMD15 __REG(0x400002fc) /* DMA Command Address Register Channel 15 */
+
+#define DDADR(x) __REG2(0x40000200, (x) << 4)
+#define DSADR(x) __REG2(0x40000204, (x) << 4)
+#define DTADR(x) __REG2(0x40000208, (x) << 4)
+#define DCMD(x) __REG2(0x4000020c, (x) << 4)
+
+#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
+#define DDADR_STOP (1 << 0) /* Stop (read / write) */
+
+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
+
+/* default combinations */
+#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
+#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
+#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4)
+
+
+/*
+ * UARTs
+ */
+
+/* Full Function UART (FFUART) */
+#define FFUART FFRBR
+#define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */
+#define FFTHR __REG(0x40100000) /* Transmit Holding Register (write only) */
+#define FFIER __REG(0x40100004) /* Interrupt Enable Register (read/write) */
+#define FFIIR __REG(0x40100008) /* Interrupt ID Register (read only) */
+#define FFFCR __REG(0x40100008) /* FIFO Control Register (write only) */
+#define FFLCR __REG(0x4010000C) /* Line Control Register (read/write) */
+#define FFMCR __REG(0x40100010) /* Modem Control Register (read/write) */
+#define FFLSR __REG(0x40100014) /* Line Status Register (read only) */
+#define FFMSR __REG(0x40100018) /* Modem Status Register (read only) */
+#define FFSPR __REG(0x4010001C) /* Scratch Pad Register (read/write) */
+#define FFISR __REG(0x40100020) /* Infrared Selection Register (read/write) */
+#define FFDLL __REG(0x40100000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define FFDLH __REG(0x40100004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+/* Bluetooth UART (BTUART) */
+#define BTUART BTRBR
+#define BTRBR __REG(0x40200000) /* Receive Buffer Register (read only) */
+#define BTTHR __REG(0x40200000) /* Transmit Holding Register (write only) */
+#define BTIER __REG(0x40200004) /* Interrupt Enable Register (read/write) */
+#define BTIIR __REG(0x40200008) /* Interrupt ID Register (read only) */
+#define BTFCR __REG(0x40200008) /* FIFO Control Register (write only) */
+#define BTLCR __REG(0x4020000C) /* Line Control Register (read/write) */
+#define BTMCR __REG(0x40200010) /* Modem Control Register (read/write) */
+#define BTLSR __REG(0x40200014) /* Line Status Register (read only) */
+#define BTMSR __REG(0x40200018) /* Modem Status Register (read only) */
+#define BTSPR __REG(0x4020001C) /* Scratch Pad Register (read/write) */
+#define BTISR __REG(0x40200020) /* Infrared Selection Register (read/write) */
+#define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+/* Standard UART (STUART) */
+#define STUART STRBR
+#define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */
+#define STTHR __REG(0x40700000) /* Transmit Holding Register (write only) */
+#define STIER __REG(0x40700004) /* Interrupt Enable Register (read/write) */
+#define STIIR __REG(0x40700008) /* Interrupt ID Register (read only) */
+#define STFCR __REG(0x40700008) /* FIFO Control Register (write only) */
+#define STLCR __REG(0x4070000C) /* Line Control Register (read/write) */
+#define STMCR __REG(0x40700010) /* Modem Control Register (read/write) */
+#define STLSR __REG(0x40700014) /* Line Status Register (read only) */
+#define STMSR __REG(0x40700018) /* Reserved */
+#define STSPR __REG(0x4070001C) /* Scratch Pad Register (read/write) */
+#define STISR __REG(0x40700020) /* Infrared Selection Register (read/write) */
+#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+#define IER_DMAE (1 << 7) /* DMA Requests Enable */
+#define IER_UUE (1 << 6) /* UART Unit Enable */
+#define IER_NRZE (1 << 5) /* NRZ coding Enable */
+#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */
+#define IER_MIE (1 << 3) /* Modem Interrupt Enable */
+#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */
+#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */
+#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */
+
+#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */
+#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */
+#define IIR_TOD (1 << 3) /* Time Out Detected */
+#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */
+#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */
+#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */
+
+#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */
+#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */
+#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */
+#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */
+#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */
+#define FCR_ITL_1 (0)
+#define FCR_ITL_8 (FCR_ITL1)
+#define FCR_ITL_16 (FCR_ITL2)
+#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1)
+
+#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */
+#define LCR_SB (1 << 6) /* Set Break */
+#define LCR_STKYP (1 << 5) /* Sticky Parity */
+#define LCR_EPS (1 << 4) /* Even Parity Select */
+#define LCR_PEN (1 << 3) /* Parity Enable */
+#define LCR_STB (1 << 2) /* Stop Bit */
+#define LCR_WLS1 (1 << 1) /* Word Length Select */
+#define LCR_WLS0 (1 << 0) /* Word Length Select */
+
+#define LSR_FIFOE (1 << 7) /* FIFO Error Status */
+#define LSR_TEMT (1 << 6) /* Transmitter Empty */
+#define LSR_TDRQ (1 << 5) /* Transmit Data Request */
+#define LSR_BI (1 << 4) /* Break Interrupt */
+#define LSR_FE (1 << 3) /* Framing Error */
+#define LSR_PE (1 << 2) /* Parity Error */
+#define LSR_OE (1 << 1) /* Overrun Error */
+#define LSR_DR (1 << 0) /* Data Ready */
+
+#define MCR_LOOP (1 << 4) */
+#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
+#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
+#define MCR_RTS (1 << 1) /* Request to Send */
+#define MCR_DTR (1 << 0) /* Data Terminal Ready */
+
+#define MSR_DCD (1 << 7) /* Data Carrier Detect */
+#define MSR_RI (1 << 6) /* Ring Indicator */
+#define MSR_DSR (1 << 5) /* Data Set Ready */
+#define MSR_CTS (1 << 4) /* Clear To Send */
+#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */
+#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */
+#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */
+#define MSR_DCTS (1 << 0) /* Delta Clear To Send */
+
+/*
+ * IrSR (Infrared Selection Register)
+ */
+#define IrSR_OFFSET 0x20
+
+#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
+#define IrSR_RXPL_POS_IS_ZERO 0x0
+#define IrSR_TXPL_NEG_IS_ZERO (1<<3)
+#define IrSR_TXPL_POS_IS_ZERO 0x0
+#define IrSR_XMODE_PULSE_1_6 (1<<2)
+#define IrSR_XMODE_PULSE_3_16 0x0
+#define IrSR_RCVEIR_IR_MODE (1<<1)
+#define IrSR_RCVEIR_UART_MODE 0x0
+#define IrSR_XMITIR_IR_MODE (1<<0)
+#define IrSR_XMITIR_UART_MODE 0x0
+
+#define IrSR_IR_RECEIVE_ON (\
+ IrSR_RXPL_NEG_IS_ZERO | \
+ IrSR_TXPL_POS_IS_ZERO | \
+ IrSR_XMODE_PULSE_3_16 | \
+ IrSR_RCVEIR_IR_MODE | \
+ IrSR_XMITIR_UART_MODE)
+
+#define IrSR_IR_TRANSMIT_ON (\
+ IrSR_RXPL_NEG_IS_ZERO | \
+ IrSR_TXPL_POS_IS_ZERO | \
+ IrSR_XMODE_PULSE_3_16 | \
+ IrSR_RCVEIR_UART_MODE | \
+ IrSR_XMITIR_IR_MODE)
+
+
+/*
+ * I2C registers
+ */
+
+#define IBMR __REG(0x40301680) /* I2C Bus Monitor Register - IBMR */
+#define IDBR __REG(0x40301688) /* I2C Data Buffer Register - IDBR */
+#define ICR __REG(0x40301690) /* I2C Control Register - ICR */
+#define ISR __REG(0x40301698) /* I2C Status Register - ISR */
+#define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */
+
+
+/*
+ * Serial Audio Controller
+ */
+
+
+/* FIXME the audio defines collide w/ the SA1111 defines. I don't like these
+ * short defines because there is too much chance of namespace collision */
+
+//#define SACR0 __REG(0x40400000) /* Global Control Register */
+//#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
+//#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
+//#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */
+//#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */
+//#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
+//#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
+
+
+/*
+ * AC97 Controller registers
+ */
+
+#define POCR __REG(0x40500000) /* PCM Out Control Register */
+#define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
+
+#define PICR __REG(0x40500004) /* PCM In Control Register */
+#define PICR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
+
+#define MCCR __REG(0x40500008) /* Mic In Control Register */
+#define MCCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
+
+#define GCR __REG(0x4050000C) /* Global Control Register */
+#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */
+#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */
+#define GCR_SECRDY_IEN (1 << 9) /* Secondary Ready Interrupt Enable */
+#define GCR_PRIRDY_IEN (1 << 8) /* Primary Ready Interrupt Enable */
+#define GCR_SECRES_IEN (1 << 5) /* Secondary Resume Interrupt Enable */
+#define GCR_PRIRES_IEN (1 << 4) /* Primary Resume Interrupt Enable */
+#define GCR_ACLINK_OFF (1 << 3) /* AC-link Shut Off */
+#define GCR_WARM_RST (1 << 2) /* AC97 Warm Reset */
+#define GCR_COLD_RST (1 << 1) /* AC'97 Cold Reset (0 = active) */
+#define GCR_GIE (1 << 0) /* Codec GPI Interrupt Enable */
+
+#define POSR __REG(0x40500010) /* PCM Out Status Register */
+#define POSR_FIFOE (1 << 4) /* FIFO error */
+
+#define PISR __REG(0x40500014) /* PCM In Status Register */
+#define PISR_FIFOE (1 << 4) /* FIFO error */
+
+#define MCSR __REG(0x40500018) /* Mic In Status Register */
+#define MCSR_FIFOE (1 << 4) /* FIFO error */
+
+#define GSR __REG(0x4050001C) /* Global Status Register */
+#define GSR_CDONE (1 << 19) /* Command Done */
+#define GSR_SDONE (1 << 18) /* Status Done */
+#define GSR_RDCS (1 << 15) /* Read Completion Status */
+#define GSR_BIT3SLT12 (1 << 14) /* Bit 3 of slot 12 */
+#define GSR_BIT2SLT12 (1 << 13) /* Bit 2 of slot 12 */
+#define GSR_BIT1SLT12 (1 << 12) /* Bit 1 of slot 12 */
+#define GSR_SECRES (1 << 11) /* Secondary Resume Interrupt */
+#define GSR_PRIRES (1 << 10) /* Primary Resume Interrupt */
+#define GSR_SCR (1 << 9) /* Secondary Codec Ready */
+#define GSR_PCR (1 << 8) /* Primary Codec Ready */
+#define GSR_MINT (1 << 7) /* Mic In Interrupt */
+#define GSR_POINT (1 << 6) /* PCM Out Interrupt */
+#define GSR_PIINT (1 << 5) /* PCM In Interrupt */
+#define GSR_MOINT (1 << 2) /* Modem Out Interrupt */
+#define GSR_MIINT (1 << 1) /* Modem In Interrupt */
+#define GSR_GSCI (1 << 0) /* Codec GPI Status Change Interrupt */
+
+#define CAR __REG(0x40500020) /* CODEC Access Register */
+#define CAR_CAIP (1 << 0) /* Codec Access In Progress */
+
+#define PCDR __REG(0x40500040) /* PCM FIFO Data Register */
+#define MCDR __REG(0x40500060) /* Mic-in FIFO Data Register */
+
+#define MOCR __REG(0x40500100) /* Modem Out Control Register */
+#define MOCR_FEIE (1 << 3) /* FIFO Error */
+
+#define MICR __REG(0x40500108) /* Modem In Control Register */
+#define MICR_FEIE (1 << 3) /* FIFO Error */
+
+#define MOSR __REG(0x40500110) /* Modem Out Status Register */
+#define MOSR_FIFOE (1 << 4) /* FIFO error */
+
+#define MISR __REG(0x40500118) /* Modem In Status Register */
+#define MISR_FIFOE (1 << 4) /* FIFO error */
+
+#define MODR __REG(0x40500140) /* Modem FIFO Data Register */
+
+#define PAC_REG_BASE __REG(0x40500200) /* Primary Audio Codec */
+#define SAC_REG_BASE __REG(0x40500300) /* Secondary Audio Codec */
+#define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */
+#define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */
+
+
+/*
+ * USB Device Controller
+ */
+
+#define UDCCR __REG(0x40600000) /* UDC Control Register */
+#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */
+#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */
+#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */
+#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */
+#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */
+#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */
+#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */
+#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */
+#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */
+#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */
+#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */
+#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */
+#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */
+#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */
+#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */
+#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */
+#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */
+#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */
+#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */
+#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */
+#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */
+#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */
+#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */
+#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */
+#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */
+#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */
+#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */
+#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */
+#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */
+#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */
+#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */
+#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */
+#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */
+#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */
+#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */
+#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */
+#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */
+#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */
+#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */
+#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */
+#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */
+#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */
+#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */
+#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */
+
+
+/*
+ * Fast Infrared Communication Port
+ */
+
+#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */
+#define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */
+#define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */
+#define ICDR __REG(0x4080000c) /* ICP Data Register */
+#define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */
+#define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */
+
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR __REG(0x40900000) /* RTC Count Register */
+#define RTAR __REG(0x40900004) /* RTC Alarm Register */
+#define RTSR __REG(0x40900008) /* RTC Status Register */
+#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */
+
+#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
+#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
+#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
+#define RTSR_AL (1 << 0) /* RTC alarm detected */
+
+
+/*
+ * OS Timer & Match Registers
+ */
+
+#define OSMR0 __REG(0x40A00000) /* */
+#define OSMR1 __REG(0x40A00004) /* */
+#define OSMR2 __REG(0x40A00008) /* */
+#define OSMR3 __REG(0x40A0000C) /* */
+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
+#define OSSR __REG(0x40A00014) /* OS Timer Status Register */
+#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */
+#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */
+
+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
+#define OSSR_M2 (1 << 2) /* Match status channel 2 */
+#define OSSR_M1 (1 << 1) /* Match status channel 1 */
+#define OSSR_M0 (1 << 0) /* Match status channel 0 */
+
+#define OWER_WME (1 << 0) /* Watchdog Match Enable */
+
+#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
+#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
+#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
+#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
+
+
+/*
+ * Pulse Width Modulator
+ */
+
+#define PWM_CTRL0 __REG(0x40B00000) /* PWM 0 Control Register */
+#define PWM_PWDUTY0 __REG(0x40B00004) /* PWM 0 Duty Cycle Register */
+#define PWM_PERVAL0 __REG(0x40B00008) /* PWM 0 Period Control Register */
+
+#define PWM_CTRL1 __REG(0x40C00000) /* PWM 1Control Register */
+#define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */
+#define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */
+
+
+/*
+ * Interrupt Controller
+ */
+
+#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */
+#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */
+#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */
+#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */
+#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
+#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
+
+
+/*
+ * General Purpose I/O
+ */
+
+#define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */
+#define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */
+#define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */
+
+#define GPDR0 __REG(0x40E0000C) /* GPIO Pin Direction Register GPIO<31:0> */
+#define GPDR1 __REG(0x40E00010) /* GPIO Pin Direction Register GPIO<63:32> */
+#define GPDR2 __REG(0x40E00014) /* GPIO Pin Direction Register GPIO<80:64> */
+
+#define GPSR0 __REG(0x40E00018) /* GPIO Pin Output Set Register GPIO<31:0> */
+#define GPSR1 __REG(0x40E0001C) /* GPIO Pin Output Set Register GPIO<63:32> */
+#define GPSR2 __REG(0x40E00020) /* GPIO Pin Output Set Register GPIO<80:64> */
+
+#define GPCR0 __REG(0x40E00024) /* GPIO Pin Output Clear Register GPIO<31:0> */
+#define GPCR1 __REG(0x40E00028) /* GPIO Pin Output Clear Register GPIO <63:32> */
+#define GPCR2 __REG(0x40E0002C) /* GPIO Pin Output Clear Register GPIO <80:64> */
+
+#define GRER0 __REG(0x40E00030) /* GPIO Rising-Edge Detect Register GPIO<31:0> */
+#define GRER1 __REG(0x40E00034) /* GPIO Rising-Edge Detect Register GPIO<63:32> */
+#define GRER2 __REG(0x40E00038) /* GPIO Rising-Edge Detect Register GPIO<80:64> */
+
+#define GFER0 __REG(0x40E0003C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */
+#define GFER1 __REG(0x40E00040) /* GPIO Falling-Edge Detect Register GPIO<63:32> */
+#define GFER2 __REG(0x40E00044) /* GPIO Falling-Edge Detect Register GPIO<80:64> */
+
+#define GEDR0 __REG(0x40E00048) /* GPIO Edge Detect Status Register GPIO<31:0> */
+#define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */
+#define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */
+
+#define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */
+#define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */
+#define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */
+#define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */
+#define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */
+#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO 80 */
+
+/* More handy macros. The argument is a literal GPIO number. */
+
+#define GPIO_bit(x) (1 << ((x) & 0x1f))
+#define GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3)
+#define GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3)
+#define GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3)
+#define GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3)
+#define GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3)
+#define GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3)
+#define GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3)
+#define GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2)
+
+/* GPIO alternate function assignments */
+
+#define GPIO1_RST 1 /* reset */
+#define GPIO6_MMCCLK 6 /* MMC Clock */
+#define GPIO8_48MHz 7 /* 48 MHz clock output */
+#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */
+#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */
+#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */
+#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */
+#define GPIO12_32KHz 12 /* 32 kHz out */
+#define GPIO13_MBGNT 13 /* memory controller grant */
+#define GPIO14_MBREQ 14 /* alternate bus master request */
+#define GPIO15_nCS_1 15 /* chip select 1 */
+#define GPIO16_PWM0 16 /* PWM0 output */
+#define GPIO17_PWM1 17 /* PWM1 output */
+#define GPIO18_RDY 18 /* Ext. Bus Ready */
+#define GPIO19_DREQ1 19 /* External DMA Request */
+#define GPIO20_DREQ0 20 /* External DMA Request */
+#define GPIO23_SCLK 23 /* SSP clock */
+#define GPIO24_SFRM 24 /* SSP Frame */
+#define GPIO25_STXD 25 /* SSP transmit */
+#define GPIO26_SRXD 26 /* SSP receive */
+#define GPIO27_SEXTCLK 27 /* SSP ext_clk */
+#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */
+#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */
+#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */
+#define GPIO31_SYNC 31 /* AC97/I2S sync */
+#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */
+#define GPIO33_nCS_5 33 /* chip select 5 */
+#define GPIO34_FFRXD 34 /* FFUART receive */
+#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */
+#define GPIO35_FFCTS 35 /* FFUART Clear to send */
+#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */
+#define GPIO37_FFDSR 37 /* FFUART data set ready */
+#define GPIO38_FFRI 38 /* FFUART Ring Indicator */
+#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */
+#define GPIO39_FFTXD 39 /* FFUART transmit data */
+#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */
+#define GPIO41_FFRTS 41 /* FFUART request to send */
+#define GPIO42_BTRXD 42 /* BTUART receive data */
+#define GPIO43_BTTXD 43 /* BTUART transmit data */
+#define GPIO44_BTCTS 44 /* BTUART clear to send */
+#define GPIO45_BTRTS 45 /* BTUART request to send */
+#define GPIO46_ICPRXD 46 /* ICP receive data */
+#define GPIO46_STRXD 46 /* STD_UART receive data */
+#define GPIO47_ICPTXD 47 /* ICP transmit data */
+#define GPIO47_STTXD 47 /* STD_UART transmit data */
+#define GPIO48_nPOE 48 /* Output Enable for Card Space */
+#define GPIO49_nPWE 49 /* Write Enable for Card Space */
+#define GPIO50_nPIOR 50 /* I/O Read for Card Space */
+#define GPIO51_nPIOW 51 /* I/O Write for Card Space */
+#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */
+#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */
+#define GPIO53_MMCCLK 53 /* MMC Clock */
+#define GPIO54_MMCCLK 54 /* MMC Clock */
+#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */
+#define GPIO55_nPREG 55 /* Card Address bit 26 */
+#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */
+#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */
+#define GPIO58_LDD_0 58 /* LCD data pin 0 */
+#define GPIO59_LDD_1 59 /* LCD data pin 1 */
+#define GPIO60_LDD_2 60 /* LCD data pin 2 */
+#define GPIO61_LDD_3 61 /* LCD data pin 3 */
+#define GPIO62_LDD_4 62 /* LCD data pin 4 */
+#define GPIO63_LDD_5 63 /* LCD data pin 5 */
+#define GPIO64_LDD_6 64 /* LCD data pin 6 */
+#define GPIO65_LDD_7 65 /* LCD data pin 7 */
+#define GPIO66_LDD_8 66 /* LCD data pin 8 */
+#define GPIO66_MBREQ 66 /* alternate bus master req */
+#define GPIO67_LDD_9 67 /* LCD data pin 9 */
+#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */
+#define GPIO68_LDD_10 68 /* LCD data pin 10 */
+#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */
+#define GPIO69_LDD_11 69 /* LCD data pin 11 */
+#define GPIO69_MMCCLK 69 /* MMC_CLK */
+#define GPIO70_LDD_12 70 /* LCD data pin 12 */
+#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */
+#define GPIO71_LDD_13 71 /* LCD data pin 13 */
+#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */
+#define GPIO72_LDD_14 72 /* LCD data pin 14 */
+#define GPIO72_32kHz 72 /* 32 kHz clock */
+#define GPIO73_LDD_15 73 /* LCD data pin 15 */
+#define GPIO73_MBGNT 73 /* Memory controller grant */
+#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */
+#define GPIO75_LCD_LCLK 75 /* LCD line clock */
+#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */
+#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */
+#define GPIO78_nCS_2 78 /* chip select 2 */
+#define GPIO79_nCS_3 79 /* chip select 3 */
+#define GPIO80_nCS_4 80 /* chip select 4 */
+
+/* GPIO alternate function mode & direction */
+
+#define GPIO_IN 0x000
+#define GPIO_OUT 0x080
+#define GPIO_ALT_FN_1_IN 0x100
+#define GPIO_ALT_FN_1_OUT 0x180
+#define GPIO_ALT_FN_2_IN 0x200
+#define GPIO_ALT_FN_2_OUT 0x280
+#define GPIO_ALT_FN_3_IN 0x300
+#define GPIO_ALT_FN_3_OUT 0x380
+#define GPIO_MD_MASK_NR 0x07f
+#define GPIO_MD_MASK_DIR 0x080
+#define GPIO_MD_MASK_FN 0x300
+
+#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN)
+#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT)
+#define GPIO8_48MHz_MD ( 8 | GPIO_ALT_FN_1_OUT)
+#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT)
+#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT)
+#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT)
+#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT)
+#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT)
+#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT)
+#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN)
+#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT)
+#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT)
+#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT)
+#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN)
+#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN)
+#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN)
+#define GPIO23_SCLK_md (23 | GPIO_ALT_FN_2_OUT)
+#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT)
+#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT)
+#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN)
+#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN)
+#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN)
+#define GPIO28_BITCLK_I2S_MD (28 | GPIO_ALT_FN_2_IN)
+#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN)
+#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN)
+#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT)
+#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT)
+#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT)
+#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT)
+#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN)
+#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT)
+#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN)
+#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT)
+#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN)
+#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN)
+#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN)
+#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN)
+#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT)
+#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT)
+#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT)
+#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT)
+#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN)
+#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT)
+#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN)
+#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT)
+#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN)
+#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN)
+#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT)
+#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT)
+#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT)
+#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT)
+#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT)
+#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT)
+#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT)
+#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT)
+#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT)
+#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT)
+#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT)
+#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT)
+#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN)
+#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN)
+#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT)
+#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT)
+#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT)
+#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT)
+#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT)
+#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT)
+#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT)
+#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT)
+#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT)
+#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN)
+#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT)
+#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT)
+#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT)
+#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT)
+#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT)
+#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT)
+#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT)
+#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT)
+#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT)
+#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT)
+#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT)
+#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT)
+#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT)
+#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT)
+#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT)
+#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT)
+#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT)
+#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT)
+#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT)
+#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT)
+#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT)
+
+
+/*
+ * Power Manager
+ */
+
+#define PMCR __REG(0x40F00000) /* Power Manager Control Register */
+#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */
+#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */
+#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */
+#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */
+#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */
+#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */
+#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */
+#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */
+#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */
+#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
+#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */
+
+
+/*
+ * SSP Serial Port Registers
+ */
+
+#define SSCR0 __REG(0x41000000) /* SSP Control Register 0 */
+#define SSCR1 __REG(0x41000004) /* SSP Control Register 1 */
+#define SSSR __REG(0x41000008) /* SSP Status Register */
+#define SSITR __REG(0x4100000C) /* SSP Interrupt Test Register */
+#define SSDR __REG(0x41000010) /* (Write / Read) SSP Data Write Register/SSP Data Read Register */
+
+
+/*
+ * MultiMediaCard (MMC) controller
+ */
+
+#define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */
+#define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */
+#define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */
+#define MMC_SPI __REG(0x4110000c) /* SPI mode control bits */
+#define MMC_CMDAT __REG(0x41100010) /* Command/response/data sequence control */
+#define MMC_RESTO __REG(0x41100014) /* Expected response time out */
+#define MMC_RDTO __REG(0x41100018) /* Expected data read time out */
+#define MMC_BLKLEN __REG(0x4110001c) /* Block length of data transaction */
+#define MMC_NOB __REG(0x41100020) /* Number of blocks, for block mode */
+#define MMC_PRTBUF __REG(0x41100024) /* Partial MMC_TXFIFO FIFO written */
+#define MMC_I_MASK __REG(0x41100028) /* Interrupt Mask */
+#define MMC_I_REG __REG(0x4110002c) /* Interrupt Register (read only) */
+#define MMC_CMD __REG(0x41100030) /* Index of current command */
+#define MMC_ARGH __REG(0x41100034) /* MSW part of the current command argument */
+#define MMC_ARGL __REG(0x41100038) /* LSW part of the current command argument */
+#define MMC_RES __REG(0x4110003c) /* Response FIFO (read only) */
+#define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */
+#define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */
+
+
+/*
+ * Core Clock
+ */
+
+#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */
+#define CKEN __REG(0x41300004) /* Clock Enable Register */
+#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */
+
+#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */
+#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */
+#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */
+
+#define CKEN16_LCD (1 << 16) /* LCD Unit Clock Enable */
+#define CKEN14_I2C (1 << 14) /* I2C Unit Clock Enable */
+#define CKEN13_FICP (1 << 13) /* FICP Unit Clock Enable */
+#define CKEN12_MMC (1 << 12) /* MMC Unit Clock Enable */
+#define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */
+#define CKEN8_I2S (1 << 8) /* I2S Unit Clock Enable */
+#define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
+#define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
+#define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
+#define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
+#define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */
+#define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */
+#define CKEN0_PWM0 (1 << 0) /* PWM0 Clock Enable */
+
+#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */
+#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */
+
+#define CCCR_L09 (0x1F)
+#define CCCR_L27 (0x1)
+#define CCCR_L32 (0x2)
+#define CCCR_L36 (0x3)
+#define CCCR_L40 (0x4)
+#define CCCR_L45 (0x5)
+
+#define CCCR_M1 (0x1 << 5)
+#define CCCR_M2 (0x2 << 5)
+#define CCCR_M4 (0x3 << 5)
+
+#define CCCR_N10 (0x2 << 7)
+#define CCCR_N15 (0x3 << 7)
+#define CCCR_N20 (0x4 << 7)
+#define CCCR_N25 (0x5 << 7)
+#define CCCR_N30 (0x6 << 7)
+
+/*
+ * LCD
+ */
+
+#define LCCR0 __REG(0x44000000) /* LCD Controller Control Register 0 */
+#define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */
+#define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */
+#define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */
+#define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */
+#define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */
+#define LCSR __REG(0x44000038) /* LCD Controller Status Register */
+#define LIIDR __REG(0x4400003C) /* LCD Controller Interrupt ID Register */
+#define TMEDRGBR __REG(0x44000040) /* TMED RGB Seed Register */
+#define TMEDCR __REG(0x44000044) /* TMED Control Register */
+
+#define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */
+#define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */
+#define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */
+#define LDCMD0 __REG(0x4400020C) /* DMA Channel 0 Command Register */
+#define FDADR1 __REG(0x44000210) /* DMA Channel 1 Frame Descriptor Address Register */
+#define FSADR1 __REG(0x44000214) /* DMA Channel 1 Frame Source Address Register */
+#define FIDR1 __REG(0x44000218) /* DMA Channel 1 Frame ID Register */
+#define LDCMD1 __REG(0x4400021C) /* DMA Channel 1 Command Register */
+
+#define LCCR0_ENB (1 << 0) /* LCD Controller enable */
+#define LCCR0_CMS (1 << 1) /* Color = 0, Monochrome = 1 */
+#define LCCR0_SDS (1 << 2) /* Single Panel = 0, Dual Panel = 1 */
+#define LCCR0_LDM (1 << 3) /* LCD Disable Done Mask */
+#define LCCR0_SFM (1 << 4) /* Start of frame mask */
+#define LCCR0_IUM (1 << 5) /* Input FIFO underrun mask */
+#define LCCR0_EFM (1 << 6) /* End of Frame mask */
+#define LCCR0_PAS (1 << 7) /* Passive = 0, Active = 1 */
+#define LCCR0_BLE (1 << 8) /* Little Endian = 0, Big Endian = 1 */
+#define LCCR0_DPD (1 << 9) /* Double Pixel mode, 4 pixel value = 0, 8 pixle values = 1 */
+#define LCCR0_DIS (1 << 10) /* LCD Disable */
+#define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */
+#define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */
+#define LCCR0_PDD_S 12
+#define LCCR0_BM (1 << 20) /* Branch mask */
+#define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */
+
+#define LCCR3_PCD (0xff) /* Pixel clock divisor */
+#define LCCR3_ACB (0xff << 8) /* AC Bias pin frequency */
+#define LCCR3_ACB_S 8
+#define LCCR3_API (0xf << 16) /* AC Bias pin trasitions per interrupt */
+#define LCCR3_API_S 16
+#define LCCR3_VSP (1 << 20) /* vertical sync polarity */
+#define LCCR3_HSP (1 << 21) /* horizontal sync polarity */
+#define LCCR3_PCP (1 << 22) /* pixel clock polarity */
+#define LCCR3_OEP (1 << 23) /* output enable polarity */
+#define LCCR3_BPP (7 << 24) /* bits per pixel */
+#define LCCR3_BPP_S 24
+#define LCCR3_DPC (1 << 27) /* double pixel clock mode */
+
+#define LCSR_LDD (1 << 0) /* LCD Disable Done */
+#define LCSR_SOF (1 << 1) /* Start of frame */
+#define LCSR_BER (1 << 2) /* Bus error */
+#define LCSR_ABC (1 << 3) /* AC Bias count */
+#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */
+#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */
+#define LCSR_OU (1 << 6) /* output FIFO underrun */
+#define LCSR_QD (1 << 7) /* quick disable */
+#define LCSR_EOF (1 << 8) /* end of frame */
+#define LCSR_BS (1 << 9) /* branch status */
+#define LCSR_SINT (1 << 10) /* subsequent interrupt */
+
+#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */
+
+/*
+ * Memory controller
+ */
+
+#define MEMC_BASE __REG(0x48000000) /* Base of Memoriy Controller */
+#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
+#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
+#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
+#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
+#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
+#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
+#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
+#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
+#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
+#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
+#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
+#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
+#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
+#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
+#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
+#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
+#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
+
+#define MDCNFG_DE0 0x00000001
+#define MDCNFG_DE1 0x00000002
+#define MDCNFG_DE2 0x00010000
+#define MDCNFG_DE3 0x00020000
+#define MDCNFG_DWID0 0x00000004
+#define MDREFR_E0PIN 0x00001000
+#define MDREFR_E1PIN 0x00008000
+
+#define MDCNFG_OFFSET 0x0
+#define MDREFR_OFFSET 0x4
+#define MSC0_OFFSET 0x8
+#define MSC1_OFFSET 0xC
+#define MSC2_OFFSET 0x10
+#define MECR_OFFSET 0x14
+#define SXLCR_OFFSET 0x18
+#define SXCNFG_OFFSET 0x1C
+#define FLYCNFG_OFFSET 0x20
+#define SXMRS_OFFSET 0x24
+#define MCMEM0_OFFSET 0x28
+#define MCMEM1_OFFSET 0x2C
+#define MCATT0_OFFSET 0x30
+#define MCATT1_OFFSET 0x34
+#define MCIO0_OFFSET 0x38
+#define MCIO1_OFFSET 0x3C
+#define MDMRS_OFFSET 0x40
+
+
+
+
#define CMD_TBL_BSP
#endif /* CFG_CMD_BSP */
+/* ----- R360MPI ---------------------------------------------------------------
+ */
+#if defined(CONFIG_R360MPI)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "kbd", 3, 1, 1, do_kbd, \
+ "kbd - read keyboard status\n", \
+ NULL \
+),
+
+int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_R360MPI */
+/* ----------------------------------------------------------------------------*/
+
#endif /* _CMD_BSP_H_ */
#define CFG_CMD_JFFS2 0x0000001000000000 /* JFFS2 Support */
#define CFG_CMD_DTT 0x0000002000000000 /* Digital Therm and Thermostat */
#define CFG_CMD_SDRAM 0x0000004000000000 /* SDRAM DIMM SPD info printout */
-#define CFG_CMD_FPGA 0x0000080000000000 /* FPGA configuration Support */
+#define CFG_CMD_DIAG 0x0000008000000000 /* Diagnostics */
+#define CFG_CMD_FPGA 0x0000010000000000 /* FPGA configuration Support */
#define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */
CFG_CMD_CACHE | \
CFG_CMD_DATE | \
CFG_CMD_DHCP | \
+ CFG_CMD_DIAG | \
CFG_CMD_DOC | \
CFG_CMD_DTT | \
CFG_CMD_ECHO | \
--- /dev/null
+/*
+ * (C) Copyright 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
+ */
+
+/*
+ * Diagnostics support
+ */
+#ifndef _CMD_DIAG_H
+#define _CMD_DIAG_H
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_DIAG) && defined(CONFIG_POST)
+#define CMD_TBL_DIAG MK_CMD_TBL_ENTRY( \
+ "diag", 4, CFG_MAXARGS, 0, do_diag, \
+ "diag - perform board diagnostics\n", \
+ " - print list of available tests\n" \
+ "diag [test1 [test2]]\n" \
+ " - print information about specified tests\n" \
+ "diag run - run all available tests\n" \
+ "diag run [test1 [test2]]\n" \
+ " - run specified tests\n" \
+),
+
+int do_diag (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#else
+#define CMD_TBL_DIAG
+#endif /* CFG_CMD_DIAG */
+
+#endif /* _CMD_DIAG_H */
/* $(BOARD)/$(BOARD).c */
int board_pre_init (void);
int board_postclk_init (void); /* after clocks/timebase, before env/serial */
+void board_poweroff (void);
#if defined(CFG_DRAM_TEST)
int testdram(void);
uint dpram_base_align(uint align);
uint dpram_alloc(uint size);
uint dpram_alloc_align(uint size,uint align);
+void post_word_store (ulong);
+ulong post_word_load (void);
/* $(CPU)/.../lcd.c */
#ifdef CONFIG_LCD
#define CPM_FEC_BASE 0x0860
#define CPM_WLKBD_BASE 0x0880
#define CPM_SCC_BASE 0x0900
+#define CPM_POST_BASE 0x0980
#endif
+#define CPM_POST_WORD_ADDR 0x07FC
+
#define BD_IIC_START ((uint) 0x0400) // <- please use CPM_I2C_BASE !!
/* Export the base address of the communication processor registers
# define CFG_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */
/* mask of address bits that overflow into the "EEPROM chip address" */
#define CFG_I2C_EEPROM_ADDR_OVERFLOW 0x07
+#define CFG_EEPROM_PAGE_WRITE_BITS 4
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* takes up to 10 msec */
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
CFG_CMD_BEDBUG | \
#define CONFIG_MPC823 1 /* This is a MPC823 CPU */
#define CONFIG_R360MPI 1
+#if 0 /* for now */
#define CONFIG_LCD
#define CONFIG_EDT32F10
+#endif /* 0 */
#define MPC8XX_FACT 1 /* Multiply by 1 */
#define MPC8XX_XIN 50000000 /* 50 MHz in */
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#undef CFG_LOADS_BAUD_CHANGE /* don't allow baudrate change */
+#define CONFIG_MISC_INIT_R /* have misc_init_r() function */
+
#undef CONFIG_WATCHDOG /* watchdog disabled */
#if 0
#define CONFIG_BOOTP_MASK (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
+#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+
#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
-#define CONFIG_SOFT_I2C 1 /* To I2C with hardware support */
-#define CFG_I2C_SPEED 500000 /* I2C speed and slave address */
+#define CONFIG_HARD_I2C 1 /* To I2C with hardware support */
+#undef CONFIG_SORT_I2C /* To I2C with software support */
+#define CFG_I2C_SPEED 4700 /* I2C speed and slave address */
#define CFG_I2C_SLAVE 0x7F
/*
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
CFG_CMD_DHCP | \
CFG_CMD_DATE | \
- CFG_CMD_I2C )
+ CFG_CMD_I2C | \
+ CFG_CMD_IDE | \
+ CFG_CMD_PCMCIA | \
+ CFG_CMD_BSP )
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
* FLASH organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
-#define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */
+#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
#undef CONFIG_BOOTARGS
+/* POST support */
+#define CONFIG_POST (CFG_POST_CACHE | \
+ CFG_POST_WATCHDOG | \
+ CFG_POST_I2C | \
+ CFG_POST_RTC | \
+ CFG_POST_MEMORY | \
+ CFG_POST_CPU | \
+ CFG_POST_UART | \
+ CFG_POST_ETHER | \
+ CFG_POST_SPI | \
+ CFG_POST_USB | \
+ CFG_POST_SPR)
+
/*
* HACK: insert some more variable definitions ;-)
*/
"bootm $(kernel_addr) $(ramdisk_addr)\0" \
"net_nfs=tftp 100000 /tftpboot/pImage.lwmon;run nfsargs;run addip;" \
"run add_wdt;run addfb;bootm\0" \
- "rootpath=/opt/hardhat/devkit/ppc/8xx/target\0" \
+ "rootpath=/opt/eldk/ppc_8xx\0" \
"load=tftp 100000 /tftpboot/ppcboot.bin\0" \
"update=protect off 1:0;era 1:0;cp.b 100000 40000000 $(filesize)\0" \
"wdt_args=wdt_8xx=off"
#undef CONFIG_STATUS_LED /* Status LED disabled */
/* enable I2C and select the hardware/software driver */
-#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-# define CFG_I2C_SPEED 50000
+#define CONFIG_HARD_I2C 1 /* I2C with hardware support */
+#undef CONFIG_SOFT_I2C /* I2C bit-banged */
+
+#ifdef CONFIG_HARD_I2C
+/*
+ * Hardware (CPM) I2C driver configuration
+ */
+# define CFG_I2C_SPEED 80000 /* 85 kHz is too fast already */
# define CFG_I2C_SLAVE 0xFE
+#endif /* CONFIG_HARD_I2C */
+
+#ifdef CONFIG_SOFT_I2C
/*
* Software (bit-bang) I2C driver configuration
*/
else immr->im_cpm.cp_pbdat &= ~PB_SDA
#define I2C_SCL(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SCL; \
else immr->im_cpm.cp_pbdat &= ~PB_SCL
-#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
+#define I2C_DELAY udelay(1) /* 1/4 I2C clock duration */
+#endif /* CONFIG_SOFT_I2C */
#define CONFIG_RTC_PCF8563 /* use Philips PCF8563 RTC */
+#ifdef CONFIG_POST
+#define CFG_CMD_POST_DIAG CFG_CMD_DIAG
+#else
+#define CFG_CMD_POST_DIAG 0
+#endif
+
#ifdef CONFIG_8xx_CONS_SCC2 /* Can't use ethernet, then */
#define CONFIG_COMMANDS ( (CONFIG_CMD_DFL & ~CFG_CMD_NET) | \
CFG_CMD_DATE | \
CFG_CMD_I2C | \
CFG_CMD_EEPROM | \
CFG_CMD_IDE | \
- CFG_CMD_BSP )
+ CFG_CMD_BSP | \
+ CFG_CMD_POST_DIAG )
#else
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
CFG_CMD_DHCP | \
CFG_CMD_I2C | \
CFG_CMD_EEPROM | \
CFG_CMD_IDE | \
- CFG_CMD_BSP )
+ CFG_CMD_BSP | \
+ CFG_CMD_POST_DIAG )
#endif
#define CONFIG_MAC_PARTITION
#define CONFIG_DOS_PARTITION
/*-----------------------------------------------------------------------
* I2C/EEPROM Configuration
*/
-#define CFG_I2C_CLOCK 33000 /* I²C Clock Rate in kHz */
#define CFG_I2C_AUDIO_ADDR 0x28 /* Audio volume control */
#define CFG_I2C_SYSMON_ADDR 0x2E /* LM87 System Monitor */
#define CFG_I2C_KEYBD_ADDR 0x56 /* PIC LWE keyboard */
#define CFG_I2C_PICIO_ADDR 0x57 /* PIC IO Expander */
#define CFG_I2C_EEPROM_ADDR 0x58 /* EEPROM AT24C164 */
+
+#define CONFIG_USE_FRAM /* Use FRAM instead of EEPROM */
+#ifdef CONFIG_USE_FRAM /* use FRAM */
+#define CFG_I2C_EEPROM_ADDR_LEN 2
+#else /* use EEPROM */
#define CFG_I2C_EEPROM_ADDR_LEN 1
-#define CFG_EEPROM_PAGE_WRITE_BITS 4
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 10 /* and takes up to 10 msec */
+#endif /* CONFIG_USE_FRAM */
+#define CFG_EEPROM_PAGE_WRITE_BITS 4
/*-----------------------------------------------------------------------
* Cache Configuration
#define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */
#define CFG_ENV_IS_IN_FLASH 1
-#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x1C0000) /* Addr of Environment Sector */
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x00040000) /* Addr of Environment Sector */
#define CFG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
#endif /* __CONFIG_H */
sync " \
: /* no output */ \
: "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
- "r" (CONFIG_DATA), "r" (data), \
+ "b" (CONFIG_DATA), "r" (data), \
"n" ((addr) & 3));
#define CONFIG_WRITE_HALFWORD( addr, data ) \
: /* no output */ \
: "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
"r" (CONFIG_DATA), "r" (data), \
- "r" ((addr) & 3));
+ "b" ((addr) & 3));
/* this assumes it's writeing on word boundaries*/
#define CONFIG_WRITE_WORD( addr, data ) \
sync " \
: "=r" (reg) \
: "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
- "r" (CONFIG_DATA), "n" ((addr) & 3));
+ "b" (CONFIG_DATA), "n" ((addr) & 3));
#define CONFIG_READ_HALFWORD( addr, reg ) \
: "=r" (reg) \
: "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
"r" (CONFIG_DATA), \
- "r" ((addr) & 3));
+ "b" ((addr) & 3));
/* this assumes it's reading on word boundaries*/
#define CONFIG_READ_WORD( addr, reg ) \
--- /dev/null
+/*
+ * (C) Copyright 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
+ */
+#ifndef _POST_H
+#define _POST_H
+
+#ifndef __ASSEMBLY__
+#include <common.h>
+#endif
+
+#ifdef CONFIG_POST
+
+#define POST_POWERON 0x01 /* test runs on power-on booting */
+#define POST_POWERNORMAL 0x02 /* test runs on normal booting */
+#define POST_POWERFAIL 0x04 /* test runs on power-fail booting */
+#define POST_POWERTEST 0x08 /* test runs after watchdog reset */
+
+#define POST_ROM 0x0100 /* test runs in ROM */
+#define POST_RAM 0x0200 /* test runs in RAM */
+#define POST_MANUAL 0x0400 /* test runs on diag command */
+#define POST_REBOOT 0x0800 /* test may cause rebooting */
+
+#define POST_MEM (POST_RAM | POST_ROM)
+#define POST_ALWAYS (POST_POWERNORMAL | \
+ POST_POWERFAIL | \
+ POST_MANUAL | \
+ POST_POWERON )
+
+#ifndef __ASSEMBLY__
+
+struct post_test {
+ char *name;
+ char *cmd;
+ char *desc;
+ int flags;
+ int (*test) (int flags);
+};
+void post_bootmode_init (void);
+int post_bootmode_get (unsigned int * last_test);
+void post_bootmode_clear (void);
+int post_run (char *name, int flags);
+int post_info (char *name);
+int post_log (char *format, ...);
+void post_reloc (void);
+
+extern struct post_test post_list[];
+extern unsigned int post_list_size;
+
+#endif /* __ASSEMBLY__ */
+
+#define CFG_POST_RTC 0x00000001
+#define CFG_POST_WATCHDOG 0x00000002
+#define CFG_POST_MEMORY 0x00000004
+#define CFG_POST_CPU 0x00000008
+#define CFG_POST_I2C 0x00000010
+#define CFG_POST_CACHE 0x00000020
+#define CFG_POST_UART 0x00000040
+#define CFG_POST_ETHER 0x00000080
+#define CFG_POST_SPI 0x00000100
+#define CFG_POST_USB 0x00000200
+#define CFG_POST_SPR 0x00000400
+
+#endif /* CONFIG_POST */
+
+#endif /* _POST_H */
extern image_header_t header; /* from cmd_bootm.c */
-void boot_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
ulong addr, ulong *len_ptr, int verify)
{
DECLARE_GLOBAL_DATA_PTR;
#include <command.h>
#include <devices.h>
#include <version.h>
+#include <net.h>
+
const char version_string[] =
PPCBOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
/* initialize environment */
env_relocate ();
+ /* IP Address */
+ bd_data.bi_ip_addr = getenv_IPaddr ("ipaddr");
+
+ /* MAC Address */
+ {
+ int i;
+ ulong reg;
+ char *s, *e;
+ uchar tmp[64];
+
+ i = getenv_r ("ethaddr", tmp, sizeof (tmp));
+ s = (i > 0) ? tmp : NULL;
+
+ for (reg = 0; reg < 6; ++reg) {
+ bd_data.bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+ }
+
/* enable exceptions */
enable_interrupts ();
#include <w83c553f.h>
#endif
#include <dtt.h>
+#if defined(CONFIG_POST)
+#include <post.h>
+#endif
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
void doc_init (void);
WATCHDOG_RESET ();
+#ifdef CONFIG_POST
+ post_bootmode_init();
+ post_run (NULL, POST_ROM | post_bootmode_get(0));
+#endif
+
+ WATCHDOG_RESET();
+
memcpy (id, gd, sizeof (gd_t));
relocate_code (addr_sp, id, addr);
WATCHDOG_RESET ();
+#ifdef CONFIG_POST
+ post_reloc ();
+#endif
+
+ WATCHDOG_RESET();
+
#if defined(CONFIG_IP860) || defined(CONFIG_PCU_E) || defined (CONFIG_FLAGADM)
icache_enable (); /* it's time to enable the instruction cache */
#endif
}
putc ('\n');
#else
- print_size (flash_size, "");
+ print_size (flash_size, "\n");
#endif /* CFG_FLASH_CHECKSUM */
} else {
puts (failed);
}
#endif
+#ifdef CONFIG_POST
+ post_run (NULL, POST_RAM | post_bootmode_get(0));
+ if (post_bootmode_get(0) & POST_POWERFAIL) {
+ post_bootmode_clear();
+ board_poweroff();
+ }
+#endif
+
/* Initialization complete - start the monitor */
/* main_loop() can return to retry autoboot, if so just run it again. */
--- /dev/null
+#
+# (C) Copyright 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
+#
+
+
+SUBDIRS = cpu
+
+LIB = libpost.a
+
+AOBJS = cache_8xx.o
+COBJS = post.o tests.o cpu.o rtc.o watchdog.o memory.o i2c.o cache.o
+COBJS += uart.o ether.o usb.o spr.o
+
+include $(TOPDIR)/post/rules.mk
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/* Cache test
+ *
+ * This test verifies the CPU data and instruction cache using
+ * several test scenarios.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_CACHE
+
+#define CACHE_POST_SIZE 1024
+
+extern int cache_post_test1 (char *, unsigned int);
+extern int cache_post_test2 (char *, unsigned int);
+extern int cache_post_test3 (char *, unsigned int);
+extern int cache_post_test4 (char *, unsigned int);
+extern int cache_post_test5 (void);
+extern int cache_post_test6 (void);
+
+int cache_post_test (bd_t * bd, int flags)
+{
+ int ints = disable_interrupts ();
+ int res = 0;
+ static char ta[CACHE_POST_SIZE + 0xf];
+ char *testarea = (char *) (((unsigned long) ta + 0xf) & ~0xf);
+
+ WATCHDOG_RESET ();
+ if (res == 0)
+ res = cache_post_test1 (testarea, CACHE_POST_SIZE);
+ WATCHDOG_RESET ();
+ if (res == 0)
+ res = cache_post_test2 (testarea, CACHE_POST_SIZE);
+ WATCHDOG_RESET ();
+ if (res == 0)
+ res = cache_post_test3 (testarea, CACHE_POST_SIZE);
+ WATCHDOG_RESET ();
+ if (res == 0)
+ res = cache_post_test4 (testarea, CACHE_POST_SIZE);
+ WATCHDOG_RESET ();
+ if (res == 0)
+ res = cache_post_test5 ();
+ WATCHDOG_RESET ();
+ if (res == 0)
+ res = cache_post_test6 ();
+
+ WATCHDOG_RESET ();
+ if (ints)
+ enable_interrupts ();
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * Copyright (C) 2002 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>
+
+#ifdef CONFIG_POST
+#if defined(CONFIG_MPC823) || \
+ defined(CONFIG_MPC850) || \
+ defined(CONFIG_MPC855) || \
+ defined(CONFIG_MPC860) || \
+ defined(CONFIG_MPC824X)
+
+#include <post.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#if CONFIG_POST & CFG_POST_CACHE
+
+ .text
+
+cache_post_dinvalidate:
+ lis r10, IDC_INVALL@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_iinvalidate:
+ lis r10, IDC_INVALL@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ddisable:
+ lis r10, IDC_DISABLE@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_dwb:
+ lis r10, IDC_ENABLE@h
+ mtspr DC_CST, r10
+ lis r10, DC_CFWT@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_dwt:
+ lis r10, IDC_ENABLE@h
+ mtspr DC_CST, r10
+ lis r10, DC_SFWT@h
+ mtspr DC_CST, r10
+ blr
+
+cache_post_idisable:
+ lis r10, IDC_DISABLE@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ienable:
+ lis r10, IDC_ENABLE@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_iunlock:
+ lis r10, IDC_UNALL@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+cache_post_ilock:
+ mtspr IC_ADR, r3
+ lis r10, IDC_LDLCK@h
+ mtspr IC_CST, r10
+ isync
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test1
+cache_post_test1:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back or write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * turn off the data cache
+ * write the negative pattern to the area
+ * turn on the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test2
+cache_post_test2:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwb
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-through mode
+ * invalidate the data cache
+ * write the zero pattern to a cached area
+ * flush the data cache
+ * write the negative pattern to the area
+ * turn off the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test3
+cache_post_test3:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwt
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+/*
+ * turn on the data cache
+ * switch the data cache to write-back mode
+ * invalidate the data cache
+ * write the negative pattern to a cached area
+ * flush the data cache
+ * write the zero pattern to the area
+ * invalidate the data cache
+ * read the area
+ *
+ * The negative pattern must be read at the last step
+ */
+ .global cache_post_test4
+cache_post_test4:
+ mflr r0
+ stw r0, 4(r1)
+
+ stwu r3, -4(r1)
+ stwu r4, -4(r1)
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Write the negative pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0xff
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_dwb
+ bl cache_post_dinvalidate
+
+ /* Write the zero pattern to the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ li r0, 0
+ lwz r3, 4(r1)
+ subi r3, r3, 1
+1:
+ stbu r0, 1(r3)
+ bdnz 1b
+
+ bl cache_post_ddisable
+ bl cache_post_dinvalidate
+
+ /* Read the test area */
+ lwz r0, 0(r1)
+ mtctr r0
+ lwz r4, 4(r1)
+ subi r4, r4, 1
+ li r3, 0
+1:
+ lbzu r0, 1(r4)
+ cmpli cr0, r0, 0xff
+ beq 2f
+ li r3, -1
+ b 3f
+2:
+ bdnz 1b
+3:
+
+ addi r1, r1, 8
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+cache_post_test5_1:
+ li r3, 0
+cache_post_test5_2:
+ li r3, -1
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+*/
+ .global cache_post_test5
+cache_post_test5:
+ mflr r0
+ stw r0, 4(r1)
+
+ bl cache_post_ienable
+ bl cache_post_iunlock
+ bl cache_post_iinvalidate
+
+ /* Compute r9 = cache_post_test5_reloc */
+ bl cache_post_test5_reloc
+cache_post_test5_reloc:
+ mflr r9
+
+ /* Copy the test instruction to cache_post_test5_data */
+ lis r3, (cache_post_test5_1 - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_1 - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Lock the branch instruction */
+ lis r3, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ bl cache_post_ilock
+
+ /* Replace the test instruction */
+ lis r3, (cache_post_test5_2 - cache_post_test5_reloc)@h
+ ori r3, r3, (cache_post_test5_2 - cache_post_test5_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
+ ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Execute to the test instruction */
+cache_post_test5_data:
+ nop
+
+ bl cache_post_iunlock
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+cache_post_test6_1:
+ li r3, -1
+cache_post_test6_2:
+ li r3, 0
+
+/*
+ * turn on the instruction cache
+ * unlock the entire instruction cache
+ * invalidate the instruction cache
+ * lock a branch instruction in the instruction cache
+ * replace the branch instruction with "nop"
+ * jump to the branch instruction
+ * check that the branch instruction was executed
+ */
+ .global cache_post_test6
+cache_post_test6:
+ mflr r0
+ stw r0, 4(r1)
+
+ bl cache_post_ienable
+ bl cache_post_iunlock
+ bl cache_post_iinvalidate
+
+ /* Compute r9 = cache_post_test6_reloc */
+ bl cache_post_test6_reloc
+cache_post_test6_reloc:
+ mflr r9
+
+ /* Copy the test instruction to cache_post_test6_data */
+ lis r3, (cache_post_test6_1 - cache_post_test6_reloc)@h
+ ori r3, r3, (cache_post_test6_1 - cache_post_test6_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+ ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Replace the test instruction */
+ lis r3, (cache_post_test6_2 - cache_post_test6_reloc)@h
+ ori r3, r3, (cache_post_test6_2 - cache_post_test6_reloc)@l
+ add r3, r3, r9
+ lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
+ ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
+ add r4, r4, r9
+ lwz r0, 0(r3)
+ stw r0, 0(r4)
+
+ bl cache_post_iinvalidate
+
+ /* Execute to the test instruction */
+cache_post_test6_data:
+ nop
+
+ lwz r0, 4(r1)
+ mtlr r0
+ blr
+
+#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */
+#endif /* CONFIG_POST & CFG_POST_CACHE */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ *
+ * This test checks the arithmetic logic unit (ALU) of CPU.
+ * It tests independently various groups of instructions using
+ * run-time modification of the code to reduce the memory footprint.
+ * For more details refer to post/cpu/ *.c files.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern int cpu_post_test_cmp (void);
+extern int cpu_post_test_cmpi (void);
+extern int cpu_post_test_two (void);
+extern int cpu_post_test_twox (void);
+extern int cpu_post_test_three (void);
+extern int cpu_post_test_threex (void);
+extern int cpu_post_test_threei (void);
+extern int cpu_post_test_andi (void);
+extern int cpu_post_test_srawi (void);
+extern int cpu_post_test_rlwnm (void);
+extern int cpu_post_test_rlwinm (void);
+extern int cpu_post_test_rlwimi (void);
+extern int cpu_post_test_store (void);
+extern int cpu_post_test_load (void);
+extern int cpu_post_test_cr (void);
+extern int cpu_post_test_b (void);
+extern int cpu_post_test_multi (void);
+extern int cpu_post_test_string (void);
+extern int cpu_post_test_complex (void);
+
+ulong cpu_post_makecr (long v)
+{
+ ulong cr = 0;
+
+ if (v < 0)
+ cr |= 0x80000000;
+ if (v > 0)
+ cr |= 0x40000000;
+ if (v == 0)
+ cr |= 0x20000000;
+
+ return cr;
+}
+
+int cpu_post_test (bd_t * bd, int flags)
+{
+ int ic = icache_status ();
+ int ret = 0;
+
+ if (ic)
+ icache_disable ();
+
+ if (ret == 0)
+ ret = cpu_post_test_cmp ();
+ if (ret == 0)
+ ret = cpu_post_test_cmpi ();
+ if (ret == 0)
+ ret = cpu_post_test_two ();
+ if (ret == 0)
+ ret = cpu_post_test_twox ();
+ if (ret == 0)
+ ret = cpu_post_test_three ();
+ if (ret == 0)
+ ret = cpu_post_test_threex ();
+ if (ret == 0)
+ ret = cpu_post_test_threei ();
+ if (ret == 0)
+ ret = cpu_post_test_andi ();
+ if (ret == 0)
+ ret = cpu_post_test_srawi ();
+ if (ret == 0)
+ ret = cpu_post_test_rlwnm ();
+ if (ret == 0)
+ ret = cpu_post_test_rlwinm ();
+ if (ret == 0)
+ ret = cpu_post_test_rlwimi ();
+ if (ret == 0)
+ ret = cpu_post_test_store ();
+ if (ret == 0)
+ ret = cpu_post_test_load ();
+ if (ret == 0)
+ ret = cpu_post_test_cr ();
+ if (ret == 0)
+ ret = cpu_post_test_b ();
+ if (ret == 0)
+ ret = cpu_post_test_multi ();
+ if (ret == 0)
+ ret = cpu_post_test_string ();
+ if (ret == 0)
+ ret = cpu_post_test_complex ();
+
+ if (ic)
+ icache_enable ();
+
+ return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_CPU */
+#endif /* CONFIG_POST */
--- /dev/null
+#
+# (C) Copyright 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
+#
+
+SUBDIRS =
+
+LIB = libcpu.a
+
+AOBJS = asm.o
+COBJS = cmp.o cmpi.o two.o twox.o three.o threex.o
+COBJS += threei.o andi.o srawi.o rlwnm.o rlwinm.o rlwimi.o
+COBJS += store.o load.o cr.o b.o multi.o string.o complex.o
+
+include $(TOPDIR)/post/rules.mk
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Logic instructions: andi., andis.
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_andi_s
+{
+ ulong cmd;
+ ulong op1;
+ ushort op2;
+ ulong res;
+} cpu_post_andi_table[] =
+{
+ {
+ OP_ANDI_,
+ 0x80008000,
+ 0xffff,
+ 0x00008000
+ },
+ {
+ OP_ANDIS_,
+ 0x80008000,
+ 0xffff,
+ 0x80000000
+ },
+};
+static unsigned int cpu_post_andi_size =
+ sizeof (cpu_post_andi_table) / sizeof (struct cpu_post_andi_s);
+
+int cpu_post_test_andi (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_andi_size && ret == 0; i++)
+ {
+ struct cpu_post_andi_s *test = cpu_post_andi_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11IX(test->cmd, reg1, reg0, test->op2),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ cpu_post_exec_21 (codecr, & cr, & res, test->op1);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at andi test %d !\n", i);
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2002 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>
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#if CONFIG_POST & CFG_POST_CPU
+
+/* void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2); */
+ .global cpu_post_exec_02
+cpu_post_exec_02:
+ mflr r0
+ stwu r0, -4(r1)
+
+ subi r1, r1, 104
+ stmw r6, 0(r1)
+
+ mtlr r3
+ mr r3, r4
+ mr r4, r5
+ blrl
+
+ lmw r6, 0(r1)
+ addi r1, r1, 104
+
+ lwz r0, 0(r1)
+ addi r1, r1, 4
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_04 (ulong *code, ulong op1, ulong op2, ulong op3, ulong op4); */
+ .global cpu_post_exec_04
+cpu_post_exec_04:
+ mflr r0
+ stwu r0, -4(r1)
+
+ subi r1, r1, 96
+ stmw r8, 0(r1)
+
+ mtlr r3
+ mr r3, r4
+ mr r4, r5
+ mr r5, r6
+ mtxer r7
+ blrl
+
+ lmw r8, 0(r1)
+ addi r1, r1, 96
+
+ lwz r0, 0(r1)
+ addi r1, r1, 4
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2); */
+ .global cpu_post_exec_12
+cpu_post_exec_12:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+
+ mtlr r3
+ mr r3, r5
+ mr r4, r6
+ blrl
+
+ lwz r4, 0(r1)
+ stw r3, 0(r4)
+
+ lwz r0, 4(r1)
+ addi r1, r1, 8
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1); */
+ .global cpu_post_exec_11
+cpu_post_exec_11:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+
+ mtlr r3
+ mr r3, r5
+ blrl
+
+ lwz r4, 0(r1)
+ stw r3, 0(r4)
+
+ lwz r0, 4(r1)
+ addi r1, r1, 8
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1); */
+ .global cpu_post_exec_21
+cpu_post_exec_21:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+ stwu r5, -4(r1)
+
+ li r0, 0
+ mtxer r0
+ lwz r0, 0(r4)
+ mtcr r0
+
+ mtlr r3
+ mr r3, r6
+ blrl
+
+ mfcr r0
+ lwz r4, 4(r1)
+ stw r0, 0(r4)
+ lwz r4, 0(r1)
+ stw r3, 0(r4)
+
+ lwz r0, 8(r1)
+ addi r1, r1, 12
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2); */
+ .global cpu_post_exec_22
+cpu_post_exec_22:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+ stwu r5, -4(r1)
+
+ li r0, 0
+ mtxer r0
+ lwz r0, 0(r4)
+ mtcr r0
+
+ mtlr r3
+ mr r3, r6
+ mr r4, r7
+ blrl
+
+ mfcr r0
+ lwz r4, 4(r1)
+ stw r0, 0(r4)
+ lwz r4, 0(r1)
+ stw r3, 0(r4)
+
+ lwz r0, 8(r1)
+ addi r1, r1, 12
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3); */
+ .global cpu_post_exec_12w
+cpu_post_exec_12w:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+
+ mtlr r3
+ lwz r3, 0(r4)
+ mr r4, r5
+ mr r5, r6
+ blrl
+
+ lwz r4, 0(r1)
+ stw r3, 0(r4)
+
+ lwz r0, 4(r1)
+ addi r1, r1, 8
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2); */
+ .global cpu_post_exec_11w
+cpu_post_exec_11w:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+
+ mtlr r3
+ lwz r3, 0(r4)
+ mr r4, r5
+ blrl
+
+ lwz r4, 0(r1)
+ stw r3, 0(r4)
+
+ lwz r0, 4(r1)
+ addi r1, r1, 8
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3); */
+ .global cpu_post_exec_22w
+cpu_post_exec_22w:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+ stwu r6, -4(r1)
+
+ mtlr r3
+ lwz r3, 0(r4)
+ mr r4, r5
+ blrl
+
+ lwz r4, 4(r1)
+ stw r3, 0(r4)
+ lwz r4, 0(r1)
+ stw r5, 0(r4)
+
+ lwz r0, 8(r1)
+ addi r1, r1, 12
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2); */
+ .global cpu_post_exec_21w
+cpu_post_exec_21w:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+ stwu r5, -4(r1)
+
+ mtlr r3
+ lwz r3, 0(r4)
+ blrl
+
+ lwz r5, 4(r1)
+ stw r3, 0(r5)
+ lwz r5, 0(r1)
+ stw r4, 0(r5)
+
+ lwz r0, 8(r1)
+ addi r1, r1, 12
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3); */
+ .global cpu_post_exec_21x
+cpu_post_exec_21x:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+ stwu r5, -4(r1)
+
+ mtlr r3
+ mr r3, r6
+ blrl
+
+ lwz r5, 4(r1)
+ stw r3, 0(r5)
+ lwz r5, 0(r1)
+ stw r4, 0(r5)
+
+ lwz r0, 8(r1)
+ addi r1, r1, 12
+ mtlr r0
+ blr
+
+/* void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
+ ulong cr); */
+ .global cpu_post_exec_31
+cpu_post_exec_31:
+ mflr r0
+ stwu r0, -4(r1)
+ stwu r4, -4(r1)
+ stwu r5, -4(r1)
+ stwu r6, -4(r1)
+
+ mtlr r3
+ lwz r3, 0(r4)
+ lwz r4, 0(r5)
+ mr r6, r7
+ blrl
+
+ lwz r7, 8(r1)
+ stw r3, 0(r7)
+ lwz r7, 4(r1)
+ stw r4, 0(r7)
+ lwz r7, 0(r1)
+ stw r5, 0(r7)
+
+ lwz r0, 12(r1)
+ addi r1, r1, 16
+ mtlr r0
+ blr
+
+/* int cpu_post_complex_1_asm (int a1, int a2, int a3, int a4, int n); */
+ .global cpu_post_complex_1_asm
+cpu_post_complex_1_asm:
+ li r9,0
+ cmpw r9,r7
+ bge cpu_post_complex_1_done
+ mtctr r7
+cpu_post_complex_1_loop:
+ mullw r0,r3,r4
+ subf r0,r5,r0
+ divw r0,r0,r6
+ add r9,r9,r0
+ bdnz cpu_post_complex_1_loop
+cpu_post_complex_1_done:
+ mr r3,r9
+ blr
+
+/* int cpu_post_complex_2_asm (int x, int n); */
+ .global cpu_post_complex_2_asm
+cpu_post_complex_2_asm:
+ mr. r0,r4
+ mtctr r0
+ mr r0,r3
+ li r3,1
+ li r4,1
+ blelr
+cpu_post_complex_2_loop:
+ mullw r3,r3,r0
+ add r3,r3,r4
+ bdnz cpu_post_complex_2_loop
+blr
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Branch instructions: b, bl, bc
+ *
+ * The first 2 instructions (b, bl) are verified by jumping
+ * to a fixed address and checking whether control was transfered
+ * to that very point. For the bl instruction the value of the
+ * link register is checked as well (using mfspr).
+ * To verify the bc instruction various combinations of the BI/BO
+ * fields, the CTR and the condition register values are
+ * checked. The list of such combinations is pre-built and
+ * linked in PPCBoot at build time.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+extern void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
+ ulong cr);
+
+static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
+ int pjump, int dec, int link, ulong pctr, ulong cr)
+{
+ int ret = 0;
+ ulong lr = 0;
+ ulong ctr = pctr;
+ ulong jump;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(6),
+ ASM_MFLR(6),
+ ASM_MTCTR(3),
+ ASM_MTLR(4),
+ ASM_LI(5, 1),
+ ASM_3O(cmd, bo, bi, 8),
+ ASM_LI(5, 0),
+ ASM_MFCTR(3),
+ ASM_MFLR(4),
+ ASM_MTLR(6),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);
+
+ if (ret == 0)
+ ret = pjump == jump ? 0 : -1;
+ if (ret == 0)
+ {
+ if (dec)
+ ret = pctr == ctr + 1 ? 0 : -1;
+ else
+ ret = pctr == ctr ? 0 : -1;
+ }
+ if (ret == 0)
+ {
+ if (link)
+ ret = lr == (ulong) code + 24 ? 0 : -1;
+ else
+ ret = lr == 0 ? 0 : -1;
+ }
+
+ return ret;
+}
+
+int cpu_post_test_b (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ if (ret == 0)
+ {
+ ulong code[] =
+ {
+ ASM_MFLR(4),
+ ASM_MTLR(3),
+ ASM_B(4),
+ ASM_MFLR(3),
+ ASM_MTLR(4),
+ ASM_BLR,
+ };
+ ulong res;
+
+ cpu_post_exec_11 (code, &res, 0);
+
+ ret = res == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at b1 test !\n");
+ }
+ }
+
+ if (ret == 0)
+ {
+ ulong code[] =
+ {
+ ASM_MFLR(4),
+ ASM_MTLR(3),
+ ASM_BL(4),
+ ASM_MFLR(3),
+ ASM_MTLR(4),
+ ASM_BLR,
+ };
+ ulong res;
+
+ cpu_post_exec_11 (code, &res, 0);
+
+ ret = res == (ulong)code + 12 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at b2 test !\n");
+ }
+ }
+
+ if (ret == 0)
+ {
+ ulong cc, cd;
+ int cond;
+ ulong ctr;
+ int link;
+
+ i = 0;
+
+ for (cc = 0; cc < 4 && ret == 0; cc++)
+ {
+ for (cd = 0; cd < 4 && ret == 0; cd++)
+ {
+ for (link = 0; link <= 1 && ret == 0; link++)
+ {
+ for (cond = 0; cond <= 1 && ret == 0; cond++)
+ {
+ for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
+ {
+ int dec = cd < 2;
+ int cr = cond ? 0x80000000 : 0x00000000;
+ int jumpc = cc >= 2 ||
+ (cc == 0 && !cond) ||
+ (cc == 1 && cond);
+ int jumpd = cd >= 2 ||
+ (cd == 0 && ctr != 1) ||
+ (cd == 1 && ctr == 1);
+ int jump = jumpc && jumpd;
+
+ ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
+ (cc << 3) + (cd << 1), 0, jump, dec, link,
+ ctr, cr);
+
+ if (ret != 0)
+ {
+ post_log ("Error at b3 test %d !\n", i);
+ }
+
+ i++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Integer compare instructions: cmpw, cmplw
+ *
+ * To verify these instructions the test runs them with
+ * different combinations of operands, reads the condition
+ * register value and compares it with the expected one.
+ * The test contains a pre-built table
+ * containing the description of each test case: the instruction,
+ * the values of the operands, the condition field to save
+ * the result in and the expected result.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2);
+
+static struct cpu_post_cmp_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ ulong cr;
+ ulong res;
+} cpu_post_cmp_table[] =
+{
+ {
+ OP_CMPW,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPW,
+ 123,
+ 133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPW,
+ 123,
+ -133,
+ 4,
+ 0x04
+ },
+ {
+ OP_CMPLW,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPLW,
+ 123,
+ -133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPLW,
+ 123,
+ 113,
+ 4,
+ 0x04
+ },
+};
+static unsigned int cpu_post_cmp_size =
+ sizeof (cpu_post_cmp_table) / sizeof (struct cpu_post_cmp_s);
+
+int cpu_post_test_cmp (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < cpu_post_cmp_size && ret == 0; i++)
+ {
+ struct cpu_post_cmp_s *test = cpu_post_cmp_table + i;
+ unsigned long code[] =
+ {
+ ASM_2C(test->cmd, test->cr, 3, 4),
+ ASM_MFCR(3),
+ ASM_BLR
+ };
+ ulong res;
+
+ cpu_post_exec_12 (code, & res, test->op1, test->op2);
+
+ ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cmp test %d !\n", i);
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Integer compare instructions: cmpwi, cmplwi
+ *
+ * To verify these instructions the test runs them with
+ * different combinations of operands, reads the condition
+ * register value and compares it with the expected one.
+ * The test contains a pre-built table
+ * containing the description of each test case: the instruction,
+ * the values of the operands, the condition field to save
+ * the result in and the expected result.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+
+static struct cpu_post_cmpi_s
+{
+ ulong cmd;
+ ulong op1;
+ ushort op2;
+ ulong cr;
+ ulong res;
+} cpu_post_cmpi_table[] =
+{
+ {
+ OP_CMPWI,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPWI,
+ 123,
+ 133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPWI,
+ 123,
+ -133,
+ 4,
+ 0x04
+ },
+ {
+ OP_CMPLWI,
+ 123,
+ 123,
+ 2,
+ 0x02
+ },
+ {
+ OP_CMPLWI,
+ 123,
+ -133,
+ 3,
+ 0x08
+ },
+ {
+ OP_CMPLWI,
+ 123,
+ 113,
+ 4,
+ 0x04
+ },
+};
+static unsigned int cpu_post_cmpi_size =
+ sizeof (cpu_post_cmpi_table) / sizeof (struct cpu_post_cmpi_s);
+
+int cpu_post_test_cmpi (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < cpu_post_cmpi_size && ret == 0; i++)
+ {
+ struct cpu_post_cmpi_s *test = cpu_post_cmpi_table + i;
+ unsigned long code[] =
+ {
+ ASM_1IC(test->cmd, test->cr, 3, test->op2),
+ ASM_MFCR(3),
+ ASM_BLR
+ };
+ ulong res;
+
+ cpu_post_exec_11 (code, & res, test->op1);
+
+ ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cmpi test %d !\n", i);
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Complex calculations
+ *
+ * The calculations in this test are just a combination of simpler
+ * calculations, but probably under different timing conditions, etc.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern int cpu_post_complex_1_asm (int a1, int a2, int a3, int a4, int n);
+extern int cpu_post_complex_2_asm (int x, int n);
+
+ /*
+ * n
+ * SUM (a1 * a2 - a3) / a4 = n * result
+ * i=1
+ */
+static int cpu_post_test_complex_1 (void)
+{
+ int a1 = 666;
+ int a2 = 667;
+ int a3 = 668;
+ int a4 = 66;
+ int n = 100;
+ int result = 6720; /* (a1 * a2 - a3) / a4 */
+
+ if (cpu_post_complex_1_asm(a1, a2, a3, a4, n) != n * result)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+ /* (1 + x + x^2 + ... + x^n) * (1 - x) = 1 - x^(n+1)
+ */
+static int cpu_post_test_complex_2 (void)
+{
+ int ret = -1;
+ int x;
+ int n;
+ int k;
+ int left;
+ int right;
+
+ for (x = -8; x <= 8; x ++)
+ {
+ n = 9;
+
+ left = cpu_post_complex_2_asm(x, n);
+ left *= 1 - x;
+
+ right = 1;
+ for (k = 0; k <= n; k ++)
+ {
+ right *= x;
+ }
+ right = 1 - right;
+
+ if (left != right)
+ {
+ goto Done;
+ }
+ }
+
+ ret = 0;
+ Done:
+
+ return ret;
+}
+
+int cpu_post_test_complex (void)
+{
+ int ret = 0;
+
+ if (ret == 0)
+ {
+ ret = cpu_post_test_complex_1();
+ }
+
+ if (ret == 0)
+ {
+ ret = cpu_post_test_complex_2();
+ }
+
+ if (ret != 0)
+ {
+ post_log ("Error at complex test !\n");
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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
+ */
+#ifndef _CPU_ASM_H
+#define _CPU_ASM_H
+
+#define BIT_C 0x00000001
+
+#define OP_BLR 0x4e800020
+#define OP_EXTSB 0x7c000774
+#define OP_EXTSH 0x7c000734
+#define OP_NEG 0x7c0000d0
+#define OP_CNTLZW 0x7c000034
+#define OP_ADD 0x7c000214
+#define OP_ADDC 0x7c000014
+#define OP_ADDME 0x7c0001d4
+#define OP_ADDZE 0x7c000194
+#define OP_ADDE 0x7c000114
+#define OP_ADDI 0x38000000
+#define OP_SUBF 0x7c000050
+#define OP_SUBFC 0x7c000010
+#define OP_SUBFE 0x7c000110
+#define OP_SUBFME 0x7c0001d0
+#define OP_SUBFZE 0x7c000190
+#define OP_MFCR 0x7c000026
+#define OP_MTCR 0x7c0ff120
+#define OP_MFXER 0x7c0102a6
+#define OP_MTXER 0x7c0103a6
+#define OP_MCRXR 0x7c000400
+#define OP_MCRF 0x4c000000
+#define OP_CRAND 0x4c000202
+#define OP_CRANDC 0x4c000102
+#define OP_CROR 0x4c000382
+#define OP_CRORC 0x4c000342
+#define OP_CRXOR 0x4c000182
+#define OP_CRNAND 0x4c0001c2
+#define OP_CRNOR 0x4c000042
+#define OP_CREQV 0x4c000242
+#define OP_CMPW 0x7c000000
+#define OP_CMPLW 0x7c000040
+#define OP_CMPWI 0x2c000000
+#define OP_CMPLWI 0x28000000
+#define OP_MULLW 0x7c0001d6
+#define OP_MULHW 0x7c000096
+#define OP_MULHWU 0x7c000016
+#define OP_DIVW 0x7c0003d6
+#define OP_DIVWU 0x7c000396
+#define OP_OR 0x7c000378
+#define OP_ORC 0x7c000338
+#define OP_XOR 0x7c000278
+#define OP_NAND 0x7c0003b8
+#define OP_NOR 0x7c0000f8
+#define OP_EQV 0x7c000238
+#define OP_SLW 0x7c000030
+#define OP_SRW 0x7c000430
+#define OP_SRAW 0x7c000630
+#define OP_ORI 0x60000000
+#define OP_ORIS 0x64000000
+#define OP_XORI 0x68000000
+#define OP_XORIS 0x6c000000
+#define OP_ANDI_ 0x70000000
+#define OP_ANDIS_ 0x74000000
+#define OP_SRAWI 0x7c000670
+#define OP_RLWINM 0x54000000
+#define OP_RLWNM 0x5c000000
+#define OP_RLWIMI 0x50000000
+#define OP_LWZ 0x80000000
+#define OP_LHZ 0xa0000000
+#define OP_LHA 0xa8000000
+#define OP_LBZ 0x88000000
+#define OP_LWZU 0x84000000
+#define OP_LHZU 0xa4000000
+#define OP_LHAU 0xac000000
+#define OP_LBZU 0x8c000000
+#define OP_LWZX 0x7c00002e
+#define OP_LHZX 0x7c00022e
+#define OP_LHAX 0x7c0002ae
+#define OP_LBZX 0x7c0000ae
+#define OP_LWZUX 0x7c00006e
+#define OP_LHZUX 0x7c00026e
+#define OP_LHAUX 0x7c0002ee
+#define OP_LBZUX 0x7c0000ee
+#define OP_STW 0x90000000
+#define OP_STH 0xb0000000
+#define OP_STB 0x98000000
+#define OP_STWU 0x94000000
+#define OP_STHU 0xb4000000
+#define OP_STBU 0x9c000000
+#define OP_STWX 0x7c00012e
+#define OP_STHX 0x7c00032e
+#define OP_STBX 0x7c0001ae
+#define OP_STWUX 0x7c00016e
+#define OP_STHUX 0x7c00036e
+#define OP_STBUX 0x7c0001ee
+#define OP_B 0x48000000
+#define OP_BL 0x48000001
+#define OP_BC 0x40000000
+#define OP_BCL 0x40000001
+#define OP_MTLR 0x7c0803a6
+#define OP_MFLR 0x7c0802a6
+#define OP_MTCTR 0x7c0903a6
+#define OP_MFCTR 0x7c0902a6
+#define OP_LMW 0xb8000000
+#define OP_STMW 0xbc000000
+#define OP_LSWI 0x7c0004aa
+#define OP_LSWX 0x7c00042a
+#define OP_STSWI 0x7c0005aa
+#define OP_STSWX 0x7c00052a
+
+#define ASM_0(opcode) (opcode)
+#define ASM_1(opcode, rd) ((opcode) + \
+ ((rd) << 21))
+#define ASM_1C(opcode, cr) ((opcode) + \
+ ((cr) << 23))
+#define ASM_11(opcode, rd, rs) ((opcode) + \
+ ((rd) << 21) + \
+ ((rs) << 16))
+#define ASM_11C(opcode, cd, cs) ((opcode) + \
+ ((cd) << 23) + \
+ ((cs) << 18))
+#define ASM_11X(opcode, rd, rs) ((opcode) + \
+ ((rs) << 21) + \
+ ((rd) << 16))
+#define ASM_11I(opcode, rd, rs, simm) ((opcode) + \
+ ((rd) << 21) + \
+ ((rs) << 16) + \
+ ((simm) & 0xffff))
+#define ASM_11IF(opcode, rd, rs, simm) ((opcode) + \
+ ((rd) << 21) + \
+ ((rs) << 16) + \
+ ((simm) << 11))
+#define ASM_11S(opcode, rd, rs, sh) ((opcode) + \
+ ((rs) << 21) + \
+ ((rd) << 16) + \
+ ((sh) << 11))
+#define ASM_11IX(opcode, rd, rs, imm) ((opcode) + \
+ ((rs) << 21) + \
+ ((rd) << 16) + \
+ ((imm) & 0xffff))
+#define ASM_12(opcode, rd, rs1, rs2) ((opcode) + \
+ ((rd) << 21) + \
+ ((rs1) << 16) + \
+ ((rs2) << 11))
+#define ASM_12F(opcode, fd, fs1, fs2) ((opcode) + \
+ ((fd) << 21) + \
+ ((fs1) << 16) + \
+ ((fs2) << 11))
+#define ASM_12X(opcode, rd, rs1, rs2) ((opcode) + \
+ ((rs1) << 21) + \
+ ((rd) << 16) + \
+ ((rs2) << 11))
+#define ASM_2C(opcode, cr, rs1, rs2) ((opcode) + \
+ ((cr) << 23) + \
+ ((rs1) << 16) + \
+ ((rs2) << 11))
+#define ASM_1IC(opcode, cr, rs, imm) ((opcode) + \
+ ((cr) << 23) + \
+ ((rs) << 16) + \
+ ((imm) & 0xffff))
+#define ASM_122(opcode, rd, rs1, rs2, imm1, imm2) \
+ ((opcode) + \
+ ((rs1) << 21) + \
+ ((rd) << 16) + \
+ ((rs2) << 11) + \
+ ((imm1) << 6) + \
+ ((imm2) << 1))
+#define ASM_113(opcode, rd, rs, imm1, imm2, imm3) \
+ ((opcode) + \
+ ((rs) << 21) + \
+ ((rd) << 16) + \
+ ((imm1) << 11) + \
+ ((imm2) << 6) + \
+ ((imm3) << 1))
+#define ASM_1O(opcode, off) ((opcode) + (off))
+#define ASM_3O(opcode, bo, bi, off) ((opcode) + \
+ ((bo) << 21) + \
+ ((bi) << 16) + \
+ (off))
+
+#define ASM_ADDI(rd, rs, simm) ASM_11I(OP_ADDI, rd, rs, simm)
+#define ASM_BLR ASM_0(OP_BLR)
+#define ASM_STW(rd, rs, simm) ASM_11I(OP_STW, rd, rs, simm)
+#define ASM_LWZ(rd, rs, simm) ASM_11I(OP_LWZ, rd, rs, simm)
+#define ASM_MFCR(rd) ASM_1(OP_MFCR, rd)
+#define ASM_MTCR(rd) ASM_1(OP_MTCR, rd)
+#define ASM_MFXER(rd) ASM_1(OP_MFXER, rd)
+#define ASM_MTXER(rd) ASM_1(OP_MTXER, rd)
+#define ASM_MFCTR(rd) ASM_1(OP_MFCTR, rd)
+#define ASM_MTCTR(rd) ASM_1(OP_MTCTR, rd)
+#define ASM_MCRXR(cr) ASM_1C(OP_MCRXR, cr)
+#define ASM_MCRF(cd, cs) ASM_11C(OP_MCRF, cd, cs)
+#define ASM_B(off) ASM_1O(OP_B, off)
+#define ASM_BL(off) ASM_1O(OP_BL, off)
+#define ASM_MFLR(rd) ASM_1(OP_MFLR, rd)
+#define ASM_MTLR(rd) ASM_1(OP_MTLR, rd)
+#define ASM_LI(rd, imm) ASM_ADDI(rd, 0, imm)
+#define ASM_LMW(rd, rs, simm) ASM_11I(OP_LMW, rd, rs, simm)
+#define ASM_STMW(rd, rs, simm) ASM_11I(OP_STMW, rd, rs, simm)
+#define ASM_LSWI(rd, rs, simm) ASM_11IF(OP_LSWI, rd, rs, simm)
+#define ASM_LSWX(rd, rs1, rs2) ASM_12(OP_LSWX, rd, rs1, rs2)
+#define ASM_STSWI(rd, rs, simm) ASM_11IF(OP_STSWI, rd, rs, simm)
+#define ASM_STSWX(rd, rs1, rs2) ASM_12(OP_STSWX, rd, rs1, rs2)
+
+
+#endif /* _CPU_ASM_H */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Condition register istructions: mtcr, mfcr, mcrxr,
+ * crand, crandc, cror, crorc, crxor,
+ * crnand, crnor, creqv, mcrf
+ *
+ * The mtcrf/mfcr instructions is tested by loading different
+ * values into the condition register (mtcrf), moving its value
+ * to a general-purpose register (mfcr) and comparing this value
+ * with the expected one.
+ * The mcrxr instruction is tested by loading a fixed value
+ * into the XER register (mtspr), moving XER value to the
+ * condition register (mcrxr), moving it to a general-purpose
+ * register (mfcr) and comparing the value of this register with
+ * the expected one.
+ * The rest of instructions is tested by loading a fixed
+ * value into the condition register (mtcrf), executing each
+ * instruction several times to modify all 4-bit condition
+ * fields, moving the value of the conditional register to a
+ * general-purpose register (mfcr) and comparing it with the
+ * expected one.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
+extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
+
+static ulong cpu_post_cr_table1[] =
+{
+ 0xaaaaaaaa,
+ 0x55555555,
+};
+static unsigned int cpu_post_cr_size1 =
+ sizeof (cpu_post_cr_table1) / sizeof (ulong);
+
+static struct cpu_post_cr_s2 {
+ ulong xer;
+ ulong cr;
+} cpu_post_cr_table2[] =
+{
+ {
+ 0xa0000000,
+ 1
+ },
+ {
+ 0x40000000,
+ 5
+ },
+};
+static unsigned int cpu_post_cr_size2 =
+ sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
+
+static struct cpu_post_cr_s3 {
+ ulong cr;
+ ulong cs;
+ ulong cd;
+ ulong res;
+} cpu_post_cr_table3[] =
+{
+ {
+ 0x01234567,
+ 0,
+ 4,
+ 0x01230567
+ },
+ {
+ 0x01234567,
+ 7,
+ 0,
+ 0x71234567
+ },
+};
+static unsigned int cpu_post_cr_size3 =
+ sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
+
+static struct cpu_post_cr_s4 {
+ ulong cmd;
+ ulong cr;
+ ulong op1;
+ ulong op2;
+ ulong op3;
+ ulong res;
+} cpu_post_cr_table4[] =
+{
+ {
+ OP_CRAND,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRAND,
+ 0x0000ffff,
+ 16,
+ 17,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRANDC,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRANDC,
+ 0x0000ffff,
+ 16,
+ 0,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CROR,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CROR,
+ 0x0000ffff,
+ 0,
+ 1,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRORC,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRORC,
+ 0x0000ffff,
+ 0,
+ 0,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRXOR,
+ 0x0000ffff,
+ 0,
+ 0,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRXOR,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRNAND,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CRNAND,
+ 0x0000ffff,
+ 16,
+ 17,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRNOR,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+ {
+ OP_CRNOR,
+ 0x0000ffff,
+ 0,
+ 1,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CREQV,
+ 0x0000ffff,
+ 0,
+ 0,
+ 0,
+ 0x8000ffff
+ },
+ {
+ OP_CREQV,
+ 0x0000ffff,
+ 0,
+ 16,
+ 0,
+ 0x0000ffff
+ },
+};
+static unsigned int cpu_post_cr_size4 =
+ sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
+
+int cpu_post_test_cr (void)
+{
+ int ret = 0;
+ unsigned int i;
+ unsigned long cr_sav;
+
+ asm ( "mfcr %0" : "=r" (cr_sav) : );
+
+ for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
+ {
+ ulong cr = cpu_post_cr_table1[i];
+ ulong res;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(3),
+ ASM_MFCR(3),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11 (code, &res, cr);
+
+ ret = res == cr ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr1 test %d !\n", i);
+ }
+ }
+
+ for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
+ {
+ struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
+ ulong res;
+ ulong xer;
+
+ unsigned long code[] =
+ {
+ ASM_MTXER(3),
+ ASM_MCRXR(test->cr),
+ ASM_MFCR(3),
+ ASM_MFXER(4),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_21x (code, &res, &xer, test->xer);
+
+ ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
+ 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr2 test %d !\n", i);
+ }
+ }
+
+ for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
+ {
+ struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
+ ulong res;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(3),
+ ASM_MCRF(test->cd, test->cs),
+ ASM_MFCR(3),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11 (code, &res, test->cr);
+
+ ret = res == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr3 test %d !\n", i);
+ }
+ }
+
+ for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
+ {
+ struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
+ ulong res;
+
+ unsigned long code[] =
+ {
+ ASM_MTCR(3),
+ ASM_12F(test->cmd, test->op3, test->op1, test->op2),
+ ASM_MFCR(3),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11 (code, &res, test->cr);
+
+ ret = res == test->res ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at cr4 test %d !\n", i);
+ }
+ }
+
+ asm ( "mtcr %0" : : "r" (cr_sav));
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Load instructions: lbz(x)(u), lhz(x)(u), lha(x)(u), lwz(x)(u)
+ *
+ * All operations are performed on a 16-byte array. The array
+ * is 4-byte aligned. The base register points to offset 8.
+ * The immediate offset (index register) ranges in [-8 ... +7].
+ * The test cases are composed so that they do not
+ * cause alignment exceptions.
+ * The test contains a pre-built table describing all test cases.
+ * The table entry contains:
+ * the instruction opcode, the array contents, the value of the index
+ * register and the expected value of the destination register.
+ * After executing the instruction, the test verifies the
+ * value of the destination register and the value of the base
+ * register (it must change for "load with update" instructions).
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3);
+extern void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2);
+
+static struct cpu_post_load_s
+{
+ ulong cmd;
+ uint width;
+ int update;
+ int index;
+ ulong offset;
+} cpu_post_load_table[] =
+{
+ {
+ OP_LWZ,
+ 4,
+ 0,
+ 0,
+ 4
+ },
+ {
+ OP_LHA,
+ 3,
+ 0,
+ 0,
+ 2
+ },
+ {
+ OP_LHZ,
+ 2,
+ 0,
+ 0,
+ 2
+ },
+ {
+ OP_LBZ,
+ 1,
+ 0,
+ 0,
+ 1
+ },
+ {
+ OP_LWZU,
+ 4,
+ 1,
+ 0,
+ 4
+ },
+ {
+ OP_LHAU,
+ 3,
+ 1,
+ 0,
+ 2
+ },
+ {
+ OP_LHZU,
+ 2,
+ 1,
+ 0,
+ 2
+ },
+ {
+ OP_LBZU,
+ 1,
+ 1,
+ 0,
+ 1
+ },
+ {
+ OP_LWZX,
+ 4,
+ 0,
+ 1,
+ 4
+ },
+ {
+ OP_LHAX,
+ 3,
+ 0,
+ 1,
+ 2
+ },
+ {
+ OP_LHZX,
+ 2,
+ 0,
+ 1,
+ 2
+ },
+ {
+ OP_LBZX,
+ 1,
+ 0,
+ 1,
+ 1
+ },
+ {
+ OP_LWZUX,
+ 4,
+ 1,
+ 1,
+ 4
+ },
+ {
+ OP_LHAUX,
+ 3,
+ 1,
+ 1,
+ 2
+ },
+ {
+ OP_LHZUX,
+ 2,
+ 1,
+ 1,
+ 2
+ },
+ {
+ OP_LBZUX,
+ 1,
+ 1,
+ 1,
+ 1
+ },
+};
+static unsigned int cpu_post_load_size =
+ sizeof (cpu_post_load_table) / sizeof (struct cpu_post_load_s);
+
+int cpu_post_test_load (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < cpu_post_load_size && ret == 0; i++)
+ {
+ struct cpu_post_load_s *test = cpu_post_load_table + i;
+ uchar data[16] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ ulong base0 = (ulong) (data + 8);
+ ulong base = base0;
+ ulong value;
+
+ if (test->index)
+ {
+ ulong code[] =
+ {
+ ASM_12(test->cmd, 5, 3, 4),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_22w (code, &base, test->offset, &value);
+ }
+ else
+ {
+ ulong code[] =
+ {
+ ASM_11I(test->cmd, 4, 3, test->offset),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_21w (code, &base, &value);
+ }
+
+ if (ret == 0)
+ {
+ if (test->update)
+ ret = base == base0 + test->offset ? 0 : -1;
+ else
+ ret = base == base0 ? 0 : -1;
+ }
+
+ if (ret == 0)
+ {
+ switch (test->width)
+ {
+ case 1:
+ ret = *(uchar *)(base0 + test->offset) == value ?
+ 0 : -1;
+ break;
+ case 2:
+ ret = *(ushort *)(base0 + test->offset) == value ?
+ 0 : -1;
+ break;
+ case 3:
+ ret = *(short *)(base0 + test->offset) == value ?
+ 0 : -1;
+ break;
+ case 4:
+ ret = *(ulong *)(base0 + test->offset) == value ?
+ 0 : -1;
+ break;
+ }
+ }
+
+ if (ret != 0)
+ {
+ post_log ("Error at load test %d !\n", i);
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Load/store multiple word instructions: lmw, stmw
+ *
+ * 26 consecutive words are loaded from a source memory buffer
+ * into GPRs r6 through r31. After that, 26 consecutive words are stored
+ * from the GPRs r6 through r31 into a target memory buffer. The contents
+ * of the source and target buffers are then compared.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2);
+
+int cpu_post_test_multi (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ if (ret == 0)
+ {
+ ulong src [26], dst [26];
+
+ ulong code[] =
+ {
+ ASM_LMW(5, 3, 0),
+ ASM_STMW(5, 4, 0),
+ ASM_BLR,
+ };
+
+ for (i = 0; i < sizeof(src) / sizeof(src[0]); i ++)
+ {
+ src[i] = i;
+ dst[i] = 0;
+ }
+
+ cpu_post_exec_02(code, (ulong)src, (ulong)dst);
+
+ ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
+ }
+
+ if (ret != 0)
+ {
+ post_log ("Error at multi test !\n");
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Shift instructions: rlwimi
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_rlwimi_s
+{
+ ulong cmd;
+ ulong op0;
+ ulong op1;
+ uchar op2;
+ uchar mb;
+ uchar me;
+ ulong res;
+} cpu_post_rlwimi_table[] =
+{
+ {
+ OP_RLWIMI,
+ 0xff00ffff,
+ 0x0000aa00,
+ 8,
+ 8,
+ 15,
+ 0xffaaffff
+ },
+};
+static unsigned int cpu_post_rlwimi_size =
+ sizeof (cpu_post_rlwimi_table) / sizeof (struct cpu_post_rlwimi_s);
+
+int cpu_post_test_rlwimi (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_rlwimi_size && ret == 0; i++)
+ {
+ struct cpu_post_rlwimi_s *test = cpu_post_rlwimi_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -20),
+ ASM_STW(3, stk, 8),
+ ASM_STW(4, stk, 12),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg1, stk, 8),
+ ASM_LWZ(reg0, stk, 12),
+ ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 20),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -20),
+ ASM_STW(3, stk, 8),
+ ASM_STW(4, stk, 12),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg1, stk, 8),
+ ASM_LWZ(reg0, stk, 12),
+ ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me) |
+ BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 20),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_22 (code, & cr, & res, test->op0, test->op1);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at rlwimi test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_22 (codecr, & cr, & res, test->op0, test->op1);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at rlwimi test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Shift instructions: rlwinm
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_rlwinm_s
+{
+ ulong cmd;
+ ulong op1;
+ uchar op2;
+ uchar mb;
+ uchar me;
+ ulong res;
+} cpu_post_rlwinm_table[] =
+{
+ {
+ OP_RLWINM,
+ 0xffff0000,
+ 24,
+ 16,
+ 23,
+ 0x0000ff00
+ },
+};
+static unsigned int cpu_post_rlwinm_size =
+ sizeof (cpu_post_rlwinm_table) / sizeof (struct cpu_post_rlwinm_s);
+
+int cpu_post_test_rlwinm (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_rlwinm_size && ret == 0; i++)
+ {
+ struct cpu_post_rlwinm_s *test = cpu_post_rlwinm_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_113(test->cmd, reg1, reg0, test->op2, test->mb,
+ test->me) | BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op1);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at rlwinm test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_21 (codecr, & cr, & res, test->op1);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at rlwinm test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Shift instructions: rlwnm
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_rlwnm_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ uchar mb;
+ uchar me;
+ ulong res;
+} cpu_post_rlwnm_table[] =
+{
+ {
+ OP_RLWNM,
+ 0xffff0000,
+ 24,
+ 16,
+ 23,
+ 0x0000ff00
+ },
+};
+static unsigned int cpu_post_rlwnm_size =
+ sizeof (cpu_post_rlwnm_table) / sizeof (struct cpu_post_rlwnm_s);
+
+int cpu_post_test_rlwnm (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_rlwnm_size && ret == 0; i++)
+ {
+ struct cpu_post_rlwnm_s *test = cpu_post_rlwnm_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int reg2 = (reg + 2) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_122(test->cmd, reg2, reg1, reg0, test->mb, test->me),
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_122(test->cmd, reg2, reg1, reg0, test->mb, test->me) |
+ BIT_C,
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at rlwnm test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at rlwnm test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Shift instructions: srawi
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_srawi_s
+{
+ ulong cmd;
+ ulong op1;
+ uchar op2;
+ ulong res;
+} cpu_post_srawi_table[] =
+{
+ {
+ OP_SRAWI,
+ 0x8000,
+ 3,
+ 0x1000
+ },
+ {
+ OP_SRAWI,
+ 0x80000000,
+ 3,
+ 0xf0000000
+ },
+};
+static unsigned int cpu_post_srawi_size =
+ sizeof (cpu_post_srawi_table) / sizeof (struct cpu_post_srawi_s);
+
+int cpu_post_test_srawi (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_srawi_size && ret == 0; i++)
+ {
+ struct cpu_post_srawi_s *test = cpu_post_srawi_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11S(test->cmd, reg1, reg0, test->op2),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11S(test->cmd, reg1, reg0, test->op2) | BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op1);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at srawi test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_21 (codecr, & cr, & res, test->op1);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at srawi test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Store instructions: stb(x)(u), sth(x)(u), stw(x)(u)
+ *
+ * All operations are performed on a 16-byte array. The array
+ * is 4-byte aligned. The base register points to offset 8.
+ * The immediate offset (index register) ranges in [-8 ... +7].
+ * The test cases are composed so that they do not
+ * cause alignment exceptions.
+ * The test contains a pre-built table describing all test cases.
+ * The table entry contains:
+ * the instruction opcode, the value of the index register and
+ * the value of the source register. After executing the
+ * instruction, the test verifies the contents of the array
+ * and the value of the base register (it must change for "store
+ * with update" instructions).
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3);
+extern void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2);
+
+static struct cpu_post_store_s
+{
+ ulong cmd;
+ uint width;
+ int update;
+ int index;
+ ulong offset;
+ ulong value;
+} cpu_post_store_table[] =
+{
+ {
+ OP_STW,
+ 4,
+ 0,
+ 0,
+ -4,
+ 0xff00ff00
+ },
+ {
+ OP_STH,
+ 2,
+ 0,
+ 0,
+ -2,
+ 0xff00
+ },
+ {
+ OP_STB,
+ 1,
+ 0,
+ 0,
+ -1,
+ 0xff
+ },
+ {
+ OP_STWU,
+ 4,
+ 1,
+ 0,
+ -4,
+ 0xff00ff00
+ },
+ {
+ OP_STHU,
+ 2,
+ 1,
+ 0,
+ -2,
+ 0xff00
+ },
+ {
+ OP_STBU,
+ 1,
+ 1,
+ 0,
+ -1,
+ 0xff
+ },
+ {
+ OP_STWX,
+ 4,
+ 0,
+ 1,
+ -4,
+ 0xff00ff00
+ },
+ {
+ OP_STHX,
+ 2,
+ 0,
+ 1,
+ -2,
+ 0xff00
+ },
+ {
+ OP_STBX,
+ 1,
+ 0,
+ 1,
+ -1,
+ 0xff
+ },
+ {
+ OP_STWUX,
+ 4,
+ 1,
+ 1,
+ -4,
+ 0xff00ff00
+ },
+ {
+ OP_STHUX,
+ 2,
+ 1,
+ 1,
+ -2,
+ 0xff00
+ },
+ {
+ OP_STBUX,
+ 1,
+ 1,
+ 1,
+ -1,
+ 0xff
+ },
+};
+static unsigned int cpu_post_store_size =
+ sizeof (cpu_post_store_table) / sizeof (struct cpu_post_store_s);
+
+int cpu_post_test_store (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < cpu_post_store_size && ret == 0; i++)
+ {
+ struct cpu_post_store_s *test = cpu_post_store_table + i;
+ uchar data[16] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ ulong base0 = (ulong) (data + 8);
+ ulong base = base0;
+
+ if (test->index)
+ {
+ ulong code[] =
+ {
+ ASM_12(test->cmd, 5, 3, 4),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_12w (code, &base, test->offset, test->value);
+ }
+ else
+ {
+ ulong code[] =
+ {
+ ASM_11I(test->cmd, 4, 3, test->offset),
+ ASM_BLR,
+ };
+
+ cpu_post_exec_11w (code, &base, test->value);
+ }
+
+ if (ret == 0)
+ {
+ if (test->update)
+ ret = base == base0 + test->offset ? 0 : -1;
+ else
+ ret = base == base0 ? 0 : -1;
+ }
+
+ if (ret == 0)
+ {
+ switch (test->width)
+ {
+ case 1:
+ ret = *(uchar *)(base0 + test->offset) == test->value ?
+ 0 : -1;
+ break;
+ case 2:
+ ret = *(ushort *)(base0 + test->offset) == test->value ?
+ 0 : -1;
+ break;
+ case 4:
+ ret = *(ulong *)(base0 + test->offset) == test->value ?
+ 0 : -1;
+ break;
+ }
+ }
+
+ if (ret != 0)
+ {
+ post_log ("Error at store test %d !\n", i);
+ }
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Load/store string instructions: lswi, stswi, lswx, stswx
+ *
+ * Several consecutive bytes from a source memory buffer are loaded
+ * left to right into GPRs. After that, the bytes are stored
+ * from the GPRs into a target memory buffer. The contents
+ * of the source and target buffers are then compared.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2);
+extern void cpu_post_exec_04 (ulong *code, ulong op1, ulong op2, ulong op3,
+ ulong op4);
+
+#include <bedbug/regs.h>
+int cpu_post_test_string (void)
+{
+ int ret = 0;
+ unsigned int i;
+
+ if (ret == 0)
+ {
+ char src [31], dst [31];
+
+ ulong code[] =
+ {
+ ASM_LSWI(5, 3, 31),
+ ASM_STSWI(5, 4, 31),
+ ASM_BLR,
+ };
+
+ for (i = 0; i < sizeof(src); i ++)
+ {
+ src[i] = (char) i;
+ dst[i] = 0;
+ }
+
+ cpu_post_exec_02(code, (ulong)src, (ulong)dst);
+
+ ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
+ }
+
+ if (ret == 0)
+ {
+ char src [95], dst [95];
+
+ ulong code[] =
+ {
+ ASM_LSWX(8, 3, 5),
+ ASM_STSWX(8, 4, 5),
+ ASM_BLR,
+ };
+
+ for (i = 0; i < sizeof(src); i ++)
+ {
+ src[i] = (char) i;
+ dst[i] = 0;
+ }
+
+ cpu_post_exec_04(code, (ulong)src, (ulong)dst, 0, sizeof(src));
+
+ ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
+ }
+
+ if (ret != 0)
+ {
+ post_log ("Error at string test !\n");
+ }
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Ternary instructions instr rD,rA,rB
+ *
+ * Arithmetic instructions: add, addc, adde, subf, subfc, subfe,
+ * mullw, mulhw, mulhwu, divw, divwu
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_three_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ ulong res;
+} cpu_post_three_table[] =
+{
+ {
+ OP_ADD,
+ 100,
+ 200,
+ 300
+ },
+ {
+ OP_ADD,
+ 100,
+ -200,
+ -100
+ },
+ {
+ OP_ADDC,
+ 100,
+ 200,
+ 300
+ },
+ {
+ OP_ADDC,
+ 100,
+ -200,
+ -100
+ },
+ {
+ OP_ADDE,
+ 100,
+ 200,
+ 300
+ },
+ {
+ OP_ADDE,
+ 100,
+ -200,
+ -100
+ },
+ {
+ OP_SUBF,
+ 100,
+ 200,
+ 100
+ },
+ {
+ OP_SUBF,
+ 300,
+ 200,
+ -100
+ },
+ {
+ OP_SUBFC,
+ 100,
+ 200,
+ 100
+ },
+ {
+ OP_SUBFC,
+ 300,
+ 200,
+ -100
+ },
+ {
+ OP_SUBFE,
+ 100,
+ 200,
+ 200 + ~100
+ },
+ {
+ OP_SUBFE,
+ 300,
+ 200,
+ 200 + ~300
+ },
+ {
+ OP_MULLW,
+ 200,
+ 300,
+ 200 * 300
+ },
+ {
+ OP_MULHW,
+ 0x10000000,
+ 0x10000000,
+ 0x1000000
+ },
+ {
+ OP_MULHWU,
+ 0x80000000,
+ 0x80000000,
+ 0x40000000
+ },
+ {
+ OP_DIVW,
+ -20,
+ 5,
+ -4
+ },
+ {
+ OP_DIVWU,
+ 0x8000,
+ 0x200,
+ 0x40
+ },
+};
+static unsigned int cpu_post_three_size =
+ sizeof (cpu_post_three_table) / sizeof (struct cpu_post_three_s);
+
+int cpu_post_test_three (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_three_size && ret == 0; i++)
+ {
+ struct cpu_post_three_s *test = cpu_post_three_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int reg2 = (reg + 2) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12(test->cmd, reg2, reg1, reg0),
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12(test->cmd, reg2, reg1, reg0) | BIT_C,
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at three test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at three test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Ternary instructions instr rA,rS,UIMM
+ *
+ * Logic instructions: ori, oris, xori, xoris
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_threei_s
+{
+ ulong cmd;
+ ulong op1;
+ ushort op2;
+ ulong res;
+} cpu_post_threei_table[] =
+{
+ {
+ OP_ORI,
+ 0x80000000,
+ 0xffff,
+ 0x8000ffff
+ },
+ {
+ OP_ORIS,
+ 0x00008000,
+ 0xffff,
+ 0xffff8000
+ },
+ {
+ OP_XORI,
+ 0x8000ffff,
+ 0xffff,
+ 0x80000000
+ },
+ {
+ OP_XORIS,
+ 0x00008000,
+ 0xffff,
+ 0xffff8000
+ },
+};
+static unsigned int cpu_post_threei_size =
+ sizeof (cpu_post_threei_table) / sizeof (struct cpu_post_threei_s);
+
+int cpu_post_test_threei (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_threei_size && ret == 0; i++)
+ {
+ struct cpu_post_threei_s *test = cpu_post_threei_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11IX(test->cmd, reg1, reg0, test->op2),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op1);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at threei test %d !\n", i);
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Ternary instructions instr rA,rS,rB
+ *
+ * Logic instructions: or, orc, xor, nand, nor, eqv
+ * Shift instructions: slw, srw, sraw
+ *
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
+ ulong op2);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_threex_s
+{
+ ulong cmd;
+ ulong op1;
+ ulong op2;
+ ulong res;
+} cpu_post_threex_table[] =
+{
+ {
+ OP_OR,
+ 0x1234,
+ 0x5678,
+ 0x1234 | 0x5678
+ },
+ {
+ OP_ORC,
+ 0x1234,
+ 0x5678,
+ 0x1234 | ~0x5678
+ },
+ {
+ OP_XOR,
+ 0x1234,
+ 0x5678,
+ 0x1234 ^ 0x5678
+ },
+ {
+ OP_NAND,
+ 0x1234,
+ 0x5678,
+ ~(0x1234 & 0x5678)
+ },
+ {
+ OP_NOR,
+ 0x1234,
+ 0x5678,
+ ~(0x1234 | 0x5678)
+ },
+ {
+ OP_EQV,
+ 0x1234,
+ 0x5678,
+ ~(0x1234 ^ 0x5678)
+ },
+ {
+ OP_SLW,
+ 0x80,
+ 16,
+ 0x800000
+ },
+ {
+ OP_SLW,
+ 0x80,
+ 32,
+ 0
+ },
+ {
+ OP_SRW,
+ 0x800000,
+ 16,
+ 0x80
+ },
+ {
+ OP_SRW,
+ 0x800000,
+ 32,
+ 0
+ },
+ {
+ OP_SRAW,
+ 0x80000000,
+ 3,
+ 0xf0000000
+ },
+ {
+ OP_SRAW,
+ 0x8000,
+ 3,
+ 0x1000
+ },
+};
+static unsigned int cpu_post_threex_size =
+ sizeof (cpu_post_threex_table) / sizeof (struct cpu_post_threex_s);
+
+int cpu_post_test_threex (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_threex_size && ret == 0; i++)
+ {
+ struct cpu_post_threex_s *test = cpu_post_threex_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int reg2 = (reg + 2) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12X(test->cmd, reg2, reg1, reg0),
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -24),
+ ASM_STW(3, stk, 12),
+ ASM_STW(4, stk, 16),
+ ASM_STW(reg0, stk, 8),
+ ASM_STW(reg1, stk, 4),
+ ASM_STW(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 12),
+ ASM_LWZ(reg0, stk, 16),
+ ASM_12X(test->cmd, reg2, reg1, reg0) | BIT_C,
+ ASM_STW(reg2, stk, 12),
+ ASM_LWZ(reg2, stk, 0),
+ ASM_LWZ(reg1, stk, 4),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_LWZ(3, stk, 12),
+ ASM_ADDI(1, stk, 24),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at threex test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at threex test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Binary instructions instr rD,rA
+ *
+ * Logic instructions: neg
+ * Arithmetic instructions: addme, addze, subfme, subfze
+
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_two_s
+{
+ ulong cmd;
+ ulong op;
+ ulong res;
+} cpu_post_two_table[] =
+{
+ {
+ OP_NEG,
+ 3,
+ -3
+ },
+ {
+ OP_NEG,
+ 5,
+ -5
+ },
+ {
+ OP_ADDME,
+ 6,
+ 5
+ },
+ {
+ OP_ADDZE,
+ 5,
+ 5
+ },
+ {
+ OP_SUBFME,
+ 6,
+ ~6 - 1
+ },
+ {
+ OP_SUBFZE,
+ 5,
+ ~5
+ },
+};
+static unsigned int cpu_post_two_size =
+ sizeof (cpu_post_two_table) / sizeof (struct cpu_post_two_s);
+
+int cpu_post_test_two (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_two_size && ret == 0; i++)
+ {
+ struct cpu_post_two_s *test = cpu_post_two_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11(test->cmd, reg1, reg0),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11(test->cmd, reg1, reg0) | BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at two test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_21 (codecr, & cr, & res, test->op);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at two test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * CPU test
+ * Binary instructions instr rA,rS
+ *
+ * Logic instructions: cntlzw
+ * Arithmetic instructions: extsb, extsh
+
+ * The test contains a pre-built table of instructions, operands and
+ * expected results. For each table entry, the test will cyclically use
+ * different sets of operand registers and result registers.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include "cpu_asm.h"
+
+#if CONFIG_POST & CFG_POST_CPU
+
+extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
+extern ulong cpu_post_makecr (long v);
+
+static struct cpu_post_twox_s
+{
+ ulong cmd;
+ ulong op;
+ ulong res;
+} cpu_post_twox_table[] =
+{
+ {
+ OP_EXTSB,
+ 3,
+ 3
+ },
+ {
+ OP_EXTSB,
+ 0xff,
+ -1
+ },
+ {
+ OP_EXTSH,
+ 3,
+ 3
+ },
+ {
+ OP_EXTSH,
+ 0xff,
+ 0xff
+ },
+ {
+ OP_EXTSH,
+ 0xffff,
+ -1
+ },
+ {
+ OP_CNTLZW,
+ 0x000fffff,
+ 12
+ },
+};
+static unsigned int cpu_post_twox_size =
+ sizeof (cpu_post_twox_table) / sizeof (struct cpu_post_twox_s);
+
+int cpu_post_test_twox (void)
+{
+ int ret = 0;
+ unsigned int i, reg;
+ int flag = disable_interrupts();
+
+ for (i = 0; i < cpu_post_twox_size && ret == 0; i++)
+ {
+ struct cpu_post_twox_s *test = cpu_post_twox_table + i;
+
+ for (reg = 0; reg < 32 && ret == 0; reg++)
+ {
+ unsigned int reg0 = (reg + 0) % 32;
+ unsigned int reg1 = (reg + 1) % 32;
+ unsigned int stk = reg < 16 ? 31 : 15;
+ unsigned long code[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11X(test->cmd, reg1, reg0),
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ unsigned long codecr[] =
+ {
+ ASM_STW(stk, 1, -4),
+ ASM_ADDI(stk, 1, -16),
+ ASM_STW(3, stk, 8),
+ ASM_STW(reg0, stk, 4),
+ ASM_STW(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 8),
+ ASM_11X(test->cmd, reg1, reg0) | BIT_C,
+ ASM_STW(reg1, stk, 8),
+ ASM_LWZ(reg1, stk, 0),
+ ASM_LWZ(reg0, stk, 4),
+ ASM_LWZ(3, stk, 8),
+ ASM_ADDI(1, stk, 16),
+ ASM_LWZ(stk, 1, -4),
+ ASM_BLR,
+ };
+ ulong res;
+ ulong cr;
+
+ if (ret == 0)
+ {
+ cr = 0;
+ cpu_post_exec_21 (code, & cr, & res, test->op);
+
+ ret = res == test->res && cr == 0 ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at twox test %d !\n", i);
+ }
+ }
+
+ if (ret == 0)
+ {
+ cpu_post_exec_21 (codecr, & cr, & res, test->op);
+
+ ret = res == test->res &&
+ (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
+
+ if (ret != 0)
+ {
+ post_log ("Error at twox test %d !\n", i);
+ }
+ }
+ }
+ }
+
+ if (flag)
+ enable_interrupts();
+
+ return ret;
+}
+
+#endif
+#endif
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * Ethernet test
+ *
+ * The Serial Communication Controllers (SCC) listed in ctlr_list array below
+ * are tested in the loopback ethernet mode.
+ * The controllers are configured accordingly and several packets
+ * are transmitted. The configurable test parameters are:
+ * MIN_PACKET_LENGTH - minimum size of packet to transmit
+ * MAX_PACKET_LENGTH - maximum size of packet to transmit
+ * TEST_NUM - number of tests
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <commproc.h>
+#include <command.h>
+#include <net.h>
+
+#if CONFIG_POST & CFG_POST_ETHER
+
+#define MIN_PACKET_LENGTH 64
+#define MAX_PACKET_LENGTH 256
+#define TEST_NUM 1
+
+#define CTLR_SCC 0
+
+extern void spi_init_f (void);
+extern void spi_init_r (void);
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] = { {CTLR_SCC, 1} };
+#else
+static int ctlr_list[][2] = { };
+#endif
+
+#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
+
+static struct {
+ void (*init) (int index);
+ int (*send) (int index, volatile void *packet, int length);
+ int (*recv) (int index, void *packet, int length);
+} ctlr_proc[1];
+
+static char *ctlr_name[1] = { "SCC" };
+
+static int used_by_uart[1] = { -1 };
+static int used_by_ether[1] = { -1 };
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH 1520
+
+#define TX_BUF_CNT 2
+
+#define TOUT_LOOP 100
+
+static char txbuf[DBUF_LENGTH];
+
+static uint rxIdx; /* index of the current RX buffer */
+static uint txIdx; /* index of the current TX buffer */
+
+/*
+ * SCC Ethernet Tx and Rx buffer descriptors allocated at the
+ * immr->udata_bd address on Dual-Port RAM
+ * Provide for Double Buffering
+ */
+
+typedef volatile struct CommonBufferDescriptor {
+ cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
+ cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
+} RTXBD;
+
+static RTXBD *rtx;
+
+ /*
+ * SCC callbacks
+ */
+
+static void scc_init (int scc_index)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ bd_t *bd = gd->bd;
+
+ static int proff[] =
+ { PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+ static unsigned int cpm_cr[] =
+ { CPM_CR_CH_SCC1, CPM_CR_CH_SCC2, CPM_CR_CH_SCC3,
+CPM_CR_CH_SCC4 };
+
+ int i;
+ scc_enet_t *pram_ptr;
+
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
+ ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+#if defined(CONFIG_FADS)
+#if defined(CONFIG_MPC860T)
+ /* The FADS860T doesn't use the MODEM_EN or DATA_VOICE signals. */
+ *((uint *) BCSR4) &= ~BCSR4_ETHLOOP;
+ *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL;
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#else
+ *((uint *) BCSR4) &= ~(BCSR4_ETHLOOP | BCSR4_MODEM_EN);
+ *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL | BCSR4_DATA_VOICE;
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif
+#endif
+
+ pram_ptr = (scc_enet_t *) & (immr->im_cpm.cp_dparam[proff[scc_index]]);
+
+ rxIdx = 0;
+ txIdx = 0;
+
+#ifdef CFG_ALLOC_DPRAM
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
+ dpram_alloc_align (sizeof (RTXBD), 8));
+#else
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_SCC_BASE);
+#endif /* 0 */
+
+#if 0
+
+#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
+ /* Configure port A pins for Txd and Rxd.
+ */
+ immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+ immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+ immr->im_ioport.iop_paodr &= ~PA_ENET_TXD;
+#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
+ /* Configure port B pins for Txd and Rxd.
+ */
+ immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
+ immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
+ immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
+#else
+#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
+#endif
+
+#if defined(PC_ENET_LBK)
+ /* Configure port C pins to disable External Loopback
+ */
+ immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
+ immr->im_ioport.iop_pcdir |= PC_ENET_LBK;
+ immr->im_ioport.iop_pcso &= ~PC_ENET_LBK;
+ immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
+#endif /* PC_ENET_LBK */
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+ immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+ immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+
+#endif /* 0 */
+
+#if 1
+ /* Configure port A for TCLK and RCLK.
+ */
+ immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+ immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+#endif /* 1 */
+
+ /*
+ * Configure Serial Interface clock routing -- see section 16.7.5.3
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+
+ immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK;
+ immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT;
+
+
+ /*
+ * Initialize SDCR -- see section 16.9.23.7
+ * SDMA configuration register
+ */
+ immr->im_siu_conf.sc_sdcr = 0x01;
+
+
+ /*
+ * Setup SCC Ethernet Parameter RAM
+ */
+
+ pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
+ pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
+
+ pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
+
+ pram_ptr->sen_genscc.scc_rbase = (unsigned int) (&rtx->rxbd[0]); /* Set RXBD tbl start at Dual Port */
+ pram_ptr->sen_genscc.scc_tbase = (unsigned int) (&rtx->txbd[0]); /* Set TXBD tbl start at Dual Port */
+
+ /*
+ * Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings:
+ * Empty, Wrap
+ */
+
+ for (i = 0; i < PKTBUFSRX; i++) {
+ rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+ rtx->rxbd[i].cbd_datlen = 0; /* Reset */
+ rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ }
+
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /*
+ * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings:
+ * Add PADs to Short FRAMES, Wrap, Last, Tx CRC
+ */
+
+ for (i = 0; i < TX_BUF_CNT; i++) {
+ rtx->txbd[i].cbd_sc =
+ (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+ rtx->txbd[i].cbd_datlen = 0; /* Reset */
+ rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
+ }
+
+ rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+ /*
+ * Enter Command: Initialize Rx Params for SCC
+ */
+
+ do { /* Spin until ready to issue command */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+ /* Issue command */
+ immr->im_cpm.cp_cpcr =
+ ((CPM_CR_INIT_RX << 8) | (cpm_cr[scc_index] << 4) |
+ CPM_CR_FLG);
+ do { /* Spin until command processed */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+ /*
+ * Ethernet Specific Parameter RAM
+ * see table 13-16, pg. 660,
+ * pg. 681 (example with suggested settings)
+ */
+
+ pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */
+ pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */
+ pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */
+ pram_ptr->sen_alec = 0x0; /* Alignment Error Counter (unused) */
+ pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */
+ pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */
+
+ pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */
+ pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */
+ pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */
+
+ pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */
+ pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */
+
+ pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */
+ pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */
+ pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
+ pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
+
+#define ea bd->bi_enetaddr
+ pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
+ pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
+ pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
+#undef ea
+
+ pram_ptr->sen_pper = 0x0; /* Persistence (unused) */
+ pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */
+ pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */
+ pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */
+ pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */
+ pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */
+ pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
+ pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
+
+ /*
+ * Enter Command: Initialize Tx Params for SCC
+ */
+
+ do { /* Spin until ready to issue command */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+ /* Issue command */
+ immr->im_cpm.cp_cpcr =
+ ((CPM_CR_INIT_TX << 8) | (cpm_cr[scc_index] << 4) |
+ CPM_CR_FLG);
+ do { /* Spin until command processed */
+ __asm__ ("eieio");
+ } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
+
+ /*
+ * Mask all Events in SCCM - we use polling mode
+ */
+ immr->im_cpm.cp_scc[scc_index].scc_sccm = 0;
+
+ /*
+ * Clear Events in SCCE -- Clear bits by writing 1's
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_scce = ~(0x0);
+
+
+ /*
+ * Initialize GSMR High 32-Bits
+ * Settings: Normal Mode
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrh = 0;
+
+ /*
+ * Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive
+ * Settings:
+ * TCI = Invert
+ * TPL = 48 bits
+ * TPP = Repeating 10's
+ * LOOP = Loopback
+ * MODE = Ethernet
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl = (SCC_GSMRL_TCI |
+ SCC_GSMRL_TPL_48 |
+ SCC_GSMRL_TPP_10 |
+ SCC_GSMRL_DIAG_LOOP |
+ SCC_GSMRL_MODE_ENET);
+
+ /*
+ * Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_dsr = 0xd555;
+
+ /*
+ * Initialize the PSMR
+ * Settings:
+ * CRC = 32-Bit CCITT
+ * NIB = Begin searching for SFD 22 bits after RENA
+ * LPB = Loopback Enable (Needed when FDE is set)
+ */
+ immr->im_cpm.cp_scc[scc_index].scc_psmr = SCC_PSMR_ENCRC |
+ SCC_PSMR_NIB22 | SCC_PSMR_LPB;
+
+#if 1
+
+ /*
+ * Configure Ethernet TENA Signal
+ */
+
+#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
+ immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
+ immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
+#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
+ immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
+ immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
+#else
+#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
+#endif
+
+#endif /* 1 */
+
+#if 0
+
+#if defined(CONFIG_ADS) && defined(CONFIG_MPC860)
+ /*
+ * Port C is used to control the PHY,MC68160.
+ */
+ immr->im_ioport.iop_pcdir |=
+ (PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL);
+
+ immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL;
+ immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL);
+ *((uint *) BCSR1) &= ~BCSR1_ETHEN;
+#endif /* MPC860ADS */
+
+#if defined(CONFIG_AMX860)
+ /*
+ * Port B is used to control the PHY,MC68160.
+ */
+ immr->im_cpm.cp_pbdir |=
+ (PB_ENET_ETHLOOP | PB_ENET_TPFLDL | PB_ENET_TPSQEL);
+
+ immr->im_cpm.cp_pbdat |= PB_ENET_TPFLDL;
+ immr->im_cpm.cp_pbdat &= ~(PB_ENET_ETHLOOP | PB_ENET_TPSQEL);
+
+ immr->im_ioport.iop_pddir |= PD_ENET_ETH_EN;
+ immr->im_ioport.iop_pddat &= ~PD_ENET_ETH_EN;
+#endif /* AMX860 */
+
+#endif /* 0 */
+
+#ifdef CONFIG_RPXCLASSIC
+ *((uchar *) BCSR0) &= ~BCSR0_ETHLPBK;
+ *((uchar *) BCSR0) |= (BCSR0_ETHEN | BCSR0_COLTEST | BCSR0_FULLDPLX);
+#endif
+
+#ifdef CONFIG_RPXLITE
+ *((uchar *) BCSR0) |= BCSR0_ETHEN;
+#endif
+
+#ifdef CONFIG_MBX
+ board_ether_init ();
+#endif
+
+ /*
+ * Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive
+ */
+
+ immr->im_cpm.cp_scc[scc_index].scc_gsmrl |=
+ (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ /*
+ * Work around transmit problem with first eth packet
+ */
+#if defined (CONFIG_FADS)
+ udelay (10000); /* wait 10 ms */
+#elif defined (CONFIG_AMX860) || defined(CONFIG_RPXCLASSIC)
+ udelay (100000); /* wait 100 ms */
+#endif
+}
+
+static int scc_send (int index, volatile void *packet, int length)
+{
+ int i, j = 0;
+
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+ udelay (1); /* will also trigger Wd if needed */
+ j++;
+ }
+ if (j >= TOUT_LOOP)
+ printf ("TX not ready\n");
+ rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
+ rtx->txbd[txIdx].cbd_datlen = length;
+ rtx->txbd[txIdx].cbd_sc |=
+ (BD_ENET_TX_READY | BD_ENET_TX_LAST | BD_ENET_TX_WRAP);
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
+ udelay (1); /* will also trigger Wd if needed */
+ j++;
+ }
+ if (j >= TOUT_LOOP)
+ printf ("TX timeout\n");
+ i = (rtx->txbd[txIdx].
+ cbd_sc & BD_ENET_TX_STATS) /* return only status bits */ ;
+ return i;
+}
+
+static int scc_recv (int index, void *packet, int max_length)
+{
+ int length = -1;
+
+ if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+ goto Done; /* nothing received */
+ }
+
+ if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) {
+ length = rtx->rxbd[rxIdx].cbd_datlen - 4;
+ memcpy (packet,
+ (void *) (NetRxPackets[rxIdx]),
+ length < max_length ? length : max_length);
+ }
+
+ /* Give the buffer back to the SCC. */
+ rtx->rxbd[rxIdx].cbd_datlen = 0;
+
+ /* wrap around buffer index when necessary */
+ if ((rxIdx + 1) >= PKTBUFSRX) {
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
+ (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+ rxIdx = 0;
+ } else {
+ rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+ rxIdx++;
+ }
+
+ Done:
+ return length;
+}
+
+ /*
+ * Test routines
+ */
+
+static void packet_fill (char *packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ packet[0] = 0xFF;
+ packet[1] = 0xFF;
+ packet[2] = 0xFF;
+ packet[3] = 0xFF;
+ packet[4] = 0xFF;
+ packet[5] = 0xFF;
+
+ for (i = 6; i < length; i++) {
+ packet[i] = c++;
+ }
+}
+
+static int packet_check (char *packet, int length)
+{
+ char c = (char) length;
+ int i;
+
+ for (i = 6; i < length; i++) {
+ if (packet[i] != c++)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int test_ctlr (int ctlr, int index)
+{
+ int res = -1;
+ char packet_send[MAX_PACKET_LENGTH];
+ char packet_recv[MAX_PACKET_LENGTH];
+ int length;
+ int i;
+ int l;
+
+ ctlr_proc[ctlr].init (index);
+
+ for (i = 0; i < TEST_NUM; i++) {
+ for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) {
+ packet_fill (packet_send, l);
+
+ ctlr_proc[ctlr].send (index, packet_send, l);
+
+ length = ctlr_proc[ctlr].recv (index, packet_recv,
+ MAX_PACKET_LENGTH);
+
+ if (length != l || packet_check (packet_recv, length) < 0) {
+ goto Done;
+ }
+ }
+ }
+
+ res = 0;
+
+ Done:
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+ if (used_by_uart[ctlr] == index) {
+ serial_init ();
+ }
+#endif
+
+#if defined(SCC_ENET)
+ if (used_by_ether[ctlr] == index) {
+ DECLARE_GLOBAL_DATA_PTR;
+
+ eth_init (gd->bd);
+ }
+#endif
+
+ /*
+ * SCC2 Ethernet parameter RAM space overlaps
+ * the SPI parameter RAM space. So we need to restore
+ * the SPI configuration after SCC2 ethernet test.
+ */
+#if defined(CONFIG_SPI)
+ if (ctlr == CTLR_SCC && index == 1) {
+ spi_init_f ();
+ spi_init_r ();
+ }
+#endif
+
+ if (res != 0) {
+ post_log ("ethernet %s%d test failed\n", ctlr_name[ctlr],
+ index + 1);
+ }
+
+ return res;
+}
+
+int ether_post_test (int flags)
+{
+ int res = 0;
+ int i;
+
+#if defined(CONFIG_8xx_CONS_SCC1)
+ used_by_uart[CTLR_SCC] = 0;
+#elif defined(CONFIG_8xx_CONS_SCC2)
+ used_by_uart[CTLR_SCC] = 1;
+#elif defined(CONFIG_8xx_CONS_SCC3)
+ used_by_uart[CTLR_SCC] = 2;
+#elif defined(CONFIG_8xx_CONS_SCC4)
+ used_by_uart[CTLR_SCC] = 3;
+#endif
+
+#if defined(SCC_ENET)
+ used_by_ether[CTLR_SCC] = SCC_ENET;
+#endif
+
+ ctlr_proc[CTLR_SCC].init = scc_init;
+ ctlr_proc[CTLR_SCC].send = scc_send;
+ ctlr_proc[CTLR_SCC].recv = scc_recv;
+
+ for (i = 0; i < CTRL_LIST_SIZE; i++) {
+ if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+ res = -1;
+ }
+ }
+
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_ETHER */
+
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+#ifdef CONFIG_POST
+
+/*
+ * I2C test
+ *
+ * For verifying the I2C bus, a full I2C bus scanning is performed.
+ * If any I2C device is found, the test is considered as passed,
+ * otherwise failed.
+ */
+
+#include <post.h>
+#include <i2c.h>
+
+#if CONFIG_POST & CFG_POST_I2C
+
+int i2c_post_test (bd_t * bd, int flags)
+{
+ unsigned int i;
+ unsigned int chips = 0;
+
+ for (i = 0; i < 128; i++) {
+ if (i2c_probe (i) == 0)
+ chips++;
+ }
+
+ return chips > 0 ? 0 : -1;
+}
+
+#endif /* CONFIG_POST & CFG_POST_I2C */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/* Memory test
+ *
+ * The memory test verifies RAM using sequential writes and reads
+ * to/from RAM. There are several test cases that use different patterns to
+ * verify RAM. Each test case fills a region of RAM with one pattern and
+ * then reads the region back and compares its contents with the pattern.
+ * The following patterns are used:
+ *
+ * 1a) zero pattern (0x00000000)
+ * 1b) negative pattern (0xffffffff)
+ * 1c) checkerboard pattern (0x55555555)
+ * 1d) checkerboard pattern (0xaaaaaaaa)
+ * 2) bit-flip pattern ((1 << (offset % 32))
+ * 3) address pattern (offset)
+ * 4) address pattern (~offset)
+ *
+ * Being run in normal mode, the test verifies only small 4Kb
+ * regions of RAM around each 1Mb boundary. For example, for 64Mb
+ * RAM the following areas are verified: 0x00000000-0x00000800,
+ * 0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800-
+ * 0x04000000. If the test is run in power-fail mode, it verifies
+ * the whole RAM.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_MEMORY
+
+static int memory_post_test1 (unsigned long start,
+ unsigned long size,
+ unsigned long val)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = val;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ if (mem[i] != val) {
+ post_log ("Memory error at %08x, "
+ "written %08x, read %08x !\n",
+ mem + i, val, mem[i]);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_test2 (unsigned long start, unsigned long size)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = 1 << (i % 32);
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ if (mem[i] != (1 << (i % 32))) {
+ post_log ("Memory error at %08x, "
+ "written %08x, read %08x !\n",
+ mem + i, 1 << (i % 32), mem[i]);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_test3 (unsigned long start, unsigned long size)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ if (mem[i] != i) {
+ post_log ("Memory error at %08x, "
+ "written %08x, read %08x !\n",
+ mem + i, i, mem[i]);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_test4 (unsigned long start, unsigned long size)
+{
+ unsigned long i;
+ ulong *mem = (ulong *) start;
+ int ret = 0;
+
+ for (i = 0; i < size / sizeof (ulong); i++) {
+ mem[i] = ~i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
+ if (mem[i] != ~i) {
+ post_log ("Memory error at %08x, "
+ "written %08x, read %08x !\n",
+ mem + i, ~i, mem[i]);
+
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET ();
+ }
+
+ return ret;
+}
+
+static int memory_post_tests (unsigned long start, unsigned long size)
+{
+ int ret = 0;
+
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0x00000000);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0xffffffff);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0x55555555);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test1 (start, size, 0xaaaaaaaa);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test2 (start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test3 (start, size);
+ WATCHDOG_RESET ();
+ if (ret == 0)
+ ret = memory_post_test4 (start, size);
+ WATCHDOG_RESET ();
+
+ return ret;
+}
+
+int memory_post_test (bd_t * bd, int flags)
+{
+ int ret = 0;
+ unsigned long memsize = (bd->bi_memsize >= 256 << 20 ?
+ 256 << 20 : bd->bi_memsize) - (1 << 20);
+
+
+ if (flags & POST_POWERFAIL) {
+ ret = memory_post_tests (CFG_SDRAM_BASE, memsize);
+ } else { /* POST_POWERNORMAL */
+
+ unsigned long i;
+
+ for (i = 0; i < (memsize >> 20) && ret == 0; i++) {
+ if (ret == 0)
+ ret = memory_post_tests (i << 20, 0x800);
+ if (ret == 0)
+ ret = memory_post_tests ((i << 20) + 0xff800, 0x800);
+ }
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_POST & CFG_POST_MEMORY */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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 <console.h>
+#include <watchdog.h>
+#include <post.h>
+
+#ifdef CONFIG_POST
+
+#define POST_MAX_NUMBER 32
+
+#define BOOTMODE_MAGIC 0xDEAD0000
+
+void post_bootmode_init (void)
+{
+ int bootmode = post_bootmode_get (0);
+
+ if (bootmode == 0) {
+ bootmode = POST_POWERON;
+ } else if (bootmode == POST_POWERON) {
+ bootmode = POST_POWERNORMAL;
+ } else {
+ return;
+ }
+
+ post_word_store (BOOTMODE_MAGIC | bootmode);
+}
+
+int post_bootmode_get (unsigned int *last_test)
+{
+ unsigned long word = post_word_load ();
+ int bootmode;
+
+ if ((word & 0xFFFF0000) != BOOTMODE_MAGIC) {
+ return 0;
+ }
+
+ bootmode = word & 0xFF;
+
+ if (last_test && (bootmode & POST_POWERTEST)) {
+ *last_test = (word >> 8) & 0xFF;
+ }
+
+ return bootmode;
+}
+
+void post_bootmode_clear (void)
+{
+ post_word_store (0);
+}
+
+static void post_bootmode_test_on (unsigned int last_test)
+{
+ unsigned long word = post_word_load ();
+
+ word |= POST_POWERTEST;
+
+ word |= (last_test & 0xFF) << 8;
+
+ post_word_store (word);
+}
+
+static void post_bootmode_test_off (void)
+{
+ unsigned long word = post_word_load ();
+
+ word &= ~POST_POWERTEST;
+
+ post_word_store (word);
+}
+
+static void post_get_flags (int *test_flags)
+{
+ int flag[] = { POST_POWERON, POST_POWERNORMAL, POST_POWERFAIL };
+ char *var[] = { "post_poweron", "post_normal", "post_shutdown" };
+ int varnum = sizeof (var) / sizeof (var[0]);
+ char list[128]; /* long enough for POST list */
+ char *name;
+ char *s;
+ int last;
+ int i, j;
+
+ for (j = 0; j < post_list_size; j++) {
+ test_flags[j] = post_list[j].flags;
+ }
+
+ for (i = 0; i < varnum; i++) {
+ if (getenv_r (var[i], list, sizeof (list)) <= 0)
+ continue;
+
+ for (j = 0; j < post_list_size; j++) {
+ test_flags[j] &= ~flag[i];
+ }
+
+ last = 0;
+ name = list;
+ while (!last) {
+ while (*name && *name == ' ')
+ name++;
+ if (*name == 0)
+ break;
+ s = name + 1;
+ while (*s && *s != ' ')
+ s++;
+ if (*s == 0)
+ last = 1;
+ else
+ *s = 0;
+
+ for (j = 0; j < post_list_size; j++) {
+ if (strcmp (post_list[j].cmd, name) == 0) {
+ test_flags[j] |= flag[i];
+ break;
+ }
+ }
+
+ if (j == post_list_size) {
+ printf ("No such test: %s\n", name);
+ }
+
+ name = s + 1;
+ }
+ }
+}
+
+static int post_run_single (struct post_test *test,
+ int test_flags, int flags, unsigned int i)
+{
+ if ((flags & test_flags & POST_ALWAYS) &&
+ (flags & test_flags & POST_MEM)) {
+ WATCHDOG_RESET ();
+
+ if (!(flags & POST_REBOOT)) {
+ if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL)) {
+ post_bootmode_test_on (i);
+ }
+
+ post_log ("START %s\n", test->cmd);
+ }
+
+ if ((*test->test) (flags) != 0)
+ post_log ("FAILED\n");
+ else
+ post_log ("PASSED\n");
+
+ if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL)) {
+ post_bootmode_test_off ();
+ }
+
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int post_run (char *name, int flags)
+{
+ unsigned int i;
+ int test_flags[POST_MAX_NUMBER];
+
+ post_get_flags (test_flags);
+
+ if (name == NULL) {
+ unsigned int last;
+
+ if (post_bootmode_get (&last) & POST_POWERTEST) {
+ if (last < post_list_size &&
+ (flags & test_flags[last] & POST_ALWAYS) &&
+ (flags & test_flags[last] & POST_MEM)) {
+
+ post_run_single (post_list + last, test_flags[last],
+ flags | POST_REBOOT, last);
+
+ for (i = last + 1; i < post_list_size; i++) {
+ post_run_single (post_list + i, test_flags[i],
+ flags, i);
+ }
+ }
+ } else {
+ for (i = 0; i < post_list_size; i++) {
+ post_run_single (post_list + i, test_flags[i], flags,
+ i);
+ }
+ }
+
+ return 0;
+ } else {
+ for (i = 0; i < post_list_size; i++) {
+ if (strcmp (post_list[i].cmd, name) == 0)
+ break;
+ }
+
+ if (i < post_list_size) {
+ return post_run_single (post_list + i,
+ test_flags[i],
+ flags, i);
+ } else {
+ return -1;
+ }
+ }
+}
+
+static int post_info_single (struct post_test *test, int full)
+{
+ if (test->flags & POST_MANUAL) {
+ if (full)
+ printf ("%s - %s\n"
+ " %s\n", test->cmd, test->name, test->desc);
+ else
+ printf (" %-15s - %s\n", test->cmd, test->name);
+
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int post_info (char *name)
+{
+ unsigned int i;
+
+ if (name == NULL) {
+ for (i = 0; i < post_list_size; i++) {
+ post_info_single (post_list + i, 0);
+ }
+
+ return 0;
+ } else {
+ for (i = 0; i < post_list_size; i++) {
+ if (strcmp (post_list[i].cmd, name) == 0)
+ break;
+ }
+
+ if (i < post_list_size) {
+ return post_info_single (post_list + i, 1);
+ } else {
+ return -1;
+ }
+ }
+}
+
+int post_log (char *format, ...)
+{
+ va_list args;
+ uint i;
+ char printbuffer[CFG_PBSIZE];
+
+ va_start (args, format);
+
+ /* For this to work, printbuffer must be larger than
+ * anything we ever want to print.
+ */
+ i = vsprintf (printbuffer, format, args);
+ va_end (args);
+
+ /* Send to the stdout file */
+ puts (printbuffer);
+
+ return 0;
+}
+
+void post_reloc (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ unsigned int i;
+
+ /*
+ * We have to relocate the test table manually
+ */
+ for (i = 0; i < post_list_size; i++) {
+ ulong addr;
+ struct post_test *test = post_list + i;
+
+ if (test->name) {
+ addr = (ulong) (test->name) + gd->reloc_off;
+ test->name = (char *) addr;
+ }
+
+ if (test->cmd) {
+ addr = (ulong) (test->cmd) + gd->reloc_off;
+ test->cmd = (char *) addr;
+ }
+
+ if (test->desc) {
+ addr = (ulong) (test->desc) + gd->reloc_off;
+ test->desc = (char *) addr;
+ }
+
+ if (test->test) {
+ addr = (ulong) (test->test) + gd->reloc_off;
+ test->test = (int (*)(int flags)) addr;
+ }
+ }
+}
+
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * RTC test
+ *
+ * The Real Time Clock (RTC) operation is verified by this test.
+ * The following features are verified:
+ * o) Time uniformity
+ * This is verified by reading RTC in polling within
+ * a short period of time.
+ * o) Passing month boundaries
+ * This is checked by setting RTC to a second before
+ * a month boundary and reading it after its passing the
+ * boundary. The test is performed for both leap- and
+ * nonleap-years.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <rtc.h>
+
+#if CONFIG_POST & CFG_POST_RTC
+
+static int rtc_post_skip (ulong * diff)
+{
+ struct rtc_time tm1;
+ struct rtc_time tm2;
+ ulong start1;
+ ulong start2;
+
+ rtc_get (&tm1);
+ start1 = get_timer (0);
+
+ while (1) {
+ rtc_get (&tm2);
+ start2 = get_timer (0);
+ if (tm1.tm_sec != tm2.tm_sec)
+ break;
+ if (start2 - start1 > 1500)
+ break;
+ }
+
+ if (tm1.tm_sec != tm2.tm_sec) {
+ *diff = start2 - start1;
+
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static void rtc_post_restore (struct rtc_time *tm, unsigned int sec)
+{
+ time_t t = mktime (tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
+ tm->tm_min, tm->tm_sec) + sec;
+ struct rtc_time ntm;
+
+ to_tm (t, &ntm);
+
+ rtc_set (&ntm);
+}
+
+int rtc_post_test (bd_t * bd, int flags)
+{
+ ulong diff;
+ unsigned int i;
+ struct rtc_time svtm;
+ static unsigned int daysnl[] =
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ static unsigned int daysl[] =
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ unsigned int ynl = 1999;
+ unsigned int yl = 2000;
+ unsigned int skipped = 0;
+
+ /* Time uniformity */
+ if (rtc_post_skip (&diff) != 0) {
+ post_log ("Timeout while waiting for a new second !\n");
+
+ return -1;
+ }
+
+ for (i = 0; i < 5; i++) {
+ if (rtc_post_skip (&diff) != 0) {
+ post_log ("Timeout while waiting for a new second !\n");
+
+ return -1;
+ }
+
+ if (diff < 950 || diff > 1050) {
+ post_log ("Invalid second duration !\n");
+
+ return -1;
+ }
+ }
+
+ /* Passing month boundaries */
+
+ if (rtc_post_skip (&diff) != 0) {
+ post_log ("Timeout while waiting for a new second !\n");
+
+ return -1;
+ }
+ rtc_get (&svtm);
+
+ for (i = 0; i < 12; i++) {
+ time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59);
+ struct rtc_time tm;
+
+ to_tm (t, &tm);
+ rtc_set (&tm);
+
+ skipped++;
+ if (rtc_post_skip (&diff) != 0) {
+ rtc_post_restore (&svtm, skipped);
+ post_log ("Timeout while waiting for a new second !\n");
+
+ return -1;
+ }
+
+ rtc_get (&tm);
+ if (tm.tm_mon == i + 1) {
+ rtc_post_restore (&svtm, skipped);
+ post_log ("Month %d boundary is not passed !\n", i + 1);
+
+ return -1;
+ }
+ }
+
+ for (i = 0; i < 12; i++) {
+ time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59);
+ struct rtc_time tm;
+
+ to_tm (t, &tm);
+ rtc_set (&tm);
+
+ skipped++;
+ if (rtc_post_skip (&diff) != 0) {
+ rtc_post_restore (&svtm, skipped);
+ post_log ("Timeout while waiting for a new second !\n");
+
+ return -1;
+ }
+
+ rtc_get (&tm);
+ if (tm.tm_mon == i + 1) {
+ rtc_post_restore (&svtm, skipped);
+ post_log ("Month %d boundary is not passed !\n", i + 1);
+
+ return -1;
+ }
+ }
+ rtc_post_restore (&svtm, skipped);
+
+ return 0;
+}
+
+#endif /* CONFIG_POST & CFG_POST_RTC */
+#endif /* CONFIG_POST */
--- /dev/null
+#
+# (C) Copyright 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 $(TOPDIR)/config.mk
+
+OBJS = $(AOBJS) $(COBJS)
+
+CPPFLAGS += -I$(TOPDIR)
+
+all: $(LIB)
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(AOBJS:.o=.S) $(COBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(AOBJS:.o=.S) $(COBJS:.o=.c) > .depend
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * SPR test
+ *
+ * The test checks the contents of Special Purpose Registers (SPR) listed
+ * in the spr_test_list array below.
+ * Each SPR value is read using mfspr instruction, some bits are masked
+ * according to the table and the resulting value is compared to the
+ * corresponding table value.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+#if CONFIG_POST & CFG_POST_SPR
+
+static struct
+{
+ int number;
+ char * name;
+ unsigned long mask;
+ unsigned long value;
+} spr_test_list [] = {
+ /* Standard Special-Purpose Registers */
+
+ {1, "XER", 0x00000000, 0x00000000},
+ {8, "LR", 0x00000000, 0x00000000},
+ {9, "CTR", 0x00000000, 0x00000000},
+ {18, "DSISR", 0x00000000, 0x00000000},
+ {19, "DAR", 0x00000000, 0x00000000},
+ {22, "DEC", 0x00000000, 0x00000000},
+ {26, "SRR0", 0x00000000, 0x00000000},
+ {27, "SRR1", 0x00000000, 0x00000000},
+ {272, "SPRG0", 0x00000000, 0x00000000},
+ {273, "SPRG1", 0x00000000, 0x00000000},
+ {274, "SPRG2", 0x00000000, 0x00000000},
+ {275, "SPRG3", 0x00000000, 0x00000000},
+ {287, "PVR", 0xFFFF0000, 0x00500000},
+
+ /* Additional Special-Purpose Registers */
+
+ {144, "CMPA", 0x00000000, 0x00000000},
+ {145, "CMPB", 0x00000000, 0x00000000},
+ {146, "CMPC", 0x00000000, 0x00000000},
+ {147, "CMPD", 0x00000000, 0x00000000},
+ {148, "ICR", 0xFFFFFFFF, 0x00000000},
+ {149, "DER", 0x00000000, 0x00000000},
+ {150, "COUNTA", 0xFFFFFFFF, 0x00000000},
+ {151, "COUNTB", 0xFFFFFFFF, 0x00000000},
+ {152, "CMPE", 0x00000000, 0x00000000},
+ {153, "CMPF", 0x00000000, 0x00000000},
+ {154, "CMPG", 0x00000000, 0x00000000},
+ {155, "CMPH", 0x00000000, 0x00000000},
+ {156, "LCTRL1", 0xFFFFFFFF, 0x00000000},
+ {157, "LCTRL2", 0xFFFFFFFF, 0x00000000},
+ {158, "ICTRL", 0xFFFFFFFF, 0x00000007},
+ {159, "BAR", 0x00000000, 0x00000000},
+ {630, "DPDR", 0x00000000, 0x00000000},
+ {631, "DPIR", 0x00000000, 0x00000000},
+ {638, "IMMR", 0xFFFF0000, CFG_IMMR },
+ {560, "IC_CST", 0x8E380000, 0x00000000},
+ {561, "IC_ADR", 0x00000000, 0x00000000},
+ {562, "IC_DAT", 0x00000000, 0x00000000},
+ {568, "DC_CST", 0xEF380000, 0x00000000},
+ {569, "DC_ADR", 0x00000000, 0x00000000},
+ {570, "DC_DAT", 0x00000000, 0x00000000},
+ {784, "MI_CTR", 0xFFFFFFFF, 0x00000000},
+ {786, "MI_AP", 0x00000000, 0x00000000},
+ {787, "MI_EPN", 0x00000000, 0x00000000},
+ {789, "MI_TWC", 0xFFFFFE02, 0x00000000},
+ {790, "MI_RPN", 0x00000000, 0x00000000},
+ {816, "MI_DBCAM", 0x00000000, 0x00000000},
+ {817, "MI_DBRAM0", 0x00000000, 0x00000000},
+ {818, "MI_DBRAM1", 0x00000000, 0x00000000},
+ {792, "MD_CTR", 0xFFFFFFFF, 0x04000000},
+ {793, "M_CASID", 0xFFFFFFF0, 0x00000000},
+ {794, "MD_AP", 0x00000000, 0x00000000},
+ {795, "MD_EPN", 0x00000000, 0x00000000},
+ {796, "M_TWB", 0x00000003, 0x00000000},
+ {797, "MD_TWC", 0x00000003, 0x00000000},
+ {798, "MD_RPN", 0x00000000, 0x00000000},
+ {799, "M_TW", 0x00000000, 0x00000000},
+ {824, "MD_DBCAM", 0x00000000, 0x00000000},
+ {825, "MD_DBRAM0", 0x00000000, 0x00000000},
+ {826, "MD_DBRAM1", 0x00000000, 0x00000000},
+};
+
+static int spr_test_list_size =
+ sizeof (spr_test_list) / sizeof (spr_test_list[0]);
+
+int spr_post_test (bd_t * bd, int flags)
+{
+ int ret = 0;
+ int ic = icache_status ();
+ int i;
+
+ unsigned long code[] = {
+ 0x7c6002a6, /* mfspr r3,SPR */
+ 0x4e800020 /* blr */
+ };
+ unsigned long (*get_spr) (void) = (void *) code;
+
+ if (ic)
+ icache_disable ();
+
+ for (i = 0; i < spr_test_list_size; i++) {
+ int num = spr_test_list[i].number;
+
+ /* mfspr r3,num */
+ code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6);
+
+ if ((get_spr () & spr_test_list[i].mask) !=
+ (spr_test_list[i].value & spr_test_list[i].mask)) {
+ post_log ("The value of %s special register "
+ "is incorrect: 0x%08X\n",
+ spr_test_list[i].name, get_spr ());
+ ret = -1;
+ }
+ }
+
+ if (ic)
+ icache_enable ();
+
+ return ret;
+}
+#endif /* CONFIG_POST & CFG_POST_SPR */
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+
+int cache_post_test (int flags);
+int watchdog_post_test (int flags);
+int i2c_post_test (int flags);
+int rtc_post_test (int flags);
+int memory_post_test (int flags);
+int cpu_post_test (int flags);
+int uart_post_test (int flags);
+int ether_post_test (int flags);
+int spi_post_test (int flags);
+int usb_post_test (int flags);
+int spr_post_test (int flags);
+
+struct post_test post_list[] =
+{
+#if CONFIG_POST & CFG_POST_CACHE
+ {
+ "Cache test",
+ "cache",
+ "This test verifies the CPU cache operation.",
+ POST_RAM | POST_ALWAYS,
+ &cache_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_WATCHDOG
+ {
+ "Watchdog timer test",
+ "watchdog",
+ "This test checks the watchdog timer.",
+ POST_RAM | POST_POWERFAIL | POST_MANUAL | POST_REBOOT,
+ &watchdog_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_I2C
+ {
+ "I2C test",
+ "i2c",
+ "This test verifies the I2C operation.",
+ POST_RAM | POST_ALWAYS,
+ &i2c_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_RTC
+ {
+ "RTC test",
+ "rtc",
+ "This test verifies the RTC operation.",
+ POST_RAM | POST_POWERFAIL | POST_MANUAL,
+ &rtc_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_MEMORY
+ {
+ "Memory test",
+ "memory",
+ "This test checks RAM.",
+ POST_ROM | POST_POWERON | POST_POWERFAIL,
+ &memory_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_CPU
+ {
+ "CPU test",
+ "cpu",
+ "This test verifies the arithmetic logic unit of"
+ " CPU.",
+ POST_RAM | POST_ALWAYS,
+ &cpu_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_UART
+ {
+ "UART test",
+ "uart",
+ "This test verifies the UART operation.",
+ POST_RAM | POST_POWERFAIL | POST_MANUAL,
+ &uart_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_ETHER
+ {
+ "ETHERNET test",
+ "ethernet",
+ "This test verifies the ETHERNET operation.",
+ POST_RAM | POST_ALWAYS | POST_MANUAL,
+ ðer_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_SPI
+ {
+ "SPI test",
+ "spi",
+ "This test verifies the SPI operation.",
+ POST_RAM | POST_ALWAYS | POST_MANUAL,
+ &spi_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_USB
+ {
+ "USB test",
+ "usb",
+ "This test verifies the USB operation.",
+ POST_RAM | POST_ALWAYS | POST_MANUAL,
+ &usb_post_test
+ },
+#endif
+#if CONFIG_POST & CFG_POST_SPR
+ {
+ "SPR test",
+ "spr",
+ "This test checks SPR contents.",
+ POST_ROM | POST_ALWAYS,
+ &spr_post_test
+ },
+#endif
+};
+
+unsigned int post_list_size = sizeof (post_list) / sizeof (struct post_test);
+
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * UART test
+ *
+ * The Serial Management Controllers (SMC) and the Serial Communication
+ * Controllers (SCC) listed in ctlr_list array below are tested in
+ * the loopback UART mode.
+ * The controllers are configured accordingly and several characters
+ * are transmitted. The configurable test parameters are:
+ * MIN_PACKET_LENGTH - minimum size of packet to transmit
+ * MAX_PACKET_LENGTH - maximum size of packet to transmit
+ * TEST_NUM - number of tests
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <commproc.h>
+#include <command.h>
+#include <net.h>
+
+#if CONFIG_POST & CFG_POST_UART
+
+#define CTLR_SMC 0
+#define CTLR_SCC 1
+
+/* The list of controllers to test */
+#if defined(CONFIG_MPC823)
+static int ctlr_list[][2] =
+ { {CTLR_SMC, 0}, {CTLR_SMC, 1}, {CTLR_SCC, 1} };
+#else
+static int ctlr_list[][2] = { };
+#endif
+
+#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
+
+static struct {
+ void (*init) (int index);
+ void (*putc) (int index, const char c);
+ int (*getc) (int index);
+} ctlr_proc[2];
+
+static char *ctlr_name[2] = { "SMC", "SCC" };
+
+static int used_by_uart[2] = { -1, -1 };
+static int used_by_ether[2] = { -1, -1 };
+
+static int proff_smc[] = { PROFF_SMC1, PROFF_SMC2 };
+static int proff_scc[] =
+ { PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
+
+ /*
+ * SMC callbacks
+ */
+
+static void smc_init (int smc_index)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ static int cpm_cr_ch[] = { CPM_CR_CH_SMC1, CPM_CR_CH_SMC2 };
+
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile smc_t *sp;
+ volatile smc_uart_t *up;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ uint dpaddr;
+
+ /* initialize pointers to SMC */
+
+ sp = (smc_t *) & (cp->cp_smc[smc_index]);
+ up = (smc_uart_t *) & cp->cp_dparam[proff_smc[smc_index]];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+ /* Enable SDMA.
+ */
+ im->im_siu_conf.sc_sdcr = 1;
+
+ /* clear error conditions */
+#ifdef CFG_SDSR
+ im->im_sdma.sdma_sdsr = CFG_SDSR;
+#else
+ im->im_sdma.sdma_sdsr = 0x83;
+#endif
+
+ /* clear SDMA interrupt mask */
+#ifdef CFG_SDMR
+ im->im_sdma.sdma_sdmr = CFG_SDMR;
+#else
+ im->im_sdma.sdma_sdmr = 0x00;
+#endif
+
+#if defined(CONFIG_FADS)
+ /* Enable RS232 */
+ *((uint *) BCSR1) &=
+ ~(smc_index == 1 ? BCSR1_RS232EN_1 : BCSR1_RS232EN_2);
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+ /* Enable Monitor Port Transceiver */
+ *((uchar *) BCSR0) |= BCSR0_ENMONXCVR;
+#endif
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+
+#ifdef CFG_ALLOC_DPRAM
+ dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
+#else
+ dpaddr = CPM_POST_BASE;
+#endif
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ * For now, this address seems OK, but it may have to
+ * change with newer versions of the firmware.
+ * damm: allocating space after the two buffers for rx/tx data
+ */
+
+ rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
+ rbdf->cbd_bufaddr = (uint) (rbdf + 2);
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+ up->smc_rbase = dpaddr;
+ up->smc_tbase = dpaddr + sizeof (cbd_t);
+ up->smc_rfcr = SMC_EB;
+ up->smc_tfcr = SMC_EB;
+
+#if defined(CONFIG_MBX)
+ board_serial_init ();
+#endif
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ * Set local loopback mode.
+ */
+ sp->smc_smcmr = smcr_mk_clen (9) | SMCMR_SM_UART | (ushort) 0x0004;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->smc_smcm = 0;
+ sp->smc_smce = 0xff;
+
+ /* Set up the baud rate generator.
+ */
+ cp->cp_simode = 0x00000000;
+
+ cp->cp_brgc1 =
+ (((gd->cpu_clk / 16 / gd->baudrate) -
+ 1) << 1) | CPM_BRG_EN;
+
+ /* Make the first buffer the only buffer.
+ */
+ tbdf->cbd_sc |= BD_SC_WRAP;
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Single character receive.
+ */
+ up->smc_mrblr = 1;
+ up->smc_maxidl = 0;
+
+ /* Initialize Tx/Rx parameters.
+ */
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ cp->cp_cpcr =
+ mk_cr_cmd (cpm_cr_ch[smc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ /* Enable transmitter/receiver.
+ */
+ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+}
+
+static void smc_putc (int smc_index, const char c)
+{
+ volatile cbd_t *tbdf;
+ volatile char *buf;
+ volatile smc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+
+ up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
+
+ tbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_tbase];
+
+ /* Wait for last character to go.
+ */
+
+ buf = (char *) tbdf->cbd_bufaddr;
+#if 0
+ __asm__ ("eieio");
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+
+ *buf = c;
+ tbdf->cbd_datlen = 1;
+ tbdf->cbd_sc |= BD_SC_READY;
+ __asm__ ("eieio");
+#if 1
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+}
+
+static int smc_getc (int smc_index)
+{
+ volatile cbd_t *rbdf;
+ volatile unsigned char *buf;
+ volatile smc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+ unsigned char c;
+ int i;
+
+ up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
+
+ rbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_rbase];
+
+ /* Wait for character to show up.
+ */
+ buf = (unsigned char *) rbdf->cbd_bufaddr;
+#if 0
+ while (rbdf->cbd_sc & BD_SC_EMPTY);
+#else
+ for (i = 100; i > 0; i--) {
+ if (!(rbdf->cbd_sc & BD_SC_EMPTY))
+ break;
+ udelay (1000);
+ }
+
+ if (i == 0)
+ return -1;
+#endif
+ c = *buf;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return (c);
+}
+
+ /*
+ * SCC callbacks
+ */
+
+static void scc_init (int scc_index)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ static int cpm_cr_ch[] = {
+ CPM_CR_CH_SCC1,
+ CPM_CR_CH_SCC2,
+ CPM_CR_CH_SCC3,
+ CPM_CR_CH_SCC4,
+ };
+
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile scc_t *sp;
+ volatile scc_uart_t *up;
+ volatile cbd_t *tbdf, *rbdf;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ uint dpaddr;
+
+ /* initialize pointers to SCC */
+
+ sp = (scc_t *) & (cp->cp_scc[scc_index]);
+ up = (scc_uart_t *) & cp->cp_dparam[proff_scc[scc_index]];
+
+ /* Disable transmitter/receiver.
+ */
+ sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+
+ /* Allocate space for two buffer descriptors in the DP ram.
+ */
+
+#ifdef CFG_ALLOC_DPRAM
+ dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
+#else
+ dpaddr = CPM_POST_BASE;
+#endif
+
+ /* Enable SDMA.
+ */
+ im->im_siu_conf.sc_sdcr = 0x0001;
+
+ /* Set the physical address of the host memory buffers in
+ * the buffer descriptors.
+ */
+
+ rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
+ rbdf->cbd_bufaddr = (uint) (rbdf + 2);
+ rbdf->cbd_sc = 0;
+ tbdf = rbdf + 1;
+ tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
+ tbdf->cbd_sc = 0;
+
+ /* Set up the baud rate generator.
+ */
+ cp->cp_sicr &= ~(0x000000FF << (8 * scc_index));
+ /* no |= needed, since BRG1 is 000 */
+
+ cp->cp_brgc1 =
+ (((gd->cpu_clk / 16 / gd->baudrate) -
+ 1) << 1) | CPM_BRG_EN;
+
+ /* Set up the uart parameters in the parameter ram.
+ */
+ up->scc_genscc.scc_rbase = dpaddr;
+ up->scc_genscc.scc_tbase = dpaddr + sizeof (cbd_t);
+
+ /* Initialize Tx/Rx parameters.
+ */
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+ cp->cp_cpcr =
+ mk_cr_cmd (cpm_cr_ch[scc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ up->scc_genscc.scc_rfcr = SCC_EB | 0x05;
+ up->scc_genscc.scc_tfcr = SCC_EB | 0x05;
+
+ up->scc_genscc.scc_mrblr = 1; /* Single character receive */
+ up->scc_maxidl = 0; /* disable max idle */
+ up->scc_brkcr = 1; /* send one break character on stop TX */
+ up->scc_parec = 0;
+ up->scc_frmec = 0;
+ up->scc_nosec = 0;
+ up->scc_brkec = 0;
+ up->scc_uaddr1 = 0;
+ up->scc_uaddr2 = 0;
+ up->scc_toseq = 0;
+ up->scc_char1 = 0x8000;
+ up->scc_char2 = 0x8000;
+ up->scc_char3 = 0x8000;
+ up->scc_char4 = 0x8000;
+ up->scc_char5 = 0x8000;
+ up->scc_char6 = 0x8000;
+ up->scc_char7 = 0x8000;
+ up->scc_char8 = 0x8000;
+ up->scc_rccm = 0xc0ff;
+
+ /* Set low latency / small fifo.
+ */
+ sp->scc_gsmrh = SCC_GSMRH_RFW;
+
+ /* Set UART mode
+ */
+ sp->scc_gsmrl &= ~0xF;
+ sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;
+
+ /* Set local loopback mode.
+ */
+ sp->scc_gsmrl &= ~SCC_GSMRL_DIAG_LE;
+ sp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
+
+ /* Set clock divider 16 on Tx and Rx
+ */
+ sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+ sp->scc_psmr |= SCU_PSMR_CL;
+
+ /* Mask all interrupts and remove anything pending.
+ */
+ sp->scc_sccm = 0;
+ sp->scc_scce = 0xffff;
+ sp->scc_dsr = 0x7e7e;
+ sp->scc_psmr = 0x3000;
+
+ /* Make the first buffer the only buffer.
+ */
+ tbdf->cbd_sc |= BD_SC_WRAP;
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Enable transmitter/receiver.
+ */
+ sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+}
+
+static void scc_putc (int scc_index, const char c)
+{
+ volatile cbd_t *tbdf;
+ volatile char *buf;
+ volatile scc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+
+ up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
+
+ tbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
+
+ /* Wait for last character to go.
+ */
+
+ buf = (char *) tbdf->cbd_bufaddr;
+#if 0
+ __asm__ ("eieio");
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+
+ *buf = c;
+ tbdf->cbd_datlen = 1;
+ tbdf->cbd_sc |= BD_SC_READY;
+ __asm__ ("eieio");
+#if 1
+ while (tbdf->cbd_sc & BD_SC_READY)
+ __asm__ ("eieio");
+#endif
+}
+
+static int scc_getc (int scc_index)
+{
+ volatile cbd_t *rbdf;
+ volatile unsigned char *buf;
+ volatile scc_uart_t *up;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cpmp = &(im->im_cpm);
+ unsigned char c;
+ int i;
+
+ up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
+
+ rbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
+
+ /* Wait for character to show up.
+ */
+ buf = (unsigned char *) rbdf->cbd_bufaddr;
+#if 0
+ while (rbdf->cbd_sc & BD_SC_EMPTY);
+#else
+ for (i = 100; i > 0; i--) {
+ if (!(rbdf->cbd_sc & BD_SC_EMPTY))
+ break;
+ udelay (1000);
+ }
+
+ if (i == 0)
+ return -1;
+#endif
+ c = *buf;
+ rbdf->cbd_sc |= BD_SC_EMPTY;
+
+ return (c);
+}
+
+ /*
+ * Test routines
+ */
+
+static int test_ctlr (int ctlr, int index)
+{
+ int res = -1;
+ char test_str[] = "*** UART Test String ***\r\n";
+ int i;
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+ if (used_by_uart[ctlr] == index) {
+ while (ctlr_proc[ctlr].getc (index) != -1);
+ }
+#endif
+
+ ctlr_proc[ctlr].init (index);
+
+ for (i = 0; i < sizeof (test_str) - 1; i++) {
+ ctlr_proc[ctlr].putc (index, test_str[i]);
+ if (ctlr_proc[ctlr].getc (index) != test_str[i])
+ goto Done;
+ }
+
+ res = 0;
+
+ Done:
+
+#if !defined(CONFIG_8xx_CONS_NONE)
+ if (used_by_uart[ctlr] == index) {
+ serial_init ();
+ }
+#endif
+
+#if defined(SCC_ENET)
+ if (used_by_ether[ctlr] == index) {
+ DECLARE_GLOBAL_DATA_PTR;
+
+ eth_init (gd->bd);
+ }
+#endif
+
+ if (res != 0) {
+ post_log ("uart %s%d test failed\n",
+ ctlr_name[ctlr], index + 1);
+ }
+
+ return res;
+}
+
+int uart_post_test (int flags)
+{
+ int res = 0;
+ int i;
+
+#if defined(CONFIG_8xx_CONS_SMC1)
+ used_by_uart[CTLR_SMC] = 0;
+#elif defined(CONFIG_8xx_CONS_SMC2)
+ used_by_uart[CTLR_SMC] = 1;
+#elif defined(CONFIG_8xx_CONS_SCC1)
+ used_by_uart[CTLR_SCC] = 0;
+#elif defined(CONFIG_8xx_CONS_SCC2)
+ used_by_uart[CTLR_SCC] = 1;
+#elif defined(CONFIG_8xx_CONS_SCC3)
+ used_by_uart[CTLR_SCC] = 2;
+#elif defined(CONFIG_8xx_CONS_SCC4)
+ used_by_uart[CTLR_SCC] = 3;
+#endif
+
+#if defined(SCC_ENET)
+ used_by_ether[CTLR_SCC] = SCC_ENET;
+#endif
+
+ ctlr_proc[CTLR_SMC].init = smc_init;
+ ctlr_proc[CTLR_SMC].putc = smc_putc;
+ ctlr_proc[CTLR_SMC].getc = smc_getc;
+
+ ctlr_proc[CTLR_SCC].init = scc_init;
+ ctlr_proc[CTLR_SCC].putc = scc_putc;
+ ctlr_proc[CTLR_SCC].getc = scc_getc;
+
+ for (i = 0; i < CTRL_LIST_SIZE; i++) {
+ if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
+ res = -1;
+ }
+ }
+
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_UART */
+
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * USB test
+ *
+ * The USB controller is tested in the local loopback mode.
+ * It is configured so that endpoint 0 operates as host and endpoint 1
+ * operates as function endpoint. After that an IN token transaction
+ * is performed.
+ * Refer to MPC850 User Manual, Section 32.11.1 USB Host Controller
+ * Initialization Example.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <commproc.h>
+#include <command.h>
+
+#if CONFIG_POST & CFG_POST_USB
+
+#define TOUT_LOOP 100
+
+#define PROFF_USB ((uint)0x0000)
+
+#define CPM_USB_EP0_BASE 0x0a00
+#define CPM_USB_EP1_BASE 0x0a20
+
+#define CPM_USB_DT0_BASE 0x0a80
+#define CPM_USB_DT1_BASE 0x0a90
+#define CPM_USB_DR0_BASE 0x0aa0
+#define CPM_USB_DR1_BASE 0x0ab0
+
+#define CPM_USB_RX0_BASE 0x0b00
+#define CPM_USB_RX1_BASE 0x0b08
+#define CPM_USB_TX0_BASE 0x0b20
+#define CPM_USB_TX1_BASE 0x0b28
+
+#define USB_EXPECT(x) if (!(x)) goto Done;
+
+typedef struct usb_param {
+ ushort ep0ptr;
+ ushort ep1ptr;
+ ushort ep2ptr;
+ ushort ep3ptr;
+ uint rstate;
+ uint rptr;
+ ushort frame_n;
+ ushort rbcnt;
+ ushort rtemp;
+} usb_param_t;
+
+typedef struct usb_param_block {
+ ushort rbase;
+ ushort tbase;
+ uchar rfcr;
+ uchar tfcr;
+ ushort mrblr;
+ ushort rbptr;
+ ushort tbptr;
+ uint tstate;
+ uint tptr;
+ ushort tcrc;
+ ushort tbcnt;
+ uint res[2];
+} usb_param_block_t;
+
+typedef struct usb {
+ uchar usmod;
+ uchar usadr;
+ uchar uscom;
+ uchar res1;
+ ushort usep[4];
+ uchar res2[4];
+ ushort usber;
+ uchar res3[2];
+ ushort usbmr;
+ uchar res4;
+ uchar usbs;
+ uchar res5[8];
+} usb_t;
+
+int usb_post_test (bd_t * bd, int flags)
+{
+ int res = -1;
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = &(im->im_cpm);
+ volatile usb_param_t *pram_ptr;
+ uint dpram;
+ ushort DPRAM;
+ volatile cbd_t *tx;
+ volatile cbd_t *rx;
+ volatile usb_t *usbr;
+ volatile usb_param_block_t *ep0;
+ volatile usb_param_block_t *ep1;
+ int j;
+
+ pram_ptr = (usb_param_t *) & (im->im_cpm.cp_dparam[PROFF_USB]);
+ dpram = (uint) im->im_cpm.cp_dpmem;
+ DPRAM = dpram;
+ tx = (cbd_t *) (dpram + CPM_USB_TX0_BASE);
+ rx = (cbd_t *) (dpram + CPM_USB_RX0_BASE);
+ ep0 = (usb_param_block_t *) (dpram + CPM_USB_EP0_BASE);
+ ep1 = (usb_param_block_t *) (dpram + CPM_USB_EP1_BASE);
+ usbr = (usb_t *) & (im->im_cpm.cp_scc[0]);
+
+ /* 01 */
+ im->im_ioport.iop_padir &= ~(ushort) 0x0200;
+ im->im_ioport.iop_papar |= (ushort) 0x0200;
+
+ cp->cp_sicr &= ~0x000000FF;
+ cp->cp_sicr |= 0x00000018;
+
+ cp->cp_brgc4 = 0x00010001;
+
+ /* 02 */
+ im->im_ioport.iop_padir &= ~(ushort) 0x0002;
+ im->im_ioport.iop_padir &= ~(ushort) 0x0001;
+
+ im->im_ioport.iop_papar |= (ushort) 0x0002;
+ im->im_ioport.iop_papar |= (ushort) 0x0001;
+
+ /* 03 */
+ im->im_ioport.iop_pcdir &= ~(ushort) 0x0020;
+ im->im_ioport.iop_pcdir &= ~(ushort) 0x0010;
+
+ im->im_ioport.iop_pcpar &= ~(ushort) 0x0020;
+ im->im_ioport.iop_pcpar &= ~(ushort) 0x0010;
+
+ im->im_ioport.iop_pcso |= (ushort) 0x0020;
+ im->im_ioport.iop_pcso |= (ushort) 0x0010;
+
+ /* 04 */
+ im->im_ioport.iop_pcdir |= (ushort) 0x0200;
+ im->im_ioport.iop_pcdir |= (ushort) 0x0100;
+
+ im->im_ioport.iop_pcpar |= (ushort) 0x0200;
+ im->im_ioport.iop_pcpar |= (ushort) 0x0100;
+
+ /* 05 */
+ pram_ptr->frame_n = 0;
+
+ /* 06 */
+ pram_ptr->ep0ptr = DPRAM + CPM_USB_EP0_BASE;
+ pram_ptr->ep1ptr = DPRAM + CPM_USB_EP1_BASE;
+
+ /* 07-10 */
+ tx[0].cbd_sc = 0xB800;
+ tx[0].cbd_datlen = 3;
+ tx[0].cbd_bufaddr = dpram + CPM_USB_DT0_BASE;
+
+ tx[1].cbd_sc = 0xBC80;
+ tx[1].cbd_datlen = 3;
+ tx[1].cbd_bufaddr = dpram + CPM_USB_DT1_BASE;
+
+ rx[0].cbd_sc = 0xA000;
+ rx[0].cbd_datlen = 0;
+ rx[0].cbd_bufaddr = dpram + CPM_USB_DR0_BASE;
+
+ rx[1].cbd_sc = 0xA000;
+ rx[1].cbd_datlen = 0;
+ rx[1].cbd_bufaddr = dpram + CPM_USB_DR1_BASE;
+
+ /* 11-12 */
+ *(volatile int *) (dpram + CPM_USB_DT0_BASE) = 0x69856000;
+ *(volatile int *) (dpram + CPM_USB_DT1_BASE) = 0xABCD1234;
+
+ *(volatile int *) (dpram + CPM_USB_DR0_BASE) = 0;
+ *(volatile int *) (dpram + CPM_USB_DR1_BASE) = 0;
+
+ /* 13-16 */
+ ep0->rbase = DPRAM + CPM_USB_RX0_BASE;
+ ep0->tbase = DPRAM + CPM_USB_TX0_BASE;
+ ep0->rfcr = 0x18;
+ ep0->tfcr = 0x18;
+ ep0->mrblr = 0x100;
+ ep0->rbptr = DPRAM + CPM_USB_RX0_BASE;
+ ep0->tbptr = DPRAM + CPM_USB_TX0_BASE;
+ ep0->tstate = 0;
+
+ /* 17-20 */
+ ep1->rbase = DPRAM + CPM_USB_RX1_BASE;
+ ep1->tbase = DPRAM + CPM_USB_TX1_BASE;
+ ep1->rfcr = 0x18;
+ ep1->tfcr = 0x18;
+ ep1->mrblr = 0x100;
+ ep1->rbptr = DPRAM + CPM_USB_RX1_BASE;
+ ep1->tbptr = DPRAM + CPM_USB_TX1_BASE;
+ ep1->tstate = 0;
+
+ /* 21-24 */
+ usbr->usep[0] = 0x0000;
+ usbr->usep[1] = 0x1100;
+ usbr->usep[2] = 0x2200;
+ usbr->usep[3] = 0x3300;
+
+ /* 25 */
+ usbr->usmod = 0x06;
+
+ /* 26 */
+ usbr->usadr = 0x05;
+
+ /* 27 */
+ usbr->uscom = 0;
+
+ /* 28 */
+ usbr->usmod |= 0x01;
+ udelay (1);
+
+ /* 29-30 */
+ usbr->uscom = 0x80;
+ usbr->uscom = 0x81;
+
+ /* Wait for the data packet to be transmitted */
+ for (j = 0; j < TOUT_LOOP; j++) {
+ if (tx[1].cbd_sc & (ushort) 0x8000)
+ udelay (1);
+ else
+ break;
+ }
+
+ USB_EXPECT (j < TOUT_LOOP);
+
+ USB_EXPECT (tx[0].cbd_sc == 0x3800);
+ USB_EXPECT (tx[0].cbd_datlen == 3);
+
+ USB_EXPECT (tx[1].cbd_sc == 0x3C80);
+ USB_EXPECT (tx[1].cbd_datlen == 3);
+
+ USB_EXPECT (rx[0].cbd_sc == 0x2C00);
+ USB_EXPECT (rx[0].cbd_datlen == 5);
+
+ USB_EXPECT (*(volatile int *) (dpram + CPM_USB_DR0_BASE) ==
+ 0xABCD122B);
+ USB_EXPECT (*(volatile char *) (dpram + CPM_USB_DR0_BASE + 4) == 0x42);
+
+ res = 0;
+ Done:
+
+ return res;
+}
+
+#endif /* CONFIG_POST & CFG_POST_USB */
+
+#endif /* CONFIG_POST */
--- /dev/null
+/*
+ * (C) Copyright 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>
+
+/*
+ * Watchdog test
+ *
+ * The test verifies the watchdog timer operation.
+ * On the first iteration, the test routine disables interrupts and
+ * makes a 10-second delay. If the system does not reboot during this delay,
+ * the watchdog timer is not operational and the test fails. If the system
+ * reboots, on the second iteration the test routine reports a success.
+ */
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_WATCHDOG
+
+static ulong gettbl (void)
+{
+ ulong r;
+
+ asm ("mftbl %0":"=r" (r));
+
+ return r;
+}
+
+int watchdog_post_test (bd_t * bd, int flags)
+{
+ if (flags & POST_REBOOT) {
+ /* Test passed */
+
+ return 0;
+ } else {
+ /* 10-second delay */
+ int ints = disable_interrupts ();
+ ulong base = gettbl ();
+ ulong clk = get_tbclk ();
+
+ while ((gettbl () - base) / 10 < clk);
+
+ if (ints)
+ enable_interrupts ();
+
+ /*
+ * If we have reached this point, the watchdog timer
+ * does not work
+ */
+ return -1;
+ }
+}
+
+#endif /* CONFIG_POST & CFG_POST_WATCHDOG */
+#endif /* CONFIG_POST */