|
2 | 2 | /* |
3 | 3 | * SGI NMI support routines |
4 | 4 | * |
5 | | - * Copyright (c) 2009-2013 Silicon Graphics, Inc. All Rights Reserved. |
6 | | - * Copyright (c) Mike Travis |
| 5 | + * Copyright (C) 2007-2017 Silicon Graphics, Inc. All rights reserved. |
| 6 | + * Copyright (c) Mike Travis |
7 | 7 | */ |
8 | 8 |
|
9 | 9 | #include <linux/cpu.h> |
@@ -54,6 +54,20 @@ static struct uv_hub_nmi_s **uv_hub_nmi_list; |
54 | 54 |
|
55 | 55 | DEFINE_PER_CPU(struct uv_cpu_nmi_s, uv_cpu_nmi); |
56 | 56 |
|
| 57 | +/* Newer SMM NMI handler, not present in all systems */ |
| 58 | +static unsigned long uvh_nmi_mmrx; /* UVH_EVENT_OCCURRED0/1 */ |
| 59 | +static unsigned long uvh_nmi_mmrx_clear; /* UVH_EVENT_OCCURRED0/1_ALIAS */ |
| 60 | +static int uvh_nmi_mmrx_shift; /* UVH_EVENT_OCCURRED0/1_EXTIO_INT0_SHFT */ |
| 61 | +static int uvh_nmi_mmrx_mask; /* UVH_EVENT_OCCURRED0/1_EXTIO_INT0_MASK */ |
| 62 | +static char *uvh_nmi_mmrx_type; /* "EXTIO_INT0" */ |
| 63 | + |
| 64 | +/* Non-zero indicates newer SMM NMI handler present */ |
| 65 | +static unsigned long uvh_nmi_mmrx_supported; /* UVH_EXTIO_INT0_BROADCAST */ |
| 66 | + |
| 67 | +/* Indicates to BIOS that we want to use the newer SMM NMI handler */ |
| 68 | +static unsigned long uvh_nmi_mmrx_req; /* UVH_BIOS_KERNEL_MMR_ALIAS_2 */ |
| 69 | +static int uvh_nmi_mmrx_req_shift; /* 62 */ |
| 70 | + |
57 | 71 | /* UV hubless values */ |
58 | 72 | #define NMI_CONTROL_PORT 0x70 |
59 | 73 | #define NMI_DUMMY_PORT 0x71 |
@@ -227,13 +241,43 @@ static inline bool uv_nmi_action_is(const char *action) |
227 | 241 | /* Setup which NMI support is present in system */ |
228 | 242 | static void uv_nmi_setup_mmrs(void) |
229 | 243 | { |
230 | | - if (uv_read_local_mmr(UVH_NMI_MMRX_SUPPORTED)) { |
231 | | - uv_write_local_mmr(UVH_NMI_MMRX_REQ, |
232 | | - 1UL << UVH_NMI_MMRX_REQ_SHIFT); |
233 | | - nmi_mmr = UVH_NMI_MMRX; |
234 | | - nmi_mmr_clear = UVH_NMI_MMRX_CLEAR; |
235 | | - nmi_mmr_pending = 1UL << UVH_NMI_MMRX_SHIFT; |
236 | | - pr_info("UV: SMI NMI support: %s\n", UVH_NMI_MMRX_TYPE); |
| 244 | + /* First determine arch specific MMRs to handshake with BIOS */ |
| 245 | + if (UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK) { |
| 246 | + uvh_nmi_mmrx = UVH_EVENT_OCCURRED0; |
| 247 | + uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED0_ALIAS; |
| 248 | + uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT; |
| 249 | + uvh_nmi_mmrx_mask = UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK; |
| 250 | + uvh_nmi_mmrx_type = "OCRD0-EXTIO_INT0"; |
| 251 | + |
| 252 | + uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST; |
| 253 | + uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2; |
| 254 | + uvh_nmi_mmrx_req_shift = 62; |
| 255 | + |
| 256 | + } else if (UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK) { |
| 257 | + uvh_nmi_mmrx = UVH_EVENT_OCCURRED1; |
| 258 | + uvh_nmi_mmrx_clear = UVH_EVENT_OCCURRED1_ALIAS; |
| 259 | + uvh_nmi_mmrx_shift = UVH_EVENT_OCCURRED1_EXTIO_INT0_SHFT; |
| 260 | + uvh_nmi_mmrx_mask = UVH_EVENT_OCCURRED1_EXTIO_INT0_MASK; |
| 261 | + uvh_nmi_mmrx_type = "OCRD1-EXTIO_INT0"; |
| 262 | + |
| 263 | + uvh_nmi_mmrx_supported = UVH_EXTIO_INT0_BROADCAST; |
| 264 | + uvh_nmi_mmrx_req = UVH_BIOS_KERNEL_MMR_ALIAS_2; |
| 265 | + uvh_nmi_mmrx_req_shift = 62; |
| 266 | + |
| 267 | + } else { |
| 268 | + pr_err("UV:%s:cannot find EVENT_OCCURRED*_EXTIO_INT0\n", |
| 269 | + __func__); |
| 270 | + return; |
| 271 | + } |
| 272 | + |
| 273 | + /* Then find out if new NMI is supported */ |
| 274 | + if (likely(uv_read_local_mmr(uvh_nmi_mmrx_supported))) { |
| 275 | + uv_write_local_mmr(uvh_nmi_mmrx_req, |
| 276 | + 1UL << uvh_nmi_mmrx_req_shift); |
| 277 | + nmi_mmr = uvh_nmi_mmrx; |
| 278 | + nmi_mmr_clear = uvh_nmi_mmrx_clear; |
| 279 | + nmi_mmr_pending = 1UL << uvh_nmi_mmrx_shift; |
| 280 | + pr_info("UV: SMI NMI support: %s\n", uvh_nmi_mmrx_type); |
237 | 281 | } else { |
238 | 282 | nmi_mmr = UVH_NMI_MMR; |
239 | 283 | nmi_mmr_clear = UVH_NMI_MMR_CLEAR; |
@@ -1049,5 +1093,5 @@ void __init uv_nmi_setup_hubless(void) |
1049 | 1093 | /* Ensure NMI enabled in Processor Interface Reg: */ |
1050 | 1094 | uv_reassert_nmi(); |
1051 | 1095 | uv_register_nmi_notifier(); |
1052 | | - pr_info("UV: Hubless NMI enabled\n"); |
| 1096 | + pr_info("UV: PCH NMI enabled\n"); |
1053 | 1097 | } |
0 commit comments