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