<p>Arthur Heymans has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/26297">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cpu/intel/model_2065x: Use parallel MP init<br><br>Change-Id: I56b352f9d76ee58f5c82cd431a4e0fa206f848a0<br>Signed-off-by: Arthur Heymans <arthur@aheymans.xyz><br>---<br>M src/cpu/intel/model_2065x/Kconfig<br>M src/cpu/intel/model_2065x/model_2065x_init.c<br>M src/northbridge/intel/nehalem/northbridge.c<br>3 files changed, 78 insertions(+), 84 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/97/26297/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/cpu/intel/model_2065x/Kconfig b/src/cpu/intel/model_2065x/Kconfig</span><br><span>index 59bb8d8..a01618f 100644</span><br><span>--- a/src/cpu/intel/model_2065x/Kconfig</span><br><span>+++ b/src/cpu/intel/model_2065x/Kconfig</span><br><span>@@ -20,6 +20,7 @@</span><br><span>      #select AP_IN_SIPI_WAIT</span><br><span>      select TSC_SYNC_MFENCE</span><br><span>       select CPU_INTEL_COMMON</span><br><span style="color: hsl(120, 100%, 40%);">+       select PARALLEL_MP</span><br><span> </span><br><span> config BOOTBLOCK_CPU_INIT</span><br><span>  string</span><br><span>diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c</span><br><span>index 322e814..503618d 100644</span><br><span>--- a/src/cpu/intel/model_2065x/model_2065x_init.c</span><br><span>+++ b/src/cpu/intel/model_2065x/model_2065x_init.c</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  * GNU General Public License for more details.</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <assert.h></span><br><span> #include <console/console.h></span><br><span> #include <device/device.h></span><br><span> #include <string.h></span><br><span>@@ -23,6 +24,7 @@</span><br><span> #include <cpu/x86/mtrr.h></span><br><span> #include <cpu/x86/msr.h></span><br><span> #include <cpu/x86/lapic.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/mp.h></span><br><span> #include <cpu/intel/microcode.h></span><br><span> #include <cpu/intel/speedstep.h></span><br><span> #include <cpu/intel/turbo.h></span><br><span>@@ -111,29 +113,6 @@</span><br><span>         { 0 }</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int cpu_get_apic_id_map(int *apic_id_map)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       int i;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct cpuid_result result;</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned int threads_per_package, threads_per_core;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Logical processors (threads) per core */</span><br><span style="color: hsl(0, 100%, 40%);">-     result = cpuid_ext(0xb, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     threads_per_core = result.ebx & 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Logical processors (threads) per package */</span><br><span style="color: hsl(0, 100%, 40%);">-  result = cpuid_ext(0xb, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-     threads_per_package = result.ebx & 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  for (i = 0; i < threads_per_package && i < CONFIG_MAX_CPUS; ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-                apic_id_map[i] = (i % threads_per_core)</span><br><span style="color: hsl(0, 100%, 40%);">-                 + ((i / threads_per_core) << 2);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return threads_per_package;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> int cpu_config_tdp_levels(void)</span><br><span> {</span><br><span>         msr_t platform_info;</span><br><span>@@ -252,58 +231,6 @@</span><br><span>          wrmsr(IA32_MC0_STATUS + (i * 4), msr);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Initialize any extra cores/threads in this package.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static void intel_cores_init(struct device *cpu)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct cpuid_result result;</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned int threads_per_package, threads_per_core, i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Logical processors (threads) per core */</span><br><span style="color: hsl(0, 100%, 40%);">-     result = cpuid_ext(0xb, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     threads_per_core = result.ebx & 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Logical processors (threads) per package */</span><br><span style="color: hsl(0, 100%, 40%);">-  result = cpuid_ext(0xb, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-     threads_per_package = result.ebx & 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Only initialize extra cores from BSP */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (cpu->path.apic.apic_id)</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n",</span><br><span style="color: hsl(0, 100%, 40%);">-            cpu->path.apic.apic_id, threads_per_package/threads_per_core,</span><br><span style="color: hsl(0, 100%, 40%);">-        threads_per_core);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 1; i < threads_per_package; ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-          struct device_path cpu_path;</span><br><span style="color: hsl(0, 100%, 40%);">-            struct device *new;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             /* Build the CPU device path */</span><br><span style="color: hsl(0, 100%, 40%);">-         cpu_path.type = DEVICE_PATH_APIC;</span><br><span style="color: hsl(0, 100%, 40%);">-               cpu_path.apic.apic_id =</span><br><span style="color: hsl(0, 100%, 40%);">-           cpu->path.apic.apic_id + (i % threads_per_core)</span><br><span style="color: hsl(0, 100%, 40%);">-                    + ((i / threads_per_core) << 2);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          /* Allocate the new CPU device structure */</span><br><span style="color: hsl(0, 100%, 40%);">-             new = alloc_dev(cpu->bus, &cpu_path);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!new)</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               printk(BIOS_DEBUG, "CPU: %u has core %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  cpu->path.apic.apic_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                      new->path.apic.apic_id);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Start the new CPU */</span><br><span style="color: hsl(0, 100%, 40%);">-         if (is_smp_boot() && !start_cpu(new)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* Record the error in cpu? */</span><br><span style="color: hsl(0, 100%, 40%);">-                  printk(BIOS_ERR, "CPU %u would not start!\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                        new->path.apic.apic_id);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void model_2065x_init(struct device *cpu)</span><br><span> {</span><br><span>  char processor_name[49];</span><br><span>@@ -311,8 +238,6 @@</span><br><span>       /* Turn on caching if we haven't already */</span><br><span>      x86_enable_cache();</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- intel_update_microcode_from_cbfs();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>  /* Clear out pending MCEs */</span><br><span>         configure_mca();</span><br><span> </span><br><span>@@ -322,10 +247,6 @@</span><br><span>  printk(BIOS_INFO, "CPU:lapic=%ld, boot_cpu=%d\n", lapicid(),</span><br><span>               boot_cpu());</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        /* Setup MTRRs based on physical address size */</span><br><span style="color: hsl(0, 100%, 40%);">-        x86_setup_mtrrs_with_detect();</span><br><span style="color: hsl(0, 100%, 40%);">-  x86_mtrr_check();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    /* Setup Page Attribute Tables (PAT) */</span><br><span>      // TODO set up PAT</span><br><span> </span><br><span>@@ -350,9 +271,81 @@</span><br><span> </span><br><span>    /* Enable Turbo */</span><br><span>   enable_turbo();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* Start up extra cores */</span><br><span style="color: hsl(0, 100%, 40%);">-      intel_cores_init(cpu);</span><br><span style="color: hsl(120, 100%, 40%);">+/* MP initialization support. */</span><br><span style="color: hsl(120, 100%, 40%);">+static const void *microcode_patch;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void pre_mp_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Setup MTRRs based on physical address size. */</span><br><span style="color: hsl(120, 100%, 40%);">+     x86_setup_mtrrs_with_detect();</span><br><span style="color: hsl(120, 100%, 40%);">+        x86_mtrr_check();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_cpu_count(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct cpuid_result result;</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int threads_per_package, threads_per_core;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Logical processors (threads) per core */</span><br><span style="color: hsl(120, 100%, 40%);">+   result = cpuid_ext(0xb, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   threads_per_core = result.ebx & 0xffff;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ASSERT(threads_per_core != 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Logical processors (threads) per package */</span><br><span style="color: hsl(120, 100%, 40%);">+        result = cpuid_ext(0xb, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+   threads_per_package = result.ebx & 0xffff;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              threads_per_package / threads_per_core, threads_per_package);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return threads_per_package;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void get_microcode_info(const void **microcode, int *parallel)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    microcode_patch = intel_microcode_find();</span><br><span style="color: hsl(120, 100%, 40%);">+     *microcode = microcode_patch;</span><br><span style="color: hsl(120, 100%, 40%);">+ *parallel = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void per_cpu_smm_trigger(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Relocate the SMM handler. */</span><br><span style="color: hsl(120, 100%, 40%);">+       smm_relocate();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* After SMM relocation a 2nd microcode load is required. */</span><br><span style="color: hsl(120, 100%, 40%);">+  intel_microcode_load_unlocked(microcode_patch);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void post_mp_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Now that all APs have been relocated as well as the BSP let SMIs</span><br><span style="color: hsl(120, 100%, 40%);">+    * start flowing. */</span><br><span style="color: hsl(120, 100%, 40%);">+  southbridge_smm_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Lock down the SMRAM space. */</span><br><span style="color: hsl(120, 100%, 40%);">+      smm_lock();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct mp_ops mp_ops = {</span><br><span style="color: hsl(120, 100%, 40%);">+     .pre_mp_init = pre_mp_init,</span><br><span style="color: hsl(120, 100%, 40%);">+   .get_cpu_count = get_cpu_count,</span><br><span style="color: hsl(120, 100%, 40%);">+       .get_smm_info = smm_info,</span><br><span style="color: hsl(120, 100%, 40%);">+     .get_microcode_info = get_microcode_info,</span><br><span style="color: hsl(120, 100%, 40%);">+     .pre_mp_smm_init = smm_initialize,</span><br><span style="color: hsl(120, 100%, 40%);">+    .per_cpu_smm_trigger = per_cpu_smm_trigger,</span><br><span style="color: hsl(120, 100%, 40%);">+   .relocation_handler = smm_relocation_handler,</span><br><span style="color: hsl(120, 100%, 40%);">+ .post_mp_init = post_mp_init,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void bsp_init_and_start_aps(struct bus *cpu_bus)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (mp_init_with_smm(cpu_bus, &mp_ops))</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "MP initialization failure.\n");</span><br><span> }</span><br><span> </span><br><span> static struct device_operations cpu_dev_ops = {</span><br><span>diff --git a/src/northbridge/intel/nehalem/northbridge.c b/src/northbridge/intel/nehalem/northbridge.c</span><br><span>index c41434c..df7e864 100644</span><br><span>--- a/src/northbridge/intel/nehalem/northbridge.c</span><br><span>+++ b/src/northbridge/intel/nehalem/northbridge.c</span><br><span>@@ -306,7 +306,7 @@</span><br><span> </span><br><span> static void cpu_bus_init(struct device *dev)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- initialize_cpus(dev->link_list);</span><br><span style="color: hsl(120, 100%, 40%);">+   bsp_init_and_start_aps(dev->link_list);</span><br><span> }</span><br><span> </span><br><span> static struct device_operations cpu_bus_ops = {</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/26297">change 26297</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/26297"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I56b352f9d76ee58f5c82cd431a4e0fa206f848a0 </div>
<div style="display:none"> Gerrit-Change-Number: 26297 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Arthur Heymans <arthur@aheymans.xyz> </div>