Skip to content

Commit 6c77944

Browse files
mike-travissuryasaimadhu
authored andcommitted
x86/platform/uv: Add UV5 direct references
Add new references to UV5 (and UVY class) system MMR addresses and fields primarily caused by the expansion from 46 to 52 bits of physical memory address. Signed-off-by: Mike Travis <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Dimitri Sivanich <[email protected]> Reviewed-by: Steve Wahl <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 647128f commit 6c77944

File tree

2 files changed

+103
-43
lines changed

2 files changed

+103
-43
lines changed

arch/x86/include/asm/uv/uv_hub.h

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct uv_hub_info_s {
160160
unsigned char gr_table_len;
161161
unsigned char apic_pnode_shift;
162162
unsigned char gpa_shift;
163+
unsigned char nasid_shift;
163164
unsigned char m_shift;
164165
unsigned char n_lshift;
165166
unsigned int gnode_extra;
@@ -226,14 +227,15 @@ static inline __init void uv_hub_type_set(int uvmask)
226227
#define UV3_HUB_REVISION_BASE 5
227228
#define UV4_HUB_REVISION_BASE 7
228229
#define UV4A_HUB_REVISION_BASE 8 /* UV4 (fixed) rev 2 */
230+
#define UV5_HUB_REVISION_BASE 9
229231

230232
static inline int is_uv(int uvmask) { return uv_hub_type() & uvmask; }
231233
static inline int is_uv1_hub(void) { return 0; }
232234
static inline int is_uv2_hub(void) { return is_uv(UV2); }
233235
static inline int is_uv3_hub(void) { return is_uv(UV3); }
234236
static inline int is_uv4a_hub(void) { return is_uv(UV4A); }
235237
static inline int is_uv4_hub(void) { return is_uv(UV4); }
236-
static inline int is_uv5_hub(void) { return 0; }
238+
static inline int is_uv5_hub(void) { return is_uv(UV5); }
237239

238240
/*
239241
* UV4A is a revision of UV4. So on UV4A, both is_uv4_hub() and
@@ -246,7 +248,7 @@ static inline int is_uv5_hub(void) { return 0; }
246248
static inline int is_uvx_hub(void) { return is_uv(UVX); }
247249

248250
/* UVY class: UV5,..? */
249-
static inline int is_uvy_hub(void) { return 0; }
251+
static inline int is_uvy_hub(void) { return is_uv(UVY); }
250252

251253
/* Any UV Hubbed System */
252254
static inline int is_uv_hub(void) { return is_uv(UV_ANY); }
@@ -271,9 +273,11 @@ union uvh_apicid {
271273
* g - GNODE (full 15-bit global nasid, right shifted 1)
272274
* p - PNODE (local part of nsids, right shifted 1)
273275
*/
274-
#define UV_NASID_TO_PNODE(n) (((n) >> 1) & uv_hub_info->pnode_mask)
276+
#define UV_NASID_TO_PNODE(n) \
277+
(((n) >> uv_hub_info->nasid_shift) & uv_hub_info->pnode_mask)
275278
#define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra)
276-
#define UV_PNODE_TO_NASID(p) (UV_PNODE_TO_GNODE(p) << 1)
279+
#define UV_PNODE_TO_NASID(p) \
280+
(UV_PNODE_TO_GNODE(p) << uv_hub_info->nasid_shift)
277281

278282
#define UV2_LOCAL_MMR_BASE 0xfa000000UL
279283
#define UV2_GLOBAL_MMR32_BASE 0xfc000000UL
@@ -290,25 +294,38 @@ union uvh_apicid {
290294
#define UV4_LOCAL_MMR_SIZE (32UL * 1024 * 1024)
291295
#define UV4_GLOBAL_MMR32_SIZE 0
292296

297+
#define UV5_LOCAL_MMR_BASE 0xfa000000UL
298+
#define UV5_GLOBAL_MMR32_BASE 0
299+
#define UV5_LOCAL_MMR_SIZE (32UL * 1024 * 1024)
300+
#define UV5_GLOBAL_MMR32_SIZE 0
301+
293302
#define UV_LOCAL_MMR_BASE ( \
294-
is_uv2_hub() ? UV2_LOCAL_MMR_BASE : \
295-
is_uv3_hub() ? UV3_LOCAL_MMR_BASE : \
296-
/*is_uv4_hub*/ UV4_LOCAL_MMR_BASE)
303+
is_uv(UV2) ? UV2_LOCAL_MMR_BASE : \
304+
is_uv(UV3) ? UV3_LOCAL_MMR_BASE : \
305+
is_uv(UV4) ? UV4_LOCAL_MMR_BASE : \
306+
is_uv(UV5) ? UV5_LOCAL_MMR_BASE : \
307+
0)
297308

298309
#define UV_GLOBAL_MMR32_BASE ( \
299-
is_uv2_hub() ? UV2_GLOBAL_MMR32_BASE : \
300-
is_uv3_hub() ? UV3_GLOBAL_MMR32_BASE : \
301-
/*is_uv4_hub*/ UV4_GLOBAL_MMR32_BASE)
310+
is_uv(UV2) ? UV2_GLOBAL_MMR32_BASE : \
311+
is_uv(UV3) ? UV3_GLOBAL_MMR32_BASE : \
312+
is_uv(UV4) ? UV4_GLOBAL_MMR32_BASE : \
313+
is_uv(UV5) ? UV5_GLOBAL_MMR32_BASE : \
314+
0)
302315

303316
#define UV_LOCAL_MMR_SIZE ( \
304-
is_uv2_hub() ? UV2_LOCAL_MMR_SIZE : \
305-
is_uv3_hub() ? UV3_LOCAL_MMR_SIZE : \
306-
/*is_uv4_hub*/ UV4_LOCAL_MMR_SIZE)
317+
is_uv(UV2) ? UV2_LOCAL_MMR_SIZE : \
318+
is_uv(UV3) ? UV3_LOCAL_MMR_SIZE : \
319+
is_uv(UV4) ? UV4_LOCAL_MMR_SIZE : \
320+
is_uv(UV5) ? UV5_LOCAL_MMR_SIZE : \
321+
0)
307322

308323
#define UV_GLOBAL_MMR32_SIZE ( \
309-
is_uv2_hub() ? UV2_GLOBAL_MMR32_SIZE : \
310-
is_uv3_hub() ? UV3_GLOBAL_MMR32_SIZE : \
311-
/*is_uv4_hub*/ UV4_GLOBAL_MMR32_SIZE)
324+
is_uv(UV2) ? UV2_GLOBAL_MMR32_SIZE : \
325+
is_uv(UV3) ? UV3_GLOBAL_MMR32_SIZE : \
326+
is_uv(UV4) ? UV4_GLOBAL_MMR32_SIZE : \
327+
is_uv(UV5) ? UV5_GLOBAL_MMR32_SIZE : \
328+
0)
312329

313330
#define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base)
314331

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ static int uv_node_id;
3535
static u8 oem_id[ACPI_OEM_ID_SIZE + 1];
3636
static u8 oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
3737

38-
/* Information derived from CPUID: */
38+
/* Information derived from CPUID and some UV MMRs */
3939
static struct {
4040
unsigned int apicid_shift;
4141
unsigned int apicid_mask;
4242
unsigned int socketid_shift; /* aka pnode_shift for UV2/3 */
4343
unsigned int pnode_mask;
44+
unsigned int nasid_shift;
4445
unsigned int gpa_shift;
4546
unsigned int gnode_shift;
47+
unsigned int m_skt;
48+
unsigned int n_skt;
4649
} uv_cpuid;
4750

4851
static int uv_min_hub_revision_id;
@@ -88,20 +91,43 @@ static bool uv_is_untracked_pat_range(u64 start, u64 end)
8891

8992
static void __init early_get_pnodeid(void)
9093
{
91-
union uvh_rh_gam_addr_map_config_u m_n_config;
9294
int pnode;
9395

96+
uv_cpuid.m_skt = 0;
97+
if (UVH_RH10_GAM_ADDR_MAP_CONFIG) {
98+
union uvh_rh10_gam_addr_map_config_u m_n_config;
99+
100+
m_n_config.v = uv_early_read_mmr(UVH_RH10_GAM_ADDR_MAP_CONFIG);
101+
uv_cpuid.n_skt = m_n_config.s.n_skt;
102+
uv_cpuid.nasid_shift = 0;
103+
} else if (UVH_RH_GAM_ADDR_MAP_CONFIG) {
104+
union uvh_rh_gam_addr_map_config_u m_n_config;
105+
94106
m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_ADDR_MAP_CONFIG);
107+
uv_cpuid.n_skt = m_n_config.s.n_skt;
108+
if (is_uv(UV3))
109+
uv_cpuid.m_skt = m_n_config.s3.m_skt;
110+
if (is_uv(UV2))
111+
uv_cpuid.m_skt = m_n_config.s2.m_skt;
112+
uv_cpuid.nasid_shift = 1;
113+
} else {
114+
unsigned long GAM_ADDR_MAP_CONFIG = 0;
115+
116+
WARN(GAM_ADDR_MAP_CONFIG == 0,
117+
"UV: WARN: GAM_ADDR_MAP_CONFIG is not available\n");
118+
uv_cpuid.n_skt = 0;
119+
uv_cpuid.nasid_shift = 0;
120+
}
95121

96-
if (is_uv4_hub())
122+
if (is_uv(UV4|UVY))
97123
uv_cpuid.gnode_shift = 2; /* min partition is 4 sockets */
98124

99-
uv_cpuid.pnode_mask = (1 << m_n_config.s.n_skt) - 1;
100-
pnode = (uv_node_id >> 1) & uv_cpuid.pnode_mask;
125+
uv_cpuid.pnode_mask = (1 << uv_cpuid.n_skt) - 1;
126+
pnode = (uv_node_id >> uv_cpuid.nasid_shift) & uv_cpuid.pnode_mask;
101127
uv_cpuid.gpa_shift = 46; /* Default unless changed */
102128

103129
pr_info("UV: n_skt:%d pnmsk:%x pn:%x\n",
104-
m_n_config.s.n_skt, uv_cpuid.pnode_mask, pnode);
130+
uv_cpuid.n_skt, uv_cpuid.pnode_mask, pnode);
105131
}
106132

107133
/* Running on a UV Hubbed system, determine which UV Hub Type it is */
@@ -121,6 +147,12 @@ static int __init early_set_hub_type(void)
121147

122148
switch (node_id.s.part_number) {
123149

150+
case UV5_HUB_PART_NUMBER:
151+
uv_min_hub_revision_id = node_id.s.revision
152+
+ UV5_HUB_REVISION_BASE;
153+
uv_hub_type_set(UV5);
154+
break;
155+
124156
/* UV4/4A only have a revision difference */
125157
case UV4_HUB_PART_NUMBER:
126158
uv_min_hub_revision_id = node_id.s.revision
@@ -282,11 +314,17 @@ static int __init uv_set_system_type(char *_oem_id)
282314

283315
/* Set hubbed type if true */
284316
uv_hub_info->hub_revision =
317+
!strncmp(oem_id, "SGI5", 4) ? UV5_HUB_REVISION_BASE :
285318
!strncmp(oem_id, "SGI4", 4) ? UV4_HUB_REVISION_BASE :
286319
!strncmp(oem_id, "SGI3", 4) ? UV3_HUB_REVISION_BASE :
287320
!strcmp(oem_id, "SGI2") ? UV2_HUB_REVISION_BASE : 0;
288321

289322
switch (uv_hub_info->hub_revision) {
323+
case UV5_HUB_REVISION_BASE:
324+
uv_hubbed_system = 0x21;
325+
uv_hub_type_set(UV5);
326+
break;
327+
290328
case UV4_HUB_REVISION_BASE:
291329
uv_hubbed_system = 0x11;
292330
uv_hub_type_set(UV4);
@@ -923,7 +961,8 @@ static __init void map_mmioh_high(int min_pnode, int max_pnode)
923961

924962
if (enable) {
925963
max_pnode &= (1 << n_io) - 1;
926-
pr_info("UV: base:0x%lx shift:%d N_IO:%d M_IO:%d max_pnode:0x%x\n",
964+
pr_info(
965+
"UV: base:0x%lx shift:%d N_IO:%d M_IO:%d max_pnode:0x%x\n",
927966
base, shift, m_io, n_io, max_pnode);
928967
map_high("MMIOH", base, shift, m_io, max_pnode, map_uc);
929968
} else {
@@ -934,8 +973,11 @@ static __init void map_mmioh_high(int min_pnode, int max_pnode)
934973

935974
static __init void map_low_mmrs(void)
936975
{
937-
init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE);
938-
init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE);
976+
if (UV_GLOBAL_MMR32_BASE)
977+
init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE);
978+
979+
if (UV_LOCAL_MMR_BASE)
980+
init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE);
939981
}
940982

941983
static __init void uv_rtc_init(void)
@@ -994,26 +1036,22 @@ struct mn {
9941036
unsigned char n_lshift;
9951037
};
9961038

1039+
/* Initialize caller's MN struct and fill in values */
9971040
static void get_mn(struct mn *mnp)
9981041
{
999-
union uvh_rh_gam_addr_map_config_u m_n_config;
1000-
union uvyh_gr0_gam_gr_config_u m_gr_config;
1001-
1002-
/* Make sure the whole structure is well initialized: */
10031042
memset(mnp, 0, sizeof(*mnp));
1004-
1005-
m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_ADDR_MAP_CONFIG);
1006-
mnp->n_val = m_n_config.s.n_skt;
1007-
1008-
if (is_uv4_hub()) {
1043+
mnp->n_val = uv_cpuid.n_skt;
1044+
if (is_uv(UV4|UVY)) {
10091045
mnp->m_val = 0;
10101046
mnp->n_lshift = 0;
10111047
} else if (is_uv3_hub()) {
1012-
mnp->m_val = m_n_config.s3.m_skt;
1048+
union uvyh_gr0_gam_gr_config_u m_gr_config;
1049+
1050+
mnp->m_val = uv_cpuid.m_skt;
10131051
m_gr_config.v = uv_read_local_mmr(UVH_GR0_GAM_GR_CONFIG);
10141052
mnp->n_lshift = m_gr_config.s3.m_skt;
10151053
} else if (is_uv2_hub()) {
1016-
mnp->m_val = m_n_config.s2.m_skt;
1054+
mnp->m_val = uv_cpuid.m_skt;
10171055
mnp->n_lshift = mnp->m_val == 40 ? 40 : 39;
10181056
}
10191057
mnp->m_shift = mnp->m_val ? 64 - mnp->m_val : 0;
@@ -1035,6 +1073,7 @@ static void __init uv_init_hub_info(struct uv_hub_info_s *hi)
10351073
hi->hub_revision = uv_hub_info->hub_revision;
10361074
hi->hub_type = uv_hub_info->hub_type;
10371075
hi->pnode_mask = uv_cpuid.pnode_mask;
1076+
hi->nasid_shift = uv_cpuid.nasid_shift;
10381077
hi->min_pnode = _min_pnode;
10391078
hi->min_socket = _min_socket;
10401079
hi->pnode_to_socket = _pnode_to_socket;
@@ -1146,16 +1185,19 @@ static int __init decode_uv_systab(void)
11461185
struct uv_systab *st;
11471186
int i;
11481187

1149-
/* If system is uv3 or lower, there is no extended UVsystab */
1150-
if (is_uv_hubbed(0xfffffe) < uv(4) && is_uv_hubless(0xfffffe) < uv(4))
1151-
return 0; /* No extended UVsystab required */
1152-
1188+
/* Get mapped UVsystab pointer */
11531189
st = uv_systab;
1190+
1191+
/* If UVsystab is version 1, there is no extended UVsystab */
1192+
if (st && st->revision == UV_SYSTAB_VERSION_1)
1193+
return 0;
1194+
11541195
if ((!st) || (st->revision < UV_SYSTAB_VERSION_UV4_LATEST)) {
11551196
int rev = st ? st->revision : 0;
11561197

1157-
pr_err("UV: BIOS UVsystab version(%x) mismatch, expecting(%x)\n", rev, UV_SYSTAB_VERSION_UV4_LATEST);
1158-
pr_err("UV: Cannot support UV operations, switching to generic PC\n");
1198+
pr_err("UV: BIOS UVsystab mismatch, (%x < %x)\n",
1199+
rev, UV_SYSTAB_VERSION_UV4_LATEST);
1200+
pr_err("UV: Does not support UV, switch to non-UV x86_64\n");
11591201
uv_system_type = UV_NONE;
11601202

11611203
return -EINVAL;
@@ -1393,7 +1435,8 @@ static void __init uv_system_init_hub(void)
13931435
struct uv_hub_info_s hub_info = {0};
13941436
int bytes, cpu, nodeid;
13951437
unsigned short min_pnode = 9999, max_pnode = 0;
1396-
char *hub = is_uv4_hub() ? "UV400" :
1438+
char *hub = is_uv5_hub() ? "UV500" :
1439+
is_uv4_hub() ? "UV400" :
13971440
is_uv3_hub() ? "UV300" :
13981441
is_uv2_hub() ? "UV2000/3000" : NULL;
13991442

0 commit comments

Comments
 (0)