mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 04:34:22 +08:00
x86: Move MP initialization codes into a common place
Most of the MP initialization codes in arch/x86/cpu/baytrail/cpu.c is common to all x86 processors, except detect_num_cpus() which varies from cpu to cpu. Move these to arch/x86/cpu/cpu.c and implement the new 'get_count' method for baytrail and cpu_x86 drivers. Now we call cpu_get_count() in mp_init() to get the number of CPUs. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
946c2b5259
commit
6e6f4ce4f8
@ -12,78 +12,9 @@
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu_x86.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/mp.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/turbo.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int enable_smis(struct udevice *cpu, void *unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mp_flight_record mp_steps[] = {
|
||||
MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
|
||||
/* Wait for APs to finish initialization before proceeding. */
|
||||
MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
|
||||
};
|
||||
|
||||
static int detect_num_cpus(void)
|
||||
{
|
||||
int ecx = 0;
|
||||
|
||||
/*
|
||||
* Use the algorithm described in Intel 64 and IA-32 Architectures
|
||||
* Software Developer's Manual Volume 3 (3A, 3B & 3C): System
|
||||
* Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping
|
||||
* of CPUID Extended Topology Leaf.
|
||||
*/
|
||||
while (1) {
|
||||
struct cpuid_result leaf_b;
|
||||
|
||||
leaf_b = cpuid_ext(0xb, ecx);
|
||||
|
||||
/*
|
||||
* Bay Trail doesn't have hyperthreading so just determine the
|
||||
* number of cores by from level type (ecx[15:8] == * 2)
|
||||
*/
|
||||
if ((leaf_b.ecx & 0xff00) == 0x0200)
|
||||
return leaf_b.ebx & 0xffff;
|
||||
ecx++;
|
||||
}
|
||||
}
|
||||
|
||||
static int baytrail_init_cpus(void)
|
||||
{
|
||||
struct mp_params mp_params;
|
||||
|
||||
lapic_setup();
|
||||
|
||||
mp_params.num_cpus = detect_num_cpus();
|
||||
mp_params.parallel_microcode_load = 0,
|
||||
mp_params.flight_plan = &mp_steps[0];
|
||||
mp_params.num_records = ARRAY_SIZE(mp_steps);
|
||||
mp_params.microcode_pointer = 0;
|
||||
|
||||
if (mp_init(&mp_params)) {
|
||||
printf("Warning: MP init failure\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int x86_init_cpus(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
debug("Init additional CPUs\n");
|
||||
baytrail_init_cpus();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_max_freq(void)
|
||||
{
|
||||
msr_t perf_ctl;
|
||||
@ -176,9 +107,38 @@ static int baytrail_get_info(struct udevice *dev, struct cpu_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int baytrail_get_count(struct udevice *dev)
|
||||
{
|
||||
int ecx = 0;
|
||||
|
||||
/*
|
||||
* Use the algorithm described in Intel 64 and IA-32 Architectures
|
||||
* Software Developer's Manual Volume 3 (3A, 3B & 3C): System
|
||||
* Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping
|
||||
* of CPUID Extended Topology Leaf.
|
||||
*/
|
||||
while (1) {
|
||||
struct cpuid_result leaf_b;
|
||||
|
||||
leaf_b = cpuid_ext(0xb, ecx);
|
||||
|
||||
/*
|
||||
* Bay Trail doesn't have hyperthreading so just determine the
|
||||
* number of cores by from level type (ecx[15:8] == * 2)
|
||||
*/
|
||||
if ((leaf_b.ecx & 0xff00) == 0x0200)
|
||||
return leaf_b.ebx & 0xffff;
|
||||
|
||||
ecx++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cpu_ops cpu_x86_baytrail_ops = {
|
||||
.get_desc = cpu_x86_get_desc,
|
||||
.get_info = baytrail_get_info,
|
||||
.get_count = baytrail_get_count,
|
||||
};
|
||||
|
||||
static const struct udevice_id cpu_x86_baytrail_ids[] = {
|
||||
|
@ -21,10 +21,13 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/control_regs.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <asm/mp.h>
|
||||
#include <asm/post.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/processor-flags.h>
|
||||
@ -621,8 +624,45 @@ int last_stage_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int enable_smis(struct udevice *cpu, void *unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mp_flight_record mp_steps[] = {
|
||||
MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
|
||||
/* Wait for APs to finish initialization before proceeding */
|
||||
MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
|
||||
};
|
||||
|
||||
static int x86_mp_init(void)
|
||||
{
|
||||
struct mp_params mp_params;
|
||||
|
||||
lapic_setup();
|
||||
|
||||
mp_params.parallel_microcode_load = 0,
|
||||
mp_params.flight_plan = &mp_steps[0];
|
||||
mp_params.num_records = ARRAY_SIZE(mp_steps);
|
||||
mp_params.microcode_pointer = 0;
|
||||
|
||||
if (mp_init(&mp_params)) {
|
||||
printf("Warning: MP init failure\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
__weak int x86_init_cpus(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
debug("Init additional CPUs\n");
|
||||
x86_mp_init();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <errno.h>
|
||||
#include <asm/cpu.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int cpu_x86_bind(struct udevice *dev)
|
||||
{
|
||||
struct cpu_platdata *plat = dev_get_parent_platdata(dev);
|
||||
@ -30,8 +32,34 @@ int cpu_x86_get_desc(struct udevice *dev, char *buf, int size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_x86_get_count(struct udevice *dev)
|
||||
{
|
||||
int node, cpu;
|
||||
int num = 0;
|
||||
|
||||
node = fdt_path_offset(gd->fdt_blob, "/cpus");
|
||||
if (node < 0)
|
||||
return -ENOENT;
|
||||
|
||||
for (cpu = fdt_first_subnode(gd->fdt_blob, node);
|
||||
cpu >= 0;
|
||||
cpu = fdt_next_subnode(gd->fdt_blob, cpu)) {
|
||||
const char *device_type;
|
||||
|
||||
device_type = fdt_getprop(gd->fdt_blob, cpu,
|
||||
"device_type", NULL);
|
||||
if (!device_type)
|
||||
continue;
|
||||
if (strcmp(device_type, "cpu") == 0)
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static const struct cpu_ops cpu_x86_ops = {
|
||||
.get_desc = cpu_x86_get_desc,
|
||||
.get_count = cpu_x86_get_count,
|
||||
};
|
||||
|
||||
static const struct udevice_id cpu_x86_ids[] = {
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
/* Total CPUs include BSP */
|
||||
static int num_cpus;
|
||||
|
||||
/* This also needs to match the sipi.S assembly code for saved MSR encoding */
|
||||
struct saved_msr {
|
||||
uint32_t index;
|
||||
@ -383,7 +386,7 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params)
|
||||
int ret = 0;
|
||||
const int timeout_us = 100000;
|
||||
const int step_us = 100;
|
||||
int num_aps = mp_params->num_cpus - 1;
|
||||
int num_aps = num_cpus - 1;
|
||||
|
||||
for (i = 0; i < mp_params->num_records; i++) {
|
||||
struct mp_flight_record *rec = &mp_params->flight_plan[i];
|
||||
@ -451,7 +454,16 @@ int mp_init(struct mp_params *p)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = check_cpu_devices(p->num_cpus);
|
||||
num_cpus = cpu_get_count(cpu);
|
||||
if (num_cpus < 0) {
|
||||
debug("Cannot get number of CPUs: err=%d\n", num_cpus);
|
||||
return num_cpus;
|
||||
}
|
||||
|
||||
if (num_cpus < 2)
|
||||
debug("Warning: Only 1 CPU is detected\n");
|
||||
|
||||
ret = check_cpu_devices(num_cpus);
|
||||
if (ret)
|
||||
debug("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n");
|
||||
|
||||
@ -471,7 +483,7 @@ int mp_init(struct mp_params *p)
|
||||
wbinvd();
|
||||
|
||||
/* Start the APs providing number of APs and the cpus_entered field */
|
||||
num_aps = p->num_cpus - 1;
|
||||
num_aps = num_cpus - 1;
|
||||
ret = start_aps(num_aps, ap_count);
|
||||
if (ret) {
|
||||
mdelay(1000);
|
||||
|
@ -59,7 +59,6 @@ struct mp_flight_record {
|
||||
* SMM support.
|
||||
*/
|
||||
struct mp_params {
|
||||
int num_cpus; /* Total cpus include BSP */
|
||||
int parallel_microcode_load;
|
||||
const void *microcode_pointer;
|
||||
/* Flight plan for APs and BSP */
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <dm/lists.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int cpu_get_desc(struct udevice *dev, char *buf, int size)
|
||||
{
|
||||
struct cpu_ops *ops = cpu_get_ops(dev);
|
||||
|
Loading…
Reference in New Issue
Block a user