1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2007 Michal Simek
4 *
5 * Michal SIMEK <monstr@monstr.eu>
6 */
7
8 /*
9 * Microblaze FSL support
10 */
11
12 #include <common.h>
13 #include <config.h>
14 #include <command.h>
15 #include <asm/asm.h>
16
do_frd(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])17 int do_frd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
18 {
19 unsigned int fslnum;
20 unsigned int num;
21 unsigned int blocking;
22
23 if (argc < 2)
24 return CMD_RET_USAGE;
25
26 fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
27 blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16);
28 if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) {
29 puts ("Bad number of FSL\n");
30 return CMD_RET_USAGE;
31 }
32
33 switch (fslnum) {
34 #if (XILINX_FSL_NUMBER > 0)
35 case 0:
36 switch (blocking) {
37 case 0: NGET (num, 0);
38 break;
39 case 1: NCGET (num, 0);
40 break;
41 case 2: GET (num, 0);
42 break;
43 case 3: CGET (num, 0);
44 break;
45 default:
46 return 2;
47 }
48 break;
49 #endif
50 #if (XILINX_FSL_NUMBER > 1)
51 case 1:
52 switch (blocking) {
53 case 0: NGET (num, 1);
54 break;
55 case 1: NCGET (num, 1);
56 break;
57 case 2: GET (num, 1);
58 break;
59 case 3: CGET (num, 1);
60 break;
61 default:
62 return 2;
63 }
64 break;
65 #endif
66 #if (XILINX_FSL_NUMBER > 2)
67 case 2:
68 switch (blocking) {
69 case 0: NGET (num, 2);
70 break;
71 case 1: NCGET (num, 2);
72 break;
73 case 2: GET (num, 2);
74 break;
75 case 3: CGET (num, 2);
76 break;
77 default:
78 return 2;
79 }
80 break;
81 #endif
82 #if (XILINX_FSL_NUMBER > 3)
83 case 3:
84 switch (blocking) {
85 case 0: NGET (num, 3);
86 break;
87 case 1: NCGET (num, 3);
88 break;
89 case 2: GET (num, 3);
90 break;
91 case 3: CGET (num, 3);
92 break;
93 default:
94 return 2;
95 }
96 break;
97 #endif
98 #if (XILINX_FSL_NUMBER > 4)
99 case 4:
100 switch (blocking) {
101 case 0: NGET (num, 4);
102 break;
103 case 1: NCGET (num, 4);
104 break;
105 case 2: GET (num, 4);
106 break;
107 case 3: CGET (num, 4);
108 break;
109 default:
110 return 2;
111 }
112 break;
113 #endif
114 #if (XILINX_FSL_NUMBER > 5)
115 case 5:
116 switch (blocking) {
117 case 0: NGET (num, 5);
118 break;
119 case 1: NCGET (num, 5);
120 break;
121 case 2: GET (num, 5);
122 break;
123 case 3: CGET (num, 5);
124 break;
125 default:
126 return 2;
127 }
128 break;
129 #endif
130 #if (XILINX_FSL_NUMBER > 6)
131 case 6:
132 switch (blocking) {
133 case 0: NGET (num, 6);
134 break;
135 case 1: NCGET (num, 6);
136 break;
137 case 2: GET (num, 6);
138 break;
139 case 3: CGET (num, 6);
140 break;
141 default:
142 return 2;
143 }
144 break;
145 #endif
146 #if (XILINX_FSL_NUMBER > 7)
147 case 7:
148 switch (blocking) {
149 case 0: NGET (num, 7);
150 break;
151 case 1: NCGET (num, 7);
152 break;
153 case 2: GET (num, 7);
154 break;
155 case 3: CGET (num, 7);
156 break;
157 default:
158 return 2;
159 }
160 break;
161 #endif
162 default:
163 return 1;
164 }
165
166 printf ("%01x: 0x%08x - %s %s read\n", fslnum, num,
167 blocking < 2 ? "non blocking" : "blocking",
168 ((blocking == 1) || (blocking == 3)) ? "control" : "data" );
169 return 0;
170 }
171
do_fwr(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])172 int do_fwr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
173 {
174 unsigned int fslnum;
175 unsigned int num;
176 unsigned int blocking;
177
178 if (argc < 3)
179 return CMD_RET_USAGE;
180
181 fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
182 num = (unsigned int)simple_strtoul (argv[2], NULL, 16);
183 blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16);
184 if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER)
185 return CMD_RET_USAGE;
186
187 switch (fslnum) {
188 #if (XILINX_FSL_NUMBER > 0)
189 case 0:
190 switch (blocking) {
191 case 0: NPUT (num, 0);
192 break;
193 case 1: NCPUT (num, 0);
194 break;
195 case 2: PUT (num, 0);
196 break;
197 case 3: CPUT (num, 0);
198 break;
199 default:
200 return 2;
201 }
202 break;
203 #endif
204 #if (XILINX_FSL_NUMBER > 1)
205 case 1:
206 switch (blocking) {
207 case 0: NPUT (num, 1);
208 break;
209 case 1: NCPUT (num, 1);
210 break;
211 case 2: PUT (num, 1);
212 break;
213 case 3: CPUT (num, 1);
214 break;
215 default:
216 return 2;
217 }
218 break;
219 #endif
220 #if (XILINX_FSL_NUMBER > 2)
221 case 2:
222 switch (blocking) {
223 case 0: NPUT (num, 2);
224 break;
225 case 1: NCPUT (num, 2);
226 break;
227 case 2: PUT (num, 2);
228 break;
229 case 3: CPUT (num, 2);
230 break;
231 default:
232 return 2;
233 }
234 break;
235 #endif
236 #if (XILINX_FSL_NUMBER > 3)
237 case 3:
238 switch (blocking) {
239 case 0: NPUT (num, 3);
240 break;
241 case 1: NCPUT (num, 3);
242 break;
243 case 2: PUT (num, 3);
244 break;
245 case 3: CPUT (num, 3);
246 break;
247 default:
248 return 2;
249 }
250 break;
251 #endif
252 #if (XILINX_FSL_NUMBER > 4)
253 case 4:
254 switch (blocking) {
255 case 0: NPUT (num, 4);
256 break;
257 case 1: NCPUT (num, 4);
258 break;
259 case 2: PUT (num, 4);
260 break;
261 case 3: CPUT (num, 4);
262 break;
263 default:
264 return 2;
265 }
266 break;
267 #endif
268 #if (XILINX_FSL_NUMBER > 5)
269 case 5:
270 switch (blocking) {
271 case 0: NPUT (num, 5);
272 break;
273 case 1: NCPUT (num, 5);
274 break;
275 case 2: PUT (num, 5);
276 break;
277 case 3: CPUT (num, 5);
278 break;
279 default:
280 return 2;
281 }
282 break;
283 #endif
284 #if (XILINX_FSL_NUMBER > 6)
285 case 6:
286 switch (blocking) {
287 case 0: NPUT (num, 6);
288 break;
289 case 1: NCPUT (num, 6);
290 break;
291 case 2: PUT (num, 6);
292 break;
293 case 3: CPUT (num, 6);
294 break;
295 default:
296 return 2;
297 }
298 break;
299 #endif
300 #if (XILINX_FSL_NUMBER > 7)
301 case 7:
302 switch (blocking) {
303 case 0: NPUT (num, 7);
304 break;
305 case 1: NCPUT (num, 7);
306 break;
307 case 2: PUT (num, 7);
308 break;
309 case 3: CPUT (num, 7);
310 break;
311 default:
312 return 2;
313 }
314 break;
315 #endif
316 default:
317 return 1;
318 }
319
320 printf ("%01x: 0x%08x - %s %s write\n", fslnum, num,
321 blocking < 2 ? "non blocking" : "blocking",
322 ((blocking == 1) || (blocking == 3)) ? "control" : "data" );
323 return 0;
324
325 }
326
do_rspr(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])327 int do_rspr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
328 {
329 unsigned int reg = 0;
330 unsigned int val = 0;
331
332 if (argc < 2)
333 return CMD_RET_USAGE;
334
335 reg = (unsigned int)simple_strtoul (argv[1], NULL, 16);
336 val = (unsigned int)simple_strtoul (argv[2], NULL, 16);
337 switch (reg) {
338 case 0x1:
339 if (argc > 2) {
340 MTS (val, rmsr);
341 NOP;
342 MFS (val, rmsr);
343 } else {
344 MFS (val, rmsr);
345 }
346 puts ("MSR");
347 break;
348 case 0x3:
349 MFS (val, rear);
350 puts ("EAR");
351 break;
352 case 0x5:
353 MFS (val, resr);
354 puts ("ESR");
355 break;
356 default:
357 puts ("Unsupported register\n");
358 return 1;
359 }
360 printf (": 0x%08x\n", val);
361 return 0;
362 }
363
364 /***************************************************/
365
366 U_BOOT_CMD (frd, 3, 1, do_frd,
367 "read data from FSL",
368 "- [fslnum [0|1|2|3]]\n"
369 " 0 - non blocking data read\n"
370 " 1 - non blocking control read\n"
371 " 2 - blocking data read\n"
372 " 3 - blocking control read");
373
374 U_BOOT_CMD (fwr, 4, 1, do_fwr,
375 "write data to FSL",
376 "- [fslnum [0|1|2|3]]\n"
377 " 0 - non blocking data write\n"
378 " 1 - non blocking control write\n"
379 " 2 - blocking data write\n"
380 " 3 - blocking control write");
381
382 U_BOOT_CMD (rspr, 3, 1, do_rspr,
383 "read/write special purpose register",
384 "- reg_num [write value] read/write special purpose register\n"
385 " 1 - MSR - Machine status register\n"
386 " 3 - EAR - Exception address register\n"
387 " 5 - ESR - Exception status register");
388