# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1206522556 0
# Node ID d97e61001d81783d7175b59b8758733573244691
# Parent f5e6cccfdda5537876d6fc2b87ea1124d6043fc8
xenfb: Dynamic modes support.
Attached patch adds dynamic frame buffer size support to the xenfb PV
backend QEMU xenfb. Backend sets feature-resize and handles the
resize frame buffer event.
Corresponding frontend LINUX patch is required for functionality but
this patch is not dependent on it, preserving backwards
compatibility.
Signed-off-by: Pat Campbell <plc@xxxxxxxxxx>
---
tools/ioemu/hw/xenfb.c | 31 +++++++++++++++++++++++++++++++
tools/python/xen/xend/server/vfbif.py | 2 +-
tools/python/xen/xm/create.py | 8 +++++++-
xen/include/public/io/fbif.h | 28 +++++++++++++++++++++++-----
4 files changed, 62 insertions(+), 7 deletions(-)
diff -r f5e6cccfdda5 -r d97e61001d81 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c Tue Mar 25 18:02:00 2008 +0000
+++ b/tools/ioemu/hw/xenfb.c Wed Mar 26 09:09:16 2008 +0000
@@ -516,6 +516,16 @@ static void xenfb_on_fb_event(struct xen
}
xenfb_guest_copy(xenfb, x, y, w, h);
break;
+ case XENFB_TYPE_RESIZE:
+ xenfb->width = event->resize.width;
+ xenfb->height = event->resize.height;
+ xenfb->row_stride = event->resize.stride;
+ dpy_colourdepth(xenfb->ds, xenfb->depth);
+ dpy_resize(xenfb->ds, xenfb->width, xenfb->height,
xenfb->row_stride);
+ if (xenfb->ds->shared_buf)
+ dpy_setdata(xenfb->ds, xenfb->pixels);
+ xenfb_invalidate(xenfb);
+ break;
}
}
xen_mb(); /* ensure we're done with ring contents */
@@ -680,6 +690,7 @@ static int xenfb_read_frontend_fb_config
static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) {
struct xenfb_page *fb_page;
int val;
+ int videoram;
if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update",
"%d", &val) < 0)
@@ -702,10 +713,30 @@ static int xenfb_read_frontend_fb_config
/* TODO check for consistency with the above */
xenfb->fb_len = fb_page->mem_length;
xenfb->row_stride = fb_page->line_length;
+
+ /* Protect against hostile frontend, limit fb_len to max allowed */
+ if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d",
+ &videoram) < 0)
+ videoram = 0;
+ videoram = videoram * 1024 * 1024;
+ if (videoram && xenfb->fb_len > videoram) {
+ fprintf(stderr, "Framebuffer requested length of %zd exceeded
allowed %d\n",
+ xenfb->fb_len, videoram);
+ xenfb->fb_len = videoram;
+ if (xenfb->row_stride * xenfb->height > xenfb->fb_len)
+ xenfb->height = xenfb->fb_len / xenfb->row_stride;
+ }
fprintf(stderr, "Framebuffer depth %d width %d height %d line %d\n",
fb_page->depth, fb_page->width, fb_page->height,
fb_page->line_length);
if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0)
return -1;
+
+ /* Indicate we have the frame buffer resize feature */
+ xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "feature-resize", "1");
+
+ /* Tell kbd pointer the screen geometry */
+ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "width", "%d",
xenfb->width);
+ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "height", "%d",
xenfb->height);
if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected))
return -1;
diff -r f5e6cccfdda5 -r d97e61001d81 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py Tue Mar 25 18:02:00 2008 +0000
+++ b/tools/python/xen/xend/server/vfbif.py Wed Mar 26 09:09:16 2008 +0000
@@ -6,7 +6,7 @@ import os
import os
CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
- 'display', 'xauthority', 'keymap',
+ 'videoram', 'display', 'xauthority', 'keymap',
'uuid', 'location', 'protocol', 'opengl']
class VfbifController(DevController):
diff -r f5e6cccfdda5 -r d97e61001d81 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Mar 25 18:02:00 2008 +0000
+++ b/tools/python/xen/xm/create.py Wed Mar 26 09:09:16 2008 +0000
@@ -500,6 +500,11 @@ gopts.var('vncunused', val='',
use="""Try to find an unused port for the VNC server.
Only valid when vnc=1.""")
+gopts.var('videoram', val='',
+ fn=set_value, default=None,
+ use="""Maximum amount of videoram PV guest can allocate
+ for frame buffer.""")
+
gopts.var('sdl', val='',
fn=set_value, default=None,
use="""Should the device model use SDL?""")
@@ -645,7 +650,8 @@ def configure_vfbs(config_devs, vals):
d['type'] = 'sdl'
for (k,v) in d.iteritems():
if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
- 'xauthority', 'type', 'vncpasswd', 'opengl' ]:
+ 'videoram', 'xauthority', 'type', 'vncpasswd',
+ 'opengl' ]:
err("configuration option %s unknown to vfbs" % k)
config.append([k,v])
if not d.has_key("keymap"):
diff -r f5e6cccfdda5 -r d97e61001d81 xen/include/public/io/fbif.h
--- a/xen/include/public/io/fbif.h Tue Mar 25 18:02:00 2008 +0000
+++ b/xen/include/public/io/fbif.h Wed Mar 26 09:09:16 2008 +0000
@@ -50,12 +50,28 @@ struct xenfb_update
int32_t height; /* rect height */
};
+/*
+ * Framebuffer resize notification event
+ * Capable backend sets feature-resize in xenstore.
+ */
+#define XENFB_TYPE_RESIZE 3
+
+struct xenfb_resize
+{
+ uint8_t type; /* XENFB_TYPE_RESIZE */
+ int32_t width; /* width in pixels */
+ int32_t height; /* height in pixels */
+ int32_t stride; /* stride in bytes */
+ int32_t depth; /* depth in bits */
+};
+
#define XENFB_OUT_EVENT_SIZE 40
union xenfb_out_event
{
uint8_t type;
struct xenfb_update update;
+ struct xenfb_resize resize;
char pad[XENFB_OUT_EVENT_SIZE];
};
@@ -109,15 +125,17 @@ struct xenfb_page
* Each directory page holds PAGE_SIZE / sizeof(*pd)
* framebuffer pages, and can thus map up to PAGE_SIZE *
* PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
- * sizeof(unsigned long) == 4, that's 4 Megs. Two directory
- * pages should be enough for a while.
+ * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2 Megs
+ * 64 bit. 256 directories give enough room for a 512 Meg
+ * framebuffer with a max resolution of 12,800x10,240. Should
+ * be enough for a while with room leftover for expansion.
*/
- unsigned long pd[2];
+ unsigned long pd[256];
};
/*
- * Wart: xenkbd needs to know resolution. Put it here until a better
- * solution is found, but don't leak it to the backend.
+ * Wart: xenkbd needs to know default resolution. Put it here until a
+ * better solution is found, but don't leak it to the backend.
*/
#ifdef __KERNEL__
#define XENFB_WIDTH 800
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|