The UV NMI MMR addresses and fields moved between UV4 and UV5
necessitating a rewrite of the UV NMI handler.  Adjust references
to accommodate those changes.

Signed-off-by: Mike Travis <mike.tra...@hpe.com>
Reviewed-by: Dimitri Sivanich <dimitri.sivan...@hpe.com>
Reviewed-by: Steve Wahl <steve.w...@hpe.com>
---
 arch/x86/include/asm/uv/uv_hub.h | 13 -------
 arch/x86/platform/uv/uv_nmi.c    | 64 +++++++++++++++++++++++++++-----
 2 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index 07079b59824d..610bda21a8d9 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -734,19 +734,6 @@ extern void uv_nmi_setup_hubless(void);
 #define UVH_NMI_MMR_SHIFT      63
 #define UVH_NMI_MMR_TYPE       "SCRATCH5"
 
-/* Newer SMM NMI handler, not present in all systems */
-#define UVH_NMI_MMRX           UVH_EVENT_OCCURRED0
-#define UVH_NMI_MMRX_CLEAR     UVH_EVENT_OCCURRED0_ALIAS
-#define UVH_NMI_MMRX_SHIFT     UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT
-#define UVH_NMI_MMRX_TYPE      "EXTIO_INT0"
-
-/* Non-zero indicates newer SMM NMI handler present */
-#define UVH_NMI_MMRX_SUPPORTED UVH_EXTIO_INT0_BROADCAST
-
-/* Indicates to BIOS that we want to use the newer SMM NMI handler */
-#define UVH_NMI_MMRX_REQ       UVH_BIOS_KERNEL_MMR_ALIAS_2
-#define UVH_NMI_MMRX_REQ_SHIFT 62
-
 struct uv_hub_nmi_s {
        raw_spinlock_t  nmi_lock;
        atomic_t        in_nmi;         /* flag this node in UV NMI IRQ */
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index 9d08ff5a755e..eac26feb0461 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c
@@ -2,8 +2,8 @@
 /*
  * SGI NMI support routines
  *
- *  Copyright (c) 2009-2013 Silicon Graphics, Inc.  All Rights Reserved.
- *  Copyright (c) Mike Travis
+ * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) Mike Travis
  */
 
 #include <linux/cpu.h>
@@ -54,6 +54,20 @@ static struct uv_hub_nmi_s **uv_hub_nmi_list;
 
 DEFINE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi);
 
+/* Newer SMM NMI handler, not present in all systems */
+static unsigned long uvh_nmi_mmrx;             /* UVH_EVENT_OCCURRED0/1 */
+static unsigned long uvh_nmi_mmrx_clear;       /* UVH_EVENT_OCCURRED0/1_ALIAS 
*/
+static int uvh_nmi_mmrx_shift;                 /* 
UVH_EVENT_OCCURRED0/1_EXTIO_INT0_SHFT */
+static int uvh_nmi_mmrx_mask;                  /* 
UVH_EVENT_OCCURRED0/1_EXTIO_INT0_MASK */
+static char *uvh_nmi_mmrx_type;                        /* "EXTIO_INT0" */
+
+/* Non-zero indicates newer SMM NMI handler present */
+static unsigned long uvh_nmi_mmrx_supported;   /* UVH_EXTIO_INT0_BROADCAST */
+
+/* Indicates to BIOS that we want to use the newer SMM NMI handler */
+static unsigned long uvh_nmi_mmrx_req;         /* UVH_BIOS_KERNEL_MMR_ALIAS_2 
*/
+static int uvh_nmi_mmrx_req_shift;             /* 62 */
+
 /* UV hubless values */
 #define NMI_CONTROL_PORT       0x70
 #define NMI_DUMMY_PORT         0x71
@@ -227,13 +241,43 @@ static inline bool uv_nmi_action_is(const char *action)
 /* Setup which NMI support is present in system */
 static void uv_nmi_setup_mmrs(void)
 {
-       if (uv_read_local_mmr(UVH_NMI_MMRX_SUPPORTED)) {
-               uv_write_local_mmr(UVH_NMI_MMRX_REQ,
-                                       1UL << UVH_NMI_MMRX_REQ_SHIFT);
-               nmi_mmr = UVH_NMI_MMRX;
-               nmi_mmr_clear = UVH_NMI_MMRX_CLEAR;
-               nmi_mmr_pending = 1UL << UVH_NMI_MMRX_SHIFT;
-               pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMRX_TYPE);
+       /* First determine arch specific MMRs to handshake with BIOS */
+       if (UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK) {
+               uvh_nmi_mmrx = UVH_EVENT_OCCURRED0;
+               uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED0_ALIAS;
+               uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT;
+               uvh_nmi_mmrx_mask = UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK;
+               uvh_nmi_mmrx_type = "OCRD0-EXTIO_INT0";
+
+               uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST;
+               uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2;
+               uvh_nmi_mmrx_req_shift = 62;
+
+       } else if (UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK) {
+               uvh_nmi_mmrx = UVH_EVENT_OCCURRED1;
+               uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED1_ALIAS;
+               uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED1_EXTIO_INT0_SHFT;
+               uvh_nmi_mmrx_mask = UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK;
+               uvh_nmi_mmrx_type = "OCRD1-EXTIO_INT0";
+
+               uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST;
+               uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2;
+               uvh_nmi_mmrx_req_shift = 62;
+
+       } else {
+               pr_err("UV:%s:cannot find EVENT_OCCURRED*_EXTIO_INT0\n",
+                       __func__);
+               return;
+       }
+
+       /* Then find out if new NMI is supported */
+       if (likely(uv_read_local_mmr(uvh_nmi_mmrx_supported))) {
+               uv_write_local_mmr(uvh_nmi_mmrx_req,
+                                       1UL << uvh_nmi_mmrx_req_shift);
+               nmi_mmr = uvh_nmi_mmrx;
+               nmi_mmr_clear = uvh_nmi_mmrx_clear;
+               nmi_mmr_pending = 1UL << uvh_nmi_mmrx_shift;
+               pr_info("UV: SMI NMI support: %s\n", uvh_nmi_mmrx_type);
        } else {
                nmi_mmr = UVH_NMI_MMR;
                nmi_mmr_clear = UVH_NMI_MMR_CLEAR;
@@ -1049,5 +1093,5 @@ void __init uv_nmi_setup_hubless(void)
        /* Ensure NMI enabled in Processor Interface Reg: */
        uv_reassert_nmi();
        uv_register_nmi_notifier();
-       pr_info("UV: Hubless NMI enabled\n");
+       pr_info("UV: PCH NMI enabled\n");
 }
-- 
2.21.0

Reply via email to