Ejemplo n.º 1
0
Archivo: rpc.c Proyecto: seL4/refos
void
rpc_sv_push_cptr(void *cl, ENDPT v)
{
    if (!v) return;
    seL4_SetCap(_rpc_cp++, v);
}
Ejemplo n.º 2
0
Archivo: swap.c Proyecto: ahixon/papaya
/* 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;
}
Ejemplo n.º 3
0
Archivo: rpc.c Proyecto: seL4/refos
void
rpc_push_cptr(ENDPT v)
{
	seL4_SetCap(_rpc_cp++, v);
}