IRQ: added IRQVector cap
authorLukas Humbel <lukas.humbel@inf.ethz.ch>
Thu, 24 Mar 2016 14:22:21 +0000 (15:22 +0100)
committerLukas Humbel <lukas.humbel@inf.ethz.ch>
Wed, 6 Apr 2016 08:36:59 +0000 (10:36 +0200)
Signed-off-by: Lukas Humbel <lukas.humbel@inf.ethz.ch>

capabilities/caps.hl
include/barrelfish_kpi/capabilities.h
include/barrelfish_kpi/distcaps.h
kernel/arch/x86_64/irq.c
kernel/capabilities.c
kernel/include/kcb.h
kernel/kcb.c
lib/barrelfish/debug.c

index 43a71b7..9b966a2 100644 (file)
@@ -388,12 +388,11 @@ cap IRQTable is_always_copy {
     **/
 };
 
-/*
 cap IRQVector from IRQTable {
     "struct capability" ep;
-    eq uint64 vector;
-    eq uint64 controller;
-} */
+    eq uint32 controller;
+    eq uint32 vector;
+};
 
 cap IRQ {
        /* IRQ capability. Represents an interrupt line at an interrupt controller. */
index 71db7eb..11a6d78 100644 (file)
@@ -55,7 +55,7 @@ struct dcb;
 
 static inline bool type_is_vnode(enum objtype type)
 {
-    STATIC_ASSERT(45 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
 
     return (type == ObjType_VNode_x86_64_pml4 ||
             type == ObjType_VNode_x86_64_pdpt ||
@@ -82,7 +82,7 @@ static inline bool type_is_vnode(enum objtype type)
 static inline size_t vnode_objbits(enum objtype type)
 {
     // This function should be emitted by hamlet or somesuch.
-    STATIC_ASSERT(45 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -120,7 +120,7 @@ static inline size_t vnode_objbits(enum objtype type)
  */
 static inline size_t vnode_entry_bits(enum objtype type) {
     // This function should be emitted by hamlet or somesuch.
-    STATIC_ASSERT(45 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -173,7 +173,7 @@ static inline size_t vnode_entry_bits(enum objtype type) {
 
 static inline enum objtype get_mapping_type(enum objtype captype)
 {
-    STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all mapping types");
+    STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
 
     switch (captype) {
         case ObjType_Frame:
@@ -212,7 +212,7 @@ static inline enum objtype get_mapping_type(enum objtype captype)
 
 static inline bool type_is_mapping(enum objtype type)
 {
-    STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all mapping types");
+    STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
 
     switch (type) {
         case ObjType_Frame_Mapping:
index ca74fdb..b225156 100644 (file)
@@ -40,7 +40,7 @@ distcap_state_is_foreign(distcap_state_t state)
  * Predicates related to sharing capabilities
  */
 
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 static inline bool
 distcap_needs_locality(enum objtype type)
 {
@@ -87,7 +87,7 @@ distcap_needs_locality(enum objtype type)
     }
 }
 
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 static inline bool
 distcap_is_moveable(enum objtype type)
 {
index 2f48d70..b5e0643 100644 (file)
@@ -417,7 +417,7 @@ static void send_user_interrupt(int irq)
     assert(irq >= 0 && irq < NDISPATCH);
     struct kcb *k = kcb_current;
     do {
-        if (k->irq_dispatch[irq].cap.type == ObjType_EndPoint) {
+        if (k->irq_dest_caps[irq].cap.type == ObjType_IRQVector) {
             break;
         }
         k = k->next;
@@ -427,12 +427,15 @@ static void send_user_interrupt(int irq)
         switch_kcb(k);
     }
     // from here: kcb_current is the kcb for which the interrupt was intended
-    struct capability *cap = &kcb_current->irq_dispatch[irq].cap;
+    struct capability *cap = &kcb_current->irq_dest_caps[irq].cap;
 
     // Return on null cap (unhandled interrupt)
     if(cap->type == ObjType_Null) {
         printk(LOG_WARN, "unhandled IRQ %d\n", irq);
         return;
+    } else if (cap->type == ObjType_IRQVector && cap->u.irqvector.ep == NULL){
+        printk(LOG_WARN, "unhandled IRQ (no endpoint) %d\n", irq);
+        return;
     } else if (cap->type > ObjType_Num) {
         // XXX: HACK: this doesn't fix the root cause of having weird entries
         // in kcb_current->irq_dispatch[], but it allows us to test the system
@@ -450,14 +453,17 @@ static void send_user_interrupt(int irq)
 
     }
     // Otherwise, cap needs to be an endpoint
-    assert(cap->type == ObjType_EndPoint);
+    assert(cap->type == ObjType_IRQVector);
+
+    struct capability * ep = cap->u.irqvector.ep;
+    assert(ep);
 
     // send empty message as notification
-    errval_t err = lmp_deliver_notification(cap);
+    errval_t err = lmp_deliver_notification(ep);
     if (err_is_fail(err)) {
         if (err_no(err) == SYS_ERR_LMP_BUF_OVERFLOW) {
             struct dispatcher_shared_generic *disp =
-                get_dispatcher_shared_generic(cap->u.endpoint.listener->disp);
+                get_dispatcher_shared_generic(ep->u.endpoint.listener->disp);
             printk(LOG_DEBUG, "%.*s: IRQ message buffer overflow on IRQ %d\n",
                    DISP_NAME_LEN, disp->name, irq);
         } else {
@@ -489,7 +495,7 @@ errval_t irq_table_alloc(int *outvec)
         struct kcb *k = kcb_current;
         bool found_free = true;
         do {
-            if (k->irq_dispatch[i].cap.type == ObjType_EndPoint) {
+            if (k->irq_dest_caps[i].cap.type == ObjType_IRQVector) {
                 found_free = false;
                 break;
             }
@@ -503,6 +509,7 @@ errval_t irq_table_alloc(int *outvec)
         *outvec = -1;
         return SYS_ERR_IRQ_NO_FREE_VECTOR;
     } else {
+        //TODO Luki: Somehow we must put here a cap in the table
         *outvec = i;
         return SYS_ERR_OK;
     }
@@ -522,20 +529,22 @@ errval_t irq_table_alloc_dest_cap(capaddr_t out_cap_addr)
     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) {
+        assert(kcb_current->irq_dest_caps[i].cap.type == ObjType_Null ||
+               kcb_current->irq_dest_caps[i].cap.type == ObjType_IRQVector);
+        //TODO Luki: iterate over kcb
+        if (kcb_current->irq_dest_caps[i].cap.type == ObjType_IRQVector) {
             break;
         }
     }
     if (i == NDISPATCH) {
         return SYS_ERR_IRQ_NO_FREE_VECTOR;
     } else {
-        out_cap->cap.type = ObjType_IRQ;
+        out_cap->cap.type = ObjType_IRQVector;
 
-        //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;
+        //TODO Luki: Set the lapic_controller_id
+        const uint32_t lapic_controller_id = 0;
+        out_cap->cap.u.irqvector.controller = lapic_controller_id;
+        out_cap->cap.u.irqvector.vector = i;
         return SYS_ERR_OK;
     }
 }
@@ -575,17 +584,17 @@ errval_t irq_connect(capaddr_t dest, capaddr_t endpoint)
 
     assert(irq != NULL);
 
-    if(irq->cap.type != ObjType_IRQ){
+    if(irq->cap.type != ObjType_IRQVector){
         return SYS_ERR_IRQ_NOT_IRQ_TYPE;
     }
 
     //TODO: Set the lapic_controller_id
-    const uint64_t lapic_controller_id = 0;
-    if(irq->cap.u.irq.controller != lapic_controller_id) {
+    const uint32_t lapic_controller_id = 0;
+    if(irq->cap.u.irqvector.controller != lapic_controller_id) {
         return SYS_ERR_IRQ_WRONG_CONTROLLER;
     }
 
-    uint64_t nidt = irq->cap.u.irq.line;
+    uint64_t nidt = irq->cap.u.irqvector.vector;
     assert(nidt < NDISPATCH);
 
     // check that we don't overwrite someone else's handler
index cf0bbdf..6776238 100644 (file)
@@ -52,7 +52,7 @@ void caps_trace_ctrl(uint64_t types, genpaddr_t start, gensize_t size)
 
 struct capability monitor_ep;
 
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 int sprint_cap(char *buf, size_t len, struct capability *cap)
 {
     switch (cap->type) {
@@ -239,6 +239,10 @@ int sprint_cap(char *buf, size_t len, struct capability *cap)
     case ObjType_IRQTable:
         return snprintf(buf, len, "IRQTable cap");
 
+    case ObjType_IRQVector:
+        return snprintf(buf, len, "IRQVector cap (vec: %"PRIu32", ctrl: %"PRIu32", ep:%p)",
+                cap->u.irqvector.vector, cap->u.irqvector.controller, cap->u.irqvector.ep);
+
     case ObjType_EndPoint:
         return snprintf(buf, len, "EndPoint cap (disp %p offset 0x%" PRIxLVADDR ")",
                         cap->u.endpoint.listener, cap->u.endpoint.epoffset);
@@ -332,7 +336,7 @@ static errval_t set_cap(struct capability *dest, struct capability *src)
 
 // If you create more capability types you need to deal with them
 // in the table below.
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 
 static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
 {
@@ -391,6 +395,7 @@ static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
 
     case ObjType_Kernel:
     case ObjType_IRQTable:
+    case ObjType_IRQVector:
     case ObjType_IRQ:
     case ObjType_IO:
     case ObjType_EndPoint:
@@ -426,7 +431,7 @@ static size_t caps_numobjs(enum objtype type, uint8_t bits, uint8_t objbits)
  *
  * For the meaning of the parameters, see the 'caps_create' function.
  */
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 
 static errval_t caps_init_objects(enum objtype type, lpaddr_t lpaddr, uint8_t
                                   bits, uint8_t objbits, size_t numobjs)
@@ -506,7 +511,7 @@ static errval_t caps_init_objects(enum objtype type, lpaddr_t lpaddr, uint8_t
  */
 // If you create more capability types you need to deal with them
 // in the table below.
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 
 static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, uint8_t bits,
                             uint8_t objbits, size_t numobjs, coreid_t owner,
@@ -987,6 +992,7 @@ static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, uint8_t bits,
     case ObjType_Kernel:
     case ObjType_IPI:
     case ObjType_IRQTable:
+    case ObjType_IRQVector:
     case ObjType_EndPoint:
     case ObjType_Notify_RCK:
     case ObjType_Notify_IPI:
@@ -1272,7 +1278,7 @@ errval_t caps_create_new(enum objtype type, lpaddr_t addr, size_t bits,
 }
 
 
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 /// Retype caps
 errval_t caps_retype(enum objtype type, size_t objbits,
                      struct capability *dest_cnode, cslot_t dest_slot,
index 3e873d8..bf37d98 100644 (file)
@@ -66,7 +66,7 @@ struct kcb {
     //driver whose kernel_now > this kcb's kernel_off.
     int64_t kernel_off;
 
-    struct cte irq_dispatch[NDISPATCH];
+    struct cte irq_dest_caps[NDISPATCH];
     // TODO: maybe add a shared part which can replace struct core_data?
 };
 
index e330df7..c258a6e 100644 (file)
@@ -105,13 +105,19 @@ void kcb_update_core_id(struct kcb *kcb)
     }
 
     for (int i = 0; i < NDISPATCH; i++) {
-        struct capability *cap = &kcb->irq_dispatch[i].cap;
-        if (cap->type == ObjType_EndPoint) {
-            printk(LOG_NOTE, "[irq] updating current core id to %d for %s\n",
-                    my_core_id, get_disp_name(cap->u.endpoint.listener));
-            struct dispatcher_shared_generic *disp =
-                get_dispatcher_shared_generic(cap->u.endpoint.listener->disp);
-            disp->curr_core_id = my_core_id;
+        struct capability *cap = &kcb->irq_dest_caps[i].cap;
+        assert(cap->type != ObjType_EndPoint); // Now we store IRQVector caps here
+        if (cap->type == ObjType_IRQVector) {
+            struct capability * ep = cap->u.irqvector.ep;
+            if(ep){
+                assert(ep->type == ObjType_EndPoint);
+                printk(LOG_NOTE, "[irq] updating current core id to %d for %s\n",
+                                    my_core_id, get_disp_name(ep->u.endpoint.listener));
+                            struct dispatcher_shared_generic *disp =
+                                get_dispatcher_shared_generic(ep->u.endpoint.listener->disp);
+                            disp->curr_core_id = my_core_id;
+            }
+
         }
     }
 }
index c58500d..f4ab1f0 100644 (file)
@@ -128,7 +128,7 @@ void debug_printf(const char *fmt, ...)
 /**
  * \brief Function to do the actual printing based on the type of capability
  */
-STATIC_ASSERT(45 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
 int debug_print_cap(char *buf, size_t len, struct capability *cap)
 {
     switch (cap->type) {
@@ -316,6 +316,10 @@ int debug_print_cap(char *buf, size_t len, struct capability *cap)
     case ObjType_IRQTable:
         return snprintf(buf, len, "IRQTable cap");
 
+    case ObjType_IRQVector:
+        return snprintf(buf, len, "IRQVector cap (vec: %"PRIu32",ctrl: %"PRIu32", ep:%p)",
+                cap->u.irqvector.vector, cap->u.irqvector.controller, cap->u.irqvector.ep);
+
     case ObjType_EndPoint:
         return snprintf(buf, len, "EndPoint cap (disp %p offset 0x%" PRIxLVADDR ")",
                         cap->u.endpoint.listener, cap->u.endpoint.epoffset);