uboot/post/lib_powerpc/twox.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25
  26/*
  27 * CPU test
  28 * Binary instructions          instr rA,rS
  29 *
  30 * Logic instructions:          cntlzw
  31 * Arithmetic instructions:     extsb, extsh
  32
  33 * The test contains a pre-built table of instructions, operands and
  34 * expected results. For each table entry, the test will cyclically use
  35 * different sets of operand registers and result registers.
  36 */
  37
  38#include <post.h>
  39#include "cpu_asm.h"
  40
  41#if CONFIG_POST & CONFIG_SYS_POST_CPU
  42
  43extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
  44extern ulong cpu_post_makecr (long v);
  45
  46static struct cpu_post_twox_s
  47{
  48    ulong cmd;
  49    ulong op;
  50    ulong res;
  51} cpu_post_twox_table[] =
  52{
  53    {
  54        OP_EXTSB,
  55        3,
  56        3
  57    },
  58    {
  59        OP_EXTSB,
  60        0xff,
  61        -1
  62    },
  63    {
  64        OP_EXTSH,
  65        3,
  66        3
  67    },
  68    {
  69        OP_EXTSH,
  70        0xff,
  71        0xff
  72    },
  73    {
  74        OP_EXTSH,
  75        0xffff,
  76        -1
  77    },
  78    {
  79        OP_CNTLZW,
  80        0x000fffff,
  81        12
  82    },
  83};
  84static unsigned int cpu_post_twox_size = ARRAY_SIZE(cpu_post_twox_table);
  85
  86int cpu_post_test_twox (void)
  87{
  88    int ret = 0;
  89    unsigned int i, reg;
  90    int flag = disable_interrupts();
  91
  92    for (i = 0; i < cpu_post_twox_size && ret == 0; i++)
  93    {
  94        struct cpu_post_twox_s *test = cpu_post_twox_table + i;
  95
  96        for (reg = 0; reg < 32 && ret == 0; reg++)
  97        {
  98            unsigned int reg0 = (reg + 0) % 32;
  99            unsigned int reg1 = (reg + 1) % 32;
 100            unsigned int stk = reg < 16 ? 31 : 15;
 101            unsigned long code[] =
 102            {
 103                ASM_STW(stk, 1, -4),
 104                ASM_ADDI(stk, 1, -16),
 105                ASM_STW(3, stk, 8),
 106                ASM_STW(reg0, stk, 4),
 107                ASM_STW(reg1, stk, 0),
 108                ASM_LWZ(reg0, stk, 8),
 109                ASM_11X(test->cmd, reg1, reg0),
 110                ASM_STW(reg1, stk, 8),
 111                ASM_LWZ(reg1, stk, 0),
 112                ASM_LWZ(reg0, stk, 4),
 113                ASM_LWZ(3, stk, 8),
 114                ASM_ADDI(1, stk, 16),
 115                ASM_LWZ(stk, 1, -4),
 116                ASM_BLR,
 117            };
 118            unsigned long codecr[] =
 119            {
 120                ASM_STW(stk, 1, -4),
 121                ASM_ADDI(stk, 1, -16),
 122                ASM_STW(3, stk, 8),
 123                ASM_STW(reg0, stk, 4),
 124                ASM_STW(reg1, stk, 0),
 125                ASM_LWZ(reg0, stk, 8),
 126                ASM_11X(test->cmd, reg1, reg0) | BIT_C,
 127                ASM_STW(reg1, stk, 8),
 128                ASM_LWZ(reg1, stk, 0),
 129                ASM_LWZ(reg0, stk, 4),
 130                ASM_LWZ(3, stk, 8),
 131                ASM_ADDI(1, stk, 16),
 132                ASM_LWZ(stk, 1, -4),
 133                ASM_BLR,
 134            };
 135            ulong res;
 136            ulong cr;
 137
 138            if (ret == 0)
 139            {
 140                cr = 0;
 141                cpu_post_exec_21 (code, & cr, & res, test->op);
 142
 143                ret = res == test->res && cr == 0 ? 0 : -1;
 144
 145                if (ret != 0)
 146                {
 147                    post_log ("Error at twox test %d !\n", i);
 148                }
 149            }
 150
 151            if (ret == 0)
 152            {
 153                cpu_post_exec_21 (codecr, & cr, & res, test->op);
 154
 155                ret = res == test->res &&
 156                      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
 157
 158                if (ret != 0)
 159                {
 160                    post_log ("Error at twox test %d !\n", i);
 161                }
 162            }
 163        }
 164    }
 165
 166    if (flag)
 167        enable_interrupts();
 168
 169    return ret;
 170}
 171
 172#endif
 173