uboot/post/lib_powerpc/two.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2002
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6
   7#include <common.h>
   8#include <irq_func.h>
   9
  10/*
  11 * CPU test
  12 * Binary instructions          instr rD,rA
  13 *
  14 * Logic instructions:          neg
  15 * Arithmetic instructions:     addme, addze, subfme, subfze
  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_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
  28extern ulong cpu_post_makecr (long v);
  29
  30static struct cpu_post_two_s
  31{
  32    ulong cmd;
  33    ulong op;
  34    ulong res;
  35} cpu_post_two_table[] =
  36{
  37    {
  38        OP_NEG,
  39        3,
  40        -3
  41    },
  42    {
  43        OP_NEG,
  44        5,
  45        -5
  46    },
  47    {
  48        OP_ADDME,
  49        6,
  50        5
  51    },
  52    {
  53        OP_ADDZE,
  54        5,
  55        5
  56    },
  57    {
  58        OP_SUBFME,
  59        6,
  60        ~6 - 1
  61    },
  62    {
  63        OP_SUBFZE,
  64        5,
  65        ~5
  66    },
  67};
  68static unsigned int cpu_post_two_size = ARRAY_SIZE(cpu_post_two_table);
  69
  70int cpu_post_test_two (void)
  71{
  72    int ret = 0;
  73    unsigned int i, reg;
  74    int flag = disable_interrupts();
  75
  76    for (i = 0; i < cpu_post_two_size && ret == 0; i++)
  77    {
  78        struct cpu_post_two_s *test = cpu_post_two_table + i;
  79
  80        for (reg = 0; reg < 32 && ret == 0; reg++)
  81        {
  82            unsigned int reg0 = (reg + 0) % 32;
  83            unsigned int reg1 = (reg + 1) % 32;
  84            unsigned int stk = reg < 16 ? 31 : 15;
  85            unsigned long code[] =
  86            {
  87                ASM_STW(stk, 1, -4),
  88                ASM_ADDI(stk, 1, -16),
  89                ASM_STW(3, stk, 8),
  90                ASM_STW(reg0, stk, 4),
  91                ASM_STW(reg1, stk, 0),
  92                ASM_LWZ(reg0, stk, 8),
  93                ASM_11(test->cmd, reg1, reg0),
  94                ASM_STW(reg1, stk, 8),
  95                ASM_LWZ(reg1, stk, 0),
  96                ASM_LWZ(reg0, stk, 4),
  97                ASM_LWZ(3, stk, 8),
  98                ASM_ADDI(1, stk, 16),
  99                ASM_LWZ(stk, 1, -4),
 100                ASM_BLR,
 101            };
 102            unsigned long codecr[] =
 103            {
 104                ASM_STW(stk, 1, -4),
 105                ASM_ADDI(stk, 1, -16),
 106                ASM_STW(3, stk, 8),
 107                ASM_STW(reg0, stk, 4),
 108                ASM_STW(reg1, stk, 0),
 109                ASM_LWZ(reg0, stk, 8),
 110                ASM_11(test->cmd, reg1, reg0) | BIT_C,
 111                ASM_STW(reg1, stk, 8),
 112                ASM_LWZ(reg1, stk, 0),
 113                ASM_LWZ(reg0, stk, 4),
 114                ASM_LWZ(3, stk, 8),
 115                ASM_ADDI(1, stk, 16),
 116                ASM_LWZ(stk, 1, -4),
 117                ASM_BLR,
 118            };
 119            ulong res;
 120            ulong cr;
 121
 122            if (ret == 0)
 123            {
 124                cr = 0;
 125                cpu_post_exec_21 (code, & cr, & res, test->op);
 126
 127                ret = res == test->res && cr == 0 ? 0 : -1;
 128
 129                if (ret != 0)
 130                {
 131                    post_log ("Error at two test %d !\n", i);
 132                }
 133            }
 134
 135            if (ret == 0)
 136            {
 137                cpu_post_exec_21 (codecr, & cr, & res, test->op);
 138
 139                ret = res == test->res &&
 140                      (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
 141
 142                if (ret != 0)
 143                {
 144                    post_log ("Error at two test %d !\n", i);
 145                }
 146            }
 147        }
 148    }
 149
 150    if (flag)
 151        enable_interrupts();
 152
 153    return ret;
 154}
 155
 156#endif
 157