diff options
-rw-r--r-- | src/cpu/x86/lapic/lapic_cpu_init.c | 93 |
1 files changed, 42 insertions, 51 deletions
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index e870921774..d01fb91a19 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -88,9 +88,25 @@ static void recover_lowest_1M(void) 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 @@ static int lapic_start_cpu(unsigned long apicid) */ 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 @@ static int lapic_start_cpu(unsigned long apicid) 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 @@ static int lapic_start_cpu(unsigned long apicid) 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 @@ static int start_cpu(struct device *cpu) #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 @@ static int start_cpu(struct device *cpu) */ 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 @@ void stop_this_cpu(void) /* 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(); } |