Author: jchandra
Date: Sun Dec 18 08:31:01 2016
New Revision: 310204
URL: https://svnweb.freebsd.org/changeset/base/310204
Log:
  Initialize GIC[DR]_IGROUPRn registers for GICv3
  
  In case where GICD_CTLR.DS is 1, the IGROUPR registers are RW in
  non-secure state and has to be initialized to 1 for the
  corresponding interrupts to be delivered as Group 1 interrupts.
  
  Update gic_v3_dist_init() and gic_v3_redist_init() to initialize
  GICD_IGROUPRn and GICR_IGROUPRn respectively to address this. The
  registers can be set unconditionally since the writes are ignored
  in non-secure state when GICD_CTLR.DS is 0.
  
  This fixes the hang on boot seen when running qemu-system-aarch64
  with machine virt,gic-version=3

Modified:
  head/sys/arm/arm/gic_common.h
  head/sys/arm64/arm64/gic_v3.c
  head/sys/arm64/arm64/gic_v3_reg.h

Modified: head/sys/arm/arm/gic_common.h
==============================================================================
--- head/sys/arm/arm/gic_common.h       Sun Dec 18 05:36:04 2016        
(r310203)
+++ head/sys/arm/arm/gic_common.h       Sun Dec 18 08:31:01 2016        
(r310204)
@@ -66,6 +66,7 @@ __BUS_ACCESSOR(gic, bus, GIC, BUS, u_int
 #define         GICD_IIDR_IMPL(x)                                      \
     (((x) & GICD_IIDR_IMPL_MASK) >> GICD_IIDR_IMPL_SHIFT)
 #define        GICD_IGROUPR(n)         (0x0080 + (((n) >> 5) * 4))     /* v1 
ICDISER */
+#define         GICD_I_PER_IGROUPRn    32
 #define        GICD_ISENABLER(n)       (0x0100 + (((n) >> 5) * 4))     /* v1 
ICDISER */
 #define         GICD_I_MASK(n)         (1ul << ((n) & 0x1f))
 #define         GICD_I_PER_ISENABLERn  32

Modified: head/sys/arm64/arm64/gic_v3.c
==============================================================================
--- head/sys/arm64/arm64/gic_v3.c       Sun Dec 18 05:36:04 2016        
(r310203)
+++ head/sys/arm64/arm64/gic_v3.c       Sun Dec 18 08:31:01 2016        
(r310204)
@@ -1040,6 +1040,10 @@ gic_v3_dist_init(struct gic_v3_softc *sc
        /*
         * 2. Configure the Distributor
         */
+       /* Set all SPIs to be Group 1 Non-secure */
+       for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_IGROUPRn)
+               gic_d_write(sc, 4, GICD_IGROUPR(i), 0xFFFFFFFF);
+
        /* Set all global interrupts to be level triggered, active low. */
        for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_ICFGRn)
                gic_d_write(sc, 4, GICD_ICFGR(i), 0x00000000);
@@ -1206,6 +1210,10 @@ gic_v3_redist_init(struct gic_v3_softc *
        if (err != 0)
                return (err);
 
+       /* Configure SGIs and PPIs to be Group1 Non-secure */
+       gic_r_write(sc, 4, GICR_SGI_BASE_SIZE + GICR_IGROUPR0,
+           0xFFFFFFFF);
+
        /* Disable SPIs */
        gic_r_write(sc, 4, GICR_SGI_BASE_SIZE + GICR_ICENABLER0,
            GICR_I_ENABLER_PPI_MASK);

Modified: head/sys/arm64/arm64/gic_v3_reg.h
==============================================================================
--- head/sys/arm64/arm64/gic_v3_reg.h   Sun Dec 18 05:36:04 2016        
(r310203)
+++ head/sys/arm64/arm64/gic_v3_reg.h   Sun Dec 18 08:31:01 2016        
(r310204)
@@ -194,6 +194,7 @@
 #define        GICR_VLPI_BASE_SIZE     PAGE_SIZE_64K
 #define        GICR_RESERVED_SIZE      PAGE_SIZE_64K
 
+#define        GICR_IGROUPR0                           (0x0080)
 #define        GICR_ISENABLER0                         (0x0100)
 #define        GICR_ICENABLER0                         (0x0180)
 #define                GICR_I_ENABLER_SGI_MASK         (0x0000FFFF)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to