From 7a7b3facec2391d8ffc981044ee73f8b0449c6be Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 12 Jan 2018 22:20:28 +0000 Subject: [PATCH] Add MULTIPROCESSOR basics for arm64. Enough to build and run a kernel with option MULTIPROCESSOR on a single CPU. ok patrick@ --- sys/arch/arm64/arm64/cpu.c | 11 ++++++++++- sys/arch/arm64/arm64/syscall.c | 4 +++- sys/arch/arm64/arm64/trap.c | 18 +++++++++++++++++- sys/arch/arm64/dev/agintc.c | 20 +++++++++++++++++++- sys/arch/arm64/dev/ampintc.c | 20 +++++++++++++++++++- sys/arch/arm64/dev/bcm2836_intr.c | 24 +++++++++++++++++++++--- sys/arch/arm64/include/cpu.h | 6 +++++- 7 files changed, 94 insertions(+), 9 deletions(-) diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index 73ec87d00d3..fbfe46152f1 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.9 2017/12/29 14:45:15 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.10 2018/01/12 22:20:28 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -92,6 +92,8 @@ const struct implementers { char cpu_model[64]; int cpu_node; +struct cpu_info *cpu_info_list = &cpu_info_primary; + int cpu_match(struct device *, void *, void *); void cpu_attach(struct device *, struct device *, void *); @@ -198,3 +200,10 @@ cpu_clockspeed(int *freq) } int (*cpu_on_fn)(register_t, register_t); + +#ifdef MULTIPROCESSOR +void +cpu_boot_secondary_processors(void) +{ +} +#endif diff --git a/sys/arch/arm64/arm64/syscall.c b/sys/arch/arm64/arm64/syscall.c index a497cd74e74..6e20b2b9968 100644 --- a/sys/arch/arm64/arm64/syscall.c +++ b/sys/arch/arm64/arm64/syscall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.c,v 1.1 2016/12/17 23:38:33 patrick Exp $ */ +/* $OpenBSD: syscall.c,v 1.2 2018/01/12 22:20:28 kettenis Exp $ */ /* * Copyright (c) 2015 Dale Rahn * @@ -130,5 +130,7 @@ child_return(arg) frame->tf_x[1] = 1; frame->tf_spsr &= ~PSR_C; /* carry bit */ + KERNEL_UNLOCK(); + mi_child_return(p); } diff --git a/sys/arch/arm64/arm64/trap.c b/sys/arch/arm64/arm64/trap.c index 01c3c92114f..6ba244f9da9 100644 --- a/sys/arch/arm64/arm64/trap.c +++ b/sys/arch/arm64/arm64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.13 2017/12/24 10:32:25 kettenis Exp $ */ +/* $OpenBSD: trap.c,v 1.14 2018/01/12 22:20:28 kettenis Exp $ */ /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. @@ -173,7 +173,9 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) /* Fault in the user page: */ if (!pmap_fault_fixup(map->pmap, va, access_type, 1)) { + KERNEL_LOCK(); error = uvm_fault(map, va, ftype, access_type); + KERNEL_UNLOCK(); } //PROC_LOCK(p); @@ -185,7 +187,9 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) * kernel. */ if (!pmap_fault_fixup(map->pmap, va, access_type, 0)) { + KERNEL_LOCK(); error = uvm_fault(map, va, ftype, access_type); + KERNEL_UNLOCK(); } } @@ -206,7 +210,9 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower, int exe) } sv.sival_ptr = (u_int64_t *)far; + KERNEL_LOCK(); trapsignal(p, sig, 0, code, sv); + KERNEL_UNLOCK(); } else { if (curcpu()->ci_idepth == 0 && pcb->pcb_onfault != 0) { @@ -293,7 +299,9 @@ do_el0_sync(struct trapframe *frame) case EXCP_UNKNOWN: vfp_save(); sv.sival_ptr = (void *)frame->tf_elr; + KERNEL_LOCK(); trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); + KERNEL_UNLOCK(); break; case EXCP_FP_SIMD: case EXCP_TRAP_FP: @@ -310,12 +318,16 @@ do_el0_sync(struct trapframe *frame) case EXCP_PC_ALIGN: vfp_save(); sv.sival_ptr = (void *)frame->tf_elr; + KERNEL_LOCK(); trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv); + KERNEL_UNLOCK(); break; case EXCP_SP_ALIGN: vfp_save(); sv.sival_ptr = (void *)frame->tf_sp; + KERNEL_LOCK(); trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv); + KERNEL_UNLOCK(); break; case EXCP_DATA_ABORT_L: vfp_save(); @@ -324,7 +336,9 @@ do_el0_sync(struct trapframe *frame) case EXCP_BRK: vfp_save(); sv.sival_ptr = (void *)frame->tf_elr; + KERNEL_LOCK(); trapsignal(p, SIGTRAP, 0, TRAP_BRKPT, sv); + KERNEL_UNLOCK(); break; default: // panic("Unknown userland exception %x esr_el1 %lx\n", exception, @@ -335,7 +349,9 @@ do_el0_sync(struct trapframe *frame) printf("exception %x esr_el1 %llx\n", exception, esr); dumpregs(frame); } + KERNEL_LOCK(); sigexit(p, SIGILL); + KERNEL_UNLOCK(); } userret(p); diff --git a/sys/arch/arm64/dev/agintc.c b/sys/arch/arm64/dev/agintc.c index ef581bb783f..ac09e1e69b4 100644 --- a/sys/arch/arm64/dev/agintc.c +++ b/sys/arch/arm64/dev/agintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agintc.c,v 1.5 2017/08/09 05:53:11 jsg Exp $ */ +/* $OpenBSD: agintc.c,v 1.6 2018/01/12 22:20:28 kettenis Exp $ */ /* * Copyright (c) 2007, 2009, 2011, 2017 Dale Rahn * @@ -138,6 +138,7 @@ struct intrhand { int (*ih_func)(void *); /* handler */ void *ih_arg; /* arg for handler */ int ih_ipl; /* IPL_* */ + int ih_flags; int ih_irq; /* IRQ number */ struct evcount ih_count; char *ih_name; @@ -637,6 +638,18 @@ agintc_irq_handler(void *frame) pri = sc->sc_agintc_handler[irq].iq_irq; s = agintc_splraise(pri); TAILQ_FOREACH(ih, &sc->sc_agintc_handler[irq].iq_list, ih_list) { +#ifdef MULTIPROCESSOR + int need_lock; + + if (ih->ih_flags & IPL_MPSAFE) + need_lock = 0; + else + need_lock = s < IPL_SCHED; + + if (need_lock) + KERNEL_LOCK(); +#endif + if (ih->ih_arg != 0) arg = ih->ih_arg; else @@ -648,6 +661,10 @@ agintc_irq_handler(void *frame) if (handled) ih->ih_count.ec_count++; +#ifdef MULTIPROCESSOR + if (need_lock) + KERNEL_UNLOCK(); +#endif } agintc_eoi(irq); @@ -692,6 +709,7 @@ agintc_intr_establish(int irqno, int level, int (*func)(void *), ih->ih_func = func; ih->ih_arg = arg; ih->ih_ipl = level; + ih->ih_flags = 0; ih->ih_irq = irqno; ih->ih_name = name; diff --git a/sys/arch/arm64/dev/ampintc.c b/sys/arch/arm64/dev/ampintc.c index 7bf7add2b6a..62bb06c3a35 100644 --- a/sys/arch/arm64/dev/ampintc.c +++ b/sys/arch/arm64/dev/ampintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ampintc.c,v 1.10 2018/01/12 14:53:37 kettenis Exp $ */ +/* $OpenBSD: ampintc.c,v 1.11 2018/01/12 22:20:28 kettenis Exp $ */ /* * Copyright (c) 2007,2009,2011 Dale Rahn * @@ -150,6 +150,7 @@ struct intrhand { int (*ih_func)(void *); /* handler */ void *ih_arg; /* arg for handler */ int ih_ipl; /* IPL_* */ + int ih_flags; int ih_irq; /* IRQ number */ struct evcount ih_count; char *ih_name; @@ -536,6 +537,18 @@ ampintc_irq_handler(void *frame) pri = sc->sc_ampintc_handler[irq].iq_irq; s = ampintc_splraise(pri); TAILQ_FOREACH(ih, &sc->sc_ampintc_handler[irq].iq_list, ih_list) { +#ifdef MULTIPROCESSOR + int need_lock; + + if (ih->ih_flags & IPL_MPSAFE) + need_lock = 0; + else + need_lock = s < IPL_SCHED; + + if (need_lock) + KERNEL_LOCK(); +#endif + if (ih->ih_arg != 0) arg = ih->ih_arg; else @@ -544,6 +557,10 @@ ampintc_irq_handler(void *frame) if (ih->ih_func(arg)) ih->ih_count.ec_count++; +#ifdef MULTIPROCESSOR + if (need_lock) + KERNEL_UNLOCK(); +#endif } ampintc_eoi(iack_val); @@ -601,6 +618,7 @@ ampintc_intr_establish(int irqno, int type, int level, int (*func)(void *), ih->ih_func = func; ih->ih_arg = arg; ih->ih_ipl = level; + ih->ih_flags = 0; ih->ih_irq = irqno; ih->ih_name = name; diff --git a/sys/arch/arm64/dev/bcm2836_intr.c b/sys/arch/arm64/dev/bcm2836_intr.c index f106b78c523..cc68af5c067 100644 --- a/sys/arch/arm64/dev/bcm2836_intr.c +++ b/sys/arch/arm64/dev/bcm2836_intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcm2836_intr.c,v 1.3 2017/04/30 16:45:45 mpi Exp $ */ +/* $OpenBSD: bcm2836_intr.c,v 1.4 2018/01/12 22:20:28 kettenis Exp $ */ /* * Copyright (c) 2007,2009 Dale Rahn * Copyright (c) 2015 Patrick Wildt @@ -79,9 +79,10 @@ struct intrhand { int (*ih_fun)(void *); /* handler */ void *ih_arg; /* arg for handler */ int ih_ipl; /* IPL_* */ + int ih_flags; int ih_irq; /* IRQ number */ - struct evcount ih_count; /* interrupt counter */ - char *ih_name; /* device name */ + struct evcount ih_count; + char *ih_name; }; struct intrsource { @@ -450,6 +451,18 @@ bcm_intc_call_handler(int irq, void *frame) pri = sc->sc_bcm_intc_handler[irq].is_irq; s = bcm_intc_splraise(pri); TAILQ_FOREACH(ih, &sc->sc_bcm_intc_handler[irq].is_list, ih_list) { +#ifdef MULTIPROCESSOR + int need_lock; + + if (ih->ih_flags & IPL_MPSAFE) + need_lock = 0; + else + need_lock = s < IPL_SCHED; + + if (need_lock) + KERNEL_LOCK(); +#endif + if (ih->ih_arg != 0) arg = ih->ih_arg; else @@ -458,6 +471,10 @@ bcm_intc_call_handler(int irq, void *frame) if (ih->ih_fun(arg)) ih->ih_count.ec_count++; +#ifdef MULTIPROCESSOR + if (need_lock) + KERNEL_UNLOCK(); +#endif } bcm_intc_splx(s); @@ -521,6 +538,7 @@ bcm_intc_intr_establish(int irqno, int level, int (*func)(void *), ih->ih_fun = func; ih->ih_arg = arg; ih->ih_ipl = level; + ih->ih_flags = 0; ih->ih_irq = irqno; ih->ih_name = name; diff --git a/sys/arch/arm64/include/cpu.h b/sys/arch/arm64/include/cpu.h index 2f31ce8d71d..c425e027cca 100644 --- a/sys/arch/arm64/include/cpu.h +++ b/sys/arch/arm64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.3 2018/01/05 17:42:35 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.4 2018/01/12 22:20:28 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn * @@ -100,6 +100,10 @@ struct cpu_info { #endif int ci_want_resched; +#ifdef MULTIPROCESSOR + struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; +#endif + #ifdef GPROF struct gmonparam *ci_gmon; #endif -- 2.20.1