uboot/post/lib_powerpc/cr.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 * Condition register istructions:      mtcr, mfcr, mcrxr,
  13 *                                      crand, crandc, cror, crorc, crxor,
  14 *                                      crnand, crnor, creqv, mcrf
  15 *
  16 * The mtcrf/mfcr instructions is tested by loading different
  17 * values into the condition register (mtcrf), moving its value
  18 * to a general-purpose register (mfcr) and comparing this value
  19 * with the expected one.
  20 * The mcrxr instruction is tested by loading a fixed value
  21 * into the XER register (mtspr), moving XER value to the
  22 * condition register (mcrxr), moving it to a general-purpose
  23 * register (mfcr) and comparing the value of this register with
  24 * the expected one.
  25 * The rest of instructions is tested by loading a fixed
  26 * value into the condition register (mtcrf), executing each
  27 * instruction several times to modify all 4-bit condition
  28 * fields, moving the value of the conditional register to a
  29 * general-purpose register (mfcr) and comparing it with the
  30 * expected one.
  31 */
  32
  33#include <post.h>
  34#include "cpu_asm.h"
  35
  36#if CONFIG_POST & CONFIG_SYS_POST_CPU
  37
  38extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
  39extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
  40
  41static ulong cpu_post_cr_table1[] =
  42{
  43    0xaaaaaaaa,
  44    0x55555555,
  45};
  46static unsigned int cpu_post_cr_size1 = ARRAY_SIZE(cpu_post_cr_table1);
  47
  48static struct cpu_post_cr_s2 {
  49    ulong xer;
  50    ulong cr;
  51} cpu_post_cr_table2[] =
  52{
  53    {
  54        0xa0000000,
  55        1
  56    },
  57    {
  58        0x40000000,
  59        5
  60    },
  61};
  62static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2);
  63
  64static struct cpu_post_cr_s3 {
  65    ulong cr;
  66    ulong cs;
  67    ulong cd;
  68    ulong res;
  69} cpu_post_cr_table3[] =
  70{
  71    {
  72        0x01234567,
  73        0,
  74        4,
  75        0x01230567
  76    },
  77    {
  78        0x01234567,
  79        7,
  80        0,
  81        0x71234567
  82    },
  83};
  84static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3);
  85
  86static struct cpu_post_cr_s4 {
  87    ulong cmd;
  88    ulong cr;
  89    ulong op1;
  90    ulong op2;
  91    ulong op3;
  92    ulong res;
  93} cpu_post_cr_table4[] =
  94{
  95    {
  96        OP_CRAND,
  97        0x0000ffff,
  98        0,
  99        16,
 100        0,
 101        0x0000ffff
 102    },
 103    {
 104        OP_CRAND,
 105        0x0000ffff,
 106        16,
 107        17,
 108        0,
 109        0x8000ffff
 110    },
 111    {
 112        OP_CRANDC,
 113        0x0000ffff,
 114        0,
 115        16,
 116        0,
 117        0x0000ffff
 118    },
 119    {
 120        OP_CRANDC,
 121        0x0000ffff,
 122        16,
 123        0,
 124        0,
 125        0x8000ffff
 126    },
 127    {
 128        OP_CROR,
 129        0x0000ffff,
 130        0,
 131        16,
 132        0,
 133        0x8000ffff
 134    },
 135    {
 136        OP_CROR,
 137        0x0000ffff,
 138        0,
 139        1,
 140        0,
 141        0x0000ffff
 142    },
 143    {
 144        OP_CRORC,
 145        0x0000ffff,
 146        0,
 147        16,
 148        0,
 149        0x0000ffff
 150    },
 151    {
 152        OP_CRORC,
 153        0x0000ffff,
 154        0,
 155        0,
 156        0,
 157        0x8000ffff
 158    },
 159    {
 160        OP_CRXOR,
 161        0x0000ffff,
 162        0,
 163        0,
 164        0,
 165        0x0000ffff
 166    },
 167    {
 168        OP_CRXOR,
 169        0x0000ffff,
 170        0,
 171        16,
 172        0,
 173        0x8000ffff
 174    },
 175    {
 176        OP_CRNAND,
 177        0x0000ffff,
 178        0,
 179        16,
 180        0,
 181        0x8000ffff
 182    },
 183    {
 184        OP_CRNAND,
 185        0x0000ffff,
 186        16,
 187        17,
 188        0,
 189        0x0000ffff
 190    },
 191    {
 192        OP_CRNOR,
 193        0x0000ffff,
 194        0,
 195        16,
 196        0,
 197        0x0000ffff
 198    },
 199    {
 200        OP_CRNOR,
 201        0x0000ffff,
 202        0,
 203        1,
 204        0,
 205        0x8000ffff
 206    },
 207    {
 208        OP_CREQV,
 209        0x0000ffff,
 210        0,
 211        0,
 212        0,
 213        0x8000ffff
 214    },
 215    {
 216        OP_CREQV,
 217        0x0000ffff,
 218        0,
 219        16,
 220        0,
 221        0x0000ffff
 222    },
 223};
 224static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4);
 225
 226int cpu_post_test_cr (void)
 227{
 228    int ret = 0;
 229    unsigned int i;
 230    unsigned long cr_sav;
 231    int flag = disable_interrupts();
 232
 233    asm ( "mfcr %0" : "=r" (cr_sav) : );
 234
 235    for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
 236    {
 237        ulong cr = cpu_post_cr_table1[i];
 238        ulong res;
 239
 240        unsigned long code[] =
 241        {
 242            ASM_MTCR(3),
 243            ASM_MFCR(3),
 244            ASM_BLR,
 245        };
 246
 247        cpu_post_exec_11 (code, &res, cr);
 248
 249        ret = res == cr ? 0 : -1;
 250
 251        if (ret != 0)
 252        {
 253            post_log ("Error at cr1 test %d !\n", i);
 254        }
 255    }
 256
 257    for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
 258    {
 259        struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
 260        ulong res;
 261        ulong xer;
 262
 263        unsigned long code[] =
 264        {
 265            ASM_MTXER(3),
 266            ASM_MCRXR(test->cr),
 267            ASM_MFCR(3),
 268            ASM_MFXER(4),
 269            ASM_BLR,
 270        };
 271
 272        cpu_post_exec_21x (code, &res, &xer, test->xer);
 273
 274        ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
 275              0 : -1;
 276
 277        if (ret != 0)
 278        {
 279            post_log ("Error at cr2 test %d !\n", i);
 280        }
 281    }
 282
 283    for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
 284    {
 285        struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
 286        ulong res;
 287
 288        unsigned long code[] =
 289        {
 290            ASM_MTCR(3),
 291            ASM_MCRF(test->cd, test->cs),
 292            ASM_MFCR(3),
 293            ASM_BLR,
 294        };
 295
 296        cpu_post_exec_11 (code, &res, test->cr);
 297
 298        ret = res == test->res ? 0 : -1;
 299
 300        if (ret != 0)
 301        {
 302            post_log ("Error at cr3 test %d !\n", i);
 303        }
 304    }
 305
 306    for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
 307    {
 308        struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
 309        ulong res;
 310
 311        unsigned long code[] =
 312        {
 313            ASM_MTCR(3),
 314            ASM_12F(test->cmd, test->op3, test->op1, test->op2),
 315            ASM_MFCR(3),
 316            ASM_BLR,
 317        };
 318
 319        cpu_post_exec_11 (code, &res, test->cr);
 320
 321        ret = res == test->res ? 0 : -1;
 322
 323        if (ret != 0)
 324        {
 325            post_log ("Error at cr4 test %d !\n", i);
 326        }
 327    }
 328
 329    asm ( "mtcr %0" : : "r" (cr_sav));
 330
 331    if (flag)
 332        enable_interrupts();
 333
 334    return ret;
 335}
 336
 337#endif
 338