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