# HG changeset patch # User kaf24@firebug.cl.cam.ac.uk # Date 1114097948 0 # Node ID caaf9d543bc52f05a96fd89f10a5d06551d9462c # Parent 67c40314aa6e67c60445ffdb465de9667274b3d7 bitkeeper revision 1.1357 (4267c91c8u7H5ttS9RWRyBY5FrTm3g) Fix APIC setup on legacy systems. Signed-off-by: Keir Fraser diff -r 67c40314aa6e -r caaf9d543bc5 xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Thu Apr 21 14:19:31 2005 +0000 +++ b/xen/arch/x86/apic.c Thu Apr 21 15:39:08 2005 +0000 @@ -229,17 +229,48 @@ void __init sync_Arb_IDs(void) extern void __error_in_apic_c (void); -/* - * WAS: An initial setup of the virtual wire mode. - * NOW: We don't bother doing anything. All we need at this point - * is to receive timer ticks, so that 'jiffies' is incremented. - * If we're SMP, then we can assume BIOS did setup for us. - * If we're UP, then the APIC should be disabled (it is at reset). - * If we're UP and APIC is enabled, then BIOS is clever and has - * probably done initial interrupt routing for us. - */ void __init init_bsp_APIC(void) { + unsigned long value, ver; + + /* + * Don't do the setup now if we have a SMP BIOS as the through-I/O-APIC + * virtual wire mode might be active. + */ + if (smp_found_config || !cpu_has_apic) + return; + + value = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(value); + + /* + * Do not trust the local APIC being empty at bootup. + */ + clear_local_APIC(); + + /* + * Enable APIC. + */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + + /* This bit is reserved on P4/Xeon and should be cleared */ + if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 15)) + value &= ~APIC_SPIV_FOCUS_DISABLED; + else + value |= APIC_SPIV_FOCUS_DISABLED; + value |= SPURIOUS_APIC_VECTOR; + apic_write_around(APIC_SPIV, value); + + /* + * Set up the virtual wire mode. + */ + apic_write_around(APIC_LVT0, APIC_DM_EXTINT); + value = APIC_DM_NMI; + if (!APIC_INTEGRATED(ver)) /* 82489DX */ + value |= APIC_LVT_LEVEL_TRIGGER; + apic_write_around(APIC_LVT1, value); } void __init setup_local_APIC (void) diff -r 67c40314aa6e -r caaf9d543bc5 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Thu Apr 21 14:19:31 2005 +0000 +++ b/xen/arch/x86/setup.c Thu Apr 21 15:39:08 2005 +0000 @@ -388,11 +388,11 @@ static void __init start_of_day(void) if ( smp_found_config ) get_smp_config(); #endif + init_apic_mappings(); /* make APICs addressable in our pagetables. */ scheduler_init(); init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */ trap_init(); time_init(); /* installs software handler for HZ clock. */ - init_apic_mappings(); /* make APICs addressable in our pagetables. */ arch_init_memory();