Kyösti Mälkki has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/55192 )
Change subject: cpu/x86/lapic: Add wait_ipi_completion() helpers ......................................................................
cpu/x86/lapic: Add wait_ipi_completion() helpers
Change-Id: Ib9c404cb55b96dcc5639287c214c5c8f468c0529 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- M src/cpu/x86/lapic/lapic_cpu_init.c 1 file changed, 42 insertions(+), 51 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/55192/1
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index 132cb5a..d8cad23 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -88,9 +88,25 @@ memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size); }
+static uint32_t wait_for_ipi_completion(const int timeout_ms) +{ + int loops = timeout_ms * 10; + uint32_t send_status; + + /* wait for the ipi send to finish */ + printk(BIOS_SPEW, "Waiting for send to finish...\n"); + do { + printk(BIOS_SPEW, "+"); + udelay(100); + send_status = lapic_busy(); + } while (send_status && (--loops > 0)); + + return send_status; +} + static int lapic_start_cpu(unsigned long apicid) { - int timeout; + const int timeout_100ms = 100; uint32_t send_status, accept_status; int j, maxlvt;
@@ -105,14 +121,8 @@ */ lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT, apicid);
- printk(BIOS_SPEW, "Waiting for send to finish...\n"); - timeout = 0; - do { - printk(BIOS_SPEW, "+"); - udelay(100); - send_status = lapic_busy(); - } while (send_status && (timeout++ < 1000)); - if (timeout >= 1000) { + send_status = wait_for_ipi_completion(timeout_100ms); + if (send_status) { printk(BIOS_ERR, "CPU %ld: First APIC write timed out. " "Disabling\n", apicid); // too bad. @@ -131,14 +141,8 @@
lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT, apicid);
- printk(BIOS_SPEW, "Waiting for send to finish...\n"); - timeout = 0; - do { - printk(BIOS_SPEW, "+"); - udelay(100); - send_status = lapic_busy(); - } while (send_status && (timeout++ < 1000)); - if (timeout >= 1000) { + send_status = wait_for_ipi_completion(timeout_100ms); + if (send_status) { printk(BIOS_ERR, "CPU %ld: Second APIC write timed out. " "Disabling\n", apicid); // too bad. @@ -172,13 +176,7 @@
printk(BIOS_SPEW, "Startup point 1.\n");
- printk(BIOS_SPEW, "Waiting for send to finish...\n"); - timeout = 0; - do { - printk(BIOS_SPEW, "+"); - udelay(100); - send_status = lapic_busy(); - } while (send_status && (timeout++ < 1000)); + send_status = wait_for_ipi_completion(timeout_100ms);
/* * Give the other CPU some time to accept the IPI. @@ -306,6 +304,23 @@ #define dprintk(LEVEL, args...) do { } while (0) #endif
+static void wait_for_ipi_completion_without_printk(const int timeout_ms) +{ + int loops = timeout_ms * 10; + uint32_t send_status; + + /* wait for the ipi send to finish */ + dprintk(BIOS_SPEW, "Waiting for send to finish...\n"); + do { + dprintk(BIOS_SPEW, "+"); + udelay(100); + send_status = lapic_busy(); + } while (send_status && (--loops > 0)); + + if (send_status) + dprintk(BIOS_ERR, "timed out\n"); +} + /** * Normally this function is defined in lapic.h as an always inline function * that just keeps the CPU in a hlt() loop. This does not work on all CPUs. @@ -314,27 +329,14 @@ */ void stop_this_cpu(void) { - int timeout; - unsigned long send_status; + const int timeout_100ms = 100; unsigned long id = lapicid();
printk(BIOS_DEBUG, "CPU %ld going down...\n", id);
/* send an LAPIC INIT to myself */ lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT, id); - - /* wait for the ipi send to finish */ - dprintk(BIOS_SPEW, "Waiting for send to finish...\n"); - - timeout = 0; - do { - dprintk(BIOS_SPEW, "+"); - udelay(100); - send_status = lapic_busy(); - } while (send_status && (timeout++ < 1000)); - - if (timeout >= 1000) - dprintk(BIOS_ERR, "timed out\n"); + wait_for_ipi_completion_without_printk(timeout_100ms);
mdelay(10);
@@ -342,18 +344,7 @@
/* Deassert the LAPIC INIT */ lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT, id); - - dprintk(BIOS_SPEW, "Waiting for send to finish...\n"); - - timeout = 0; - do { - dprintk(BIOS_SPEW, "+"); - udelay(100); - send_status = lapic_busy(); - } while (send_status && (timeout++ < 1000)); - - if (timeout >= 1000) - dprintk(BIOS_ERR, "timed out\n"); + wait_for_ipi_completion_without_printk(timeout_100ms);
halt(); }