[coreboot-gerrit] New patch to review for coreboot: b228080 haswell: allow for disabled hyperthreading

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Mon Jun 3 16:56:36 CEST 2013


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3353

-gerrit

commit b2280806bcbca6b6df011da8b387be02c5c9bc79
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Tue May 28 14:26:29 2013 -0500

    haswell: allow for disabled hyperthreading
    
    There were assumptions being made in the haswell
    MP and SMM code which assumed the APIC id space
    was 1:1 w.r.t. cpu number. When hyperthreading is
    disabled the APIC ids of the logical processors
    are all even. That means the APIC id space is sparse.
    Handle this situation.
    
    Change-Id: Ibe79ab156c0a171208a77db8a252aa5b73205d6c
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/cpu/intel/haswell/haswell.h     |  3 +++
 src/cpu/intel/haswell/mp_init.c     | 22 +++++++++++++++++++---
 src/cpu/intel/haswell/smmrelocate.c | 32 +++++++++++++++++++++++++++++---
 3 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h
index c550cfa..4a739a9 100644
--- a/src/cpu/intel/haswell/haswell.h
+++ b/src/cpu/intel/haswell/haswell.h
@@ -175,6 +175,9 @@ int setup_ap_init(struct bus *cpu_bus, int *max_cpus,
 /* Returns 0 on success, < 0 on failure. */
 int start_aps(struct bus *cpu_bus, int max_cpus);
 void release_aps_for_smm_relocation(int do_parallel_relocation);
+/* Determine if HyperThreading is disabled. The variable is not valid until
+ * setup_ap_init() has been called. */
+extern int ht_disabled;
 #endif
 
 /* This structure is saved along with the relocated ramstage program in SMM
diff --git a/src/cpu/intel/haswell/mp_init.c b/src/cpu/intel/haswell/mp_init.c
index 357fbb2..1358418 100644
--- a/src/cpu/intel/haswell/mp_init.c
+++ b/src/cpu/intel/haswell/mp_init.c
@@ -80,6 +80,8 @@ static atomic_t num_aps;
 static atomic_t num_aps_relocated_smm;
 /* Barrier to stop APs from performing SMM relcoation. */
 static int smm_relocation_barrier_begin __attribute__ ((aligned (64)));
+/* Determine if hyperthreading is disabled. */
+int ht_disabled;
 
 static inline void mfence(void)
 {
@@ -197,6 +199,8 @@ static void asmlinkage ap_init(unsigned int cpu, void *microcode_ptr)
 static void setup_default_sipi_vector_params(struct sipi_params *sp)
 {
 	int i;
+	u8 apic_id;
+	u8 apic_id_inc;
 
 	sp->gdt = (u32)&gdt;
 	sp->gdtlimit = (u32)&gdt_end - (u32)&gdt - 1;
@@ -205,9 +209,15 @@ static void setup_default_sipi_vector_params(struct sipi_params *sp)
 	sp->stack_top = (u32)&_estack;
 	/* Adjust the stack top to take into account cpu_info. */
 	sp->stack_top -= sizeof(struct cpu_info);
-	/* Default to linear APIC id space. */
-	for (i = 0; i < CONFIG_MAX_CPUS; i++)
-		sp->apic_to_cpu_num[i] = i;
+
+	/* Default to linear APIC id space if HT is enabled. If it is
+	 * disabled the APIC ids increase by 2 as the odd numbered APIC
+	 * ids are not present.*/
+	apic_id_inc = (ht_disabled) ? 2 : 1;
+	for (i = 0, apic_id = 0; i < CONFIG_MAX_CPUS; i++) {
+		sp->apic_to_cpu_num[i] = apic_id;
+		apic_id += apic_id_inc;
+	}
 }
 
 #define NUM_FIXED_MTRRS 11
@@ -374,6 +384,10 @@ static int allocate_cpu_devices(struct bus *cpu_bus, int *total_hw_threads)
 		max_cpus = CONFIG_MAX_CPUS;
 	}
 
+	/* Determine if hyperthreading is enabled. If not, the APIC id space
+	 * is sparse with ids incrementing by 2 instead of 1. */
+	ht_disabled = num_threads == num_cores;
+
 	for (i = 1; i < max_cpus; i++) {
 		struct device_path cpu_path;
 		device_t new;
@@ -381,6 +395,8 @@ static int allocate_cpu_devices(struct bus *cpu_bus, int *total_hw_threads)
 		/* Build the cpu device path */
 		cpu_path.type = DEVICE_PATH_APIC;
 		cpu_path.apic.apic_id = info->cpu->path.apic.apic_id + i;
+		if (ht_disabled)
+			cpu_path.apic.apic_id = cpu_path.apic.apic_id * 2;
 
 		/* Allocate the new cpu device structure */
 		new = alloc_find_dev(cpu_bus, &cpu_path);
diff --git a/src/cpu/intel/haswell/smmrelocate.c b/src/cpu/intel/haswell/smmrelocate.c
index 6caeafa..4fe6489 100644
--- a/src/cpu/intel/haswell/smmrelocate.c
+++ b/src/cpu/intel/haswell/smmrelocate.c
@@ -286,6 +286,22 @@ static void fill_in_relocation_params(device_t dev,
 	params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1;
 }
 
+static void adjust_apic_id_map(struct smm_loader_params *smm_params)
+{
+	struct smm_runtime *runtime;
+	int i;
+
+	/* Adjust the APIC id map if HT is disabled. */
+	if (!ht_disabled)
+		return;
+
+	runtime = smm_params->runtime;
+
+	/* The APIC ids increment by 2 when HT is disabled. */
+	for (i = 0; i < CONFIG_MAX_CPUS; i++)
+		runtime->apic_id_to_cpu[i] = runtime->apic_id_to_cpu[i] * 2;
+}
+
 static int install_relocation_handler(int num_cpus,
                                       struct smm_relocation_params *relo_params)
 {
@@ -305,7 +321,12 @@ static int install_relocation_handler(int num_cpus,
 		.handler_arg = (void *)relo_params,
 	};
 
-	return smm_setup_relocation_handler(&smm_params);
+	if (smm_setup_relocation_handler(&smm_params))
+		return -1;
+
+	adjust_apic_id_map(&smm_params);
+
+	return 0;
 }
 
 static void setup_ied_area(struct smm_relocation_params *params)
@@ -347,8 +368,13 @@ static int install_permanent_handler(int num_cpus,
 
 	printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n",
 	       relo_params->smram_base);
-	return smm_load_module((void *)relo_params->smram_base,
-	                       relo_params->smram_size, &smm_params);
+	if (smm_load_module((void *)relo_params->smram_base,
+	                     relo_params->smram_size, &smm_params))
+		return -1;
+
+	adjust_apic_id_map(&smm_params);
+
+	return 0;
 }
 
 static int cpu_smm_setup(void)



More information about the coreboot-gerrit mailing list