smp basics for arm64

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

smp basics for arm64

Mark Kettenis
Diff below adds the necessary bits to build and run a GENERIC.MP
kernel on a single CPU.  It doesn't actually add the GENERIC.MP config
file yet; that would be a bit premature.

Most bits taken from Dale's SMP series.  His diff did disable one of
the KERNEL_LOCK/UNLOCK pairs I'm adding here to make things actually
work when running on multiple CPUs.  I'll keep that in the back of my
mind.

ok?


Index: arch/arm64/arm64/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v
retrieving revision 1.9
diff -u -p -r1.9 cpu.c
--- arch/arm64/arm64/cpu.c 29 Dec 2017 14:45:15 -0000 1.9
+++ arch/arm64/arm64/cpu.c 12 Jan 2018 19:50:17 -0000
@@ -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
Index: arch/arm64/arm64/syscall.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/syscall.c,v
retrieving revision 1.1
diff -u -p -r1.1 syscall.c
--- arch/arm64/arm64/syscall.c 17 Dec 2016 23:38:33 -0000 1.1
+++ arch/arm64/arm64/syscall.c 12 Jan 2018 19:50:17 -0000
@@ -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);
 }
Index: arch/arm64/arm64/trap.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/trap.c,v
retrieving revision 1.13
diff -u -p -r1.13 trap.c
--- arch/arm64/arm64/trap.c 24 Dec 2017 10:32:25 -0000 1.13
+++ arch/arm64/arm64/trap.c 12 Jan 2018 19:50:17 -0000
@@ -173,7 +173,9 @@ data_abort(struct trapframe *frame, uint
 
  /* 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, uint
  * 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, uint
  }
  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);
Index: arch/arm64/dev/agintc.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/dev/agintc.c,v
retrieving revision 1.5
diff -u -p -r1.5 agintc.c
--- arch/arm64/dev/agintc.c 9 Aug 2017 05:53:11 -0000 1.5
+++ arch/arm64/dev/agintc.c 12 Jan 2018 19:50:17 -0000
@@ -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 lev
  ih->ih_func = func;
  ih->ih_arg = arg;
  ih->ih_ipl = level;
+ ih->ih_flags = 0;
  ih->ih_irq = irqno;
  ih->ih_name = name;
 
Index: arch/arm64/dev/ampintc.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/dev/ampintc.c,v
retrieving revision 1.10
diff -u -p -r1.10 ampintc.c
--- arch/arm64/dev/ampintc.c 12 Jan 2018 14:53:37 -0000 1.10
+++ arch/arm64/dev/ampintc.c 12 Jan 2018 19:50:17 -0000
@@ -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 ty
  ih->ih_func = func;
  ih->ih_arg = arg;
  ih->ih_ipl = level;
+ ih->ih_flags = 0;
  ih->ih_irq = irqno;
  ih->ih_name = name;
 
Index: arch/arm64/dev/bcm2836_intr.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/dev/bcm2836_intr.c,v
retrieving revision 1.3
diff -u -p -r1.3 bcm2836_intr.c
--- arch/arm64/dev/bcm2836_intr.c 30 Apr 2017 16:45:45 -0000 1.3
+++ arch/arm64/dev/bcm2836_intr.c 12 Jan 2018 19:50:17 -0000
@@ -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 *fra
  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 *fra
  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 l
  ih->ih_fun = func;
  ih->ih_arg = arg;
  ih->ih_ipl = level;
+ ih->ih_flags = 0;
  ih->ih_irq = irqno;
  ih->ih_name = name;
 
Index: arch/arm64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v
retrieving revision 1.3
diff -u -p -r1.3 cpu.h
--- arch/arm64/include/cpu.h 5 Jan 2018 17:42:35 -0000 1.3
+++ arch/arm64/include/cpu.h 12 Jan 2018 19:50:17 -0000
@@ -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