[BACK]Return to gic.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / arm / cortex

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/arm/cortex/gic.c between version 1.32.2.5 and 1.33

version 1.32.2.5, 2018/11/26 01:52:18 version 1.33, 2018/04/01 04:35:04
Line 43  __KERNEL_RCSID(0, "$NetBSD$");
Line 43  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/evcnt.h>  #include <sys/evcnt.h>
 #include <sys/intr.h>  #include <sys/intr.h>
 #include <sys/proc.h>  #include <sys/proc.h>
 #include <sys/atomic.h>  
   
 #include <arm/armreg.h>  #include <arm/armreg.h>
 #include <arm/atomic.h>  #include <arm/atomic.h>
Line 76  static void armgic_source_name(struct pi
Line 75  static void armgic_source_name(struct pi
 #ifdef MULTIPROCESSOR  #ifdef MULTIPROCESSOR
 static void armgic_cpu_init(struct pic_softc *, struct cpu_info *);  static void armgic_cpu_init(struct pic_softc *, struct cpu_info *);
 static void armgic_ipi_send(struct pic_softc *, const kcpuset_t *, u_long);  static void armgic_ipi_send(struct pic_softc *, const kcpuset_t *, u_long);
 static void armgic_get_affinity(struct pic_softc *, size_t, kcpuset_t *);  
 static int armgic_set_affinity(struct pic_softc *, size_t, const kcpuset_t *);  
 #endif  #endif
   
 static const struct pic_ops armgic_picops = {  static const struct pic_ops armgic_picops = {
Line 91  static const struct pic_ops armgic_picop
Line 88  static const struct pic_ops armgic_picop
 #ifdef MULTIPROCESSOR  #ifdef MULTIPROCESSOR
         .pic_cpu_init = armgic_cpu_init,          .pic_cpu_init = armgic_cpu_init,
         .pic_ipi_send = armgic_ipi_send,          .pic_ipi_send = armgic_ipi_send,
         .pic_get_affinity = armgic_get_affinity,  
         .pic_set_affinity = armgic_set_affinity,  
 #endif  #endif
 };  };
   
Line 109  static struct armgic_softc {
Line 104  static struct armgic_softc {
         uint32_t sc_gic_valid_lines[1024/32];          uint32_t sc_gic_valid_lines[1024/32];
         uint32_t sc_enabled_local;          uint32_t sc_enabled_local;
 #ifdef MULTIPROCESSOR  #ifdef MULTIPROCESSOR
         uint32_t sc_target[MAXCPUS];  
         uint32_t sc_mptargets;          uint32_t sc_mptargets;
 #endif  #endif
         uint32_t sc_bptargets;          uint32_t sc_bptargets;
Line 228  armgic_set_priority(struct pic_softc *pi
Line 222  armgic_set_priority(struct pic_softc *pi
         gicc_write(sc, GICC_PMR, priority);          gicc_write(sc, GICC_PMR, priority);
 }  }
   
 #ifdef MULTIPROCESSOR  
 static void  
 armgic_get_affinity(struct pic_softc *pic, size_t irq, kcpuset_t *affinity)  
 {  
         struct armgic_softc * const sc = PICTOSOFTC(pic);  
         const size_t group = irq / 32;  
         int n;  
   
         kcpuset_zero(affinity);  
         if (group == 0) {  
                 /* All CPUs are targets for group 0 (SGI/PPI) */  
                 for (n = 0; n < MAXCPUS; n++) {  
                         if (sc->sc_target[n] != 0)  
                                 kcpuset_set(affinity, n);  
                 }  
         } else {  
                 /* Find distributor targets (SPI) */  
                 const u_int byte_shift = 8 * (irq & 3);  
                 const bus_size_t targets_reg = GICD_ITARGETSRn(irq / 4);  
                 const uint32_t targets = gicd_read(sc, targets_reg);  
                 const uint32_t targets_val = (targets >> byte_shift) & 0xff;  
   
                 for (n = 0; n < MAXCPUS; n++) {  
                         if (sc->sc_target[n] & targets_val)  
                                 kcpuset_set(affinity, n);  
                 }  
         }  
 }  
   
 static int  
 armgic_set_affinity(struct pic_softc *pic, size_t irq,  
     const kcpuset_t *affinity)  
 {  
         struct armgic_softc * const sc = PICTOSOFTC(pic);  
         const size_t group = irq / 32;  
         if (group == 0)  
                 return EINVAL;  
   
         const u_int byte_shift = 8 * (irq & 3);  
         const bus_size_t targets_reg = GICD_ITARGETSRn(irq / 4);  
         uint32_t targets_val = 0;  
         int n;  
   
         for (n = 0; n < MAXCPUS; n++) {  
                 if (kcpuset_isset(affinity, n))  
                         targets_val |= sc->sc_target[n];  
         }  
   
         uint32_t targets = gicd_read(sc, targets_reg);  
         targets &= ~(0xff << byte_shift);  
         targets |= (targets_val << byte_shift);  
         gicd_write(sc, targets_reg, targets);  
   
         return 0;  
 }  
 #endif  
   
 #ifdef __HAVE_PIC_FAST_SOFTINTS  #ifdef __HAVE_PIC_FAST_SOFTINTS
 void  void
 softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep_p)  softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep_p)
Line 465  static void
Line 402  static void
 armgic_cpu_init_priorities(struct armgic_softc *sc)  armgic_cpu_init_priorities(struct armgic_softc *sc)
 {  {
         /* Set lowest priority, i.e. disable interrupts */          /* Set lowest priority, i.e. disable interrupts */
         for (size_t i = 0; i < sc->sc_pic.pic_maxsources; i += 4) {          for (size_t i = 0; i < 32; i += 4) {
                 const bus_size_t priority_reg = GICD_IPRIORITYRn(i / 4);                  const bus_size_t priority_reg = GICD_IPRIORITYRn(i / 4);
                 gicd_write(sc, priority_reg, ~0);                  gicd_write(sc, priority_reg, ~0);
         }          }
Line 475  static void
Line 412  static void
 armgic_cpu_update_priorities(struct armgic_softc *sc)  armgic_cpu_update_priorities(struct armgic_softc *sc)
 {  {
         uint32_t enabled = sc->sc_enabled_local;          uint32_t enabled = sc->sc_enabled_local;
         for (size_t i = 0; i < sc->sc_pic.pic_maxsources; i += 4, enabled >>= 4) {          for (size_t i = 0; i < 32; i += 4, enabled >>= 4) {
                 const bus_size_t priority_reg = GICD_IPRIORITYRn(i / 4);                  const bus_size_t priority_reg = GICD_IPRIORITYRn(i / 4);
                 uint32_t priority = gicd_read(sc, priority_reg);                  uint32_t priority = gicd_read(sc, priority_reg);
                 uint32_t byte_mask = 0xff;                  uint32_t byte_mask = 0xff;
Line 514  void
Line 451  void
 armgic_cpu_init(struct pic_softc *pic, struct cpu_info *ci)  armgic_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
 {  {
         struct armgic_softc * const sc = PICTOSOFTC(pic);          struct armgic_softc * const sc = PICTOSOFTC(pic);
         sc->sc_target[cpu_index(ci)] = gicd_find_targets(sc);          sc->sc_mptargets |= gicd_find_targets(sc);
         atomic_or_32(&sc->sc_mptargets, sc->sc_target[cpu_index(ci)]);  
         KASSERTMSG(ci->ci_cpl == IPL_HIGH, "ipl %d not IPL_HIGH", ci->ci_cpl);          KASSERTMSG(ci->ci_cpl == IPL_HIGH, "ipl %d not IPL_HIGH", ci->ci_cpl);
         armgic_cpu_init_priorities(sc);          armgic_cpu_init_priorities(sc);
         if (!CPU_IS_PRIMARY(ci)) {          if (!CPU_IS_PRIMARY(ci)) {
Line 547  armgic_ipi_send(struct pic_softc *pic, c
Line 483  armgic_ipi_send(struct pic_softc *pic, c
   
         uint32_t sgir = __SHIFTIN(ARMGIC_SGI_IPIBASE + ipi, GICD_SGIR_SGIINTID);          uint32_t sgir = __SHIFTIN(ARMGIC_SGI_IPIBASE + ipi, GICD_SGIR_SGIINTID);
         if (kcp != NULL) {          if (kcp != NULL) {
                 uint32_t targets_val = 0;                  uint32_t targets;
                 for (int n = 0; n < MAXCPUS; n++) {                  kcpuset_export_u32(kcp, &targets, sizeof(targets));
                         if (kcpuset_isset(kcp, n))                  sgir |= __SHIFTIN(targets, GICD_SGIR_TargetList);
                                 targets_val |= sc->sc_target[n];  
                 }  
                 sgir |= __SHIFTIN(targets_val, GICD_SGIR_TargetList);  
                 sgir |= GICD_SGIR_TargetListFilter_List;                  sgir |= GICD_SGIR_TargetListFilter_List;
         } else {          } else {
                 if (ncpu == 1)                  if (ncpu == 1)
Line 677  armgic_attach(device_t parent, device_t 
Line 610  armgic_attach(device_t parent, device_t 
                 }                  }
         }          }
 #ifdef __HAVE_PIC_FAST_SOFTINTS  #ifdef __HAVE_PIC_FAST_SOFTINTS
         intr_establish_xname(SOFTINT_BIO, IPL_SOFTBIO, IST_MPSAFE | IST_EDGE,          intr_establish(SOFTINT_BIO, IPL_SOFTBIO, IST_MPSAFE | IST_EDGE,
             pic_handle_softint, (void *)SOFTINT_BIO, "softint bio");              pic_handle_softint, (void *)SOFTINT_BIO);
         intr_establish_xname(SOFTINT_CLOCK, IPL_SOFTCLOCK, IST_MPSAFE | IST_EDGE,          intr_establish(SOFTINT_CLOCK, IPL_SOFTCLOCK, IST_MPSAFE | IST_EDGE,
             pic_handle_softint, (void *)SOFTINT_CLOCK, "softint clock");              pic_handle_softint, (void *)SOFTINT_CLOCK);
         intr_establish_xname(SOFTINT_NET, IPL_SOFTNET, IST_MPSAFE | IST_EDGE,          intr_establish(SOFTINT_NET, IPL_SOFTNET, IST_MPSAFE | IST_EDGE,
             pic_handle_softint, (void *)SOFTINT_NET, "softint net");              pic_handle_softint, (void *)SOFTINT_NET);
         intr_establish_xname(SOFTINT_SERIAL, IPL_SOFTSERIAL, IST_MPSAFE | IST_EDGE,          intr_establish(SOFTINT_SERIAL, IPL_SOFTSERIAL, IST_MPSAFE | IST_EDGE,
             pic_handle_softint, (void *)SOFTINT_SERIAL, "softint serial");              pic_handle_softint, (void *)SOFTINT_SERIAL);
 #endif  #endif
 #ifdef MULTIPROCESSOR  #ifdef MULTIPROCESSOR
         armgic_cpu_init(&sc->sc_pic, curcpu());          armgic_cpu_init(&sc->sc_pic, curcpu());
   
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_AST, IPL_VM,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_AST, IPL_VM,
             IST_MPSAFE | IST_EDGE, pic_ipi_ast, (void *)-1, "IPI ast");              IST_MPSAFE | IST_EDGE, pic_ipi_ast, (void *)-1);
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_XCALL, IPL_HIGH,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_XCALL, IPL_HIGH,
             IST_MPSAFE | IST_EDGE, pic_ipi_xcall, (void *)-1, "IPI xcall");              IST_MPSAFE | IST_EDGE, pic_ipi_xcall, (void *)-1);
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_GENERIC, IPL_HIGH,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_GENERIC, IPL_HIGH,
             IST_MPSAFE | IST_EDGE, pic_ipi_generic, (void *)-1, "IPI generic");              IST_MPSAFE | IST_EDGE, pic_ipi_generic, (void *)-1);
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_NOP, IPL_VM,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_NOP, IPL_VM,
             IST_MPSAFE | IST_EDGE, pic_ipi_nop, (void *)-1, "IPI nop");              IST_MPSAFE | IST_EDGE, pic_ipi_nop, (void *)-1);
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_SHOOTDOWN, IPL_SCHED,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_SHOOTDOWN, IPL_SCHED,
             IST_MPSAFE | IST_EDGE, pic_ipi_shootdown, (void *)-1, "IPI shootdown");              IST_MPSAFE | IST_EDGE, pic_ipi_shootdown, (void *)-1);
 #ifdef DDB  #ifdef DDB
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_DDB, IPL_HIGH,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_DDB, IPL_HIGH,
             IST_MPSAFE | IST_EDGE, pic_ipi_ddb, NULL, "IPI ddb");              IST_MPSAFE | IST_EDGE, pic_ipi_ddb, NULL);
 #endif  #endif
 #ifdef __HAVE_PREEMPTION  #ifdef __HAVE_PREEMPTION
         intr_establish_xname(ARMGIC_SGI_IPIBASE + IPI_KPREEMPT, IPL_VM,          intr_establish(ARMGIC_SGI_IPIBASE + IPI_KPREEMPT, IPL_VM,
             IST_MPSAFE | IST_EDGE, pic_ipi_kpreempt, (void *)-1, "IPI kpreempt");              IST_MPSAFE | IST_EDGE, pic_ipi_kpreempt, (void *)-1);
 #endif  #endif
 #endif  #endif
   

Legend:
Removed from v.1.32.2.5  
changed lines
  Added in v.1.33

CVSweb <webmaster@jp.NetBSD.org>