enum ia_css_err ia_css_frame_allocate_with_buffer_size(
	struct ia_css_frame **frame,
	const unsigned int buffer_size_bytes,
	const bool contiguous)
{
	/* AM: Body coppied from frame_allocate_with_data(). */
	enum ia_css_err err;
	struct ia_css_frame *me = frame_create(0, 0,
		IA_CSS_FRAME_FORMAT_NUM,/* Not valid format yet */
		0, 0, contiguous, false);

	if (me == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

	/* Get the data size */
	me->data_bytes = buffer_size_bytes;

	err = frame_allocate_buffer_data(me);

	if (err != IA_CSS_SUCCESS) {
		sh_css_free(me);
		return err;
	}

	*frame = me;

	return err;
}
Beispiel #2
0
static struct resizor *
resizor_create(struct display *display)
{
	struct resizor *resizor;

	resizor = malloc(sizeof *resizor);
	if (resizor == NULL)
		return resizor;
	memset(resizor, 0, sizeof *resizor);

	resizor->window = window_create(display);
	resizor->widget = frame_create(resizor->window, resizor);
	window_set_title(resizor->window, "Wayland Resizor");
	resizor->display = display;

	window_set_key_handler(resizor->window, key_handler);
	window_set_user_data(resizor->window, resizor);
	widget_set_redraw_handler(resizor->widget, redraw_handler);
	window_set_keyboard_focus_handler(resizor->window,
					  keyboard_focus_handler);

	widget_set_button_handler(resizor->widget, button_handler);

	resizor->height.previous = 400;
	resizor->height.current = 400;
	resizor->height.target = 400;

	resizor->width.previous = 400;
	resizor->width.current = 400;
	resizor->width.target = 400;

	widget_schedule_resize(resizor->widget, 400, 400);

	return resizor;
}
static enum ia_css_err frame_allocate_with_data(struct ia_css_frame **frame,
	unsigned int width,
	unsigned int height,
	enum ia_css_frame_format format,
	unsigned int padded_width,
	unsigned int raw_bit_depth,
	bool contiguous)
{
	enum ia_css_err err;
	struct ia_css_frame *me = frame_create(width,
		height,
		format,
		padded_width,
		raw_bit_depth,
		contiguous,
		true);

	if (me == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

	err = ia_css_frame_init_planes(me);

	if (err == IA_CSS_SUCCESS)
		err = frame_allocate_buffer_data(me);

	if (err != IA_CSS_SUCCESS) {
		sh_css_free(me);
		return err;
	}

	*frame = me;

	return err;
}
Beispiel #4
0
static struct clickdot *
clickdot_create(struct display *display)
{
	struct clickdot *clickdot;

	clickdot = xzalloc(sizeof *clickdot);
	clickdot->window = window_create(display);
	clickdot->widget = frame_create(clickdot->window, clickdot);
	window_set_title(clickdot->window, "Wayland ClickDot");
	clickdot->display = display;
	clickdot->buffer = NULL;

	window_set_key_handler(clickdot->window, key_handler);
	window_set_user_data(clickdot->window, clickdot);
	window_set_keyboard_focus_handler(clickdot->window,
					  keyboard_focus_handler);

	widget_set_redraw_handler(clickdot->widget, redraw_handler);
	widget_set_button_handler(clickdot->widget, button_handler);
	widget_set_motion_handler(clickdot->widget, motion_handler);
	widget_set_resize_handler(clickdot->widget, resize_handler);
	widget_set_leave_handler(clickdot->widget, leave_handler);

	widget_schedule_resize(clickdot->widget, 500, 400);
	clickdot->dot.x = 250;
	clickdot->dot.y = 200;
	clickdot->line.x = -1;
	clickdot->line.y = -1;
	clickdot->line.old_x = -1;
	clickdot->line.old_y = -1;
	clickdot->reset = 0;

	return clickdot;
}
Beispiel #5
0
int
main(int argc, char *argv[])
{
	struct editor editor;

	editor.display = display_create(argc, argv);
	if (editor.display == NULL) {
		fprintf(stderr, "failed to create display: %m\n");
		return -1;
	}
	wl_display_add_global_listener(display_get_display(editor.display),
				       global_handler, &editor);


	editor.window = window_create(editor.display);
	editor.widget = frame_create(editor.window, &editor);

	editor.entry = text_entry_create(&editor, "Entry");
	editor.editor = text_entry_create(&editor, "Editor");

	window_set_title(editor.window, "Text Editor");

	widget_set_redraw_handler(editor.widget, redraw_handler);
	widget_set_resize_handler(editor.widget, resize_handler);
	widget_set_button_handler(editor.widget, button_handler);

	window_schedule_resize(editor.window, 500, 400);

	display_run(editor.display);

	text_entry_destroy(editor.entry);
	text_entry_destroy(editor.editor);

	return 0;
}
Beispiel #6
0
static struct view *
view_create(struct display *display,
	    uint32_t key, const char *filename, int fullscreen, int *view_counter)
{
	struct view *view;
	gchar *basename;
	gchar *title;
	GFile *file = NULL;
	GError *error = NULL;

	view = malloc(sizeof *view);
	if (view == NULL)
		return view;
	memset(view, 0, sizeof *view);

	file = g_file_new_for_commandline_arg(filename);
	basename = g_file_get_basename(file);
	if(!basename) {
		title = g_strdup("Wayland View");
	} else {
	        title = g_strdup_printf("Wayland View - %s", basename);
	        g_free(basename);
	}

        view->document = poppler_document_new_from_file(g_file_get_uri(file),
                                                        NULL, &error);

        if(error) {
		title = g_strdup("File not found");
        }

	view->window = window_create(display);
	view->widget = frame_create(view->window, view);
	window_set_title(view->window, title);
	g_free(title);
	view->display = display;

	window_set_user_data(view->window, view);
	window_set_key_handler(view->window, key_handler);
	window_set_keyboard_focus_handler(view->window,
					  keyboard_focus_handler);
	window_set_fullscreen_handler(view->window, fullscreen_handler);
	window_set_close_handler(view->window, close_handler);

	widget_set_button_handler(view->widget, button_handler);
	widget_set_resize_handler(view->widget, resize_handler);
	widget_set_redraw_handler(view->widget, redraw_handler);

	view->page = 0;

	view->fullscreen = fullscreen;
	window_set_fullscreen(view->window, view->fullscreen);

	window_schedule_resize(view->window, 500, 400);
	view->view_counter = view_counter;
	*view_counter += 1;

	return view;
}
Beispiel #7
0
// FIXME: error handling (not asserts) needed in this function
static void mem_allocate_handler(struct mem_binding *b, uint8_t bits,
                                 genpaddr_t minbase, genpaddr_t maxlimit)
{
    struct capref *cap = malloc(sizeof(struct capref));
    errval_t err, ret;

    trace_event(TRACE_SUBSYS_MEMSERV, TRACE_EVENT_MEMSERV_ALLOC, bits);

    /* refill slot allocator if needed */
    err = slot_prealloc_refill(mm_ram.slot_alloc_inst);
    assert(err_is_ok(err));

    /* refill slab allocator if needed */
    while (slab_freecount(&mm_ram.slabs) <= MINSPARENODES) {
        struct capref frame;
        err = msa.a.alloc(&msa.a, &frame);
        assert(err_is_ok(err));
        err = frame_create(frame, BASE_PAGE_SIZE * 8, NULL);
        assert(err_is_ok(err));
        void *buf;
        err = vspace_map_one_frame(&buf, BASE_PAGE_SIZE * 8, frame, NULL, NULL);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "vspace_map_one_frame failed");
            assert(buf);
        }
        slab_grow(&mm_ram.slabs, buf, BASE_PAGE_SIZE * 8);
    }

    ret = mymm_alloc(cap, bits, minbase, maxlimit);
    if (err_is_ok(ret)) {
        mem_avail -= 1UL << bits;
    } else {
        // DEBUG_ERR(ret, "allocation of %d bits in % " PRIxGENPADDR "-%" PRIxGENPADDR " failed",
        //          bits, minbase, maxlimit);
        *cap = NULL_CAP;
    }

    /* Reply */
    err = b->tx_vtbl.allocate_response(b, MKCONT(allocate_response_done, cap),
                                       ret, *cap);
    if (err_is_fail(err)) {
        if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
            struct pending_reply *r = malloc(sizeof(struct pending_reply));
            assert(r != NULL);
            r->b = b;
            r->err = ret;
            r->cap = cap;
            err = b->register_send(b, get_default_waitset(), MKCONT(retry_reply,r));
            assert(err_is_ok(err));
        } else {
            DEBUG_ERR(err, "failed to reply to memory request");
            allocate_response_done(cap);
        }
    }
}
Beispiel #8
0
static struct image *
image_create(struct display *display, const char *filename,
	     int *image_counter)
{
	struct image *image;
	char *b, *copy, title[512];;

	image = malloc(sizeof *image);
	if (image == NULL)
		return image;
	memset(image, 0, sizeof *image);

	copy = strdup(filename);
	b = basename(copy);
	snprintf(title, sizeof title, "Wayland Image - %s", b);
	free(copy);

	image->filename = strdup(filename);
	image->image = load_cairo_surface(filename);

	if (!image->image) {
		fprintf(stderr, "could not find the image %s!\n", b);
		free(image);
		return NULL;
	}

	image->window = window_create(display);
	image->widget = frame_create(image->window, image);
	window_set_title(image->window, title);
	image->display = display;
	image->image_counter = image_counter;
	*image_counter += 1;
	image->initialized = false;

	window_set_user_data(image->window, image);
	widget_set_redraw_handler(image->widget, redraw_handler);
	widget_set_resize_handler(image->widget, resize_handler);
	window_set_keyboard_focus_handler(image->window,
					  keyboard_focus_handler);
	window_set_fullscreen_handler(image->window, fullscreen_handler);
	window_set_close_handler(image->window, close_handler);

	widget_set_enter_handler(image->widget, enter_handler);
	widget_set_motion_handler(image->widget, motion_handler);
	widget_set_button_handler(image->widget, button_handler);
	widget_set_axis_handler(image->widget, axis_handler);
	window_set_key_handler(image->window, key_handler);
	widget_schedule_resize(image->widget, 500, 400);

	return image;
}
Beispiel #9
0
int test_01()
{
	FILE* log = stdout;
	int frame_size = 10;
	int data_size = (int)1e6;
	int* data_in = (int*)calloc(data_size, sizeof(int));
	int* data_out = NULL;

	int times = 100;
	int i = 0;

	transmitter_t transmitter = transmitter_create(log, frame_size, data_in, data_size);
	receiver_t receiver = receiver_create(log, frame_size, data_size);

	transmitter->start(transmitter);
	receiver->start(receiver);

L_Loop:
	frame_t frame_in = transmitter->transmit_frame(transmitter);
	if (frame_in == NULL) goto L_Stop;
	
	frame_display(frame_in);

	/* channel emulation */
	frame_t frame_out = frame_create(frame_size);
	frame_out = frame_cpy(frame_out, frame_in);
	frame_display(frame_out);

	receiver->receive_frame(receiver, frame_out, frame_in);
	goto L_Loop;

L_Stop:
	transmitter->stop(transmitter);
	receiver->stop(receiver);

	data_out = receiver_get_received_data(receiver);

	if (cmp_data(data_in, data_out, data_size))
		printf("test: OK\n");
	else
		printf("test: FAIL\n");

	//print_data(data_in, data_size);
	//print_data(data_out, data_size);

	free(data_in);

	receiver_destroy(receiver);
	transmitter_destroy(transmitter);
	return 0;
}
Beispiel #10
0
errval_t memserv_alloc(struct capref *ret, uint8_t bits, genpaddr_t minbase,
                       genpaddr_t maxlimit)
{
    errval_t err;

    assert(bits >= MINSIZEBITS);

    /* refill slot allocator if needed */
    err = slot_prealloc_refill(mm_ram.slot_alloc_inst);
    assert(err_is_ok(err));

    /* refill slab allocator if needed */
    size_t freecount = slab_freecount(&mm_ram.slabs);
    while (!refilling && (freecount <= MINSPARENODES)) {
        refilling = true;
        struct capref frame;
        err = msa.a.alloc(&msa.a, &frame);
        assert(err_is_ok(err));
        size_t retsize;
        err = frame_create(frame, BASE_PAGE_SIZE * 8, &retsize);
        assert(err_is_ok(err));
        assert(retsize % BASE_PAGE_SIZE == 0);
        assert(retsize >= BASE_PAGE_SIZE);
        void *buf;
        err = paging_map_frame(get_current_paging_state(), &buf, retsize, frame, NULL, NULL);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "paging_map_frame failed");
            assert(buf);
        }
        slab_grow(&mm_ram.slabs, buf, retsize);
        freecount = slab_freecount(&mm_ram.slabs);
    }
    if (freecount > MINSPARENODES) {
        refilling = false;
    }

    if(maxlimit == 0) {
        err = mm_alloc(&mm_ram, bits, ret, NULL);
    } else {
        err = mm_alloc_range(&mm_ram, bits, minbase, maxlimit, ret, NULL);
    }

    if (err_is_fail(err)) {
        debug_printf("in mem_serv:mymm_alloc(bits=%"PRIu8", minbase=%"PRIxGENPADDR
                     ", maxlimit=%"PRIxGENPADDR")\n", bits, minbase, maxlimit);
        DEBUG_ERR(err, "mem_serv:mymm_alloc");
    }

    return err;
}
Beispiel #11
0
/* create various resources like shrapnells */
void client_game_create()
{
	frame_create();
	shrapnells_init();
	shine_load();
	init_angles();

	/* background */
	bkgnd = stk_surface_create( SDL_SWSURFACE, 
			stk_display->w, stk_display->h );
	SDL_SetColorKey( bkgnd, 0, 0 );
	stk_surface_fill( bkgnd, 0,0,-1,-1, 0x0 );

}
Beispiel #12
0
static struct ModeInfo *
create_wscreensaver_instance(struct wscreensaver *screensaver,
			     struct wl_output *output, int width, int height)
{
	static int instance;
	struct ModeInfo *mi;
	struct rectangle drawarea;

	mi = calloc(1, sizeof *mi);
	if (!mi)
		return NULL;

	if (demo_mode)
		mi->window = window_create(screensaver->display);
	else
		mi->window = window_create_custom(screensaver->display);

	if (!mi->window) {
		fprintf(stderr, "%s: creating a window failed.\n", progname);
		free(mi);
		return NULL;
	}

	window_set_title(mi->window, progname);

	if (screensaver->interface && !demo_mode) {
		mi->widget = window_add_widget(mi->window, mi);
		screensaver_set_surface(screensaver->interface,
					window_get_wl_surface(mi->window),
					output);
	} else {
		mi->widget = frame_create(mi->window, mi);
	}
	widget_set_redraw_handler(mi->widget, redraw_handler);

	mi->priv = screensaver;
	mi->eglctx = EGL_NO_CONTEXT;
	mi->instance_number = instance++; /* XXX */

	widget_get_allocation(mi->widget, &drawarea);
	mi->width = drawarea.width;
	mi->height = drawarea.height;

	screensaver->plugin->init(mi);

	window_schedule_resize(mi->window, width, height);
	return mi;
}
Beispiel #13
0
static struct demoapp *
demoapp_create(struct display *display)
{
	struct demoapp *app;

	app = calloc(1, sizeof *app);
	if (!app)
		return NULL;

	app->egl = egl_state_create(display_get_display(display));

	app->display = display;
	display_set_user_data(app->display, app);

	app->window = window_create(app->display);
	app->widget = frame_create(app->window, app);
	window_set_title(app->window, "Wayland Sub-surface Demo");

	window_set_key_handler(app->window, key_handler);
	window_set_user_data(app->window, app);
	window_set_keyboard_focus_handler(app->window, keyboard_focus_handler);

	widget_set_redraw_handler(app->widget, redraw_handler);
	widget_set_resize_handler(app->widget, resize_handler);

	app->subsurface = window_add_subsurface(app->window, app,
		int_to_mode(option_red_mode));
	widget_set_redraw_handler(app->subsurface, sub_redraw_handler);
	widget_set_resize_handler(app->subsurface, sub_resize_handler);

	if (app->egl && !option_no_triangle)
		app->triangle = triangle_create(app->window, app->egl);

	/* minimum size */
	widget_schedule_resize(app->widget, 100, 100);

	/* initial size */
	widget_schedule_resize(app->widget, 400, 300);

	app->animate = 1;

	return app;
}
enum ia_css_err ia_css_frame_create_from_info(struct ia_css_frame **frame,
	const struct ia_css_frame_info *info)
{
	enum ia_css_err err = IA_CSS_SUCCESS;
	struct ia_css_frame *me;
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
		"ia_css_frame_create_from_info() enter:\n");
	if (frame == NULL || info == NULL) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
			"ia_css_frame_create_from_info() leave:"
			" invalid arguments\n");
		return IA_CSS_ERR_INVALID_ARGUMENTS;
	}

	me = frame_create(info->res.width,
		info->res.height,
		info->format,
		info->padded_width,
		info->raw_bit_depth,
		false,
		false);
	if (me == NULL) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
			"ia_css_frame_create_from_info() leave:"
			" frame create failed\n");
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	}

	err = ia_css_frame_init_planes(me);

	if (err == IA_CSS_SUCCESS)
		*frame = me;
	else
		sh_css_free(me);

	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_frame_create_from_info() leave:\n");

	return err;
}
Beispiel #15
0
int
main(int argc, char *argv[])
{
	struct editor editor;

	memset(&editor, 0, sizeof editor);

	editor.display = display_create(argc, argv);
	if (editor.display == NULL) {
		fprintf(stderr, "failed to create display: %m\n");
		return -1;
	}

	display_set_user_data(editor.display, &editor);
	display_set_global_handler(editor.display, global_handler);

	editor.window = window_create(editor.display);
	editor.widget = frame_create(editor.window, &editor);

	editor.entry = text_entry_create(&editor, "Entry");
	editor.editor = text_entry_create(&editor, "Editor");

	window_set_title(editor.window, "Text Editor");
	window_set_key_handler(editor.window, key_handler);
	window_set_user_data(editor.window, &editor);

	widget_set_redraw_handler(editor.widget, redraw_handler);
	widget_set_resize_handler(editor.widget, resize_handler);
	widget_set_button_handler(editor.widget, editor_button_handler);

	window_schedule_resize(editor.window, 500, 400);

	display_run(editor.display);

	text_entry_destroy(editor.entry);
	text_entry_destroy(editor.editor);

	return 0;
}
Beispiel #16
0
/**
 * \brief Create mappings
 *
 * \param state     The object metadata
 * \param frame     An empty slot to place the frame capability in
 * \param req_size  The required amount by the application
 * \param retbuf    Pointer to return the mapped buffer
 * \param retsize   The actual size returned
 *
 * This function will returns a special error code if frame_create
 * fails due to the constrains to the memory server (amount of memory
 * or region of memory). This is to facilitate retrying with different
 * constraints.
 */
errval_t vspace_mmu_aware_map(struct vspace_mmu_aware *state, size_t req_size,
                              void **retbuf, size_t *retsize)
{
    errval_t err;

    struct capref frame;

    // Calculate how much still to map in
    size_t origsize = req_size;
    assert(state->mapoffset >= state->offset);
    if(state->mapoffset - state->offset > req_size) {
        req_size = 0;
    } else {
        req_size -= state->mapoffset - state->offset;
    }
    size_t alloc_size = ROUND_UP(req_size, BASE_PAGE_SIZE);
    size_t ret_size = 0;

    if (req_size > 0) {
#if __x86_64__
        if ((state->vregion.flags & VREGION_FLAGS_HUGE) &&
            (state->mapoffset & HUGE_PAGE_MASK) == 0)
        {
            // this is an opportunity to switch to 1G pages if requested.
            // we know that we can use large pages without jumping through hoops
            // if state->vregion.flags has VREGION_FLAGS_HUGE set and
            // mapoffset is aligned to at least HUGE_PAGE_SIZE.
            alloc_size = ROUND_UP(req_size, HUGE_PAGE_SIZE);

            // goto allocation directly so we can avoid nasty code interaction
            // between #if __x86_64__ and the size checks, we want to be able
            // to use 2M pages on x86_64 also. -SG, 2015-04-30.
            goto allocate;
        }
#endif
        if ((state->vregion.flags & VREGION_FLAGS_LARGE) &&
            (state->mapoffset & LARGE_PAGE_MASK) == 0)
        {
            // this is an opportunity to switch to 2M pages if requested.
            // we know that we can use large pages without jumping through hoops
            // if state->vregion.flags has VREGION_FLAGS_LARGE set and
            // mapoffset is aligned to at least LARGE_PAGE_SIZE.
            alloc_size = ROUND_UP(req_size, LARGE_PAGE_SIZE);
        }
        // Create frame of appropriate size
allocate:
        err = state->slot_alloc->alloc(state->slot_alloc, &frame);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_SLOT_ALLOC_NO_SPACE);
        }

        err = frame_create(frame, alloc_size, &ret_size);
        if (err_is_fail(err)) {
            if (err_no(err) == LIB_ERR_RAM_ALLOC_MS_CONSTRAINTS) {
                // we can only get 4k frames for now; retry with 4k
                if (alloc_size > BASE_PAGE_SIZE && req_size <= BASE_PAGE_SIZE) {
                    alloc_size = BASE_PAGE_SIZE;
                    goto allocate;
                }
                return err_push(err, LIB_ERR_FRAME_CREATE_MS_CONSTRAINTS);
            }
            return err_push(err, LIB_ERR_FRAME_CREATE);
        }
        assert(ret_size >= req_size);
        origsize += ret_size - req_size;
        req_size = ret_size;

        if (state->consumed + req_size > state->size) {
            err = cap_delete(frame);
            if (err_is_fail(err)) {
                debug_err(__FILE__, __func__, __LINE__, err,
                          "cap_delete failed");
            }
            state->slot_alloc->free(state->slot_alloc, frame);
            return LIB_ERR_VSPACE_MMU_AWARE_NO_SPACE;
        }

        // Map it in
        err = state->memobj.m.f.fill(&state->memobj.m, state->mapoffset, frame,
                                     req_size);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_MEMOBJ_FILL);
        }
        err = state->memobj.m.f.pagefault(&state->memobj.m, &state->vregion,
                                          state->mapoffset, 0);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
        }
    }

    // Return buffer
    genvaddr_t gvaddr = vregion_get_base_addr(&state->vregion) + state->offset;
    *retbuf = (void*)vspace_genvaddr_to_lvaddr(gvaddr);
    *retsize = origsize;
    state->mapoffset += req_size;
    state->offset += origsize;
    state->consumed += origsize;

    return SYS_ERR_OK;
}
Beispiel #17
0
static errval_t elf_allocate(void *state, genvaddr_t base, size_t size,
                             uint32_t flags, void **retbase)
{
    errval_t err;

    struct spawninfo *si = state;

    // Increase size by space wasted on first page due to page-alignment
    size_t base_offset = BASE_PAGE_OFFSET(base);
    size += base_offset;
    base -= base_offset;
    // Page-align
    size = ROUND_UP(size, BASE_PAGE_SIZE);

    cslot_t vspace_slot = si->elfload_slot;

    // Allocate the frames
    size_t sz = 0;
    for (lpaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = si->elfload_slot++,
        };
        err = frame_create(frame, sz, NULL);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_FRAME_CREATE);
        }
    }

    cslot_t spawn_vspace_slot = si->elfload_slot;
    cslot_t new_slot_count = si->elfload_slot - vspace_slot;

    // create copies of the frame capabilities for spawn vspace
    for (int copy_idx = 0; copy_idx < new_slot_count; copy_idx++) {
        struct capref frame = {
            .cnode = si->segcn,
            .slot = vspace_slot + copy_idx,
        };
        struct capref spawn_frame = {
            .cnode = si->segcn,
            .slot = si->elfload_slot++,
        };
        err = cap_copy(spawn_frame, frame);
        if (err_is_fail(err)) {
            // TODO: make debug printf
            printf("cap_copy failed for src_slot = %"PRIuCSLOT", dest_slot = %"PRIuCSLOT"\n", frame.slot, spawn_frame.slot);
            return err_push(err, LIB_ERR_CAP_COPY);
        }
    }

    /* Map into my vspace */
    struct memobj *memobj = malloc(sizeof(struct memobj_anon));
    if (!memobj) {
        return LIB_ERR_MALLOC_FAIL;
    }
    struct vregion *vregion = malloc(sizeof(struct vregion));
    if (!vregion) {
        return LIB_ERR_MALLOC_FAIL;
    }
    // Create the objects
    err = memobj_create_anon((struct memobj_anon*)memobj, size, 0);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_MEMOBJ_CREATE_ANON);
    }
    err = vregion_map(vregion, get_current_vspace(), memobj, 0, size,
                      VREGION_FLAGS_READ_WRITE);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_VSPACE_MAP);
    }
    for (lvaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = vspace_slot++,
        };
        genvaddr_t genvaddr = vspace_lvaddr_to_genvaddr(offset);
        err = memobj->f.fill(memobj, genvaddr, frame, sz);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_MEMOBJ_FILL);
        }
        err = memobj->f.pagefault(memobj, vregion, offset, 0);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "lib_err_memobj_pagefault_handler");
            return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
        }
    }

    /* Map into spawn vspace */
    struct memobj *spawn_memobj = NULL;
    struct vregion *spawn_vregion = NULL;
    err = spawn_vspace_map_anon_fixed_attr(si, base, size, &spawn_vregion,
                                           &spawn_memobj,
                                           elf_to_vregion_flags(flags));
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_VSPACE_MAP);
    }
    for (lvaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = spawn_vspace_slot++,
        };
        genvaddr_t genvaddr = vspace_lvaddr_to_genvaddr(offset);
        err = memobj->f.fill(spawn_memobj, genvaddr, frame, sz);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_MEMOBJ_FILL);
        }
        err = spawn_memobj->f.pagefault(spawn_memobj, spawn_vregion, offset, 0);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "lib_err_memobj_pagefault_handler");
            return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
        }
    }

    genvaddr_t genvaddr = vregion_get_base_addr(vregion) + base_offset;
    *retbase = (void*)vspace_genvaddr_to_lvaddr(genvaddr);
    return SYS_ERR_OK;
}

/**
 * \brief Load the elf image
 */
errval_t spawn_arch_load(struct spawninfo *si,
                         lvaddr_t binary, size_t binary_size,
                         genvaddr_t *entry, void** arch_info)
{
    errval_t err;

    // Reset the elfloader_slot
    si->elfload_slot = 0;
    struct capref cnode_cap = {
        .cnode = si->rootcn,
        .slot  = ROOTCN_SLOT_SEGCN,
    };
    err = cnode_create_raw(cnode_cap, &si->segcn, DEFAULT_CNODE_SLOTS, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_SEGCN);
    }

    // TLS is NYI
    si->tls_init_base = 0;
    si->tls_init_len = si->tls_total_len = 0;

    // Load the binary
    err = elf_load(EM_HOST, elf_allocate, si, binary, binary_size, entry);
    if (err_is_fail(err)) {
        return err;
    }

    struct Elf32_Shdr* got_shdr =
        elf32_find_section_header_name(binary, binary_size, ".got");
    if (got_shdr)
    {
        *arch_info = (void*)got_shdr->sh_addr;
    }
    else {
        return SPAWN_ERR_LOAD;
    }

    return SYS_ERR_OK;
}

void spawn_arch_set_registers(void *arch_load_info,
                              dispatcher_handle_t handle,
                              arch_registers_state_t *enabled_area,
                              arch_registers_state_t *disabled_area)
{
    assert(arch_load_info != NULL);
    uintptr_t got_base = (uintptr_t)arch_load_info;

    struct dispatcher_shared_arm* disp_arm = get_dispatcher_shared_arm(handle);
    disp_arm->got_base = got_base;

    enabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
    disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;

#ifndef __ARM_ARCH_7M__ //armv7-m does not support these flags
    enabled_area->named.cpsr = CPSR_F_MASK | ARM_MODE_USR;
    disabled_area->named.cpsr = CPSR_F_MASK | ARM_MODE_USR;
#endif
}
Beispiel #18
0
static errval_t elf_allocate(void *state, genvaddr_t base, size_t size,
                             uint32_t flags, void **retbase)
{
    errval_t err;
    lvaddr_t vaddr;
    size_t used_size;

    struct spawninfo *si = state;

    // Increase size by space wasted on first page due to page-alignment
    size_t base_offset = BASE_PAGE_OFFSET(base);
    size += base_offset;
    base -= base_offset;
    // Page-align
    size = ROUND_UP(size, BASE_PAGE_SIZE);

    cslot_t vspace_slot = si->elfload_slot;

    // Step 1: Allocate the frames
    size_t sz = 0;
    for (lpaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = si->elfload_slot++,
        };
        err = frame_create(frame, sz, NULL);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_FRAME_CREATE);
        }
    }

    cslot_t spawn_vspace_slot = si->elfload_slot;
    cslot_t new_slot_count = si->elfload_slot - vspace_slot;

    // Step 2: create copies of the frame capabilities for child vspace
    for (int copy_idx = 0; copy_idx < new_slot_count; copy_idx++) {
        struct capref frame = {
            .cnode = si->segcn,
            .slot = vspace_slot + copy_idx,
        };

        struct capref spawn_frame = {
            .cnode = si->segcn,
            .slot = si->elfload_slot++,
        };
        err = cap_copy(spawn_frame, frame);
        if (err_is_fail(err)) {
            debug_printf("cap_copy failed for src_slot = %"PRIuCSLOT
                    ", dest_slot = %"PRIuCSLOT"\n", frame.slot,
                    spawn_frame.slot);
            return err_push(err, LIB_ERR_CAP_COPY);
        }
    }

    // Step 3: map into own vspace

    // Get virtual address range to hold the module
    void *vaddr_range;
    err = paging_alloc(get_current_paging_state(), &vaddr_range, size);
    if (err_is_fail(err)) {
        debug_printf("elf_allocate: paging_alloc failed\n");
        return (err);
    }

    // map allocated physical memory in virutal memory of parent process
    vaddr = (lvaddr_t)vaddr_range;
    used_size = size;

    while (used_size > 0) {
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = vspace_slot++,
        };       // find out the size of the frame

        struct frame_identity id;
        err = invoke_frame_identify(frame, &id);
        assert(err_is_ok(err));
        size_t slot_size = (1UL << id.bits);

        // map frame to provide physical memory backing
        err = paging_map_fixed_attr(get_current_paging_state(), vaddr, frame, slot_size,
                VREGION_FLAGS_READ_WRITE);

        if (err_is_fail(err)) {
            debug_printf("elf_allocate: paging_map_fixed_attr failed\n");
            return err;
        }

        used_size -= slot_size;
        vaddr +=  slot_size;
    } // end while:


    // Step 3: map into new process
    struct paging_state *cp = si->vspace;

    // map allocated physical memory in virutal memory of child process
    vaddr = (lvaddr_t)base;
    used_size = size;

    while (used_size > 0) {
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = spawn_vspace_slot++,
        };

        // find out the size of the frame
        struct frame_identity id;
        err = invoke_frame_identify(frame, &id);
        assert(err_is_ok(err));
        size_t slot_size = (1UL << id.bits);

        // map frame to provide physical memory backing
        err = paging_map_fixed_attr(cp, vaddr, frame, slot_size,
                elf_to_vregion_flags(flags));

        if (err_is_fail(err)) {
            debug_printf("elf_allocate: paging_map_fixed_attr failed\n");
            return err;
        }

        used_size -= slot_size;
        vaddr +=  slot_size;
    } // end while:

    *retbase = (void*) vaddr_range + base_offset;

    return SYS_ERR_OK;
} // end function: elf_allocate

/**
 * \brief Load the elf image
 */
errval_t spawn_arch_load(struct spawninfo *si,
                         lvaddr_t binary, size_t binary_size,
                         genvaddr_t *entry, void** arch_info)
{
    errval_t err;

    // Reset the elfloader_slot
    si->elfload_slot = 0;
    struct capref cnode_cap = {
        .cnode = si->rootcn,
        .slot  = ROOTCN_SLOT_SEGCN,
    };
    err = cnode_create_raw(cnode_cap, &si->segcn, DEFAULT_CNODE_SLOTS, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_SEGCN);
    }

    // TLS is NYI
    si->tls_init_base = 0;
    si->tls_init_len = si->tls_total_len = 0;

    //debug_printf("spawn_arch_load: about to load elf %p\n", elf_allocate);
    // Load the binary
    err = elf_load(EM_HOST, elf_allocate, si, binary, binary_size, entry);
    if (err_is_fail(err)) {
        return err;
    }

    //debug_printf("hello here\n");
    struct Elf32_Shdr* got_shdr =
        elf32_find_section_header_name(binary, binary_size, ".got");
    if (got_shdr)
    {
        *arch_info = (void*)got_shdr->sh_addr;
    }
    else {
        return SPAWN_ERR_LOAD;
    }

    return SYS_ERR_OK;
}

void spawn_arch_set_registers(void *arch_load_info,
                              dispatcher_handle_t handle,
                              arch_registers_state_t *enabled_area,
                              arch_registers_state_t *disabled_area)
{
    assert(arch_load_info != NULL);
    uintptr_t got_base = (uintptr_t)arch_load_info;

    struct dispatcher_shared_arm* disp_arm = get_dispatcher_shared_arm(handle);
    disp_arm->got_base = got_base;

    enabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
    enabled_area->named.cpsr = CPSR_F_MASK | ARM_MODE_USR;

    disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
    disabled_area->named.cpsr = CPSR_F_MASK | ARM_MODE_USR;
}
Beispiel #19
0
int main( int argc, char *argv[] ){
	int ret = 0;
	signed char option;
	int i = 0;
	int lastopt = 0;
	bool interactive = false;
	bool load_libs = true;
	bool set_a_gc_profile = false;
	unsigned new_gc_profile = 0;

	stack_frame_t *global_frame;

	if ( argc < 2 ){
		// By default, go into an REPL
		interactive = true;

	} else {
		// otherwise parse options
		lastopt = 1;

		for ( i = 1; i < argc && argv[i][0] == '-'; i++ ){
			option = argv[i][1];

			switch ( option ){
				case 'i':
					interactive = true;
					break;

				case 'h':
					print_help( );
					exit( 0 );
					break;

				case 'L':
					load_libs = false;
					break;

				case 'g':
					{
						char *profile = argv[++i];

						set_a_gc_profile = true;

						if ( strcmp( profile, "fast" ) == 0 ){
							new_gc_profile = GC_PROFILE_FAST;

						} else if ( strcmp( profile, "balanced" ) == 0 ){
							new_gc_profile = GC_PROFILE_BALANCED;

						} else if ( strcmp( profile, "lowmem" ) == 0 ){
							new_gc_profile = GC_PROFILE_LOWMEM;

						} else {
							printf( "Unknown garbage collector profile \"%s\", "
							        "using \"balanced\" instead...\n", profile );

							new_gc_profile = GC_PROFILE_BALANCED;
						}
					}

				case 'v':
					break;

				default:
					print_help( );
					exit( 1 );
					break;
			}

			/* This keeps track of where the argument after the current argument is,
			   in order to find the filenames after option parsing is done.          */
			lastopt = i + 1;
		}
	}

	// print some info about the interpreter going into a REPL
	if ( interactive ){
		printf( "%s\n", GOJIRA_BUILD_NAME );
	}

	// Initialize the global interpreter state
	global_frame = frame_create( NULL, NULL, MAKE_ENV );
	init_global_frame( global_frame );

	if ( set_a_gc_profile ){
		gc_set_profile( get_current_gc( global_frame ), new_gc_profile );
	}

	// Load the 'base' library for needed primatives
	if ( load_libs ){
		evaluate_file( global_frame, BASE_LIB );
	}

	make_argument_var( global_frame, lastopt, argc, argv );

	if ( lastopt ){
		evaluate_file( global_frame, argv[lastopt] );
	}

	// Go into the REPL if the interpreter flag is set
	if ( interactive ){
		read_eval_print( global_frame );
	}

	// Clean up the global frame, and free all tokens left in the token cache
	gc_collect( get_current_gc( global_frame ));
	destroy_token_cache( );

	return ret;
} 
Beispiel #20
0
void _DbgNewFrame(int l, const char* name)
{
	// Create a new frame and add it as an element on the frames' list
	frames=linked_list_element_push_front(frames, frame_create(l, name));
}
Beispiel #21
0
/**
 * \brief Setup arguments and environment
 *
 * \param argv   Command-line arguments, NULL-terminated
 * \param envp   Environment, NULL-terminated
 */
static errval_t spawn_setup_env(struct spawninfo *si,
                                char *const argv[], char *const envp[])
{
    errval_t err;

    // Create frame (actually multiple pages) for arguments
    si->argspg.cnode = si->taskcn;
    si->argspg.slot  = TASKCN_SLOT_ARGSPAGE;
    struct capref spawn_argspg = {
        .cnode = si->taskcn,
        .slot  = TASKCN_SLOT_ARGSPAGE2,
    };
    err = frame_create(si->argspg, ARGS_SIZE, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_ARGSPG);
    }
    err = cap_copy(spawn_argspg, si->argspg);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_ARGSPG);
    }

    /* Map in args frame */
    genvaddr_t spawn_args_base;
    err = spawn_vspace_map_one_frame(si, &spawn_args_base, spawn_argspg, ARGS_SIZE);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_ARGSPG_TO_NEW);
    }

    void *argspg;
    err = vspace_map_one_frame(&argspg, ARGS_SIZE, si->argspg, NULL, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_ARGSPG_TO_SELF);
    }

    /* Layout of arguments page:
     *   struct spawn_domain_params; // contains pointers to other fields
     *   char buf[]; // NUL-terminated strings for arguments and environment
     *   vspace layout data follows the string data
     */
    struct spawn_domain_params *params = argspg;
    char *buf = (char *)(params + 1);
    size_t buflen = ARGS_SIZE - (buf - (char *)argspg);

    /* Copy command-line arguments */
    int i;
    size_t len;
    for (i = 0; argv[i] != NULL; i++) {
        len = strlen(argv[i]) + 1;
        if (len > buflen) {
            return SPAWN_ERR_ARGSPG_OVERFLOW;
        }
        strcpy(buf, argv[i]);
        params->argv[i] = buf - (char *)argspg + (char *)(lvaddr_t)spawn_args_base;
        buf += len;
        buflen -= len;
    }
    assert(i <= MAX_CMDLINE_ARGS);
    int argc = i;
    params->argv[i] = NULL;

    /* Copy environment strings */
    for (i = 0; envp[i] != NULL; i++) {
        len = strlen(envp[i]) + 1;
        if (len > buflen) {
            return SPAWN_ERR_ARGSPG_OVERFLOW;
        }
        strcpy(buf, envp[i]);
        params->envp[i] = buf - (char *)argspg + (char *)(lvaddr_t)spawn_args_base;
        buf += len;
        buflen -= len;
    }

    assert(i <= MAX_ENVIRON_VARS);
    params->envp[i] = NULL;

    /* Serialise vspace data */
    // XXX: align buf to next word
    char *vspace_buf = (char *)ROUND_UP((lvaddr_t)buf, sizeof(uintptr_t));
    buflen -= vspace_buf - buf;

    // FIXME: currently just the pmap is serialised
    err = si->vspace->pmap->f.serialise(si->vspace->pmap, vspace_buf, buflen);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_SERIALISE_VSPACE);
    }

    /* Setup environment pointer and vspace pointer */
    params->argc = argc;
    params->vspace_buf = (char *)vspace_buf - (char *)argspg
                    + (char *)(lvaddr_t)spawn_args_base;
    params->vspace_buf_len = buflen;

    // Setup TLS data
    params->tls_init_base = (void *)vspace_genvaddr_to_lvaddr(si->tls_init_base);
    params->tls_init_len = si->tls_init_len;
    params->tls_total_len = si->tls_total_len;

    arch_registers_state_t *enabled_area =
        dispatcher_get_enabled_save_area(si->handle);
    registers_set_param(enabled_area, (uintptr_t)spawn_args_base);

    return SYS_ERR_OK;
}

/**
 * Copies caps from inheritcnode into destination cnode,
 * ignores caps that to not exist.
 *
 * \param  inheritcn    Source cnode
 * \param  inherit_slot Source cnode slot
 * \param  destcn       Target cnode
 * \param  destcn_slot  Target cnode slot
 *
 * \retval SYS_ERR_OK Copy to target was successful or source cap
 * did not exist.
 * \retval SPAWN_ERR_COPY_INHERITCN_CAP Error in cap_copy
 */
static errval_t spawn_setup_inherited_cap(struct cnoderef inheritcn,
                                          capaddr_t inherit_slot,
                                          struct cnoderef destcn,
                                          capaddr_t destcn_slot)
{
    errval_t err;

    struct capref src;
    src.cnode = inheritcn;
    src.slot  = inherit_slot;;

    // Create frame (actually multiple pages) for fds
    struct capref dest;
    dest.cnode = destcn;
    dest.slot  = destcn_slot;

    err = cap_copy(dest, src);
    if (err_no(err) == SYS_ERR_SOURCE_CAP_LOOKUP) {
        // there was no fdcap to inherit, continue
        return SYS_ERR_OK;
    } else if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_COPY_INHERITCN_CAP);
    }

    return SYS_ERR_OK;
}
Beispiel #22
0
/**
 * \brief Setup the dispatcher frame
 */
static errval_t spawn_setup_dispatcher(struct spawninfo *si,
                                       coreid_t core_id,
                                       const char *name,
                                       genvaddr_t entry,
                                       void* arch_info)
{
    errval_t err;

    /* Create dispatcher frame (in taskcn) */
    si->dispframe.cnode = si->taskcn;
    si->dispframe.slot  = TASKCN_SLOT_DISPFRAME;
    struct capref spawn_dispframe = {
        .cnode = si->taskcn,
        .slot  = TASKCN_SLOT_DISPFRAME2,
    };
    err = frame_create(si->dispframe, (1 << DISPATCHER_FRAME_BITS), NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_DISPATCHER_FRAME);
    }
    err = cap_copy(spawn_dispframe, si->dispframe);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_DISPATCHER_FRAME);
    }

    /* Map in dispatcher frame */
    dispatcher_handle_t handle;
    err = vspace_map_one_frame((void**)&handle, 1ul << DISPATCHER_FRAME_BITS,
                               si->dispframe, NULL, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_DISPATCHER_TO_SELF);
    }
    genvaddr_t spawn_dispatcher_base;
    err = spawn_vspace_map_one_frame(si, &spawn_dispatcher_base, spawn_dispframe,
                                     1UL << DISPATCHER_FRAME_BITS);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_DISPATCHER_TO_NEW);
    }

    /* Set initial state */
    // XXX: Confusion address translation about l/gen/addr in entry
    struct dispatcher_shared_generic *disp =
        get_dispatcher_shared_generic(handle);
    struct dispatcher_generic *disp_gen = get_dispatcher_generic(handle);
    arch_registers_state_t *enabled_area =
        dispatcher_get_enabled_save_area(handle);
    arch_registers_state_t *disabled_area =
        dispatcher_get_disabled_save_area(handle);

    /* Place core_id */
    disp_gen->core_id = core_id;

    /* place eh information */
    disp_gen->eh_frame = si->eh_frame;
    disp_gen->eh_frame_size = si->eh_frame_size;
    disp_gen->eh_frame_hdr = si->eh_frame_hdr;
    disp_gen->eh_frame_hdr_size = si->eh_frame_hdr_size;

    /* Setup dispatcher and make it runnable */
    disp->udisp = spawn_dispatcher_base;
    disp->disabled = 1;
    disp->fpu_trap = 1;
#ifdef __k1om__
    disp->xeon_phi_id = disp_xeon_phi_id();
#endif

    // Copy the name for debugging
    const char *copy_name = strrchr(name, '/');
    if (copy_name == NULL) {
        copy_name = name;
    } else {
        copy_name++;
    }
    strncpy(disp->name, copy_name, DISP_NAME_LEN);

    spawn_arch_set_registers(arch_info, handle, enabled_area, disabled_area);
    registers_set_entry(disabled_area, entry);

    si->handle = handle;
    return SYS_ERR_OK;
}

errval_t spawn_map_bootinfo(struct spawninfo *si, genvaddr_t *retvaddr)
{
    errval_t err;

    struct capref src = {
        .cnode = cnode_task,
        .slot  = TASKCN_SLOT_BOOTINFO
    };
    struct capref dest = {
        .cnode = si->taskcn,
        .slot  = TASKCN_SLOT_BOOTINFO
    };
    err = cap_copy(dest, src);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_CAP_COPY);
    }

    err = spawn_vspace_map_one_frame(si, retvaddr, dest, BOOTINFO_SIZE);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_BOOTINFO);
    }

    return SYS_ERR_OK;
}

/**
 * \brief Retrive the commandline args of #name
 *
 * The arguments are malloced into a new space so need to be freed after use
 */
errval_t spawn_get_cmdline_args(struct mem_region *module,
                                char **retargs)
{
    assert(module != NULL && retargs != NULL);

    /* Get the cmdline args */
    const char *args = getopt_module(module);

    /* Allocate space */
    *retargs = malloc(sizeof(char) * strlen(args));
    if (!retargs) {
        return LIB_ERR_MALLOC_FAIL;
    }

    /* Copy args */
    strcpy(*retargs, args);
    return SYS_ERR_OK;
}
Beispiel #23
0
int
main(int argc, char *argv[])
{
	struct editor editor;
	int i;
	uint32_t click_to_show = 0;
	const char *preferred_language = NULL;

	for (i = 1; i < argc; i++) {
		if (strcmp("--click-to-show", argv[i]) == 0)
			click_to_show = 1;
		else if (strcmp("--preferred-language", argv[i]) == 0) {
			if (i + 1 < argc) {
				preferred_language = argv[i + 1];
				i++;
			}
		}
	}

	memset(&editor, 0, sizeof editor);

#ifdef HAVE_PANGO
	g_type_init();
#endif

	editor.display = display_create(&argc, argv);
	if (editor.display == NULL) {
		fprintf(stderr, "failed to create display: %m\n");
		return -1;
	}

	display_set_user_data(editor.display, &editor);
	display_set_global_handler(editor.display, global_handler);

	editor.window = window_create(editor.display);
	editor.widget = frame_create(editor.window, &editor);

	editor.entry = text_entry_create(&editor, "Entry");
	editor.entry->click_to_show = click_to_show;
	if (preferred_language)
		editor.entry->preferred_language = strdup(preferred_language);
	editor.editor = text_entry_create(&editor, "Numeric");
	editor.editor->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER;
	editor.editor->click_to_show = click_to_show;

	window_set_title(editor.window, "Text Editor");
	window_set_key_handler(editor.window, key_handler);
	window_set_user_data(editor.window, &editor);

	widget_set_redraw_handler(editor.widget, redraw_handler);
	widget_set_resize_handler(editor.widget, resize_handler);
	widget_set_button_handler(editor.widget, editor_button_handler);

	window_schedule_resize(editor.window, 500, 400);

	display_run(editor.display);

	text_entry_destroy(editor.entry);
	text_entry_destroy(editor.editor);

	return 0;
}
Beispiel #24
0
static struct gears *
gears_create(struct display *display)
{
	const int width = 450, height = 500;
	struct gears *gears;
	int i;

	gears = malloc(sizeof *gears);
	memset(gears, 0, sizeof *gears);
	gears->d = display;
	gears->window = window_create(display);
	gears->widget = frame_create(gears->window, gears);
	window_set_title(gears->window, "Wayland Gears");

	gears->display = display_get_egl_display(gears->d);
	if (gears->display == NULL)
		die("failed to create egl display\n");

	eglBindAPI(EGL_OPENGL_API);

	gears->config = display_get_argb_egl_config(gears->d);

	gears->context = eglCreateContext(gears->display, gears->config,
					  EGL_NO_CONTEXT, NULL);
	if (gears->context == NULL)
		die("failed to create context\n");

	if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context))
		die("failed to make context current\n");

	for (i = 0; i < 3; i++) {
		gears->gear_list[i] = glGenLists(1);
		glNewList(gears->gear_list[i], GL_COMPILE);
		make_gear(&gear_templates[i]);
		glEndList();
	}

	glEnable(GL_NORMALIZE);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 200.0);
	glMatrixMode(GL_MODELVIEW);

	glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
	glEnable(GL_CULL_FACE);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
	glClearColor(0, 0, 0, 0.92);

	window_set_user_data(gears->window, gears);
	widget_set_resize_handler(gears->widget, resize_handler);
	widget_set_redraw_handler(gears->widget, redraw_handler);
	window_set_keyboard_focus_handler(gears->window,
					  keyboard_focus_handler);

	window_schedule_resize(gears->window, width, height);

	return gears;
}
Beispiel #25
0
static errval_t elf_allocate(void *state, genvaddr_t base, size_t size,
                             uint32_t flags, void **retbase)
{
    errval_t err;

    struct spawninfo *si = state;

    // Increase size by space wasted on first page due to page-alignment
    size_t base_offset = BASE_PAGE_OFFSET(base);
    size += base_offset;
    base -= base_offset;
    // Page-align
    size = ROUND_UP(size, BASE_PAGE_SIZE);

    cslot_t vspace_slot = si->elfload_slot;

    // Allocate the frames
    size_t sz = 0;
    for (lpaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = si->elfload_slot++,
        };
        err = frame_create(frame, sz, NULL);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_FRAME_CREATE);
        }
    }

    cslot_t spawn_vspace_slot = si->elfload_slot;
    cslot_t new_slot_count = si->elfload_slot - vspace_slot;

    // create copies of the frame capabilities for spawn vspace
    for (int copy_idx = 0; copy_idx < new_slot_count; copy_idx++) {
        struct capref frame = {
            .cnode = si->segcn,
            .slot = vspace_slot + copy_idx,
        };
        struct capref spawn_frame = {
            .cnode = si->segcn,
            .slot = si->elfload_slot++,
        };
        err = cap_copy(spawn_frame, frame);
        if (err_is_fail(err)) {
            // TODO: make debug printf
            printf("cap_copy failed for src_slot = %"PRIuCSLOT", dest_slot = %"PRIuCSLOT"\n", frame.slot, spawn_frame.slot);
            return err_push(err, LIB_ERR_CAP_COPY);
        }
    }

    /* Map into my vspace */
    struct memobj *memobj = malloc(sizeof(struct memobj_anon));
    if (!memobj) {
        return LIB_ERR_MALLOC_FAIL;
    }
    struct vregion *vregion = malloc(sizeof(struct vregion));
    if (!vregion) {
        return LIB_ERR_MALLOC_FAIL;
    }
    // Create the objects
    err = memobj_create_anon((struct memobj_anon*)memobj, size, 0);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_MEMOBJ_CREATE_ANON);
    }
    err = vregion_map(vregion, get_current_vspace(), memobj, 0, size,
                      VREGION_FLAGS_READ_WRITE);
    if (err_is_fail(err)) {
        return err_push(err, LIB_ERR_VSPACE_MAP);
    }
    for (lvaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref frame = {
            .cnode = si->segcn,
            .slot  = vspace_slot++,
        };
        genvaddr_t genvaddr = vspace_lvaddr_to_genvaddr(offset);
        err = memobj->f.fill(memobj, genvaddr, frame, sz);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_MEMOBJ_FILL);
        }
        err = memobj->f.pagefault(memobj, vregion, offset, 0);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "lib_err_memobj_pagefault_handler");
            return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
        }
    }

    /* Map into spawn vspace */
    struct memobj *spawn_memobj = NULL;
    struct vregion *spawn_vregion = NULL;
    err = spawn_vspace_map_anon_fixed_attr(si, base, size, &spawn_vregion,
                                           &spawn_memobj,
                                           elf_to_vregion_flags(flags));
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_VSPACE_MAP);
    }
    for (lvaddr_t offset = 0; offset < size; offset += sz) {
        sz = 1UL << log2floor(size - offset);
        struct capref spawn_frame = {
            .cnode = si->segcn,
            .slot = spawn_vspace_slot++,
        };
        genvaddr_t genvaddr = vspace_lvaddr_to_genvaddr(offset);
        err = memobj->f.fill(spawn_memobj, genvaddr, spawn_frame, sz);
        if (err_is_fail(err)) {
            return err_push(err, LIB_ERR_MEMOBJ_FILL);
        }
        err = spawn_memobj->f.pagefault(spawn_memobj, spawn_vregion, offset, 0);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "lib_err_memobj_pagefault_handler");
            return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
        }
    }

    si->vregion[si->vregions] = vregion;
    si->base[si->vregions++] = base;

    genvaddr_t genvaddr = vregion_get_base_addr(vregion) + base_offset;
    *retbase = (void*)vspace_genvaddr_to_lvaddr(genvaddr);
    return SYS_ERR_OK;
}

/**
 * \brief Load the elf image
 */
errval_t spawn_arch_load(struct spawninfo *si,
                         lvaddr_t binary, size_t binary_size,
                         genvaddr_t *entry, void** arch_load_info)
{
    errval_t err;

    // Reset the elfloader_slot
    si->elfload_slot = 0;
    si->vregions = 0;

    struct capref cnode_cap = {
        .cnode = si->rootcn,
        .slot  = ROOTCN_SLOT_SEGCN,
    };
    // XXX: this code assumes that elf_load never needs more than 32 slots for 
    // text frame capabilities.
    err = cnode_create_raw(cnode_cap, &si->segcn, DEFAULT_CNODE_SLOTS, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_CREATE_SEGCN);
    }

    // Load the binary
    si->tls_init_base = 0;
    si->tls_init_len = si->tls_total_len = 0;
    err = elf_load_tls(EM_HOST, elf_allocate, si, binary, binary_size, entry,
                       &si->tls_init_base, &si->tls_init_len, &si->tls_total_len);
    if (err_is_fail(err)) {
        return err;
    }

    return SYS_ERR_OK;
}

void spawn_arch_set_registers(void *arch_load_info,
                              dispatcher_handle_t handle,
                              arch_registers_state_t *enabled_area,
                              arch_registers_state_t *disabled_area)
{
#if defined(__x86_64__)
    /* XXX: 1st argument to _start is the dispatcher pointer
     * see lib/crt/arch/x86_64/crt0.s */
    disabled_area->rdi = get_dispatcher_shared_generic(handle)->udisp;
#elif defined(__i386__)
    /* XXX: 1st argument to _start is the dispatcher pointer
     * see lib/crt/arch/x86_32/crt0.s */
    disabled_area->edi = get_dispatcher_shared_generic(handle)->udisp;
#endif
}