File: /usr/src/linux/include/asm-ia64/sal.h

1     #ifndef _ASM_IA64_SAL_H
2     #define _ASM_IA64_SAL_H
3     
4     /*
5      * System Abstraction Layer definitions.
6      *
7      * This is based on version 2.5 of the manual "IA-64 System
8      * Abstraction Layer".
9      *
10      * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
11      * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
12      * Copyright (C) 1999 Srinivasa Prasad Thirumalachar <sprasad@sprasad.engr.sgi.com>
13      *
14      * 99/09/29 davidm	Updated for SAL 2.6.
15      * 00/03/29 cfleck      Updated SAL Error Logging info for processor (SAL 2.6) 
16      *                      (plus examples of platform error info structures from smariset @ Intel)
17      */
18     
19     #include <linux/spinlock.h>
20     
21     #include <asm/pal.h>
22     #include <asm/system.h>
23     
24     extern spinlock_t sal_lock;
25     
26     /* SAL spec _requires_ eight args for each call. */
27     #define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7)	\
28     	result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7)
29     
30     # define SAL_CALL(result,args...) do {			\
31     	unsigned long flags;				\
32     	spin_lock_irqsave(&sal_lock, flags);		\
33     	__SAL_CALL(result,args);			\
34     	spin_unlock_irqrestore(&sal_lock, flags);	\
35     } while (0)
36     
37     #define SAL_SET_VECTORS			0x01000000
38     #define SAL_GET_STATE_INFO		0x01000001
39     #define SAL_GET_STATE_INFO_SIZE		0x01000002
40     #define SAL_CLEAR_STATE_INFO		0x01000003
41     #define SAL_MC_RENDEZ			0x01000004
42     #define SAL_MC_SET_PARAMS		0x01000005
43     #define SAL_REGISTER_PHYSICAL_ADDR	0x01000006
44     
45     #define SAL_CACHE_FLUSH			0x01000008
46     #define SAL_CACHE_INIT			0x01000009
47     #define SAL_PCI_CONFIG_READ		0x01000010
48     #define SAL_PCI_CONFIG_WRITE		0x01000011
49     #define SAL_FREQ_BASE			0x01000012
50     
51     #define SAL_UPDATE_PAL			0x01000020
52     
53     struct ia64_sal_retval {
54     	/*
55     	 * A zero status value indicates call completed without error.
56     	 * A negative status value indicates reason of call failure.
57     	 * A positive status value indicates success but an
58     	 * informational value should be printed (e.g., "reboot for
59     	 * change to take effect").
60     	 */
61     	s64 status;
62     	u64 v0;
63     	u64 v1;
64     	u64 v2;
65     };
66     
67     typedef struct ia64_sal_retval (*ia64_sal_handler) (u64, ...);
68     
69     enum {
70     	SAL_FREQ_BASE_PLATFORM = 0,
71     	SAL_FREQ_BASE_INTERVAL_TIMER = 1,
72     	SAL_FREQ_BASE_REALTIME_CLOCK = 2
73     };
74     
75     /*
76      * The SAL system table is followed by a variable number of variable
77      * length descriptors.  The structure of these descriptors follows
78      * below.
79      * The defininition follows SAL specs from July 2000
80      */
81     struct ia64_sal_systab {
82     	u8 signature[4];	/* should be "SST_" */
83     	u32 size;		/* size of this table in bytes */
84     	u8 sal_rev_minor;
85     	u8 sal_rev_major;
86     	u16 entry_count;	/* # of entries in variable portion */
87     	u8 checksum;
88     	u8 reserved1[7];
89     	u8 sal_a_rev_minor;
90     	u8 sal_a_rev_major;
91     	u8 sal_b_rev_minor;
92     	u8 sal_b_rev_major;
93     	/* oem_id & product_id: terminating NUL is missing if string is exactly 32 bytes long. */
94     	u8 oem_id[32];
95     	u8 product_id[32];	/* ASCII product id  */
96     	u8 reserved2[8];
97     };
98     
99     enum sal_systab_entry_type {
100     	SAL_DESC_ENTRY_POINT = 0,
101     	SAL_DESC_MEMORY = 1,
102     	SAL_DESC_PLATFORM_FEATURE = 2,
103     	SAL_DESC_TR = 3,
104     	SAL_DESC_PTC = 4,
105     	SAL_DESC_AP_WAKEUP = 5
106     };
107     
108     /*
109      * Entry type:	Size:
110      *	0	48
111      *	1	32
112      *	2	16
113      *	3	32
114      *	4	16
115      *	5	16
116      */
117     #define SAL_DESC_SIZE(type)	"\060\040\020\040\020\020"[(unsigned) type]
118     
119     typedef struct ia64_sal_desc_entry_point {
120     	u8 type;
121     	u8 reserved1[7];
122     	u64 pal_proc;
123     	u64 sal_proc;
124     	u64 gp;
125     	u8 reserved2[16];
126     }ia64_sal_desc_entry_point_t;
127     
128     typedef struct ia64_sal_desc_memory {
129     	u8 type;
130     	u8 used_by_sal;	/* needs to be mapped for SAL? */
131     	u8 mem_attr;		/* current memory attribute setting */
132     	u8 access_rights;	/* access rights set up by SAL */
133     	u8 mem_attr_mask;	/* mask of supported memory attributes */
134     	u8 reserved1;
135     	u8 mem_type;		/* memory type */
136     	u8 mem_usage;		/* memory usage */
137     	u64 addr;		/* physical address of memory */
138     	u32 length;	/* length (multiple of 4KB pages) */
139     	u32 reserved2;
140     	u8 oem_reserved[8];
141     } ia64_sal_desc_memory_t;
142     
143     #define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK		(1 << 0)
144     #define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT	(1 << 1)
145     #define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT	(1 << 2)
146     
147     typedef struct ia64_sal_desc_platform_feature {
148     	u8 type;
149     	u8 feature_mask;
150     	u8 reserved1[14];
151     } ia64_sal_desc_platform_feature_t;
152     
153     typedef struct ia64_sal_desc_tr {
154     	u8 type;
155     	u8 tr_type;		/* 0 == instruction, 1 == data */
156     	u8 regnum;		/* translation register number */
157     	u8 reserved1[5];
158     	u64 addr;		/* virtual address of area covered */
159     	u64 page_size;		/* encoded page size */
160     	u8 reserved2[8];
161     } ia64_sal_desc_tr_t;
162     
163     typedef struct ia64_sal_desc_ptc {
164     	u8 type;
165     	u8 reserved1[3];
166     	u32 num_domains;	/* # of coherence domains */
167     	u64 domain_info;	/* physical address of domain info table */
168     } ia64_sal_desc_ptc_t;
169     
170     typedef struct ia64_sal_ptc_domain_info {
171     	u64 proc_count;		/* number of processors in domain */
172     	u64 proc_list;		/* physical address of LID array */
173     } ia64_sal_ptc_domain_info_t;
174     
175     typedef struct ia64_sal_ptc_domain_proc_entry {
176     	u64 reserved : 16;
177     	u64 eid : 8;		/* eid of processor */
178     	u64 id  : 8;		/* id of processor */
179     	u64 ignored : 32;
180     } ia64_sal_ptc_domain_proc_entry_t;
181     
182     
183     #define IA64_SAL_AP_EXTERNAL_INT 0
184     
185     typedef struct ia64_sal_desc_ap_wakeup {
186     	u8 type;
187     	u8 mechanism;		/* 0 == external interrupt */
188     	u8 reserved1[6];
189     	u64 vector;		/* interrupt vector in range 0x10-0xff */
190     } ia64_sal_desc_ap_wakeup_t ;
191     
192     extern ia64_sal_handler ia64_sal;
193     extern struct ia64_sal_desc_ptc *ia64_ptc_domain_info;
194     
195     extern const char *ia64_sal_strerror (long status);
196     extern void ia64_sal_init (struct ia64_sal_systab *sal_systab);
197     
198     /* SAL information type encodings */
199     enum {
200     	SAL_INFO_TYPE_MCA	=		0,	/* Machine check abort information */
201             SAL_INFO_TYPE_INIT	=		1,	/* Init information */
202             SAL_INFO_TYPE_CMC	=		2 	/* Corrected machine check information */
203     };
204     
205     /* Sub information type encodings */
206     enum {
207             SAL_SUB_INFO_TYPE_PROCESSOR	=	0,	/* Processor information */
208             SAL_SUB_INFO_TYPE_PLATFORM	=	1	/* Platform information */
209     };
210     
211     /* Encodings for machine check parameter types */
212     enum {
213             SAL_MC_PARAM_RENDEZ_INT		=	1,	/* Rendezevous interrupt */
214             SAL_MC_PARAM_RENDEZ_WAKEUP	=	2	/* Wakeup */
215     };
216     
217     /* Encodings for rendezvous mechanisms */
218     enum {
219             SAL_MC_PARAM_MECHANISM_INT	=	1,	/* Use interrupt */
220             SAL_MC_PARAM_MECHANISM_MEM	=	2	/* Use memory synchronization variable*/
221     };
222     
223     /* Encodings for vectors which can be registered by the OS with SAL */
224     enum {
225     	SAL_VECTOR_OS_MCA		= 0,
226     	SAL_VECTOR_OS_INIT		= 1,
227     	SAL_VECTOR_OS_BOOT_RENDEZ	= 2
228     };
229     
230     /* Definition of the SAL Error Log from the SAL spec */
231     
232     /* Definition of timestamp according to SAL spec for logging purposes */
233     
234     typedef struct sal_log_timestamp {
235     	u8 slh_century;		/* Century (19, 20, 21, ...) */
236     	u8 slh_year;		/* Year (00..99) */
237     	u8 slh_month;		/* Month (1..12) */
238     	u8 slh_day;		/* Day (1..31) */
239     	u8 slh_reserved;					
240     	u8 slh_hour;		/* Hour (0..23)	*/
241     	u8 slh_minute;		/* Minute (0..59) */
242     	u8 slh_second;		/* Second (0..59) */
243     } sal_log_timestamp_t;
244     
245     
246     #define MAX_CACHE_ERRORS			6
247     #define MAX_TLB_ERRORS				6
248     #define MAX_BUS_ERRORS				1
249     
250     typedef struct sal_log_processor_info {
251     	struct	{
252     		u64 slpi_psi		: 1,
253     		    slpi_cache_check: MAX_CACHE_ERRORS,
254     		    slpi_tlb_check	: MAX_TLB_ERRORS,
255     		    slpi_bus_check	: MAX_BUS_ERRORS,
256     		    slpi_reserved2	: (31 - (MAX_TLB_ERRORS + MAX_CACHE_ERRORS
257     		    			 + MAX_BUS_ERRORS)),
258     		    slpi_minstate	: 1,
259     		    slpi_bank1_gr	: 1,
260     		    slpi_br		: 1,
261     		    slpi_cr		: 1,
262     		    slpi_ar		: 1,
263     		    slpi_rr		: 1,
264     		    slpi_fr		: 1,
265     		    slpi_reserved1	: 25;
266     	} slpi_valid;
267     
268     	pal_processor_state_info_t slpi_processor_state_info;
269     
270     	struct {
271     		pal_cache_check_info_t slpi_cache_check;
272     		u64 slpi_target_address;
273     	} slpi_cache_check_info[MAX_CACHE_ERRORS];
274     		
275     	pal_tlb_check_info_t slpi_tlb_check_info[MAX_TLB_ERRORS];
276     
277     	struct {
278     		pal_bus_check_info_t slpi_bus_check;
279     		u64 slpi_requestor_addr;	
280     		u64 slpi_responder_addr;	
281     		u64 slpi_target_addr;
282     	} slpi_bus_check_info[MAX_BUS_ERRORS];
283     
284     	pal_min_state_area_t slpi_min_state_area;
285     	u64 slpi_br[8];
286     	u64 slpi_cr[128];
287     	u64 slpi_ar[128];
288     	u64 slpi_rr[8];
289     	u64 slpi_fr[128];
290     } sal_log_processor_info_t;
291     
292     /* platform error log structures */
293     typedef struct platerr_logheader {
294     	u64 nextlog;		/* next log offset if present */
295     	u64 loglength;		/* log length */
296     	u64 logsubtype;		/* log subtype memory/bus/component */
297     	u64 eseverity;		/* error severity */
298     } ehdr_t;
299     
300     typedef struct sysmem_errlog {
301     	ehdr_t lhdr;		/* header */
302     	u64 vflag;		/* valid bits for each field in the log */
303     	u64 addr;		/* memory address */
304     	u64 data;		/* memory data */
305     	u64 cmd;		/* command bus value if any */
306     	u64 ctrl;		/* control bus value if any */
307     	u64 addrsyndrome;	/* memory address ecc/parity syndrome bits */
308     	u64 datasyndrome;	/* data ecc/parity syndrome */
309     	u64 cacheinfo;		/* platform cache info as defined in pal spec. table 7-34 */
310     } merrlog_t;
311     
312     typedef struct sysbus_errlog {
313     	ehdr_t lhdr;		/* linkded list header */
314     	u64 vflag;		/* valid bits for each field in the log */
315     	u64 busnum;		/* bus number in error */
316     	u64 reqaddr;		/* requestor address */
317     	u64 resaddr;		/* responder address */
318     	u64 taraddr;		/* target address */
319     	u64 data;		/* requester r/w data */
320     	u64 cmd;		/* bus commands */
321     	u64 ctrl;		/* bus controls (be# &-0) */
322     	u64 addrsyndrome;	/* addr bus ecc/parity bits */
323     	u64 datasyndrome;	/* data bus ecc/parity bits */
324     	u64 cmdsyndrome;	/* command bus ecc/parity bits */
325     	u64 ctrlsyndrome;	/* control bus ecc/parity bits */
326     } berrlog_t;
327     
328     /* platform error log structures */
329     typedef struct syserr_chdr {	/* one header per component */
330     	u64 busnum;		/* bus number on which the component resides */
331     	u64 devnum;		/* same as device select */
332     	u64 funcid;		/* function id of the device */
333     	u64 devid;		/* pci device id */
334     	u64 classcode;		/* pci class code for the device */
335     	u64 cmdreg;		/* pci command reg value */
336     	u64 statreg;		/* pci status reg value */
337     } chdr_t;
338     
339     typedef struct cfginfo {
340     	u64 cfgaddr;
341     	u64 cfgval;
342     } cfginfo_t;
343     
344     typedef struct sys_comperr {	/* per component */
345     	ehdr_t lhdr;		/* linked list header */
346     	u64 vflag;		/* valid bits for each field in the log */
347     	chdr_t scomphdr;	
348     	u64 numregpair;		/* number of reg addr/value pairs */
349     	cfginfo_t cfginfo;
350     } cerrlog_t;
351     
352     typedef struct sel_records {
353     	ehdr_t lhdr;
354     	u64 seldata;
355     } isel_t;
356     
357     typedef struct plat_errlog {
358     	u64 mbcsvalid;		/* valid bits for each type of log */
359     	merrlog_t smemerrlog;	/* platform memory error logs */
360     	berrlog_t sbuserrlog;	/* platform bus error logs */
361     	cerrlog_t scomperrlog;	/* platform chipset error logs */
362     	isel_t selrecord;	/* ipmi sel record */
363     } platforminfo_t;
364     
365     /* over all log structure (processor+platform) */
366     
367     typedef union udev_specific_log {
368     	sal_log_processor_info_t proclog;
369     	platforminfo_t platlog;
370     } devicelog_t;
371     
372     
373     #define sal_log_processor_info_psi_valid		slpi_valid.spli_psi
374     #define sal_log_processor_info_cache_check_valid	slpi_valid.spli_cache_check
375     #define sal_log_processor_info_tlb_check_valid		slpi_valid.spli_tlb_check
376     #define sal_log_processor_info_bus_check_valid		slpi_valid.spli_bus_check
377     #define sal_log_processor_info_minstate_valid		slpi_valid.spli_minstate
378     #define sal_log_processor_info_bank1_gr_valid		slpi_valid.slpi_bank1_gr
379     #define sal_log_processor_info_br_valid			slpi_valid.slpi_br
380     #define sal_log_processor_info_cr_valid			slpi_valid.slpi_cr
381     #define sal_log_processor_info_ar_valid			slpi_valid.slpi_ar
382     #define sal_log_processor_info_rr_valid			slpi_valid.slpi_rr
383     #define sal_log_processor_info_fr_valid			slpi_valid.slpi_fr
384     
385     typedef struct sal_log_header {
386     	u64 slh_next_log;	/* Offset of the next log from the beginning of this structure */
387     	u32 slh_log_len;	/* Length of this error log in bytes */
388     	u16 slh_log_type;	/* Type of log (0 - cpu ,1 - platform) */
389     	u16 slh_log_sub_type;	/* SGI specific sub type */
390     	sal_log_timestamp_t slh_log_timestamp;	/* Timestamp */
391     } sal_log_header_t;
392     
393     /* SAL PSI log structure */
394     typedef struct psilog {
395     	sal_log_header_t sal_elog_header;
396     	devicelog_t devlog;
397     } ia64_psilog_t;
398     
399     /*
400      * Now define a couple of inline functions for improved type checking
401      * and convenience.
402      */
403     static inline long
404     ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
405     		    unsigned long *drift_info)
406     {
407     	struct ia64_sal_retval isrv;
408     
409     	SAL_CALL(isrv, SAL_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
410     	*ticks_per_second = isrv.v0;
411     	*drift_info = isrv.v1;
412     	return isrv.status;
413     }
414     
415     /* Flush all the processor and platform level instruction and/or data caches */
416     static inline s64
417     ia64_sal_cache_flush (u64 cache_type)
418     {
419     	struct ia64_sal_retval isrv;
420     	SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
421     	return isrv.status;
422     }
423     
424     
425     	
426     /* Initialize all the processor and platform level instruction and data caches */
427     static inline s64
428     ia64_sal_cache_init (void)
429     {
430     	struct ia64_sal_retval isrv;
431     	SAL_CALL(isrv, SAL_CACHE_INIT, 0, 0, 0, 0, 0, 0, 0);
432     	return isrv.status;
433     }
434     
435     /* Clear the processor and platform information logged by SAL with respect to the 
436      * machine state at the time of MCA's, INITs or CMCs 
437      */
438     static inline s64
439     ia64_sal_clear_state_info (u64 sal_info_type)
440     {
441     	struct ia64_sal_retval isrv;
442     	SAL_CALL(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, 0, 0, 0, 0, 0, 0);
443     	return isrv.status;
444     }
445     
446     
447     /* Get the processor and platform information logged by SAL with respect to the machine
448      * state at the time of the MCAs, INITs or CMCs.
449      */
450     static inline u64
451     ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info)
452     {
453     	struct ia64_sal_retval isrv;
454     	SAL_CALL(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
455     	         sal_info, 0, 0, 0, 0);
456     	if (isrv.status)
457     		return 0;
458     	return isrv.v0;
459     }	
460     /* Get the maximum size of the information logged by SAL with respect to the machine 
461      * state at the time of MCAs, INITs or CMCs
462      */
463     static inline u64
464     ia64_sal_get_state_info_size (u64 sal_info_type)
465     {
466     	struct ia64_sal_retval isrv;
467     	SAL_CALL(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, 0, 0, 0, 0, 0, 0);
468     	if (isrv.status)
469     		return 0;
470     	return isrv.v0;
471     }
472     
473     /* Causes the processor to go into a spin loop within SAL where SAL awaits a wakeup
474      * from the monarch processor.
475      */
476     static inline s64
477     ia64_sal_mc_rendez (void)
478     {
479     	struct ia64_sal_retval isrv;
480     	SAL_CALL(isrv, SAL_MC_RENDEZ, 0, 0, 0, 0, 0, 0, 0);
481     	return isrv.status;
482     }
483     
484     /* Allow the OS to specify the interrupt number to be used by SAL to interrupt OS during
485      * the machine check rendezvous sequence as well as the mechanism to wake up the 
486      * non-monarch processor at the end of machine check processing.
487      */
488     static inline s64
489     ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout, u64 rz_always)
490     {
491     	struct ia64_sal_retval isrv;
492     	SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val, timeout, rz_always, 0, 0);
493     	return isrv.status;
494     }
495     
496     /* Read from PCI configuration space */
497     static inline s64
498     ia64_sal_pci_config_read (u64 pci_config_addr, u64 size, u64 *value)
499     {
500     	struct ia64_sal_retval isrv;
501     	SAL_CALL(isrv, SAL_PCI_CONFIG_READ, pci_config_addr, size, 0, 0, 0, 0, 0);
502     	if (value)
503     		*value = isrv.v0;
504     	return isrv.status;
505     }
506     
507     /* Write to PCI configuration space */
508     static inline s64
509     ia64_sal_pci_config_write (u64 pci_config_addr, u64 size, u64 value)
510     {
511     	struct ia64_sal_retval isrv;
512     	SAL_CALL(isrv, SAL_PCI_CONFIG_WRITE, pci_config_addr, size, value,
513     	         0, 0, 0, 0);
514     	return isrv.status;
515     }
516     
517     /*
518      * Register physical addresses of locations needed by SAL when SAL
519      * procedures are invoked in virtual mode.
520      */
521     static inline s64
522     ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr)
523     {
524     	struct ia64_sal_retval isrv;
525     	SAL_CALL(isrv, SAL_REGISTER_PHYSICAL_ADDR, phys_entry, phys_addr,
526     	         0, 0, 0, 0, 0);
527     	return isrv.status;
528     }
529     
530     /* Register software dependent code locations within SAL. These locations are handlers
531      * or entry points where SAL will pass control for the specified event. These event
532      * handlers are for the bott rendezvous, MCAs and INIT scenarios.
533      */
534     static inline s64
535     ia64_sal_set_vectors (u64 vector_type,
536     		      u64 handler_addr1, u64 gp1, u64 handler_len1,
537     		      u64 handler_addr2, u64 gp2, u64 handler_len2)
538     {
539     	struct ia64_sal_retval isrv;
540     	SAL_CALL(isrv, SAL_SET_VECTORS, vector_type,
541     			handler_addr1, gp1, handler_len1,
542     			handler_addr2, gp2, handler_len2);			
543     
544     	return isrv.status;
545     }		
546     /* Update the contents of PAL block in the non-volatile storage device */
547     static inline s64
548     ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size,
549     		     u64 *error_code, u64 *scratch_buf_size_needed)
550     {
551     	struct ia64_sal_retval isrv;
552     	SAL_CALL(isrv, SAL_UPDATE_PAL, param_buf, scratch_buf, scratch_buf_size,
553     	         0, 0, 0, 0);
554     	if (error_code)
555     		*error_code = isrv.v0;
556     	if (scratch_buf_size_needed)
557     		*scratch_buf_size_needed = isrv.v1;
558     	return isrv.status;
559     }
560     
561     #endif /* _ASM_IA64_PAL_H */
562