1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2002 4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 5 */ 6 7 #include <common.h> 8 9 /* 10 * CPU test 11 * Ternary instructions instr rA,rS,UIMM 12 * 13 * Logic instructions: ori, oris, xori, xoris 14 * 15 * The test contains a pre-built table of instructions, operands and 16 * expected results. For each table entry, the test will cyclically use 17 * different sets of operand registers and result registers. 18 */ 19 20 #include <post.h> 21 #include "cpu_asm.h" 22 23 #if CONFIG_POST & CONFIG_SYS_POST_CPU 24 25 extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op); 26 extern ulong cpu_post_makecr (long v); 27 28 static struct cpu_post_threei_s 29 { 30 ulong cmd; 31 ulong op1; 32 ushort op2; 33 ulong res; 34 } cpu_post_threei_table[] = 35 { 36 { 37 OP_ORI, 38 0x80000000, 39 0xffff, 40 0x8000ffff 41 }, 42 { 43 OP_ORIS, 44 0x00008000, 45 0xffff, 46 0xffff8000 47 }, 48 { 49 OP_XORI, 50 0x8000ffff, 51 0xffff, 52 0x80000000 53 }, 54 { 55 OP_XORIS, 56 0x00008000, 57 0xffff, 58 0xffff8000 59 }, 60 }; 61 static unsigned int cpu_post_threei_size = ARRAY_SIZE(cpu_post_threei_table); 62 63 int cpu_post_test_threei (void) 64 { 65 int ret = 0; 66 unsigned int i, reg; 67 int flag = disable_interrupts(); 68 69 for (i = 0; i < cpu_post_threei_size && ret == 0; i++) 70 { 71 struct cpu_post_threei_s *test = cpu_post_threei_table + i; 72 73 for (reg = 0; reg < 32 && ret == 0; reg++) 74 { 75 unsigned int reg0 = (reg + 0) % 32; 76 unsigned int reg1 = (reg + 1) % 32; 77 unsigned int stk = reg < 16 ? 31 : 15; 78 unsigned long code[] = 79 { 80 ASM_STW(stk, 1, -4), 81 ASM_ADDI(stk, 1, -16), 82 ASM_STW(3, stk, 8), 83 ASM_STW(reg0, stk, 4), 84 ASM_STW(reg1, stk, 0), 85 ASM_LWZ(reg0, stk, 8), 86 ASM_11IX(test->cmd, reg1, reg0, test->op2), 87 ASM_STW(reg1, stk, 8), 88 ASM_LWZ(reg1, stk, 0), 89 ASM_LWZ(reg0, stk, 4), 90 ASM_LWZ(3, stk, 8), 91 ASM_ADDI(1, stk, 16), 92 ASM_LWZ(stk, 1, -4), 93 ASM_BLR, 94 }; 95 ulong res; 96 ulong cr; 97 98 cr = 0; 99 cpu_post_exec_21 (code, & cr, & res, test->op1); 100 101 ret = res == test->res && cr == 0 ? 0 : -1; 102 103 if (ret != 0) 104 { 105 post_log ("Error at threei test %d !\n", i); 106 } 107 } 108 } 109 110 if (flag) 111 enable_interrupts(); 112 113 return ret; 114 } 115 116 #endif 117