GICv3: enable interrupts
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Fri, 10 Mar 2017 16:28:54 +0000 (17:28 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Fri, 10 Mar 2017 16:30:17 +0000 (17:30 +0100)
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

devices/armv8.dev
kernel/arch/armv8/exn.c
kernel/arch/armv8/gic_v3.c

index 4258a16..055cfb3 100644 (file)
@@ -649,7 +649,7 @@ device armv8 msbfirst () "ARMv8 architecture registers" {
         intid       24 "INTID from the corresponding ICC_IAR0_EL1 access";
     };
 
-    register ICC_EOI1_EL1 rw sysreg(ICC_EOI1_EL1) "Interrupt Controller End Of Interrupt Register 1" {
+    register ICC_EOIR1_EL1 rw sysreg(ICC_EOIR1_EL1) "Interrupt Controller End Of Interrupt Register 1" {
         _            8;
         intid       24 "INTID from the corresponding ICC_IAR1_EL1 access";
     };
index 22204f8..a60e413 100644 (file)
@@ -203,7 +203,6 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
                 uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
 {
     uint32_t irq = 0;
-    printk(LOG_NOTE, "enter handle_irq...\n");
 
     /* The assembly stub leaves the first 4 registers, the stack pointer, and
      * the exception PC for us to save, as it's run out of room for the
@@ -217,7 +216,7 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
 
     irq = gicv3_get_active_irq();
 
-    printk(LOG_NOTE, "IRQ %"PRIu32"\n", irq);
+    printk(LOG_NOTE, "handle_irq IRQ %"PRIu32"\n", irq);
 
     debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
           dcb_current ? (dcb_current->disabled ? "disabled": "enabled") :
@@ -253,7 +252,7 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
      * We just acknowledge it here. */
     else
 #endif
-if(irq == 1)
+    if(irq == 30)
     {
        gicv3_ack_irq(irq);
        dispatch(schedule());
index f574417..9d7d9b7 100644 (file)
 #include <kernel.h>
 #include <sysreg.h>
 #include <dev/armv8_dev.h>
+#include <dev/gic_v3_dev.h>
 #include <platform.h>
 #include <paging_kernel_arch.h>
 #include <arch/armv8/gic_v3.h>
 
 static armv8_t armv8_dev;
+static gic_v3_t gic_v3_dev;
 
 /*
  * Initialize the global interrupt controller
@@ -30,6 +32,9 @@ errval_t gicv3_init(void)
     // Enable system register access
     armv8_ICC_SRE_EL1_SRE_wrf(&armv8_dev, 1);
 
+    lvaddr_t gic_dist = local_phys_to_mem(platform_get_gic_cpu_address());
+    gic_v3_initialize(&gic_v3_dev, (char *)gic_dist);
+
     printk(LOG_NOTE, "gicv3_init done\n");
     return SYS_ERR_OK;
 }
@@ -39,8 +44,7 @@ errval_t gicv3_init(void)
  */
 uint32_t gicv3_get_active_irq(void)
 {
-    armv8_ICC_IAR1_EL1_t iar = armv8_ICC_IAR1_EL1_rd(NULL);
-    return armv8_ICC_IAR1_EL1_intid_extract(iar);
+    return armv8_ICC_IAR1_EL1_intid_rdf(NULL);
 }
 
 /*
@@ -48,12 +52,12 @@ uint32_t gicv3_get_active_irq(void)
  */
 void gicv3_ack_irq(uint32_t irq)
 {
-    armv8_ICC_EOIR0_EL1_rawwr(NULL, irq);
+    armv8_ICC_EOIR1_EL1_rawwr(NULL, irq);
 }
 
+
 errval_t gicv3_cpu_interface_enable(void)
 {
-    //TODO: GICD_CTLR: set affinity routing
     printk(LOG_NOTE, "gicv3_cpu_interface_enable: enabling group 1 int\n");
 
     // Linux does: 
@@ -66,5 +70,23 @@ errval_t gicv3_cpu_interface_enable(void)
     armv8_ICC_IGRPEN1_EL1_wr(NULL, 0x1);
     printk(LOG_NOTE, "gicv3_cpu_interface_enable: group 1 int enabled\n");
 
+    printk(LOG_NOTE, "gicv3_cpu_interface_enable: configuring distributor\n");
+    printk(LOG_NOTE, "GICD IIDR "
+            "implementer=0x%x, revision=0x%x, variant=0x%x,prodid=0x%x\n",
+            gic_v3_GICD_IIDR_Implementer_rdf(&gic_v3_dev),
+            gic_v3_GICD_IIDR_Revision_rdf(&gic_v3_dev),
+            gic_v3_GICD_IIDR_Variant_rdf(&gic_v3_dev),
+            gic_v3_GICD_IIDR_ProductID_rdf(&gic_v3_dev)
+            );
+
+    gic_v3_GICD_CTLR_secure_t ctrl = 0;
+    // Set affinity routing (redundant on CN88xx)
+    ctrl = gic_v3_GICD_CTLR_secure_ARE_NS_insert(ctrl, 1);
+    // Enable group 1 interrupts
+    ctrl = gic_v3_GICD_CTLR_secure_EnableGrp1NS_insert(ctrl, 1);
+    gic_v3_GICD_CTLR_secure_wr(&gic_v3_dev, ctrl);
+
     return SYS_ERR_OK;
 }
+
+