uboot/post/lib_powerpc/store.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 * Store instructions:          stb(x)(u), sth(x)(u), stw(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 value of the index register and
  22 * the value of the source register. After executing the
  23 * instruction, the test verifies the contents of the array
  24 * and the value of the base register (it must change for "store
  25 * 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_12w (ulong *code, ulong *op1, ulong op2, ulong op3);
  34extern void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2);
  35
  36static struct cpu_post_store_s
  37{
  38    ulong cmd;
  39    uint width;
  40    int update;
  41    int index;
  42    ulong offset;
  43    ulong value;
  44} cpu_post_store_table[] =
  45{
  46    {
  47        OP_STW,
  48        4,
  49        0,
  50        0,
  51        -4,
  52        0xff00ff00
  53    },
  54    {
  55        OP_STH,
  56        2,
  57        0,
  58        0,
  59        -2,
  60        0xff00
  61    },
  62    {
  63        OP_STB,
  64        1,
  65        0,
  66        0,
  67        -1,
  68        0xff
  69    },
  70    {
  71        OP_STWU,
  72        4,
  73        1,
  74        0,
  75        -4,
  76        0xff00ff00
  77    },
  78    {
  79        OP_STHU,
  80        2,
  81        1,
  82        0,
  83        -2,
  84        0xff00
  85    },
  86    {
  87        OP_STBU,
  88        1,
  89        1,
  90        0,
  91        -1,
  92        0xff
  93    },
  94    {
  95        OP_STWX,
  96        4,
  97        0,
  98        1,
  99        -4,
 100        0xff00ff00
 101    },
 102    {
 103        OP_STHX,
 104        2,
 105        0,
 106        1,
 107        -2,
 108        0xff00
 109    },
 110    {
 111        OP_STBX,
 112        1,
 113        0,
 114        1,
 115        -1,
 116        0xff
 117    },
 118    {
 119        OP_STWUX,
 120        4,
 121        1,
 122        1,
 123        -4,
 124        0xff00ff00
 125    },
 126    {
 127        OP_STHUX,
 128        2,
 129        1,
 130        1,
 131        -2,
 132        0xff00
 133    },
 134    {
 135        OP_STBUX,
 136        1,
 137        1,
 138        1,
 139        -1,
 140        0xff
 141    },
 142};
 143static unsigned int cpu_post_store_size = ARRAY_SIZE(cpu_post_store_table);
 144
 145int cpu_post_test_store (void)
 146{
 147    int ret = 0;
 148    unsigned int i;
 149    int flag = disable_interrupts();
 150
 151    for (i = 0; i < cpu_post_store_size && ret == 0; i++)
 152    {
 153        struct cpu_post_store_s *test = cpu_post_store_table + i;
 154        uchar data[16] =
 155        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 156        ulong base0 = (ulong) (data + 8);
 157        ulong base = base0;
 158
 159        if (test->index)
 160        {
 161            ulong code[] =
 162            {
 163                ASM_12(test->cmd, 5, 3, 4),
 164                ASM_BLR,
 165            };
 166
 167            cpu_post_exec_12w (code, &base, test->offset, test->value);
 168        }
 169        else
 170        {
 171            ulong code[] =
 172            {
 173                ASM_11I(test->cmd, 4, 3, test->offset),
 174                ASM_BLR,
 175            };
 176
 177            cpu_post_exec_11w (code, &base, test->value);
 178        }
 179
 180        if (ret == 0)
 181        {
 182           if (test->update)
 183               ret = base == base0 + test->offset ? 0 : -1;
 184           else
 185               ret = base == base0 ? 0 : -1;
 186        }
 187
 188        if (ret == 0)
 189        {
 190            switch (test->width)
 191            {
 192            case 1:
 193                ret = *(uchar *)(base0 + test->offset) == test->value ?
 194                      0 : -1;
 195                break;
 196            case 2:
 197                ret = *(ushort *)(base0 + test->offset) == test->value ?
 198                      0 : -1;
 199                break;
 200            case 4:
 201                ret = *(ulong *)(base0 + test->offset) == test->value ?
 202                      0 : -1;
 203                break;
 204            }
 205        }
 206
 207        if (ret != 0)
 208        {
 209            post_log ("Error at store test %d !\n", i);
 210        }
 211    }
 212
 213    if (flag)
 214        enable_interrupts();
 215
 216    return ret;
 217}
 218
 219#endif
 220