Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic changes from Ingo Molnar: "Changes: - SGI UV APIC driver updates - dead code removal" * 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/apic/uv: Update the UV APIC HUB check x86/apic/uv: Update the UV APIC driver check x86/apic/uv: Update the APIC UV OEM check x86/apic: Remove verify_local_APIC()
This commit is contained in:
commit
977e1ba508
4 changed files with 59 additions and 93 deletions
|
@ -204,7 +204,6 @@ extern void clear_local_APIC(void);
|
|||
extern void disconnect_bsp_APIC(int virt_wire_setup);
|
||||
extern void disable_local_APIC(void);
|
||||
extern void lapic_shutdown(void);
|
||||
extern int verify_local_APIC(void);
|
||||
extern void sync_Arb_IDs(void);
|
||||
extern void init_bsp_APIC(void);
|
||||
extern void setup_local_APIC(void);
|
||||
|
|
|
@ -1084,67 +1084,6 @@ void lapic_shutdown(void)
|
|||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is to verify that we're looking at a real local APIC.
|
||||
* Check these against your board if the CPUs aren't getting
|
||||
* started for no apparent reason.
|
||||
*/
|
||||
int __init verify_local_APIC(void)
|
||||
{
|
||||
unsigned int reg0, reg1;
|
||||
|
||||
/*
|
||||
* The version register is read-only in a real APIC.
|
||||
*/
|
||||
reg0 = apic_read(APIC_LVR);
|
||||
apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0);
|
||||
apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
|
||||
reg1 = apic_read(APIC_LVR);
|
||||
apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1);
|
||||
|
||||
/*
|
||||
* The two version reads above should print the same
|
||||
* numbers. If the second one is different, then we
|
||||
* poke at a non-APIC.
|
||||
*/
|
||||
if (reg1 != reg0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Check if the version looks reasonably.
|
||||
*/
|
||||
reg1 = GET_APIC_VERSION(reg0);
|
||||
if (reg1 == 0x00 || reg1 == 0xff)
|
||||
return 0;
|
||||
reg1 = lapic_get_maxlvt();
|
||||
if (reg1 < 0x02 || reg1 == 0xff)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The ID register is read/write in a real APIC.
|
||||
*/
|
||||
reg0 = apic_read(APIC_ID);
|
||||
apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
|
||||
apic_write(APIC_ID, reg0 ^ apic->apic_id_mask);
|
||||
reg1 = apic_read(APIC_ID);
|
||||
apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
|
||||
apic_write(APIC_ID, reg0);
|
||||
if (reg1 != (reg0 ^ apic->apic_id_mask))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The next two are just to see if we have sane values.
|
||||
* They're only really relevant if we're in Virtual Wire
|
||||
* compatibility mode, but most boxes are anymore.
|
||||
*/
|
||||
reg0 = apic_read(APIC_LVT0);
|
||||
apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
|
||||
reg1 = apic_read(APIC_LVT1);
|
||||
apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_Arb_IDs - synchronize APIC bus arbitration IDs
|
||||
*/
|
||||
|
@ -2283,7 +2222,6 @@ int __init APIC_init_uniprocessor(void)
|
|||
disable_ioapic_support();
|
||||
|
||||
default_setup_apic_routing();
|
||||
verify_local_APIC();
|
||||
apic_bsp_setup(true);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -144,33 +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;
|
||||
|
||||
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;
|
||||
}
|
||||
if (strncmp(oem_id, "SGI", 3) != 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
@ -854,10 +881,14 @@ void __init uv_system_init(void)
|
|||
unsigned long mmr_base, present, paddr;
|
||||
unsigned short pnode_mask;
|
||||
unsigned char n_lshift;
|
||||
char *hub = (is_uv1_hub() ? "UV1" :
|
||||
(is_uv2_hub() ? "UV2" :
|
||||
"UV3"));
|
||||
char *hub = (is_uv1_hub() ? "UV100/1000" :
|
||||
(is_uv2_hub() ? "UV2000/3000" :
|
||||
(is_uv3_hub() ? "UV300" : NULL)));
|
||||
|
||||
if (!hub) {
|
||||
pr_err("UV: Unknown/unsupported UV hub\n");
|
||||
return;
|
||||
}
|
||||
pr_info("UV: Found %s hub\n", hub);
|
||||
map_low_mmrs();
|
||||
|
||||
|
|
|
@ -1086,8 +1086,6 @@ static int __init smp_sanity_check(unsigned max_cpus)
|
|||
return SMP_NO_APIC;
|
||||
}
|
||||
|
||||
verify_local_APIC();
|
||||
|
||||
/*
|
||||
* If SMP should be disabled, then really disable it!
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue