]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
[Merge of DENX' "STABLE-branch"]
authorwdenk <wdenk>
Fri, 13 Sep 2002 00:02:45 +0000 (00:02 +0000)
committerwdenk <wdenk>
Fri, 13 Sep 2002 00:02:45 +0000 (00:02 +0000)
* 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

73 files changed:
CHANGELOG
CREDITS
MAINTAINERS
MAKEALL
Makefile
board/lwmon/lwmon.c
board/pn62/cmd_pn62.c
board/pn62/pn62.c
board/r360mpi/r360mpi.c
board/smdk2400/smdk2400.c
common/Makefile
common/cmd_bootm.c
common/cmd_diag.c [new file with mode: 0644]
common/cmd_nvedit.c
common/cmd_pcmcia.c
common/command.c
cpu/mpc8260/soft_i2c.c [deleted file]
cpu/mpc8xx/commproc.c
cpu/mpc8xx/i2c.c
cpu/mpc8xx/soft_i2c.c [deleted file]
cpu/mpc8xx/spi.c
include/asm-arm/arch-pxa/pxa-regs.h [new file with mode: 0644]
include/cmd_bsp.h
include/cmd_confdefs.h
include/cmd_diag.h [new file with mode: 0644]
include/common.h
include/commproc.h
include/configs/IP860.h
include/configs/R360MPI.h
include/configs/lwmon.h
include/configs/smdk2400.h
include/mpc824x.h
include/post.h [new file with mode: 0644]
lib_arm/armlinux.c
lib_arm/board.c
lib_ppc/board.c
post/Makefile [new file with mode: 0644]
post/cache.c [new file with mode: 0644]
post/cache_8xx.S [new file with mode: 0644]
post/cpu.c [new file with mode: 0644]
post/cpu/Makefile [new file with mode: 0644]
post/cpu/andi.c [new file with mode: 0644]
post/cpu/asm.S [new file with mode: 0644]
post/cpu/b.c [new file with mode: 0644]
post/cpu/cmp.c [new file with mode: 0644]
post/cpu/cmpi.c [new file with mode: 0644]
post/cpu/complex.c [new file with mode: 0644]
post/cpu/cpu_asm.h [new file with mode: 0644]
post/cpu/cr.c [new file with mode: 0644]
post/cpu/load.c [new file with mode: 0644]
post/cpu/multi.c [new file with mode: 0644]
post/cpu/rlwimi.c [new file with mode: 0644]
post/cpu/rlwinm.c [new file with mode: 0644]
post/cpu/rlwnm.c [new file with mode: 0644]
post/cpu/srawi.c [new file with mode: 0644]
post/cpu/store.c [new file with mode: 0644]
post/cpu/string.c [new file with mode: 0644]
post/cpu/three.c [new file with mode: 0644]
post/cpu/threei.c [new file with mode: 0644]
post/cpu/threex.c [new file with mode: 0644]
post/cpu/two.c [new file with mode: 0644]
post/cpu/twox.c [new file with mode: 0644]
post/ether.c [new file with mode: 0644]
post/i2c.c [new file with mode: 0644]
post/memory.c [new file with mode: 0644]
post/post.c [new file with mode: 0644]
post/rtc.c [new file with mode: 0644]
post/rules.mk [new file with mode: 0644]
post/spr.c [new file with mode: 0644]
post/tests.c [new file with mode: 0644]
post/uart.c [new file with mode: 0644]
post/usb.c [new file with mode: 0644]
post/watchdog.c [new file with mode: 0644]

index 016f2b96979381150d44cea54c42a9470cd24aae..16bc7518b5c7ab100f007bb54aa7dd8b348d3eeb 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,11 +2,6 @@
 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
@@ -15,6 +10,33 @@ Modifications for 1.2.0:
 
 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)
@@ -24,7 +46,7 @@ For details about the current modifications, please see README-WIP
   - 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:
diff --git a/CREDITS b/CREDITS
index 743114825207f6e02f06080f7b12b113eb5e0f31..b7b5453243c41bdc139223b1e7c17a7c7c20ea5d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -68,7 +68,7 @@ D: FLAGA DM Support
 
 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
@@ -85,7 +85,8 @@ D: EEPROM Speedup, SXNI855T port
 
 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
@@ -94,7 +95,7 @@ W: www.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
@@ -126,6 +127,11 @@ H: Rich Ireland
 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
@@ -164,6 +170,15 @@ N: Frank Morauf
 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
@@ -213,3 +228,8 @@ D: Port to Cray L1 board; DHCP vendor extensions
 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
index 819c4c6dbfb237cdc99b2dff76d04c132f1e42d7..bf821aa8bb61214154ee6b0fa24a893ccec8a839 100644 (file)
@@ -40,7 +40,6 @@ K
 Wolfgang Denk <wd@denx.de>
 
        AMX860                  MPC860
-       CCM                     MPC855
        ETX094                  MPC850
        FPS850L                 MPC850
        ICU862                  MPC862
@@ -91,9 +90,12 @@ Frank Gottschling <fgottschling@eltec.de>
 
 Wolfgang Grandegger <wg@denx.de>
 
+       CCM                     MPC855
+
        PN62                    MPC8240
 
        IPHASE4539              MPC8260
+       SCM                     MPC8260
 
 Howard Gray <mvsensor@matrix-vision.de>
 
diff --git a/MAKEALL b/MAKEALL
index 3a4918526f7c2e1603c084c22f0a8144588c4a1c..26207f36e39fb7ff0a3a53f1044508d634ab3e9c 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -47,7 +47,8 @@ LIST_4xx="    \
 
 LIST_824x="    \
        BMW             CU824           MOUSSE          MUSENKI         \
-       OXC             Sandpoint8240   Sandpoint8245   utx8245         \
+       OXC             PN62            Sandpoint8240   Sandpoint8245   \
+       utx8245                                                         \
 "
 
 #########################################################################
@@ -58,7 +59,7 @@ LIST_8260="   \
        cogent_mpc8260  CPU86           ep8260          gw8260          \
        hymod           IPHASE4539      MPC8260ADS      PM826           \
        ppmc8260        RPXsuper        rsdproto        sbc8260         \
-       TQM8260         \
+       SCM             TQM8260                                         \
 "
 
 #########################################################################
index c8956f9c10ceb41254dc38d3cc4522cd856a8964..47d3354e304d17e1e31a8cddf15953f77774df82 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -95,6 +95,8 @@ SUBDIRS       = tools \
          rtc \
          dtt \
          drivers \
+         post \
+         post/cpu \
          examples
 
 #########################################################################
@@ -115,6 +117,7 @@ LIBS += disk/libdisk.a
 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
 
index 30d637c8428efeb3b3b2bf77a011a375b3e2a060..4203f3be028fcc122920430e3e2131b609d410e0 100644 (file)
@@ -28,6 +28,7 @@
 #include <command.h>
 #include <cmd_bsp.h>
 #include <malloc.h>
+#include <post.h>
 
 #include <linux/types.h>
 #include <linux/string.h>      /* for strdup */
@@ -443,7 +444,7 @@ int misc_init_r (void)
                }
        }
 #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) {
@@ -679,3 +680,14 @@ void pic_write (uchar reg, uchar val)
 {
        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);
+}
index 22431e19e9fce61ce6f46e3522e1f0e33a2a3dbf..b3d7d57deaf30b7655973ee763fe9276073cb44f 100644 (file)
 
 #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;
 
@@ -60,7 +60,7 @@ int do_led (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 #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;
@@ -145,7 +145,7 @@ int do_loadpci (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        
        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
index 05756c203ad37bcbf2a1c14db98650c24811519a..fb7831f46e388a415e7fb813bfe5b4b2b19bf2e0 100644 (file)
@@ -151,6 +151,8 @@ void pci_init (void)
 
 int misc_init_r (void)
 {
+       DECLARE_GLOBAL_DATA_PTR;
+
        char str[20];
        u8 mac[6];
 
@@ -168,14 +170,14 @@ int misc_init_r (void)
        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);
 
index 54a09b5816f6460572069e13a6a46a2794bf27ba..a63a99abc6f73d9433e17a50f198ec4ed0590dda 100644 (file)
 #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
  *
@@ -254,3 +263,161 @@ void r360_pwm_write (uchar reg, uchar val)
                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;
+}
index 361bf5e0a384fbef347fe45fe4f4a3f20f074fe7..1f618bd7c016986e5f272a6dceda6d904dcf6299 100644 (file)
@@ -58,8 +58,7 @@ int board_init (void)
        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;
index e0a9cf5266125e19d5c057f6ccc549c45173a801..2e835542163d511ccf53120b4f55f44f685e81b3 100644 (file)
@@ -26,22 +26,22 @@ include $(TOPDIR)/config.mk
 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)
 
index b3a5f786933002e7c5031f8e3e896d96d7c436fb..1f04297bf0fd374cde565d46332fc78b1b69b3cf 100644 (file)
@@ -31,6 +31,7 @@
 #include <image.h>
 #include <malloc.h>
 #include <zlib.h>
+#include <asm/byteorder.h>
 #if (CONFIG_COMMANDS & CFG_CMD_DATE)
 #include <rtc.h>
 #endif
@@ -74,7 +75,11 @@ typedef void boot_os_Fcn (cmd_tbl_t *cmdtp, int flag,
                          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;
@@ -113,7 +118,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        /* 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;
@@ -123,7 +128,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        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) {
@@ -137,11 +142,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        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;
@@ -152,7 +157,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
        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;
@@ -165,7 +170,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        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)
@@ -191,12 +196,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                        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);
@@ -215,7 +220,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
        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();
 
@@ -264,6 +269,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return 1;
 }
 
+#ifndef CONFIG_ARM
 static void
 do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                int     argc, char *argv[],
@@ -271,10 +277,6 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
                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;
@@ -533,8 +535,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
         *   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,
@@ -658,7 +660,7 @@ static int image_info (ulong addr)
        /* 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;
        }
@@ -666,7 +668,7 @@ static int image_info (ulong addr)
        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) {
@@ -678,10 +680,10 @@ static int image_info (ulong addr)
        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;
        }
@@ -706,19 +708,20 @@ print_image_hdr (image_header_t *hdr)
                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");
                }
        }
 }
diff --git a/common/cmd_diag.c b/common/cmd_diag.c
new file mode 100644 (file)
index 0000000..31471ba
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * (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 */
index 532be56443b9ff97c628f48cd28a67c84085154b..55299c466600be8c81e3789a238c7b2f0c75c8b4 100644 (file)
@@ -305,7 +305,7 @@ void env_relocate (void)
 # 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__);
index 644249c553ece241ecec42d0e1d4cacabfb40f2a..1e8735b80b5c1f577419da465482637b584ae4af 100644 (file)
@@ -1594,6 +1594,242 @@ static void cfg_ports (void)
 
 #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                                                 */
 /* ---------------------------------------------------------------------------- */
index e321c5a05b03142a3f84a5ed50639f7e58f5c113..af0759bbd476c4d06fae6e32157906cc9caa54b4 100644 (file)
@@ -42,6 +42,7 @@
 #include <cmd_reginfo.h>
 #include <cmd_pcmcia.h>
 #include <cmd_autoscript.h>
+#include <cmd_diag.h>
 
 #include <cmd_eeprom.h>
 #include <cmd_i2c.h>
@@ -313,6 +314,7 @@ cmd_tbl_t cmd_tbl[] = {
        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 )
 };
diff --git a/cpu/mpc8260/soft_i2c.c b/cpu/mpc8260/soft_i2c.c
deleted file mode 100644 (file)
index c017ebc..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * (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 */
-/*-----------------------------------------------------------------------
- */
index 128874bcc6d328d68a71873203ed0999a9de31f9..62a4458a5ea63de9d40784f735ec67784c230674 100644 (file)
@@ -89,5 +89,24 @@ uint dpram_base_align (uint align)
 
        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 */
index a0c548c75864e9934d19a9d8bac9a9651bf9b527..fcbeac0e76524cebb188cc2adf1e7eb3447f78e5 100644 (file)
@@ -37,9 +37,6 @@
 /* define to enable debug messages */
 #undef DEBUG_I2C
 
-/* us to wait before checking the i2c */
-#define DELAY_US       100000
-
 /*-----------------------------------------------------------------------
  * Set default values
  */
@@ -138,7 +135,7 @@ i2c_roundrate(int hz, int speed, int filter, int modval,
 
     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));
@@ -147,7 +144,7 @@ i2c_roundrate(int hz, int speed, int filter, int modval,
 
     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));
 
@@ -513,10 +510,6 @@ static int i2c_doio(i2c_state_t *state)
        /* Begin transmission */
        i2c->i2c_i2com |= 0x80;
 
-       /* This is a patch! */
-       udelay (DELAY_US)
-         ;
-
        /* Loop until transmit & receive completed */
 
        if (state->tx_idx > 0) {
diff --git a/cpu/mpc8xx/soft_i2c.c b/cpu/mpc8xx/soft_i2c.c
deleted file mode 100644 (file)
index 9fcceb1..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * (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 */
-/*-----------------------------------------------------------------------
- */
index 657653f5298d52d6834dd480fde2446a4a55e341..e9a800c14d7a8417f5e32c4927642e36c1be7251 100644 (file)
 #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
@@ -385,6 +387,7 @@ ssize_t spi_xfer (size_t count)
        volatile cpm8xx_t *cp;
        volatile spi_t *spi;
        cbd_t *tbdf, *rbdf;
+       ushort loop;
        int tm;
 
        DPRINT (("*** spi_xfer entered ***\n"));
@@ -417,7 +420,9 @@ ssize_t spi_xfer (size_t count)
        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       |
@@ -463,6 +468,104 @@ ssize_t spi_xfer (size_t count)
 
        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 */
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
new file mode 100644 (file)
index 0000000..3bc0751
--- /dev/null
@@ -0,0 +1,1121 @@
+/*
+ *  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
+
+
+
+
index 301f2a54e8483e8aaba8a82cb1b18cadbb32c1e7..e756fed655b5efe59af5ebe01df15d0f7c656815 100644 (file)
@@ -280,4 +280,19 @@ extern int do_led (cmd_tbl_t *, int, int, char *[]);
 #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_ */
index 0d91575762fd75f360359be3c0ad26b493528235..155c9249a96eabcad83c3ec0d5384657cde7d36d 100644 (file)
@@ -71,7 +71,8 @@
 #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                 */
 
@@ -84,6 +85,7 @@
                        CFG_CMD_CACHE   | \
                        CFG_CMD_DATE    | \
                        CFG_CMD_DHCP    | \
+                       CFG_CMD_DIAG    | \
                        CFG_CMD_DOC     | \
                        CFG_CMD_DTT     | \
                        CFG_CMD_ECHO    | \
diff --git a/include/cmd_diag.h b/include/cmd_diag.h
new file mode 100644 (file)
index 0000000..8834a7f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * (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 */
index 630e74e3c60c8b012052e80a6ed65f221ccefb2f..c8dc5e75827d4d197ce7539c6ff5cc89604bc01e 100644 (file)
@@ -220,6 +220,7 @@ void        load_sernum_ethaddr (void);
 /* $(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);
@@ -332,6 +333,8 @@ uint        dpram_base(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
index 87ac7dfeaf64d9bd543d2ac128824eda1539a6be..4fbade694fad8777932d589aa1a2281d428476e5 100644 (file)
 #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
index e7ac586723ba1a0d2ca75ccab76adc6c656b4709..4ca803c7f62c05c46220ae1e1188ca50894bf1f1 100644 (file)
@@ -88,6 +88,8 @@
 # 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 | \
index a4e8834ec9b0242a21688aeb49aabaf208378096..fe32e40b597b0d9b1a5dd36a28e9dea30174b266 100644 (file)
 #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            */
@@ -70,6 +72,8 @@
 #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)      */
index 7ced2eb0a0e62af254e82c7cc2f82f810067991c..e0db45eab8c85e75902dc212de40053e273d0c76 100644 (file)
 
 #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
index 5bb64c000a8569e57aa77d924a8bb15bc556b1b8..8314885de92885586061c4e13498ba1c19300dd5 100644 (file)
 #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 */
index 6d5d71b0f5aa16e2cec63b817ab8637c69f18b30..503da1daf126b105c9c2a7fe00edf0f24d026e40 100644 (file)
     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 ) \
diff --git a/include/post.h b/include/post.h
new file mode 100644 (file)
index 0000000..a6d4016
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * (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 */
index b3c9d81cef7273a17a8fb89a8102604a88355539..4cc2c101a68060ec97427a5e7ad6e4b627ea703e 100644 (file)
@@ -51,7 +51,7 @@ static struct tag *params;
 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;
index 104fe59bf9fee3fa474cb3edddd4d8d848d522ea..145a09d4ec0b219f89de871ac86ef236aae6bb2c 100644 (file)
@@ -29,6 +29,8 @@
 #include <command.h>
 #include <devices.h>
 #include <version.h>
+#include <net.h>
+
 
 const char version_string[] =
        PPCBOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
@@ -202,6 +204,26 @@ void start_armboot (void)
        /* 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 ();
 
index afe74cd493d5120e0736412f3072b766fe628448..e843aa21346cbeedac24f2c5f3ed62b270765dff 100644 (file)
@@ -54,6 +54,9 @@
 #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);
@@ -547,6 +550,13 @@ void board_init_f (ulong bootflag)
 
        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);
@@ -622,6 +632,12 @@ void board_init_r (gd_t *id, ulong dest_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
@@ -666,7 +682,7 @@ void board_init_r (gd_t *id, ulong dest_addr)
                }
                putc ('\n');
 #else
-               print_size (flash_size, "");
+               print_size (flash_size, "\n");
 #endif /* CFG_FLASH_CHECKSUM */
        } else {
                puts (failed);
@@ -880,6 +896,14 @@ void board_init_r (gd_t *id, ulong dest_addr)
        }
 #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. */
diff --git a/post/Makefile b/post/Makefile
new file mode 100644 (file)
index 0000000..2877b53
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# (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
diff --git a/post/cache.c b/post/cache.c
new file mode 100644 (file)
index 0000000..c15be75
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * (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 */
diff --git a/post/cache_8xx.S b/post/cache_8xx.S
new file mode 100644 (file)
index 0000000..19a9a23
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ *  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 */
diff --git a/post/cpu.c b/post/cpu.c
new file mode 100644 (file)
index 0000000..85f9b4d
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * (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 */
diff --git a/post/cpu/Makefile b/post/cpu/Makefile
new file mode 100644 (file)
index 0000000..43fc044
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# (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
diff --git a/post/cpu/andi.c b/post/cpu/andi.c
new file mode 100644 (file)
index 0000000..7ddf2ab
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * (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
diff --git a/post/cpu/asm.S b/post/cpu/asm.S
new file mode 100644 (file)
index 0000000..a0815a4
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ *  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
diff --git a/post/cpu/b.c b/post/cpu/b.c
new file mode 100644 (file)
index 0000000..751aba7
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * (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
diff --git a/post/cpu/cmp.c b/post/cpu/cmp.c
new file mode 100644 (file)
index 0000000..1e43c12
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * (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
diff --git a/post/cpu/cmpi.c b/post/cpu/cmpi.c
new file mode 100644 (file)
index 0000000..751430d
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * (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
diff --git a/post/cpu/complex.c b/post/cpu/complex.c
new file mode 100644 (file)
index 0000000..dc8b080
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * (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
diff --git a/post/cpu/cpu_asm.h b/post/cpu/cpu_asm.h
new file mode 100644 (file)
index 0000000..1cbaf41
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * (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 */
diff --git a/post/cpu/cr.c b/post/cpu/cr.c
new file mode 100644 (file)
index 0000000..1546758
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * (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
diff --git a/post/cpu/load.c b/post/cpu/load.c
new file mode 100644 (file)
index 0000000..b3418ef
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * (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
diff --git a/post/cpu/multi.c b/post/cpu/multi.c
new file mode 100644 (file)
index 0000000..bdad5d9
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * (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
diff --git a/post/cpu/rlwimi.c b/post/cpu/rlwimi.c
new file mode 100644 (file)
index 0000000..f65f79a
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * (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
diff --git a/post/cpu/rlwinm.c b/post/cpu/rlwinm.c
new file mode 100644 (file)
index 0000000..e240c41
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * (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
diff --git a/post/cpu/rlwnm.c b/post/cpu/rlwnm.c
new file mode 100644 (file)
index 0000000..523cf4d
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * (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
diff --git a/post/cpu/srawi.c b/post/cpu/srawi.c
new file mode 100644 (file)
index 0000000..91c82c9
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * (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
diff --git a/post/cpu/store.c b/post/cpu/store.c
new file mode 100644 (file)
index 0000000..e5189c7
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * (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
diff --git a/post/cpu/string.c b/post/cpu/string.c
new file mode 100644 (file)
index 0000000..a19a755
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * (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
diff --git a/post/cpu/three.c b/post/cpu/three.c
new file mode 100644 (file)
index 0000000..87bdee4
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * (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
diff --git a/post/cpu/threei.c b/post/cpu/threei.c
new file mode 100644 (file)
index 0000000..e7d74fe
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * (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
diff --git a/post/cpu/threex.c b/post/cpu/threex.c
new file mode 100644 (file)
index 0000000..1fa6ed1
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * (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
diff --git a/post/cpu/two.c b/post/cpu/two.c
new file mode 100644 (file)
index 0000000..8e6b771
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * (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
diff --git a/post/cpu/twox.c b/post/cpu/twox.c
new file mode 100644 (file)
index 0000000..431308f
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * (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
diff --git a/post/ether.c b/post/ether.c
new file mode 100644 (file)
index 0000000..af3befe
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * (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 */
diff --git a/post/i2c.c b/post/i2c.c
new file mode 100644 (file)
index 0000000..b962483
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * (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 */
diff --git a/post/memory.c b/post/memory.c
new file mode 100644 (file)
index 0000000..f32c107
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * (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 */
diff --git a/post/post.c b/post/post.c
new file mode 100644 (file)
index 0000000..4f4b72f
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * (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 */
diff --git a/post/rtc.c b/post/rtc.c
new file mode 100644 (file)
index 0000000..0ca35fc
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * (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 */
diff --git a/post/rules.mk b/post/rules.mk
new file mode 100644 (file)
index 0000000..1ad6959
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# (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
+
+#########################################################################
diff --git a/post/spr.c b/post/spr.c
new file mode 100644 (file)
index 0000000..458dd1f
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * (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 */
diff --git a/post/tests.c b/post/tests.c
new file mode 100644 (file)
index 0000000..b200703
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * (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,
+        &ether_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 */
diff --git a/post/uart.c b/post/uart.c
new file mode 100644 (file)
index 0000000..202ffcf
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * (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 */
diff --git a/post/usb.c b/post/usb.c
new file mode 100644 (file)
index 0000000..2bfa64e
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * (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 */
diff --git a/post/watchdog.c b/post/watchdog.c
new file mode 100644 (file)
index 0000000..7b74c3d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * (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 */