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