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 =
  63    sizeof (cpu_post_cr_table1) / sizeof (ulong);
  64
  65static struct cpu_post_cr_s2 {
  66    ulong xer;
  67    ulong cr;
  68} cpu_post_cr_table2[] =
  69{
  70    {
  71        0xa0000000,
  72        1
  73    },
  74    {
  75        0x40000000,
  76        5
  77    },
  78};
  79static unsigned int cpu_post_cr_size2 =
  80    sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
  81
  82static struct cpu_post_cr_s3 {
  83    ulong cr;
  84    ulong cs;
  85    ulong cd;
  86    ulong res;
  87} cpu_post_cr_table3[] =
  88{
  89    {
  90        0x01234567,
  91        0,
  92        4,
  93        0x01230567
  94    },
  95    {
  96        0x01234567,
  97        7,
  98        0,
  99        0x71234567
 100    },
 101};
 102static unsigned int cpu_post_cr_size3 =
 103    sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
 104
 105static struct cpu_post_cr_s4 {
 106    ulong cmd;
 107    ulong cr;
 108    ulong op1;
 109    ulong op2;
 110    ulong op3;
 111    ulong res;
 112} cpu_post_cr_table4[] =
 113{
 114    {
 115        OP_CRAND,
 116        0x0000ffff,
 117        0,
 118        16,
 119        0,
 120        0x0000ffff
 121    },
 122    {
 123        OP_CRAND,
 124        0x0000ffff,
 125        16,
 126        17,
 127        0,
 128        0x8000ffff
 129    },
 130    {
 131        OP_CRANDC,
 132        0x0000ffff,
 133        0,
 134        16,
 135        0,
 136        0x0000ffff
 137    },
 138    {
 139        OP_CRANDC,
 140        0x0000ffff,
 141        16,
 142        0,
 143        0,
 144        0x8000ffff
 145    },
 146    {
 147        OP_CROR,
 148        0x0000ffff,
 149        0,
 150        16,
 151        0,
 152        0x8000ffff
 153    },
 154    {
 155        OP_CROR,
 156        0x0000ffff,
 157        0,
 158        1,
 159        0,
 160        0x0000ffff
 161    },
 162    {
 163        OP_CRORC,
 164        0x0000ffff,
 165        0,
 166        16,
 167        0,
 168        0x0000ffff
 169    },
 170    {
 171        OP_CRORC,
 172        0x0000ffff,
 173        0,
 174        0,
 175        0,
 176        0x8000ffff
 177    },
 178    {
 179        OP_CRXOR,
 180        0x0000ffff,
 181        0,
 182        0,
 183        0,
 184        0x0000ffff
 185    },
 186    {
 187        OP_CRXOR,
 188        0x0000ffff,
 189        0,
 190        16,
 191        0,
 192        0x8000ffff
 193    },
 194    {
 195        OP_CRNAND,
 196        0x0000ffff,
 197        0,
 198        16,
 199        0,
 200        0x8000ffff
 201    },
 202    {
 203        OP_CRNAND,
 204        0x0000ffff,
 205        16,
 206        17,
 207        0,
 208        0x0000ffff
 209    },
 210    {
 211        OP_CRNOR,
 212        0x0000ffff,
 213        0,
 214        16,
 215        0,
 216        0x0000ffff
 217    },
 218    {
 219        OP_CRNOR,
 220        0x0000ffff,
 221        0,
 222        1,
 223        0,
 224        0x8000ffff
 225    },
 226    {
 227        OP_CREQV,
 228        0x0000ffff,
 229        0,
 230        0,
 231        0,
 232        0x8000ffff
 233    },
 234    {
 235        OP_CREQV,
 236        0x0000ffff,
 237        0,
 238        16,
 239        0,
 240        0x0000ffff
 241    },
 242};
 243static unsigned int cpu_post_cr_size4 =
 244    sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
 245
 246int cpu_post_test_cr (void)
 247{
 248    int ret = 0;
 249    unsigned int i;
 250    unsigned long cr_sav;
 251    int flag = disable_interrupts();
 252
 253    asm ( "mfcr %0" : "=r" (cr_sav) : );
 254
 255    for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
 256    {
 257        ulong cr = cpu_post_cr_table1[i];
 258        ulong res;
 259
 260        unsigned long code[] =
 261        {
 262            ASM_MTCR(3),
 263            ASM_MFCR(3),
 264            ASM_BLR,
 265        };
 266
 267        cpu_post_exec_11 (code, &res, cr);
 268
 269        ret = res == cr ? 0 : -1;
 270
 271        if (ret != 0)
 272        {
 273            post_log ("Error at cr1 test %d !\n", i);
 274        }
 275    }
 276
 277    for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
 278    {
 279        struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
 280        ulong res;
 281        ulong xer;
 282
 283        unsigned long code[] =
 284        {
 285            ASM_MTXER(3),
 286            ASM_MCRXR(test->cr),
 287            ASM_MFCR(3),
 288            ASM_MFXER(4),
 289            ASM_BLR,
 290        };
 291
 292        cpu_post_exec_21x (code, &res, &xer, test->xer);
 293
 294        ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
 295              0 : -1;
 296
 297        if (ret != 0)
 298        {
 299            post_log ("Error at cr2 test %d !\n", i);
 300        }
 301    }
 302
 303    for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
 304    {
 305        struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
 306        ulong res;
 307
 308        unsigned long code[] =
 309        {
 310            ASM_MTCR(3),
 311            ASM_MCRF(test->cd, test->cs),
 312            ASM_MFCR(3),
 313            ASM_BLR,
 314        };
 315
 316        cpu_post_exec_11 (code, &res, test->cr);
 317
 318        ret = res == test->res ? 0 : -1;
 319
 320        if (ret != 0)
 321        {
 322            post_log ("Error at cr3 test %d !\n", i);
 323        }
 324    }
 325
 326    for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
 327    {
 328        struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
 329        ulong res;
 330
 331        unsigned long code[] =
 332        {
 333            ASM_MTCR(3),
 334            ASM_12F(test->cmd, test->op3, test->op1, test->op2),
 335            ASM_MFCR(3),
 336            ASM_BLR,
 337        };
 338
 339        cpu_post_exec_11 (code, &res, test->cr);
 340
 341        ret = res == test->res ? 0 : -1;
 342
 343        if (ret != 0)
 344        {
 345            post_log ("Error at cr4 test %d !\n", i);
 346        }
 347    }
 348
 349    asm ( "mtcr %0" : : "r" (cr_sav));
 350
 351    if (flag)
 352        enable_interrupts();
 353
 354    return ret;
 355}
 356
 357#endif
 358