@@ -35,14 +35,17 @@ static int uv_node_id;
35
35
static u8 oem_id [ACPI_OEM_ID_SIZE + 1 ];
36
36
static u8 oem_table_id [ACPI_OEM_TABLE_ID_SIZE + 1 ];
37
37
38
- /* Information derived from CPUID: */
38
+ /* Information derived from CPUID and some UV MMRs */
39
39
static struct {
40
40
unsigned int apicid_shift ;
41
41
unsigned int apicid_mask ;
42
42
unsigned int socketid_shift ; /* aka pnode_shift for UV2/3 */
43
43
unsigned int pnode_mask ;
44
+ unsigned int nasid_shift ;
44
45
unsigned int gpa_shift ;
45
46
unsigned int gnode_shift ;
47
+ unsigned int m_skt ;
48
+ unsigned int n_skt ;
46
49
} uv_cpuid ;
47
50
48
51
static int uv_min_hub_revision_id ;
@@ -88,20 +91,43 @@ static bool uv_is_untracked_pat_range(u64 start, u64 end)
88
91
89
92
static void __init early_get_pnodeid (void )
90
93
{
91
- union uvh_rh_gam_addr_map_config_u m_n_config ;
92
94
int pnode ;
93
95
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
+
94
106
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
+ }
95
121
96
- if (is_uv4_hub ( ))
122
+ if (is_uv ( UV4 | UVY ))
97
123
uv_cpuid .gnode_shift = 2 ; /* min partition is 4 sockets */
98
124
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 ;
101
127
uv_cpuid .gpa_shift = 46 ; /* Default unless changed */
102
128
103
129
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 );
105
131
}
106
132
107
133
/* 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)
121
147
122
148
switch (node_id .s .part_number ) {
123
149
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
+
124
156
/* UV4/4A only have a revision difference */
125
157
case UV4_HUB_PART_NUMBER :
126
158
uv_min_hub_revision_id = node_id .s .revision
@@ -282,11 +314,17 @@ static int __init uv_set_system_type(char *_oem_id)
282
314
283
315
/* Set hubbed type if true */
284
316
uv_hub_info -> hub_revision =
317
+ !strncmp (oem_id , "SGI5" , 4 ) ? UV5_HUB_REVISION_BASE :
285
318
!strncmp (oem_id , "SGI4" , 4 ) ? UV4_HUB_REVISION_BASE :
286
319
!strncmp (oem_id , "SGI3" , 4 ) ? UV3_HUB_REVISION_BASE :
287
320
!strcmp (oem_id , "SGI2" ) ? UV2_HUB_REVISION_BASE : 0 ;
288
321
289
322
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
+
290
328
case UV4_HUB_REVISION_BASE :
291
329
uv_hubbed_system = 0x11 ;
292
330
uv_hub_type_set (UV4 );
@@ -923,7 +961,8 @@ static __init void map_mmioh_high(int min_pnode, int max_pnode)
923
961
924
962
if (enable ) {
925
963
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" ,
927
966
base , shift , m_io , n_io , max_pnode );
928
967
map_high ("MMIOH" , base , shift , m_io , max_pnode , map_uc );
929
968
} else {
@@ -934,8 +973,11 @@ static __init void map_mmioh_high(int min_pnode, int max_pnode)
934
973
935
974
static __init void map_low_mmrs (void )
936
975
{
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 );
939
981
}
940
982
941
983
static __init void uv_rtc_init (void )
@@ -994,26 +1036,22 @@ struct mn {
994
1036
unsigned char n_lshift ;
995
1037
};
996
1038
1039
+ /* Initialize caller's MN struct and fill in values */
997
1040
static void get_mn (struct mn * mnp )
998
1041
{
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: */
1003
1042
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 )) {
1009
1045
mnp -> m_val = 0 ;
1010
1046
mnp -> n_lshift = 0 ;
1011
1047
} 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 ;
1013
1051
m_gr_config .v = uv_read_local_mmr (UVH_GR0_GAM_GR_CONFIG );
1014
1052
mnp -> n_lshift = m_gr_config .s3 .m_skt ;
1015
1053
} else if (is_uv2_hub ()) {
1016
- mnp -> m_val = m_n_config . s2 .m_skt ;
1054
+ mnp -> m_val = uv_cpuid .m_skt ;
1017
1055
mnp -> n_lshift = mnp -> m_val == 40 ? 40 : 39 ;
1018
1056
}
1019
1057
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)
1035
1073
hi -> hub_revision = uv_hub_info -> hub_revision ;
1036
1074
hi -> hub_type = uv_hub_info -> hub_type ;
1037
1075
hi -> pnode_mask = uv_cpuid .pnode_mask ;
1076
+ hi -> nasid_shift = uv_cpuid .nasid_shift ;
1038
1077
hi -> min_pnode = _min_pnode ;
1039
1078
hi -> min_socket = _min_socket ;
1040
1079
hi -> pnode_to_socket = _pnode_to_socket ;
@@ -1146,16 +1185,19 @@ static int __init decode_uv_systab(void)
1146
1185
struct uv_systab * st ;
1147
1186
int i ;
1148
1187
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 */
1153
1189
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
+
1154
1195
if ((!st ) || (st -> revision < UV_SYSTAB_VERSION_UV4_LATEST )) {
1155
1196
int rev = st ? st -> revision : 0 ;
1156
1197
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" );
1159
1201
uv_system_type = UV_NONE ;
1160
1202
1161
1203
return - EINVAL ;
@@ -1393,7 +1435,8 @@ static void __init uv_system_init_hub(void)
1393
1435
struct uv_hub_info_s hub_info = {0 };
1394
1436
int bytes , cpu , nodeid ;
1395
1437
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" :
1397
1440
is_uv3_hub () ? "UV300" :
1398
1441
is_uv2_hub () ? "UV2000/3000" : NULL ;
1399
1442
0 commit comments