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 rD,rA 29 * 30 * Logic instructions: neg 31 * Arithmetic instructions: addme, addze, subfme, subfze 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_two_s 47 { 48 ulong cmd; 49 ulong op; 50 ulong res; 51 } cpu_post_two_table[] = 52 { 53 { 54 OP_NEG, 55 3, 56 -3 57 }, 58 { 59 OP_NEG, 60 5, 61 -5 62 }, 63 { 64 OP_ADDME, 65 6, 66 5 67 }, 68 { 69 OP_ADDZE, 70 5, 71 5 72 }, 73 { 74 OP_SUBFME, 75 6, 76 ~6 - 1 77 }, 78 { 79 OP_SUBFZE, 80 5, 81 ~5 82 }, 83 }; 84 static unsigned int cpu_post_two_size = ARRAY_SIZE(cpu_post_two_table); 85 86 int cpu_post_test_two (void) 87 { 88 int ret = 0; 89 unsigned int i, reg; 90 int flag = disable_interrupts(); 91 92 for (i = 0; i < cpu_post_two_size && ret == 0; i++) 93 { 94 struct cpu_post_two_s *test = cpu_post_two_table + i; 95 96 for (reg = 0; reg < 32 && ret == 0; reg++) 97 { 98 unsigned int reg0 = (reg + 0) % 32; 99 unsigned int reg1 = (reg + 1) % 32; 100 unsigned int stk = reg < 16 ? 31 : 15; 101 unsigned long code[] = 102 { 103 ASM_STW(stk, 1, -4), 104 ASM_ADDI(stk, 1, -16), 105 ASM_STW(3, stk, 8), 106 ASM_STW(reg0, stk, 4), 107 ASM_STW(reg1, stk, 0), 108 ASM_LWZ(reg0, stk, 8), 109 ASM_11(test->cmd, reg1, reg0), 110 ASM_STW(reg1, stk, 8), 111 ASM_LWZ(reg1, stk, 0), 112 ASM_LWZ(reg0, stk, 4), 113 ASM_LWZ(3, stk, 8), 114 ASM_ADDI(1, stk, 16), 115 ASM_LWZ(stk, 1, -4), 116 ASM_BLR, 117 }; 118 unsigned long codecr[] = 119 { 120 ASM_STW(stk, 1, -4), 121 ASM_ADDI(stk, 1, -16), 122 ASM_STW(3, stk, 8), 123 ASM_STW(reg0, stk, 4), 124 ASM_STW(reg1, stk, 0), 125 ASM_LWZ(reg0, stk, 8), 126 ASM_11(test->cmd, reg1, reg0) | BIT_C, 127 ASM_STW(reg1, stk, 8), 128 ASM_LWZ(reg1, stk, 0), 129 ASM_LWZ(reg0, stk, 4), 130 ASM_LWZ(3, stk, 8), 131 ASM_ADDI(1, stk, 16), 132 ASM_LWZ(stk, 1, -4), 133 ASM_BLR, 134 }; 135 ulong res; 136 ulong cr; 137 138 if (ret == 0) 139 { 140 cr = 0; 141 cpu_post_exec_21 (code, & cr, & res, test->op); 142 143 ret = res == test->res && cr == 0 ? 0 : -1; 144 145 if (ret != 0) 146 { 147 post_log ("Error at two test %d !\n", i); 148 } 149 } 150 151 if (ret == 0) 152 { 153 cpu_post_exec_21 (codecr, & cr, & res, test->op); 154 155 ret = res == test->res && 156 (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1; 157 158 if (ret != 0) 159 { 160 post_log ("Error at two test %d !\n", i); 161 } 162 } 163 } 164 } 165 166 if (flag) 167 enable_interrupts(); 168 169 return ret; 170 } 171 172 #endif 173