ia64/xen-unstable

changeset 16233:b760a4aa8dcf

pv-qemu 6/10: Merge private & public xenfb structs

This patch merges the public & private structs from the paravirt FB
into a single struct. Since QEMU is the only consumer of this code
there is no need for the artifical pub/priv split. Merging the two
will make it possible to more tightly integrate with QEMU's event
loop and do asynchronous non-blocking negoiation with the frontend
devices (see next patch).

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
author Keir Fraser <keir@xensource.com>
date Thu Oct 25 14:40:19 2007 +0100 (2007-10-25)
parents 54b72f14eb25
children 695871933840
files tools/ioemu/hw/xen_machine_pv.c tools/ioemu/hw/xenfb.c tools/ioemu/hw/xenfb.h
line diff
     1.1 --- a/tools/ioemu/hw/xen_machine_pv.c	Thu Oct 25 14:39:33 2007 +0100
     1.2 +++ b/tools/ioemu/hw/xen_machine_pv.c	Thu Oct 25 14:40:19 2007 +0100
     1.3 @@ -53,9 +53,6 @@ static void xen_init_pv(uint64_t ram_siz
     1.4                  strerror(errno));
     1.5          exit(1);
     1.6      }
     1.7 -
     1.8 -    /* Setup QEMU display */
     1.9 -    dpy_resize(ds, xenfb->width, xenfb->height);
    1.10  }
    1.11  
    1.12  QEMUMachine xenpv_machine = {
     2.1 --- a/tools/ioemu/hw/xenfb.c	Thu Oct 25 14:39:33 2007 +0100
     2.2 +++ b/tools/ioemu/hw/xenfb.c	Thu Oct 25 14:40:19 2007 +0100
     2.3 @@ -22,6 +22,8 @@
     2.4  
     2.5  // FIXME defend against malicious frontend?
     2.6  
     2.7 +struct xenfb;
     2.8 +
     2.9  struct xenfb_device {
    2.10  	const char *devicetype;
    2.11  	char nodename[64];	/* backend xenstore dir */
    2.12 @@ -30,16 +32,23 @@ struct xenfb_device {
    2.13  	enum xenbus_state state; /* backend state */
    2.14  	void *page;		/* shared page */
    2.15  	evtchn_port_t port;
    2.16 -	struct xenfb_private *xenfb;
    2.17 +	struct xenfb *xenfb;
    2.18  };
    2.19  
    2.20 -struct xenfb_private {
    2.21 -	struct xenfb pub;
    2.22 +struct xenfb {
    2.23 +	DisplayState *ds;       /* QEMU graphical console state */
    2.24  	int evt_xch;		/* event channel driver handle */
    2.25  	int xc;			/* hypervisor interface handle */
    2.26  	struct xs_handle *xsh;	/* xs daemon handle */
    2.27  	struct xenfb_device fb, kbd;
    2.28 +	void *pixels;           /* guest framebuffer data */
    2.29  	size_t fb_len;		/* size of framebuffer */
    2.30 +	int row_stride;         /* width of one row in framebuffer */
    2.31 +	int depth;              /* colour depth of guest framebuffer */
    2.32 +	int width;              /* pixel width of guest framebuffer */
    2.33 +	int height;             /* pixel height of guest framebuffer */
    2.34 +	int abs_pointer_wanted; /* Whether guest supports absolute pointer */
    2.35 +	int button_state;       /* Last seen pointer button state */
    2.36  	char protocol[64];	/* frontend protocol */
    2.37  };
    2.38  
    2.39 @@ -95,7 +104,7 @@ static const unsigned char atkbd_unxlate
    2.40  static unsigned char scancode2linux[512];
    2.41  
    2.42  
    2.43 -static void xenfb_detach_dom(struct xenfb_private *);
    2.44 +static void xenfb_detach_dom(struct xenfb *);
    2.45  
    2.46  static char *xenfb_path_in_dom(struct xs_handle *xsh,
    2.47  			       char *buf, size_t size,
    2.48 @@ -176,7 +185,7 @@ static int xenfb_xs_printf(struct xs_han
    2.49  
    2.50  static void xenfb_device_init(struct xenfb_device *dev,
    2.51  			      const char *type,
    2.52 -			      struct xenfb_private *xenfb)
    2.53 +			      struct xenfb *xenfb)
    2.54  {
    2.55  	dev->devicetype = type;
    2.56  	dev->otherend_id = -1;
    2.57 @@ -184,19 +193,17 @@ static void xenfb_device_init(struct xen
    2.58  	dev->xenfb = xenfb;
    2.59  }
    2.60  
    2.61 -int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
    2.62 +static int xenfb_device_set_domain(struct xenfb_device *dev, int domid)
    2.63  {
    2.64 -	struct xenfb_private *xenfb = dev->xenfb;
    2.65 -
    2.66  	dev->otherend_id = domid;
    2.67  
    2.68 -	if (!xenfb_path_in_dom(xenfb->xsh,
    2.69 +	if (!xenfb_path_in_dom(dev->xenfb->xsh,
    2.70  			       dev->otherend, sizeof(dev->otherend),
    2.71  			       domid, "device/%s/0", dev->devicetype)) {
    2.72  		errno = ENOENT;
    2.73  		return -1;
    2.74  	}
    2.75 -	if (!xenfb_path_in_dom(xenfb->xsh,
    2.76 +	if (!xenfb_path_in_dom(dev->xenfb->xsh,
    2.77  			       dev->nodename, sizeof(dev->nodename),
    2.78  			       0, "backend/%s/%d/0", dev->devicetype, domid)) {
    2.79  		errno = ENOENT;
    2.80 @@ -208,7 +215,7 @@ int xenfb_device_set_domain(struct xenfb
    2.81  
    2.82  struct xenfb *xenfb_new(void)
    2.83  {
    2.84 -	struct xenfb_private *xenfb = malloc(sizeof(*xenfb));
    2.85 +	struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
    2.86  	int serrno;
    2.87  	int i;
    2.88  
    2.89 @@ -239,30 +246,26 @@ struct xenfb *xenfb_new(void)
    2.90  	if (!xenfb->xsh)
    2.91  		goto fail;
    2.92  
    2.93 -	return &xenfb->pub;
    2.94 +	return xenfb;
    2.95  
    2.96   fail:
    2.97  	serrno = errno;
    2.98 -	xenfb_delete(&xenfb->pub);
    2.99 +	xenfb_delete(xenfb);
   2.100  	errno = serrno;
   2.101  	return NULL;
   2.102  }
   2.103  
   2.104  /* Remove the backend area in xenbus since the framebuffer really is
   2.105     going away. */
   2.106 -void xenfb_teardown(struct xenfb *xenfb_pub)
   2.107 +void xenfb_teardown(struct xenfb *xenfb)
   2.108  {
   2.109 -       struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.110 -
   2.111         xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
   2.112         xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);
   2.113  }
   2.114  
   2.115  
   2.116 -void xenfb_delete(struct xenfb *xenfb_pub)
   2.117 +void xenfb_delete(struct xenfb *xenfb)
   2.118  {
   2.119 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.120 -
   2.121  	xenfb_detach_dom(xenfb);
   2.122  	if (xenfb->xc >= 0)
   2.123  		xc_interface_close(xenfb->xc);
   2.124 @@ -394,7 +397,7 @@ static void xenfb_copy_mfns(int mode, in
   2.125  		dst[i] = (mode == 32) ? src32[i] : src64[i];
   2.126  }
   2.127  
   2.128 -static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
   2.129 +static int xenfb_map_fb(struct xenfb *xenfb, int domid)
   2.130  {
   2.131  	struct xenfb_page *page = xenfb->fb.page;
   2.132  	int n_fbmfns;
   2.133 @@ -466,9 +469,9 @@ static int xenfb_map_fb(struct xenfb_pri
   2.134  	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
   2.135  	munmap(map, n_fbdirs * XC_PAGE_SIZE);
   2.136  
   2.137 -	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
   2.138 +	xenfb->pixels = xc_map_foreign_pages(xenfb->xc, domid,
   2.139  				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
   2.140 -	if (xenfb->pub.pixels == NULL)
   2.141 +	if (xenfb->pixels == NULL)
   2.142  		goto out;
   2.143  
   2.144  	ret = 0; /* all is fine */
   2.145 @@ -483,7 +486,7 @@ static int xenfb_map_fb(struct xenfb_pri
   2.146  
   2.147  static int xenfb_bind(struct xenfb_device *dev)
   2.148  {
   2.149 -	struct xenfb_private *xenfb = dev->xenfb;
   2.150 +	struct xenfb *xenfb = dev->xenfb;
   2.151  	unsigned long mfn;
   2.152  	evtchn_port_t evtchn;
   2.153  
   2.154 @@ -566,17 +569,18 @@ static void xenfb_dev_fatal(struct xenfb
   2.155  }
   2.156  
   2.157  
   2.158 -static void xenfb_detach_dom(struct xenfb_private *xenfb)
   2.159 +static void xenfb_detach_dom(struct xenfb *xenfb)
   2.160  {
   2.161  	xenfb_unbind(&xenfb->fb);
   2.162  	xenfb_unbind(&xenfb->kbd);
   2.163 -	if (xenfb->pub.pixels) {
   2.164 -		munmap(xenfb->pub.pixels, xenfb->fb_len);
   2.165 -		xenfb->pub.pixels = NULL;
   2.166 +	if (xenfb->pixels) {
   2.167 +		munmap(xenfb->pixels, xenfb->fb_len);
   2.168 +		xenfb->pixels = NULL;
   2.169  	}
   2.170  }
   2.171  
   2.172 -static void xenfb_on_fb_event(struct xenfb_private *xenfb)
   2.173 +
   2.174 +static void xenfb_on_fb_event(struct xenfb *xenfb)
   2.175  {
   2.176  	uint32_t prod, cons;
   2.177  	struct xenfb_page *page = xenfb->fb.page;
   2.178 @@ -590,11 +594,10 @@ static void xenfb_on_fb_event(struct xen
   2.179  
   2.180  		switch (event->type) {
   2.181  		case XENFB_TYPE_UPDATE:
   2.182 -                    if (xenfb->pub.update)
   2.183 -			xenfb->pub.update(&xenfb->pub,
   2.184 -					  event->update.x, event->update.y,
   2.185 -					  event->update.width, event->update.height);
   2.186 -                    break;
   2.187 +			xenfb_guest_copy(xenfb,
   2.188 +					 event->update.x, event->update.y,
   2.189 +					 event->update.width, event->update.height);
   2.190 +			break;
   2.191  		}
   2.192  	}
   2.193  	mb();			/* ensure we're done with ring contents */
   2.194 @@ -602,7 +605,7 @@ static void xenfb_on_fb_event(struct xen
   2.195  	xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port);
   2.196  }
   2.197  
   2.198 -static void xenfb_on_kbd_event(struct xenfb_private *xenfb)
   2.199 +static void xenfb_on_kbd_event(struct xenfb *xenfb)
   2.200  {
   2.201  	struct xenkbd_page *page = xenfb->kbd.page;
   2.202  
   2.203 @@ -640,7 +643,7 @@ static int xenfb_on_state_change(struct 
   2.204  	return 0;
   2.205  }
   2.206  
   2.207 -static int xenfb_kbd_event(struct xenfb_private *xenfb,
   2.208 +static int xenfb_kbd_event(struct xenfb *xenfb,
   2.209  			   union xenkbd_in_event *event)
   2.210  {
   2.211  	uint32_t prod;
   2.212 @@ -662,9 +665,8 @@ static int xenfb_kbd_event(struct xenfb_
   2.213  	return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port);
   2.214  }
   2.215  
   2.216 -static int xenfb_send_key(struct xenfb *xenfb_pub, bool down, int keycode)
   2.217 +static int xenfb_send_key(struct xenfb *xenfb, bool down, int keycode)
   2.218  {
   2.219 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.220  	union xenkbd_in_event event;
   2.221  
   2.222  	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
   2.223 @@ -675,9 +677,8 @@ static int xenfb_send_key(struct xenfb *
   2.224  	return xenfb_kbd_event(xenfb, &event);
   2.225  }
   2.226  
   2.227 -static int xenfb_send_motion(struct xenfb *xenfb_pub, int rel_x, int rel_y)
   2.228 +static int xenfb_send_motion(struct xenfb *xenfb, int rel_x, int rel_y)
   2.229  {
   2.230 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.231  	union xenkbd_in_event event;
   2.232  
   2.233  	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
   2.234 @@ -688,9 +689,8 @@ static int xenfb_send_motion(struct xenf
   2.235  	return xenfb_kbd_event(xenfb, &event);
   2.236  }
   2.237  
   2.238 -static int xenfb_send_position(struct xenfb *xenfb_pub, int abs_x, int abs_y)
   2.239 +static int xenfb_send_position(struct xenfb *xenfb, int abs_x, int abs_y)
   2.240  {
   2.241 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.242  	union xenkbd_in_event event;
   2.243  
   2.244  	memset(&event, 0, XENKBD_IN_EVENT_SIZE);
   2.245 @@ -702,9 +702,9 @@ static int xenfb_send_position(struct xe
   2.246  }
   2.247  
   2.248  
   2.249 -static void xenfb_dispatch_channel(void *xenfb_pub)
   2.250 +static void xenfb_dispatch_channel(void *opaque)
   2.251  {
   2.252 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.253 +	struct xenfb *xenfb = (struct xenfb *)opaque;
   2.254  	evtchn_port_t port;
   2.255  	port = xc_evtchn_pending(xenfb->evt_xch);
   2.256  	if (port == -1)
   2.257 @@ -719,9 +719,9 @@ static void xenfb_dispatch_channel(void 
   2.258  		exit(1);
   2.259  }
   2.260  
   2.261 -static void xenfb_dispatch_store(void *xenfb_pub)
   2.262 +static void xenfb_dispatch_store(void *opaque)
   2.263  {
   2.264 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.265 +	struct xenfb *xenfb = (struct xenfb *)opaque;
   2.266  	unsigned dummy;
   2.267  	char **vec;
   2.268  	int r;
   2.269 @@ -736,9 +736,8 @@ static void xenfb_dispatch_store(void *x
   2.270  }
   2.271  
   2.272  
   2.273 -int xenfb_attach_dom(struct xenfb *xenfb_pub, int domid, DisplayState *ds)
   2.274 +int xenfb_attach_dom(struct xenfb *xenfb, int domid, DisplayState *ds)
   2.275  {
   2.276 -	struct xenfb_private *xenfb = (struct xenfb_private *)xenfb_pub;
   2.277  	struct xs_handle *xsh = xenfb->xsh;
   2.278  	int val, serrno;
   2.279  	struct xenfb_page *fb_page;
   2.280 @@ -794,12 +793,12 @@ int xenfb_attach_dom(struct xenfb *xenfb
   2.281  
   2.282  	/* TODO check for permitted ranges */
   2.283  	fb_page = xenfb->fb.page;
   2.284 -	xenfb->pub.depth = fb_page->depth;
   2.285 -	xenfb->pub.width = fb_page->width;
   2.286 -	xenfb->pub.height = fb_page->height;
   2.287 +	xenfb->depth = fb_page->depth;
   2.288 +	xenfb->width = fb_page->width;
   2.289 +	xenfb->height = fb_page->height;
   2.290  	/* TODO check for consistency with the above */
   2.291  	xenfb->fb_len = fb_page->mem_length;
   2.292 -	xenfb->pub.row_stride = fb_page->line_length;
   2.293 +	xenfb->row_stride = fb_page->line_length;
   2.294  
   2.295  	if (xenfb_map_fb(xenfb, domid) < 0)
   2.296  		goto error;
   2.297 @@ -814,7 +813,7 @@ int xenfb_attach_dom(struct xenfb *xenfb
   2.298  	if (xenfb_xs_scanf1(xsh, xenfb->kbd.otherend, "request-abs-pointer",
   2.299  			    "%d", &val) < 0)
   2.300  		val = 0;
   2.301 -	xenfb->pub.abs_pointer_wanted = val;
   2.302 +	xenfb->abs_pointer_wanted = val;
   2.303  
   2.304  	/* Listen for events from xenstore */
   2.305  	if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)
   2.306 @@ -827,19 +826,18 @@ int xenfb_attach_dom(struct xenfb *xenfb
   2.307  	/* Register our keyboard & mouse handlers */
   2.308  	qemu_add_kbd_event_handler(xenfb_key_event, xenfb);
   2.309  	qemu_add_mouse_event_handler(xenfb_mouse_event, xenfb,
   2.310 -				     xenfb_pub->abs_pointer_wanted,
   2.311 +				     xenfb->abs_pointer_wanted,
   2.312  				     "Xen PVFB Mouse");
   2.313  
   2.314 -	xenfb_pub->update = xenfb_guest_copy;
   2.315 -	xenfb_pub->user_data = ds;
   2.316 +	xenfb->ds = ds;
   2.317  
   2.318  	/* Tell QEMU to allocate a graphical console */
   2.319  	graphic_console_init(ds,
   2.320  			     xenfb_update,
   2.321  			     xenfb_invalidate,
   2.322  			     xenfb_screen_dump,
   2.323 -			     xenfb_pub);
   2.324 -	dpy_resize(ds, xenfb_pub->width, xenfb_pub->height);
   2.325 +			     xenfb);
   2.326 +	dpy_resize(ds, xenfb->width, xenfb->height);
   2.327  
   2.328  	return 0;
   2.329  
   2.330 @@ -898,11 +896,10 @@ static void xenfb_mouse_event(void *opaq
   2.331  {
   2.332      int i;
   2.333      struct xenfb *xenfb = opaque;
   2.334 -    DisplayState *ds = (DisplayState *)xenfb->user_data;
   2.335      if (xenfb->abs_pointer_wanted)
   2.336  	    xenfb_send_position(xenfb,
   2.337 -				dx * ds->width / 0x7fff,
   2.338 -				dy * ds->height / 0x7fff);
   2.339 +				dx * xenfb->ds->width / 0x7fff,
   2.340 +				dy * xenfb->ds->height / 0x7fff);
   2.341      else
   2.342  	    xenfb_send_motion(xenfb, dx, dy);
   2.343  
   2.344 @@ -924,9 +921,9 @@ static void xenfb_mouse_event(void *opaq
   2.345          SRC_T *src = (SRC_T *)(xenfb->pixels                            \
   2.346                                 + (line * xenfb->row_stride)             \
   2.347                                 + (x * xenfb->depth / 8));               \
   2.348 -        DST_T *dst = (DST_T *)(ds->data                                 \
   2.349 -                               + (line * ds->linesize)                  \
   2.350 -                               + (x * ds->depth / 8));                  \
   2.351 +        DST_T *dst = (DST_T *)(xenfb->ds->data                                 \
   2.352 +                               + (line * xenfb->ds->linesize)                  \
   2.353 +                               + (x * xenfb->ds->depth / 8));                  \
   2.354          int col;                                                        \
   2.355          for (col = x ; col < w ; col++) {                               \
   2.356              *dst = (((*src >> RRS) & RM) << RLS) |                      \
   2.357 @@ -945,40 +942,39 @@ static void xenfb_mouse_event(void *opaq
   2.358   */
   2.359  static void xenfb_guest_copy(struct xenfb *xenfb, int x, int y, int w, int h)
   2.360  {
   2.361 -    DisplayState *ds = (DisplayState *)xenfb->user_data;
   2.362      int line;
   2.363  
   2.364 -    if (xenfb->depth == ds->depth) { /* Perfect match can use fast path */
   2.365 +    if (xenfb->depth == xenfb->ds->depth) { /* Perfect match can use fast path */
   2.366          for (line = y ; line < (y+h) ; line++) {
   2.367 -            memcpy(ds->data + (line * ds->linesize) + (x * ds->depth / 8),
   2.368 +            memcpy(xenfb->ds->data + (line * xenfb->ds->linesize) + (x * xenfb->ds->depth / 8),
   2.369                     xenfb->pixels + (line * xenfb->row_stride) + (x * xenfb->depth / 8),
   2.370                     w * xenfb->depth / 8);
   2.371          }
   2.372      } else { /* Mismatch requires slow pixel munging */
   2.373          if (xenfb->depth == 8) {
   2.374              /* 8 bit source == r:3 g:3 b:2 */
   2.375 -            if (ds->depth == 16) {
   2.376 +            if (xenfb->ds->depth == 16) {
   2.377                  BLT(uint8_t, uint16_t,   5, 2, 0,   11, 5, 0,   7, 7, 3);
   2.378 -            } else if (ds->depth == 32) {
   2.379 +            } else if (xenfb->ds->depth == 32) {
   2.380                  BLT(uint8_t, uint32_t,   5, 2, 0,   16, 8, 0,   7, 7, 3);
   2.381              }
   2.382          } else if (xenfb->depth == 16) {
   2.383              /* 16 bit source == r:5 g:6 b:5 */
   2.384 -            if (ds->depth == 8) {
   2.385 +            if (xenfb->ds->depth == 8) {
   2.386                  BLT(uint16_t, uint8_t,    11, 5, 0,   5, 2, 0,    31, 63, 31);
   2.387 -            } else if (ds->depth == 32) {
   2.388 +            } else if (xenfb->ds->depth == 32) {
   2.389                  BLT(uint16_t, uint32_t,   11, 5, 0,   16, 8, 0,   31, 63, 31);
   2.390              }
   2.391          } else if (xenfb->depth == 32) {
   2.392              /* 32 bit source == r:8 g:8 b:8 (padding:8) */
   2.393 -            if (ds->depth == 8) {
   2.394 +            if (xenfb->ds->depth == 8) {
   2.395                  BLT(uint32_t, uint8_t,    16, 8, 0,   5, 2, 0,    255, 255, 255);
   2.396 -            } else if (ds->depth == 16) {
   2.397 +            } else if (xenfb->ds->depth == 16) {
   2.398                  BLT(uint32_t, uint16_t,   16, 8, 0,   11, 5, 0,   255, 255, 255);
   2.399              }
   2.400          }
   2.401      }
   2.402 -    dpy_update(ds, x, y, w, h);
   2.403 +    dpy_update(xenfb->ds, x, y, w, h);
   2.404  }
   2.405  
   2.406  /* QEMU display state changed, so refresh the framebuffer copy */
     3.1 --- a/tools/ioemu/hw/xenfb.h	Thu Oct 25 14:39:33 2007 +0100
     3.2 +++ b/tools/ioemu/hw/xenfb.h	Thu Oct 25 14:40:19 2007 +0100
     3.3 @@ -5,21 +5,7 @@
     3.4  #include <stdbool.h>
     3.5  #include <sys/types.h>
     3.6  
     3.7 -struct xenfb
     3.8 -{
     3.9 -	void *pixels;
    3.10 -
    3.11 -	int row_stride;
    3.12 -	int depth;
    3.13 -	int width;
    3.14 -	int height;
    3.15 -	int abs_pointer_wanted;
    3.16 -	int button_state;
    3.17 -
    3.18 -	void *user_data;
    3.19 -
    3.20 -	void (*update)(struct xenfb *xenfb, int x, int y, int width, int height);
    3.21 -};
    3.22 +struct xenfb;
    3.23  
    3.24  struct xenfb *xenfb_new(void);
    3.25  void xenfb_delete(struct xenfb *xenfb);