uboot/post/lib_powerpc/threex.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9
  10/*
  11 * CPU test
  12 * Ternary instructions         instr rA,rS,rB
  13 *
  14 * Logic instructions:          or, orc, xor, nand, nor, eqv
  15 * Shift instructions:          slw, srw, sraw
  16 *
  17 * The test contains a pre-built table of instructions, operands and
  18 * expected results. For each table entry, the test will cyclically use
  19 * different sets of operand registers and result registers.
  20 */
  21
  22#include <post.h>
  23#include "cpu_asm.h"
  24
  25#if CONFIG_POST & CONFIG_SYS_POST_CPU
  26
  27extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
  28    ulong op2);
  29extern ulong cpu_post_makecr (long v);
  30
  31static struct cpu_post_threex_s
  32{
  33    ulong cmd;
  34    ulong op1;
  35    ulong op2;
  36    ulong res;
  37} cpu_post_threex_table[] =
  38{
  39    {
  40        OP_OR,
  41        0x1234,
  42        0x5678,
  43        0x1234 | 0x5678
  44    },
  45    {
  46        OP_ORC,
  47        0x1234,
  48        0x5678,
  49        0x1234 | ~0x5678
  50    },
  51    {
  52        OP_XOR,
  53        0x1234,
  54        0x5678,
  55        0x1234 ^ 0x5678
  56    },
  57    {
  58        OP_NAND,
  59        0x1234,
  60        0x5678,
  61        ~(0x1234 & 0x5678)
  62    },
  63    {
  64        OP_NOR,
  65        0x1234,
  66        0x5678,
  67        ~(0x1234 | 0x5678)
  68    },
  69    {
  70        OP_EQV,
  71        0x1234,
  72        0x5678,
  73        ~(0x1234 ^ 0x5678)
  74    },
  75    {
  76        OP_SLW,
  77        0x80,
  78        16,
  79        0x800000
  80    },
  81    {
  82        OP_SLW,
  83        0x80,
  84        32,
  85        0
  86    },
  87    {
  88        OP_SRW,
  89        0x800000,
  90        16,
  91        0x80
  92    },
  93    {
  94        OP_SRW,
  95        0x800000,
  96        32,
  97        0
  98    },
  99    {
 100        OP_SRAW,
 101        0x80000000,
 102        3,
 103        0xf0000000
 104    },
 105    {
 106        OP_SRAW,
 107        0x8000,
 108        3,
 109        0x1000
 110    },
 111};
 112static unsigned int cpu_post_threex_size = ARRAY_SIZE(cpu_post_threex_table);
 113
 114int cpu_post_test_threex (void)
 115{
 116    int ret = 0;
 117    unsigned int i, reg;
 118    int flag = disable_interrupts();
 119
 120    for (i = 0; i < cpu_post_threex_size && ret == 0; i++)
 121    {
 122        struct cpu_post_threex_s *test = cpu_post_threex_table + i;
 123
 124        for (reg = 0; reg < 32 && ret == 0; reg++)
 125        {
 126            unsigned int reg0 = (reg + 0) % 32;
 127            unsigned int reg1 = (reg + 1) % 32;
 128            unsigned int reg2 = (reg + 2) % 32;
 129            unsigned int stk = reg < 16 ? 31 : 15;
 130            unsigned long code[] =
 131            {
 132                ASM_STW(stk, 1, -4),
 133                ASM_ADDI(stk, 1, -24),
 134                ASM_STW(3, stk, 12),
 135                ASM_STW(4, stk, 16),
 136                ASM_STW(reg0, stk, 8),
 137                ASM_STW(reg1, stk, 4),
 138                ASM_STW(reg2, stk, 0),
 139                ASM_LWZ(reg1, stk, 12),
 140                ASM_LWZ(reg0, stk, 16),
 141                ASM_12X(test->cmd, reg2, reg1, reg0),
 142                ASM_STW(reg2, stk, 12),
 143                ASM_LWZ(reg2, stk, 0),
 144                ASM_LWZ(reg1, stk, 4),
 145                ASM_LWZ(reg0, stk, 8),
 146                ASM_LWZ(3, stk, 12),
 147                ASM_ADDI(1, stk, 24),
 148                ASM_LWZ(stk, 1, -4),
 149                ASM_BLR,
 150            };
 151            unsigned long codecr[] =
 152            {
 153                ASM_STW(stk, 1, -4),
 154                ASM_ADDI(stk, 1, -24),
 155                ASM_STW(3, stk, 12),
 156                ASM_STW(4, stk, 16),
 157                ASM_STW(reg0, stk, 8),
 158                ASM_STW(reg1, stk, 4),
 159                ASM_STW(reg2, stk, 0),
 160                ASM_LWZ(reg1, stk, 12),
 161                ASM_LWZ(reg0, stk, 16),
 162                ASM_12X(test->cmd, reg2, reg1, reg0) | BIT_C,
 163                ASM_STW(reg2, stk, 12),
 164                ASM_LWZ(reg2, stk, 0),
 165                ASM_LWZ(reg1, stk, 4),
 166                ASM_LWZ(reg0, stk, 8),
 167                ASM_LWZ(3, stk, 12),
 168                ASM_ADDI(1, stk, 24),
 169                ASM_LWZ(stk, 1, -4),
 170                ASM_BLR,
 171            };
 172            ulong res;
 173            ulong cr;
 174
 175            if (ret == 0)
 176            {
 177                cr = 0;
 178                cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
 179
 180                ret = res == test->res && cr == 0 ? 0 : -1;
 181
 182                if (ret != 0)
 183                {
 184                    post_log ("Error at threex test %d !\n", i);
 185                }
 186            }
 187
 188            if (ret == 0)
 189            {
 190                cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
 191
 192                ret = res == test->res &&
 193                      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
 194
 195                if (ret != 0)
 196                {
 197                    post_log ("Error at threex test %d !\n", i);
 198                }
 199            }
 200        }
 201    }
 202
 203    if (flag)
 204        enable_interrupts();
 205
 206    return ret;
 207}
 208
 209#endif
 210