T264: Add L1 and L2 CNode cap types
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Mon, 4 Jul 2016 14:47:34 +0000 (16:47 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Mon, 4 Jul 2016 14:47:36 +0000 (16:47 +0200)
Cannot create new types yet, as implementations for caps_retype() and
check_caps_create_arguments() are missing.

Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

capabilities/caps.hl
include/barrelfish_kpi/capabilities.h
include/barrelfish_kpi/distcaps.h
kernel/capabilities.c
kernel/include/capabilities.h
lib/barrelfish/debug.c

index 48acfec..4a6aea3 100644 (file)
@@ -24,6 +24,8 @@
 
 /* Size of CNode entry: */
 define cte_size 6;
+/* Size of L2 CNode: L2 resolves 8 bits of Cap address space */
+define l2cn_size 16384;
 /* Size of DCB: */
 define dispatcher_size 10;
 /* Size of (x86_64) VNode: */
@@ -91,6 +93,20 @@ cap CNode from RAM {
 
 };
 
+cap L1CNode from RAM {
+    /* Level 1 CNode table, resizable */
+    address lpaddr cnode;               /* Base address of CNode */
+    size gensize allocated_bytes;       /* Allocated size of L1 CNode in bytes */
+    caprights rightsmask;               /* Cap access rights */
+};
+
+cap L2CNode from RAM {
+    /* Level 2 CNode table, resolves 8 bits of cap address */
+    address lpaddr cnode;               /* Base address of CNode */
+    size { l2cn_size };                 /* Size of L2 CNode in bytes (16kB) */
+    caprights rightsmask;               /* Cap access rights */
+};
+
 cap FCNode {
      /* Foreign CNode capability */
 
index 3caecaa..0c05847 100644 (file)
 #ifndef BARRELFISH_CAPABILITIES_H
 #define BARRELFISH_CAPABILITIES_H
 
-/* FIXME: OBJBITS defines must match sizes in Hamlet's capabilities/caps.hl */
+/* FIXME: OBJBITS and OBJSIZE defines must match sizes in Hamlet's capabilities/caps.hl */
 
 // Size of CNode entry
 #define OBJBITS_CTE             6
 
+// Size of L2 CNode table: resolve 8 bits of cap address
+#define OBJSIZE_L2CNODE         (1UL << (OBJBITS_CTE + 8))
+
 // Size of dispatcher
 #define OBJBITS_DISPATCHER     10
 
@@ -55,7 +58,7 @@ struct dcb;
 
 static inline bool type_is_vnode(enum objtype type)
 {
-    STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
 
     return (type == ObjType_VNode_x86_64_pml4 ||
             type == ObjType_VNode_x86_64_pdpt ||
@@ -82,7 +85,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(46 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -121,11 +124,14 @@ static inline size_t vnode_objbits(enum objtype type)
  * @param type Object type.
  *
  * @return Size of a VNode in bytes.
+ *
+ * XXX: this should probably just do 1UL << vnode_objbits(type) for vnode
+ * objtypes -SG, 2016-07-06.
  */
 static inline size_t vnode_objsize(enum objtype type)
 {
     // This function should be emitted by hamlet or somesuch.
-    STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -168,7 +174,7 @@ static inline size_t vnode_objsize(enum objtype type)
  */
 static inline size_t vnode_entry_bits(enum objtype type) {
     // This function should be emitted by hamlet or somesuch.
-    STATIC_ASSERT(46 == ObjType_Num, "Check VNode definitions");
+    STATIC_ASSERT(48 == ObjType_Num, "Check VNode definitions");
 
     if (type == ObjType_VNode_x86_64_pml4 ||
         type == ObjType_VNode_x86_64_pdpt ||
@@ -221,7 +227,7 @@ static inline size_t vnode_entry_bits(enum objtype type) {
 
 static inline enum objtype get_mapping_type(enum objtype captype)
 {
-    STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
+    STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all mapping types");
 
     switch (captype) {
         case ObjType_Frame:
@@ -260,7 +266,7 @@ static inline enum objtype get_mapping_type(enum objtype captype)
 
 static inline bool type_is_mapping(enum objtype type)
 {
-    STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
+    STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all mapping types");
 
     switch (type) {
         case ObjType_Frame_Mapping:
@@ -287,7 +293,7 @@ static inline bool type_is_mapping(enum objtype type)
 
 static inline bool type_is_mappable(enum objtype type)
 {
-    STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all mapping types");
+    STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all mappable types");
 
     switch (type) {
         case ObjType_Frame:
index b225156..7ed3577 100644 (file)
@@ -40,7 +40,7 @@ distcap_state_is_foreign(distcap_state_t state)
  * Predicates related to sharing capabilities
  */
 
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 static inline bool
 distcap_needs_locality(enum objtype type)
 {
@@ -48,6 +48,8 @@ distcap_needs_locality(enum objtype type)
     case ObjType_PhysAddr:
     case ObjType_RAM:
     case ObjType_CNode:
+    case ObjType_L1CNode:
+    case ObjType_L2CNode:
     case ObjType_FCNode:
     case ObjType_Dispatcher:
     case ObjType_EndPoint:
@@ -87,7 +89,7 @@ distcap_needs_locality(enum objtype type)
     }
 }
 
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 static inline bool
 distcap_is_moveable(enum objtype type)
 {
index 7bdf1c0..c376396 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(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 int sprint_cap(char *buf, size_t len, struct capability *cap)
 {
     switch (cap->type) {
@@ -76,6 +76,21 @@ int sprint_cap(char *buf, size_t len, struct capability *cap)
         return ret;
     }
 
+    case ObjType_L1CNode: {
+        int ret = snprintf(buf, len, "L1 CNode cap "
+                           "(allocated bytes %#"PRIxGENSIZE
+                           ", rights mask %#"PRIxCAPRIGHTS")",
+                           get_size(cap), cap->u.l1cnode.rightsmask);
+        return ret;
+    }
+
+    case ObjType_L2CNode: {
+        int ret = snprintf(buf, len, "L2 CNode cap "
+                           "(rights mask %#"PRIxCAPRIGHTS")",
+                           cap->u.l1cnode.rightsmask);
+        return ret;
+    }
+
     case ObjType_Dispatcher:
         return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);
 
@@ -343,7 +358,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(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t objsize)
 {
     switch(type) {
@@ -364,6 +379,23 @@ static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t o
             return srcsize / objsize / (1UL << OBJBITS_CTE);
         }
 
+    case ObjType_L1CNode:
+        if (srcsize < OBJSIZE_L2CNODE || objsize < OBJSIZE_L2CNODE) {
+            // disallow L1 CNode to be smaller than 16kB.
+            return 0;
+        } else {
+            return srcsize / objsize;
+        }
+
+    case ObjType_L2CNode:
+        if (srcsize < OBJSIZE_L2CNODE || objsize != OBJSIZE_L2CNODE) {
+            // disallow L2 CNode creation if source too small or objsize wrong
+            return 0;
+        } else {
+            return srcsize / objsize;
+        }
+
+
     case ObjType_VNode_x86_64_pml4:
     case ObjType_VNode_x86_64_pdpt:
     case ObjType_VNode_x86_64_pdir:
@@ -436,7 +468,7 @@ static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t o
  *
  * For the meaning of the parameters, see the 'caps_create' function.
  */
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 
 static errval_t caps_zero_objects(enum objtype type, lpaddr_t lpaddr,
                                   gensize_t objsize, size_t count)
@@ -475,6 +507,16 @@ static errval_t caps_zero_objects(enum objtype type, lpaddr_t lpaddr,
         TRACE(KERNEL, BZERO, 0);
         break;
 
+    case ObjType_L1CNode:
+    case ObjType_L2CNode:
+        debug(SUBSYS_CAPS, "L%dCNode: zeroing %zu bytes @%#"PRIxLPADDR"\n",
+                type == ObjType_L1CNode ? 1 : 2, (size_t)objsize * count,
+                lpaddr);
+        TRACE(KERNEL, BZERO, 1);
+        memset((void*)lvaddr, 0, objsize * count);
+        TRACE(KERNEL, BZERO, 0);
+        break;
+
     case ObjType_VNode_ARM_l1:
     case ObjType_VNode_ARM_l2:
     case ObjType_VNode_AARCH64_l1:
@@ -544,7 +586,7 @@ static errval_t caps_zero_objects(enum objtype type, lpaddr_t lpaddr,
  */
 // If you create more capability types you need to deal with them
 // in the table below.
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 
 static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, gensize_t size,
                             gensize_t objsize, size_t count, coreid_t owner,
@@ -677,6 +719,14 @@ static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, gensize_t size,
         }
         break;
 
+    case ObjType_L1CNode:
+        panic("caps_create L1CNode NYI!");
+        break;
+
+    case ObjType_L2CNode:
+        panic("caps_create L2CNode NYI!");
+        break;
+
     case ObjType_VNode_ARM_l1:
     {
         size_t objsize_vnode = vnode_objsize(type);
@@ -1229,6 +1279,7 @@ errval_t caps_create_from_existing(struct capability *root, capaddr_t cnode_cptr
 //{{{1 Capability creation
 
 /// check arguments, return true iff ok
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 static bool check_caps_create_arguments(enum objtype type,
                                         size_t bytes, size_t objsize,
                                         bool exact)
@@ -1262,6 +1313,14 @@ static bool check_caps_create_arguments(enum objtype type,
         return true;
     }
 
+    if (type == ObjType_L1CNode) {
+        panic("check_caps_create_arguments NYI for L1 CNode");
+    }
+
+    if (type == ObjType_L2CNode) {
+        panic("check_caps_create_arguments NYI for L2 CNode");
+    }
+
     /* special case Dispatcher which is 1kB right now */
     if (type == ObjType_Dispatcher) {
         if (bytes & ((1UL << OBJBITS_DISPATCHER) - 1)) {
@@ -1321,7 +1380,7 @@ errval_t caps_create_new(enum objtype type, lpaddr_t addr, size_t bytes,
     return SYS_ERR_OK;
 }
 
-STATIC_ASSERT(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 /// Retype caps
 /// Create `count` new caps of `type` from `offset` in src, and put them in
 /// `dest_cnode` starting at `dest_slot`.
@@ -1367,10 +1426,23 @@ errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
         printk(LOG_WARN, "%s: CNode: objsize = %zu\n", __FUNCTION__, objsize);
         return SYS_ERR_INVALID_SIZE;
     }
+    else if (type == ObjType_L1CNode && objsize % OBJSIZE_L2CNODE != 0)
+    {
+        printk(LOG_WARN, "%s: L1CNode: objsize = %zu\n", __FUNCTION__, objsize);
+        return SYS_ERR_INVALID_SIZE;
+    }
+    else if (type == ObjType_L2CNode && objsize != OBJSIZE_L2CNODE)
+    {
+        printk(LOG_WARN, "%s: L2CNode: objsize = %zu\n", __FUNCTION__, objsize);
+        return SYS_ERR_INVALID_SIZE;
+    }
     // TODO: clean up semantics for type == ObjType_CNode
     assert((type == ObjType_CNode
             && ((objsize * sizeof(struct cte)) % BASE_PAGE_SIZE == 0)) ||
            (type_is_mappable(type) && objsize % BASE_PAGE_SIZE == 0) ||
+           (type == ObjType_L1CNode && objsize % OBJSIZE_L2CNODE == 0 &&
+            objsize >= OBJSIZE_L2CNODE) ||
+           (type == ObjType_L2CNode && objsize == OBJSIZE_L2CNODE) ||
            !(type_is_mappable(type) || type == ObjType_CNode));
 
     /* No explicit retypes to Mapping allowed */
@@ -1565,6 +1637,7 @@ errval_t caps_copy_to_cnode(struct cte *dest_cnode_cte, cslot_t dest_slot,
 }
 
 /// Create copies to a cte
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 errval_t caps_copy_to_cte(struct cte *dest_cte, struct cte *src_cte, bool mint,
                           uintptr_t param1, uintptr_t param2)
 {
@@ -1628,6 +1701,10 @@ errval_t caps_copy_to_cte(struct cte *dest_cte, struct cte *src_cte, bool mint,
         dest_cap->u.cnode.guard_size = param2;
         break;
 
+    case ObjType_L1CNode:
+    case ObjType_L2CNode:
+        panic("Mint NYI for L1/L2 CNodes");
+
     case ObjType_EndPoint:
         // XXX: FIXME: check that buffer offset lies wholly within the disp frame
         // can't easily enforce this here, because the dispatcher frame may not
index 3659b12..3e65d25 100644 (file)
@@ -133,7 +133,7 @@ errval_t caps_revoke(struct cte *cte);
  * Cap tracing
  */
 #ifdef TRACE_PMEM_CAPS
-STATIC_ASSERT(46 == ObjType_Num, "knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "knowledge of all cap types");
 STATIC_ASSERT(64 >= ObjType_Num, "cap types fit in uint64_t bitfield");
 #define MAPPING_TYPES \
     ((1ull<<ObjType_VNode_x86_64_pml4_Mapping) | \
@@ -156,6 +156,8 @@ STATIC_ASSERT(64 >= ObjType_Num, "cap types fit in uint64_t bitfield");
      (1ull<<ObjType_Frame) | \
      (1ull<<ObjType_DevFrame) | \
      (1ull<<ObjType_CNode) | \
+     (1ull<<ObjType_L1CNode) | \
+     (1ull<<ObjType_L2CNode) | \
      (1ull<<ObjType_FCNode) | \
      (1ull<<ObjType_VNode_x86_64_pml4) | \
      (1ull<<ObjType_VNode_x86_64_pdpt) | \
index 3ca8356..2905e97 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(46 == ObjType_Num, "Knowledge of all cap types");
+STATIC_ASSERT(48 == ObjType_Num, "Knowledge of all cap types");
 int debug_print_cap(char *buf, size_t len, struct capability *cap)
 {
     switch (cap->type) {
@@ -152,6 +152,22 @@ int debug_print_cap(char *buf, size_t len, struct capability *cap)
         return ret;
     }
 
+    case ObjType_L1CNode: {
+        int ret = snprintf(buf, len, "L1 CNode cap "
+                           "(allocated bytes %#"PRIxGENSIZE
+                           ", rights mask %#"PRIxCAPRIGHTS")",
+                           cap->u.l1cnode.allocated_bytes, cap->u.l1cnode.rightsmask);
+        return ret;
+    }
+
+    case ObjType_L2CNode: {
+        int ret = snprintf(buf, len, "L2 CNode cap "
+                           "(rights mask %#"PRIxCAPRIGHTS")",
+                           cap->u.l1cnode.rightsmask);
+        return ret;
+    }
+
+
     case ObjType_Dispatcher:
         return snprintf(buf, len, "Dispatcher cap %p", cap->u.dispatcher.dcb);