summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2018-01-12 22:20:29 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2018-01-12 22:20:29 +0000
commitab5739f17cf2ce7b7473226afd323b1b002cb951 (patch)
tree151b85733958f39c45fbf3685d44bd20cd73d409
parent666bc0914e210ef7d6b0f620451c2b78722bb517 (diff)
Add MULTIPROCESSOR basics for arm64. Enough to build and run a kernel with
option MULTIPROCESSOR on a single CPU. ok patrick@
-rw-r--r--sys/arch/arm64/arm64/cpu.c11
-rw-r--r--sys/arch/arm64/arm64/syscall.c4
-rw-r--r--sys/arch/arm64/arm64/trap.c18
-rw-r--r--sys/arch/arm64/dev/agintc.c20
-rw-r--r--sys/arch/arm64/dev/ampintc.c20
-rw-r--r--sys/arch/arm64/dev/bcm2836_intr.c24
-rw-r--r--sys/arch/arm64/include/cpu.h6
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 <drahn@dalerahn.com>
@@ -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 <drahn@dalerahn.com>
*
@@ -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 <drahn@dalerahn.com>
*
@@ -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 <drahn@openbsd.org>
*
@@ -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 <drahn@openbsd.org>
* Copyright (c) 2015 Patrick Wildt <patrick@blueri.se>
@@ -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 <drahn@dalerahn.com>
*
@@ -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