Das U-Boot: Universal Boot Loader
authorwdenk <wdenk>
Thu, 12 Sep 2002 22:01:13 +0000 (22:01 +0000)
committerwdenk <wdenk>
Thu, 12 Sep 2002 22:01:13 +0000 (22:01 +0000)
13 files changed:
common/cmd_diag.c [new file with mode: 0644]
include/cmd_diag.h [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/complex.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]

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 */
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 */
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/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/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