IRQ: work in progress on receiving side
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Tue, 22 Mar 2016 21:36:59 +0000 (22:36 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Wed, 6 Apr 2016 08:36:51 +0000 (10:36 +0200)
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

capabilities/caps.hl
if/monitor_blocking.if
include/arch/x86_64/barrelfish/invocations_arch.h
include/barrelfish_kpi/capabilities.h
kernel/arch/x86_64/irq.c
kernel/arch/x86_64/syscall.c
kernel/include/arch/x86_64/irq.h
lib/pci/pci_client.c
usr/monitor/monitor_rpc_server.c

index 6ad3cc1..43a71b7 100644 (file)
@@ -388,6 +388,13 @@ cap IRQTable is_always_copy {
     **/
 };
 
+/*
+cap IRQVector from IRQTable {
+    "struct capability" ep;
+    eq uint64 vector;
+    eq uint64 controller;
+} */
+
 cap IRQ {
        /* IRQ capability. Represents an interrupt line at an interrupt controller. */
        eq uint64 line;
index a6ab867..d73c003 100644 (file)
@@ -34,6 +34,9 @@ interface monitor_blocking "The monitor to client RPC interface" {
 
     rpc get_phyaddr_cap(out cap pyaddr, out errval err);
     rpc get_io_cap(out cap io, out errval err);
+    
+    // Get a capability that is targeted at the local apic.
+    rpc get_irq_dest_cap(out cap io, out errval err);
 
     // Resource control
     rpc rsrc_manifest(in cap dispatcher, in string manifest,
index 3340963..af199c0 100644 (file)
@@ -420,7 +420,15 @@ static inline errval_t invoke_irq_connect(struct capref irqcap, struct capref ep
     return ret.error;
 }
 
+static inline errval_t invoke_irqtable_alloc_dest_cap(struct capref irqcap, struct capref dest_cap)
+{
+    struct sysret ret = cap_invoke2(irqcap, IRQTableCmd_AllocDestCap, get_cap_addr(dest_cap));
+    return ret.error;
+}
 
+/**
+ * Deprecated. Use
+ */
 static inline errval_t invoke_irqtable_alloc_vector(struct capref irqcap, int *retirq)
 {
     struct sysret ret = cap_invoke1(irqcap, IRQTableCmd_Alloc);
index 6ca3342..71db7eb 100644 (file)
@@ -333,6 +333,7 @@ enum frame_cmd {
  */
 enum irqtable_cmd {
     IRQTableCmd_Alloc,  ///< Allocate new vector (XXX: HACK: this is x86 specific)
+    IRQTableCmd_AllocDestCap,  ///< Allocate new dest capability (XXX: HACK: this is x86 specific)
     IRQTableCmd_Set,    ///< Set endpoint for IRQ# notifications
     IRQTableCmd_Delete  ///< Remove notification endpoint for IRQ#
 };
index 17b576a..3066125 100644 (file)
@@ -505,6 +505,38 @@ errval_t irq_table_alloc(int *outvec)
     }
 }
 
+errval_t irq_table_alloc_dest_cap(capaddr_t out_cap_addr)
+{
+    errval_t err;
+    struct cte * out_cap;
+
+    err = caps_lookup_slot(&dcb_current->cspace.cap, out_cap_addr,
+            CPTR_BITS, &out_cap, CAPRIGHTS_WRITE);
+    if (err_is_fail(err)) {
+        return err_push(err, SYS_ERR_IRQ_LOOKUP_EP);
+    }
+
+    int i;
+    for (i = 0; i < NDISPATCH; i++) {
+        //struct kcb * k = kcb_current;
+        //TODO iterate over kcb
+        if (kcb_current->irq_dispatch[i].cap.type == ObjType_EndPoint) {
+            break;
+        }
+    }
+    if (i == NDISPATCH) {
+        return SYS_ERR_IRQ_NO_FREE_VECTOR;
+    } else {
+        out_cap->cap.type = ObjType_IRQ;
+
+        //TODO: Set the lapic_controller_id
+        const uint64_t lapic_controller_id = 0;
+        out_cap->cap.u.irq.controller = lapic_controller_id;
+        out_cap->cap.u.irq.line = i;
+        return SYS_ERR_OK;
+    }
+}
+
 errval_t irq_connect(capaddr_t dest, capaddr_t endpoint)
 {
     errval_t err;
index 02da281..61018e6 100644 (file)
@@ -815,6 +815,12 @@ static struct sysret handle_irq_table_alloc(struct capability *to, int cmd,
     return ret;
 }
 
+static struct sysret handle_irq_table_alloc_dest_cap(struct capability *to, int cmd,
+                                            uintptr_t *args)
+{
+    return SYSRET(irq_table_alloc_dest_cap(args[0]));
+}
+
 
 static struct sysret handle_irq_table_set(struct capability *to, int cmd,
                                           uintptr_t *args)
@@ -1160,6 +1166,7 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
        },
     [ObjType_IRQTable] = {
         [IRQTableCmd_Alloc] = handle_irq_table_alloc,
+        [IRQTableCmd_AllocDestCap] = handle_irq_table_alloc_dest_cap,
         [IRQTableCmd_Set] = handle_irq_table_set,
         [IRQTableCmd_Delete] = handle_irq_table_delete
     },
index 8549abb..a684f33 100644 (file)
@@ -164,5 +164,6 @@ errval_t irq_table_set(unsigned int nidt, capaddr_t endpoint);
 errval_t irq_table_delete(unsigned int nidt);
 struct kcb;
 errval_t irq_table_notify_domains(struct kcb *kcb);
+errval_t irq_table_alloc_dest_cap(capaddr_t out_cap_addr);
 
 #endif
index 03b0706..2f22057 100644 (file)
@@ -108,6 +108,7 @@ errval_t pci_register_driver_movable_irq(pci_driver_init_fn init_func, uint32_t
     struct capref irq_dest_cap;
     // TODO
 
+
     // Setup routing
     // TODO
 
index 2e42cd1..e8b589a 100644 (file)
@@ -361,6 +361,30 @@ static void get_io_cap(struct monitor_blocking_binding *b)
     }
 }
 
+static void get_irq_dest_cap(struct monitor_blocking_binding *b)
+{
+    errval_t err;
+    //TODO get real cap
+
+    struct capref dest_cap;
+    slot_alloc(&dest_cap);
+    invoke_irqtable_alloc_dest_cap(cap_irq, dest_cap);
+
+    err = b->tx_vtbl.get_irq_dest_cap_response(b, NOP_CONT, dest_cap,
+            SYS_ERR_OK);
+    if (err_is_fail(err)) {
+        if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+            err = b->register_send(b, get_default_waitset(),
+                                   MKCONT((void (*)(void *))get_io_cap, b));
+            if (err_is_fail(err)) {
+                USER_PANIC_ERR(err, "register_send failed");
+            }
+        }
+
+        USER_PANIC_ERR(err, "sending get_io_cap_response failed");
+    }
+}
+
 
 static void get_bootinfo(struct monitor_blocking_binding *b)
 {
@@ -514,6 +538,7 @@ static struct monitor_blocking_rx_vtbl rx_vtbl = {
     .get_bootinfo_call = get_bootinfo,
     .get_phyaddr_cap_call = get_phyaddr_cap,
     .get_io_cap_call = get_io_cap,
+    .get_irq_dest_cap_call = get_irq_dest_cap,
 
     .remote_cap_retype_call  = remote_cap_retype,
     .remote_cap_delete_call  = remote_cap_delete,