Skip to content

Commit ffe2feb

Browse files
mike-travissuryasaimadhu
authored andcommitted
x86/platform/uv: Update MMIOH references based on new UV5 MMRs
Make modifications to the MMIOH mappings to accommodate changes for UV5. [ Fix W=1 build warnings. ] Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Mike Travis <mike.travis@hpe.com> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Steve Wahl <steve.wahl@hpe.com> Link: https://lkml.kernel.org/r/20201005203929.148656-8-mike.travis@hpe.com
1 parent 1e61f5a commit ffe2feb

1 file changed

Lines changed: 144 additions & 68 deletions

File tree

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 144 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ static void __init uv_tsc_check_sync(void)
226226
mark_tsc_unstable("UV BIOS");
227227
}
228228

229+
/* Selector for (4|4A|5) structs */
230+
#define uvxy_field(sname, field, undef) ( \
231+
is_uv(UV4A) ? sname.s4a.field : \
232+
is_uv(UV4) ? sname.s4.field : \
233+
is_uv(UV3) ? sname.s3.field : \
234+
undef)
235+
229236
/* [Copied from arch/x86/kernel/cpu/topology.c:detect_extended_topology()] */
230237

231238
#define SMT_LEVEL 0 /* Leaf 0xb SMT level */
@@ -878,6 +885,7 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
878885
}
879886

880887
enum map_type {map_wb, map_uc};
888+
static const char * const mt[] = { "WB", "UC" };
881889

882890
static __init void map_high(char *id, unsigned long base, int pshift, int bshift, int max_pnode, enum map_type map_type)
883891
{
@@ -889,11 +897,13 @@ static __init void map_high(char *id, unsigned long base, int pshift, int bshift
889897
pr_info("UV: Map %s_HI base address NULL\n", id);
890898
return;
891899
}
892-
pr_debug("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes);
893900
if (map_type == map_uc)
894901
init_extra_mapping_uc(paddr, bytes);
895902
else
896903
init_extra_mapping_wb(paddr, bytes);
904+
905+
pr_info("UV: Map %s_HI 0x%lx - 0x%lx %s (%d segments)\n",
906+
id, paddr, paddr + bytes, mt[map_type], max_pnode + 1);
897907
}
898908

899909
static __init void map_gru_high(int max_pnode)
@@ -927,52 +937,74 @@ static __init void map_mmr_high(int max_pnode)
927937
pr_info("UV: MMR disabled\n");
928938
}
929939

930-
/* UV3/4 have identical MMIOH overlay configs, UV4A is slightly different */
931-
static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode)
932-
{
933-
unsigned long overlay;
934-
unsigned long mmr;
935-
unsigned long base;
936-
unsigned long nasid_mask;
937-
unsigned long m_overlay;
938-
int i, n, shift, m_io, max_io;
939-
int nasid, lnasid, fi, li;
940-
char *id;
941-
942-
if (index == 0) {
943-
id = "MMIOH0";
944-
m_overlay = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0;
945-
overlay = uv_read_local_mmr(m_overlay);
946-
base = overlay & UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK;
940+
/* Arch specific ENUM cases */
941+
enum mmioh_arch {
942+
UV2_MMIOH = -1,
943+
UVY_MMIOH0, UVY_MMIOH1,
944+
UVX_MMIOH0, UVX_MMIOH1,
945+
};
946+
947+
/* Calculate and Map MMIOH Regions */
948+
static void __init calc_mmioh_map(enum mmioh_arch index,
949+
int min_pnode, int max_pnode,
950+
int shift, unsigned long base, int m_io, int n_io)
951+
{
952+
unsigned long mmr, nasid_mask;
953+
int nasid, min_nasid, max_nasid, lnasid, mapped;
954+
int i, fi, li, n, max_io;
955+
char id[8];
956+
957+
/* One (UV2) mapping */
958+
if (index == UV2_MMIOH) {
959+
strncpy(id, "MMIOH", sizeof(id));
960+
max_io = max_pnode;
961+
mapped = 0;
962+
goto map_exit;
963+
}
964+
965+
/* small and large MMIOH mappings */
966+
switch (index) {
967+
case UVY_MMIOH0:
968+
mmr = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0;
969+
nasid_mask = UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK;
970+
n = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG0_DEPTH;
971+
min_nasid = min_pnode;
972+
max_nasid = max_pnode;
973+
mapped = 1;
974+
break;
975+
case UVY_MMIOH1:
976+
mmr = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1;
977+
nasid_mask = UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK;
978+
n = UVH_RH10_GAM_MMIOH_REDIRECT_CONFIG1_DEPTH;
979+
min_nasid = min_pnode;
980+
max_nasid = max_pnode;
981+
mapped = 1;
982+
break;
983+
case UVX_MMIOH0:
947984
mmr = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0;
948-
m_io = (overlay & UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_MASK)
949-
>> UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_SHFT;
950-
shift = UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_M_IO_SHFT;
985+
nasid_mask = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_MASK;
951986
n = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG0_DEPTH;
952-
nasid_mask = UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG0_NASID_MASK;
953-
} else {
954-
id = "MMIOH1";
955-
m_overlay = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1;
956-
overlay = uv_read_local_mmr(m_overlay);
957-
base = overlay & UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK;
987+
min_nasid = min_pnode * 2;
988+
max_nasid = max_pnode * 2;
989+
mapped = 1;
990+
break;
991+
case UVX_MMIOH1:
958992
mmr = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1;
959-
m_io = (overlay & UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_MASK)
960-
>> UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_SHFT;
961-
shift = UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_M_IO_SHFT;
993+
nasid_mask = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_MASK;
962994
n = UVH_RH_GAM_MMIOH_REDIRECT_CONFIG1_DEPTH;
963-
nasid_mask = UV3H_RH_GAM_MMIOH_REDIRECT_CONFIG1_NASID_MASK;
964-
}
965-
pr_info("UV: %s overlay 0x%lx base:0x%lx m_io:%d\n", id, overlay, base, m_io);
966-
if (!(overlay & UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG0_ENABLE_MASK)) {
967-
pr_info("UV: %s disabled\n", id);
995+
min_nasid = min_pnode * 2;
996+
max_nasid = max_pnode * 2;
997+
mapped = 1;
998+
break;
999+
default:
1000+
pr_err("UV:%s:Invalid mapping type:%d\n", __func__, index);
9681001
return;
9691002
}
9701003

971-
/* Convert to NASID: */
972-
min_pnode *= 2;
973-
max_pnode *= 2;
974-
max_io = lnasid = fi = li = -1;
1004+
/* enum values chosen so (index mod 2) is MMIOH 0/1 (low/high) */
1005+
snprintf(id, sizeof(id), "MMIOH%d", index%2);
9751006

1007+
max_io = lnasid = fi = li = -1;
9761008
for (i = 0; i < n; i++) {
9771009
unsigned long m_redirect = mmr + i * 8;
9781010
unsigned long redirect = uv_read_local_mmr(m_redirect);
@@ -982,9 +1014,12 @@ static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode)
9821014
pr_info("UV: %s redirect base 0x%lx(@0x%lx) 0x%04x\n",
9831015
id, redirect, m_redirect, nasid);
9841016

985-
/* Invalid NASID: */
986-
if (nasid < min_pnode || max_pnode < nasid)
1017+
/* Invalid NASID check */
1018+
if (nasid < min_nasid || max_nasid < nasid) {
1019+
pr_err("UV:%s:Invalid NASID:%x (range:%x..%x)\n",
1020+
__func__, index, min_nasid, max_nasid);
9871021
nasid = -1;
1022+
}
9881023

9891024
if (nasid == lnasid) {
9901025
li = i;
@@ -1007,51 +1042,92 @@ static __init void map_mmioh_high_uv34(int index, int min_pnode, int max_pnode)
10071042
}
10081043
addr1 = (base << shift) + f * (1ULL << m_io);
10091044
addr2 = (base << shift) + (l + 1) * (1ULL << m_io);
1010-
pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n", id, fi, li, lnasid, addr1, addr2);
1045+
pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n",
1046+
id, fi, li, lnasid, addr1, addr2);
10111047
if (max_io < l)
10121048
max_io = l;
10131049
}
10141050
fi = li = i;
10151051
lnasid = nasid;
10161052
}
10171053

1018-
pr_info("UV: %s base:0x%lx shift:%d M_IO:%d MAX_IO:%d\n", id, base, shift, m_io, max_io);
1054+
map_exit:
1055+
pr_info("UV: %s base:0x%lx shift:%d m_io:%d max_io:%d max_pnode:0x%x\n",
1056+
id, base, shift, m_io, max_io, max_pnode);
10191057

1020-
if (max_io >= 0)
1058+
if (max_io >= 0 && !mapped)
10211059
map_high(id, base, shift, m_io, max_io, map_uc);
10221060
}
10231061

10241062
static __init void map_mmioh_high(int min_pnode, int max_pnode)
10251063
{
1026-
union uvh_rh_gam_mmioh_overlay_config_u mmioh;
1027-
unsigned long mmr, base;
1028-
int shift, enable, m_io, n_io;
1064+
/* UVY flavor */
1065+
if (UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0) {
1066+
union uvh_rh10_gam_mmioh_overlay_config0_u mmioh0;
1067+
union uvh_rh10_gam_mmioh_overlay_config1_u mmioh1;
1068+
1069+
mmioh0.v = uv_read_local_mmr(UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0);
1070+
if (unlikely(mmioh0.s.enable == 0))
1071+
pr_info("UV: MMIOH0 disabled\n");
1072+
else
1073+
calc_mmioh_map(UVY_MMIOH0, min_pnode, max_pnode,
1074+
UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT,
1075+
mmioh0.s.base, mmioh0.s.m_io, mmioh0.s.n_io);
10291076

1030-
if (is_uv3_hub() || is_uv4_hub()) {
1031-
/* Map both MMIOH regions: */
1032-
map_mmioh_high_uv34(0, min_pnode, max_pnode);
1033-
map_mmioh_high_uv34(1, min_pnode, max_pnode);
1077+
mmioh1.v = uv_read_local_mmr(UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1);
1078+
if (unlikely(mmioh1.s.enable == 0))
1079+
pr_info("UV: MMIOH1 disabled\n");
1080+
else
1081+
calc_mmioh_map(UVY_MMIOH1, min_pnode, max_pnode,
1082+
UVH_RH10_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT,
1083+
mmioh1.s.base, mmioh1.s.m_io, mmioh1.s.n_io);
10341084
return;
10351085
}
1086+
/* UVX flavor */
1087+
if (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0) {
1088+
union uvh_rh_gam_mmioh_overlay_config0_u mmioh0;
1089+
union uvh_rh_gam_mmioh_overlay_config1_u mmioh1;
1090+
1091+
mmioh0.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0);
1092+
if (unlikely(mmioh0.s.enable == 0))
1093+
pr_info("UV: MMIOH0 disabled\n");
1094+
else {
1095+
unsigned long base = uvxy_field(mmioh0, base, 0);
1096+
int m_io = uvxy_field(mmioh0, m_io, 0);
1097+
int n_io = uvxy_field(mmioh0, n_io, 0);
1098+
1099+
calc_mmioh_map(UVX_MMIOH0, min_pnode, max_pnode,
1100+
UVH_RH_GAM_MMIOH_OVERLAY_CONFIG0_BASE_SHFT,
1101+
base, m_io, n_io);
1102+
}
10361103

1037-
if (is_uv2_hub()) {
1038-
mmr = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG;
1039-
shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_SHFT;
1040-
mmioh.v = uv_read_local_mmr(mmr);
1041-
enable = !!mmioh.s2.enable;
1042-
base = mmioh.s2.base;
1043-
m_io = mmioh.s2.m_io;
1044-
n_io = mmioh.s2.n_io;
1045-
1046-
if (enable) {
1047-
max_pnode &= (1 << n_io) - 1;
1048-
pr_info(
1049-
"UV: base:0x%lx shift:%d N_IO:%d M_IO:%d max_pnode:0x%x\n",
1050-
base, shift, m_io, n_io, max_pnode);
1051-
map_high("MMIOH", base, shift, m_io, max_pnode, map_uc);
1052-
} else {
1053-
pr_info("UV: MMIOH disabled\n");
1104+
mmioh1.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1);
1105+
if (unlikely(mmioh1.s.enable == 0))
1106+
pr_info("UV: MMIOH1 disabled\n");
1107+
else {
1108+
unsigned long base = uvxy_field(mmioh1, base, 0);
1109+
int m_io = uvxy_field(mmioh1, m_io, 0);
1110+
int n_io = uvxy_field(mmioh1, n_io, 0);
1111+
1112+
calc_mmioh_map(UVX_MMIOH1, min_pnode, max_pnode,
1113+
UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_BASE_SHFT,
1114+
base, m_io, n_io);
10541115
}
1116+
return;
1117+
}
1118+
1119+
/* UV2 flavor */
1120+
if (UVH_RH_GAM_MMIOH_OVERLAY_CONFIG) {
1121+
union uvh_rh_gam_mmioh_overlay_config_u mmioh;
1122+
1123+
mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG);
1124+
if (unlikely(mmioh.s2.enable == 0))
1125+
pr_info("UV: MMIOH disabled\n");
1126+
else
1127+
calc_mmioh_map(UV2_MMIOH, min_pnode, max_pnode,
1128+
UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_BASE_SHFT,
1129+
mmioh.s2.base, mmioh.s2.m_io, mmioh.s2.n_io);
1130+
return;
10551131
}
10561132
}
10571133

0 commit comments

Comments
 (0)