1 #ifndef _ASM_IA64_SN_SN_SAL_H
2 #define _ASM_IA64_SN_SN_SAL_H
5 * System Abstraction Layer definitions for IA64
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
11 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All rights reserved.
15 #include <linux/config.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>
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_CONSOLE_PUTC 0x02000021
37 #define SN_SAL_CONSOLE_GETC 0x02000022
38 #define SN_SAL_CONSOLE_PUTS 0x02000023
39 #define SN_SAL_CONSOLE_GETS 0x02000024
40 #define SN_SAL_CONSOLE_GETS_TIMEOUT 0x02000025
41 #define SN_SAL_CONSOLE_POLL 0x02000026
42 #define SN_SAL_CONSOLE_INTR 0x02000027
43 #define SN_SAL_CONSOLE_PUTB 0x02000028
44 #define SN_SAL_CONSOLE_XMIT_CHARS 0x0200002a
45 #define SN_SAL_CONSOLE_READC 0x0200002b
46 #define SN_SAL_SYSCTL_MODID_GET 0x02000031
47 #define SN_SAL_SYSCTL_GET 0x02000032
48 #define SN_SAL_SYSCTL_IOBRICK_MODULE_GET 0x02000033
49 #define SN_SAL_SYSCTL_IO_PORTSPEED_GET 0x02000035
50 #define SN_SAL_SYSCTL_SLAB_GET 0x02000036
51 #define SN_SAL_BUS_CONFIG 0x02000037
52 #define SN_SAL_SYS_SERIAL_GET 0x02000038
53 #define SN_SAL_PARTITION_SERIAL_GET 0x02000039
54 #define SN_SAL_SYSCTL_PARTITION_GET 0x0200003a
55 #define SN_SAL_SYSTEM_POWER_DOWN 0x0200003b
56 #define SN_SAL_GET_MASTER_BASEIO_NASID 0x0200003c
57 #define SN_SAL_COHERENCE 0x0200003d
58 #define SN_SAL_MEMPROTECT 0x0200003e
59 #define SN_SAL_SYSCTL_FRU_CAPTURE 0x0200003f
61 #define SN_SAL_SYSCTL_IOBRICK_PCI_OP 0x02000042 // reentrant
64 * Service-specific constants
67 /* Console interrupt manipulation */
69 #define SAL_CONSOLE_INTR_OFF 0 /* turn the interrupt off */
70 #define SAL_CONSOLE_INTR_ON 1 /* turn the interrupt on */
71 #define SAL_CONSOLE_INTR_STATUS 2 /* retrieve the interrupt status */
72 /* interrupt specification & status return codes */
73 #define SAL_CONSOLE_INTR_XMIT 1 /* output interrupt */
74 #define SAL_CONSOLE_INTR_RECV 2 /* input interrupt */
76 #ifdef CONFIG_HOTPLUG_PCI_SGI
77 /* power up / power down / reset a PCI slot or bus */
78 #define SAL_SYSCTL_PCI_POWER_UP 0
79 #define SAL_SYSCTL_PCI_POWER_DOWN 1
80 #define SAL_SYSCTL_PCI_RESET 2
82 /* what type of I/O brick? */
83 #define SAL_SYSCTL_IO_XTALK 0 /* connected via a compute node */
85 #endif /* CONFIG_HOTPLUG_PCI_SGI */
88 * SN_SAL_GET_PARTITION_ADDR return constants
90 #define SALRET_MORE_PASSES 1
92 #define SALRET_INVALID_ARG -2
93 #define SALRET_ERROR -3
97 * sn_sal_rev_major - get the major SGI SAL revision number
99 * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
100 * This routine simply extracts the major value from the
101 * @ia64_sal_systab structure constructed by ia64_sal_init().
104 sn_sal_rev_major(void)
106 struct ia64_sal_systab *systab = efi.sal_systab;
108 return (int)systab->sal_b_rev_major;
112 * sn_sal_rev_minor - get the minor SGI SAL revision number
114 * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
115 * This routine simply extracts the minor value from the
116 * @ia64_sal_systab structure constructed by ia64_sal_init().
119 sn_sal_rev_minor(void)
121 struct ia64_sal_systab *systab = efi.sal_systab;
123 return (int)systab->sal_b_rev_minor;
127 * Specify the minimum PROM revsion required for this kernel.
128 * Note that they're stored in hex format...
130 #define SN_SAL_MIN_MAJOR 0x1 /* SN2 kernels need at least PROM 1.0 */
131 #define SN_SAL_MIN_MINOR 0x0
133 u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
136 * Returns the master console nasid, if the call fails, return an illegal
140 ia64_sn_get_console_nasid(void)
142 struct ia64_sal_retval ret_stuff;
144 ret_stuff.status = 0;
148 SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
150 if (ret_stuff.status < 0)
151 return ret_stuff.status;
153 /* Master console nasid is in 'v0' */
158 * Returns the master baseio nasid, if the call fails, return an illegal
162 ia64_sn_get_master_baseio_nasid(void)
164 struct ia64_sal_retval ret_stuff;
166 ret_stuff.status = 0;
170 SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
172 if (ret_stuff.status < 0)
173 return ret_stuff.status;
175 /* Master baseio nasid is in 'v0' */
180 ia64_sn_get_klconfig_addr(nasid_t nasid)
182 struct ia64_sal_retval ret_stuff;
185 cnodeid = nasid_to_cnodeid(nasid);
186 ret_stuff.status = 0;
190 SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
193 * We should panic if a valid cnode nasid does not produce
194 * a klconfig address.
196 if (ret_stuff.status != 0) {
197 panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
199 return(ret_stuff.v0);
203 * Returns the next console character.
206 ia64_sn_console_getc(int *ch)
208 struct ia64_sal_retval ret_stuff;
210 ret_stuff.status = 0;
214 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
216 /* character is in 'v0' */
217 *ch = (int)ret_stuff.v0;
219 return ret_stuff.status;
223 * Read a character from the SAL console device, after a previous interrupt
224 * or poll operation has given us to know that a character is available
228 ia64_sn_console_readc(void)
230 struct ia64_sal_retval ret_stuff;
232 ret_stuff.status = 0;
236 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
238 /* character is in 'v0' */
243 * Sends the given character to the console.
246 ia64_sn_console_putc(char ch)
248 struct ia64_sal_retval ret_stuff;
250 ret_stuff.status = 0;
254 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
256 return ret_stuff.status;
260 * Sends the given buffer to the console.
263 ia64_sn_console_putb(const char *buf, int len)
265 struct ia64_sal_retval ret_stuff;
267 ret_stuff.status = 0;
271 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0);
273 if ( ret_stuff.status == 0 ) {
280 * Print a platform error record
283 ia64_sn_plat_specific_err_print(int (*hook)(const char*, ...), char *rec)
285 struct ia64_sal_retval ret_stuff;
287 ret_stuff.status = 0;
291 SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0);
293 return ret_stuff.status;
297 * Check for Platform errors
300 ia64_sn_plat_cpei_handler(void)
302 struct ia64_sal_retval ret_stuff;
304 ret_stuff.status = 0;
308 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
310 return ret_stuff.status;
314 * Checks for console input.
317 ia64_sn_console_check(int *result)
319 struct ia64_sal_retval ret_stuff;
321 ret_stuff.status = 0;
325 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
327 /* result is in 'v0' */
328 *result = (int)ret_stuff.v0;
330 return ret_stuff.status;
334 * Checks console interrupt status
337 ia64_sn_console_intr_status(void)
339 struct ia64_sal_retval ret_stuff;
341 ret_stuff.status = 0;
345 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR,
346 0, SAL_CONSOLE_INTR_STATUS,
349 if (ret_stuff.status == 0) {
357 * Enable an interrupt on the SAL console device.
360 ia64_sn_console_intr_enable(uint64_t intr)
362 struct ia64_sal_retval ret_stuff;
364 ret_stuff.status = 0;
368 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR,
369 intr, SAL_CONSOLE_INTR_ON,
374 * Disable an interrupt on the SAL console device.
377 ia64_sn_console_intr_disable(uint64_t intr)
379 struct ia64_sal_retval ret_stuff;
381 ret_stuff.status = 0;
385 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR,
386 intr, SAL_CONSOLE_INTR_OFF,
391 * Sends a character buffer to the console asynchronously.
394 ia64_sn_console_xmit_chars(char *buf, int len)
396 struct ia64_sal_retval ret_stuff;
398 ret_stuff.status = 0;
402 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
403 (uint64_t)buf, (uint64_t)len,
406 if (ret_stuff.status == 0) {
414 * Returns the iobrick module Id
417 ia64_sn_sysctl_iobrick_module_get(nasid_t nasid, int *result)
419 struct ia64_sal_retval ret_stuff;
421 ret_stuff.status = 0;
425 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
427 /* result is in 'v0' */
428 *result = (int)ret_stuff.v0;
430 return ret_stuff.status;
434 * ia64_sn_pod_mode - call the SN_SAL_POD_MODE function
436 * SN_SAL_POD_MODE actually takes an argument, but it's always
437 * 0 when we call it from the kernel, so we don't have to expose
441 ia64_sn_pod_mode(void)
443 struct ia64_sal_retval isrv;
444 SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
451 * Retrieve the system serial number as an ASCII string.
454 ia64_sn_sys_serial_get(char *buf)
456 struct ia64_sal_retval ret_stuff;
457 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
458 return ret_stuff.status;
461 extern char sn_system_serial_number_string[];
462 extern u64 sn_partition_serial_number;
465 sn_system_serial_number(void) {
466 if (sn_system_serial_number_string[0]) {
467 return(sn_system_serial_number_string);
469 ia64_sn_sys_serial_get(sn_system_serial_number_string);
470 return(sn_system_serial_number_string);
476 * Returns a unique id number for this system and partition (suitable for
477 * use with license managers), based in part on the system serial number.
480 ia64_sn_partition_serial_get(void)
482 struct ia64_sal_retval ret_stuff;
483 SAL_CALL(ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, 0, 0, 0, 0, 0, 0);
484 if (ret_stuff.status != 0)
490 sn_partition_serial_number_val(void) {
491 if (sn_partition_serial_number) {
492 return(sn_partition_serial_number);
494 return(sn_partition_serial_number = ia64_sn_partition_serial_get());
499 * Returns the partition id of the nasid passed in as an argument,
500 * or INVALID_PARTID if the partition id cannot be retrieved.
502 static inline partid_t
503 ia64_sn_sysctl_partition_get(nasid_t nasid)
505 struct ia64_sal_retval ret_stuff;
506 SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
508 if (ret_stuff.status != 0)
509 return INVALID_PARTID;
510 return ((partid_t)ret_stuff.v0);
514 * Returns the partition id of the current processor.
517 extern partid_t sn_partid;
519 static inline partid_t
520 sn_local_partid(void) {
522 return (sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id())));
529 * Register or unregister a physical address range being referenced across
530 * a partition boundary for which certain SAL errors should be scanned for,
531 * cleaned up and ignored. This is of value for kernel partitioning code only.
532 * Values for the operation argument:
533 * 1 = register this address range with SAL
534 * 0 = unregister this address range with SAL
536 * SAL maintains a reference count on an address range in case it is registered
539 * On success, returns the reference count of the address range after the SAL
540 * call has performed the current registration/unregistration. Returns a
541 * negative value if an error occurred.
544 sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
546 struct ia64_sal_retval ret_stuff;
547 SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
549 return ret_stuff.status;
553 * Register or unregister an instruction range for which SAL errors should
554 * be ignored. If an error occurs while in the registered range, SAL jumps
555 * to return_addr after ignoring the error. Values for the operation argument:
556 * 1 = register this instruction range with SAL
557 * 0 = unregister this instruction range with SAL
559 * Returns 0 on success, or a negative value if an error occurred.
562 sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
563 int virtual, int operation)
565 struct ia64_sal_retval ret_stuff;
568 call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
570 call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
572 SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
574 return ret_stuff.status;
578 * Change or query the coherence domain for this partition. Each cpu-based
579 * nasid is represented by a bit in an array of 64-bit words:
580 * 0 = not in this partition's coherency domain
581 * 1 = in this partition's coherency domain
583 * It is not possible for the local system's nasids to be removed from
584 * the coherency domain. Purpose of the domain arguments:
585 * new_domain = set the coherence domain to the given nasids
586 * old_domain = return the current coherence domain
588 * Returns 0 on success, or a negative value if an error occurred.
591 sn_change_coherence(u64 *new_domain, u64 *old_domain)
593 struct ia64_sal_retval ret_stuff;
594 SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
596 return ret_stuff.status;
600 * Change memory access protections for a physical address range.
601 * nasid_array is not used on Altix, but may be in future architectures.
602 * Available memory protection access classes are defined after the function.
605 sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
607 struct ia64_sal_retval ret_stuff;
609 unsigned long irq_flags;
611 cnodeid = nasid_to_cnodeid(get_node_number(paddr));
612 spin_lock(&NODEPDA(cnodeid)->bist_lock);
613 local_irq_save(irq_flags);
614 SAL_CALL_NOLOCK(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
616 local_irq_restore(irq_flags);
617 spin_unlock(&NODEPDA(cnodeid)->bist_lock);
618 return ret_stuff.status;
620 #define SN_MEMPROT_ACCESS_CLASS_0 0x14a080
621 #define SN_MEMPROT_ACCESS_CLASS_1 0x2520c2
622 #define SN_MEMPROT_ACCESS_CLASS_2 0x14a1ca
623 #define SN_MEMPROT_ACCESS_CLASS_3 0x14a290
624 #define SN_MEMPROT_ACCESS_CLASS_6 0x084080
625 #define SN_MEMPROT_ACCESS_CLASS_7 0x021080
628 * Turns off system power.
631 ia64_sn_power_down(void)
633 struct ia64_sal_retval ret_stuff;
634 SAL_CALL(ret_stuff, SN_SAL_SYSTEM_POWER_DOWN, 0, 0, 0, 0, 0, 0, 0);
640 * ia64_sn_fru_capture - tell the system controller to capture hw state
642 * This routine will call the SAL which will tell the system controller(s)
643 * to capture hw mmr information from each SHub in the system.
646 ia64_sn_fru_capture(void)
648 struct ia64_sal_retval isrv;
649 SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
656 * Performs an operation on a PCI bus or slot -- power up, power down
660 ia64_sn_sysctl_iobrick_pci_op(nasid_t n, u64 connection_type,
661 u64 bus, slotid_t slot,
664 struct ia64_sal_retval rv = {0, 0, 0, 0};
666 SAL_CALL_NOLOCK(rv, SN_SAL_SYSCTL_IOBRICK_PCI_OP, connection_type, n, action,
667 bus, (u64) slot, 0, 0);
673 #endif /* _ASM_IA64_SN_SN_SAL_H */