VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / include / asm-ia64 / sn / sn_sal.h
1 #ifndef _ASM_IA64_SN_SN_SAL_H
2 #define _ASM_IA64_SN_SN_SAL_H
3
4 /*
5  * System Abstraction Layer definitions for IA64
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  *
11  * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
12  */
13
14
15 #include <linux/config.h>
16 #include <asm/sal.h>
17 #include <asm/sn/sn_cpuid.h>
18 #include <asm/sn/arch.h>
19 #include <asm/sn/nodepda.h>
20 #include <asm/sn/klconfig.h>
21         
22
23 // SGI Specific Calls
24 #define  SN_SAL_POD_MODE                           0x02000001
25 #define  SN_SAL_SYSTEM_RESET                       0x02000002
26 #define  SN_SAL_PROBE                              0x02000003
27 #define  SN_SAL_GET_MASTER_NASID                   0x02000004
28 #define  SN_SAL_GET_KLCONFIG_ADDR                  0x02000005
29 #define  SN_SAL_LOG_CE                             0x02000006
30 #define  SN_SAL_REGISTER_CE                        0x02000007
31 #define  SN_SAL_GET_PARTITION_ADDR                 0x02000009
32 #define  SN_SAL_XP_ADDR_REGION                     0x0200000f
33 #define  SN_SAL_NO_FAULT_ZONE_VIRTUAL              0x02000010
34 #define  SN_SAL_NO_FAULT_ZONE_PHYSICAL             0x02000011
35 #define  SN_SAL_PRINT_ERROR                        0x02000012
36 #define  SN_SAL_SET_ERROR_HANDLING_FEATURES        0x0200001a   // reentrant
37 #define  SN_SAL_CONSOLE_PUTC                       0x02000021
38 #define  SN_SAL_CONSOLE_GETC                       0x02000022
39 #define  SN_SAL_CONSOLE_PUTS                       0x02000023
40 #define  SN_SAL_CONSOLE_GETS                       0x02000024
41 #define  SN_SAL_CONSOLE_GETS_TIMEOUT               0x02000025
42 #define  SN_SAL_CONSOLE_POLL                       0x02000026
43 #define  SN_SAL_CONSOLE_INTR                       0x02000027
44 #define  SN_SAL_CONSOLE_PUTB                       0x02000028
45 #define  SN_SAL_CONSOLE_XMIT_CHARS                 0x0200002a
46 #define  SN_SAL_CONSOLE_READC                      0x0200002b
47 #define  SN_SAL_SYSCTL_MODID_GET                   0x02000031
48 #define  SN_SAL_SYSCTL_GET                         0x02000032
49 #define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
50 #define  SN_SAL_SYSCTL_IO_PORTSPEED_GET            0x02000035
51 #define  SN_SAL_SYSCTL_SLAB_GET                    0x02000036
52 #define  SN_SAL_BUS_CONFIG                         0x02000037
53 #define  SN_SAL_SYS_SERIAL_GET                     0x02000038
54 #define  SN_SAL_PARTITION_SERIAL_GET               0x02000039
55 #define  SN_SAL_SYSCTL_PARTITION_GET               0x0200003a
56 #define  SN_SAL_SYSTEM_POWER_DOWN                  0x0200003b
57 #define  SN_SAL_GET_MASTER_BASEIO_NASID            0x0200003c
58 #define  SN_SAL_COHERENCE                          0x0200003d
59 #define  SN_SAL_MEMPROTECT                         0x0200003e
60 #define  SN_SAL_SYSCTL_FRU_CAPTURE                 0x0200003f
61
62 #define  SN_SAL_SYSCTL_IOBRICK_PCI_OP              0x02000042   // reentrant
63
64 /*
65  * Service-specific constants
66  */
67
68 /* Console interrupt manipulation */
69         /* action codes */
70 #define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
71 #define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
72 #define SAL_CONSOLE_INTR_STATUS 2       /* retrieve the interrupt status */
73         /* interrupt specification & status return codes */
74 #define SAL_CONSOLE_INTR_XMIT   1       /* output interrupt */
75 #define SAL_CONSOLE_INTR_RECV   2       /* input interrupt */
76
77 #ifdef CONFIG_HOTPLUG_PCI_SGI
78 /* power up / power down / reset a PCI slot or bus */
79 #define SAL_SYSCTL_PCI_POWER_UP         0
80 #define SAL_SYSCTL_PCI_POWER_DOWN       1
81 #define SAL_SYSCTL_PCI_RESET            2
82
83 /* what type of I/O brick? */
84 #define SAL_SYSCTL_IO_XTALK     0       /* connected via a compute node */
85
86 #endif  /* CONFIG_HOTPLUG_PCI_SGI */
87
88 /*
89  * SN_SAL_GET_PARTITION_ADDR return constants
90  */
91 #define SALRET_MORE_PASSES      1
92 #define SALRET_OK               0
93 #define SALRET_INVALID_ARG      -2
94 #define SALRET_ERROR            -3
95
96 /*
97  * SN_SAL_SET_ERROR_HANDLING_FEATURES bit settings
98  */
99 enum 
100 {
101         /* if "rz always" is set, have the mca slaves call os_init_slave */
102         SN_SAL_EHF_MCA_SLV_TO_OS_INIT_SLV=0,
103         /* do not rz on tlb checks, even if "rz always" is set */
104         SN_SAL_EHF_NO_RZ_TLBC,
105         /* do not rz on PIO reads to I/O space, even if "rz always" is set */
106         SN_SAL_EHF_NO_RZ_IO_READ,
107 };
108
109
110 /**
111  * sn_sal_rev_major - get the major SGI SAL revision number
112  *
113  * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
114  * This routine simply extracts the major value from the
115  * @ia64_sal_systab structure constructed by ia64_sal_init().
116  */
117 static inline int
118 sn_sal_rev_major(void)
119 {
120         struct ia64_sal_systab *systab = efi.sal_systab;
121
122         return (int)systab->sal_b_rev_major;
123 }
124
125 /**
126  * sn_sal_rev_minor - get the minor SGI SAL revision number
127  *
128  * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
129  * This routine simply extracts the minor value from the
130  * @ia64_sal_systab structure constructed by ia64_sal_init().
131  */
132 static inline int
133 sn_sal_rev_minor(void)
134 {
135         struct ia64_sal_systab *systab = efi.sal_systab;
136         
137         return (int)systab->sal_b_rev_minor;
138 }
139
140 /*
141  * Specify the minimum PROM revsion required for this kernel.
142  * Note that they're stored in hex format...
143  */
144 #define SN_SAL_MIN_MAJOR        0x3  /* SN2 kernels need at least PROM 3.40 */
145 #define SN_SAL_MIN_MINOR        0x40
146
147 u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
148
149 /*
150  * Returns the master console nasid, if the call fails, return an illegal
151  * value.
152  */
153 static inline u64
154 ia64_sn_get_console_nasid(void)
155 {
156         struct ia64_sal_retval ret_stuff;
157
158         ret_stuff.status = 0;
159         ret_stuff.v0 = 0;
160         ret_stuff.v1 = 0;
161         ret_stuff.v2 = 0;
162         SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
163
164         if (ret_stuff.status < 0)
165                 return ret_stuff.status;
166
167         /* Master console nasid is in 'v0' */
168         return ret_stuff.v0;
169 }
170
171 /*
172  * Returns the master baseio nasid, if the call fails, return an illegal
173  * value.
174  */
175 static inline u64
176 ia64_sn_get_master_baseio_nasid(void)
177 {
178         struct ia64_sal_retval ret_stuff;
179
180         ret_stuff.status = 0;
181         ret_stuff.v0 = 0;
182         ret_stuff.v1 = 0;
183         ret_stuff.v2 = 0;
184         SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
185
186         if (ret_stuff.status < 0)
187                 return ret_stuff.status;
188
189         /* Master baseio nasid is in 'v0' */
190         return ret_stuff.v0;
191 }
192
193 static inline u64
194 ia64_sn_get_klconfig_addr(nasid_t nasid)
195 {
196         struct ia64_sal_retval ret_stuff;
197         int cnodeid;
198
199         cnodeid = nasid_to_cnodeid(nasid);
200         ret_stuff.status = 0;
201         ret_stuff.v0 = 0;
202         ret_stuff.v1 = 0;
203         ret_stuff.v2 = 0;
204         SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
205
206         /*
207          * We should panic if a valid cnode nasid does not produce
208          * a klconfig address.
209          */
210         if (ret_stuff.status != 0) {
211                 panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
212         }
213         return(ret_stuff.v0);
214 }
215
216 /*
217  * Returns the next console character.
218  */
219 static inline u64
220 ia64_sn_console_getc(int *ch)
221 {
222         struct ia64_sal_retval ret_stuff;
223
224         ret_stuff.status = 0;
225         ret_stuff.v0 = 0;
226         ret_stuff.v1 = 0;
227         ret_stuff.v2 = 0;
228         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
229
230         /* character is in 'v0' */
231         *ch = (int)ret_stuff.v0;
232
233         return ret_stuff.status;
234 }
235
236 /*
237  * Read a character from the SAL console device, after a previous interrupt
238  * or poll operation has given us to know that a character is available
239  * to be read.
240  */
241 static inline u64
242 ia64_sn_console_readc(void)
243 {
244         struct ia64_sal_retval ret_stuff;
245
246         ret_stuff.status = 0;
247         ret_stuff.v0 = 0;
248         ret_stuff.v1 = 0;
249         ret_stuff.v2 = 0;
250         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
251
252         /* character is in 'v0' */
253         return ret_stuff.v0;
254 }
255
256 /*
257  * Sends the given character to the console.
258  */
259 static inline u64
260 ia64_sn_console_putc(char ch)
261 {
262         struct ia64_sal_retval ret_stuff;
263
264         ret_stuff.status = 0;
265         ret_stuff.v0 = 0;
266         ret_stuff.v1 = 0;
267         ret_stuff.v2 = 0;
268         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
269
270         return ret_stuff.status;
271 }
272
273 /*
274  * Sends the given buffer to the console.
275  */
276 static inline u64
277 ia64_sn_console_putb(const char *buf, int len)
278 {
279         struct ia64_sal_retval ret_stuff;
280
281         ret_stuff.status = 0;
282         ret_stuff.v0 = 0; 
283         ret_stuff.v1 = 0;
284         ret_stuff.v2 = 0;
285         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0);
286
287         if ( ret_stuff.status == 0 ) {
288                 return ret_stuff.v0;
289         }
290         return (u64)0;
291 }
292
293 /*
294  * Print a platform error record
295  */
296 static inline u64
297 ia64_sn_plat_specific_err_print(int (*hook)(const char*, ...), char *rec)
298 {
299         struct ia64_sal_retval ret_stuff;
300
301         ret_stuff.status = 0;
302         ret_stuff.v0 = 0;
303         ret_stuff.v1 = 0;
304         ret_stuff.v2 = 0;
305         SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0);
306
307         return ret_stuff.status;
308 }
309
310 /*
311  * Check for Platform errors
312  */
313 static inline u64
314 ia64_sn_plat_cpei_handler(void)
315 {
316         struct ia64_sal_retval ret_stuff;
317
318         ret_stuff.status = 0;
319         ret_stuff.v0 = 0;
320         ret_stuff.v1 = 0;
321         ret_stuff.v2 = 0;
322         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
323
324         return ret_stuff.status;
325 }
326
327 /*
328  * Checks for console input.
329  */
330 static inline u64
331 ia64_sn_console_check(int *result)
332 {
333         struct ia64_sal_retval ret_stuff;
334
335         ret_stuff.status = 0;
336         ret_stuff.v0 = 0;
337         ret_stuff.v1 = 0;
338         ret_stuff.v2 = 0;
339         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
340
341         /* result is in 'v0' */
342         *result = (int)ret_stuff.v0;
343
344         return ret_stuff.status;
345 }
346
347 /*
348  * Checks console interrupt status
349  */
350 static inline u64
351 ia64_sn_console_intr_status(void)
352 {
353         struct ia64_sal_retval ret_stuff;
354
355         ret_stuff.status = 0;
356         ret_stuff.v0 = 0;
357         ret_stuff.v1 = 0;
358         ret_stuff.v2 = 0;
359         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
360                  0, SAL_CONSOLE_INTR_STATUS,
361                  0, 0, 0, 0, 0);
362
363         if (ret_stuff.status == 0) {
364             return ret_stuff.v0;
365         }
366         
367         return 0;
368 }
369
370 /*
371  * Enable an interrupt on the SAL console device.
372  */
373 static inline void
374 ia64_sn_console_intr_enable(uint64_t intr)
375 {
376         struct ia64_sal_retval ret_stuff;
377
378         ret_stuff.status = 0;
379         ret_stuff.v0 = 0;
380         ret_stuff.v1 = 0;
381         ret_stuff.v2 = 0;
382         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
383                  intr, SAL_CONSOLE_INTR_ON,
384                  0, 0, 0, 0, 0);
385 }
386
387 /*
388  * Disable an interrupt on the SAL console device.
389  */
390 static inline void
391 ia64_sn_console_intr_disable(uint64_t intr)
392 {
393         struct ia64_sal_retval ret_stuff;
394
395         ret_stuff.status = 0;
396         ret_stuff.v0 = 0;
397         ret_stuff.v1 = 0;
398         ret_stuff.v2 = 0;
399         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
400                  intr, SAL_CONSOLE_INTR_OFF,
401                  0, 0, 0, 0, 0);
402 }
403
404 /*
405  * Sends a character buffer to the console asynchronously.
406  */
407 static inline u64
408 ia64_sn_console_xmit_chars(char *buf, int len)
409 {
410         struct ia64_sal_retval ret_stuff;
411
412         ret_stuff.status = 0;
413         ret_stuff.v0 = 0;
414         ret_stuff.v1 = 0;
415         ret_stuff.v2 = 0;
416         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
417                  (uint64_t)buf, (uint64_t)len,
418                  0, 0, 0, 0, 0);
419
420         if (ret_stuff.status == 0) {
421             return ret_stuff.v0;
422         }
423
424         return 0;
425 }
426
427 /*
428  * Returns the iobrick module Id
429  */
430 static inline u64
431 ia64_sn_sysctl_iobrick_module_get(nasid_t nasid, int *result)
432 {
433         struct ia64_sal_retval ret_stuff;
434
435         ret_stuff.status = 0;
436         ret_stuff.v0 = 0;
437         ret_stuff.v1 = 0;
438         ret_stuff.v2 = 0;
439         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
440
441         /* result is in 'v0' */
442         *result = (int)ret_stuff.v0;
443
444         return ret_stuff.status;
445 }
446
447 /**
448  * ia64_sn_pod_mode - call the SN_SAL_POD_MODE function
449  *
450  * SN_SAL_POD_MODE actually takes an argument, but it's always
451  * 0 when we call it from the kernel, so we don't have to expose
452  * it to the caller.
453  */
454 static inline u64
455 ia64_sn_pod_mode(void)
456 {
457         struct ia64_sal_retval isrv;
458         SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
459         if (isrv.status)
460                 return 0;
461         return isrv.v0;
462 }
463
464 /*
465  * Retrieve the system serial number as an ASCII string.
466  */
467 static inline u64
468 ia64_sn_sys_serial_get(char *buf)
469 {
470         struct ia64_sal_retval ret_stuff;
471         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
472         return ret_stuff.status;
473 }
474
475 extern char sn_system_serial_number_string[];
476 extern u64 sn_partition_serial_number;
477
478 static inline char *
479 sn_system_serial_number(void) {
480         if (sn_system_serial_number_string[0]) {
481                 return(sn_system_serial_number_string);
482         } else {
483                 ia64_sn_sys_serial_get(sn_system_serial_number_string);
484                 return(sn_system_serial_number_string);
485         }
486 }
487         
488
489 /*
490  * Returns a unique id number for this system and partition (suitable for
491  * use with license managers), based in part on the system serial number.
492  */
493 static inline u64
494 ia64_sn_partition_serial_get(void)
495 {
496         struct ia64_sal_retval ret_stuff;
497         SAL_CALL(ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, 0, 0, 0, 0, 0, 0);
498         if (ret_stuff.status != 0)
499             return 0;
500         return ret_stuff.v0;
501 }
502
503 static inline u64
504 sn_partition_serial_number_val(void) {
505         if (sn_partition_serial_number) {
506                 return(sn_partition_serial_number);
507         } else {
508                 return(sn_partition_serial_number = ia64_sn_partition_serial_get());
509         }
510 }
511
512 /*
513  * Returns the partition id of the nasid passed in as an argument,
514  * or INVALID_PARTID if the partition id cannot be retrieved.
515  */
516 static inline partid_t
517 ia64_sn_sysctl_partition_get(nasid_t nasid)
518 {
519         struct ia64_sal_retval ret_stuff;
520         SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
521                  0, 0, 0, 0, 0, 0);
522         if (ret_stuff.status != 0)
523             return INVALID_PARTID;
524         return ((partid_t)ret_stuff.v0);
525 }
526
527 /*
528  * Returns the partition id of the current processor.
529  */
530
531 extern partid_t sn_partid;
532
533 static inline partid_t
534 sn_local_partid(void) {
535         if (sn_partid < 0) {
536                 return (sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id())));
537         } else {
538                 return sn_partid;
539         }
540 }
541
542 /*
543  * Register or unregister a physical address range being referenced across
544  * a partition boundary for which certain SAL errors should be scanned for,
545  * cleaned up and ignored.  This is of value for kernel partitioning code only.
546  * Values for the operation argument:
547  *      1 = register this address range with SAL
548  *      0 = unregister this address range with SAL
549  * 
550  * SAL maintains a reference count on an address range in case it is registered
551  * multiple times.
552  * 
553  * On success, returns the reference count of the address range after the SAL
554  * call has performed the current registration/unregistration.  Returns a
555  * negative value if an error occurred.
556  */
557 static inline int
558 sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
559 {
560         struct ia64_sal_retval ret_stuff;
561         SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
562                  0, 0, 0, 0);
563         return ret_stuff.status;
564 }
565
566 /*
567  * Register or unregister an instruction range for which SAL errors should
568  * be ignored.  If an error occurs while in the registered range, SAL jumps
569  * to return_addr after ignoring the error.  Values for the operation argument:
570  *      1 = register this instruction range with SAL
571  *      0 = unregister this instruction range with SAL
572  *
573  * Returns 0 on success, or a negative value if an error occurred.
574  */
575 static inline int
576 sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
577                          int virtual, int operation)
578 {
579         struct ia64_sal_retval ret_stuff;
580         u64 call;
581         if (virtual) {
582                 call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
583         } else {
584                 call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
585         }
586         SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
587                  0, 0, 0);
588         return ret_stuff.status;
589 }
590
591 /*
592  * Change or query the coherence domain for this partition. Each cpu-based
593  * nasid is represented by a bit in an array of 64-bit words:
594  *      0 = not in this partition's coherency domain
595  *      1 = in this partition's coherency domain
596  *
597  * It is not possible for the local system's nasids to be removed from
598  * the coherency domain.  Purpose of the domain arguments:
599  *      new_domain = set the coherence domain to the given nasids
600  *      old_domain = return the current coherence domain
601  *
602  * Returns 0 on success, or a negative value if an error occurred.
603  */
604 static inline int
605 sn_change_coherence(u64 *new_domain, u64 *old_domain)
606 {
607         struct ia64_sal_retval ret_stuff;
608         SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
609                  0, 0, 0);
610         return ret_stuff.status;
611 }
612
613 /*
614  * Change memory access protections for a physical address range.
615  * nasid_array is not used on Altix, but may be in future architectures.
616  * Available memory protection access classes are defined after the function.
617  */
618 static inline int
619 sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
620 {
621         struct ia64_sal_retval ret_stuff;
622         int cnodeid;
623         unsigned long irq_flags;
624
625         cnodeid = nasid_to_cnodeid(get_node_number(paddr));
626         spin_lock(&NODEPDA(cnodeid)->bist_lock);
627         local_irq_save(irq_flags);
628         SAL_CALL_NOLOCK(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
629                  perms, 0, 0, 0);
630         local_irq_restore(irq_flags);
631         spin_unlock(&NODEPDA(cnodeid)->bist_lock);
632         return ret_stuff.status;
633 }
634 #define SN_MEMPROT_ACCESS_CLASS_0               0x14a080
635 #define SN_MEMPROT_ACCESS_CLASS_1               0x2520c2
636 #define SN_MEMPROT_ACCESS_CLASS_2               0x14a1ca
637 #define SN_MEMPROT_ACCESS_CLASS_3               0x14a290
638 #define SN_MEMPROT_ACCESS_CLASS_6               0x084080
639 #define SN_MEMPROT_ACCESS_CLASS_7               0x021080
640
641 /*
642  * Turns off system power.
643  */
644 static inline void
645 ia64_sn_power_down(void)
646 {
647         struct ia64_sal_retval ret_stuff;
648         SAL_CALL(ret_stuff, SN_SAL_SYSTEM_POWER_DOWN, 0, 0, 0, 0, 0, 0, 0);
649         while(1);
650         /* never returns */
651 }
652
653 /**
654  * ia64_sn_fru_capture - tell the system controller to capture hw state
655  *
656  * This routine will call the SAL which will tell the system controller(s)
657  * to capture hw mmr information from each SHub in the system.
658  */
659 static inline u64
660 ia64_sn_fru_capture(void)
661 {
662         struct ia64_sal_retval isrv;
663         SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
664         if (isrv.status)
665                 return 0;
666         return isrv.v0;
667 }
668
669 /*
670  * Performs an operation on a PCI bus or slot -- power up, power down
671  * or reset.
672  */
673 static inline u64
674 ia64_sn_sysctl_iobrick_pci_op(nasid_t n, u64 connection_type, 
675                               u64 bus, slotid_t slot, 
676                               u64 action)
677 {
678         struct ia64_sal_retval rv = {0, 0, 0, 0};
679
680         SAL_CALL_NOLOCK(rv, SN_SAL_SYSCTL_IOBRICK_PCI_OP, connection_type, n, action,
681                  bus, (u64) slot, 0, 0);
682         if (rv.status)
683                 return rv.v0;
684         return 0;
685 }
686
687 /*
688  * Tell the prom how the OS wants to handle specific error features.
689  * It takes an array of 7 u64.
690  */
691 static inline u64
692 ia64_sn_set_error_handling_features(const u64 *feature_bits)
693 {
694         struct ia64_sal_retval rv = {0, 0, 0, 0};
695
696         SAL_CALL_REENTRANT(rv, SN_SAL_SET_ERROR_HANDLING_FEATURES,
697                         feature_bits[0],
698                         feature_bits[1],
699                         feature_bits[2],
700                         feature_bits[3],
701                         feature_bits[4],
702                         feature_bits[5],
703                         feature_bits[6]);
704         return rv.status;
705 }
706
707 #endif /* _ASM_IA64_SN_SN_SAL_H */