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 * Binary instructions instr rA,rS 29 * 30 * Logic instructions: cntlzw 31 * Arithmetic instructions: extsb, extsh 32 33 * The test contains a pre-built table of instructions, operands and 34 * expected results. For each table entry, the test will cyclically use 35 * different sets of operand registers and result registers. 36 */ 37 38 #include <post.h> 39 #include "cpu_asm.h" 40 41 #if CONFIG_POST & CONFIG_SYS_POST_CPU 42 43 extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1); 44 extern ulong cpu_post_makecr (long v); 45 46 static struct cpu_post_twox_s 47 { 48 ulong cmd; 49 ulong op; 50 ulong res; 51 } cpu_post_twox_table[] = 52 { 53 { 54 OP_EXTSB, 55 3, 56 3 57 }, 58 { 59 OP_EXTSB, 60 0xff, 61 -1 62 }, 63 { 64 OP_EXTSH, 65 3, 66 3 67 }, 68 { 69 OP_EXTSH, 70 0xff, 71 0xff 72 }, 73 { 74 OP_EXTSH, 75 0xffff, 76 -1 77 }, 78 { 79 OP_CNTLZW, 80 0x000fffff, 81 12 82 }, 83 }; 84 static unsigned int cpu_post_twox_size = 85 sizeof (cpu_post_twox_table) / sizeof (struct cpu_post_twox_s); 86 87 int cpu_post_test_twox (void) 88 { 89 int ret = 0; 90 unsigned int i, reg; 91 int flag = disable_interrupts(); 92 93 for (i = 0; i < cpu_post_twox_size && ret == 0; i++) 94 { 95 struct cpu_post_twox_s *test = cpu_post_twox_table + i; 96 97 for (reg = 0; reg < 32 && ret == 0; reg++) 98 { 99 unsigned int reg0 = (reg + 0) % 32; 100 unsigned int reg1 = (reg + 1) % 32; 101 unsigned int stk = reg < 16 ? 31 : 15; 102 unsigned long code[] = 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), 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 unsigned long codecr[] = 120 { 121 ASM_STW(stk, 1, -4), 122 ASM_ADDI(stk, 1, -16), 123 ASM_STW(3, stk, 8), 124 ASM_STW(reg0, stk, 4), 125 ASM_STW(reg1, stk, 0), 126 ASM_LWZ(reg0, stk, 8), 127 ASM_11X(test->cmd, reg1, reg0) | BIT_C, 128 ASM_STW(reg1, stk, 8), 129 ASM_LWZ(reg1, stk, 0), 130 ASM_LWZ(reg0, stk, 4), 131 ASM_LWZ(3, stk, 8), 132 ASM_ADDI(1, stk, 16), 133 ASM_LWZ(stk, 1, -4), 134 ASM_BLR, 135 }; 136 ulong res; 137 ulong cr; 138 139 if (ret == 0) 140 { 141 cr = 0; 142 cpu_post_exec_21 (code, & cr, & res, test->op); 143 144 ret = res == test->res && cr == 0 ? 0 : -1; 145 146 if (ret != 0) 147 { 148 post_log ("Error at twox test %d !\n", i); 149 } 150 } 151 152 if (ret == 0) 153 { 154 cpu_post_exec_21 (codecr, & cr, & res, test->op); 155 156 ret = res == test->res && 157 (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1; 158 159 if (ret != 0) 160 { 161 post_log ("Error at twox test %d !\n", i); 162 } 163 } 164 } 165 } 166 167 if (flag) 168 enable_interrupts(); 169 170 return ret; 171 } 172 173 #endif 174