[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] stubdom: make use of PVFB resize event
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1208337668 -3600 # Node ID 06242949ff569930bdb13f627fbb54ea13d8af08 # Parent 774e38a40d012d3cc92715237d6932bcf01bbd39 stubdom: make use of PVFB resize event which with the offset support also permits to expose the VGA vram and non-shared vram throught PVFB at the same time, switching between both as appropriate. Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx> --- extras/mini-os/fbfront.c | 98 ++++++++++++++---------- extras/mini-os/include/fbfront.h | 3 extras/mini-os/kernel.c | 15 +++ tools/ioemu/hw/cirrus_vga.c | 4 + tools/ioemu/hw/vga.c | 6 - tools/ioemu/hw/xenfb.c | 153 +++++++++++++++++++++++++++------------ tools/ioemu/vl.h | 1 7 files changed, 186 insertions(+), 94 deletions(-) diff -r 774e38a40d01 -r 06242949ff56 extras/mini-os/fbfront.c --- a/extras/mini-os/fbfront.c Wed Apr 16 10:07:49 2008 +0100 +++ b/extras/mini-os/fbfront.c Wed Apr 16 10:21:08 2008 +0100 @@ -243,12 +243,12 @@ struct fbfront_dev { char *backend; int request_update; - char *data; int width; int height; int depth; - int line_length; + int stride; int mem_length; + int offset; }; void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) @@ -256,7 +256,7 @@ void fbfront_handler(evtchn_port_t port, wake_up(&fbfront_queue); } -struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int height, int depth, int line_length, int mem_length) +struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int width, int height, int depth, int stride, int n) { xenbus_transaction_t xbt; char* err; @@ -289,24 +289,17 @@ struct fbfront_dev *init_fbfront(char *n dev->width = s->width = width; dev->height = s->height = height; dev->depth = s->depth = depth; - dev->line_length = s->line_length = line_length; - dev->mem_length = s->mem_length = mem_length; - - ASSERT(!((unsigned long)data & ~PAGE_MASK)); - dev->data = data; + dev->stride = s->line_length = stride; + dev->mem_length = s->mem_length = n * PAGE_SIZE; + dev->offset = 0; const int max_pd = sizeof(s->pd) / sizeof(s->pd[0]); unsigned long mapped = 0; - for (i = 0; mapped < mem_length && i < max_pd; i++) { + for (i = 0; mapped < n && i < max_pd; i++) { unsigned long *pd = (unsigned long *) alloc_page(); - for (j = 0; mapped < mem_length && j < PAGE_SIZE / sizeof(unsigned long); j++) { - /* Trigger CoW */ - * ((char *)data + mapped) = 0; - barrier(); - pd[j] = virtual_to_mfn((unsigned long) data + mapped); - mapped += PAGE_SIZE; - } + for (j = 0; mapped < n && j < PAGE_SIZE / sizeof(unsigned long); j++) + pd[j] = mfns[mapped++]; for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++) pd[j] = 0; s->pd[i] = virt_to_mfn(pd); @@ -395,31 +388,11 @@ done: return dev; } -void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height) +static void fbfront_out_event(struct fbfront_dev *dev, union xenfb_out_event *event) { struct xenfb_page *page = dev->page; uint32_t prod; DEFINE_WAIT(w); - - if (dev->request_update <= 0) - return; - - if (x < 0) { - width += x; - x = 0; - } - if (x + width > dev->width) - width = dev->width - x; - - if (y < 0) { - height += y; - y = 0; - } - if (y + height > dev->height) - height = dev->height - y; - - if (width <= 0 || height <= 0) - return; add_waiter(w, fbfront_queue); while (page->out_prod - page->out_cons == XENFB_OUT_RING_LEN) @@ -428,14 +401,55 @@ void fbfront_update(struct fbfront_dev * prod = page->out_prod; mb(); /* ensure ring space available */ - XENFB_OUT_RING_REF(page, prod).type = XENFB_TYPE_UPDATE; - XENFB_OUT_RING_REF(page, prod).update.x = x; - XENFB_OUT_RING_REF(page, prod).update.y = y; - XENFB_OUT_RING_REF(page, prod).update.width = width; - XENFB_OUT_RING_REF(page, prod).update.height = height; + XENFB_OUT_RING_REF(page, prod) = *event; wmb(); /* ensure ring contents visible */ page->out_prod = prod + 1; notify_remote_via_evtchn(dev->evtchn); +} + +void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height) +{ + struct xenfb_update update; + + if (dev->request_update <= 0) + return; + + if (x < 0) { + width += x; + x = 0; + } + if (x + width > dev->width) + width = dev->width - x; + + if (y < 0) { + height += y; + y = 0; + } + if (y + height > dev->height) + height = dev->height - y; + + if (width <= 0 || height <= 0) + return; + + update.type = XENFB_TYPE_UPDATE; + update.x = x; + update.y = y; + update.width = width; + update.height = height; + fbfront_out_event(dev, (union xenfb_out_event *) &update); +} + +void fbfront_resize(struct fbfront_dev *dev, int width, int height, int stride, int depth, int offset) +{ + struct xenfb_resize resize; + + resize.type = XENFB_TYPE_RESIZE; + dev->width = resize.width = width; + dev->height = resize.height = height; + dev->stride = resize.stride = stride; + dev->depth = resize.depth = depth; + dev->offset = resize.offset = offset; + fbfront_out_event(dev, (union xenfb_out_event *) &resize); } void shutdown_fbfront(struct fbfront_dev *dev) diff -r 774e38a40d01 -r 06242949ff56 extras/mini-os/include/fbfront.h --- a/extras/mini-os/include/fbfront.h Wed Apr 16 10:07:49 2008 +0100 +++ b/extras/mini-os/include/fbfront.h Wed Apr 16 10:21:08 2008 +0100 @@ -31,11 +31,12 @@ void shutdown_kbdfront(struct kbdfront_d void shutdown_kbdfront(struct kbdfront_dev *dev); -struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int height, int depth, int line_length, int mem_length); +struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int width, int height, int depth, int stride, int n); #ifdef HAVE_LIBC int fbfront_open(struct fbfront_dev *dev); #endif void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height); +void fbfront_resize(struct fbfront_dev *dev, int width, int height, int stride, int depth, int offset); void shutdown_fbfront(struct fbfront_dev *dev); diff -r 774e38a40d01 -r 06242949ff56 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Wed Apr 16 10:07:49 2008 +0100 +++ b/extras/mini-os/kernel.c Wed Apr 16 10:21:08 2008 +0100 @@ -297,9 +297,20 @@ static void fbfront_thread(void *p) { size_t line_length = WIDTH * (DEPTH / 8); size_t memsize = HEIGHT * line_length; - + unsigned long *mfns; + int i, n = (memsize + PAGE_SIZE-1) / PAGE_SIZE; + + memsize = n * PAGE_SIZE; fb = _xmalloc(memsize, PAGE_SIZE); - fb_dev = init_fbfront(NULL, fb, WIDTH, HEIGHT, DEPTH, line_length, memsize); + mfns = xmalloc_array(unsigned long, n); + for (i = 0; i < n; i++) { + /* trigger CoW */ + ((char *) fb) [i * PAGE_SIZE] = 0; + barrier(); + mfns[i] = virtual_to_mfn((char *) fb + i * PAGE_SIZE); + } + fb_dev = init_fbfront(NULL, mfns, WIDTH, HEIGHT, DEPTH, line_length, n); + xfree(mfns); if (!fb_dev) { xfree(fb); return; diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/hw/cirrus_vga.c --- a/tools/ioemu/hw/cirrus_vga.c Wed Apr 16 10:07:49 2008 +0100 +++ b/tools/ioemu/hw/cirrus_vga.c Wed Apr 16 10:21:08 2008 +0100 @@ -2595,6 +2595,10 @@ static void *set_vram_mapping(unsigned l memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE); +#ifdef CONFIG_STUBDOM + xenfb_pv_display_start(vram_pointer); +#endif + free(extent_start); return vram_pointer; diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/hw/vga.c --- a/tools/ioemu/hw/vga.c Wed Apr 16 10:07:49 2008 +0100 +++ b/tools/ioemu/hw/vga.c Wed Apr 16 10:21:08 2008 +0100 @@ -2067,8 +2067,8 @@ void vga_common_init(VGAState *s, Displa & ~(TARGET_PAGE_SIZE - 1)); /* Video RAM must be 128-bit aligned for SSE optimizations later */ - s->vram_alloc = qemu_malloc(vga_ram_size + 15); - s->vram_ptr = (uint8_t *)((long)(s->vram_alloc + 15) & ~15L); + /* and page-aligned for PVFB memory sharing */ + s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size); s->vram_offset = vga_ram_offset; s->vram_size = vga_ram_size; @@ -2210,7 +2210,7 @@ void *vga_update_vram(VGAState *s, void } if (!vga_ram_base) { - vga_ram_base = qemu_malloc(vga_ram_size + TARGET_PAGE_SIZE + 1); + vga_ram_base = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size + TARGET_PAGE_SIZE + 1); if (!vga_ram_base) { fprintf(stderr, "reallocate error\n"); return NULL; diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/hw/xenfb.c --- a/tools/ioemu/hw/xenfb.c Wed Apr 16 10:07:49 2008 +0100 +++ b/tools/ioemu/hw/xenfb.c Wed Apr 16 10:21:08 2008 +0100 @@ -1235,14 +1235,10 @@ static struct semaphore kbd_sem = __SEMA static struct semaphore kbd_sem = __SEMAPHORE_INITIALIZER(kbd_sem, 0); static struct kbdfront_dev *kbd_dev; static char *kbd_path, *fb_path; +static void *vga_vram, *nonshared_vram; +static DisplayState *xenfb_ds; static unsigned char linux2scancode[KEY_MAX + 1]; - -#define WIDTH 1024 -#define HEIGHT 768 -#define DEPTH 32 -#define LINESIZE (1280 * (DEPTH / 8)) -#define MEMSIZE (LINESIZE * HEIGHT) int xenfb_connect_vkbd(const char *path) { @@ -1256,33 +1252,73 @@ int xenfb_connect_vfb(const char *path) return 0; } -static void xenfb_pv_update(DisplayState *s, int x, int y, int w, int h) -{ - struct fbfront_dev *fb_dev = s->opaque; +static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h) +{ + struct fbfront_dev *fb_dev = ds->opaque; + if (!fb_dev) + return; fbfront_update(fb_dev, x, y, w, h); } -static void xenfb_pv_resize(DisplayState *s, int w, int h, int linesize) -{ - struct fbfront_dev *fb_dev = s->opaque; - fprintf(stderr,"resize to %dx%d required\n", w, h); - s->width = w; - s->height = h; - /* TODO: send resize event if supported */ - memset(s->data, 0, MEMSIZE); - fbfront_update(fb_dev, 0, 0, WIDTH, HEIGHT); +static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize) +{ + struct fbfront_dev *fb_dev = ds->opaque; + fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize); + ds->width = w; + ds->height = h; + if (!linesize) + ds->shared_buf = 0; + if (!ds->shared_buf) + linesize = w * 4; + ds->linesize = linesize; + if (!fb_dev) + return; + if (ds->shared_buf) { + ds->data = NULL; + } else { + ds->data = nonshared_vram; + fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE); + } } static void xenfb_pv_colourdepth(DisplayState *ds, int depth) { - /* TODO: send redepth event if supported */ + struct fbfront_dev *fb_dev = ds->opaque; static int lastdepth = -1; + if (!depth) { + ds->shared_buf = 0; + ds->depth = 32; + } else { + ds->shared_buf = 1; + ds->depth = depth; + } if (depth != lastdepth) { fprintf(stderr,"redepth to %d required\n", depth); lastdepth = depth; + } else return; + if (!fb_dev) + return; + if (ds->shared_buf) { + ds->data = NULL; + } else { + ds->data = nonshared_vram; + fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, VGA_RAM_SIZE); } - /* We can't redepth for now */ - ds->depth = DEPTH; +} + +static void xenfb_pv_setdata(DisplayState *ds, void *pixels) +{ + struct fbfront_dev *fb_dev = ds->opaque; + int offset = pixels - vga_vram; + ds->data = pixels; + if (!fb_dev) + return; + fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); +} + +static void xenfb_pv_refresh(DisplayState *ds) +{ + vga_hw_update(); } static void xenfb_kbd_handler(void *opaque) @@ -1373,13 +1409,6 @@ static void xenfb_kbd_handler(void *opaq } } -static void xenfb_pv_refresh(DisplayState *ds) -{ - /* always request negociation */ - ds->depth = -1; - vga_hw_update(); -} - static void kbdfront_thread(void *p) { int scancode, keycode; @@ -1399,40 +1428,72 @@ static void kbdfront_thread(void *p) int xenfb_pv_display_init(DisplayState *ds) { - void *data; + if (!fb_path || !kbd_path) + return -1; + + create_thread("kbdfront", kbdfront_thread, (void*) kbd_path); + + xenfb_ds = ds; + + ds->data = nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE); + memset(ds->data, 0, VGA_RAM_SIZE); + ds->depth = 32; + ds->bgr = 0; + ds->width = 640; + ds->height = 400; + ds->linesize = 640 * 4; + ds->dpy_update = xenfb_pv_update; + ds->dpy_resize = xenfb_pv_resize; + ds->dpy_colourdepth = xenfb_pv_colourdepth; + ds->dpy_setdata = xenfb_pv_setdata; + ds->dpy_refresh = xenfb_pv_refresh; + return 0; +} + +int xenfb_pv_display_start(void *data) +{ + DisplayState *ds = xenfb_ds; struct fbfront_dev *fb_dev; int kbd_fd; + int offset = 0; + unsigned long *mfns; + int n = VGA_RAM_SIZE / PAGE_SIZE; + int i; if (!fb_path || !kbd_path) - return -1; - - create_thread("kbdfront", kbdfront_thread, (void*) kbd_path); - - data = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE); - fb_dev = init_fbfront(fb_path, data, WIDTH, HEIGHT, DEPTH, LINESIZE, MEMSIZE); + return 0; + + vga_vram = data; + mfns = malloc(2 * n * sizeof(*mfns)); + for (i = 0; i < n; i++) + mfns[i] = virtual_to_mfn(vga_vram + i * PAGE_SIZE); + for (i = 0; i < n; i++) + mfns[n + i] = virtual_to_mfn(nonshared_vram + i * PAGE_SIZE); + + fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n); + free(mfns); if (!fb_dev) { fprintf(stderr,"can't open frame buffer\n"); exit(1); } free(fb_path); + if (ds->shared_buf) { + offset = (void*) ds->data - vga_vram; + } else { + offset = VGA_RAM_SIZE; + ds->data = nonshared_vram; + } + if (offset) + fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); + down(&kbd_sem); free(kbd_path); kbd_fd = kbdfront_open(kbd_dev); qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, ds); - ds->data = data; - ds->linesize = LINESIZE; - ds->depth = DEPTH; - ds->bgr = 0; - ds->width = WIDTH; - ds->height = HEIGHT; - ds->dpy_update = xenfb_pv_update; - ds->dpy_resize = xenfb_pv_resize; - ds->dpy_colourdepth = xenfb_pv_colourdepth; - ds->dpy_refresh = xenfb_pv_refresh; - ds->opaque = fb_dev; + xenfb_ds->opaque = fb_dev; return 0; } #endif diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Wed Apr 16 10:07:49 2008 +0100 +++ b/tools/ioemu/vl.h Wed Apr 16 10:21:08 2008 +0100 @@ -1545,6 +1545,7 @@ char *xenstore_vm_read(int domid, char * /* xenfb.c */ int xenfb_pv_display_init(DisplayState *ds); +int xenfb_pv_display_start(void *vram_start); int xenfb_connect_vkbd(const char *path); int xenfb_connect_vfb(const char *path); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |