From ec2af96ad1603562dcbcad9de48a2d0692367e14 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 6 Aug 2007 05:15:57 +0000 Subject: [PATCH] Clear pending interrupts before we enable external interrupts. Recently the AP in my Merced box seems to have grown a habit of getting unexpected interrupts, such as redundant wake-ups and legacy interrupts that require an INTA cycle. While here, replace DELAY(0) with cpu_spinwait() so that it's clear what we're doing as well as enable the code to take advantage of cpu_spinwait() when it gets implemented. Approved by: re (blanket) --- sys/ia64/ia64/mp_machdep.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 0ba5f2791ba7..7886a0bf1d7c 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -50,7 +51,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include #include #include @@ -64,8 +67,6 @@ MALLOC_DECLARE(M_PMAP); void ia64_ap_startup(void); -extern uint64_t ia64_lapic_address; - #define LID_SAPIC_ID(x) ((int)((x) >> 24) & 0xff) #define LID_SAPIC_EID(x) ((int)((x) >> 16) & 0xff) #define LID_SAPIC_SET(id,eid) (((id & 0xff) << 8 | (eid & 0xff)) << 16); @@ -86,6 +87,8 @@ static void cpu_mp_unleash(void *); void ia64_ap_startup(void) { + volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK; + int vector; pcpup = ap_pcpu; ia64_set_k4((intptr_t)pcpup); @@ -104,7 +107,7 @@ ia64_ap_startup(void) /* Wait until it's time for us to be unleashed */ while (ap_spin) - DELAY(0); + cpu_spinwait(); /* Initialize curthread. */ KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread")); @@ -119,10 +122,22 @@ ia64_ap_startup(void) ap_awake++; while (!smp_started) - DELAY(0); + cpu_spinwait(); CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid)); + /* Acknowledge and EOI all interrupts. */ + vector = ia64_get_ivr(); + while (vector != 15) { + ia64_srlz_d(); + if (vector == 0) + vector = (int)ib->ib_inta; + ia64_set_eoi(0); + ia64_srlz_d(); + vector = ia64_get_ivr(); + } + ia64_srlz_d(); + /* kick off the clock on this AP */ pcpu_initclock(); @@ -278,7 +293,7 @@ cpu_mp_unleash(void *dummy) ap_spin = 0; while (ap_awake != smp_cpus) - DELAY(0); + cpu_spinwait(); if (smp_cpus != cpus || cpus != mp_ncpus) { printf("SMP: %d CPUs found; %d CPUs usable; %d CPUs woken\n",