Merge with /home/wd/git/u-boot/master
[platform/kernel/u-boot.git] / post / cpu / store.c
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  * Store instructions:          stb(x)(u), sth(x)(u), stw(x)(u)
29  *
30  * All operations are performed on a 16-byte array. The array
31  * is 4-byte aligned. The base register points to offset 8.
32  * The immediate offset (index register) ranges in [-8 ... +7].
33  * The test cases are composed so that they do not
34  * cause alignment exceptions.
35  * The test contains a pre-built table describing all test cases.
36  * The table entry contains:
37  * the instruction opcode, the value of the index register and
38  * the value of the source register. After executing the
39  * instruction, the test verifies the contents of the array
40  * and the value of the base register (it must change for "store
41  * with update" instructions).
42  */
43
44 #ifdef CONFIG_POST
45
46 #include <post.h>
47 #include "cpu_asm.h"
48
49 #if CONFIG_POST & CFG_POST_CPU
50
51 extern void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3);
52 extern void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2);
53
54 static struct cpu_post_store_s
55 {
56     ulong cmd;
57     uint width;
58     int update;
59     int index;
60     ulong offset;
61     ulong value;
62 } cpu_post_store_table[] =
63 {
64     {
65         OP_STW,
66         4,
67         0,
68         0,
69         -4,
70         0xff00ff00
71     },
72     {
73         OP_STH,
74         2,
75         0,
76         0,
77         -2,
78         0xff00
79     },
80     {
81         OP_STB,
82         1,
83         0,
84         0,
85         -1,
86         0xff
87     },
88     {
89         OP_STWU,
90         4,
91         1,
92         0,
93         -4,
94         0xff00ff00
95     },
96     {
97         OP_STHU,
98         2,
99         1,
100         0,
101         -2,
102         0xff00
103     },
104     {
105         OP_STBU,
106         1,
107         1,
108         0,
109         -1,
110         0xff
111     },
112     {
113         OP_STWX,
114         4,
115         0,
116         1,
117         -4,
118         0xff00ff00
119     },
120     {
121         OP_STHX,
122         2,
123         0,
124         1,
125         -2,
126         0xff00
127     },
128     {
129         OP_STBX,
130         1,
131         0,
132         1,
133         -1,
134         0xff
135     },
136     {
137         OP_STWUX,
138         4,
139         1,
140         1,
141         -4,
142         0xff00ff00
143     },
144     {
145         OP_STHUX,
146         2,
147         1,
148         1,
149         -2,
150         0xff00
151     },
152     {
153         OP_STBUX,
154         1,
155         1,
156         1,
157         -1,
158         0xff
159     },
160 };
161 static unsigned int cpu_post_store_size =
162     sizeof (cpu_post_store_table) / sizeof (struct cpu_post_store_s);
163
164 int cpu_post_test_store (void)
165 {
166     int ret = 0;
167     unsigned int i;
168
169     for (i = 0; i < cpu_post_store_size && ret == 0; i++)
170     {
171         struct cpu_post_store_s *test = cpu_post_store_table + i;
172         uchar data[16] =
173         { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
174         ulong base0 = (ulong) (data + 8);
175         ulong base = base0;
176
177         if (test->index)
178         {
179             ulong code[] =
180             {
181                 ASM_12(test->cmd, 5, 3, 4),
182                 ASM_BLR,
183             };
184
185             cpu_post_exec_12w (code, &base, test->offset, test->value);
186         }
187         else
188         {
189             ulong code[] =
190             {
191                 ASM_11I(test->cmd, 4, 3, test->offset),
192                 ASM_BLR,
193             };
194
195             cpu_post_exec_11w (code, &base, test->value);
196         }
197
198         if (ret == 0)
199         {
200            if (test->update)
201                ret = base == base0 + test->offset ? 0 : -1;
202            else
203                ret = base == base0 ? 0 : -1;
204         }
205
206         if (ret == 0)
207         {
208             switch (test->width)
209             {
210             case 1:
211                 ret = *(uchar *)(base0 + test->offset) == test->value ?
212                       0 : -1;
213                 break;
214             case 2:
215                 ret = *(ushort *)(base0 + test->offset) == test->value ?
216                       0 : -1;
217                 break;
218             case 4:
219                 ret = *(ulong *)(base0 + test->offset) == test->value ?
220                       0 : -1;
221                 break;
222             }
223         }
224
225         if (ret != 0)
226         {
227             post_log ("Error at store test %d !\n", i);
228         }
229     }
230
231     return ret;
232 }
233
234 #endif
235 #endif