]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
x86: Move MP initialization codes into a common place
authorBin Meng <bmeng.cn@gmail.com>
Wed, 17 Jun 2015 03:15:36 +0000 (11:15 +0800)
committerSimon Glass <sjg@chromium.org>
Wed, 15 Jul 2015 00:03:16 +0000 (18:03 -0600)
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>
arch/x86/cpu/baytrail/cpu.c
arch/x86/cpu/cpu.c
arch/x86/cpu/cpu_x86.c
arch/x86/cpu/mp_init.c
arch/x86/include/asm/mp.h
drivers/cpu/cpu-uclass.c

index 05156a5a7b3cf8bcbeb0883ce5db900b98fea815..a0117308aeb4d2ec3ed88a0f73ad33b464b422b4 100644 (file)
 #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[] = {
index 1dfd9e6d27b7f7ce5789602b364b726cd82e3183..a6e88cfe19bc524f3edaca51fda0485e2d38c933 100644 (file)
 
 #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;
 }
 
index d32ba6614eebea18e6d230b194fb58d9e556a359..09410416a1ff07aee6698adc94165f37af958fa5 100644 (file)
@@ -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[] = {
index ac5753a1fdc933a2080ffec87345098694697af4..5564d84e17e46569c0d882ee6d289c2796476a90 100644 (file)
@@ -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);
index c0930fd0c6e1f2c091a13285e348ec37346df599..2e6c3120c771f5ade5c5e0f1d413c8d32f6e5130 100644 (file)
@@ -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 */
index a2814a8dcf5b0f7e04a8db6e8e14bdadffed16b4..7660f99ef5956804685b6cd7b3789fa1b99a82fc 100644 (file)
@@ -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);