summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2021-05-29 22:50:22 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2021-06-10 17:51:51 +0000
commit36c90179f0c7ef0d11ca78a109bd563b3ec0e0a9 (patch)
tree4283ee34bfff7b053fae614c66fe380282a668fa
parent68fe11beb0c27c2ae995ab0fa190960d8813e32c (diff)
downloadcoreboot-36c90179f0c7ef0d11ca78a109bd563b3ec0e0a9.tar.gz
coreboot-36c90179f0c7ef0d11ca78a109bd563b3ec0e0a9.tar.bz2
coreboot-36c90179f0c7ef0d11ca78a109bd563b3ec0e0a9.zip
cpu/x86/lapic: Separate stop_this_cpu()
Function is needed with PARALLEL_MP and excluding guard will be added to the source file. The incompatibilities with X2APIC_SUPPORT have been fixed so the exclusion is removed here too. Change-Id: I5696da4dfe98579a3b37a027966b6758f22574aa Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/55193 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
-rw-r--r--src/cpu/x86/Kconfig2
-rw-r--r--src/cpu/x86/lapic/Makefile.inc6
-rw-r--r--src/cpu/x86/lapic/lapic_cpu_init.c68
-rw-r--r--src/cpu/x86/lapic/lapic_cpu_stop.c70
-rw-r--r--src/include/cpu/x86/lapic.h2
5 files changed, 75 insertions, 73 deletions
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index d7057ad86148..84b1fc1297de 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -29,13 +29,11 @@ config X2APIC_ONLY
prompt "Set X2APIC mode"
bool
depends on PARALLEL_MP
- depends on !AP_IN_SIPI_WAIT
config X2APIC_RUNTIME
prompt "Support both XAPIC and X2APIC"
bool
depends on PARALLEL_MP
- depends on !AP_IN_SIPI_WAIT
endchoice
diff --git a/src/cpu/x86/lapic/Makefile.inc b/src/cpu/x86/lapic/Makefile.inc
index 8e89d29f688a..91a41f76a59d 100644
--- a/src/cpu/x86/lapic/Makefile.inc
+++ b/src/cpu/x86/lapic/Makefile.inc
@@ -1,5 +1,7 @@
-ramstage-y += lapic_cpu_init.c
-ramstage-$(CONFIG_SMP) += secondary.S
+ramstage-$(CONFIG_AP_IN_SIPI_WAIT) += lapic_cpu_stop.c
+ramstage-$(CONFIG_LEGACY_SMP_INIT) += lapic_cpu_init.c
+ramstage-$(CONFIG_LEGACY_SMP_INIT) += secondary.S
+
bootblock-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c
index d01fb91a1978..9b5825a6a828 100644
--- a/src/cpu/x86/lapic/lapic_cpu_init.c
+++ b/src/cpu/x86/lapic/lapic_cpu_init.c
@@ -6,7 +6,6 @@
#include <cpu/x86/smi_deprecated.h>
#include <acpi/acpi.h>
#include <delay.h>
-#include <halt.h>
#include <lib.h>
#include <string.h>
#include <symbols.h>
@@ -283,73 +282,6 @@ static int start_cpu(struct device *cpu)
return result;
}
-#if CONFIG(AP_IN_SIPI_WAIT)
-
-/**
- * Sending INIT IPI to self is equivalent of asserting #INIT with a bit of
- * delay.
- * An undefined number of instruction cycles will complete. All global locks
- * must be released before INIT IPI and no printk is allowed after this.
- * De-asserting INIT IPI is a no-op on later Intel CPUs.
- *
- * If you set DEBUG_HALT_SELF to 1, printk's after INIT IPI are enabled
- * but running thread may halt without releasing the lock and effectively
- * deadlock other CPUs.
- */
-#define DEBUG_HALT_SELF 0
-
-#if DEBUG_HALT_SELF
-#define dprintk(LEVEL, args...) do { printk(LEVEL, ##args); } while (0)
-#else
-#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.
- * I think all hyperthreading CPUs might need this version, but I could only
- * verify this on the Intel Core Duo
- */
-void stop_this_cpu(void)
-{
- 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_ipi_completion_without_printk(timeout_100ms);
-
- mdelay(10);
-
- dprintk(BIOS_SPEW, "Deasserting INIT.\n");
-
- /* Deassert the LAPIC INIT */
- lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT, id);
- wait_for_ipi_completion_without_printk(timeout_100ms);
-
- halt();
-}
-#endif
-
/* C entry point of secondary cpus */
asmlinkage void secondary_cpu_init(unsigned int index)
{
diff --git a/src/cpu/x86/lapic/lapic_cpu_stop.c b/src/cpu/x86/lapic/lapic_cpu_stop.c
new file mode 100644
index 000000000000..e933ce4c4704
--- /dev/null
+++ b/src/cpu/x86/lapic/lapic_cpu_stop.c
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <cpu/x86/lapic.h>
+#include <delay.h>
+#include <halt.h>
+
+/**
+ * Sending INIT IPI to self is equivalent of asserting #INIT with a bit of
+ * delay.
+ * An undefined number of instruction cycles will complete. All global locks
+ * must be released before INIT IPI and no printk is allowed after this.
+ * De-asserting INIT IPI is a no-op on later Intel CPUs.
+ *
+ * If you set DEBUG_HALT_SELF to 1, printk's after INIT IPI are enabled
+ * but running thread may halt without releasing the lock and effectively
+ * deadlock other CPUs.
+ */
+#define DEBUG_HALT_SELF 0
+
+#if DEBUG_HALT_SELF
+#define dprintk(LEVEL, args...) do { printk(LEVEL, ##args); } while (0)
+#else
+#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.
+ * I think all hyperthreading CPUs might need this version, but I could only
+ * verify this on the Intel Core Duo
+ */
+void stop_this_cpu(void)
+{
+ 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_ipi_completion_without_printk(timeout_100ms);
+
+ mdelay(10);
+
+ dprintk(BIOS_SPEW, "Deasserting INIT.\n");
+
+ /* Deassert the LAPIC INIT */
+ lapic_send_ipi(LAPIC_INT_LEVELTRIG | LAPIC_DM_INIT, id);
+ wait_for_ipi_completion_without_printk(timeout_100ms);
+
+ halt();
+}
diff --git a/src/include/cpu/x86/lapic.h b/src/include/cpu/x86/lapic.h
index 4647877ae9d2..d5e5edca9a60 100644
--- a/src/include/cpu/x86/lapic.h
+++ b/src/include/cpu/x86/lapic.h
@@ -159,7 +159,7 @@ static __always_inline unsigned int lapicid(void)
#if !CONFIG(AP_IN_SIPI_WAIT)
/* If we need to go back to sipi wait, we use the long non-inlined version of
- * this function in lapic_cpu_init.c
+ * this function in lapic_cpu_stop.c
*/
static __always_inline void stop_this_cpu(void)
{