uboot/post/lib_powerpc/load.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 * Load instructions:           lbz(x)(u), lhz(x)(u), lha(x)(u), lwz(x)(u)
  13 *
  14 * All operations are performed on a 16-byte array. The array
  15 * is 4-byte aligned. The base register points to offset 8.
  16 * The immediate offset (index register) ranges in [-8 ... +7].
  17 * The test cases are composed so that they do not
  18 * cause alignment exceptions.
  19 * The test contains a pre-built table describing all test cases.
  20 * The table entry contains:
  21 * the instruction opcode, the array contents, the value of the index
  22 * register and the expected value of the destination register.
  23 * After executing the instruction, the test verifies the
  24 * value of the destination register and the value of the base
  25 * register (it must change for "load with update" instructions).
  26 */
  27
  28#include <post.h>
  29#include "cpu_asm.h"
  30
  31#if CONFIG_POST & CONFIG_SYS_POST_CPU
  32
  33extern void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3);
  34extern void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2);
  35
  36static struct cpu_post_load_s
  37{
  38    ulong cmd;
  39    uint width;
  40    int update;
  41    int index;
  42    ulong offset;
  43} cpu_post_load_table[] =
  44{
  45    {
  46        OP_LWZ,
  47        4,
  48        0,
  49        0,
  50        4
  51    },
  52    {
  53        OP_LHA,
  54        3,
  55        0,
  56        0,
  57        2
  58    },
  59    {
  60        OP_LHZ,
  61        2,
  62        0,
  63        0,
  64        2
  65    },
  66    {
  67        OP_LBZ,
  68        1,
  69        0,
  70        0,
  71        1
  72    },
  73    {
  74        OP_LWZU,
  75        4,
  76        1,
  77        0,
  78        4
  79    },
  80    {
  81        OP_LHAU,
  82        3,
  83        1,
  84        0,
  85        2
  86    },
  87    {
  88        OP_LHZU,
  89        2,
  90        1,
  91        0,
  92        2
  93    },
  94    {
  95        OP_LBZU,
  96        1,
  97        1,
  98        0,
  99        1
 100    },
 101    {
 102        OP_LWZX,
 103        4,
 104        0,
 105        1,
 106        4
 107    },
 108    {
 109        OP_LHAX,
 110        3,
 111        0,
 112        1,
 113        2
 114    },
 115    {
 116        OP_LHZX,
 117        2,
 118        0,
 119        1,
 120        2
 121    },
 122    {
 123        OP_LBZX,
 124        1,
 125        0,
 126        1,
 127        1
 128    },
 129    {
 130        OP_LWZUX,
 131        4,
 132        1,
 133        1,
 134        4
 135    },
 136    {
 137        OP_LHAUX,
 138        3,
 139        1,
 140        1,
 141        2
 142    },
 143    {
 144        OP_LHZUX,
 145        2,
 146        1,
 147        1,
 148        2
 149    },
 150    {
 151        OP_LBZUX,
 152        1,
 153        1,
 154        1,
 155        1
 156    },
 157};
 158static unsigned int cpu_post_load_size = ARRAY_SIZE(cpu_post_load_table);
 159
 160int cpu_post_test_load (void)
 161{
 162    int ret = 0;
 163    unsigned int i;
 164    int flag = disable_interrupts();
 165
 166    for (i = 0; i < cpu_post_load_size && ret == 0; i++)
 167    {
 168        struct cpu_post_load_s *test = cpu_post_load_table + i;
 169        uchar data[16] =
 170        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 171        ulong base0 = (ulong) (data + 8);
 172        ulong base = base0;
 173        ulong value;
 174
 175        if (test->index)
 176        {
 177            ulong code[] =
 178            {
 179                ASM_12(test->cmd, 5, 3, 4),
 180                ASM_BLR,
 181            };
 182
 183            cpu_post_exec_22w (code, &base, test->offset, &value);
 184        }
 185        else
 186        {
 187            ulong code[] =
 188            {
 189                ASM_11I(test->cmd, 4, 3, test->offset),
 190                ASM_BLR,
 191            };
 192
 193            cpu_post_exec_21w (code, &base, &value);
 194        }
 195
 196        if (ret == 0)
 197        {
 198           if (test->update)
 199               ret = base == base0 + test->offset ? 0 : -1;
 200           else
 201               ret = base == base0 ? 0 : -1;
 202        }
 203
 204        if (ret == 0)
 205        {
 206            switch (test->width)
 207            {
 208            case 1:
 209                ret = *(uchar *)(base0 + test->offset) == value ?
 210                      0 : -1;
 211                break;
 212            case 2:
 213                ret = *(ushort *)(base0 + test->offset) == value ?
 214                      0 : -1;
 215                break;
 216            case 3:
 217                ret = *(short *)(base0 + test->offset) == value ?
 218                      0 : -1;
 219                break;
 220            case 4:
 221                ret = *(ulong *)(base0 + test->offset) == value ?
 222                      0 : -1;
 223                break;
 224            }
 225        }
 226
 227        if (ret != 0)
 228        {
 229            post_log ("Error at load test %d !\n", i);
 230        }
 231    }
 232
 233    if (flag)
 234        enable_interrupts();
 235
 236    return ret;
 237}
 238
 239#endif
 240