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