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 = 63 sizeof (cpu_post_cr_table1) / sizeof (ulong); 64 65 static 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 }; 79 static unsigned int cpu_post_cr_size2 = 80 sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2); 81 82 static 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 }; 102 static unsigned int cpu_post_cr_size3 = 103 sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3); 104 105 static 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 }; 243 static unsigned int cpu_post_cr_size4 = 244 sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4); 245 246 int 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