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