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@chromium.org> Reviewed-on: http://review.coreboot.org/3353 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
27435d3bcd
commit
66da043e48
|
@ -175,6 +175,9 @@ int setup_ap_init(struct bus *cpu_bus, int *max_cpus,
|
||||||
/* Returns 0 on success, < 0 on failure. */
|
/* Returns 0 on success, < 0 on failure. */
|
||||||
int start_aps(struct bus *cpu_bus, int max_cpus);
|
int start_aps(struct bus *cpu_bus, int max_cpus);
|
||||||
void release_aps_for_smm_relocation(int do_parallel_relocation);
|
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
|
#endif
|
||||||
|
|
||||||
/* This structure is saved along with the relocated ramstage program in SMM
|
/* This structure is saved along with the relocated ramstage program in SMM
|
||||||
|
|
|
@ -80,6 +80,8 @@ static atomic_t num_aps;
|
||||||
static atomic_t num_aps_relocated_smm;
|
static atomic_t num_aps_relocated_smm;
|
||||||
/* Barrier to stop APs from performing SMM relcoation. */
|
/* Barrier to stop APs from performing SMM relcoation. */
|
||||||
static int smm_relocation_barrier_begin __attribute__ ((aligned (64)));
|
static int smm_relocation_barrier_begin __attribute__ ((aligned (64)));
|
||||||
|
/* Determine if hyperthreading is disabled. */
|
||||||
|
int ht_disabled;
|
||||||
|
|
||||||
static inline void mfence(void)
|
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)
|
static void setup_default_sipi_vector_params(struct sipi_params *sp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
u8 apic_id;
|
||||||
|
u8 apic_id_inc;
|
||||||
|
|
||||||
sp->gdt = (u32)&gdt;
|
sp->gdt = (u32)&gdt;
|
||||||
sp->gdtlimit = (u32)&gdt_end - (u32)&gdt - 1;
|
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;
|
sp->stack_top = (u32)&_estack;
|
||||||
/* Adjust the stack top to take into account cpu_info. */
|
/* Adjust the stack top to take into account cpu_info. */
|
||||||
sp->stack_top -= sizeof(struct cpu_info);
|
sp->stack_top -= sizeof(struct cpu_info);
|
||||||
/* Default to linear APIC id space. */
|
|
||||||
for (i = 0; i < CONFIG_MAX_CPUS; i++)
|
/* Default to linear APIC id space if HT is enabled. If it is
|
||||||
sp->apic_to_cpu_num[i] = i;
|
* 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
|
#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;
|
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++) {
|
for (i = 1; i < max_cpus; i++) {
|
||||||
struct device_path cpu_path;
|
struct device_path cpu_path;
|
||||||
device_t new;
|
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 */
|
/* Build the cpu device path */
|
||||||
cpu_path.type = DEVICE_PATH_APIC;
|
cpu_path.type = DEVICE_PATH_APIC;
|
||||||
cpu_path.apic.apic_id = info->cpu->path.apic.apic_id + i;
|
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 */
|
/* Allocate the new cpu device structure */
|
||||||
new = alloc_find_dev(cpu_bus, &cpu_path);
|
new = alloc_find_dev(cpu_bus, &cpu_path);
|
||||||
|
|
|
@ -286,6 +286,22 @@ static void fill_in_relocation_params(device_t dev,
|
||||||
params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1;
|
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,
|
static int install_relocation_handler(int num_cpus,
|
||||||
struct smm_relocation_params *relo_params)
|
struct smm_relocation_params *relo_params)
|
||||||
{
|
{
|
||||||
|
@ -305,7 +321,12 @@ static int install_relocation_handler(int num_cpus,
|
||||||
.handler_arg = (void *)relo_params,
|
.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)
|
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",
|
printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n",
|
||||||
relo_params->smram_base);
|
relo_params->smram_base);
|
||||||
return smm_load_module((void *)relo_params->smram_base,
|
if (smm_load_module((void *)relo_params->smram_base,
|
||||||
relo_params->smram_size, &smm_params);
|
relo_params->smram_size, &smm_params))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
adjust_apic_id_map(&smm_params);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpu_smm_setup(void)
|
static int cpu_smm_setup(void)
|
||||||
|
|
Loading…
Reference in New Issue