[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] The attached patch apic.patch updates xen/arch/x86/apic.c so that it is based on linux 2.6.10 code. A few changes made to linux required reworking functions in other files as well so I held off on those changes. For example, setup_APIC_timer(void *) changed to setup_APIC_timer(unsigned int). The change has no real bearing on the Xen code -- it's just a question of how close to linux one wants to be. However, that change goes with a change to smp_call_function which would affect quite a few other files/functions so I left it as is. Most of the other changes are trivial.
ChangeSet 1.1308, 2005/04/16 00:40:59+01:00, iap10@xxxxxxxxxxxxxxxxxxxxx The attached patch apic.patch updates xen/arch/x86/apic.c so that it is based on linux 2.6.10 code. A few changes made to linux required reworking functions in other files as well so I held off on those changes. For example, setup_APIC_timer(void *) changed to setup_APIC_timer(unsigned int). The change has no real bearing on the Xen code -- it's just a question of how close to linux one wants to be. However, that change goes with a change to smp_call_function which would affect quite a few other files/functions so I left it as is. Most of the other changes are trivial. xen/ac_timer.h was included but not needed by apic.c so I removed it from the list of #includes. The new apic.c includes two new files: asm/io_ports.h and asm/mach_apic.h. Patches to create those files are included as well. arch/x86/apic.c | 372 +++++++++++++++++++++++++++++++------------- include/asm-x86/io_ports.h | 30 +++ include/asm-x86/mach_apic.h | 32 +++ 3 files changed, 327 insertions(+), 107 deletions(-) diff -Nru a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c 2005-04-18 21:03:10 -04:00 +++ b/xen/arch/x86/apic.c 2005-04-18 21:03:10 -04:00 @@ -1,4 +1,6 @@ /* + * based on linux-2.6.10/arch/i386/kernel/apic.c + * * Local APIC handling, local APIC timers * * (c) 1999, 2000 Ingo Molnar <mingo@xxxxxxxxxx> @@ -10,11 +12,11 @@ * for testing these extensively. * Maciej W. Rozycki : Various updates and fixes. * Mikael Pettersson : Power Management for UP-APIC. + * Pavel Machek and + * Mikael Pettersson : PM converted to driver model. */ - #include <xen/config.h> -#include <xen/ac_timer.h> #include <xen/perfc.h> #include <xen/errno.h> #include <xen/init.h> @@ -32,7 +34,8 @@ #include <asm/hardirq.h> #include <asm/apic.h> #include <asm/io_apic.h> - +#include <asm/mach_apic.h> +#include <asm/io_ports.h> /* Using APIC to generate smp_local_timer_interrupt? */ int using_apic_timer = 0; @@ -80,6 +83,16 @@ apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED); } +#if 0 +/* lets not touch this if we didn't frob it */ +#ifdef CONFIG_X86_MCE_P4THERMAL + if (maxlvt >= 5) { + v = apic_read(APIC_LVTTHMR); + apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED); + } +#endif +#endif + /* * Clean APIC state for other OSs: */ @@ -90,9 +103,17 @@ apic_write_around(APIC_LVTERR, APIC_LVT_MASKED); if (maxlvt >= 4) apic_write_around(APIC_LVTPC, APIC_LVT_MASKED); + +#if 0 +#ifdef CONFIG_X86_MCE_P4THERMAL + if (maxlvt >= 5) + apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED); +#endif +#endif + v = GET_APIC_VERSION(apic_read(APIC_LVR)); if (APIC_INTEGRATED(v)) { /* !82489DX */ - if (maxlvt > 3) + if (maxlvt > 3) /* Due to Pentium errata 3AP and 11AP. */ apic_write(APIC_ESR, 0); apic_read(APIC_ESR); } @@ -113,6 +134,9 @@ outb(0x70, 0x22); outb(0x01, 0x23); } +#if 0 + enable_apic_mode(); +#endif } void disconnect_bsp_APIC(void) @@ -193,12 +217,6 @@ */ reg0 = apic_read(APIC_ID); Dprintk("Getting ID: %x\n", reg0); - apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); - reg1 = apic_read(APIC_ID); - Dprintk("Getting ID: %x\n", reg1); - apic_write(APIC_ID, reg0); - if (reg1 != (reg0 ^ APIC_ID_MASK)) - return 0; /* * The next two are just to see if we have sane values. @@ -215,6 +233,10 @@ void __init sync_Arb_IDs(void) { + /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ + unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); + if (ver >= 0x14) /* P4 or higher */ + return; /* * Wait for idle. */ @@ -240,15 +262,17 @@ { } -static unsigned long calculate_ldr(unsigned long old) -{ - unsigned long id = 1UL << smp_processor_id(); - return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id); -} - void __init setup_local_APIC (void) { - unsigned long value, ver, maxlvt; + unsigned long oldvalue, value, ver, maxlvt; + + /* Pound the ESR really hard over the head with a big hammer - mbligh */ + if (esr_disable) { + apic_write(APIC_ESR, 0); + apic_write(APIC_ESR, 0); + apic_write(APIC_ESR, 0); + apic_write(APIC_ESR, 0); + } value = apic_read(APIC_LVR); ver = GET_APIC_VERSION(value); @@ -256,8 +280,10 @@ if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f) __error_in_apic_c(); - /* Double-check wether this APIC is really registered. */ - if (!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map)) + /* + * Double-check whether this APIC is really registered. + */ + if (!apic_id_registered()) BUG(); /* @@ -265,19 +291,7 @@ * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel * document number 292116). So here it goes... */ - - /* - * In clustered apic mode, the firmware does this for us - * Put the APIC into flat delivery mode. - * Must be "all ones" explicitly for 82489DX. - */ - apic_write_around(APIC_DFR, APIC_DFR_FLAT); - - /* - * Set up the logical destination ID. - */ - value = apic_read(APIC_LDR); - apic_write_around(APIC_LDR, calculate_ldr(value)); + init_apic_ldr(); /* * Set Task Priority to 'accept all'. We never change this @@ -297,10 +311,35 @@ */ value |= APIC_SPIV_APIC_ENABLED; + /* + * Some unknown Intel IO/APIC (or APIC) errata is biting us with + * certain networking cards. If high frequency interrupts are + * happening on a particular IOAPIC pin, plus the IOAPIC routing + * entry is masked/unmasked at a high rate as well then sooner or + * later IOAPIC line gets 'stuck', no more interrupts are received + * from the device. If focus CPU is disabled then the hang goes + * away, oh well :-( + * + * [ This bug can be reproduced easily with a level-triggered + * PCI Ne2000 networking cards and PII/PIII processors, dual + * BX chipset. ] + */ + /* + * Actually disabling the focus CPU check just makes the hang less + * frequent as it makes the interrupt distributon model be more + * like LRU than MRU (the short-term load is more even across CPUs). + * See also the comment in end_level_ioapic_irq(). --macro + */ +#if 1 /* Enable focus processor (bit==0) */ value &= ~APIC_SPIV_FOCUS_DISABLED; - - /* Set spurious IRQ vector */ +#else + /* Disable focus processor (bit==1) */ + value |= APIC_SPIV_FOCUS_DISABLED; +#endif + /* + * Set spurious IRQ vector + */ value |= SPURIOUS_APIC_VECTOR; apic_write_around(APIC_SPIV, value); @@ -315,7 +354,7 @@ * TODO: set up through-local-APIC from through-I/O-APIC? --macro */ value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; - if (!smp_processor_id()) { + if (!smp_processor_id() && (pic_mode || !value)) { value = APIC_DM_EXTINT; printk("enabled ExtINT on CPU#%d\n", smp_processor_id()); } else { @@ -335,33 +374,43 @@ value |= APIC_LVT_LEVEL_TRIGGER; apic_write_around(APIC_LVT1, value); - if (APIC_INTEGRATED(ver)) { /* !82489DX */ + if (APIC_INTEGRATED(ver) && !esr_disable) { /* !82489DX */ maxlvt = get_maxlvt(); if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ apic_write(APIC_ESR, 0); - value = apic_read(APIC_ESR); - printk("ESR value before enabling vector: %08lx\n", value); + oldvalue = apic_read(APIC_ESR); - value = ERROR_APIC_VECTOR; /* enables sending errors */ + value = ERROR_APIC_VECTOR; // enables sending errors apic_write_around(APIC_LVTERR, value); - /* spec says clear errors after enabling vector. */ + /* + * spec says clear errors after enabling vector. + */ if (maxlvt > 3) apic_write(APIC_ESR, 0); value = apic_read(APIC_ESR); - printk("ESR value after enabling vector: %08lx\n", value); + if (value != oldvalue) + printk("ESR value before enabling vector: 0x%08lx " + "after: 0x%08lx\n", oldvalue, value); } else { + if (esr_disable) + /* + * Something untraceble is creating bad interrupts on + * secondary quads ... for the moment, just leave the + * ESR disabled - we can't do anything useful with the + * errors anyway - mbligh + */ + printk("Leaving ESR disabled.\n"); + else printk("No ESR for 82489DX.\n"); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |