mfsl.c 6.66 KB
Newer Older
1 2 3 4
/*
 * (C) Copyright 2007 Michal Simek
 *
 * Michal  SIMEK <monstr@monstr.eu>
Michal Simek's avatar
Michal Simek committed
5
 *
6
 * SPDX-License-Identifier:	GPL-2.0+
Michal Simek's avatar
Michal Simek committed
7 8 9 10 11 12 13 14 15
 */

/*
 * Microblaze FSL support
 */

#include <common.h>
#include <config.h>
#include <command.h>
16
#include <asm/asm.h>
Michal Simek's avatar
Michal Simek committed
17

18
int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Michal Simek's avatar
Michal Simek committed
19 20 21 22 23
{
	unsigned int fslnum;
	unsigned int num;
	unsigned int blocking;

24
	if (argc < 2)
25
		return CMD_RET_USAGE;
Michal Simek's avatar
Michal Simek committed
26 27 28 29 30

	fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
	blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16);
	if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) {
		puts ("Bad number of FSL\n");
31
		return CMD_RET_USAGE;
Michal Simek's avatar
Michal Simek committed
32 33 34 35 36
	}

	switch (fslnum) {
#if (XILINX_FSL_NUMBER > 0)
	case 0:
37 38 39 40 41 42 43 44 45 46 47
		switch (blocking) {
		case 0:	NGET (num, 0);
			break;
		case 1:	NCGET (num, 0);
			break;
		case 2:	GET (num, 0);
			break;
		case 3:	CGET (num, 0);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
48 49 50 51 52
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 1)
	case 1:
53 54 55 56 57 58 59 60 61 62 63
		switch (blocking) {
		case 0:	NGET (num, 1);
			break;
		case 1:	NCGET (num, 1);
			break;
		case 2:	GET (num, 1);
			break;
		case 3:	CGET (num, 1);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
64 65 66 67 68
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 2)
	case 2:
69 70 71 72 73 74 75 76 77 78 79
		switch (blocking) {
		case 0:	NGET (num, 2);
			break;
		case 1:	NCGET (num, 2);
			break;
		case 2:	GET (num, 2);
			break;
		case 3:	CGET (num, 2);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
80 81 82 83 84
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 3)
	case 3:
85 86 87 88 89 90 91 92 93 94 95
		switch (blocking) {
		case 0:	NGET (num, 3);
			break;
		case 1:	NCGET (num, 3);
			break;
		case 2:	GET (num, 3);
			break;
		case 3:	CGET (num, 3);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
96 97 98 99 100
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 4)
	case 4:
101 102 103 104 105 106 107 108 109 110 111
		switch (blocking) {
		case 0:	NGET (num, 4);
			break;
		case 1:	NCGET (num, 4);
			break;
		case 2:	GET (num, 4);
			break;
		case 3:	CGET (num, 4);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
112 113 114 115 116
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 5)
	case 5:
117 118 119 120 121 122 123 124 125 126 127
		switch (blocking) {
		case 0:	NGET (num, 5);
			break;
		case 1:	NCGET (num, 5);
			break;
		case 2:	GET (num, 5);
			break;
		case 3:	CGET (num, 5);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
128 129 130 131 132
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 6)
	case 6:
133 134 135 136 137 138 139 140 141 142 143
		switch (blocking) {
		case 0:	NGET (num, 6);
			break;
		case 1:	NCGET (num, 6);
			break;
		case 2:	GET (num, 6);
			break;
		case 3:	CGET (num, 6);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
144 145 146 147 148
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 7)
	case 7:
149 150 151 152 153 154 155 156 157 158 159
		switch (blocking) {
		case 0:	NGET (num, 7);
			break;
		case 1:	NCGET (num, 7);
			break;
		case 2:	GET (num, 7);
			break;
		case 3:	CGET (num, 7);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
160 161 162 163 164 165 166
		}
		break;
#endif
	default:
		return 1;
	}

Stefan Roese's avatar
Stefan Roese committed
167
	printf ("%01x: 0x%08x - %s %s read\n", fslnum, num,
168 169
		blocking < 2  ? "non blocking" : "blocking",
		((blocking == 1) || (blocking == 3)) ? "control" : "data" );
Michal Simek's avatar
Michal Simek committed
170 171 172
	return 0;
}

173
int do_fwr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Michal Simek's avatar
Michal Simek committed
174 175 176 177 178
{
	unsigned int fslnum;
	unsigned int num;
	unsigned int blocking;

179
	if (argc < 3)
180
		return CMD_RET_USAGE;
Michal Simek's avatar
Michal Simek committed
181 182 183 184

	fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
	num = (unsigned int)simple_strtoul (argv[2], NULL, 16);
	blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16);
185
	if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER)
186
		return CMD_RET_USAGE;
Michal Simek's avatar
Michal Simek committed
187 188 189 190

	switch (fslnum) {
#if (XILINX_FSL_NUMBER > 0)
	case 0:
191 192 193 194 195 196 197 198 199 200 201
		switch (blocking) {
		case 0:	NPUT (num, 0);
			break;
		case 1:	NCPUT (num, 0);
			break;
		case 2:	PUT (num, 0);
			break;
		case 3:	CPUT (num, 0);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
202 203 204 205 206
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 1)
	case 1:
207 208 209 210 211 212 213 214 215 216 217
		switch (blocking) {
		case 0:	NPUT (num, 1);
			break;
		case 1:	NCPUT (num, 1);
			break;
		case 2:	PUT (num, 1);
			break;
		case 3:	CPUT (num, 1);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
218 219 220 221 222
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 2)
	case 2:
223 224 225 226 227 228 229 230 231 232 233
		switch (blocking) {
		case 0:	NPUT (num, 2);
			break;
		case 1:	NCPUT (num, 2);
			break;
		case 2:	PUT (num, 2);
			break;
		case 3:	CPUT (num, 2);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
234 235 236 237 238
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 3)
	case 3:
239 240 241 242 243 244 245 246 247 248 249
		switch (blocking) {
		case 0:	NPUT (num, 3);
			break;
		case 1:	NCPUT (num, 3);
			break;
		case 2:	PUT (num, 3);
			break;
		case 3:	CPUT (num, 3);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
250 251 252 253 254
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 4)
	case 4:
255 256 257 258 259 260 261 262 263 264 265
		switch (blocking) {
		case 0:	NPUT (num, 4);
			break;
		case 1:	NCPUT (num, 4);
			break;
		case 2:	PUT (num, 4);
			break;
		case 3:	CPUT (num, 4);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
266 267 268 269 270
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 5)
	case 5:
271 272 273 274 275 276 277 278 279 280 281
		switch (blocking) {
		case 0:	NPUT (num, 5);
			break;
		case 1:	NCPUT (num, 5);
			break;
		case 2:	PUT (num, 5);
			break;
		case 3:	CPUT (num, 5);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
282 283 284 285 286
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 6)
	case 6:
287 288 289 290 291 292 293 294 295 296 297
		switch (blocking) {
		case 0:	NPUT (num, 6);
			break;
		case 1:	NCPUT (num, 6);
			break;
		case 2:	PUT (num, 6);
			break;
		case 3:	CPUT (num, 6);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
298 299 300 301 302
		}
		break;
#endif
#if (XILINX_FSL_NUMBER > 7)
	case 7:
303 304 305 306 307 308 309 310 311 312 313
		switch (blocking) {
		case 0:	NPUT (num, 7);
			break;
		case 1:	NCPUT (num, 7);
			break;
		case 2:	PUT (num, 7);
			break;
		case 3:	CPUT (num, 7);
			break;
		default:
			return 2;
Michal Simek's avatar
Michal Simek committed
314 315 316 317 318 319 320
		}
		break;
#endif
	default:
		return 1;
	}

Stefan Roese's avatar
Stefan Roese committed
321
	printf ("%01x: 0x%08x - %s %s write\n", fslnum, num,
322 323
		blocking < 2  ? "non blocking" : "blocking",
		((blocking == 1) || (blocking == 3)) ? "control" : "data" );
Michal Simek's avatar
Michal Simek committed
324 325 326 327
	return 0;

}

328
int do_rspr (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
Michal Simek's avatar
Michal Simek committed
329
{
330
	unsigned int reg = 0;
331
	unsigned int val = 0;
Michal Simek's avatar
Michal Simek committed
332

333
	if (argc < 2)
334
		return CMD_RET_USAGE;
335

336 337
	reg = (unsigned int)simple_strtoul (argv[1], NULL, 16);
	val = (unsigned int)simple_strtoul (argv[2], NULL, 16);
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
	switch (reg) {
	case 0x1:
		if (argc > 2) {
			MTS (val, rmsr);
			NOP;
			MFS (val, rmsr);
		} else {
			MFS (val, rmsr);
		}
		puts ("MSR");
		break;
	case 0x3:
		MFS (val, rear);
		puts ("EAR");
		break;
	case 0x5:
		MFS (val, resr);
		puts ("ESR");
		break;
	default:
358
		puts ("Unsupported register\n");
359
		return 1;
360
	}
Stefan Roese's avatar
Stefan Roese committed
361
	printf (": 0x%08x\n", val);
Michal Simek's avatar
Michal Simek committed
362 363 364 365 366 367
	return 0;
}

/***************************************************/

U_BOOT_CMD (frd, 3, 1, do_frd,
Peter Tyser's avatar
Peter Tyser committed
368
		"read data from FSL",
369 370 371 372
		"- [fslnum [0|1|2|3]]\n"
		" 0 - non blocking data read\n"
		" 1 - non blocking control read\n"
		" 2 - blocking data read\n"
373
		" 3 - blocking control read");
Michal Simek's avatar
Michal Simek committed
374 375

U_BOOT_CMD (fwr, 4, 1, do_fwr,
Peter Tyser's avatar
Peter Tyser committed
376
		"write data to FSL",
377 378 379 380
		"- [fslnum [0|1|2|3]]\n"
		" 0 - non blocking data write\n"
		" 1 - non blocking control write\n"
		" 2 - blocking data write\n"
381
		" 3 - blocking control write");
Michal Simek's avatar
Michal Simek committed
382

383
U_BOOT_CMD (rspr, 3, 1, do_rspr,
Peter Tyser's avatar
Peter Tyser committed
384
		"read/write special purpose register",
385
		"- reg_num [write value] read/write special purpose register\n"
386 387
		" 1 - MSR - Machine status register\n"
		" 3 - EAR - Exception address register\n"
388
		" 5 - ESR - Exception status register");