|
@@ -144,36 +144,60 @@ static void __init uv_set_apicid_hibit(void)
|
|
|
|
|
|
static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
|
|
{
|
|
|
- int pnodeid, is_uv1, is_uv2, is_uv3;
|
|
|
+ int pnodeid;
|
|
|
+ int uv_apic;
|
|
|
|
|
|
if (strncmp(oem_id, "SGI", 3) != 0)
|
|
|
return 0;
|
|
|
|
|
|
- is_uv1 = !strcmp(oem_id, "SGI");
|
|
|
- is_uv2 = !strcmp(oem_id, "SGI2");
|
|
|
- is_uv3 = !strncmp(oem_id, "SGI3", 4); /* there are varieties of UV3 */
|
|
|
- if (is_uv1 || is_uv2 || is_uv3) {
|
|
|
- uv_hub_info->hub_revision =
|
|
|
- (is_uv1 ? UV1_HUB_REVISION_BASE :
|
|
|
- (is_uv2 ? UV2_HUB_REVISION_BASE :
|
|
|
- UV3_HUB_REVISION_BASE));
|
|
|
- pnodeid = early_get_pnodeid();
|
|
|
- early_get_apic_pnode_shift();
|
|
|
- x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
|
|
|
- x86_platform.nmi_init = uv_nmi_init;
|
|
|
- if (!strcmp(oem_table_id, "UVL"))
|
|
|
- uv_system_type = UV_LEGACY_APIC;
|
|
|
- else if (!strcmp(oem_table_id, "UVX"))
|
|
|
- uv_system_type = UV_X2APIC;
|
|
|
- else if (!strcmp(oem_table_id, "UVH")) {
|
|
|
- __this_cpu_write(x2apic_extra_bits,
|
|
|
- pnodeid << uvh_apicid.s.pnode_shift);
|
|
|
- uv_system_type = UV_NON_UNIQUE_APIC;
|
|
|
- uv_set_apicid_hibit();
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ /*
|
|
|
+ * Determine UV arch type.
|
|
|
+ * SGI: UV100/1000
|
|
|
+ * SGI2: UV2000/3000
|
|
|
+ * SGI3: UV300 (truncated to 4 chars because of different varieties)
|
|
|
+ */
|
|
|
+ uv_hub_info->hub_revision =
|
|
|
+ !strncmp(oem_id, "SGI3", 4) ? UV3_HUB_REVISION_BASE :
|
|
|
+ !strcmp(oem_id, "SGI2") ? UV2_HUB_REVISION_BASE :
|
|
|
+ !strcmp(oem_id, "SGI") ? UV1_HUB_REVISION_BASE : 0;
|
|
|
+
|
|
|
+ if (uv_hub_info->hub_revision == 0)
|
|
|
+ goto badbios;
|
|
|
+
|
|
|
+ pnodeid = early_get_pnodeid();
|
|
|
+ early_get_apic_pnode_shift();
|
|
|
+ x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range;
|
|
|
+ x86_platform.nmi_init = uv_nmi_init;
|
|
|
+
|
|
|
+ if (!strcmp(oem_table_id, "UVX")) { /* most common */
|
|
|
+ uv_system_type = UV_X2APIC;
|
|
|
+ uv_apic = 0;
|
|
|
+
|
|
|
+ } else if (!strcmp(oem_table_id, "UVH")) { /* only UV1 systems */
|
|
|
+ uv_system_type = UV_NON_UNIQUE_APIC;
|
|
|
+ __this_cpu_write(x2apic_extra_bits,
|
|
|
+ pnodeid << uvh_apicid.s.pnode_shift);
|
|
|
+ uv_set_apicid_hibit();
|
|
|
+ uv_apic = 1;
|
|
|
+
|
|
|
+ } else if (!strcmp(oem_table_id, "UVL")) { /* only used for */
|
|
|
+ uv_system_type = UV_LEGACY_APIC; /* very small systems */
|
|
|
+ uv_apic = 0;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ goto badbios;
|
|
|
}
|
|
|
- return 0;
|
|
|
+
|
|
|
+ pr_info("UV: OEM IDs %s/%s, System/HUB Types %d/%d, uv_apic %d\n",
|
|
|
+ oem_id, oem_table_id, uv_system_type,
|
|
|
+ uv_min_hub_revision_id, uv_apic);
|
|
|
+
|
|
|
+ return uv_apic;
|
|
|
+
|
|
|
+badbios:
|
|
|
+ pr_err("UV: OEM_ID:%s OEM_TABLE_ID:%s\n", oem_id, oem_table_id);
|
|
|
+ pr_err("Current BIOS not supported, update kernel and/or BIOS\n");
|
|
|
+ BUG();
|
|
|
}
|
|
|
|
|
|
enum uv_system_type get_uv_system_type(void)
|