[coreboot-gerrit] Patch set updated for coreboot: 43673dd x86/smm: Initialize SMM on CPUs one-by-one

Patrick Georgi (patrick@georgi-clan.de) gerrit at coreboot.org
Mon Jul 21 21:13:48 CEST 2014


Patrick Georgi (patrick at georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6311

-gerrit

commit 43673dd4b9c87cd5d44af7caa29e9d3cf06c82f2
Author: Patrick Georgi <patrick at georgi-clan.de>
Date:   Mon Jul 21 20:58:18 2014 +0200

    x86/smm: Initialize SMM on CPUs one-by-one
    
    We currently race in SMM init on Atom 230 (and potentially
    other CPUs). At least on the 230, this leads to a hang on
    RSM, likely because both hyperthreads mess around with
    SMBASE and other SMM state variables in parallel without
    coordination.
    
    Change it so first APs are spun up and sent to sleep, then
    BSP initializes SMM, then every CPU, one after another.
    
    Change-Id: I1ae864e37546298ea222e81349c27cf774ed251f
    Signed-off-by: Patrick Georgi <patrick at georgi-clan.de>
---
 src/cpu/x86/lapic/lapic_cpu_init.c | 48 ++++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c
index 09b6b9e..8846470 100644
--- a/src/cpu/x86/lapic/lapic_cpu_init.c
+++ b/src/cpu/x86/lapic/lapic_cpu_init.c
@@ -463,6 +463,41 @@ static void start_other_cpus(struct bus *cpu_bus, device_t bsp_cpu)
 
 }
 
+#if CONFIG_HAVE_SMI_HANDLER && CONFIG_SMP && CONFIG_MAX_CPUS > 1
+static void smm_other_cpus(struct bus *cpu_bus, device_t bsp_cpu)
+{
+	device_t cpu;
+	int pre_count = atomic_read(&active_cpus);
+
+	/* Loop through the cpus once to let them run through SMM relocator */
+
+	for(cpu = cpu_bus->children; cpu ; cpu = cpu->sibling) {
+		if (cpu->path.type != DEVICE_PATH_APIC) {
+			continue;
+		}
+
+		printk(BIOS_ERR, "considering CPU 0x%02x for SMM init\n",
+			cpu->path.apic.apic_id);
+
+		if (cpu==bsp_cpu)
+			continue;
+
+		if (!cpu->enabled) {
+			continue;
+		}
+
+		if (!start_cpu(cpu)) {
+			/* Record the error in cpu? */
+			printk(BIOS_ERR, "CPU 0x%02x would not start!\n",
+				cpu->path.apic.apic_id);
+		}
+
+		/* FIXME: endless loop */
+		while (atomic_read(&active_cpus) != pre_count) ;
+	}
+}
+#endif
+
 static void wait_other_cpus_stop(struct bus *cpu_bus)
 {
 	device_t cpu;
@@ -531,10 +566,6 @@ void initialize_cpus(struct bus *cpu_bus)
 	copy_secondary_start_to_lowest_1M();
 #endif
 
-#if CONFIG_HAVE_SMI_HANDLER
-	smm_init();
-#endif
-
 #if CONFIG_SMP && CONFIG_MAX_CPUS > 1
 	/* start all aps at first, so we can init ECC all together */
 	if (IS_ENABLED(CONFIG_PARALLEL_CPU_INIT))
@@ -551,4 +582,13 @@ void initialize_cpus(struct bus *cpu_bus)
 	/* Now wait the rest of the cpus stop*/
 	wait_other_cpus_stop(cpu_bus);
 #endif
+
+#if CONFIG_HAVE_SMI_HANDLER
+	/* BSP only, all APs are sleeping */
+	smm_init();
+#if CONFIG_SMP && CONFIG_MAX_CPUS > 1
+	last_cpu_index = 0;
+	smm_other_cpus(cpu_bus, info->cpu);
+#endif
+#endif
 }



More information about the coreboot-gerrit mailing list