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 54 extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1); 55 extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3); 56 57 static ulong cpu_post_cr_table1[] = 58 { 59 0xaaaaaaaa, 60 0x55555555, 61 }; 62 static unsigned int cpu_post_cr_size1 = ARRAY_SIZE(cpu_post_cr_table1); 63 64 static 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 }; 78 static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2); 79 80 static 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 }; 100 static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3); 101 102 static 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 }; 240 static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4); 241 242 int 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