1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * ARC firmware interface defines.
7  *
8  * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
9  * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org)
10  * Copyright (C) 1999 Silicon Graphics, Inc.
11  */
12 #ifndef _ASM_SGIARCS_H
13 #define _ASM_SGIARCS_H
14 
15 #include <asm/types.h>
16 #include <asm/fw/arc/types.h>
17 
18 /* Various ARCS error codes. */
19 #define PROM_ESUCCESS			0x00
20 #define PROM_E2BIG			0x01
21 #define PROM_EACCESS			0x02
22 #define PROM_EAGAIN			0x03
23 #define PROM_EBADF			0x04
24 #define PROM_EBUSY			0x05
25 #define PROM_EFAULT			0x06
26 #define PROM_EINVAL			0x07
27 #define PROM_EIO			0x08
28 #define PROM_EISDIR			0x09
29 #define PROM_EMFILE			0x0a
30 #define PROM_EMLINK			0x0b
31 #define PROM_ENAMETOOLONG		0x0c
32 #define PROM_ENODEV			0x0d
33 #define PROM_ENOENT			0x0e
34 #define PROM_ENOEXEC			0x0f
35 #define PROM_ENOMEM			0x10
36 #define PROM_ENOSPC			0x11
37 #define PROM_ENOTDIR			0x12
38 #define PROM_ENOTTY			0x13
39 #define PROM_ENXIO			0x14
40 #define PROM_EROFS			0x15
41 /* SGI ARCS specific errno's. */
42 #define PROM_EADDRNOTAVAIL		0x1f
43 #define PROM_ETIMEDOUT			0x20
44 #define PROM_ECONNABORTED		0x21
45 #define PROM_ENOCONNECT			0x22
46 
47 /* Device classes, types, and identifiers for prom
48  * device inventory queries.
49  */
50 enum linux_devclass {
51 	system, processor, cache, adapter, controller, peripheral, memory
52 };
53 
54 enum linux_devtypes {
55 	/* Generic stuff. */
56 	Arc, Cpu, Fpu,
57 
58 	/* Primary insn and data caches. */
59 	picache, pdcache,
60 
61 	/* Secondary insn, data, and combined caches. */
62 	sicache, sdcache, sccache,
63 
64 	memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter,
65 	multifunc_adapter, dsk_controller, tp_controller, cdrom_controller,
66 	worm_controller, serial_controller, net_controller, disp_controller,
67 	parallel_controller, ptr_controller, kbd_controller, audio_controller,
68 	misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral,
69 	modem_peripheral, monitor_peripheral, printer_peripheral,
70 	ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral,
71 	net_peripheral, misc_peripheral, anon
72 };
73 
74 enum linux_identifier {
75 	bogus, ronly, removable, consin, consout, input, output
76 };
77 
78 /* A prom device tree component. */
79 struct linux_component {
80 	enum linux_devclass	class;	/* node class */
81 	enum linux_devtypes	type;	/* node type */
82 	enum linux_identifier	iflags; /* node flags */
83 	USHORT			vers;	/* node version */
84 	USHORT			rev;	/* node revision */
85 	ULONG			key;	/* completely magic */
86 	ULONG			amask;	/* XXX affinity mask??? */
87 	ULONG			cdsize; /* size of configuration data */
88 	ULONG			ilen;	/* length of string identifier */
89 	_PULONG			iname;	/* string identifier */
90 };
91 typedef struct linux_component pcomponent;
92 
93 struct linux_sysid {
94 	char vend[8], prod[8];
95 };
96 
97 /* ARCS prom memory descriptors. */
98 enum arcs_memtypes {
99 	arcs_eblock,  /* exception block */
100 	arcs_rvpage,  /* ARCS romvec page */
101 	arcs_fcontig, /* Contiguous and free */
102 	arcs_free,    /* Generic free memory */
103 	arcs_bmem,    /* Borken memory, don't use */
104 	arcs_prog,    /* A loaded program resides here */
105 	arcs_atmp,    /* ARCS temporary storage area, wish Sparc OpenBoot told this */
106 	arcs_aperm,   /* ARCS permanent storage... */
107 };
108 
109 /* ARC has slightly different types than ARCS */
110 enum arc_memtypes {
111 	arc_eblock,  /* exception block */
112 	arc_rvpage,  /* romvec page */
113 	arc_free,    /* Generic free memory */
114 	arc_bmem,    /* Borken memory, don't use */
115 	arc_prog,    /* A loaded program resides here */
116 	arc_atmp,    /* temporary storage area */
117 	arc_aperm,   /* permanent storage */
118 	arc_fcontig, /* Contiguous and free */
119 };
120 
121 union linux_memtypes {
122     enum arcs_memtypes arcs;
123     enum arc_memtypes arc;
124 };
125 
126 struct linux_mdesc {
127 	union linux_memtypes type;
128 	ULONG base;
129 	ULONG pages;
130 };
131 
132 /* Time of day descriptor. */
133 struct linux_tinfo {
134 	unsigned short yr;
135 	unsigned short mnth;
136 	unsigned short day;
137 	unsigned short hr;
138 	unsigned short min;
139 	unsigned short sec;
140 	unsigned short msec;
141 };
142 
143 /* ARCS virtual dirents. */
144 struct linux_vdirent {
145 	ULONG namelen;
146 	unsigned char attr;
147 	char fname[32]; /* XXX empirical, should be a define */
148 };
149 
150 /* Other stuff for files. */
151 enum linux_omode {
152 	rdonly, wronly, rdwr, wronly_creat, rdwr_creat,
153 	wronly_ssede, rdwr_ssede, dirent, dirent_creat
154 };
155 
156 enum linux_seekmode {
157 	absolute, relative
158 };
159 
160 enum linux_mountops {
161 	media_load, media_unload
162 };
163 
164 /* This prom has a bolixed design. */
165 struct linux_bigint {
166 #ifdef __MIPSEL__
167 	u32 lo;
168 	s32 hi;
169 #else /* !(__MIPSEL__) */
170 	s32 hi;
171 	u32 lo;
172 #endif
173 };
174 
175 struct linux_finfo {
176 	struct linux_bigint   begin;
177 	struct linux_bigint   end;
178 	struct linux_bigint   cur;
179 	enum linux_devtypes   dtype;
180 	unsigned long	      namelen;
181 	unsigned char	      attr;
182 	char		      name[32]; /* XXX empirical, should be define */
183 };
184 
185 /* This describes the vector containing function pointers to the ARC
186    firmware functions.	*/
187 struct linux_romvec {
188 	LONG	load;			/* Load an executable image. */
189 	LONG	invoke;			/* Invoke a standalong image. */
190 	LONG	exec;			/* Load and begin execution of a
191 					   standalone image. */
192 	LONG	halt;			/* Halt the machine. */
193 	LONG	pdown;			/* Power down the machine. */
194 	LONG	restart;		/* XXX soft reset??? */
195 	LONG	reboot;			/* Reboot the machine. */
196 	LONG	imode;			/* Enter PROM interactive mode. */
197 	LONG	_unused1;		/* Was ReturnFromMain(). */
198 
199 	/* PROM device tree interface. */
200 	LONG	next_component;
201 	LONG	child_component;
202 	LONG	parent_component;
203 	LONG	component_data;
204 	LONG	child_add;
205 	LONG	comp_del;
206 	LONG	component_by_path;
207 
208 	/* Misc. stuff. */
209 	LONG	cfg_save;
210 	LONG	get_sysid;
211 
212 	/* Probing for memory. */
213 	LONG	get_mdesc;
214 	LONG	_unused2;		/* was Signal() */
215 
216 	LONG	get_tinfo;
217 	LONG	get_rtime;
218 
219 	/* File type operations. */
220 	LONG	get_vdirent;
221 	LONG	open;
222 	LONG	close;
223 	LONG	read;
224 	LONG	get_rstatus;
225 	LONG	write;
226 	LONG	seek;
227 	LONG	mount;
228 
229 	/* Dealing with firmware environment variables. */
230 	LONG	get_evar;
231 	LONG	set_evar;
232 
233 	LONG	get_finfo;
234 	LONG	set_finfo;
235 
236 	/* Miscellaneous. */
237 	LONG	cache_flush;
238 	LONG	TestUnicodeCharacter;		/* ARC; not sure if ARCS too */
239 	LONG	GetDisplayStatus;
240 };
241 
242 /* The SGI ARCS parameter block is in a fixed location for standalone
243  * programs to access PROM facilities easily.
244  */
245 typedef struct _SYSTEM_PARAMETER_BLOCK {
246 	ULONG			magic;		/* magic cookie */
247 #define PROMBLOCK_MAGIC	     0x53435241
248 
249 	ULONG			len;		/* length of parm block */
250 	USHORT			ver;		/* ARCS firmware version */
251 	USHORT			rev;		/* ARCS firmware revision */
252 	_PLONG			rs_block;	/* Restart block. */
253 	_PLONG			dbg_block;	/* Debug block. */
254 	_PLONG			gevect;		/* XXX General vector??? */
255 	_PLONG			utlbvect;	/* XXX UTLB vector??? */
256 	ULONG			rveclen;	/* Size of romvec struct. */
257 	_PVOID			romvec;		/* Function interface. */
258 	ULONG			pveclen;	/* Length of private vector. */
259 	_PVOID			pvector;	/* Private vector. */
260 	ULONG			adap_cnt;	/* Adapter count. */
261 	ULONG			adap_typ0;	/* First adapter type. */
262 	ULONG			adap_vcnt0;	/* Adapter 0 vector count. */
263 	_PVOID			adap_vector;	/* Adapter 0 vector ptr. */
264 	ULONG			adap_typ1;	/* Second adapter type. */
265 	ULONG			adap_vcnt1;	/* Adapter 1 vector count. */
266 	_PVOID			adap_vector1;	/* Adapter 1 vector ptr. */
267 	/* More adapter vectors go here... */
268 } SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK;
269 
270 #define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000)
271 #define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec)
272 
273 /* Cache layout parameter block. */
274 union linux_cache_key {
275 	struct param {
276 #ifdef __MIPSEL__
277 		unsigned short size;
278 		unsigned char lsize;
279 		unsigned char bsize;
280 #else /* !(__MIPSEL__) */
281 		unsigned char bsize;
282 		unsigned char lsize;
283 		unsigned short size;
284 #endif
285 	} info;
286 	unsigned long allinfo;
287 };
288 
289 /* Configuration data. */
290 struct linux_cdata {
291 	char *name;
292 	int mlen;
293 	enum linux_devtypes type;
294 };
295 
296 /* Common SGI ARCS firmware file descriptors. */
297 #define SGIPROM_STDIN	  0
298 #define SGIPROM_STDOUT	  1
299 
300 /* Common SGI ARCS firmware file types. */
301 #define SGIPROM_ROFILE	  0x01	/* read-only file */
302 #define SGIPROM_HFILE	  0x02	/* hidden file */
303 #define SGIPROM_SFILE	  0x04	/* System file */
304 #define SGIPROM_AFILE	  0x08	/* Archive file */
305 #define SGIPROM_DFILE	  0x10	/* Directory file */
306 #define SGIPROM_DELFILE	  0x20	/* Deleted file */
307 
308 /* SGI ARCS boot record information. */
309 struct sgi_partition {
310 	unsigned char flag;
311 #define SGIPART_UNUSED 0x00
312 #define SGIPART_ACTIVE 0x80
313 
314 	unsigned char shead, ssect, scyl; /* unused */
315 	unsigned char systype; /* OS type, Irix or NT */
316 	unsigned char ehead, esect, ecyl; /* unused */
317 	unsigned char rsect0, rsect1, rsect2, rsect3;
318 	unsigned char tsect0, tsect1, tsect2, tsect3;
319 };
320 
321 #define SGIBBLOCK_MAGIC	  0xaa55
322 #define SGIBBLOCK_MAXPART 0x0004
323 
324 struct sgi_bootblock {
325 	unsigned char _unused[446];
326 	struct sgi_partition partitions[SGIBBLOCK_MAXPART];
327 	unsigned short magic;
328 };
329 
330 /* BIOS parameter block. */
331 struct sgi_bparm_block {
332 	unsigned short bytes_sect;    /* bytes per sector */
333 	unsigned char  sect_clust;    /* sectors per cluster */
334 	unsigned short sect_resv;     /* reserved sectors */
335 	unsigned char  nfats;	      /* # of allocation tables */
336 	unsigned short nroot_dirents; /* # of root directory entries */
337 	unsigned short sect_volume;   /* sectors in volume */
338 	unsigned char  media_type;    /* media descriptor */
339 	unsigned short sect_fat;      /* sectors per allocation table */
340 	unsigned short sect_track;    /* sectors per track */
341 	unsigned short nheads;	      /* # of heads */
342 	unsigned short nhsects;	      /* # of hidden sectors */
343 };
344 
345 struct sgi_bsector {
346 	unsigned char	jmpinfo[3];
347 	unsigned char	manuf_name[8];
348 	struct sgi_bparm_block info;
349 };
350 
351 /* Debugging block used with SGI symmon symbolic debugger. */
352 #define SMB_DEBUG_MAGIC	  0xfeeddead
353 struct linux_smonblock {
354 	unsigned long	magic;
355 	void		(*handler)(void);  /* Breakpoint routine. */
356 	unsigned long	dtable_base;	   /* Base addr of dbg table. */
357 	int		(*printf)(const char *fmt, ...);
358 	unsigned long	btable_base;	   /* Breakpoint table. */
359 	unsigned long	mpflushreqs;	   /* SMP cache flush request list. */
360 	unsigned long	ntab;		   /* Name table. */
361 	unsigned long	stab;		   /* Symbol table. */
362 	int		smax;		   /* Max # of symbols. */
363 };
364 
365 /*
366  * Macros for calling a 32-bit ARC implementation from 64-bit code
367  */
368 
369 #if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32)
370 
371 #define __arc_clobbers							\
372 	"$2", "$3" /* ... */, "$8", "$9", "$10", "$11",				\
373 	"$12", "$13", "$14", "$15", "$16", "$24", "$25", "$31"
374 
375 #define ARC_CALL0(dest)							\
376 ({	long __res;							\
377 	long __vec = (long) romvec->dest;				\
378 	__asm__ __volatile__(						\
379 	"dsubu\t$29, 32\n\t"						\
380 	"jalr\t%1\n\t"							\
381 	"daddu\t$29, 32\n\t"						\
382 	"move\t%0, $2"							\
383 	: "=r" (__res), "=r" (__vec)					\
384 	: "1" (__vec)							\
385 	: __arc_clobbers, "$4", "$5", "$6", "$7");			\
386 	(unsigned long) __res;						\
387 })
388 
389 #define ARC_CALL1(dest, a1)						\
390 ({	long __res;							\
391 	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
392 	long __vec = (long) romvec->dest;				\
393 	__asm__ __volatile__(						\
394 	"dsubu\t$29, 32\n\t"						\
395 	"jalr\t%1\n\t"							\
396 	"daddu\t$29, 32\n\t"						\
397 	"move\t%0, $2"							\
398 	: "=r" (__res), "=r" (__vec)					\
399 	: "1" (__vec), "r" (__a1)					\
400 	: __arc_clobbers, "$5", "$6", "$7");				\
401 	(unsigned long) __res;						\
402 })
403 
404 #define ARC_CALL2(dest, a1, a2)						\
405 ({	long __res;							\
406 	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
407 	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
408 	long __vec = (long) romvec->dest;				\
409 	__asm__ __volatile__(						\
410 	"dsubu\t$29, 32\n\t"						\
411 	"jalr\t%1\n\t"							\
412 	"daddu\t$29, 32\n\t"						\
413 	"move\t%0, $2"							\
414 	: "=r" (__res), "=r" (__vec)					\
415 	: "1" (__vec), "r" (__a1), "r" (__a2)				\
416 	: __arc_clobbers, "$6", "$7");					\
417 	__res;								\
418 })
419 
420 #define ARC_CALL3(dest, a1, a2, a3)					\
421 ({	long __res;							\
422 	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
423 	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
424 	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
425 	long __vec = (long) romvec->dest;				\
426 	__asm__ __volatile__(						\
427 	"dsubu\t$29, 32\n\t"						\
428 	"jalr\t%1\n\t"							\
429 	"daddu\t$29, 32\n\t"						\
430 	"move\t%0, $2"							\
431 	: "=r" (__res), "=r" (__vec)					\
432 	: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3)		\
433 	: __arc_clobbers, "$7");					\
434 	__res;								\
435 })
436 
437 #define ARC_CALL4(dest, a1, a2, a3, a4)					\
438 ({	long __res;							\
439 	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
440 	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
441 	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
442 	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
443 	long __vec = (long) romvec->dest;				\
444 	__asm__ __volatile__(						\
445 	"dsubu\t$29, 32\n\t"						\
446 	"jalr\t%1\n\t"							\
447 	"daddu\t$29, 32\n\t"						\
448 	"move\t%0, $2"							\
449 	: "=r" (__res), "=r" (__vec)					\
450 	: "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3),		\
451 	  "r" (__a4)							\
452 	: __arc_clobbers);						\
453 	__res;								\
454 })
455 
456 #define ARC_CALL5(dest, a1, a2, a3, a4, a5)					\
457 ({	long __res;							\
458 	register signed int __a1 __asm__("$4") = (int) (long) (a1);	\
459 	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
460 	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
461 	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
462 	register signed int __a5 = (int) (long) (a5);			\
463 	long __vec = (long) romvec->dest;				\
464 	__asm__ __volatile__(						\
465 	"dsubu\t$29, 32\n\t"						\
466 	"sw\t%7, 16($29)\n\t"						\
467 	"jalr\t%1\n\t"							\
468 	"daddu\t$29, 32\n\t"						\
469 	"move\t%0, $2"							\
470 	: "=r" (__res), "=r" (__vec)					\
471 	: "1" (__vec),							\
472 	  "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4),		\
473 	  "r" (__a5)							\
474 	: __arc_clobbers);						\
475 	__res;								\
476 })
477 
478 #endif /* defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32) */
479 
480 #if (defined(CONFIG_32BIT) && defined(CONFIG_FW_ARC32)) ||		\
481     (defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC64))
482 
483 #define ARC_CALL0(dest)							\
484 ({	long __res;							\
485 	long (*__vec)(void) = (void *) romvec->dest;			\
486 									\
487 	__res = __vec();						\
488 	__res;								\
489 })
490 
491 #define ARC_CALL1(dest, a1)						\
492 ({	long __res;							\
493 	long __a1 = (long) (a1);					\
494 	long (*__vec)(long) = (void *) romvec->dest;			\
495 									\
496 	__res = __vec(__a1);						\
497 	__res;								\
498 })
499 
500 #define ARC_CALL2(dest, a1, a2)						\
501 ({	long __res;							\
502 	long __a1 = (long) (a1);					\
503 	long __a2 = (long) (a2);					\
504 	long (*__vec)(long, long) = (void *) romvec->dest;		\
505 									\
506 	__res = __vec(__a1, __a2);					\
507 	__res;								\
508 })
509 
510 #define ARC_CALL3(dest, a1, a2, a3)					\
511 ({	long __res;							\
512 	long __a1 = (long) (a1);					\
513 	long __a2 = (long) (a2);					\
514 	long __a3 = (long) (a3);					\
515 	long (*__vec)(long, long, long) = (void *) romvec->dest;	\
516 									\
517 	__res = __vec(__a1, __a2, __a3);				\
518 	__res;								\
519 })
520 
521 #define ARC_CALL4(dest, a1, a2, a3, a4)					\
522 ({	long __res;							\
523 	long __a1 = (long) (a1);					\
524 	long __a2 = (long) (a2);					\
525 	long __a3 = (long) (a3);					\
526 	long __a4 = (long) (a4);					\
527 	long (*__vec)(long, long, long, long) = (void *) romvec->dest;	\
528 									\
529 	__res = __vec(__a1, __a2, __a3, __a4);				\
530 	__res;								\
531 })
532 
533 #define ARC_CALL5(dest, a1, a2, a3, a4, a5)				\
534 ({	long __res;							\
535 	long __a1 = (long) (a1);					\
536 	long __a2 = (long) (a2);					\
537 	long __a3 = (long) (a3);					\
538 	long __a4 = (long) (a4);					\
539 	long __a5 = (long) (a5);					\
540 	long (*__vec)(long, long, long, long, long);			\
541 	__vec = (void *) romvec->dest;					\
542 									\
543 	__res = __vec(__a1, __a2, __a3, __a4, __a5);			\
544 	__res;								\
545 })
546 #endif /* both kernel and ARC either 32-bit or 64-bit */
547 
548 #endif /* _ASM_SGIARCS_H */
549