<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25752">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/cavium: Add secondary CPU support<br><br>Change-Id: I07428161615bcd3d03a3eea0df2dd813e08c8f66<br>---<br>M src/mainboard/cavium/cn8100_sff_evb/Kconfig<br>M src/mainboard/cavium/cn8100_sff_evb/mainboard.c<br>M src/soc/cavium/cn81xx/Kconfig<br>M src/soc/cavium/cn81xx/Makefile.inc<br>M src/soc/cavium/cn81xx/cpu.c<br>A src/soc/cavium/cn81xx/cpu_secondary.S<br>M src/soc/cavium/cn81xx/include/soc/addressmap.h<br>M src/soc/cavium/cn81xx/include/soc/cpu.h<br>M src/soc/cavium/cn81xx/include/soc/memlayout.ld<br>M src/soc/cavium/cn81xx/soc.c<br>M src/soc/cavium/common/Makefile.inc<br>11 files changed, 286 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/52/25752/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/mainboard/cavium/cn8100_sff_evb/Kconfig b/src/mainboard/cavium/cn8100_sff_evb/Kconfig</span><br><span>index 15dd814..3f13ad5 100644</span><br><span>--- a/src/mainboard/cavium/cn8100_sff_evb/Kconfig</span><br><span>+++ b/src/mainboard/cavium/cn8100_sff_evb/Kconfig</span><br><span>@@ -56,6 +56,9 @@</span><br><span>   string</span><br><span>       default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+config MAX_CPUS</span><br><span style="color: hsl(120, 100%, 40%);">+      default 4</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ##########################################################</span><br><span> #### Update below when adding a new derivative board. ####</span><br><span> ##########################################################</span><br><span>diff --git a/src/mainboard/cavium/cn8100_sff_evb/mainboard.c b/src/mainboard/cavium/cn8100_sff_evb/mainboard.c</span><br><span>index 31163d2..3dbfbfd 100644</span><br><span>--- a/src/mainboard/cavium/cn8100_sff_evb/mainboard.c</span><br><span>+++ b/src/mainboard/cavium/cn8100_sff_evb/mainboard.c</span><br><span>@@ -62,7 +62,7 @@</span><br><span>   printk(BIOS_INFO, "MB: COREclk         : %llu MHz\n",</span><br><span>             thunderx_get_core_clock() / 1000000ULL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     printk(BIOS_INFO, "MB: #CPU cores      : %zu\n", cpu_get_num_cores());</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_INFO, "MB: #CPU cores      : %zu\n", cpu_get_num_available_cores());</span><br><span> }</span><br><span> </span><br><span> static void mainboard_init(device_t dev)</span><br><span>@@ -77,6 +77,10 @@</span><br><span> </span><br><span>     /* Init timer */</span><br><span>     soc_timer_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Init CPUs */</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 1; i < CONFIG_MAX_CPUS; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+              start_cpu(i, NULL);</span><br><span> }</span><br><span> </span><br><span> static void mainboard_enable(device_t dev)</span><br><span>diff --git a/src/soc/cavium/cn81xx/Kconfig b/src/soc/cavium/cn81xx/Kconfig</span><br><span>index cec0ada..d98378b 100644</span><br><span>--- a/src/soc/cavium/cn81xx/Kconfig</span><br><span>+++ b/src/soc/cavium/cn81xx/Kconfig</span><br><span>@@ -22,4 +22,7 @@</span><br><span> </span><br><span> if SOC_CAVIUM_CN81XX</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+config STACK_SIZE</span><br><span style="color: hsl(120, 100%, 40%);">+    default 0x2000</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> endif</span><br><span>diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>index f98e890..6fb664e 100644</span><br><span>--- a/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>+++ b/src/soc/cavium/cn81xx/Makefile.inc</span><br><span>@@ -65,6 +65,7 @@</span><br><span> ramstage-y += cpu.c</span><br><span> ramstage-y += l2c.c</span><br><span> ramstage-y += ecam0.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += cpu_secondary.S</span><br><span> </span><br><span> ramstage-y += bl31_plat_params.c</span><br><span> BL31_MAKEARGS += PLAT=t81 M0_CROSS_COMPILE="$(CROSS_COMPILE_arm)" ENABLE_SPE_FOR_LOWER_ELS=0</span><br><span>diff --git a/src/soc/cavium/cn81xx/cpu.c b/src/soc/cavium/cn81xx/cpu.c</span><br><span>index c054aa8..ee6feb4 100644</span><br><span>--- a/src/soc/cavium/cn81xx/cpu.c</span><br><span>+++ b/src/soc/cavium/cn81xx/cpu.c</span><br><span>@@ -14,13 +14,121 @@</span><br><span>  */</span><br><span> </span><br><span> #include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/addressmap.h></span><br><span> #include <arch/io.h></span><br><span> #include <soc/cpu.h></span><br><span> #include <bdk-coreboot.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <delay.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Return the number of cores available in the chip */</span><br><span style="color: hsl(0, 100%, 40%);">-size_t cpu_get_num_cores(void)</span><br><span style="color: hsl(120, 100%, 40%);">+uint64_t cpu_get_available_core_mask(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    uint64_t available = read64((void *)0x87e006001738ll);</span><br><span style="color: hsl(0, 100%, 40%);">-  return bdk_dpop(available);</span><br><span style="color: hsl(120, 100%, 40%);">+   return read64((void *)RST_PP_AVAILABLE);</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%);">+size_t cpu_get_num_available_cores(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return bdk_dpop(cpu_get_available_core_mask());</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 (* secondary_c_entry)(size_t core_id) = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t secondary_booted;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void secondary_cpu_init(size_t core_id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        write64(&secondary_booted, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+    dmb();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (secondary_c_entry)</span><br><span style="color: hsl(120, 100%, 40%);">+                secondary_c_entry(core_id);</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          asm("wfi");</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%);">+size_t cpu_self_get_core_id(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 mpidr_el1;</span><br><span style="color: hsl(120, 100%, 40%);">+        asm("mrs %0, MPIDR_EL1\n\t" : "=r" (mpidr_el1) :: "memory");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Core is 4 bits from AFF0 and rest from AFF1 */</span><br><span style="color: hsl(120, 100%, 40%);">+     size_t core_num;</span><br><span style="color: hsl(120, 100%, 40%);">+      core_num = mpidr_el1 & 0xf;</span><br><span style="color: hsl(120, 100%, 40%);">+       core_num |= (mpidr_el1 & 0xff00) >> 4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return core_num;</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%);">+uint64_t cpu_self_get_core_mask(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return 1ULL << cpu_self_get_core_id();</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%);">+size_t start_cpu(size_t cpu, void (* entry_64)(size_t core_id))</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint64_t coremask = 1ULL << cpu;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct stopwatch sw;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint64_t pending;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printk(BIOS_DEBUG, "CPU: Starting CPU%zu @ %p.\n", cpu, entry_64);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Core not available */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!(coremask & cpu_get_available_core_mask()))</span><br><span style="color: hsl(120, 100%, 40%);">+          return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Only secondary CPUs are supported */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (cpu == cpu_self_get_core_id())</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Check stack here, instead of in cpu_secondary.S */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((CONFIG_STACK_SIZE * cpu) > _stack_sec_size)</span><br><span style="color: hsl(120, 100%, 40%);">+           return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Write the address of the main entry point */</span><br><span style="color: hsl(120, 100%, 40%);">+       write64((void *)MIO_BOOT_AP_JUMP, (uintptr_t)secondary_init);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Get coremask of cores in reset */</span><br><span style="color: hsl(120, 100%, 40%);">+  const uint64_t reset = read64((void *)RST_PP_RESET);</span><br><span style="color: hsl(120, 100%, 40%);">+  printk(BIOS_INFO, "CPU: Cores currently in reset: 0x%llx\n", reset);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Setup entry for secondary core */</span><br><span style="color: hsl(120, 100%, 40%);">+  write64(&secondary_c_entry, (uintptr_t)entry_64);</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(&secondary_booted, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    dmb();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "CPU: Taking core %zu out of reset.\n", cpu);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Release core from reset */</span><br><span style="color: hsl(120, 100%, 40%);">+ write64((void *)RST_PP_RESET, reset & ~coremask);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Wait for cores to finish coming out of reset */</span><br><span style="color: hsl(120, 100%, 40%);">+    udelay(1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  stopwatch_init_usecs_expire(&sw, 1000000);</span><br><span style="color: hsl(120, 100%, 40%);">+        do {</span><br><span style="color: hsl(120, 100%, 40%);">+          pending = read64((void *)RST_PP_PENDING);</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (!stopwatch_expired(&sw) && (pending & coremask));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (stopwatch_expired(&sw)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printk(BIOS_ERR, "ERROR: Timeout waiting for reset "</span><br><span style="color: hsl(120, 100%, 40%);">+                       "pending to clear.");</span><br><span style="color: hsl(120, 100%, 40%);">+                return 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%);">+   stopwatch_init_usecs_expire(&sw, 1000000);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "CPU: Wait up to 1s for the core to boot...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ while (!stopwatch_expired(&sw) && !read64(&secondary_booted));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Cleanup */</span><br><span style="color: hsl(120, 100%, 40%);">+ write64(&secondary_c_entry, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   dmb();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!read64(&secondary_booted)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printk(BIOS_ERR, "ERROR: Core %zu failed to start.\n", cpu);</span><br><span style="color: hsl(120, 100%, 40%);">+                return 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%);">+   printk(BIOS_INFO, "CPU: Core %zu booted\n", cpu);</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span> }</span><br><span>diff --git a/src/soc/cavium/cn81xx/cpu_secondary.S b/src/soc/cavium/cn81xx/cpu_secondary.S</span><br><span>new file mode 100644</span><br><span>index 0000000..d4b4d3c</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/cavium/cn81xx/cpu_secondary.S</span><br><span>@@ -0,0 +1,91 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Early initialization code for aarch64 (a.k.a. armv8)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2016          Cavium, Inc. <support@cavium.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018-present  Facebook, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</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%);">+#include <arch/asm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/addressmap.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+// based on arm64_init_cpu</span><br><span style="color: hsl(120, 100%, 40%);">+ENTRY(secondary_init)</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Initialize PSTATE (unmask all exceptions, select SP_EL0). */</span><br><span style="color: hsl(120, 100%, 40%);">+       msr     SPSel, #0</span><br><span style="color: hsl(120, 100%, 40%);">+     msr     DAIFClr, #0xf</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* TODO: This is where we'd put non-boot CPUs into WFI if needed. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* x22: SCTLR, return address: x23 (callee-saved by subroutine) */</span><br><span style="color: hsl(120, 100%, 40%);">+    mov     x23, x30</span><br><span style="color: hsl(120, 100%, 40%);">+      /* TODO: Assert that we always start running at EL3 */</span><br><span style="color: hsl(120, 100%, 40%);">+        mrs     x22, sctlr_el3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Activate ICache (12) already for speed during cache flush below. */</span><br><span style="color: hsl(120, 100%, 40%);">+        orr     x22, x22, #(1 << 12)</span><br><span style="color: hsl(120, 100%, 40%);">+    msr     sctlr_el3, x22</span><br><span style="color: hsl(120, 100%, 40%);">+        isb</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Invalidate dcache */</span><br><span style="color: hsl(120, 100%, 40%);">+       bl      dcache_invalidate_all</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Deactivate MMU (0), Alignment Check (1) and DCache (2) */</span><br><span style="color: hsl(120, 100%, 40%);">+  and     x22, x22, # ~(1 << 0) & ~(1 << 1) & ~(1 << 2)</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Activate Stack Alignment (3) because why not */</span><br><span style="color: hsl(120, 100%, 40%);">+    orr     x22, x22, #(1 << 3)</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Set to little-endian (25) */</span><br><span style="color: hsl(120, 100%, 40%);">+       and     x22, x22, # ~(1 << 25)</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Deactivate write-xor-execute enforcement (19) */</span><br><span style="color: hsl(120, 100%, 40%);">+   and     x22, x22, # ~(1 << 19)</span><br><span style="color: hsl(120, 100%, 40%);">+  msr     sctlr_el3, x22</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Invalidate icache and TLB for good measure */</span><br><span style="color: hsl(120, 100%, 40%);">+      ic      iallu</span><br><span style="color: hsl(120, 100%, 40%);">+ tlbi    alle3</span><br><span style="color: hsl(120, 100%, 40%);">+ dsb     sy</span><br><span style="color: hsl(120, 100%, 40%);">+    isb</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Load core ID to x0 */</span><br><span style="color: hsl(120, 100%, 40%);">+      mrs     x0, MPIDR_EL1</span><br><span style="color: hsl(120, 100%, 40%);">+ and     x1, x0, # 0xf</span><br><span style="color: hsl(120, 100%, 40%);">+ lsr     x0, x0, 4</span><br><span style="color: hsl(120, 100%, 40%);">+     and     x0, x0, # 0xff0</span><br><span style="color: hsl(120, 100%, 40%);">+       orr     x0, x0, x1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Each core gets CONFIG_STACK_SIZE bytes of stack */</span><br><span style="color: hsl(120, 100%, 40%);">+ mov     x2, # CONFIG_STACK_SIZE</span><br><span style="color: hsl(120, 100%, 40%);">+       mul     x1, x0, x2</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Backup core id */</span><br><span style="color: hsl(120, 100%, 40%);">+  mov     x22, x0</span><br><span style="color: hsl(120, 100%, 40%);">+       ldr     x0, =_stack_sec</span><br><span style="color: hsl(120, 100%, 40%);">+       add     x0, x1, x0 // x0 = CONFIG_STACK_SIZE * coreid + _stack_sec</span><br><span style="color: hsl(120, 100%, 40%);">+    add     x1, x0, # CONFIG_STACK_SIZE // x1 = x0 + CONFIG_STACK_SIZE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Initialize stack with sentinel value to later check overflow. */</span><br><span style="color: hsl(120, 100%, 40%);">+   ldr     x2, =0xdeadbeefdeadbeef</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+1:</span><br><span style="color: hsl(120, 100%, 40%);">+ stp     x2, x2, [x0], #16</span><br><span style="color: hsl(120, 100%, 40%);">+     cmp     x0, x1</span><br><span style="color: hsl(120, 100%, 40%);">+        bne     1b</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Leave a line of beef dead for easier visibility in stack dumps. */</span><br><span style="color: hsl(120, 100%, 40%);">+ sub     sp, x0, #16</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set arg0 to core id */</span><br><span style="color: hsl(120, 100%, 40%);">+     mov     x0, x22</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Call C entry */</span><br><span style="color: hsl(120, 100%, 40%);">+    bl      secondary_cpu_init</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ENDPROC(secondary_init)</span><br><span>diff --git a/src/soc/cavium/cn81xx/include/soc/addressmap.h b/src/soc/cavium/cn81xx/include/soc/addressmap.h</span><br><span>index e235494..f902963 100644</span><br><span>--- a/src/soc/cavium/cn81xx/include/soc/addressmap.h</span><br><span>+++ b/src/soc/cavium/cn81xx/include/soc/addressmap.h</span><br><span>@@ -54,9 +54,14 @@</span><br><span> </span><br><span> /* RST */</span><br><span> #define RST_PF_BAR0         (0x87E006000000ULL + 0x1600)</span><br><span style="color: hsl(120, 100%, 40%);">+#define RST_PP_AVAILABLE  (RST_PF_BAR0 + 0x138ULL)</span><br><span style="color: hsl(120, 100%, 40%);">+#define RST_PP_RESET          (RST_PF_BAR0 + 0x140ULL)</span><br><span style="color: hsl(120, 100%, 40%);">+#define RST_PP_PENDING                (RST_PF_BAR0 + 0x148ULL)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define FUSF_PF_BAR0              0x87E004000000ULL</span><br><span> #define MIO_FUS_PF_BAR0            0x87E003000000ULL</span><br><span> #define MIO_BOOT_PF_BAR0   0x87E000000000ULL</span><br><span style="color: hsl(120, 100%, 40%);">+#define MIO_BOOT_AP_JUMP     (MIO_BOOT_PF_BAR0 + 0xD0ULL)</span><br><span> </span><br><span> /* PTP */</span><br><span> #define MIO_PTP_PF_BAR0                0x807000000000ULL</span><br><span>diff --git a/src/soc/cavium/cn81xx/include/soc/cpu.h b/src/soc/cavium/cn81xx/include/soc/cpu.h</span><br><span>index e4ee99b..3720750 100644</span><br><span>--- a/src/soc/cavium/cn81xx/include/soc/cpu.h</span><br><span>+++ b/src/soc/cavium/cn81xx/include/soc/cpu.h</span><br><span>@@ -9,6 +9,59 @@</span><br><span> #ifndef __SOC_CAVIUM_CN81XX_CPU_H__</span><br><span> #define __SOC_CAVIUM_CN81XX_CPU_H__</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-size_t cpu_get_num_cores(void);</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Number of the Core on which the program is currently running.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return Number of cores</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+size_t cpu_self_get_core_id(void);</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%);">+ * Return a mask representing this core in a 64bit bitmask</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return The mask of active core.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+uint64_t cpu_self_get_core_mask(void);</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%);">+ * Return the mask of available cores.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return Mask of available cores</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+uint64_t cpu_get_available_core_mask(void);</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%);">+ * Return the number of cores available in the chip.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return The number of available cores.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+size_t cpu_get_num_available_cores(void);</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%);">+ * Init secondary cores and call the provided entry for given core.</span><br><span style="color: hsl(120, 100%, 40%);">+ * A stack of size 0x1000 is set up for each core in REGION stack_sec.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The unique core id is passed to the entry point functions.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return zero on success</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+size_t start_cpu(size_t cpu, void (* entry_64)(size_t core_id));</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%);">+ * Secondary ASM CPU entry point.</span><br><span style="color: hsl(120, 100%, 40%);">+ * For internal use only.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void secondary_init(void);</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%);">+ * Secondary CPU C entry point.</span><br><span style="color: hsl(120, 100%, 40%);">+ * For internal use only.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void secondary_cpu_init(size_t core_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Symbols in memlayout.ld */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern u8 _stack_sec[];</span><br><span style="color: hsl(120, 100%, 40%);">+extern u8 _estack_sec[];</span><br><span style="color: hsl(120, 100%, 40%);">+#define _stack_sec_size (_estack_sec - _stack_sec)</span><br><span> </span><br><span> #endif  /* __SOC_CAVIUM_CN81XX_CPU_H__ */</span><br><span>diff --git a/src/soc/cavium/cn81xx/include/soc/memlayout.ld b/src/soc/cavium/cn81xx/include/soc/memlayout.ld</span><br><span>index e4a71eb..96acb3f 100644</span><br><span>--- a/src/soc/cavium/cn81xx/include/soc/memlayout.ld</span><br><span>+++ b/src/soc/cavium/cn81xx/include/soc/memlayout.ld</span><br><span>@@ -38,6 +38,9 @@</span><br><span>   SRAM_END(BOOTROM_OFFSET + 0x80000)</span><br><span>   TTB(BOOTROM_OFFSET + 0x80000, 128K)</span><br><span>  RAMSTAGE(BOOTROM_OFFSET + 0xa0000, 512K)</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Stack for secondary CPUs */</span><br><span style="color: hsl(120, 100%, 40%);">+        REGION(stack_sec, BOOTROM_OFFSET + 0x120000,</span><br><span style="color: hsl(120, 100%, 40%);">+         CONFIG_MAX_CPUS * CONFIG_STACK_SIZE, 0x1000)</span><br><span> </span><br><span>      /* Leave some space for the payload */</span><br><span>       POSTRAM_CBFS_CACHE(0x2000000, 16M)</span><br><span>diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c</span><br><span>index 3471ce2..1c79226 100644</span><br><span>--- a/src/soc/cavium/cn81xx/soc.c</span><br><span>+++ b/src/soc/cavium/cn81xx/soc.c</span><br><span>@@ -83,9 +83,12 @@</span><br><span> }</span><br><span> </span><br><span> static struct device_operations soc_ops = {</span><br><span style="color: hsl(0, 100%, 40%);">-        .read_resources = soc_read_resources,</span><br><span style="color: hsl(0, 100%, 40%);">-   .init = soc_init,</span><br><span style="color: hsl(0, 100%, 40%);">-       .final = soc_final,</span><br><span style="color: hsl(120, 100%, 40%);">+   .read_resources   = soc_read_resources,</span><br><span style="color: hsl(120, 100%, 40%);">+       .set_resources    = DEVICE_NOOP,</span><br><span style="color: hsl(120, 100%, 40%);">+      .enable_resources = DEVICE_NOOP,</span><br><span style="color: hsl(120, 100%, 40%);">+      .init             = soc_init,</span><br><span style="color: hsl(120, 100%, 40%);">+ .final            = soc_final,</span><br><span style="color: hsl(120, 100%, 40%);">+        .scan_bus         = NULL,</span><br><span> };</span><br><span> </span><br><span> static void enable_soc_dev(device_t dev)</span><br><span>@@ -93,7 +96,8 @@</span><br><span>  if (dev->path.type == DEVICE_PATH_DOMAIN &&</span><br><span>               dev->path.domain.domain == 0) {</span><br><span>           dev->ops = &pci_domain_ops_ecam0;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)</span><br><span style="color: hsl(120, 100%, 40%);">+              dev->ops = &soc_ops;</span><br><span> }</span><br><span> </span><br><span> struct chip_operations soc_cavium_cn81xx_ops = {</span><br><span>diff --git a/src/soc/cavium/common/Makefile.inc b/src/soc/cavium/common/Makefile.inc</span><br><span>index 1c959e3..5e49755 100644</span><br><span>--- a/src/soc/cavium/common/Makefile.inc</span><br><span>+++ b/src/soc/cavium/common/Makefile.inc</span><br><span>@@ -15,7 +15,7 @@</span><br><span> </span><br><span> ifeq ($(CONFIG_SOC_CAVIUM_COMMON),y)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-CFLAGS_arm64   += -Wstack-usage=8192</span><br><span style="color: hsl(120, 100%, 40%);">+CFLAGS_arm64   += -Wstack-usage=$(CONFIG_STACK_SIZE)</span><br><span> </span><br><span> bootblock-$(CONFIG_BOOTBLOCK_CUSTOM) += bootblock.c</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25752">change 25752</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/25752"/><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: I07428161615bcd3d03a3eea0df2dd813e08c8f66 </div>
<div style="display:none"> Gerrit-Change-Number: 25752 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>