armv7: compiles.
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 27 Mar 2014 16:22:09 +0000 (17:22 +0100)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 27 Mar 2014 16:22:09 +0000 (17:22 +0100)
include/arch/arm/barrelfish/invocations_arch.h
include/arch/arm/barrelfish/lmp_chan_arch.h
kernel/arch/armv7/syscall.c
kernel/arch/omap44xx/startup_arch.c
kernel/include/capabilities.h
lib/barrelfish/arch/arm/sys_debug.c
usr/monitor/arch/armv7/boot.c
usr/monitor/capops/delete.c
usr/monitor/capops/deletestep.c
usr/monitor/include/arch/arm/monitor_invocations_arch.h

index 89d7538..c6a2d97 100644 (file)
 
 #include <barrelfish/syscall_arch.h> // for sys_invoke and cap_invoke
 #include <barrelfish_kpi/dispatcher_shared.h>
+#include <barrelfish_kpi/distcaps.h>            // for distcap_state_t
+#include <barrelfish_kpi/syscalls.h>
 #include <barrelfish/caddr.h>
 #include <barrelfish_kpi/paging_arch.h>
+
+/**
+ * capability invocation syscall wrapper, copied from x86_32 version
+ */
+static inline struct sysret cap_invoke(struct capref to, uintptr_t cmd,
+                                       uintptr_t arg2, uintptr_t arg3,
+                                       uintptr_t arg4, uintptr_t arg5,
+                                       uintptr_t arg6, uintptr_t arg7,
+                                       uintptr_t arg8, uintptr_t arg9,
+                                       uintptr_t arg10, uintptr_t arg11)
+{
+    uint8_t invoke_bits = get_cap_valid_bits(to);
+    capaddr_t invoke_cptr = get_cap_addr(to) >> (CPTR_BITS - invoke_bits);
+
+    // invoke_bits << 16 | cmd << 8 | syscall_invoke
+    uint32_t invocation = ((invoke_bits << 16) | (cmd << 8) | SYSCALL_INVOKE);
+
+    return syscall12(invocation, invoke_cptr, arg2, arg3, arg4, arg5, arg6,
+            arg7, arg8, arg9, arg10, arg11);
+}
+
+#define cap_invoke11(to, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k)   \
+    cap_invoke(to, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k)
+#define cap_invoke10(to, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j)   \
+    cap_invoke11(to, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, 0)
+#define cap_invoke9(to, _a, _b, _c, _d, _e, _f, _g, _h, _i)        \
+    cap_invoke10(to, _a, _b, _c, _d, _e, _f, _g, _h, _i, 0)
+#define cap_invoke8(to, _a, _b, _c, _d, _e, _f, _g, _h)    \
+    cap_invoke9(to, _a, _b, _c, _d, _e, _f, _g, _h, 0)
+#define cap_invoke7(to, _a, _b, _c, _d, _e, _f, _g)    \
+    cap_invoke8(to, _a, _b, _c, _d, _e, _f, _g, 0)
+#define cap_invoke6(to, _a, _b, _c, _d, _e, _f)        \
+    cap_invoke7(to, _a, _b, _c, _d, _e, _f, 0)
+#define cap_invoke5(to, _a, _b, _c, _d, _e)            \
+    cap_invoke6(to, _a, _b, _c, _d, _e, 0)
+#define cap_invoke4(to, _a, _b, _c, _d)                \
+    cap_invoke5(to, _a, _b, _c, _d, 0)
+#define cap_invoke3(to, _a, _b, _c)                    \
+    cap_invoke4(to, _a, _b, _c, 0)
+#define cap_invoke2(to, _a, _b)                        \
+    cap_invoke3(to, _a, _b, 0)
+#define cap_invoke1(to, _a)                            \
+    cap_invoke2(to, _a, 0)
 /**
  * \brief Retype a capability.
  *
@@ -240,6 +285,35 @@ static __attribute__((noinline, unused)) errval_t
 #else
 static inline errval_t
 #endif
+invoke_cnode_get_state(struct capref root, capaddr_t cap,
+                                              int bits, distcap_state_t *ret)
+{
+    uint8_t invoke_bits = get_cap_valid_bits(root);
+    capaddr_t invoke_cptr = get_cap_addr(root) >> (CPTR_BITS - invoke_bits);
+
+    assert (bits <= 0xff);
+
+    struct sysret sysret =
+        syscall4((invoke_bits << 16) | (CNodeCmd_GetState << 8) | SYSCALL_INVOKE,
+                invoke_cptr, cap, bits);
+
+    assert(ret != NULL);
+    if (err_is_ok(sysret.error)) {
+        *ret = sysret.value;
+    }
+    else {
+        *ret = 0;
+    }
+    return sysret.error;
+}
+
+//XXX: workaround for inline bug of arm-gcc 4.6.1 and lower
+#if defined(__ARM_ARCH_7A__) && defined(__GNUC__) \
+       && __GNUC__ == 4 && __GNUC_MINOR__ <= 6 && __GNUC_PATCHLEVEL__ <= 1
+static __attribute__((noinline, unused)) errval_t
+#else
+static inline errval_t
+#endif
 invoke_vnode_map(struct capref ptable, capaddr_t slot, capaddr_t from,
                  int frombits, uintptr_t flags, uintptr_t offset,
                  uintptr_t pte_count)
index fea59e9..bc73606 100644 (file)
@@ -18,6 +18,7 @@
 #include <barrelfish/syscall_arch.h>
 #include <barrelfish/caddr.h>
 #include <barrelfish_kpi/lmp.h>
+#include <barrelfish_kpi/syscalls.h>
 
 /**
  * \brief Send a message on the given LMP channel, if possible
index ee06e5b..5ad9136 100644 (file)
@@ -253,7 +253,7 @@ handle_delete(
     capaddr_t cptr = (capaddr_t)sa->arg2;
     int     bits = (int)sa->arg3;
 
-    return sys_delete(root, cptr, bits, false);
+    return sys_delete(root, cptr, bits);
 }
 
 static struct sysret
@@ -291,7 +291,7 @@ handle_revoke(
     capaddr_t cptr = (capaddr_t)sa->arg2;
     int     bits = (int)sa->arg3;
 
-    return sys_revoke(root, cptr, bits, false);
+    return sys_revoke(root, cptr, bits);
 }
 
 static struct sysret
@@ -390,33 +390,6 @@ monitor_handle_register(
 }
 
 static struct sysret
-monitor_remote_cap(
-       struct capability *kernel_cap,
-       arch_registers_state_t* context,
-       int argc)
-{
-       //assert(3 == argc);
-
-       struct registers_arm_syscall_args* sa = &context->syscall_args;
-
-       struct capability *root = &dcb_current->cspace.cap;
-    capaddr_t cptr = sa->arg2;
-    int bits = sa->arg3;
-    bool remote = (bool)sa->arg4;
-
-    struct cte *cte;
-    errval_t err = caps_lookup_slot(root, cptr, bits, &cte, CAPRIGHTS_WRITE);
-    if (err_is_fail(err)) {
-        return SYSRET(err_push(err, SYS_ERR_IDENTIFY_LOOKUP));
-    }
-
-    set_cap_remote(cte, remote);
-    bool has_desc = has_descendants(cte);
-
-    return (struct sysret){ .error = SYS_ERR_OK, .value = has_desc };
-}
-
-static struct sysret
 monitor_create_cap(
     struct capability *kernel_cap,
     arch_registers_state_t* context,
@@ -432,23 +405,28 @@ monitor_create_cap(
 
     /* Create the cap in the destination */
     capaddr_t cnode_cptr = sa->arg2;
-    int cnode_vbits    = sa->arg3;
-    size_t slot        = sa->arg4;
+    int cnode_vbits      = sa->arg3;
+    size_t slot          = sa->arg4;
+    coreid_t owner       = sa->arg5;
     struct capability *src =
-        (struct capability*)sa->arg5;
+        (struct capability*)sa->arg6;
 
-    //printf("type = %d\n", src->type);
+    /* Cannot create null caps */
+    if (src->type == ObjType_Null ) {
+        return SYSRET(SYS_ERR_ILLEGAL_DEST_TYPE);
+    }
 
-    /* Certain types cannot be created here */
-    if ((src->type == ObjType_Null) || (src->type == ObjType_EndPoint)
-        || (src->type == ObjType_Dispatcher) || (src->type == ObjType_Kernel)
-        || (src->type == ObjType_IRQTable)) {
+    /* For certain types, only foreign copies can be created here */
+    if ((src->type == ObjType_EndPoint || src->type == ObjType_Dispatcher
+         || src->type == ObjType_Kernel || src->type == ObjType_IRQTable)
+        && owner == my_core_id)
+    {
         return SYSRET(SYS_ERR_ILLEGAL_DEST_TYPE);
     }
 
     return SYSRET(caps_create_from_existing(&dcb_current->cspace.cap,
                                             cnode_cptr, cnode_vbits,
-                                            slot, src));
+                                            slot, owner, src));
 }
 
 /**
@@ -597,7 +575,6 @@ static invocation_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [KernelCmd_Get_arch_id]  = monitor_get_arch_id,
         [KernelCmd_Register]     = monitor_handle_register,
         [KernelCmd_Create_cap]   = monitor_create_cap,
-        [KernelCmd_Remote_cap]   = monitor_remote_cap,
         [KernelCmd_Spawn_core]   = monitor_spawn_core,
         [KernelCmd_Identify_cap] = monitor_identify_cap,
     },
@@ -649,6 +626,8 @@ handle_invoke(arch_registers_state_t *context, int argc)
                 // does the sender want to yield to the target
                 // if undeliverable?
                 bool yield = flags & LMP_FLAG_YIELD;
+                // is the cap (if present) to be deleted on send?
+                bool give_away = flags & LMP_FLAG_GIVEAWAY;
 
                 // Message registers in context are
                 // discontinguous for now so copy message words
@@ -668,7 +647,7 @@ handle_invoke(arch_registers_state_t *context, int argc)
 
                 // try to deliver message
                 r.error = lmp_deliver(to, dcb_current, msg_words,
-                                      length_words, send_cptr, send_bits);
+                                      length_words, send_cptr, send_bits, give_away);
 
                 /* Switch to reciever upon successful delivery
                  * with sync flag, or (some cases of)
index 5e921f0..2fcd086 100644 (file)
@@ -93,8 +93,8 @@ static lpaddr_t app_alloc_phys(size_t size)
 
 static lpaddr_t app_alloc_phys_aligned(size_t size, size_t align)
 {
-       app_alloc_phys_start = round_up(app_alloc_phys_start, align);
-       return app_alloc_phys(size);
+    app_alloc_phys_start = round_up(app_alloc_phys_start, align);
+    return app_alloc_phys(size);
 }
 
 /**
@@ -128,8 +128,8 @@ lpaddr_t bsp_alloc_phys(size_t size)
 
 static lpaddr_t bsp_alloc_phys_aligned(size_t size, size_t align)
 {
-       bsp_init_alloc_addr = round_up(bsp_init_alloc_addr, align);
-       return bsp_alloc_phys(size);
+    bsp_init_alloc_addr = round_up(bsp_init_alloc_addr, align);
+    return bsp_alloc_phys(size);
 }
 
 /**
@@ -171,7 +171,7 @@ static uint32_t elf_to_l2_flags(uint32_t eflags)
 {
 #ifdef __ARM_ARCH_7M__//the cortex-m3 does not actually understand these flags yet
 //XXX: if we ever allow all these flags, then remove the ifdef again
-    return 0; 
+    return 0;
 #else   //normal case, __ARM_ARCH_7A__
     switch (eflags & (PF_W|PF_R))
     {
@@ -290,7 +290,7 @@ void create_module_caps(struct spawn_state *st)
     // create cap for strings area in first slot of modulecn
     assert(st->modulecn_slot == 0);
     err = caps_create_new(ObjType_Frame, mmstrings_phys, BASE_PAGE_BITS,
-                          BASE_PAGE_BITS,
+                          BASE_PAGE_BITS, my_core_id,
                           caps_locate_slot(CNODE(st->modulecn),
                                            st->modulecn_slot++));
     assert(err_is_ok(err));
@@ -326,7 +326,7 @@ void create_module_caps(struct spawn_state *st)
             assert(st->modulecn_slot < (1UL << st->modulecn->cap.u.cnode.bits));
             // create as DevFrame cap to avoid zeroing memory contents
             err = caps_create_new(ObjType_DevFrame, base_addr, block_size,
-                                  block_size,
+                                  block_size, my_core_id,
                                   caps_locate_slot(CNODE(st->modulecn),
                                                    st->modulecn_slot++));
             assert(err_is_ok(err));
@@ -346,69 +346,64 @@ void create_module_caps(struct spawn_state *st)
 /// Create physical address range or RAM caps to unused physical memory
 static void create_phys_caps(lpaddr_t init_alloc_addr)
 {
-       errval_t err;
-
-       /* Walk multiboot MMAP structure, and create appropriate caps for memory */
-       char *mmap_addr = MBADDR_ASSTRING(glbl_core_data->mmap_addr);
-       genpaddr_t last_end_addr = 0;
-
-       for(char *m = mmap_addr; m < mmap_addr + glbl_core_data->mmap_length;)
-       {
-               struct multiboot_mmap *mmap = (struct multiboot_mmap * SAFE)TC(m);
-
-               debug(SUBSYS_STARTUP, "MMAP %llx--%llx Type %"PRIu32"\n",
-                               mmap->base_addr, mmap->base_addr + mmap->length,
-                               mmap->type);
-
-               if (last_end_addr >= init_alloc_addr
-                               && mmap->base_addr > last_end_addr)
-               {
-                       /* we have a gap between regions. add this as a physaddr range */
-                       debug(SUBSYS_STARTUP, "physical address range %llx--%llx\n",
-                                       last_end_addr, mmap->base_addr);
-
-                       err = create_caps_to_cnode(last_end_addr,
-                                       mmap->base_addr - last_end_addr,
-                                       RegionType_PhyAddr, &spawn_state, bootinfo);
-                       assert(err_is_ok(err));
-               }
-
-               if (mmap->type == MULTIBOOT_MEM_TYPE_RAM)
-               {
-                       genpaddr_t base_addr = mmap->base_addr;
-                       genpaddr_t end_addr  = base_addr + mmap->length;
-
-                       // only map RAM which is greater than init_alloc_addr
-                       if (end_addr > local_phys_to_gen_phys(init_alloc_addr))
-                       {
-                               if (base_addr < local_phys_to_gen_phys(init_alloc_addr)) {
-                                       base_addr = local_phys_to_gen_phys(init_alloc_addr);
-                               }
-                               debug(SUBSYS_STARTUP, "RAM %llx--%llx\n", base_addr, end_addr);
-
-                               assert(end_addr >= base_addr);
-                               err = create_caps_to_cnode(base_addr, end_addr - base_addr,
-                                               RegionType_Empty, &spawn_state, bootinfo);
-                               assert(err_is_ok(err));
-                       }
-               }
-               else if (mmap->base_addr > local_phys_to_gen_phys(init_alloc_addr))
-               {
-                       /* XXX: The multiboot spec just says that mapping types other than
-                        * RAM are "reserved", but GRUB always maps the ACPI tables as type
-                        * 3, and things like the IOAPIC tend to show up as type 2 or 4,
-                        * so we map all these regions as platform data
-                        */
-                       debug(SUBSYS_STARTUP, "platform %llx--%llx\n", mmap->base_addr,
-                                       mmap->base_addr + mmap->length);
-                       assert(mmap->base_addr > local_phys_to_gen_phys(init_alloc_addr));
-                       err = create_caps_to_cnode(mmap->base_addr, mmap->length,
-                                       RegionType_PlatformData, &spawn_state, bootinfo);
-                       assert(err_is_ok(err));
-               }
+    errval_t err;
+
+    /* Walk multiboot MMAP structure, and create appropriate caps for memory */
+    char *mmap_addr = MBADDR_ASSTRING(glbl_core_data->mmap_addr);
+    genpaddr_t last_end_addr = 0;
+
+    for(char *m = mmap_addr; m < mmap_addr + glbl_core_data->mmap_length;) {
+        struct multiboot_mmap *mmap = (struct multiboot_mmap * SAFE)TC(m);
+
+        debug(SUBSYS_STARTUP, "MMAP %llx--%llx Type %"PRIu32"\n",
+                mmap->base_addr, mmap->base_addr + mmap->length,
+                mmap->type);
+
+        if (last_end_addr >= init_alloc_addr
+                && mmap->base_addr > last_end_addr) {
+            /* we have a gap between regions. add this as a physaddr range */
+            debug(SUBSYS_STARTUP, "physical address range %llx--%llx\n",
+                    last_end_addr, mmap->base_addr);
+
+            err = create_caps_to_cnode(last_end_addr,
+                    mmap->base_addr - last_end_addr,
+                    RegionType_PhyAddr, &spawn_state, bootinfo);
+            assert(err_is_ok(err));
+        }
+
+        if (mmap->type == MULTIBOOT_MEM_TYPE_RAM) {
+            genpaddr_t base_addr = mmap->base_addr;
+            genpaddr_t end_addr  = base_addr + mmap->length;
+
+            // only map RAM which is greater than init_alloc_addr
+            if (end_addr > local_phys_to_gen_phys(init_alloc_addr))
+            {
+                if (base_addr < local_phys_to_gen_phys(init_alloc_addr)) {
+                    base_addr = local_phys_to_gen_phys(init_alloc_addr);
+                }
+                debug(SUBSYS_STARTUP, "RAM %llx--%llx\n", base_addr, end_addr);
+
+                assert(end_addr >= base_addr);
+                err = create_caps_to_cnode(base_addr, end_addr - base_addr,
+                        RegionType_Empty, &spawn_state, bootinfo);
+                assert(err_is_ok(err));
+            }
+        } else if (mmap->base_addr > local_phys_to_gen_phys(init_alloc_addr)) {
+            /* XXX: The multiboot spec just says that mapping types other than
+             * RAM are "reserved", but GRUB always maps the ACPI tables as type
+             * 3, and things like the IOAPIC tend to show up as type 2 or 4,
+             * so we map all these regions as platform data
+             */
+            debug(SUBSYS_STARTUP, "platform %llx--%llx\n", mmap->base_addr,
+                    mmap->base_addr + mmap->length);
+            assert(mmap->base_addr > local_phys_to_gen_phys(init_alloc_addr));
+            err = create_caps_to_cnode(mmap->base_addr, mmap->length,
+                    RegionType_PlatformData, &spawn_state, bootinfo);
+            assert(err_is_ok(err));
+        }
         last_end_addr = mmap->base_addr + mmap->length;
         m += mmap->size + 4;
-       }
+    }
 
     // Assert that we have some physical address space
     assert(last_end_addr != 0);
@@ -475,7 +470,7 @@ static void init_page_tables(void)
      */
     caps_create_new(ObjType_VNode_ARM_l1,
                     mem_to_local_phys((lvaddr_t)init_l1),
-                    vnode_objbits(ObjType_VNode_ARM_l1), 0,
+                    vnode_objbits(ObjType_VNode_ARM_l1), 0, my_core_id,
                     caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++)
                     );
 
@@ -489,7 +484,7 @@ static void init_page_tables(void)
         caps_create_new(
                         ObjType_VNode_ARM_l2,
                         mem_to_local_phys((lvaddr_t)init_l2) + (i << objbits_vnode),
-                        objbits_vnode, 0,
+                        objbits_vnode, 0, my_core_id,
                         caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++)
                         );
     }
@@ -550,7 +545,7 @@ static struct dcb *spawn_init_common(const char *name,
      * should not be a problem.
      */
     struct cte *iocap = caps_locate_slot(CNODE(spawn_state.taskcn), TASKCN_SLOT_IO);
-    errval_t  err = caps_create_new(ObjType_DevFrame, 0x40000000, 30, 30, iocap);
+    errval_t  err = caps_create_new(ObjType_DevFrame, 0x40000000, 30, 30, my_core_id, iocap);
         assert(err_is_ok(err));
 
     struct dispatcher_shared_generic *disp
@@ -625,37 +620,30 @@ struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys)
     /* Fill bootinfo struct */
     bootinfo->mem_spawn_core = KERNEL_IMAGE_SIZE; // Size of kernel
 
-    /*
-    // Map dispatcher
-    spawn_init_map(init_l2, INIT_VBASE, INIT_DISPATCHER_VBASE,
-                   mem_to_local_phys(init_dcb->disp), DISPATCHER_SIZE,
-                   INIT_PERM_RW);
-    disp_arm->disabled_save_area.named.rtls = INIT_DISPATCHER_VBASE;
-       */
     return init_dcb;
 }
 
 struct dcb *spawn_app_init(struct arm_core_data *core_data,
                            const char *name, alloc_phys_func alloc_phys)
 {
-       errval_t err;
+    errval_t err;
 
-       /* Construct cmdline args */
-       // Core id of the core that booted this core
-       char coreidchar[10];
-       snprintf(coreidchar, sizeof(coreidchar), "%d", core_data->src_core_id);
+    /* Construct cmdline args */
+    // Core id of the core that booted this core
+    char coreidchar[10];
+    snprintf(coreidchar, sizeof(coreidchar), "%d", core_data->src_core_id);
 
-       // IPI channel id of core that booted this core
-       char chanidchar[30];
-       snprintf(chanidchar, sizeof(chanidchar), "chanid=%"PRIu32, core_data->chan_id);
+    // IPI channel id of core that booted this core
+    char chanidchar[30];
+    snprintf(chanidchar, sizeof(chanidchar), "chanid=%"PRIu32, core_data->chan_id);
 
-       // Arch id of the core that booted this core
-       char archidchar[30];
-       snprintf(archidchar, sizeof(archidchar), "archid=%d",
-                       core_data->src_arch_id);
+    // Arch id of the core that booted this core
+    char archidchar[30];
+    snprintf(archidchar, sizeof(archidchar), "archid=%d",
+            core_data->src_arch_id);
 
-       const char *argv[5] = { name, coreidchar, chanidchar, archidchar };
-       int argc = 4;
+    const char *argv[5] = { name, coreidchar, chanidchar, archidchar };
+    int argc = 4;
 
     struct dcb *init_dcb = spawn_init_common(name, argc, argv,0, alloc_phys);
 
@@ -664,8 +652,8 @@ struct dcb *spawn_app_init(struct arm_core_data *core_data,
                TASKCN_SLOT_MON_URPC);
     // XXX: Create as devframe so the memory is not zeroed out
     err = caps_create_new(ObjType_DevFrame, core_data->urpc_frame_base,
-               core_data->urpc_frame_bits,
-               core_data->urpc_frame_bits, urpc_frame_cte);
+            core_data->urpc_frame_bits,
+            core_data->urpc_frame_bits, my_core_id, urpc_frame_cte);
     assert(err_is_ok(err));
     urpc_frame_cte->cap.type = ObjType_Frame;
     lpaddr_t urpc_ptr = gen_phys_to_local_phys(urpc_frame_cte->cap.u.frame.base);
@@ -680,7 +668,7 @@ struct dcb *spawn_app_init(struct arm_core_data *core_data,
     genvaddr_t entry_point, got_base=0;
     err = elf_load(EM_ARM, startup_alloc_init, &l2_info,
                local_phys_to_mem(core_data->monitor_binary),
-               core_data->monitor_binary_size, &entry_point);
+                core_data->monitor_binary_size, &entry_point);
     if (err_is_fail(err)) {
        //err_print_calltrace(err);
        panic("ELF load of init module failed!");
index d0129d7..91ee3e3 100644 (file)
@@ -50,7 +50,14 @@ struct cte {
     char padding[(1UL << OBJBITS_CTE)
                  - sizeof(struct capability) - sizeof(struct mdbnode)
                  - sizeof(struct delete_list) - sizeof(struct mapping_info)];
-};
+}
+// XXX: this is ugly, we might consider having packed for all architectures. -SG
+#if defined(__ARM_ARCH_7A__)
+__attribute__((packed))
+#endif
+;
+
+STATIC_ASSERT_SIZEOF(struct cte, (1UL << OBJBITS_CTE));
 
 static inline struct cte *caps_locate_slot(lpaddr_t cnode, cslot_t offset)
 {
index 37dfeae..725c870 100644 (file)
@@ -86,6 +86,12 @@ errval_t sys_debug_set_breakpoint(uintptr_t addr, uint8_t mode, uint8_t length)
                     DEBUG_SET_BREAKPOINT, addr, mode, length).error;
 }
 
+errval_t sys_debug_cap_trace_ctrl(bool enable, genpaddr_t start, gensize_t size)
+{
+    return syscall5(SYSCALL_DEBUG,
+                    DEBUG_TRACE_PMEM_CTRL, enable, start, size).error;
+}
+
 errval_t sys_debug_hardware_timer_read(uintptr_t* v)
 {
     struct sysret sr
index 2f69870..3868ddc 100644 (file)
@@ -93,8 +93,7 @@ setup_intermon_connection(int local_hwid,
     }
 
     // Mark it remote
-    bool has_descendants;
-    err = monitor_cap_remote(frame, true, &has_descendants);
+    err = monitor_remote_relations(frame, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
     if (err_is_fail(err)) {
         return err;
     }
@@ -244,8 +243,7 @@ cpu_memory_prepare(size_t *size,
     }
 
     // Mark memory as remote
-    bool has_descendants;
-    err = monitor_cap_remote(cap, true, &has_descendants);
+    err = monitor_remote_relations(cap, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
     if (err_is_fail(err)) {
         return err;
     }
@@ -292,8 +290,7 @@ spawn_memory_prepare(size_t size, struct capref *cap_ret,
     }
 
     // Mark memory as remote
-    bool has_descendants;
-    err = monitor_cap_remote(cap, true, &has_descendants);
+    err = monitor_remote_relations(cap, RRELS_COPY_BIT, RRELS_COPY_BIT, NULL);
     if (err_is_fail(err)) {
         return err;
     }
index 474b06b..27d5c1a 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <barrelfish/barrelfish.h>
+#include <barrelfish/core_state.h>
 #include "monitor.h"
 #include "capops.h"
 #include "capsend.h"
index 5b791b0..c78795b 100644 (file)
@@ -4,6 +4,7 @@
 #include <monitor_invocations.h>
 #include <caplock.h>
 #include <barrelfish/event_queue.h>
+#include <barrelfish/slot_alloc.h>
 
 static struct event_queue trigger_queue;
 static bool triggered;
index 737eb25..fa7812b 100644 (file)
@@ -17,6 +17,9 @@
 
 #include <barrelfish/syscall_arch.h>
 #include <barrelfish/caddr.h>
+#include <barrelfish/invocations_arch.h>
+#include <barrelfish_kpi/cpu.h>
+#include <barrelfish_kpi/syscalls.h>
 
 /**
  * \brief Spawn a new core.
@@ -84,7 +87,7 @@ invoke_monitor_nullify_cap(capaddr_t cap, int bits)
 }
 
 static inline errval_t
-invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int bits, capaddr_t slot)
+invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int bits, capaddr_t slot, coreid_t owner)
 {
     uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
     capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
@@ -95,22 +98,6 @@ invoke_monitor_create_cap(uint64_t *raw, capaddr_t caddr, int bits, capaddr_t sl
 }
 
 static inline errval_t
-invoke_monitor_cap_remote(capaddr_t cap, int bits, bool is_remote,
-                          bool * has_descendents)
-{
-    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
-    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
-
-    struct sysret r;
-    r = syscall5((invoke_bits << 16) | (KernelCmd_Remote_cap << 8)
-                 | SYSCALL_INVOKE, invoke_cptr, cap, bits, is_remote);
-    if (err_is_ok(r.error)) {
-        *has_descendents = r.value;
-    }
-    return r.error;
-}
-
-static inline errval_t
 invoke_monitor_register(struct capref ep)
 {
     uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
@@ -132,56 +119,127 @@ invoke_monitor_remote_cap_retype(capaddr_t rootcap_addr, uint8_t rootcap_vbits,
 }
 
 static inline errval_t
-invoke_monitor_remote_cap_delete(capaddr_t rootcap_addr, uint8_t rootcap_vbits,
-                                 capaddr_t src, int bits) {
-    assert(src != CPTR_NULL);
+invoke_monitor_get_cap_owner(capaddr_t root, int rbits, capaddr_t cap, int cbits, coreid_t *ret_owner)
+{
+    struct sysret sysret = cap_invoke5(cap_kernel, KernelCmd_Get_cap_owner,
+                                       root, rbits, cap, cbits);
+    if (err_is_ok(sysret.error)) {
+        *ret_owner = sysret.value;
+    }
+    return sysret.error;
+}
 
-    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
-    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
+static inline errval_t
+invoke_monitor_set_cap_owner(capaddr_t root, int rbits, capaddr_t cap, int cbits, coreid_t owner)
+{
+    return cap_invoke6(cap_kernel, KernelCmd_Set_cap_owner, root, rbits, cap, cbits, owner).error;
+}
 
-    return syscall6(invoke_bits << 16 | (MonitorCmd_Delete << 8)
-                    | SYSCALL_INVOKE, invoke_cptr, rootcap_addr,
-                    rootcap_vbits, src, bits).error;
+
+static inline errval_t
+invoke_monitor_remote_relations(capaddr_t root_cap, int root_bits,
+                                capaddr_t cap, int bits,
+                                uint8_t relations, uint8_t mask,
+                                uint8_t *ret_remote_relations)
+{
+    struct sysret r = cap_invoke6(cap_kernel, KernelCmd_Remote_relations,
+                                  root_cap, root_bits, cap, bits,
+                                  ((uint16_t)relations) | (((uint16_t)mask)<<8));
+    if (err_is_ok(r.error) && ret_remote_relations) {
+        *ret_remote_relations = r.value;
+    }
+    return r.error;
 }
 
 static inline errval_t
-invoke_monitor_remote_cap_revoke(capaddr_t rootcap_addr, uint8_t rootcap_vbits,
-                                 capaddr_t src, int bits) {
-    assert(src != CPTR_NULL);
+invoke_monitor_cap_has_relations(capaddr_t caddr, uint8_t bits, uint8_t mask, uint8_t *res)
+{
+    assert(res);
+    struct sysret ret = cap_invoke4(cap_kernel, KernelCmd_Cap_has_relations,
+                                    caddr, bits, mask);
+    if (err_is_ok(ret.error)) {
+        *res = ret.value;
+    }
+    return ret.error;
+}
 
-    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
-    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
 
-    return syscall6(invoke_bits << 16 | (MonitorCmd_Revoke << 8)
-                    | SYSCALL_INVOKE, invoke_cptr, rootcap_addr,
-                    rootcap_vbits, src, bits).error;
+static inline errval_t
+invoke_monitor_lock_cap(capaddr_t root, int rbits, capaddr_t cap, int cbits)
+{
+    return cap_invoke5(cap_kernel, KernelCmd_Lock_cap, root, rbits, cap, cbits).error;
 }
 
 static inline errval_t
-invoke_monitor_get_cap_owner(capaddr_t cap, int bits, coreid_t *res)
+invoke_monitor_unlock_cap(capaddr_t root, int rbits, capaddr_t cap, int cbits)
 {
-    assert(res);
-    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
-    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
+    return cap_invoke5(cap_kernel, KernelCmd_Unlock_cap, root, rbits, cap, cbits).error;
+}
+
+static inline errval_t
+invoke_monitor_delete_last(capaddr_t root, int rbits, capaddr_t cap, int cbits,
+                           capaddr_t retcn, int retcnbits, cslot_t retslot)
+{
+    assert(rbits <= 0xff);
+    assert(cbits <= 0xff);
+    assert(retcnbits <= 0xff);
+
+    return cap_invoke6(cap_kernel, KernelCmd_Delete_last, root, cap,
+                       retcn, retslot, ((cbits<<16)|(rbits<<8)|retcnbits)).error;
+}
+
+static inline errval_t
+invoke_monitor_delete_foreigns(capaddr_t cap, int bits)
+{
+    return cap_invoke3(cap_kernel, KernelCmd_Delete_foreigns, cap, bits).error;
+}
+
+static inline errval_t
+invoke_monitor_revoke_mark_target(capaddr_t root, int rbits,
+                                  capaddr_t cap, int cbits)
+{
+    return cap_invoke5(cap_kernel, KernelCmd_Revoke_mark_target,
+                       root, rbits, cap, cbits).error;
+}
+
+static inline errval_t
+invoke_monitor_revoke_mark_relations(uint64_t *raw_base)
+{
+    // XXX: this is assumed in client code of this function!
+    assert(sizeof(struct capability) / sizeof(uint64_t) <= 4);
+    return cap_invoke2(cap_kernel, KernelCmd_Revoke_mark_relations,
+                       (uintptr_t)raw_base).error;
+}
+
+static inline errval_t
+invoke_monitor_delete_step(capaddr_t retcn, int retcnbits, cslot_t retslot)
+{
+    return cap_invoke4(cap_kernel, KernelCmd_Delete_step,
+                       retcn, retcnbits, retslot).error;
+}
+
+static inline errval_t
+invoke_monitor_clear_step(capaddr_t retcn, int retcnbits, cslot_t retslot)
+{
+    return cap_invoke4(cap_kernel, KernelCmd_Clear_step,
+                       retcn, retcnbits, retslot).error;
+}
+
+static inline errval_t
+invoke_monitor_has_descendants(uint64_t *raw, bool *res)
+{
+    // XXX: this is assumed in client code of this function!
+    assert(sizeof(struct capability) / sizeof(uint64_t) <= 4);
 
     struct sysret sysret;
-    sysret = syscall3((invoke_bits << 16) | (KernelCmd_Get_cap_owner << 8)
-                      | SYSCALL_INVOKE, invoke_cptr, cap, bits);
+    sysret = cap_invoke2(cap_kernel, KernelCmd_Has_descendants,
+                         (uintptr_t)raw);
     if (err_is_ok(sysret.error)) {
         *res = sysret.value;
     }
     return sysret.error;
 }
 
-static inline errval_t
-invoke_monitor_set_cap_owner(capaddr_t cap, int bits, coreid_t owner)
-{
-    uint8_t invoke_bits = get_cap_valid_bits(cap_kernel);
-    capaddr_t invoke_cptr = get_cap_addr(cap_kernel) >> (CPTR_BITS - invoke_bits);
-
-    return syscall4((invoke_bits << 16) | (KernelCmd_Set_cap_owner << 8)
-                    | SYSCALL_INVOKE, invoke_cptr, cap, bits, owner).error;
-}
 
 /**
  * \brief Set up tracing in the kernel
@@ -266,4 +324,14 @@ invoke_monitor_ipi_delete(int chanid)
                     chanid).error;
 }
 
+static inline errval_t
+invoke_monitor_copy_existing(uint64_t *raw, capaddr_t cn_addr, int cn_bits, cslot_t slot)
+{
+    // XXX: this is assumed in client code of this function!
+    assert(sizeof(struct capability) <= 4*sizeof(uint64_t));
+
+    return cap_invoke5(cap_kernel, KernelCmd_Copy_existing,
+                       cn_addr, cn_bits, slot, (uintptr_t)raw).error;
+}
+
 #endif