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