From: Sepherosa Ziehau Date: Mon, 19 Dec 2011 11:54:10 +0000 (+0800) Subject: x86_64: Always set LINTEN for AMD CPUs if their family >= 0xF X-Git-Tag: v3.0.0~351 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/056fad5a00589cc391af1801314564031707329b x86_64: Always set LINTEN for AMD CPUs if their family >= 0xF This merges d54b8204947bb8a83fa3d2c7f1b595e47f3802c2 --- diff --git a/sys/platform/pc64/apic/lapic.c b/sys/platform/pc64/apic/lapic.c index 4ed8a6d630..da6eadafbb 100644 --- a/sys/platform/pc64/apic/lapic.c +++ b/sys/platform/pc64/apic/lapic.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,40 @@ lapic_init(boolean_t bsp) * only need to be installed once; we do it on BSP. */ if (bsp) { + if (cpu_vendor_id == CPU_VENDOR_AMD && + CPUID_TO_FAMILY(cpu_id) >= 0xf) { + uint32_t tcr; + + /* + * Set the LINTEN bit in the HyperTransport + * Transaction Control Register. + * + * This will cause EXTINT and NMI interrupts + * routed over the hypertransport bus to be + * fed into the LAPIC LINT0/LINT1. If the bit + * isn't set, the interrupts will go to the + * general cpu INTR/NMI pins. On a dual-core + * cpu the interrupt winds up going to BOTH cpus. + * The first cpu that does the interrupt ack + * cycle will get the correct interrupt. The + * second cpu that does it will get a spurious + * interrupt vector (typically IRQ 7). + */ + outl(0x0cf8, + (1 << 31) | /* enable */ + (0 << 16) | /* bus */ + (0x18 << 11) | /* dev (cpu + 0x18) */ + (0 << 8) | /* func */ + 0x68 /* reg */ + ); + tcr = inl(0xcfc); + if ((tcr & 0x00010000) == 0) { + kprintf("LAPIC: AMD LINTEN on\n"); + outl(0xcfc, tcr|0x00010000); + } + outl(0x0cf8, 0); + } + /* Install a 'Spurious INTerrupt' vector */ setidt_global(XSPURIOUSINT_OFFSET, Xspuriousint, SDT_SYSIGT, SEL_KPL, 0); diff --git a/sys/platform/pc64/x86_64/initcpu.c b/sys/platform/pc64/x86_64/initcpu.c index 1755377d40..643342fb9b 100644 --- a/sys/platform/pc64/x86_64/initcpu.c +++ b/sys/platform/pc64/x86_64/initcpu.c @@ -145,35 +145,6 @@ initializecpu(void) load_cr4(rcr4() | CR4_FXSR | CR4_XMM); cpu_fxsr = hw_instruction_sse = 1; } -#ifdef CPU_AMD64X2_INTR_SPAM - /* - * Set the LINTEN bit in the HyperTransport Transaction - * Control Register. - * - * This will cause EXTINT and NMI interrupts routed over the - * hypertransport bus to be fed into the LAPIC LINT0/LINT1. If - * the bit isn't set, the interrupts will go to the general cpu - * INTR/NMI pins. On a multi-core cpus the interrupt winds up - * going to ALL cpus. The first cpu that does the interrupt ack - * cycle will get the correct interrupt. The second cpu that does - * it will get a spurious interrupt vector (typically IRQ 7). - */ - if ((cpu_id & 0xff0) == 0xf30) { - int32_t tcr; - outl(0x0cf8, - (1 << 31) | /* enable */ - (0 << 16) | /* bus */ - (24 << 11) | /* dev (cpu + 24) */ - (0 << 8) | /* func */ - 0x68 /* reg */ - ); - tcr = inl(0xcfc); - if ((tcr & 0x00010000) == 0) { - outl(0xcfc, tcr|0x00010000); - } - outl(0x0cf8, 0); - } -#endif if ((amd_feature & AMDID_NX) != 0) { msr = rdmsr(MSR_EFER) | EFER_NXE;