T243: capability types and kernel code now accurately reflects ARMv7 12/8/12 bit...
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Mon, 15 Aug 2016 08:48:36 +0000 (10:48 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Mon, 15 Aug 2016 11:59:50 +0000 (13:59 +0200)
Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

capabilities/caps.hl
include/barrelfish_kpi/capabilities.h
kernel/arch/armv7/paging.c
lib/barrelfish/capabilities.c

index 27dfce0..3f8d04b 100644 (file)
@@ -28,6 +28,9 @@ define l2cn_size 16384;
 define dispatcher_size 10;
 /* Size of (x86_64) VNode: */
 define vnode_size 4096; /* BASE_PAGE_SIZE */
+/* Size of ARMv7 VNodes */
+define vnode_arm_l1_size 16384;
+define vnode_arm_l2_size 1024;
 /* size of a kernel control block */
 define kcb_size 16; /* OBJBITS_KCB */
 
@@ -300,7 +303,7 @@ cap VNode_ARM_l1 from RAM {
     /* L1 Page Table */
 
     address genpaddr base;  /* Base address of VNode */
-    size { vnode_size };
+    size { vnode_arm_l1_size };
 };
 
 cap VNode_ARM_l1_Mapping from VNode_ARM_l1 {
@@ -314,7 +317,7 @@ cap VNode_ARM_l1_Mapping from VNode_ARM_l1 {
 cap VNode_ARM_l2 from RAM {
     /* L2 Page Table */
     address genpaddr base;  /* Base address of VNode */
-    size { vnode_size };
+    size { vnode_arm_l2_size };
 };
 
 cap VNode_ARM_l2_Mapping from VNode_ARM_l2 {
index 476fc63..3ab6002 100644 (file)
@@ -129,9 +129,7 @@ static inline size_t vnode_objbits(enum objtype type)
     }
     else if (type == ObjType_VNode_ARM_l2)
     {
-        // XXX: should be 1024, once we get around to untangling the ARMv7
-        // page table mess, cf. T243.
-        return 12;
+        return 10;
     }
 
     assert(0 && !"Page table size unknown.");
index 52f2f42..b453f4f 100644 (file)
@@ -335,18 +335,6 @@ caps_map_l1(struct capability* dest,
             uintptr_t          pte_count,
             struct cte*        mapping_cte)
 {
-    //
-    // Note:
-    //
-    // We have chicken-and-egg problem in initializing resources so
-    // instead of treating an L2 table it's actual 1K size, we treat
-    // it as being 4K. As a result when we map an "L2" table we actually
-    // map a page of memory as if it is 4 consecutive L2 tables.
-    //
-    // See lib/barrelfish/arch/arm/pmap_arch.c for more discussion.
-    //
-    const int ARM_L1_SCALE = 4;
-
     if (src->type != ObjType_VNode_ARM_l2) {
         //large page mapping goes here
         assert(0 == (kpi_paging_flags & ~KPI_PAGING_FLAGS_MASK));
@@ -475,7 +463,7 @@ caps_map_l1(struct capability* dest,
         entry->page_table.type   = L1_TYPE_PAGE_TABLE_ENTRY;
         entry->page_table.domain = 0;
         entry->page_table.base_address =
-            (src_lpaddr + i * BASE_PAGE_SIZE / ARM_L1_SCALE) >> 10;
+            (src_lpaddr + i * ARM_L2_TABLE_BYTES) >> 10;
 
         /* Clean the modified entry to L2 cache. */
         clean_to_pou(entry);
@@ -500,10 +488,8 @@ caps_map_l2(struct capability* dest,
 {
     assert(0 == (kpi_paging_flags & ~KPI_PAGING_FLAGS_MASK));
 
-    // ARM L2 has 256 entries, but we treat a 4K page as a consecutive
-    // region of L2 with a single index. 4K == 4 * 1K
-    if (slot >= (256 * 4)) {
-        panic("oops: slot >= (256 * 4)");
+    if (slot >= ARM_L2_MAX_ENTRIES) {
+        panic("oops: slot >= 256");
         return SYS_ERR_VNODE_SLOT_INVALID;
     }
 
@@ -513,14 +499,14 @@ caps_map_l2(struct capability* dest,
     }
 
     // check offset within frame
-    if ((offset + BYTES_PER_PAGE > get_size(src)) ||
-        ((offset % BYTES_PER_PAGE) != 0)) {
+    if ((offset + BASE_PAGE_SIZE > get_size(src)) ||
+        ((offset % BASE_PAGE_SIZE) != 0)) {
         panic("oops: frame offset invalid");
         return SYS_ERR_FRAME_OFFSET_INVALID;
     }
 
     // check mapping does not overlap leaf page table
-    if (slot + pte_count > (256 * 4)) {
+    if (slot + pte_count > ARM_L2_MAX_ENTRIES) {
         return SYS_ERR_VM_MAP_SIZE;
     }
 
@@ -547,7 +533,7 @@ caps_map_l2(struct capability* dest,
 
         entry->small_page.type = L2_TYPE_SMALL_PAGE;
         paging_set_flags(entry, kpi_paging_flags);
-        entry->small_page.base_address = (src_lpaddr + i * BYTES_PER_PAGE) >> 12;
+        entry->small_page.base_address = (src_lpaddr + i * BASE_PAGE_SIZE) >> 12;
 
         /* Clean the modified entry to L2 cache. */
         clean_to_pou(entry);
index e3e0dc3..d7dfa53 100644 (file)
@@ -647,6 +647,11 @@ errval_t vnode_create(struct capref dest, enum objtype type)
 
     size_t objbits_vnode = vnode_objbits(type);
     err = ram_alloc(&ram, objbits_vnode);
+    if (err_no(err) == LIB_ERR_RAM_ALLOC_WRONG_SIZE && type != ObjType_VNode_ARM_l1) {
+        // can only get 4kB pages, cannot create ARM_l1, and waste 3kB for
+        // ARM_l2
+        err = ram_alloc(&ram, BASE_PAGE_BITS);
+    }
     if (err_is_fail(err)) {
         return err_push(err, LIB_ERR_RAM_ALLOC);
     }