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