Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/riscv risc-v: MULTIPROCESSOR support
details: https://anonhg.NetBSD.org/src/rev/bfc499a2c3fc
branches: trunk
changeset: 376349:bfc499a2c3fc
user: skrll <skrll%NetBSD.org@localhost>
date: Mon Jun 12 19:04:13 2023 +0000
description:
risc-v: MULTIPROCESSOR support
Add MULTIPROCESSOR support for RISC-V, but leave disabled for the moment
as it's not 100% stable.
Some other improvements to spl and cpu identification / reporting.
diffstat:
sys/arch/riscv/conf/files.riscv | 4 +-
sys/arch/riscv/fdt/cpu_fdt.c | 158 +++++++++++++-
sys/arch/riscv/fdt/intc_fdt.c | 69 +++--
sys/arch/riscv/fdt/riscv_fdtvar.h | 41 +++
sys/arch/riscv/fdt/riscv_platform.c | 14 +-
sys/arch/riscv/include/cpu.h | 100 ++++++++-
sys/arch/riscv/include/db_machdep.h | 7 +-
sys/arch/riscv/include/intr.h | 8 +-
sys/arch/riscv/include/machdep.h | 9 +-
sys/arch/riscv/include/pmap.h | 30 +-
sys/arch/riscv/riscv/clock_machdep.c | 23 +-
sys/arch/riscv/riscv/cpu.c | 133 ++++++++++-
sys/arch/riscv/riscv/cpu_subr.c | 404 ++++++++++++++++++++++++++++++++++-
sys/arch/riscv/riscv/db_interface.c | 13 +-
sys/arch/riscv/riscv/db_machdep.c | 5 +-
sys/arch/riscv/riscv/genassym.cf | 8 +-
sys/arch/riscv/riscv/interrupt.c | 63 +++++-
sys/arch/riscv/riscv/ipifuncs.c | 168 ++++++++++++++
sys/arch/riscv/riscv/locore.S | 244 +++++++++++++++++---
sys/arch/riscv/riscv/pmap_machdep.c | 105 +-------
sys/arch/riscv/riscv/riscv_machdep.c | 43 +++-
sys/arch/riscv/riscv/riscv_tlb.c | 127 +++++++++++
sys/arch/riscv/riscv/spl.S | 59 ++--
23 files changed, 1574 insertions(+), 261 deletions(-)
diffs (truncated from 2656 to 300 lines):
diff -r 802297a920a1 -r bfc499a2c3fc sys/arch/riscv/conf/files.riscv
--- a/sys/arch/riscv/conf/files.riscv Mon Jun 12 18:59:57 2023 +0000
+++ b/sys/arch/riscv/conf/files.riscv Mon Jun 12 19:04:13 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.riscv,v 1.12 2023/05/07 12:41:48 skrll Exp $
+# $NetBSD: files.riscv,v 1.13 2023/06/12 19:04:13 skrll Exp $
#
maxpartitions 16
@@ -43,6 +43,7 @@ file arch/riscv/riscv/kobj_machdep.c mo
file arch/riscv/riscv/pmap_machdep.c
file arch/riscv/riscv/process_machdep.c
file arch/riscv/riscv/procfs_machdep.c procfs
+file arch/riscv/riscv/riscv_tlb.c
file arch/riscv/riscv/riscv_generic_dma.c
file arch/riscv/riscv/riscv_machdep.c
file arch/riscv/riscv/sbi.c # SBI
@@ -63,6 +64,7 @@ file kern/subr_disk_mbr.c disk
file uvm/pmap/pmap.c
file uvm/pmap/pmap_devmap.c
file uvm/pmap/pmap_segtab.c
+file uvm/pmap/pmap_synci.c
file uvm/pmap/pmap_tlb.c
device plic
diff -r 802297a920a1 -r bfc499a2c3fc sys/arch/riscv/fdt/cpu_fdt.c
--- a/sys/arch/riscv/fdt/cpu_fdt.c Mon Jun 12 18:59:57 2023 +0000
+++ b/sys/arch/riscv/fdt/cpu_fdt.c Mon Jun 12 19:04:13 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_fdt.c,v 1.1 2023/05/07 12:41:48 skrll Exp $ */
+/* $NetBSD: cpu_fdt.c,v 1.2 2023/06/12 19:04:13 skrll Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -29,13 +29,167 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.1 2023/05/07 12:41:48 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v 1.2 2023/06/12 19:04:13 skrll Exp $");
#include <sys/param.h>
+#include <sys/cpu.h>
#include <dev/fdt/fdtvar.h>
+#include <riscv/cpufunc.h>
#include <riscv/cpuvar.h>
+#include <riscv/machdep.h>
+#include <riscv/sbi.h>
+
+#include <riscv/fdt/riscv_fdtvar.h>
+
+
+#ifdef MULTIPROCESSOR
+static bool
+riscv_fdt_cpu_okay(const int child)
+{
+ const char *s;
+
+ s = fdtbus_get_string(child, "device_type");
+ if (!s || strcmp(s, "cpu") != 0)
+ return false;
+
+ s = fdtbus_get_string(child, "status");
+ if (s) {
+ if (strcmp(s, "okay") == 0)
+ return true;
+ if (strcmp(s, "disabled") == 0)
+ return false;
+ return false;
+ } else {
+ return true;
+ }
+}
+#endif /* MULTIPROCESSOR */
+
+void
+riscv_fdt_cpu_bootstrap(void)
+{
+#ifdef MULTIPROCESSOR
+
+ const int cpus = OF_finddevice("/cpus");
+ if (cpus == -1) {
+ aprint_error("%s: no /cpus node found\n", __func__);
+ riscv_cpu_max = 1;
+ return;
+ }
+
+ /* Count harts and add hart IDs to to cpu_hartid array */
+ size_t cpuindex = 1;
+ for (int child = OF_child(cpus); child; child = OF_peer(child)) {
+ if (!riscv_fdt_cpu_okay(child))
+ continue;
+
+ riscv_cpu_max++;
+
+ uint64_t reg;
+ if (fdtbus_get_reg64(child, 0, ®, NULL) != 0)
+ continue;
+
+ const cpuid_t hartid = reg;
+
+ struct sbiret sbiret = sbi_hart_get_status(hartid);
+ switch (sbiret.error) {
+ case SBI_ERR_INVALID_PARAM:
+ aprint_error("Unknown hart id %lx", hartid);
+ continue;
+ case SBI_SUCCESS:
+ break;
+ default:
+ aprint_error("Unexpected error (%ld) from get_status",
+ sbiret.error);
+ }
+
+ /* Assume the BP is the only one started. */
+ if (sbiret.value == SBI_HART_STARTED) {
+ if (cpu_hartid[0] != -1) {
+ panic("more than 1 hart started");
+ }
+ cpu_hartid[0] = hartid;
+ continue;
+ }
+
+ KASSERT(cpuindex < MAXCPUS);
+ cpu_hartid[cpuindex] = hartid;
+ cpu_dcache_wb_range((vaddr_t)&cpu_hartid[cpuindex],
+ sizeof(cpu_hartid[cpuindex]));
+
+ cpuindex++;
+ }
+#endif
+}
+int
+riscv_fdt_cpu_mpstart(void)
+{
+ int ret = 0;
+#ifdef MULTIPROCESSOR
+ const int cpus = OF_finddevice("/cpus");
+ if (cpus == -1) {
+ aprint_error("%s: no /cpus node found\n", __func__);
+ return 0;
+ }
+
+ // riscv_fdt_cpu_bootstrap put the boot hart id in cpu_hartid[0]
+ const cpuid_t bp_hartid = cpu_hartid[0];
+
+ /* BootAPs */
+ size_t cpuindex = 1;
+ for (int child = OF_child(cpus); child; child = OF_peer(child)) {
+ if (!riscv_fdt_cpu_okay(child))
+ continue;
+
+ uint64_t reg;
+ if (fdtbus_get_reg64(child, 0, ®, NULL) != 0)
+ continue;
+
+ cpuid_t hartid = reg;
+
+ if (hartid == bp_hartid)
+ continue; /* BP already started */
+
+ const paddr_t entry = KERN_VTOPHYS(cpu_mpstart);
+ struct sbiret sbiret = sbi_hart_start(hartid, entry, 0);
+ switch (sbiret.error) {
+ case SBI_SUCCESS:
+ break;
+ case SBI_ERR_INVALID_ADDRESS:
+ break;
+ case SBI_ERR_INVALID_PARAM:
+ break;
+ case SBI_ERR_ALREADY_AVAILABLE:
+ break;
+ case SBI_ERR_FAILED:
+ break;
+ default:
+ aprint_error("%s: failed to enable CPU %#lx\n",
+ __func__, hartid);
+ }
+
+ size_t i;
+ /* Wait for AP to start */
+ for (i = 0x10000000; i > 0; i--) {
+ if (cpu_hatched_p(cpuindex))
+ break;
+ }
+
+ if (i == 0) {
+ ret++;
+ aprint_error("cpu%zu: WARNING: AP failed to start\n",
+ cpuindex);
+ }
+
+ cpuindex++;
+ }
+#else
+ aprint_normal("%s: kernel compiled without MULTIPROCESSOR\n", __func__);
+#endif /* MULTIPROCESSOR */
+ return ret;
+}
static int
cpu_fdt_match(device_t parent, cfdata_t cf, void *aux)
diff -r 802297a920a1 -r bfc499a2c3fc sys/arch/riscv/fdt/intc_fdt.c
--- a/sys/arch/riscv/fdt/intc_fdt.c Mon Jun 12 18:59:57 2023 +0000
+++ b/sys/arch/riscv/fdt/intc_fdt.c Mon Jun 12 19:04:13 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intc_fdt.c,v 1.1 2023/05/07 12:41:48 skrll Exp $ */
+/* $NetBSD: intc_fdt.c,v 1.2 2023/06/12 19:04:13 skrll Exp $ */
/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_multiprocessor.h"
+
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intc_fdt.c,v 1.1 2023/05/07 12:41:48 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intc_fdt.c,v 1.2 2023/06/12 19:04:13 skrll Exp $");
#include <sys/param.h>
@@ -237,42 +239,59 @@ static void
intc_intr_handler(struct trapframe *tf, register_t epc, register_t status,
register_t cause)
{
+ const int ppl = splhigh();
struct cpu_info * const ci = curcpu();
- const int source = CAUSE_CODE(cause);
+ unsigned long pending;
+ int ipl;
KASSERT(CAUSE_INTERRUPT_P(cause));
struct intc_fdt_softc * const sc = intc_sc;
ci->ci_intr_depth++;
- struct intc_irq *irq = sc->sc_irq[source];
- KASSERTMSG(irq != NULL, "source %d\n", source);
- if (irq) {
- struct intc_irqhandler *iih;
+ ci->ci_data.cpu_nintr++;
+
+ while (ppl < (ipl = splintr(&pending))) {
+ if (pending == 0)
+ continue;
- bool mpsafe = (irq->intr_istflags & IST_MPSAFE) != 0;
- struct clockframe cf = {
- .cf_epc = epc,
- .cf_status = status,
- .cf_intr_depth = ci->ci_intr_depth
- };
+ splx(ipl);
+
+ int source = ffs(pending) - 1;
+ struct intc_irq *irq = sc->sc_irq[source];
+ KASSERTMSG(irq != NULL, "source %d\n", source);
+
+ if (irq) {
+ struct intc_irqhandler *iih;
- if (!mpsafe) {
- KERNEL_LOCK(1, NULL);
- }
+ bool mpsafe =
+ source != IRQ_SUPERVISOR_EXTERNAL ||
+ (irq->intr_istflags & IST_MPSAFE) != 0;
+ struct clockframe cf = {
+ .cf_epc = epc,
+ .cf_status = status,
+ .cf_intr_depth = ci->ci_intr_depth
+ };
+
+ if (!mpsafe) {
+ KERNEL_LOCK(1, NULL);
+ }
- TAILQ_FOREACH(iih, &irq->intr_handlers, ih_next) {
- int handled =
- iih->ih_fn(iih->ih_arg ? iih->ih_arg : &cf);
- if (handled)
- break;
+ TAILQ_FOREACH(iih, &irq->intr_handlers, ih_next) {
+ int handled =
+ iih->ih_fn(iih->ih_arg ? iih->ih_arg : &cf);
+ if (handled)
+ break;
+ }
+
+ if (!mpsafe) {
+ KERNEL_UNLOCK_ONE(NULL);
+ }
}
-
- if (!mpsafe) {
- KERNEL_UNLOCK_ONE(NULL);
- }
Home |
Main Index |
Thread Index |
Old Index