[IA64] hotplug/ia64: SN Hotplug Driver - new SN PROM version code
[linux-2.6.git] / include / asm-ia64 / sn / sn_sal.h
index 88c31b5..27976d2 100644 (file)
@@ -8,7 +8,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -35,8 +35,8 @@
 #define  SN_SAL_PRINT_ERROR                       0x02000012
 #define  SN_SAL_SET_ERROR_HANDLING_FEATURES       0x0200001a   // reentrant
 #define  SN_SAL_GET_FIT_COMPT                     0x0200001b   // reentrant
-#define  SN_SAL_GET_SN_INFO                        0x0200001c
 #define  SN_SAL_GET_SAPIC_INFO                     0x0200001d
+#define  SN_SAL_GET_SN_INFO                        0x0200001e
 #define  SN_SAL_CONSOLE_PUTC                       0x02000021
 #define  SN_SAL_CONSOLE_GETC                       0x02000022
 #define  SN_SAL_CONSOLE_PUTS                       0x02000023
@@ -64,6 +64,7 @@
 
 #define  SN_SAL_SYSCTL_IOBRICK_PCI_OP             0x02000042   // reentrant
 #define         SN_SAL_IROUTER_OP                         0x02000043
+#define  SN_SAL_SYSCTL_EVENT                       0x02000044
 #define  SN_SAL_IOIF_INTERRUPT                    0x0200004a
 #define  SN_SAL_HWPERF_OP                         0x02000050   // lock
 #define  SN_SAL_IOIF_ERROR_INTERRUPT              0x02000051
@@ -76,7 +77,8 @@
 #define  SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST     0x02000058
 
 #define SN_SAL_HUB_ERROR_INTERRUPT                0x02000060
-
+#define SN_SAL_BTE_RECOVER                        0x02000061
+#define SN_SAL_IOIF_GET_PCI_TOPOLOGY              0x02000062
 
 /*
  * Service-specific constants
 #define SAL_IROUTER_INTR_XMIT  SAL_CONSOLE_INTR_XMIT
 #define SAL_IROUTER_INTR_RECV  SAL_CONSOLE_INTR_RECV
 
+/*
+ * Error Handling Features
+ */
+#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV    0x1
+#define SAL_ERR_FEAT_LOG_SBES                  0x2
+#define SAL_ERR_FEAT_MFR_OVERRIDE              0x4
+#define SAL_ERR_FEAT_SBE_THRESHOLD             0xffff0000
 
 /*
  * SAL Error Codes
 #define SALRET_INVALID_ARG     (-2)
 #define SALRET_ERROR           (-3)
 
+#define SN_SAL_FAKE_PROM                          0x02009999
 
 /**
- * sn_sal_rev_major - get the major SGI SAL revision number
- *
- * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
- * This routine simply extracts the major value from the
- * @ia64_sal_systab structure constructed by ia64_sal_init().
- */
-static inline int
-sn_sal_rev_major(void)
+  * sn_sal_revision - get the SGI SAL revision number
+  *
+  * The SGI PROM stores its version in the sal_[ab]_rev_(major|minor).
+  * This routine simply extracts the major and minor values and
+  * presents them in a u32 format.
+  *
+  * For example, version 4.05 would be represented at 0x0405.
+  */
+static inline u32
+sn_sal_rev(void)
 {
        struct ia64_sal_systab *systab = efi.sal_systab;
 
-       return (int)systab->sal_b_rev_major;
-}
-
-/**
- * sn_sal_rev_minor - get the minor SGI SAL revision number
- *
- * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
- * This routine simply extracts the minor value from the
- * @ia64_sal_systab structure constructed by ia64_sal_init().
- */
-static inline int
-sn_sal_rev_minor(void)
-{
-       struct ia64_sal_systab *systab = efi.sal_systab;
-       
-       return (int)systab->sal_b_rev_minor;
+       return (u32)(systab->sal_b_rev_major << 8 | systab->sal_b_rev_minor);
 }
 
 /*
  * Specify the minimum PROM revsion required for this kernel.
  * Note that they're stored in hex format...
  */
-#define SN_SAL_MIN_MAJOR       0x4  /* SN2 kernels need at least PROM 4.0 */
-#define SN_SAL_MIN_MINOR       0x0
+#define SN_SAL_MIN_VERSION     0x0404
 
 /*
  * Returns the master console nasid, if the call fails, return an illegal
@@ -340,6 +336,25 @@ ia64_sn_plat_cpei_handler(void)
 }
 
 /*
+ * Set Error Handling Features
+ */
+static inline u64
+ia64_sn_plat_set_error_handling_features(void)
+{
+       struct ia64_sal_retval ret_stuff;
+
+       ret_stuff.status = 0;
+       ret_stuff.v0 = 0;
+       ret_stuff.v1 = 0;
+       ret_stuff.v2 = 0;
+       SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES,
+               (SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV | SAL_ERR_FEAT_LOG_SBES),
+               0, 0, 0, 0, 0, 0);
+
+       return ret_stuff.status;
+}
+
+/*
  * Checks for console input.
  */
 static inline u64
@@ -470,7 +485,7 @@ static inline u64
 ia64_sn_pod_mode(void)
 {
        struct ia64_sal_retval isrv;
-       SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
+       SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
        if (isrv.status)
                return 0;
        return isrv.v0;
@@ -555,7 +570,8 @@ static inline u64
 ia64_sn_partition_serial_get(void)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, 0, 0, 0, 0, 0, 0);
+       ia64_sal_oemcall_reentrant(&ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0,
+                                  0, 0, 0, 0, 0, 0);
        if (ret_stuff.status != 0)
            return 0;
        return ret_stuff.v0;
@@ -563,11 +579,10 @@ ia64_sn_partition_serial_get(void)
 
 static inline u64
 sn_partition_serial_number_val(void) {
-       if (sn_partition_serial_number) {
-               return(sn_partition_serial_number);
-       } else {
-               return(sn_partition_serial_number = ia64_sn_partition_serial_get());
+       if (unlikely(sn_partition_serial_number == 0)) {
+               sn_partition_serial_number = ia64_sn_partition_serial_get();
        }
+       return sn_partition_serial_number;
 }
 
 /*
@@ -578,8 +593,8 @@ static inline partid_t
 ia64_sn_sysctl_partition_get(nasid_t nasid)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
-                0, 0, 0, 0, 0, 0);
+       ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
+                               0, 0, 0, 0, 0, 0);
        if (ret_stuff.status != 0)
            return INVALID_PARTID;
        return ((partid_t)ret_stuff.v0);
@@ -593,11 +608,38 @@ extern partid_t sn_partid;
 
 static inline partid_t
 sn_local_partid(void) {
-       if (sn_partid < 0) {
-               return (sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id())));
-       } else {
-               return sn_partid;
+       if (unlikely(sn_partid < 0)) {
+               sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id()));
        }
+       return sn_partid;
+}
+
+/*
+ * Returns the physical address of the partition's reserved page through
+ * an iterative number of calls.
+ *
+ * On first call, 'cookie' and 'len' should be set to 0, and 'addr'
+ * set to the nasid of the partition whose reserved page's address is
+ * being sought.
+ * On subsequent calls, pass the values, that were passed back on the
+ * previous call.
+ *
+ * While the return status equals SALRET_MORE_PASSES, keep calling
+ * this function after first copying 'len' bytes starting at 'addr'
+ * into 'buf'. Once the return status equals SALRET_OK, 'addr' will
+ * be the physical address of the partition's reserved page. If the
+ * return status equals neither of these, an error as occurred.
+ */
+static inline s64
+sn_partition_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len)
+{
+       struct ia64_sal_retval rv;
+       ia64_sal_oemcall_reentrant(&rv, SN_SAL_GET_PARTITION_ADDR, *cookie,
+                                  *addr, buf, *len, 0, 0, 0);
+       *cookie = rv.v0;
+       *addr = rv.v1;
+       *len = rv.v2;
+       return rv.status;
 }
 
 /*
@@ -619,8 +661,8 @@ static inline int
 sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
-                0, 0, 0, 0);
+       ia64_sal_oemcall(&ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len,
+                        (u64)operation, 0, 0, 0, 0);
        return ret_stuff.status;
 }
 
@@ -644,8 +686,8 @@ sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
        } else {
                call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
        }
-       SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
-                0, 0, 0);
+       ia64_sal_oemcall(&ret_stuff, call, start_addr, end_addr, return_addr,
+                        (u64)1, 0, 0, 0);
        return ret_stuff.status;
 }
 
@@ -666,8 +708,8 @@ static inline int
 sn_change_coherence(u64 *new_domain, u64 *old_domain)
 {
        struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
-                0, 0, 0);
+       ia64_sal_oemcall(&ret_stuff, SN_SAL_COHERENCE, (u64)new_domain,
+                        (u64)old_domain, 0, 0, 0, 0, 0);
        return ret_stuff.status;
 }
 
@@ -686,8 +728,8 @@ sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
        cnodeid = nasid_to_cnodeid(get_node_number(paddr));
        // spin_lock(&NODEPDA(cnodeid)->bist_lock);
        local_irq_save(irq_flags);
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
-                perms, 0, 0, 0);
+       ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len,
+                               (u64)nasid_array, perms, 0, 0, 0);
        local_irq_restore(irq_flags);
        // spin_unlock(&NODEPDA(cnodeid)->bist_lock);
        return ret_stuff.status;
@@ -849,6 +891,19 @@ ia64_sn_irtr_intr_disable(nasid_t nasid, int subch, u64 intr)
        return (int) rv.v0;
 }
 
+/*
+ * Set up a node as the point of contact for system controller
+ * environmental event delivery.
+ */
+static inline int
+ia64_sn_sysctl_event_init(nasid_t nasid)
+{
+        struct ia64_sal_retval rv;
+        SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_EVENT, (u64) nasid,
+                          0, 0, 0, 0, 0, 0);
+        return (int) rv.v0;
+}
+
 /**
  * ia64_sn_get_fit_compt - read a FIT entry from the PROM header
  * @nasid: NASID of node to read
@@ -1012,4 +1067,37 @@ ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2,
        return (int) rv.status;
 }
 
+static inline int
+ia64_sn_ioif_get_pci_topology(u64 rack, u64 bay, u64 slot, u64 slab,
+                             u64 buf, u64 len)
+{
+       struct ia64_sal_retval rv;
+       SAL_CALL_NOLOCK(rv, SN_SAL_IOIF_GET_PCI_TOPOLOGY,
+               rack, bay, slot, slab, buf, len, 0);
+       return (int) rv.status;
+}
+
+/*
+ * BTE error recovery is implemented in SAL
+ */
+static inline int
+ia64_sn_bte_recovery(nasid_t nasid)
+{
+       struct ia64_sal_retval rv;
+
+       rv.status = 0;
+       SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, 0, 0, 0, 0, 0, 0, 0);
+       if (rv.status == SALRET_NOT_IMPLEMENTED)
+               return 0;
+       return (int) rv.status;
+}
+
+static inline int
+ia64_sn_is_fake_prom(void)
+{
+       struct ia64_sal_retval rv;
+       SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0);
+       return (rv.status == 0);
+}
+
 #endif /* _ASM_IA64_SN_SN_SAL_H */