Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/aarch64 add MULTIPROCESSOR support
details: https://anonhg.NetBSD.org/src/rev/c6cea6b3b38f
branches: trunk
changeset: 363045:c6cea6b3b38f
user: ryo <ryo%NetBSD.org@localhost>
date: Mon Jul 09 06:19:53 2018 +0000
description:
add MULTIPROCESSOR support
diffstat:
sys/arch/aarch64/aarch64/cpu.c | 180 +++++++++++---
sys/arch/aarch64/aarch64/cpu_machdep.c | 38 +---
sys/arch/aarch64/aarch64/db_machdep.c | 123 +++++++++-
sys/arch/aarch64/aarch64/genassym.cf | 7 +-
sys/arch/aarch64/aarch64/locore.S | 376 ++++++++++++++++++++++++++------
sys/arch/aarch64/include/cpu.h | 14 +-
sys/arch/aarch64/include/locore.h | 7 +-
sys/arch/aarch64/include/machdep.h | 6 +-
8 files changed, 573 insertions(+), 178 deletions(-)
diffs (truncated from 1131 to 300 lines):
diff -r 0eab3c7fa136 -r c6cea6b3b38f sys/arch/aarch64/aarch64/cpu.c
--- a/sys/arch/aarch64/aarch64/cpu.c Mon Jul 09 06:14:38 2018 +0000
+++ b/sys/arch/aarch64/aarch64/cpu.c Mon Jul 09 06:19:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.1 2018/04/01 04:35:03 ryo Exp $ */
+/* $NetBSD: cpu.c,v 1.2 2018/07/09 06:19:53 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,13 +27,16 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.1 2018/04/01 04:35:03 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.2 2018/07/09 06:19:53 ryo Exp $");
#include "locators.h"
+#include "opt_arm_debug.h"
+#include "opt_fdt.h"
#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/atomic.h>
#include <sys/device.h>
#include <sys/cpu.h>
#include <sys/kmem.h>
@@ -43,71 +46,106 @@
#include <aarch64/cpufunc.h>
#include <aarch64/machdep.h>
+#ifdef FDT
+#include <arm/fdt/arm_fdtvar.h>
+#endif
+
void cpu_attach(device_t, cpuid_t);
-static void cpu_identify(device_t self, struct cpu_info *);
+static void identify_aarch64_model(uint32_t, char *, size_t);
+static void cpu_identify(device_t self, struct cpu_info *, uint32_t, uint64_t);
+static void cpu_identify1(device_t self, struct cpu_info *);
static void cpu_identify2(device_t self, struct cpu_info *);
+#ifdef MULTIPROCESSOR
+volatile u_int arm_cpu_hatched __cacheline_aligned = 0;
+volatile uint32_t arm_cpu_mbox __cacheline_aligned = 0;
+u_int arm_cpu_max = 1;
+
+/* stored by secondary processors (available when arm_cpu_hatched) */
+uint32_t cpus_midr[MAXCPUS];
+uint64_t cpus_mpidr[MAXCPUS];
+
+static kmutex_t cpu_hatch_lock;
+#endif /* MULTIPROCESSOR */
+
+/* Our exported CPU info; we can have only one. */
+struct cpu_info cpu_info_store __cacheline_aligned = {
+ .ci_cpl = IPL_HIGH,
+ .ci_curlwp = &lwp0
+};
+
+#ifdef MULTIPROCESSOR
+#define NCPUINFO MAXCPUS
+#else
+#define NCPUINFO 1
+#endif /* MULTIPROCESSOR */
+
+struct cpu_info *cpu_info[NCPUINFO] = {
+ [0] = &cpu_info_store
+};
+
void
cpu_attach(device_t dv, cpuid_t id)
{
struct cpu_info *ci;
+ uint64_t mpidr;
+ uint32_t midr;
if (id == 0) {
ci = curcpu();
-
+ midr = reg_midr_el1_read();
+ mpidr = reg_mpidr_el1_read();
} else {
#ifdef MULTIPROCESSOR
- //XXXAARCH64: notyet?
-
- uint64_t mpidr = reg_mpidr_el1_read();
-
KASSERT(cpu_info[id] == NULL);
ci = kmem_zalloc(sizeof(*ci), KM_SLEEP);
ci->ci_cpl = IPL_HIGH;
ci->ci_cpuid = id;
- if (mpidr & MPIDR_MT) {
- ci->ci_data.cpu_smt_id = mpidr & MPIDR_AFF0;
- ci->ci_data.cpu_core_id = mpidr & MPIDR_AFF1;
- ci->ci_data.cpu_package_id = mpidr & MPIDR_AFF2;
- } else {
- ci->ci_data.cpu_core_id = mpidr & MPIDR_AFF0;
- ci->ci_data.cpu_package_id = mpidr & MPIDR_AFF1;
- }
- ci->ci_data.cpu_cc_freq = cpu_info_store.ci_data.cpu_cc_freq;
+
+ ci->ci_data.cpu_cc_freq = cpu_info[0]->ci_data.cpu_cc_freq;
cpu_info[ci->ci_cpuid] = ci;
if ((arm_cpu_hatched & (1 << id)) == 0) {
ci->ci_dev = dv;
dv->dv_private = ci;
aprint_naive(": disabled\n");
- aprint_normal(": disabled (uniprocessor kernel)\n");
+ aprint_normal(": disabled (unresponsive)\n");
return;
}
-#else
+
+ /* cpus_{midr,mpidr}[id] is stored by secondary processor */
+ midr = cpus_midr[id];
+ mpidr = cpus_mpidr[id];
+#else /* MULTIPROCESSOR */
aprint_naive(": disabled\n");
aprint_normal(": disabled (uniprocessor kernel)\n");
return;
-#endif
+#endif /* MULTIPROCESSOR */
+ }
+
+ if (mpidr & MPIDR_MT) {
+ ci->ci_data.cpu_smt_id = mpidr & MPIDR_AFF0;
+ ci->ci_data.cpu_core_id = mpidr & MPIDR_AFF1;
+ ci->ci_data.cpu_package_id = mpidr & MPIDR_AFF2;
+ } else {
+ ci->ci_data.cpu_core_id = mpidr & MPIDR_AFF0;
+ ci->ci_data.cpu_package_id = mpidr & MPIDR_AFF1;
}
ci->ci_dev = dv;
dv->dv_private = ci;
+ cpu_identify(ci->ci_dev, ci, midr, mpidr);
#ifdef MULTIPROCESSOR
- if (caa->caa_cpucore != 0) {
- aprint_naive("\n");
- aprint_normal(": %s\n", cpu_getmodel());
+ if (id != 0) {
mi_cpu_attach(ci);
-
- // XXXAARCH64
- //pmap_tlb_info_attach();
- panic("notyet");
+ return;
}
-#endif
+#endif /* MULTIPROCESSOR */
fpu_attach(ci);
- cpu_identify(dv, ci);
+ cpu_identify1(dv, ci);
cpu_identify2(dv, ci);
}
@@ -224,30 +262,25 @@
}
static void
-cpu_identify(device_t self, struct cpu_info *ci)
+cpu_identify(device_t self, struct cpu_info *ci, uint32_t midr, uint64_t mpidr)
{
- uint64_t mpidr;
- int level;
- uint32_t cpuid;
- uint32_t ctr, sctlr; /* for cache */
char model[128];
- cpuid = reg_midr_el1_read();
- identify_aarch64_model(cpuid, model, sizeof(model));
+ identify_aarch64_model(midr, model, sizeof(model));
if (ci->ci_cpuid == 0)
cpu_setmodel("%s", model);
aprint_naive("\n");
aprint_normal(": %s\n", model);
-
+ aprint_normal_dev(ci->ci_dev, "package %lu, core %lu, smt %lu\n",
+ ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id);
+}
- mpidr = reg_mpidr_el1_read();
- aprint_normal_dev(self, "CPU Affinity %llu-%llu-%llu-%llu\n",
- __SHIFTOUT(mpidr, MPIDR_AFF3),
- __SHIFTOUT(mpidr, MPIDR_AFF2),
- __SHIFTOUT(mpidr, MPIDR_AFF1),
- __SHIFTOUT(mpidr, MPIDR_AFF0));
-
+static void
+cpu_identify1(device_t self, struct cpu_info *ci)
+{
+ int level;
+ uint32_t ctr, sctlr; /* for cache */
/* SCTLR - System Control Register */
sctlr = reg_sctlr_el1_read();
@@ -448,3 +481,62 @@
aprint_normal("\n");
}
+
+#ifdef MULTIPROCESSOR
+void
+cpu_boot_secondary_processors(void)
+{
+ mutex_init(&cpu_hatch_lock, MUTEX_DEFAULT, IPL_NONE);
+
+#ifdef VERBOSE_INIT_ARM
+ printf("%s: writing mbox with %#x\n", __func__, arm_cpu_hatched);
+#endif
+
+ /* send mbox to have secondary processors do cpu_hatch() */
+ atomic_or_32(&arm_cpu_mbox, arm_cpu_hatched);
+ __asm __volatile ("sev; sev; sev");
+
+ /* wait all cpus have done cpu_hatch() */
+ while (arm_cpu_mbox) {
+ __asm __volatile ("wfe");
+ }
+
+#ifdef VERBOSE_INIT_ARM
+ printf("%s: secondary processors hatched\n", __func__);
+#endif
+
+ /* add available processors to kcpuset */
+ uint32_t mbox = arm_cpu_hatched;
+ kcpuset_export_u32(kcpuset_attached, &mbox, sizeof(mbox));
+}
+
+void
+cpu_hatch(struct cpu_info *ci)
+{
+ KASSERT(curcpu() == ci);
+
+ delay(1000 * ci->ci_index); /* XXX: to attach cpu* in order */
+
+ mutex_enter(&cpu_hatch_lock);
+
+ fpu_attach(ci);
+
+ cpu_identify1(ci->ci_dev, ci);
+ cpu_identify2(ci->ci_dev, ci);
+
+ mutex_exit(&cpu_hatch_lock);
+
+ intr_cpu_init(ci);
+
+#ifdef FDT
+ arm_fdt_cpu_hatch(ci);
+#endif
+#ifdef MD_CPU_HATCH
+ MD_CPU_HATCH(ci); /* for non-fdt arch? */
+#endif
+
+ /* clear my bit of arm_cpu_mbox to tell cpu_boot_secondary_processors() */
+ atomic_and_32(&arm_cpu_mbox, ~(1 << ci->ci_cpuid));
+ __asm __volatile ("sev; sev; sev");
+}
+#endif /* MULTIPROCESSOR */
diff -r 0eab3c7fa136 -r c6cea6b3b38f sys/arch/aarch64/aarch64/cpu_machdep.c
--- a/sys/arch/aarch64/aarch64/cpu_machdep.c Mon Jul 09 06:14:38 2018 +0000
+++ b/sys/arch/aarch64/aarch64/cpu_machdep.c Mon Jul 09 06:19:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_machdep.c,v 1.3 2018/04/01 04:35:03 ryo Exp $ */
+/* $NetBSD: cpu_machdep.c,v 1.4 2018/07/09 06:19:53 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cpu_machdep.c,v 1.3 2018/04/01 04:35:03 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu_machdep.c,v 1.4 2018/07/09 06:19:53 ryo Exp $");
#include "opt_multiprocessor.h"
@@ -52,30 +52,6 @@
#include <aarch64/pcb.h>
#include <aarch64/userret.h>
-#ifdef MULTIPROCESSOR
-/* for arm compatibility (referred from pic.c) */
-volatile u_int arm_cpu_hatched;
-u_int arm_cpu_max = 1;
-#endif
-
-/* Our exported CPU info; we can have only one. */
-struct cpu_info cpu_info_store __cacheline_aligned = {
- .ci_cpl = IPL_HIGH,
- .ci_curlwp = &lwp0
-};
-
-#ifdef MULTIPROCESSOR
Home |
Main Index |
Thread Index |
Old Index