1 /* 2 * (C) Copyright 2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 10 /* 11 * CPU test 12 * Binary instructions instr rA,rS 13 * 14 * Logic instructions: cntlzw 15 * Arithmetic instructions: extsb, extsh 16 17 * The test contains a pre-built table of instructions, operands and 18 * expected results. For each table entry, the test will cyclically use 19 * different sets of operand registers and result registers. 20 */ 21 22 #include <post.h> 23 #include "cpu_asm.h" 24 25 #if CONFIG_POST & CONFIG_SYS_POST_CPU 26 27 extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1); 28 extern ulong cpu_post_makecr (long v); 29 30 static struct cpu_post_twox_s 31 { 32 ulong cmd; 33 ulong op; 34 ulong res; 35 } cpu_post_twox_table[] = 36 { 37 { 38 OP_EXTSB, 39 3, 40 3 41 }, 42 { 43 OP_EXTSB, 44 0xff, 45 -1 46 }, 47 { 48 OP_EXTSH, 49 3, 50 3 51 }, 52 { 53 OP_EXTSH, 54 0xff, 55 0xff 56 }, 57 { 58 OP_EXTSH, 59 0xffff, 60 -1 61 }, 62 { 63 OP_CNTLZW, 64 0x000fffff, 65 12 66 }, 67 }; 68 static unsigned int cpu_post_twox_size = ARRAY_SIZE(cpu_post_twox_table); 69 70 int cpu_post_test_twox (void) 71 { 72 int ret = 0; 73 unsigned int i, reg; 74 int flag = disable_interrupts(); 75 76 for (i = 0; i < cpu_post_twox_size && ret == 0; i++) 77 { 78 struct cpu_post_twox_s *test = cpu_post_twox_table + i; 79 80 for (reg = 0; reg < 32 && ret == 0; reg++) 81 { 82 unsigned int reg0 = (reg + 0) % 32; 83 unsigned int reg1 = (reg + 1) % 32; 84 unsigned int stk = reg < 16 ? 31 : 15; 85 unsigned long code[] = 86 { 87 ASM_STW(stk, 1, -4), 88 ASM_ADDI(stk, 1, -16), 89 ASM_STW(3, stk, 8), 90 ASM_STW(reg0, stk, 4), 91 ASM_STW(reg1, stk, 0), 92 ASM_LWZ(reg0, stk, 8), 93 ASM_11X(test->cmd, reg1, reg0), 94 ASM_STW(reg1, stk, 8), 95 ASM_LWZ(reg1, stk, 0), 96 ASM_LWZ(reg0, stk, 4), 97 ASM_LWZ(3, stk, 8), 98 ASM_ADDI(1, stk, 16), 99 ASM_LWZ(stk, 1, -4), 100 ASM_BLR, 101 }; 102 unsigned long codecr[] = 103 { 104 ASM_STW(stk, 1, -4), 105 ASM_ADDI(stk, 1, -16), 106 ASM_STW(3, stk, 8), 107 ASM_STW(reg0, stk, 4), 108 ASM_STW(reg1, stk, 0), 109 ASM_LWZ(reg0, stk, 8), 110 ASM_11X(test->cmd, reg1, reg0) | BIT_C, 111 ASM_STW(reg1, stk, 8), 112 ASM_LWZ(reg1, stk, 0), 113 ASM_LWZ(reg0, stk, 4), 114 ASM_LWZ(3, stk, 8), 115 ASM_ADDI(1, stk, 16), 116 ASM_LWZ(stk, 1, -4), 117 ASM_BLR, 118 }; 119 ulong res; 120 ulong cr; 121 122 if (ret == 0) 123 { 124 cr = 0; 125 cpu_post_exec_21 (code, & cr, & res, test->op); 126 127 ret = res == test->res && cr == 0 ? 0 : -1; 128 129 if (ret != 0) 130 { 131 post_log ("Error at twox test %d !\n", i); 132 } 133 } 134 135 if (ret == 0) 136 { 137 cpu_post_exec_21 (codecr, & cr, & res, test->op); 138 139 ret = res == test->res && 140 (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1; 141 142 if (ret != 0) 143 { 144 post_log ("Error at twox test %d !\n", i); 145 } 146 } 147 } 148 } 149 150 if (flag) 151 enable_interrupts(); 152 153 return ret; 154 } 155 156 #endif 157