void rpc_setup_recv_cspace(seL4_CPtr cspace, seL4_CPtr recv_cslot, seL4_Word depth) { assert(recv_cslot); seL4_SetCapReceivePath(cspace, recv_cslot, depth); _rpc_recv_cslot = recv_cslot; }
void rpc_setup_recv(seL4_CPtr recv_cslot) { assert(recv_cslot); seL4_SetCapReceivePath(REFOS_CSPACE, recv_cslot, REFOS_CSPACE_DEPTH); _rpc_recv_cslot = recv_cslot; }
int stat (const char *path, stat_t *buf) { seL4_MessageInfo_t msg; if (!vfs_ep) { vfs_ep = pawpaw_service_lookup ("svc_vfs"); } struct pawpaw_share* share = pawpaw_share_new (); if (!share) { return -1; } memset (share->buf, 0, PAPAYA_IPC_PAGE_SIZE); if (path && path[0] != '/') { strcpy (share->buf, cwd); int cwdlen = strlen (cwd); if (cwdlen > 0 && cwd[cwdlen - 1] != '/') { strcat (share->buf, "/"); } strcat (share->buf, path); /* XXX: check if buffer overflows */ } else { strcpy (share->buf, path); } msg = seL4_MessageInfo_new (0, 0, 1, 2); seL4_CPtr recv_cap = pawpaw_cspace_alloc_slot (); if (!recv_cap) { pawpaw_share_unmount (share); return -1; } seL4_SetCapReceivePath (PAPAYA_ROOT_CNODE_SLOT, recv_cap, PAPAYA_CSPACE_DEPTH); seL4_SetCap (0, share->cap); seL4_SetMR (0, VFS_STAT); seL4_SetMR (1, share->id); seL4_Call (vfs_ep, msg); int status = seL4_GetMR (0); if (status == 0) { memcpy (buf, share->buf, sizeof (stat_t)); } pawpaw_share_unmount (share); return status; }
int getdirent (int pos, char *path, size_t nbyte) { seL4_MessageInfo_t msg; if (!vfs_ep) { vfs_ep = pawpaw_service_lookup ("svc_vfs"); } struct pawpaw_share* share = pawpaw_share_new (); if (!share) { return -1; } msg = seL4_MessageInfo_new (0, 0, 1, 4); seL4_CPtr recv_cap = pawpaw_cspace_alloc_slot (); if (!recv_cap) { pawpaw_share_unmount (share); return -1; } seL4_SetCapReceivePath (PAPAYA_ROOT_CNODE_SLOT, recv_cap, PAPAYA_CSPACE_DEPTH); seL4_SetCap (0, share->cap); memset (share->buf, 0, PAPAYA_IPC_PAGE_SIZE); strcpy (share->buf, cwd); seL4_SetMR (0, VFS_LISTDIR); seL4_SetMR (1, share->id); seL4_SetMR (2, pos); seL4_SetMR (3, nbyte); seL4_Call (vfs_ep, msg); int read = seL4_GetMR (0); if (read >= 0) { memcpy (path, share->buf, nbyte); pawpaw_share_unmount (share); return read; } else { pawpaw_share_unmount (share); return -1; } }
/* FIXME: what if the VFS service dies and then restarts? endpoint will have changed */ fildes_t open(const char *path, fmode_t mode) { seL4_MessageInfo_t msg; if (!vfs_ep) { vfs_ep = pawpaw_service_lookup ("svc_vfs"); } struct pawpaw_share* share = pawpaw_share_new (); if (!share) { return -1; } struct sos_fhandle* h = malloc (sizeof (struct sos_fhandle)); if (!h) { pawpaw_share_unmount (share); return -1; } msg = seL4_MessageInfo_new (0, 0, 1, 3); seL4_CPtr recv_cap = pawpaw_cspace_alloc_slot (); if (!recv_cap) { pawpaw_share_unmount (share); free (h); return -1; } seL4_SetCapReceivePath (PAPAYA_ROOT_CNODE_SLOT, recv_cap, PAPAYA_CSPACE_DEPTH); seL4_SetCap (0, share->cap); memset (share->buf, 0, PAPAYA_IPC_PAGE_SIZE); if (path && path[0] != '/') { strcpy (share->buf, cwd); int cwdlen = strlen (cwd); if (cwdlen > 0 && cwd[cwdlen - 1] != '/') { strcat (share->buf, "/"); } strcat (share->buf, path); /* XXX: check if buffer overflows */ } else { strcpy (share->buf, path); } seL4_SetMR (0, VFS_OPEN); seL4_SetMR (1, share->id); seL4_SetMR (2, mode); seL4_MessageInfo_t reply = seL4_Call (vfs_ep, msg); if (seL4_MessageInfo_get_extraCaps (reply) >= 1) { h->share = share; h->fd = last_fd; last_fd++; h->cap = recv_cap; /* add to list */ h->next = open_list; open_list = h; return h->fd; } else { free (h); pawpaw_share_unmount (share); pawpaw_cspace_free_slot (recv_cap); return seL4_GetMR (0); } }
/* 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; }