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