armv7: Move distributor driver to userspace
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Thu, 13 Dec 2018 14:20:16 +0000 (15:20 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Thu, 13 Dec 2018 14:20:16 +0000 (15:20 +0100)
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

47 files changed:
devices/Hakefile
devices/pl130_gic_cpuif.dev [new file with mode: 0644]
devices/pl130_gic_dist.dev [moved from devices/pl130_gic.dev with 79% similarity]
hake/menu.lst.armv7_a15a7ve
hake/menu.lst.armv7_a15ve_1
hake/menu.lst.armv7_a15ve_2 [new file with mode: 0644]
hake/menu.lst.armv7_a15ve_4
hake/menu.lst.armv7_a15ve_fvp_1
hake/menu.lst.armv7_a15ve_fvp_4
include/barrelfish/debug.h
include/barrelfish/sys_debug.h
include/barrelfish_kpi/sys_debug.h
include/int_route/int_route_debug.h
kernel/Hakefile
kernel/arch/arm/exn.c
kernel/arch/arm/gic.c
kernel/arch/arm/gic_v3.c
kernel/arch/arm/irq.c
kernel/arch/armv7/init.c
kernel/arch/armv7/paging.c
kernel/arch/armv7/plat_a15mpcore.c
kernel/arch/armv7/plat_a9mpcore.c
kernel/arch/armv7/syscall.c
kernel/arch/armv8/exn.c
kernel/arch/armv8/plat_rpi3.c
kernel/include/arch/arm/platform.h
lib/barrelfish/sys_debug.c
lib/driverkit/dcontrol_service.c
lib/driverkit/ddomain_service.c
lib/driverkit/debug.h
lib/driverkit/modules.c
lib/int_route/Hakefile
lib/int_route/server/standalone.c [new file with mode: 0644]
platforms/Hakefile
usr/drivers/domain/Hakefile
usr/drivers/omap44xx/pl130_dist/Hakefile [new file with mode: 0644]
usr/drivers/omap44xx/pl130_dist/debug.h [new file with mode: 0644]
usr/drivers/omap44xx/pl130_dist/main.c [new file with mode: 0644]
usr/kaluga/armv7.c
usr/kaluga/armv7_startup.c
usr/kaluga/device_caps.c
usr/kaluga/driver_startup.c
usr/kaluga/driver_startup.h
usr/kaluga/main.c
usr/skb/programs/plat_VE_A15x1.pl
usr/skb/programs/plat_VE_A15x2.pl [new file with mode: 0644]
usr/skb/programs/plat_VE_A15x4.pl

index c07d5c6..882dd34 100644 (file)
@@ -65,7 +65,8 @@
            "xapic",
            "x2apic",
            "amd64",
-           "pl130_gic",
+           "pl130_gic_dist",
+           "pl130_gic_cpuif",
            "pl011_uart",
            "rpi3_miniuart",
            "sp804_pit",
diff --git a/devices/pl130_gic_cpuif.dev b/devices/pl130_gic_cpuif.dev
new file mode 100644 (file)
index 0000000..4a390f1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, ETH Zurich. All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+ * Attn: Systems Group.
+ */
+
+/*
+ * pl130_gic_cpuif.dev
+ *
+ * DESCRIPTION: PrimeCell PL130 Generic Interrupt Controller
+ *
+ * This is derived from:
+ *
+ * [1] PrimeCell Generic Interrupt Controller PL130
+ *     (DDI0416B_gic_pl390_r0p0_trm.pdf)
+ * [2] ARM Cortex A9 MPCore TRM r2p0
+ * [3] ARM Generic Interrupt Controller v1.0
+ *
+ * Updated to work on PandaBoard according to [2] Table 3-1
+ *
+ * Register map for distributor: [3], chp 4.1.2
+ * Register map for CPU interface: [3], chp 4.1.3
+ */
+
+device pl130_gic_cpuif msbfirst (addr cpu_base)
+    "PrimeCell PL130 Generic Interrupt Controller CPU interface"
+{
+
+
+    //
+    // CPU interface register map
+    //
+
+    register ICCICR addr(cpu_base, 0x0) "CPU Interface Control" {
+        _               31;
+        enable          1       "en. fwding to connected processors";
+    };
+
+    register ICCPMR addr(cpu_base, 0x4) "Interrupt Priority Mask" {
+        _               24;
+        priority        8       "Priority mask level for CPU Interface";
+    };
+
+    register ICCBPR addr(cpu_base, 0x8) "Binary Point" {
+        _               29;
+        binary_point    3       "Split Group- and subpriority";
+    };
+
+    register ICCIAR ro addr(cpu_base, 0xc) "Interrupt Acknowledge" {
+        _               19;
+        cpu_id          3       "Processor ID of interrupting processor";
+        ack_int_id      10      "Interrupt ID";
+    };
+
+    register ICCEOIR wo addr(cpu_base, 0x10) "End of Interrupt" {
+        _               19 mbz;
+        cpu_id          3       "Proc ID of ICCIAR access";
+        eoi_int_id      10      "ACKINTID of ICCIAR access";
+    };
+
+    register ICCRPR ro addr(cpu_base, 0x14) "Running Priority" {
+        _               24;
+        priority        8       "Highest priority active interrupt";
+    };
+
+    register ICCHPIR ro addr(cpu_base, 0x18) "Highest Pending Interrupt" {
+        _               19;
+        cpu_id          3       "ID of interrupting processor";
+        pend_int_id     10      "ID of highest pri. pending int.";
+    };
+
+    register ICCABPR addr(cpu_base, 0x1c) "Aliased Binary Point" {
+        _               29 rsvd;
+        binary_point    3       "Split Group- and subpriority";
+    };
+
+    register ICCIIDR ro addr(cpu_base, 0xfc) "CPU Interface Identification" {
+        product_id      12      "Product ID";
+        arch_version    4       "Implemented GIC architecture version";
+        revision        4       "Revision number for the CPU Interface";
+        implementer     12      "JEP106 code of the implementer";
+    };
+ };
similarity index 79%
rename from devices/pl130_gic.dev
rename to devices/pl130_gic_dist.dev
index fc45531..4662ad5 100644 (file)
@@ -25,8 +25,8 @@
  * Register map for CPU interface: [3], chp 4.1.3
  */
 
-device pl130_gic msbfirst (addr dist_base, addr cpu_base)
-    "PrimeCell PL130 Generic Interrupt Controller"
+device pl130_gic_dist msbfirst (addr dist_base)
+    "PrimeCell PL130 Generic Interrupt Controller Distributor"
 {
     //
     // Distributor register map
@@ -202,59 +202,4 @@ device pl130_gic msbfirst (addr dist_base, addr cpu_base)
         _               24;
         component_id    8;
     };
-
-
-    //
-    // CPU interface register map
-    //
-
-    register ICCICR addr(cpu_base, 0x0) "CPU Interface Control" {
-        _               31;
-        enable          1       "en. fwding to connected processors";
-    };
-
-    register ICCPMR addr(cpu_base, 0x4) "Interrupt Priority Mask" {
-        _               24;
-        priority        8       "Priority mask level for CPU Interface";
-    };
-
-    register ICCBPR addr(cpu_base, 0x8) "Binary Point" {
-        _               29;
-        binary_point    3       "Split Group- and subpriority";
-    };
-
-    register ICCIAR ro addr(cpu_base, 0xc) "Interrupt Acknowledge" {
-        _               19;
-        cpu_id          3       "Processor ID of interrupting processor";
-        ack_int_id      10      "Interrupt ID";
-    };
-
-    register ICCEOIR wo addr(cpu_base, 0x10) "End of Interrupt" {
-        _               19 mbz;
-        cpu_id          3       "Proc ID of ICCIAR access";
-        eoi_int_id      10      "ACKINTID of ICCIAR access";
-    };
-
-    register ICCRPR ro addr(cpu_base, 0x14) "Running Priority" {
-        _               24;
-        priority        8       "Highest priority active interrupt";
-    };
-
-    register ICCHPIR ro addr(cpu_base, 0x18) "Highest Pending Interrupt" {
-        _               19;
-        cpu_id          3       "ID of interrupting processor";
-        pend_int_id     10      "ID of highest pri. pending int.";
-    };
-
-    register ICCABPR addr(cpu_base, 0x1c) "Aliased Binary Point" {
-        _               29 rsvd;
-        binary_point    3       "Split Group- and subpriority";
-    };
-
-    register ICCIIDR ro addr(cpu_base, 0xfc) "CPU Interface Identification" {
-        product_id      12      "Product ID";
-        arch_version    4       "Implemented GIC architecture version";
-        revision        4       "Revision number for the CPU Interface";
-        implementer     12      "JEP106 code of the implementer";
-    };
- };
+};
index 9414fb4..eb25747 100644 (file)
@@ -29,6 +29,7 @@ module /armv7/sbin/startd boot
 
 # Device drivers
 # module /armv7/sbin/serial_pl011 auto
+module /armv7/sbin/driverdomain auto
 module /armv7/sbin/serial_kernel irq=37
 module /armv7/sbin/corectrl nospawn
 
index 412a713..386cebb 100644 (file)
@@ -29,6 +29,7 @@ module /armv7/sbin/startd boot
 
 # Device drivers
 # module /armv7/sbin/serial_pl011 auto
+module /armv7/sbin/driverdomain auto
 module /armv7/sbin/serial_kernel irq=37
 module /armv7/sbin/corectrl auto
 
@@ -36,6 +37,7 @@ module /armv7/sbin/corectrl auto
 module /armv7/sbin/angler serial0.terminal dumb
 module /armv7/sbin/fish nospawn
 
+module /armv7/sbin/int_route 
 module /armv7/sbin/memtest
 
 # gem5 simulates 512MB of RAM starting at 0x80000000
diff --git a/hake/menu.lst.armv7_a15ve_2 b/hake/menu.lst.armv7_a15ve_2
new file mode 100644 (file)
index 0000000..0c916c6
--- /dev/null
@@ -0,0 +1,46 @@
+timeout 0
+
+#
+# This script is used to describe the commands to start at
+# boot-time and the arguments they should receive.
+#
+# Kernel arguments are not read from this script. On QEMU they can be
+# set using 'qemu-system-arm -append ...'.
+
+title  Barrelfish
+#root  (nd)
+kernel /armv7/sbin/cpu_a15ve loglevel=3 periphbase=0x2c000000 consolePort=0
+module /armv7/sbin/cpu_a15ve
+module /armv7/sbin/init
+
+# Domains spawned by init
+module /armv7/sbin/mem_serv
+module /armv7/sbin/monitor
+
+# Special boot time domains spawned by monitor
+module /armv7/sbin/ramfsd boot
+module /armv7/sbin/skb boot
+modulenounzip /eclipseclp_ramfs.cpio.gz nospawn
+modulenounzip /skb_ramfs.cpio.gz nospawn
+module /armv7/sbin/kaluga boot add_device_db=plat_VE_A15x2
+module /armv7/sbin/spawnd boot
+module /armv7/sbin/proc_mgmt boot
+module /armv7/sbin/startd boot
+
+# Device drivers
+# module /armv7/sbin/serial_pl011 auto
+module /armv7/sbin/driverdomain auto
+module /armv7/sbin/serial_kernel irq=37
+module /armv7/sbin/corectrl auto
+
+# General user domains
+module /armv7/sbin/angler serial0.terminal dumb
+module /armv7/sbin/fish nospawn
+
+module /armv7/sbin/int_route 
+module /armv7/sbin/memtest
+
+# gem5 simulates 512MB of RAM starting at 0x80000000
+#        start       size       id
+mmap map 0x00000000  0x80000000 13 # Device region
+mmap map 0x80000000  0x20000000 1
index 0351723..03f9c85 100644 (file)
@@ -29,6 +29,7 @@ module /armv7/sbin/startd boot
 
 # Device drivers
 # module /armv7/sbin/serial_pl011 auto
+module /armv7/sbin/driverdomain auto
 module /armv7/sbin/serial_kernel irq=37
 module /armv7/sbin/corectrl auto
 
@@ -36,6 +37,7 @@ module /armv7/sbin/corectrl auto
 module /armv7/sbin/angler serial0.terminal dumb
 module /armv7/sbin/fish nospawn
 
+module /armv7/sbin/int_route 
 module /armv7/sbin/memtest
 
 # gem5 simulates 512MB of RAM starting at 0x80000000
index f5d8586..a470f74 100644 (file)
@@ -29,6 +29,7 @@ module /armv7/sbin/startd boot
 
 # Device drivers
 # module /armv7/sbin/serial_pl011 auto
+module /armv7/sbin/driverdomain auto
 module /armv7/sbin/serial_kernel irq=37
 module /armv7/sbin/corectrl auto
 
index 0a977a9..f1e6ca4 100644 (file)
@@ -29,6 +29,7 @@ module /armv7/sbin/startd boot
 
 # Device drivers
 # module /armv7/sbin/serial_pl011 auto
+module /armv7/sbin/driverdomain auto
 module /armv7/sbin/serial_kernel irq=37
 module /armv7/sbin/corectrl auto
 
index a1fcf44..29e8e38 100644 (file)
@@ -71,6 +71,13 @@ void user_panic_fn(const char *file, const char *func, int line,
 } while (0)
 
 /**
+ * \brief If err is an error, panic
+ */
+#define USER_PANIC_ON_ERR(err, msg...) do {               \
+    if(err_is_fail(err)) USER_PANIC_ERR(err, msg);     \
+} while (0)
+
+/**
  * \brief Prints out a string and abort the domain
  */
 #define USER_PANIC(msg...)                                 \
index d3d4cf7..c78fa82 100644 (file)
@@ -29,6 +29,7 @@ __BEGIN_DECLS
 #define X86_DEBUG_LENGTH_8BYTE      (2) ///< Undefined?
 #define X86_DEBUG_LENGTH_4BYTE      (3)
 
+errval_t sys_debug_gic_dist(void);
 errval_t sys_debug_context_counter_reset(void);
 errval_t sys_debug_context_counter_read(uint64_t *ret);
 errval_t sys_debug_timeslice_counter_read(uint64_t *ret);
index a91d1b4..166149e 100644 (file)
@@ -35,6 +35,7 @@ enum debug_message {
     DEBUG_TRACE_PMEM_CTRL,
     DEBUG_GET_APIC_ID,
     DEBUG_CREATE_IRQ_SRC_CAP,
+    DEBUG_GIC_DIST,
 };
 
 #endif //BARRELFISH_KPI_SYS_DEBUG_H
index f28837f..3e55d3a 100644 (file)
@@ -8,7 +8,7 @@
 #ifndef INT_ROUTE_INT_ROUTE_DEBUG_H_
 #define INT_ROUTE_INT_ROUTE_DEBUG_H_
 
-//#define INT_ROUTE_SERVICE_DEBUG
+#define INT_ROUTE_SERVICE_DEBUG
 
 #if defined(INT_ROUTE_SERVICE_DEBUG)
 #define INT_DEBUG(x...) debug_printf("int_service: " x)
index 04e8d9b..e8e528e 100644 (file)
@@ -243,7 +243,8 @@ let
     mackerelDevices = [ "arm",
                         "cpuid_arm",
                         "pl011_uart",
-                        "pl130_gic" ],
+                        "pl130_gic_cpuif",
+                        "pl130_gic_dist" ],
     addLibraries = [ "elf" ]
     },
   --
@@ -312,7 +313,8 @@ let
      mackerelDevices = [ "arm",
                          "cpuid_arm",
                          "pl011_uart",
-                         "pl130_gic",
+                         "pl130_gic_cpuif",
+                         "pl130_gic_dist",
                          "cortex_a9_gt",
                          "cortex_a9_scu"
                        ],
@@ -381,7 +383,8 @@ let
                 ],
      mackerelDevices = [ "arm",
                          "cpuid_arm",
-                         "pl130_gic",
+                         "pl130_gic_cpuif",
+                         "pl130_gic_dist",
                          "cortex_a9_pit",
                          "cortex_a9_gt",
                          "cortex_a9_scu",
@@ -465,7 +468,8 @@ let
                 ],
      mackerelDevices = [ "arm",
                          "cpuid_arm",
-                         "pl130_gic",
+                         "pl130_gic_cpuif",
+                         "pl130_gic_dist",
                          "cortex_a9_pit",
                          "cortex_a9_gt",
                          "cortex_a9_scu",
@@ -515,7 +519,7 @@ let
         "gic_v3_redist",
         "gic_v2_cpu",
         "armv8/armv8_cache_ctrl",
-        "pl130_gic",
+        "pl130_gic_cpuif",
         "arm_icp_pit",
         "apm88xxxx/apm88xxxx_pc16550"
      ],
@@ -714,7 +718,7 @@ let
         "gic_v3_redist",
         "armv8/armv8_cache_ctrl",
         "pl011_uart",
-        "pl130_gic",
+        "pl130_gic_cpuif",
         "arm_icp_pit"
      ],
      addLibraries = [
index 94b7a52..4586633 100644 (file)
@@ -319,6 +319,11 @@ void handle_irq(arch_registers_state_t* save_area,
 
     // Offer it to the timer
     if (platform_is_timer_interrupt(irq)) {
+        static int timer_irq_seen = false;
+        if(!timer_irq_seen){
+            printk(LOG_NOTE, "Timer IRQ received\n");
+            timer_irq_seen = true;
+        }
         platform_acknowledge_irq(irq);
         wakeup_check(systime_now());
 #ifndef CONFIG_ONESHOT_TIMER
index 27911af..0673d84 100644 (file)
@@ -9,17 +9,16 @@
 
 #include <kernel.h>
 
-#include <dev/pl130_gic_dev.h>
+#include <dev/pl130_gic_cpuif_dev.h>
+#include <dev/pl130_gic_dist_dev.h>
 #include <arch/arm/gic.h>
 #include <arch/arm/platform.h>
 #include <paging_kernel_arch.h>
 #include <arch/armv7/irq.h>
 #include <getopt/getopt.h>
 
-static pl130_gic_t gic;
-static uint32_t it_num_lines;
-static pl130_gic_ICDICTR_t gic_config;
-static uint8_t cpu_number;
+static pl130_gic_cpuif_t gic;
+static pl130_gic_dist_t gic_dist;
 
 #define MSG(format, ...) printk( LOG_NOTE, "GIC: "format, ## __VA_ARGS__ )
 
@@ -38,8 +37,8 @@ enum IrqType {
     IrqType_SPI
 };
 
-#define DIST_SIZE 0x1000
 #define CPU_SIZE  0x1000
+#define DIST_SIZE  0x1000
 
 /**
  * \brief Returns the IRQ type based on the interrupt ID
@@ -51,6 +50,7 @@ enum IrqType {
  *
  * \return The type of the interrupt.
  */
+/*
 static enum IrqType get_irq_type(uint32_t int_id)
 {
     if (int_id < 16) {
@@ -60,7 +60,7 @@ static enum IrqType get_irq_type(uint32_t int_id)
     } else {
         return IrqType_SPI;
     }
-}
+} */
 
 /*
  * Initialize the global interrupt controller
@@ -74,49 +74,30 @@ void gic_init(void)
 {
     printk(LOG_NOTE, "GICv1: Initializing\n");
     parse_commandline(kernel_command_line, cmdargs);
-    lvaddr_t gic_dist_base =
-        paging_map_device(platform_gic_distributor_base, DIST_SIZE );
+    printk(LOG_NOTE, "GICv1: gic_cpu_base=%p\n", platform_gic_cpu_interface_base);
     lvaddr_t gic_cpu_base =
         paging_map_device(platform_gic_cpu_interface_base, CPU_SIZE );
-    pl130_gic_initialize(&gic, (mackerel_addr_t)gic_dist_base,
-                               (mackerel_addr_t)gic_cpu_base );
-
-    // read GIC configuration
-    gic_config = pl130_gic_ICDICTR_rd(&gic);
-
-    // ARM GIC 2.0 TRM, Table 4-6
-    // This is the number of ICDISERs, i.e. #SPIs
-    // Number of SGIs (0-15) and PPIs (16-31) is fixed
-    uint32_t it_num_lines_tmp =
-        pl130_gic_ICDICTR_it_lines_num_extract(gic_config);
-    it_num_lines = 32*(it_num_lines_tmp + 1);
-
-    MSG("%d interrupt lines detected\n", it_num_lines);
+    pl130_gic_cpuif_initialize(&gic, (mackerel_addr_t)gic_cpu_base );
 
-    cpu_number = pl130_gic_ICDICTR_cpu_number_extract(gic_config) + 1;
+    printk(LOG_NOTE, "GICv1: dist_base=%p\n", platform_gic_distributor_base);
+    lvaddr_t gic_dist_base =
+        paging_map_device(platform_gic_distributor_base, DIST_SIZE );
+    pl130_gic_dist_initialize(&gic_dist, (mackerel_addr_t)gic_dist_base );
 
     // set priority mask of cpu interface, currently set to lowest priority
     // to accept all interrupts
-    pl130_gic_ICCPMR_wr(&gic, 0xff);
+    pl130_gic_cpuif_ICCPMR_wr(&gic, 0xff);
 
     // set binary point to define split of group- and subpriority
     // currently we allow for 8 subpriorities
-    pl130_gic_ICCBPR_wr(&gic, 0x2);
+    pl130_gic_cpuif_ICCBPR_wr(&gic, 0x2);
 
     // enable interrupt forwarding to processor
-    pl130_gic_ICCICR_enable_wrf(&gic, 0x1);
+    pl130_gic_cpuif_ICCICR_enable_wrf(&gic, 0x1);
 
-    // Distributor:
-    // enable interrupt forwarding from distributor to cpu interface
-    pl130_gic_ICDDCR_enable_wrf(&gic, 0x1);
     MSG("gic_init done\n");
 }
 
-size_t
-gic_cpu_count(void) {
-    return cpu_number;
-}
-
 void  __attribute__((noreturn)) gic_disable_all_irqs(void)
 {
     panic("gic_disable_all_irqs NYI for armv7");
@@ -124,36 +105,38 @@ void  __attribute__((noreturn)) gic_disable_all_irqs(void)
     // ALSO remove noreturn option
 
     /* //disable PPI interrupts */
-    /* pl130_gic_PPI_ICDICER_wr(&gic, (uint16_t)0xffff); */
+    /* pl130_gic_cpuif_PPI_ICDICER_wr(&gic, (uint16_t)0xffff); */
 
     /* //disable SPI interrupts */
     /* for(uint8_t i=0; i < it_num_lines; i++) { */
-    /*     pl130_gic_SPI_ICDICER_wr(&gic, i, (uint32_t)0xffffffff); */
+    /*     pl130_gic_cpuif_SPI_ICDICER_wr(&gic, i, (uint32_t)0xffffffff); */
     /* } */
 }
 
 uint32_t platform_get_active_irq(void)
 {
-    uint32_t regval = pl130_gic_ICCIAR_rd(&gic);
+    return pl130_gic_cpuif_ICCIAR_rd(&gic);
+}
 
-    return regval;
+uint32_t gic_cpu_count(void){
+    MSG("GIC can't be used to determine CPU COUNT!\n");
+    return 1;
 }
 
 void gic_raise_softirq(uint8_t cpumask, uint8_t irq)
 {
-    uint32_t regval = (cpumask << 16) | irq;
-    pl130_gic_ICDSGIR_wr(&gic, regval);
+    assert(!"NYI"); // This needs distributor access
 }
 
 void platform_acknowledge_irq(uint32_t irq)
 {
-    pl130_gic_ICCEOIR_rawwr(&gic, irq);
+    pl130_gic_cpuif_ICCEOIR_rawwr(&gic, irq);
 }
 
 //enable interrupt forwarding to processor
 void gic_cpu_interface_enable(void)
 {
-    pl130_gic_ICCICR_wr(&gic, 0x1);
+    pl130_gic_cpuif_ICCICR_wr(&gic, 0x1);
 }
 
 errval_t platform_init_ic_bsp(void) {
@@ -163,54 +146,44 @@ errval_t platform_init_ic_bsp(void) {
 }
 
 errval_t platform_init_ic_app(void) {
+    gic_init();
     gic_cpu_interface_enable();
     return SYS_ERR_OK;
 }
 
 /**
- * \brief Enable an interrupt
+ * \brief Enable an PPI interrupt
  *
  * \see ARM Generic Interrupt Controller Architecture Specification v1.0
  *
  * \param int_id
- * \param cpu_targets 8 Bit mask. One bit for each core in the system.
- *    (chapter 4.3.11)
  * \param prio Priority of the interrupt (lower is higher). We allow 0..15.
  *    The number of priority bits is implementation specific, but at least 16
  *    (using bits [7:4] of the priority field, chapter 3.3)
  * \param 0 is level-sensitive, 1 is edge-triggered
  * \param 0 is N-to-N, 1 is 1-N
  */
-void platform_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t prio,
-                          bool edge_triggered, bool one_to_n)
+void platform_enable_interrupt(uint32_t int_id, uint16_t prio,
+                               bool edge_triggered, bool one_to_n)
 {
     // Set Interrupt Set-Enable Register
+    /*
     uint32_t ind = int_id / 32;
     uint32_t bit_mask = (1U << (int_id % 32));
-    uint32_t regval;
 
     MSG("platform_enable_interrupt for id=0x%"PRIx32", "
-           "offset=0x%"PRIx32", index=0x%"PRIx32"\n",
+           "bit_mask=0x%"PRIx32", index=0x%"PRIx32"\n",
            int_id, bit_mask, ind);
 
     enum IrqType irq_type = get_irq_type(int_id);
-
-    // Set the Interrupt Set Enable register to enable the interupt
-    // See ARM GIC TRM
-    if (irq_type == IrqType_SGI) {
-        MSG("unhandled SGI IRQ %d\n", int_id);
-        return;    // Do nothing for SGI interrupts
-    }
-
-    // XXX: check what we need to do if int_id > it_num_lines
-    //  -SG, 2012/12/13
-    assert(int_id <= it_num_lines);
+    // We only allow enableing PPI interrupts. 
+    assert(irq_type == IrqType_PPI);
 
     // Enable
     // 1 Bit per interrupt
-    regval = pl130_gic_ICDISER_rd(&gic, ind);
+    uint32_t regval = pl130_gic_dist_ICDISER_rd(&gic_dist, ind);
     regval |= bit_mask;
-    pl130_gic_ICDISER_wr(&gic, ind, regval);
+    pl130_gic_dist_ICDISER_wr(&gic_dist, ind, regval);
 
     // TODO: cleanup pl130 mackerel file so that we don't need bit magic
     // here.  -SG, 2012/12/13
@@ -223,91 +196,89 @@ void platform_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t pr
     prio = (prio & 0xF)<<4;
     switch(int_id % 4) {
     case 0:
-        pl130_gic_ICDIPR_prio_off0_wrf(&gic, ind, prio);
+        pl130_gic_dist_ICDIPR_prio_off0_wrf(&gic_dist, ind, prio);
         break;
     case 1:
-        pl130_gic_ICDIPR_prio_off1_wrf(&gic, ind, prio);
+        pl130_gic_dist_ICDIPR_prio_off1_wrf(&gic_dist, ind, prio);
         break;
     case 2:
-        pl130_gic_ICDIPR_prio_off2_wrf(&gic, ind, prio);
+        pl130_gic_dist_ICDIPR_prio_off2_wrf(&gic_dist, ind, prio);
         break;
     case 3:
-        pl130_gic_ICDIPR_prio_off3_wrf(&gic, ind, prio);
+        pl130_gic_dist_ICDIPR_prio_off3_wrf(&gic_dist, ind, prio);
         break;
     }
 
-    // Target processors (only SPIs)
-    // 8 Bit per interrupt
-    ind = int_id/4;
-    if (irq_type == IrqType_SPI) { // rest is ro
-        switch (int_id % 4) {
-        case 0:
-            pl130_gic_ICDIPTR_targets_off0_wrf(&gic, ind, cpu_targets);
-            break;
-        case 1:
-            pl130_gic_ICDIPTR_targets_off1_wrf(&gic, ind, cpu_targets);
-            break;
-        case 2:
-            pl130_gic_ICDIPTR_targets_off2_wrf(&gic, ind, cpu_targets);
-            break;
-        case 3:
-            pl130_gic_ICDIPTR_targets_off3_wrf(&gic, ind, cpu_targets);
-            break;
-        }
-    }
-
     // Configuration registers
     // 2 Bit per IRQ
     ind = int_id/16;
     uint8_t val = ((edge_triggered&0x1) << 1) | (one_to_n&0x1);
     switch (int_id % 16) {
     case 0:
-        pl130_gic_ICDICR_conf0_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf0_wrf(&gic_dist, ind, val);
         break;
     case 1:
-        pl130_gic_ICDICR_conf1_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf1_wrf(&gic_dist, ind, val);
         break;
     case 2:
-        pl130_gic_ICDICR_conf2_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf2_wrf(&gic_dist, ind, val);
         break;
     case 3:
-        pl130_gic_ICDICR_conf3_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf3_wrf(&gic_dist, ind, val);
         break;
     case 4:
-        pl130_gic_ICDICR_conf4_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf4_wrf(&gic_dist, ind, val);
         break;
     case 5:
-        pl130_gic_ICDICR_conf5_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf5_wrf(&gic_dist, ind, val);
         break;
     case 6:
-        pl130_gic_ICDICR_conf6_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf6_wrf(&gic_dist, ind, val);
         break;
     case 7:
-        pl130_gic_ICDICR_conf7_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf7_wrf(&gic_dist, ind, val);
         break;
     case 8:
-        pl130_gic_ICDICR_conf8_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf8_wrf(&gic_dist, ind, val);
         break;
     case 9:
-        pl130_gic_ICDICR_conf9_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf9_wrf(&gic_dist, ind, val);
         break;
     case 10:
-        pl130_gic_ICDICR_conf10_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf10_wrf(&gic_dist, ind, val);
         break;
     case 11:
-        pl130_gic_ICDICR_conf11_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf11_wrf(&gic_dist, ind, val);
         break;
     case 12:
-        pl130_gic_ICDICR_conf12_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf12_wrf(&gic_dist, ind, val);
         break;
     case 13:
-        pl130_gic_ICDICR_conf13_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf13_wrf(&gic_dist, ind, val);
         break;
     case 14:
-        pl130_gic_ICDICR_conf14_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf14_wrf(&gic_dist, ind, val);
         break;
     case 15:
-        pl130_gic_ICDICR_conf15_wrf(&gic, ind, val);
+        pl130_gic_dist_ICDICR_conf15_wrf(&gic_dist, ind, val);
         break;
     }
+    */
+}
+
+void dist_debug(void);
+void systime_set_timer(systime_t relative_timeout);
+void dist_debug(void)
+{
+    printf("Entering dist_debug...\n");
+    
+    uint32_t reg0 = pl130_gic_dist_ICDISER_rd(&gic_dist, 0);
+    uint32_t reg1 = pl130_gic_dist_ICDISER_rd(&gic_dist, 1);
+    uint32_t reg2 = pl130_gic_dist_ICDISER_rd(&gic_dist, 2);
+    printf("ICDISER[0] = %"PRIx32"\n", reg0);
+    printf("ICDISER[1] = %"PRIx32"\n", reg1);
+    printf("ICDISER[2] = %"PRIx32"\n", reg2);
+    systime_set_timer(100);
 }
+
+
index 0d5a8a1..e6e3232 100644 (file)
@@ -172,7 +172,7 @@ void gic_cpu_interface_enable(void)
  * \param 0 is level-sensitive, 1 is edge-triggered
  * \param 0 is N-to-N, 1 is 1-N
  */
-void platform_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t prio,
+void platform_enable_interrupt(uint32_t int_id, uint16_t prio,
                           bool edge_triggered, bool one_to_n)
 {
 }
index 7697fcc..46ddf85 100644 (file)
@@ -64,15 +64,9 @@ errval_t irq_table_set(unsigned int nidt, capaddr_t endpoint)
         }
         err = caps_copy_to_cte(&irq_dispatch[nidt], recv, false, 0, 0);
 
-        // Route the interrupt to this CPU, as we're the only CPU driver that
-        // knows where to send it.  XXX - this should change once we have more
-        // sophisticated interrupt routing.
-        //
-        // The mapping of interrupt interfaces to cores doesn't seem to be
-        // documented anywhere for the A9, and this will have to be different
-        // if we're using affinity routing on GICv3+ systems.
-        platform_enable_interrupt(nidt, BIT(my_core_id), 0,
-                IRQ_EDGE_TRIGGERED, IRQ_N_TO_N);
+        // Correct interrupt forwarding by the distributor must be ensured
+        // in userspace.
+        
         return err;
     }
 
index 1705578..d27fc3f 100644 (file)
@@ -251,8 +251,8 @@ arch_init(struct arm_core_data *boot_core_data,
     MSG("Debug port initialized.\n");
 
 
+    platform_revision_init();
     if (cpu_is_bsp()) {
-        platform_revision_init();
            MSG("%"PRIu32" cores in system\n", platform_get_core_count());
         MSG("Initializing the interrupt controller\n");
         platform_init_ic_bsp();
index 439a815..13ec1a0 100644 (file)
@@ -350,8 +350,11 @@ caps_map_l1(struct capability* dest,
             return SYS_ERR_VNODE_SLOT_INVALID;
         }
 
-        if (src->type != ObjType_Frame && src->type != ObjType_DevFrame) {
-            panic("oops: src->type != ObjType_Frame && src->type != ObjType_DevFrame");
+        if (src->type != ObjType_Frame && src->type != ObjType_DevFrame &&
+            src->type != ObjType_EndPointUMP) {
+            panic("oops: src->type != ObjType_Frame && "
+                  "src->type != ObjType_DevFrame &&"
+                  "src->type != ObjType_EndPointUMP");
             return SYS_ERR_WRONG_MAPPING;
         }
 
@@ -492,8 +495,11 @@ caps_map_l2(struct capability* dest,
         return SYS_ERR_VNODE_SLOT_INVALID;
     }
 
-    if (src->type != ObjType_Frame && src->type != ObjType_DevFrame) {
-        panic("oops: src->type != ObjType_Frame && src->type != ObjType_DevFrame");
+    if (src->type != ObjType_Frame && src->type != ObjType_DevFrame &&
+        src->type != ObjType_EndPointUMP) {
+        panic("oops: src->type != ObjType_Frame &&"
+              "src->type != ObjType_DevFrame &&"
+              "src->type != ObjType_EndPointUMP");
         return SYS_ERR_WRONG_MAPPING;
     }
 
index 1ac0e47..16615cb 100644 (file)
 
 /* These are called from the A9/A15 common GIC (interrupt controller) code. */
 
-lpaddr_t platform_gic_cpu_interface_base = A15MPCORE_GICC_OFFSET;
-lpaddr_t platform_gic_distributor_base = A15MPCORE_GICD_OFFSET;
+lpaddr_t platform_gic_cpu_interface_base = 0;
+lpaddr_t platform_gic_distributor_base = 0;
 
 /* A15 platforms don't need anything special done. */
 void platform_revision_init(void)
 {
-    platform_gic_cpu_interface_base += platform_get_private_region();
-    platform_gic_distributor_base += platform_get_private_region();
+    platform_gic_cpu_interface_base =
+        A15MPCORE_GICC_OFFSET + platform_get_private_region();
+    platform_gic_distributor_base =
+       A15MPCORE_GICD_OFFSET + platform_get_private_region();
 }
 
 /*
@@ -81,8 +83,8 @@ void platform_timer_init(int timeslice)
     if(timerirq == 0) timerirq= DEFAULT_TIMER_IRQ;
     MSG("Timer interrupt is %u\n", timerirq);
 
-    /* Enable the interrupt. */
-    platform_enable_interrupt(timerirq, 0, 0, 0, 0);
+    ///* Enable the interrupt. */
+    platform_enable_interrupt(timerirq, 0, 0, 0);
 
     /* Set the first timeout. */
     systime_set_timer(kernel_timeslice);
index 32c049e..0da4648 100644 (file)
@@ -88,7 +88,7 @@ void platform_timer_init(int timeslice)
     /* Global timer: use the Cortex-A9 Global Timer
        (see Cortex-A9 MPCore TRM 4.3). */
     a9_gt_init(platform_get_gt_address());
-    platform_enable_interrupt(GLOBAL_TIMER_IRQ, 0, 0, 0, 0);
+    platform_enable_interrupt(GLOBAL_TIMER_IRQ, 0, 0, 0);
     /* Discover the clock rate. */
     a9_probe_tsc();
     assert(systime_frequency != 0);
index e84eba5..9c2658a 100644 (file)
@@ -119,7 +119,8 @@ handle_frame_identify(
 
     struct registers_arm_syscall_args* sa = &context->syscall_args;
 
-    assert(to->type == ObjType_Frame || to->type == ObjType_DevFrame);
+    assert(to->type == ObjType_Frame || to->type == ObjType_DevFrame ||
+           to->type == ObjType_RAM   || to->type == ObjType_EndPointUMP);
     assert((get_address(to) & BASE_PAGE_MASK) == 0);
 
     struct frame_identity *fi = (struct frame_identity *)sa->arg2;
@@ -1354,11 +1355,15 @@ handle_invoke(arch_registers_state_t *context, int argc)
     return r;
 }
 
+extern void dist_debug(void);
 static struct sysret handle_debug_syscall(struct registers_arm_syscall_args* sa)
 {
     int msg = sa->arg1;
     struct sysret retval = { .error = SYS_ERR_OK };
     switch (msg) {
+        case DEBUG_GIC_DIST:
+            dist_debug();
+            break;
 
         case DEBUG_FLUSH_CACHE:
             invalidate_data_caches_pouu(true);
index 223baa3..ed9b14f 100644 (file)
@@ -239,7 +239,7 @@ void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
 
     irq = platform_get_active_irq();
 
-    // printk(LOG_NOTE, "handle_irq IRQ %"PRIu32"\n", irq);
+    printf("handle_irq IRQ %"PRIu32"\n", irq);
 
     debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
           dcb_current ? (dcb_current->disabled ? "disabled": "enabled") :
index 1894791..79b46e1 100644 (file)
@@ -144,7 +144,7 @@ errval_t platform_init_ic_app(void)
     return SYS_ERR_OK;
 }
 
-void platform_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t prio,
+void platform_enable_interrupt(uint32_t int_id, uint16_t prio,
                               bool edge_triggered, bool one_to_n)
 {
 }
index 414129d..212a0b0 100644 (file)
@@ -84,7 +84,7 @@ extern size_t platform_uart_size[];
  errval_t platform_init_ic_app(void);
  uint32_t platform_get_active_irq(void);
  void     platform_acknowledge_irq(uint32_t irq);
- void     platform_enable_interrupt(uint32_t int_id, uint8_t cpu_targets, uint16_t prio,
+ void     platform_enable_interrupt(uint32_t int_id, uint16_t prio,
                                bool edge_triggered, bool one_to_n);
 
 /*
index 673ded7..151c6eb 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <inttypes.h>
 
+
 errval_t sys_nop(void)
 {
     return syscall1(SYSCALL_NOP).error;
@@ -35,6 +36,11 @@ errval_t sys_debug_context_counter_reset(void)
     return syscall2(SYSCALL_DEBUG, DEBUG_CONTEXT_COUNTER_RESET).error;
 }
 
+errval_t sys_debug_gic_dist(void)
+{
+    return syscall2(SYSCALL_DEBUG, DEBUG_GIC_DIST).error;
+}
+
 errval_t sys_debug_context_counter_read(uint64_t *ret)
 {
     struct sysret sr = syscall2(SYSCALL_DEBUG, DEBUG_CONTEXT_COUNTER_READ);
index 7572001..af18207 100644 (file)
@@ -129,6 +129,7 @@ static struct dcontrol_rx_vtbl rpc_rx_vtbl = {
 errval_t dcontrol_service_init(struct bfdriver_instance* bfi, struct waitset* ws, 
                                 bool lmp, struct capref* ret_cap)
 {
+    debug_printf("dcontrol_service_init: enter\n");
     struct waitset* service_ws = (ws == NULL) ? get_default_waitset() : ws;
     
     errval_t err = dcontrol_create_endpoint(lmp? IDC_ENDPOINT_LMP: IDC_ENDPOINT_UMP, 
index 34fc2f7..aea8bbf 100644 (file)
@@ -116,7 +116,8 @@ static void create_handler(struct ddomain_binding* binding, const char* cls, siz
         inst->argv[3] = NULL;
     }
 
-    strncpy(inst->name, name, sizeof(inst->name));
+    DRIVERKIT_DEBUG("sizeof(inst->name)=%d\n", sizeof(inst->name));
+    strncpy(inst->name, name, 256);
 
     err = slot_alloc(&inst->ctrl);
     if (err_is_fail(err)){
@@ -219,6 +220,8 @@ static void create_with_argcn_handler(struct ddomain_binding* binding,
         goto send_reply;
     }
 
+    strncpy(inst->name, name, 256);
+
     DRIVERKIT_DEBUG("Instantiate driver\n");
     err = driverkit_create_driver(cls, inst, flags, &dev, &inst->ctrl);
     if (err_is_fail(err)) {
index 46383ef..f19011d 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef __DRIVERKIT_DEBUG__
 #define __DRIVERKIT_DEBUG__
 
-//#define ENABLE_DRIVERKIT_DEBUG 1
+#define ENABLE_DRIVERKIT_DEBUG 1
 
 #if defined(ENABLE_DRIVERKIT_DEBUG) || defined(GLOBAL_DEBUG)
 #define DRIVERKIT_DEBUG(x...) debug_printf("[dkit] " x)
index 82459c1..65e0d10 100644 (file)
@@ -194,7 +194,8 @@ errval_t driverkit_create_driver(const char* cls, struct bfdriver_instance *inst
 
     err = drv->init(inst, flags, device);
     if (err_is_fail(err)) {
-       // DEBUG_ERR(err, "Can't initialize the device");
+        //DRIVERKIT_DEBUG("Init returned error...\n");
+        DEBUG_ERR(err, "Can't initialize the device");
         free_driver_instance(inst);
         return err_push(err, DRIVERKIT_ERR_DRIVER_INIT);
     }
@@ -202,7 +203,7 @@ errval_t driverkit_create_driver(const char* cls, struct bfdriver_instance *inst
     // Since Kaluga always has to be on core 0, we can do this ...
     err = dcontrol_service_init(inst, NULL, (disp_get_core_id() == 0), control);
     if (err_is_fail(err)) {
-       // DEBUG_ERR(err, "Can't set-up control interface for device.");
+        DEBUG_ERR(err, "Can't set-up control interface for device.");
         free_driver_instance(inst);
         return err_push(err, DRIVERKIT_ERR_CONTROL_SERVICE_INIT);
     }
index 6947a48..395ef97 100644 (file)
@@ -12,6 +12,8 @@
 
 [
 
+    --- This library co-locates the interrupt routing server into an existing
+    --- domain
     build library { target = "int_route_server",
                     cFiles = [ "server/init.c" ],
                     flounderDefs = [ "int_route_service" ],
                     flounderDefs = [ "int_route_service" ],
                     flounderBindings = [ "int_route_service" ],
                     flounderExtraBindings = [ ("int_route_service", ["rpcclient"]) ]
+                   },
+
+    -- We run a stand alone IRS on ARMv7
+    build application { target = "int_route",
+                    cFiles = [ "server/standalone.c" ],
+                    flounderDefs = [ "int_route_service" ],
+                    flounderBindings = [ "int_route_service", "int_route_controller" ],
+                    flounderExtraBindings = [ ("int_route_service", ["rpcclient"]) ],
+                    architectures = ["armv7"]
                    }
 ]
diff --git a/lib/int_route/server/standalone.c b/lib/int_route/server/standalone.c
new file mode 100644 (file)
index 0000000..5966f57
--- /dev/null
@@ -0,0 +1,248 @@
+/**
+ * \file
+ * \brief Contains handler functions for server-side octopus interface RPC call.
+ */
+
+/*
+ * Copyright (c) 2009, 2010, 2012, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <errno.h>
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+#include <skb/skb.h> // read list
+#include <int_route/int_route_server.h>
+#include <int_route/int_route_debug.h>
+
+#include <if/int_route_service_defs.h>
+#include <if/int_route_controller_defs.h>
+
+struct controller_driver {
+   char * label; // Label used in the SKB
+   char * class; // Class used in the SKB
+   struct int_route_controller_binding * binding; //
+   struct controller_driver * next; // Linked list next
+};
+
+/* This server exports two interfaces:
+ * * RPC interface - This is RPC the interface that
+ * * Controller interface - Interrupt controllers use a
+ */
+
+struct controller_driver * controller_head;
+static int exported = 0;
+
+static struct controller_driver * add_controller(struct controller_driver * d){
+    struct controller_driver * cur;
+    if(controller_head == NULL){
+        controller_head = malloc(sizeof(struct controller_driver));
+        cur = controller_head;
+    } else if(d != NULL && d->next != NULL){
+        return add_controller(d->next);
+    } else {
+        assert(d != NULL);
+        d->next = malloc(sizeof(struct controller_driver));
+        cur = d->next;
+    }
+
+    // Initialize cur
+    cur->next = NULL;
+    cur->binding = NULL;
+    cur->label = NULL;
+    cur->class = NULL;
+    return cur;
+}
+
+/*
+ * Finds a controller for the given label/class combination.
+ * First, if a label is passed, it tries to match the label exactly, if no
+ * controller is found, it goes on to match on the class.
+ */
+static struct controller_driver *find_controller(const char *label,
+                                                 const char *class) {
+    if (label != NULL && strlen(label) > 0) {
+        for (struct controller_driver *cur = controller_head; cur != NULL;
+             cur = cur->next) {
+            if (strcmp(label, cur->label) == 0) {
+                return cur;
+            }
+        }
+    }
+    if (class != NULL && strlen(class) > 0) {
+        for (struct controller_driver *cur = controller_head; cur != NULL;
+             cur = cur->next) {
+            if (strcmp(class, cur->class) == 0) {
+                return cur;
+            }
+        }
+    }
+    return NULL;
+}
+
+struct controller_add_mapping_data {
+    char * lbl;
+    char * class;
+    int_route_controller_int_message_t in_msg;
+    int_route_controller_int_message_t out_msg;
+    struct int_route_controller_binding *binding;
+};
+
+#define INVALID_PORT -1
+#define INVALID_VECTOR ((uint64_t)-1)
+
+/**
+ * Since on ARMv7 the topolgy is easy, we don't use the SKB.
+ */
+static void driver_route_call_armv7(struct int_route_service_binding *b,
+        struct capref intsource, int irq_idx,
+        struct capref intdest){
+    INT_DEBUG("%s: enter\n", __FUNCTION__);
+
+    errval_t err;
+    uint64_t int_src_num = INVALID_VECTOR;
+    err = invoke_irqsrc_get_vec_start(intsource, &int_src_num);
+    uint64_t int_src_num_high = INVALID_VECTOR;
+    err = invoke_irqsrc_get_vec_end(intsource, &int_src_num_high);
+    if(int_src_num + irq_idx > int_src_num_high || irq_idx < 0){
+        err = SYS_ERR_IRQ_INVALID;
+        DEBUG_ERR(err, "irq_idx out of range");
+        b->tx_vtbl.route_response(b, NOP_CONT, err);
+        return;
+    }
+
+    assert(err_is_ok(err));
+    int_src_num += irq_idx;
+
+    uint64_t dest_vec = INVALID_VECTOR;
+    err = invoke_irqdest_get_vector(intdest, &dest_vec);
+    assert(err_is_ok(err));
+
+    uint64_t dest_cpu = INVALID_VECTOR;
+    err = invoke_irqdest_get_cpu(intdest, &dest_cpu);
+    assert(err_is_ok(err));
+
+    printf("Int route service: Routing request, (int=%"PRIu64") to "
+            "(cpu=%"PRIu64",vec=%"PRIu64")\n",
+            int_src_num, dest_cpu, dest_vec);
+
+
+    const char * class = "gic_dist";
+    struct controller_driver * gic_dist = find_controller(NULL, class);
+
+    if(gic_dist == NULL){
+        err = SYS_ERR_IRQ_INVALID;
+        DEBUG_ERR(err, "gic_dist controller not found!\n");
+    } else {
+        int_route_controller_int_message_t in_msg;
+        in_msg.port = int_src_num;
+        int_route_controller_int_message_t out_msg;
+        out_msg.port = dest_cpu;
+        err = int_route_controller_add_mapping__tx(gic_dist->binding,
+                BLOCKING_CONT, NULL, class, in_msg,
+                out_msg);
+        assert(err_is_ok(err));
+    }
+
+    b->tx_vtbl.route_response(b, NOP_CONT, SYS_ERR_IRQ_INVALID);
+}
+
+static void ctrl_register_controller(struct int_route_controller_binding *_binding,
+        const char *label, const char *class) {
+    struct controller_driver * c = add_controller(controller_head);
+    c->label = malloc(strlen(label)+1);
+    assert(c->label != NULL);
+    strcpy(c->label, label);
+
+    c->class = malloc(strlen(class)+1);
+    assert(c->class != NULL);
+    strcpy(c->class, class);
+    INT_DEBUG("ctrl_register_controller, label=%s, class=%s\n",c->label, c->class);
+
+    c->binding = _binding;
+}
+
+
+static struct int_route_service_rx_vtbl driver_rx_vtbl = {
+        .route_call = driver_route_call_armv7
+
+};
+
+static struct int_route_controller_rx_vtbl ctrl_rx_vtbl = {
+        .register_controller = ctrl_register_controller
+};
+
+static errval_t driver_connect_cb(void *st, struct int_route_service_binding *b) {
+    INT_DEBUG("%s: enter\n", __FUNCTION__);
+    b->st = NULL;
+    b->rx_vtbl = driver_rx_vtbl;
+    return SYS_ERR_OK;
+
+}
+
+static errval_t ctrl_connect_cb(void *st, struct int_route_controller_binding *b) {
+    INT_DEBUG("%s: enter\n", __FUNCTION__);
+    b->st = NULL;
+    b->rx_vtbl = ctrl_rx_vtbl;
+    return SYS_ERR_OK;
+
+}
+
+static void driver_export_cb(void *st, errval_t err, iref_t iref){
+    INT_DEBUG("%s: enter\n", __FUNCTION__);
+    assert(err_is_ok(err));
+
+    err = nameservice_register("int_route_service", iref);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "nameservice_register 1 failed");
+    };
+    exported++;
+}
+
+static void ctrl_export_cb(void *st, errval_t err, iref_t iref){
+    INT_DEBUG("%s: enter\n", __FUNCTION__);
+    assert(err_is_ok(err));
+
+    err = nameservice_register("int_ctrl_service", iref);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "nameservice_register 2 failed");
+    };
+    exported++;
+}
+
+
+// The main function of this service
+int main(void) {
+    errval_t err;
+    debug_printf("Start\n");
+
+    // Export route service for PCI device drivers
+    err = int_route_service_export(NULL, driver_export_cb, driver_connect_cb,
+                                   get_default_waitset(),
+                                   IDC_EXPORT_FLAGS_DEFAULT);
+
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "int_route_service_export failed");
+    }
+
+    err = int_route_controller_export(NULL, ctrl_export_cb, ctrl_connect_cb,
+                                      get_default_waitset(),
+                                      IDC_EXPORT_FLAGS_DEFAULT);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "int_route_controller_export failed");
+    }
+
+    while (true) {
+        event_dispatch(get_default_waitset());
+    }
+
+    return 0;
+}
index 0793460..0f1a4ab 100644 (file)
@@ -287,7 +287,8 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                         "serial_kernel",
                         "angler",
                         "corectrl",
-                        "driverdomain"
+                        "driverdomain",
+                        "int_route"
                         ] ]
 
     -- ARMv7-A modules for Versatile Express EMM board (GEM5, qemu)
@@ -307,7 +308,9 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                                "skb",
                                "angler",
                                "fish",
-                               "memtest"
+                               "memtest",
+                               "driverdomain",
+                               "int_route"
                                ] ]
 
     -- ARMv7-A modules for Versatile Express EMM board (FVP)
@@ -546,6 +549,8 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
        ("root", "/armv7_a15ve_1_image-gdb.gdb"),
        ("root", "/armv7_a15ve_fvp_1_image"),
        ("root", "/armv7_a15ve_fvp_1_image-gdb.gdb"),
+       ("root", "/armv7_a15ve_2_image"),
+       ("root", "/armv7_a15ve_2_image-gdb.gdb"),
        ("root", "/armv7_a15ve_4_image"),
        ("root", "/armv7_a15ve_4_image-gdb.gdb"),
        ("root", "/armv7_a15ve_fvp_4_image"),
@@ -588,6 +593,9 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
     -- quirks)
     armv7Image "armv7_a15ve_fvp_1" "ve" "a15ve" "0x80000000" vExpressEMMModules_A15,
 
+    -- Build the A15 simulation image (VersatileExpress EMM board, 2 cores)
+    armv7Image "armv7_a15ve_2" "ve" "a15ve" "0x80000000" vExpressEMMModules_A15,
+
     -- Build the A15 simulation image (VersatileExpress EMM board, 4 cores)
     armv7Image "armv7_a15ve_4" "ve" "a15ve" "0x80000000" vExpressEMMModules_A15,
 
@@ -631,6 +639,7 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                      "armv7_a9ve_1",
                      "armv7_a9ve_4",
                      "armv7_a15ve_1",
+                     "armv7_a15ve_2",
                      "armv7_a15ve_4",
                      "armv7_a15ve_fvp_1",
                      "armv7_a15ve_fvp_4",
@@ -702,6 +711,13 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
       Str "--smp", Str "1" ]
     "Boot QEMU in 32-bit ARM mode emulating a Versatile Express board (1 core)",
 
+    boot "qemu_a15ve_2" [ "armv7" ] [
+      In SrcTree "tools" "/tools/qemu-wrapper.sh",
+      Str "--image", In BuildTree "root" "/armv7_a15ve_2_image",
+      Str "--arch", Str "a15ve",
+      Str "--smp", Str "2" ]
+    "Boot QEMU in 32-bit ARM mode emulating a Versatile Express board (2 core)",
+
     boot "qemu_a15ve_4" [ "armv7" ] [
       In SrcTree "tools" "/tools/qemu-wrapper.sh",
       Str "--image", In BuildTree "root" "/armv7_a15ve_4_image",
index a48b20c..f23c25d 100644 (file)
@@ -28,7 +28,8 @@
     cFiles = [ "main.c"],
     addLinkFlags = ["-T" ++ Config.source_dir ++ "/lib/driverkit/bfdrivers.ld" ],
     addLibraries = libDeps [ "driverkit", "thc" ],
-    addModules = ["fdif_module", "sdma_module", "cm2_module", "twl6030_module", "mmchs_module"],
+    addModules = ["fdif_module", "sdma_module", "cm2_module", "twl6030_module",
+                  "mmchs_module", "pl130_dist_module"],
     architectures = ["armv7"]
   }
 ]
diff --git a/usr/drivers/omap44xx/pl130_dist/Hakefile b/usr/drivers/omap44xx/pl130_dist/Hakefile
new file mode 100644 (file)
index 0000000..621706b
--- /dev/null
@@ -0,0 +1,20 @@
+--------------------------------------------------------------------------
+-- Copyright (c) 2007-2014, ETH Zurich.
+-- All rights reserved.
+--
+-- This file is distributed under the terms in the attached LICENSE file.
+-- If you do not find this file, copies can be found by writing to:
+-- ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+--
+-- Hakefile for omap44xx sdma driver
+--
+--------------------------------------------------------------------------
+
+[
+    build library { target = "pl130_dist_module",
+                    flounderBindings = [ "int_route_controller" ],
+                    cFiles = ["main.c"],
+                    mackerelDevices = [ "pl130_gic_dist" ],
+                    architectures = ["armv7"]
+    }
+]
diff --git a/usr/drivers/omap44xx/pl130_dist/debug.h b/usr/drivers/omap44xx/pl130_dist/debug.h
new file mode 100644 (file)
index 0000000..4e75af7
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef PL130_DEBUG_H_
+#define PL130_DEBUG_H_
+
+#define PL130_DEBUG_ON
+
+#if defined(PL130_DEBUG_ON)
+#define PL130_DEBUG(x...) debug_printf("pl130_dist:" x)
+#else
+#define PL130_DEBUG(x...) ((void)0) 
+#endif 
+
+#endif
diff --git a/usr/drivers/omap44xx/pl130_dist/main.c b/usr/drivers/omap44xx/pl130_dist/main.c
new file mode 100644 (file)
index 0000000..ffd4b76
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2014, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/nameservice_client.h>
+#include <driverkit/driverkit.h>
+
+//HACK
+#include <barrelfish/sys_debug.h>
+//ENDHACK
+
+#include <dev/pl130_gic_dist_dev.h>
+#include <if/int_route_controller_defs.h>
+
+#include "debug.h"
+
+
+struct pl130_dist_driver_state {
+    pl130_gic_dist_t devgic;
+    uint32_t it_num_lines;
+    int cpu_index;
+    int cpu_count;
+};
+
+enum IrqType {
+    IrqType_SGI,
+    IrqType_PPI,
+    IrqType_SPI
+};
+
+/**
+ * \brief Returns the IRQ type based on the interrupt ID
+ *
+ * We have three types of interrupts
+ * 1) Software generated Interrupts (SGI): IDs 0-15
+ * 2) Private Peripheral Interrupts (PPI): IDs 16-31
+ * 3) Shared Peripheral Interrups (SPI): IDs 32-
+ *
+ * \return The type of the interrupt.
+ */
+static enum IrqType get_irq_type(uint32_t int_id)
+{
+    if (int_id < 16) {
+        return IrqType_SGI;
+    } else if (int_id < 32) {
+        return IrqType_PPI;
+    } else {
+        return IrqType_SPI;
+    }
+}
+
+
+__attribute__((unused))
+static void gic_raise_softirq(struct pl130_dist_driver_state * ds, uint8_t cpumask, uint8_t irq)
+{
+    uint32_t regval = (cpumask << 16) | irq;
+    pl130_gic_dist_ICDSGIR_wr(&ds->devgic, regval);
+};
+
+
+static errval_t pl130_dist_init(struct pl130_dist_driver_state * ds, mackerel_addr_t reg_base){
+    pl130_gic_dist_initialize(&ds->devgic, reg_base);
+
+    // read GIC configuration
+    pl130_gic_dist_ICDICTR_t gic_config = pl130_gic_dist_ICDICTR_rd(&ds->devgic);
+
+    // ARM GIC 2.0 TRM, Table 4-6
+    // This is the number of ICDISERs, i.e. #SPIs
+    // Number of SGIs (0-15) and PPIs (16-31) is fixed
+    uint32_t it_num_lines_tmp =
+        pl130_gic_dist_ICDICTR_it_lines_num_extract(gic_config);
+    ds->it_num_lines = 32*(it_num_lines_tmp + 1);
+    ds->cpu_count = pl130_gic_dist_ICDICTR_cpu_number_extract(gic_config) + 1;
+    // TODO: determine cpu index
+    ds->cpu_index = 0;
+
+    PL130_DEBUG("interrupt lines = %d\n", ds->it_num_lines);
+    PL130_DEBUG("cpu_count = %d\n", ds->cpu_count);
+
+    // Distributor:
+    // enable interrupt forwarding from distributor to cpu interface
+    pl130_gic_dist_ICDDCR_enable_wrf(&ds->devgic, 0x1);
+
+    return SYS_ERR_OK;
+}
+
+
+/**
+ * \brief Enable an interrupt
+ *
+ * \see ARM Generic Interrupt Controller Architecture Specification v1.0
+ *
+ * \param int_id
+ * \param cpu_targets 8 Bit mask. One bit for each core in the system.
+ *    (chapter 4.3.11)
+ * \param prio Priority of the interrupt (lower is higher). We allow 0..15.
+ *    The number of priority bits is implementation specific, but at least 16
+ *    (using bits [7:4] of the priority field, chapter 3.3)
+ * \param 0 is level-sensitive, 1 is edge-triggered
+ * \param 0 is N-to-N, 1 is 1-N
+ */
+static errval_t enable_interrupt(struct pl130_dist_driver_state *ds, int int_id,
+    uint8_t cpu_targets, bool edge_triggered, bool one_to_n, uint16_t prio)
+{
+
+    uint32_t ind = int_id / 32;
+    uint32_t bit_mask = (1U << (int_id % 32));
+    enum IrqType irq_type = get_irq_type(int_id);
+
+    // We allow PPI on any core, and SPI only on instance 0
+    if(!(irq_type == IrqType_PPI
+         || (irq_type == IrqType_SPI && int_id <= ds->it_num_lines)))
+    {
+        PL130_DEBUG("invalid int_id=%d on cpu=%d\n", int_id, ds->cpu_index);
+        return SYS_ERR_IRQ_INVALID;
+    }
+    
+    // Enable
+    // 1 Bit per interrupt
+    uint32_t regval = pl130_gic_dist_ICDISER_rd(&ds->devgic, ind);
+    regval |= bit_mask;
+    pl130_gic_dist_ICDISER_wr(&ds->devgic, ind, regval);
+
+    // TODO: cleanup pl130 mackerel file so that we don't need bit magic
+    // here.  -SG, 2012/12/13
+
+    // Priority
+    // 8 Bit per interrupt
+    // chp 4.3.10
+    ind = int_id/4;
+    // XXX: check that priorities work properly, -SG, 2012/12/13
+    prio = (prio & 0xF)<<4;
+    switch(int_id % 4) {
+    case 0:
+        pl130_gic_dist_ICDIPR_prio_off0_wrf(&ds->devgic, ind, prio);
+        break;
+    case 1:
+        pl130_gic_dist_ICDIPR_prio_off1_wrf(&ds->devgic, ind, prio);
+        break;
+    case 2:
+        pl130_gic_dist_ICDIPR_prio_off2_wrf(&ds->devgic, ind, prio);
+        break;
+    case 3:
+        pl130_gic_dist_ICDIPR_prio_off3_wrf(&ds->devgic, ind, prio);
+        break;
+    }
+
+    // Target processors (only SPIs)
+    // 8 Bit per interrupt
+    ind = int_id/4;
+    if (irq_type == IrqType_SPI) { // rest is ro
+        switch (int_id % 4) {
+        case 0:
+            pl130_gic_dist_ICDIPTR_targets_off0_wrf(&ds->devgic, ind, cpu_targets);
+            break;
+        case 1:
+            pl130_gic_dist_ICDIPTR_targets_off1_wrf(&ds->devgic, ind, cpu_targets);
+            break;
+        case 2:
+            pl130_gic_dist_ICDIPTR_targets_off2_wrf(&ds->devgic, ind, cpu_targets);
+            break;
+        case 3:
+            pl130_gic_dist_ICDIPTR_targets_off3_wrf(&ds->devgic, ind, cpu_targets);
+            break;
+        }
+    }
+
+    // Configuration registers
+    // 2 Bit per IRQ
+    ind = int_id/16;
+    uint8_t val = ((edge_triggered&0x1) << 1) | (one_to_n&0x1);
+    switch (int_id % 16) {
+    case 0:
+        pl130_gic_dist_ICDICR_conf0_wrf(&ds->devgic, ind, val);
+        break;
+    case 1:
+        pl130_gic_dist_ICDICR_conf1_wrf(&ds->devgic, ind, val);
+        break;
+    case 2:
+        pl130_gic_dist_ICDICR_conf2_wrf(&ds->devgic, ind, val);
+        break;
+    case 3:
+        pl130_gic_dist_ICDICR_conf3_wrf(&ds->devgic, ind, val);
+        break;
+    case 4:
+        pl130_gic_dist_ICDICR_conf4_wrf(&ds->devgic, ind, val);
+        break;
+    case 5:
+        pl130_gic_dist_ICDICR_conf5_wrf(&ds->devgic, ind, val);
+        break;
+    case 6:
+        pl130_gic_dist_ICDICR_conf6_wrf(&ds->devgic, ind, val);
+        break;
+    case 7:
+        pl130_gic_dist_ICDICR_conf7_wrf(&ds->devgic, ind, val);
+        break;
+    case 8:
+        pl130_gic_dist_ICDICR_conf8_wrf(&ds->devgic, ind, val);
+        break;
+    case 9:
+        pl130_gic_dist_ICDICR_conf9_wrf(&ds->devgic, ind, val);
+        break;
+    case 10:
+        pl130_gic_dist_ICDICR_conf10_wrf(&ds->devgic, ind, val);
+        break;
+    case 11:
+        pl130_gic_dist_ICDICR_conf11_wrf(&ds->devgic, ind, val);
+        break;
+    case 12:
+        pl130_gic_dist_ICDICR_conf12_wrf(&ds->devgic, ind, val);
+        break;
+    case 13:
+        pl130_gic_dist_ICDICR_conf13_wrf(&ds->devgic, ind, val);
+        break;
+    case 14:
+        pl130_gic_dist_ICDICR_conf14_wrf(&ds->devgic, ind, val);
+        break;
+    case 15:
+        pl130_gic_dist_ICDICR_conf15_wrf(&ds->devgic, ind, val);
+        break;
+    }
+
+    return SYS_ERR_OK;
+}
+
+static void add_mapping(struct int_route_controller_binding *b,
+        const char *label,
+        const char *class,
+        int_route_controller_int_message_t from,
+        int_route_controller_int_message_t to)
+{
+    errval_t err;
+    PL130_DEBUG("add_mapping: label:%s, class:%s (%"PRIu64", %"PRIu64") to "
+            "(%"PRIu64", %"PRIu64")\n", label, class, from.addr, from.msg, to.addr, to.msg);
+    // TODO: CPU mask
+    err = enable_interrupt(b->st, from.port, 0, 0, 0, 0);
+    assert(err_is_ok(err));
+}
+
+static void bind_cb(void *st, errval_t err, struct int_route_controller_binding *b) {
+    struct pl130_dist_driver_state * ds = st;
+
+    if(!err_is_ok(err)){
+        DEBUG_ERR(err, "Bind failure\n");
+        return;
+    }
+
+    b->st = st;
+    b->rx_vtbl.add_mapping = add_mapping;
+
+    // Register this binding for all controllers with class pcilnk
+    char label[128];
+    snprintf(label, sizeof(label), "dist_%d", ds->cpu_index);
+    const char * ctrl_class = "gic_dist";
+    HERE;
+    b->tx_vtbl.register_controller(b, NOP_CONT, label, ctrl_class);
+}
+
+static errval_t connect_to_irs(struct bfdriver_instance *bfi) {
+    // Connect to int route service
+    iref_t int_route_service;
+    errval_t err;
+    PL130_DEBUG("int_ctrl_service lookup...\n");
+    err = nameservice_blocking_lookup("int_ctrl_service", &int_route_service);
+    if (!err_is_ok(err)) {
+        DEBUG_ERR(err, "Could not lookup int_route_service\n");
+        return err;
+    }
+
+    HERE;
+    err = int_route_controller_bind(
+        int_route_service, bind_cb, bfi,
+        get_default_waitset(), IDC_BIND_FLAGS_DEFAULT);
+
+    if (!err_is_ok(err)) {
+        DEBUG_ERR(err, "Could not bind int_route_service\n");
+        return err;
+    }
+    HERE;
+
+    return SYS_ERR_OK;
+}
+
+
+static errval_t init(struct bfdriver_instance* bfi, uint64_t flags, iref_t *dev) {
+    errval_t err;
+    PL130_DEBUG("Entering driver init. name=%s\n", bfi->name);
+
+    bfi->dstate = malloc(sizeof(struct pl130_dist_driver_state));
+    assert(bfi->dstate != NULL);
+
+    // Map device registers
+    struct capref mem_cap = {
+        .cnode = bfi->argcn,
+        .slot = 0
+    };
+
+    lvaddr_t dev_base;
+    err = map_device_cap(mem_cap, &dev_base);
+    USER_PANIC_ON_ERR(err, "map_device_cap");
+
+    // Initialize driver structure
+    err = pl130_dist_init(bfi->dstate, (mackerel_addr_t)dev_base);
+    USER_PANIC_ON_ERR(err, "pl130_dist_init");
+
+    //HACK
+    //if(strcmp(bfi->name, "hw.arm.gic.dist.1") == 0)
+    //    sys_debug_gic_dist();
+    //ENDHACK
+
+    PL130_DEBUG("ENABLING TIMER INTERRUPT!\n");
+    err = enable_interrupt(bfi->dstate, 29, 0, 0, 0, 0);
+    assert(err_is_ok(err));
+    //err = enable_interrupt(bfi->dstate, 30, 0, 0, 0, 0);
+    //assert(err_is_ok(err));
+    PL130_DEBUG("ENABLED TIMER INTERRUPT!\n");
+
+    //HACK
+    //if(strcmp(bfi->name, "hw.arm.gic.dist.1") == 0)
+    //    sys_debug_gic_dist();
+    //ENDHACK
+
+    // Connect to interrupt routing service
+    err = connect_to_irs(bfi->dstate);
+    assert(err_is_ok(err));
+
+    HERE;
+    return SYS_ERR_OK;
+}
+
+static errval_t attach(struct bfdriver_instance* bfi) {
+    return SYS_ERR_OK;
+}
+
+static errval_t detach(struct bfdriver_instance* bfi) {
+    return SYS_ERR_OK;
+}
+
+static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
+    return SYS_ERR_OK;
+}
+
+static errval_t destroy(struct bfdriver_instance* bfi) {
+    struct pl130_dist_driver_state* uds = bfi->dstate;
+    free(uds);
+    bfi->dstate = NULL;
+    // XXX: Tear-down the service
+    bfi->device = 0x0;
+    return SYS_ERR_OK;
+}
+
+static errval_t get_ep(struct bfdriver_instance* bfi, bool lmp, struct capref* ret_cap)
+{   
+    USER_PANIC("NIY \n");
+    return SYS_ERR_OK;
+}
+
+DEFINE_MODULE(pl130_dist, init, attach, detach, set_sleep_level, destroy, get_ep);
index 4ea4655..6a80da7 100644 (file)
 #include <barrelfish/barrelfish.h>
 #include <barrelfish_kpi/platform.h>
 #include <if/monitor_blocking_defs.h>
+#include <maps/vexpress_map.h>
 
 #include <skb/skb.h>
 #include <octopus/getset.h>
 
 #include "kaluga.h"
 
-static void start_driverdomain(char* record) {
+static void start_driverdomain(char* module_name, char* record) {
     struct module_info* mi = find_module("driverdomain");
+    struct driver_argument arg;
+    arg.module_name = module_name;
     if (mi != NULL) {
-        errval_t err = mi->start_function(0, mi, record, NULL);
+        errval_t err = mi->start_function(0, mi, record, &arg);
         assert(err_is_ok(err));
+    } else {
+        debug_printf("driverdomain not found!\n");
     }
 }
 
@@ -38,9 +43,10 @@ static errval_t omap44xx_startup(void)
     err = init_device_caps_manager();
     assert(err_is_ok(err));
 
-    start_driverdomain("fdif {}");
-    start_driverdomain("sdma {}");
-    start_driverdomain("mmchs { dep1: 'cm2', dep2: 'twl6030' }");
+    //start_driverdomain("pl130_dist", "pl130_dist {}");
+    start_driverdomain("fdif", "fdif {}");
+    start_driverdomain("sdma", "sdma {}");
+    start_driverdomain("mmchs", "mmchs { dep1: 'cm2', dep2: 'twl6030' }");
 
     struct module_info* mi = find_module("prcm");
     if (mi != NULL) {
@@ -79,14 +85,84 @@ static errval_t omap44xx_startup(void)
     return SYS_ERR_OK;
 }
 
+/**
+ * \brief Starts the gic distributor driver on every core
+ *
+ */
+static errval_t start_all_gic_dist(void){
+    errval_t err;
+
+    /* Prepare module and cap */
+    struct module_info *mi = find_module("driverdomain");
+    if (mi == NULL) {
+        debug_printf("Binary driverdomain not found!\n");
+        return KALUGA_ERR_MODULE_NOT_FOUND;
+    }
+    struct capref dist_reg;
+    err = get_device_cap(VEXPRESS_MAP_GIC_DIST, VEXPRESS_MAP_GIC_DIST_SIZE,
+            &dist_reg);
+    if(err_is_fail(err)){
+        DEBUG_ERR(err, "Get gic_dist device cap\n");
+        return err;
+    }
+    struct driver_argument arg;
+    init_driver_argument(&arg);
+    arg.module_name = "pl130_dist";
+    struct capref dst = {
+        .cnode = arg.argnode_ref,
+        .slot = 0
+    };
+    err = cap_copy(dst, dist_reg);
+    if(err_is_fail(err)){
+        DEBUG_ERR(err, "cap_copy\n");
+        return err;
+    }
+
+    /* Iterate over cores */
+    err= skb_execute_query("arm_mpids(L),write(L).");
+    if (err_is_fail(err)) {
+        USER_PANIC_SKB_ERR(err, "Finding cores.");
+    }
+
+    /* Create Octopus records for the known cores. */
+    int mpidr_raw;
+    struct list_parser_status skb_list;
+    skb_read_list_init(&skb_list);
+    while(skb_read_list(&skb_list, "mpid(%d)", &mpidr_raw)) {
+        char oct_key[128];
+        snprintf(oct_key, sizeof(oct_key), "hw.arm.gic.dist.%d {}", mpidr_raw); 
+        debug_printf("starting pl130_dist on core=%d\n", mpidr_raw);
+        err = mi->start_function(mpidr_raw, mi, oct_key, &arg);
+        if(err_is_fail(err)){
+            DEBUG_ERR(err, "couldnt start gic dist on core=%d\n", mpidr_raw);
+            return err;
+        }
+    }
+    return SYS_ERR_OK;
+}
+
 static errval_t vexpress_startup(void)
 {
     errval_t err;
+    err = init_device_caps_manager();
+    assert(err_is_ok(err));
+
+    HERE;
+    err = start_all_gic_dist();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Unable to start all gic dist.");
+    }
+
+    HERE;
     struct module_info* mi = find_module("serial_pl011");
     if (mi != NULL) {
         err = mi->start_function(0, mi, "hw.arm.vexpress.uart {}", NULL);
         assert(err_is_ok(err));
+    } else {
+        debug_printf("Module serial_pl011 not found!\n");
     }
+
+
     return SYS_ERR_OK;
 }
 
@@ -167,7 +243,7 @@ errval_t arch_startup(char * add_device_db_file)
 
     /* Query the SKB for the available cores on this platform - we can't
      * generally discover this on ARMv7. */
-    err= skb_execute_query("arm_mpids(L) ,write(L).");
+    err= skb_execute_query("arm_mpids(L),write(L).");
     if (err_is_fail(err)) {
         USER_PANIC_SKB_ERR(err, "Finding cores.");
     }
@@ -198,6 +274,7 @@ errval_t arch_startup(char * add_device_db_file)
         USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
     }
 
+
     switch(platform) {
         case PI_PLATFORM_OMAP44XX:
             debug_printf("Kaluga running on Pandaboard\n");
index c9b905a..7c83f4b 100644 (file)
@@ -127,6 +127,7 @@ static struct allowed_registers sdma = {
     }
 };
 
+
 static struct allowed_registers* omap44xx[] = {
     &usb,
     &fdif,
@@ -139,6 +140,15 @@ static struct allowed_registers* omap44xx[] = {
     NULL,
 };
 
+static struct allowed_registers vexpress_pl130_dist = {
+    .binary = "pl130_dist",
+    .registers =
+    {
+        {VEXPRESS_MAP_GIC_DIST, VEXPRESS_MAP_GIC_DIST_SIZE},
+        {0x0, 0x0}
+    }
+};
+
 static struct allowed_registers vexpress_uart = {
     .binary = "hw.arm.vexpress.uart",
     .registers =
@@ -153,6 +163,7 @@ static struct allowed_registers vexpress_uart = {
 
 static struct allowed_registers* vexpress[] = {
     &vexpress_uart,
+    &vexpress_pl130_dist,
     NULL,
 };
 
index 6fa4d26..86cc019 100644 (file)
@@ -100,6 +100,8 @@ errval_t init_device_caps_manager(void)
     struct frame_identity ret;
     err = frame_identify(requested_cap, &ret);
     size_t capbits= log2ceil(ret.bytes);
+
+    debug_printf("requested_cap base=%lx bytes=%lx\n", ret.base, ret.bytes);
     assert (err_is_ok(err));
     assert((1ULL << capbits) == ret.bytes);
 
@@ -144,4 +146,4 @@ errval_t device_id_cap_create(struct capref dest, uint8_t type, uint16_t segment
     err =cap_invoke6(devman_cap, DeviceIDManager_CreateID, caddr,
                      level, slot, address, segflags).error;
     return err;
-}
\ No newline at end of file
+}
index 47e3e2f..3931f3f 100644 (file)
@@ -127,14 +127,42 @@ errval_t default_start_function(coreid_t where,
 }
 #endif
 
-/*
-static void handler(void* arg) {
-    return ;
+/**
+ * \brief Startup function for drivers. Makes no assumptions about started 
+ * device.
+ */
+errval_t
+default_start_function_pure(coreid_t where, struct module_info* mi, char* record,
+                           struct driver_argument* arg) {
+
+    // TODO this doesn't reuse existing driver domains
+    struct domain_instance* inst;
+    errval_t err;
+
+    KALUGA_DEBUG("Creating new driver domain for %s\n", mi->binary);
+    inst = instantiate_driver_domain(mi->binary, where);
+    if (inst == NULL) {
+        return DRIVERKIT_ERR_DRIVER_INIT;
+    }
+    
+    while (inst->b == NULL) {
+        event_dispatch(get_default_waitset());
+    }   
+
+    char* oct_id;
+    err = oct_read(record, "%s {}", &oct_id);
+    assert(err_is_ok(err));
+
+    struct driver_instance* drv =
+        ddomain_create_driver_instance(arg->module_name, oct_id);
+
+    drv->args = (char*[]){NULL,NULL,NULL,NULL};
+    drv->argcn_cap = arg->arg_caps;
+    return ddomain_instantiate_driver(inst, drv);
 }
-*/
 
 /**
- * \brief Startup function for new-style drivers.
+ * \brief Startup function for new-style PCI drivers.
  *
  * Launches the driver instance in a driver domain instead.
  */
index 4d199ea..a5bf61c 100644 (file)
@@ -20,6 +20,10 @@ errval_t newstyle_start_function(coreid_t where, struct module_info* driver, cha
 errval_t
 default_start_function_new(coreid_t where, struct module_info* mi, char* record,
                            struct driver_argument* arg);
+errval_t
+default_start_function_pure(coreid_t where, struct module_info* mi, char* record,
+                           struct driver_argument* arg);
+
 errval_t start_iommu_driver(coreid_t where, struct module_info* driver,
                             char* record, struct driver_argument* int_arg);
 #endif /* DRIVER_STARTUP_H_ */
index 72ac2f5..cee3a64 100644 (file)
@@ -65,7 +65,7 @@ static void add_start_function_overrides(void)
     set_start_function("ioat_dma", default_start_function_new);
     set_start_function("xeon_phi", default_start_function_new);
 #else
-    set_start_function("driverdomain", default_start_function_new);
+    set_start_function("driverdomain", default_start_function_pure);
 #endif
 
 
index 2777cfa..ff387d6 100644 (file)
@@ -15,3 +15,5 @@ monitor(cortexA15, "/armv7/sbin/monitor").
 
 % One cluster of one Cortex A15
 arm_core(16'000000,cortexA15).
+
+kernel_timer_irq(29).
diff --git a/usr/skb/programs/plat_VE_A15x2.pl b/usr/skb/programs/plat_VE_A15x2.pl
new file mode 100644 (file)
index 0000000..77418c9
--- /dev/null
@@ -0,0 +1,20 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Copyright (c) 2016, ETH Zurich.
+% All rights reserved.
+%
+% This file is distributed under the terms in the attached LICENSE file.
+% If you do not find this file, copies can be found by writing to:
+% ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Statically-initialised hardware facts for the Fixed Virtual Platform A15x4,
+% or qemu.
+
+cpu_driver(cortexA15, "/armv7/sbin/cpu_a15ve").
+monitor(cortexA15, "/armv7/sbin/monitor").
+
+% One cluster of two Cortex A15s
+arm_core(16'000000,cortexA15).
+arm_core(16'000001,cortexA15).
+
+kernel_timer_irq(29).
index c775a2b..a5adddc 100644 (file)
@@ -18,3 +18,5 @@ arm_core(16'000000,cortexA15).
 arm_core(16'000001,cortexA15).
 arm_core(16'000002,cortexA15).
 arm_core(16'000003,cortexA15).
+
+kernel_timer_irq(29).