void rpc_sv_push_cptr(void *cl, ENDPT v) { if (!v) return; seL4_SetCap(_rpc_cp++, v); }
/* sends off a frame to the relevant swap file (in or out) * * returns True if the root server needs to be notified immediately (ie not * waiting for an async reply */ static int mmap_queue_schedule (int direction, vaddr_t vaddr, struct frameinfo *frame, void* callback, struct pawpaw_event* evt) { struct mmap_queue_item* q = mmap_queue_new (frame, callback, evt); if (!q) { return false; } //assert (frame); if (direction == PAGE_SWAP_IN) { assert (frame->file); assert (frame->file->file); /* FIXME: seriously this needs work */ struct seen_item *item = regd_caps; while (item) { if (item->cap == frame->file->file) { break; } item = item->next; } /* register with the filesystem for async notifications if this is our * first time with this file */ if (!item) { seL4_MessageInfo_t reg_msg = seL4_MessageInfo_new (0, 0, 1, 1); seL4_CPtr their_cap = cspace_mint_cap (cur_cspace, cur_cspace, _mmap_ep, seL4_AllRights, seL4_CapData_Badge_new ((seL4_Word)frame)); assert (their_cap); seL4_SetMR (0, VFS_REGISTER_CAP); seL4_SetCap (0, their_cap); seL4_Call (frame->file->file, reg_msg); seL4_Word id = seL4_GetMR (0); assert (id > 0); item = malloc (sizeof (struct seen_item)); assert (item); item->cap = frame->file->file; item->id = id; item->next = regd_caps; regd_caps = item; } seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 1, 4); seL4_Word id = cid_next (); maps_append (id, ((thread_t)evt->args[1])->pid, vaddr); /* create a "valid badge" in the badgemap so we can mount the * shared buffer */ seL4_CPtr badge_cap = cspace_mint_cap ( cur_cspace, cur_cspace, _badgemap_ep, seL4_AllRights, seL4_CapData_Badge_new (id)); assert (badge_cap); assert (frame->file); msg = seL4_MessageInfo_new (0, 0, 1, 7); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_READ_OFFSET); seL4_SetMR (1, id); seL4_SetMR (2, frame->file->load_length); seL4_SetMR (3, frame->file->file_offset); seL4_SetMR (4, frame->file->load_offset); seL4_SetMR (5, item->id); /* async ID */ seL4_SetMR (6, (seL4_Word)frame); /* use frame ptr as "event id" */ seL4_Send (frame->file->file, msg); /* and we go back to waiting on our EP */ } else if (direction == PAGE_SWAP_OUT) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 1, 4); /* FIXME: needs to be cleaned up on successful swap */ seL4_Word id = cid_next (); maps_append (id, 0, vaddr); /* create a "valid badge" in the badgemap so we can mount the shared * buffer */ seL4_CPtr badge_cap = cspace_mint_cap (cur_cspace, cur_cspace, _badgemap_ep, seL4_AllRights, seL4_CapData_Badge_new (id)); assert (badge_cap); seL4_Word page_id = last_page_id * PAGE_SIZE; last_page_id++; seL4_Word wrote = 0; while (wrote < PAGE_SIZE) { msg = seL4_MessageInfo_new (0, 0, 1, 7); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_WRITE_OFFSET); seL4_SetMR (1, id); seL4_SetMR (2, PAGE_SIZE - wrote); /* write whole page out */ seL4_SetMR (3, page_id + wrote); /* file offset */ seL4_SetMR (4, wrote); /* load into start of share */ //seL4_SetMR (5, swap_id); /* async ID - NOT USED */ seL4_SetMR (6, (seL4_Word)frame); /* and write it out */ seL4_Call (swap_cap, msg); seL4_Word wrote_this_call = seL4_GetMR (0); assert (wrote_this_call >= 0); wrote += wrote_this_call; } cspace_delete_cap (cur_cspace, badge_cap); /* memory map it */ frame->file = frame_create_mmap (swap_cap, 0, page_id, PAGE_SIZE); assert (frame->file); mmap_move_done (q); return true; /* and we go back to waiting on our EP */ } else if (direction == BUFFER_OPEN_LOAD) { seL4_Word share_id = cid_next (); maps_append (share_id, 0, vaddr); /* create a "valid badge" in the badgemap so we can mount the shared * buffer */ seL4_CPtr badge_cap = cspace_mint_cap (cur_cspace, cur_cspace, _badgemap_ep, seL4_AllRights, seL4_CapData_Badge_new (share_id)); assert (badge_cap); seL4_CPtr recv_cap = cspace_alloc_slot (cur_cspace); assert (recv_cap); seL4_SetCapReceivePath (cur_cspace->root_cnode, recv_cap, CSPACE_DEPTH); printf ("OK, asking VFS to open our file '%s'\n", (char*)vaddr); seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 1, 4); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_OPEN); seL4_SetMR (1, share_id); seL4_SetMR (2, FM_READ); seL4_SetMR (3, 0); /* XXX: hack of the century - should really ask VFS async * for cap */ seL4_CPtr nfs_fs_cap = service_lookup ("fs_nfs"); while (!nfs_fs_cap) { printf ("failed to find nfs service\n"); nfs_fs_cap = service_lookup ("fs_nfs"); //return false; } printf ("calling on %d\n", nfs_fs_cap); seL4_MessageInfo_t reply = seL4_Call (nfs_fs_cap, msg); if (seL4_GetMR (0) != 0) { printf ("%s: failed to open file\n", __FUNCTION__); //return false; mmap_move_done (q); q->frame = NULL; return true; } assert (seL4_MessageInfo_get_capsUnwrapped (reply) == 0); if (seL4_MessageInfo_get_extraCaps (reply) != 1) { /* could not find file */ printf ("%s: did not have cap\n", __FUNCTION__); return false; } printf ("yum, setting evt arg\n"); evt->args[2] = recv_cap; /* then, load in the first page worth of the file into kmem, so we * can read the headers we need */ printf ("sweeto, trying to read in data...\n"); msg = seL4_MessageInfo_new (0, 0, 1, 3); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_READ); seL4_SetMR (1, share_id); seL4_SetMR (2, PAGE_SIZE); //seL4_SetMR (3, 0); /* offset */ printf ("ASKING TO READ FILE\n"); seL4_Call (recv_cap, msg); if (seL4_GetMR (0) <= 0) { printf ("%s: read was empty/failed\n", __FUNCTION__); //return NULL; return false; } printf("read was ok\n"); mmap_move_done (q); return true; } return false; }
void rpc_push_cptr(ENDPT v) { seL4_SetCap(_rpc_cp++, v); }