xref: /qemu/hw/display/xenfb.c (revision 6402cbbb)
1 /*
2  *  xen paravirt framebuffer backend
3  *
4  *  Copyright IBM, Corp. 2005-2006
5  *  Copyright Red Hat, Inc. 2006-2008
6  *
7  *  Authors:
8  *       Anthony Liguori <aliguori@us.ibm.com>,
9  *       Markus Armbruster <armbru@redhat.com>,
10  *       Daniel P. Berrange <berrange@redhat.com>,
11  *       Pat Campbell <plc@novell.com>,
12  *       Gerd Hoffmann <kraxel@redhat.com>
13  *
14  *  This program is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by
16  *  the Free Software Foundation; under version 2 of the License.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License along
24  *  with this program; if not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #include "qemu/osdep.h"
28 
29 #include "hw/hw.h"
30 #include "ui/console.h"
31 #include "hw/xen/xen_backend.h"
32 
33 #include <xen/event_channel.h>
34 #include <xen/io/fbif.h>
35 #include <xen/io/kbdif.h>
36 #include <xen/io/protocols.h>
37 
38 #include "trace.h"
39 
40 #ifndef BTN_LEFT
41 #define BTN_LEFT 0x110 /* from <linux/input.h> */
42 #endif
43 
44 /* -------------------------------------------------------------------- */
45 
46 struct common {
47     struct XenDevice  xendev;  /* must be first */
48     void              *page;
49 };
50 
51 struct XenInput {
52     struct common c;
53     int abs_pointer_wanted; /* Whether guest supports absolute pointer */
54     int button_state;       /* Last seen pointer button state */
55     int extended;
56     QEMUPutMouseEntry *qmouse;
57 };
58 
59 #define UP_QUEUE 8
60 
61 struct XenFB {
62     struct common     c;
63     QemuConsole       *con;
64     size_t            fb_len;
65     int               row_stride;
66     int               depth;
67     int               width;
68     int               height;
69     int               offset;
70     void              *pixels;
71     int               fbpages;
72     int               feature_update;
73     int               bug_trigger;
74     int               do_resize;
75 
76     struct {
77 	int x,y,w,h;
78     } up_rects[UP_QUEUE];
79     int               up_count;
80     int               up_fullscreen;
81 };
82 static const GraphicHwOps xenfb_ops;
83 
84 /* -------------------------------------------------------------------- */
85 
86 static int common_bind(struct common *c)
87 {
88     uint64_t val;
89     xen_pfn_t mfn;
90 
91     if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
92         return -1;
93     mfn = (xen_pfn_t)val;
94     assert(val == mfn);
95 
96     if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
97         return -1;
98 
99     c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom,
100                                    PROT_READ | PROT_WRITE, 1, &mfn, NULL);
101     if (c->page == NULL)
102         return -1;
103 
104     xen_be_bind_evtchn(&c->xendev);
105     xen_pv_printf(&c->xendev, 1,
106                   "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
107                   mfn, c->xendev.remote_port, c->xendev.local_port);
108 
109     return 0;
110 }
111 
112 static void common_unbind(struct common *c)
113 {
114     xen_pv_unbind_evtchn(&c->xendev);
115     if (c->page) {
116         xenforeignmemory_unmap(xen_fmem, c->page, 1);
117 	c->page = NULL;
118     }
119 }
120 
121 /* -------------------------------------------------------------------- */
122 
123 #if 0
124 /*
125  * These two tables are not needed any more, but left in here
126  * intentionally as documentation, to show how scancode2linux[]
127  * was generated.
128  *
129  * Tables to map from scancode to Linux input layer keycode.
130  * Scancodes are hardware-specific.  These maps assumes a
131  * standard AT or PS/2 keyboard which is what QEMU feeds us.
132  */
133 const unsigned char atkbd_set2_keycode[512] = {
134 
135      0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
136      0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
137      0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
138      0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
139      0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
140      0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
141      0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
142     82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
143 
144       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
145     217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
146     173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
147     159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
148     157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
149     226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
150       0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
151     110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
152 
153 };
154 
155 const unsigned char atkbd_unxlate_table[128] = {
156 
157       0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
158      21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
159      35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
160      50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
161      11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
162     114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
163      71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
164      19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
165 
166 };
167 #endif
168 
169 /*
170  * for (i = 0; i < 128; i++) {
171  *     scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
172  *     scancode2linux[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
173  * }
174  */
175 static const unsigned char scancode2linux[512] = {
176       0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
177      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
178      32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
179      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
180      64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
181      80, 81, 82, 83, 99,  0, 86, 87, 88,117,  0,  0, 95,183,184,185,
182       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
183      93,  0,  0, 89,  0,  0, 85, 91, 90, 92,  0, 94,  0,124,121,  0,
184 
185       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
186     165,  0,  0,  0,  0,  0,  0,  0,  0,163,  0,  0, 96, 97,  0,  0,
187     113,140,164,  0,166,  0,  0,  0,  0,  0,255,  0,  0,  0,114,  0,
188     115,  0,150,  0,  0, 98,255, 99,100,  0,  0,  0,  0,  0,  0,  0,
189       0,  0,  0,  0,  0,119,119,102,103,104,  0,105,112,106,118,107,
190     108,109,110,111,  0,  0,  0,  0,  0,  0,  0,125,126,127,116,142,
191       0,  0,  0,143,  0,217,156,173,128,159,158,157,155,226,  0,112,
192       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
193 };
194 
195 /* Send an event to the keyboard frontend driver */
196 static int xenfb_kbd_event(struct XenInput *xenfb,
197 			   union xenkbd_in_event *event)
198 {
199     struct xenkbd_page *page = xenfb->c.page;
200     uint32_t prod;
201 
202     if (xenfb->c.xendev.be_state != XenbusStateConnected)
203 	return 0;
204     if (!page)
205         return 0;
206 
207     prod = page->in_prod;
208     if (prod - page->in_cons == XENKBD_IN_RING_LEN) {
209 	errno = EAGAIN;
210 	return -1;
211     }
212 
213     xen_mb();		/* ensure ring space available */
214     XENKBD_IN_RING_REF(page, prod) = *event;
215     xen_wmb();		/* ensure ring contents visible */
216     page->in_prod = prod + 1;
217     return xen_pv_send_notify(&xenfb->c.xendev);
218 }
219 
220 /* Send a keyboard (or mouse button) event */
221 static int xenfb_send_key(struct XenInput *xenfb, bool down, int keycode)
222 {
223     union xenkbd_in_event event;
224 
225     memset(&event, 0, XENKBD_IN_EVENT_SIZE);
226     event.type = XENKBD_TYPE_KEY;
227     event.key.pressed = down ? 1 : 0;
228     event.key.keycode = keycode;
229 
230     return xenfb_kbd_event(xenfb, &event);
231 }
232 
233 /* Send a relative mouse movement event */
234 static int xenfb_send_motion(struct XenInput *xenfb,
235 			     int rel_x, int rel_y, int rel_z)
236 {
237     union xenkbd_in_event event;
238 
239     memset(&event, 0, XENKBD_IN_EVENT_SIZE);
240     event.type = XENKBD_TYPE_MOTION;
241     event.motion.rel_x = rel_x;
242     event.motion.rel_y = rel_y;
243     event.motion.rel_z = rel_z;
244 
245     return xenfb_kbd_event(xenfb, &event);
246 }
247 
248 /* Send an absolute mouse movement event */
249 static int xenfb_send_position(struct XenInput *xenfb,
250 			       int abs_x, int abs_y, int z)
251 {
252     union xenkbd_in_event event;
253 
254     memset(&event, 0, XENKBD_IN_EVENT_SIZE);
255     event.type = XENKBD_TYPE_POS;
256     event.pos.abs_x = abs_x;
257     event.pos.abs_y = abs_y;
258     event.pos.rel_z = z;
259 
260     return xenfb_kbd_event(xenfb, &event);
261 }
262 
263 /*
264  * Send a key event from the client to the guest OS
265  * QEMU gives us a raw scancode from an AT / PS/2 style keyboard.
266  * We have to turn this into a Linux Input layer keycode.
267  *
268  * Extra complexity from the fact that with extended scancodes
269  * (like those produced by arrow keys) this method gets called
270  * twice, but we only want to send a single event. So we have to
271  * track the '0xe0' scancode state & collapse the extended keys
272  * as needed.
273  *
274  * Wish we could just send scancodes straight to the guest which
275  * already has code for dealing with this...
276  */
277 static void xenfb_key_event(void *opaque, int scancode)
278 {
279     struct XenInput *xenfb = opaque;
280     int down = 1;
281 
282     if (scancode == 0xe0) {
283 	xenfb->extended = 1;
284 	return;
285     } else if (scancode & 0x80) {
286 	scancode &= 0x7f;
287 	down = 0;
288     }
289     if (xenfb->extended) {
290 	scancode |= 0x80;
291 	xenfb->extended = 0;
292     }
293     xenfb_send_key(xenfb, down, scancode2linux[scancode]);
294 }
295 
296 /*
297  * Send a mouse event from the client to the guest OS
298  *
299  * The QEMU mouse can be in either relative, or absolute mode.
300  * Movement is sent separately from button state, which has to
301  * be encoded as virtual key events. We also don't actually get
302  * given any button up/down events, so have to track changes in
303  * the button state.
304  */
305 static void xenfb_mouse_event(void *opaque,
306 			      int dx, int dy, int dz, int button_state)
307 {
308     struct XenInput *xenfb = opaque;
309     QemuConsole *con = qemu_console_lookup_by_index(0);
310     DisplaySurface *surface;
311     int dw, dh, i;
312 
313     if (!con) {
314         xen_pv_printf(&xenfb->c.xendev, 0, "No QEMU console available");
315         return;
316     }
317 
318     surface = qemu_console_surface(con);
319     dw = surface_width(surface);
320     dh = surface_height(surface);
321 
322     trace_xenfb_mouse_event(opaque, dx, dy, dz, button_state,
323                             xenfb->abs_pointer_wanted);
324     if (xenfb->abs_pointer_wanted)
325 	xenfb_send_position(xenfb,
326 			    dx * (dw - 1) / 0x7fff,
327 			    dy * (dh - 1) / 0x7fff,
328 			    dz);
329     else
330 	xenfb_send_motion(xenfb, dx, dy, dz);
331 
332     for (i = 0 ; i < 8 ; i++) {
333 	int lastDown = xenfb->button_state & (1 << i);
334 	int down = button_state & (1 << i);
335 	if (down == lastDown)
336 	    continue;
337 
338 	if (xenfb_send_key(xenfb, down, BTN_LEFT+i) < 0)
339 	    return;
340     }
341     xenfb->button_state = button_state;
342 }
343 
344 static int input_init(struct XenDevice *xendev)
345 {
346     xenstore_write_be_int(xendev, "feature-abs-pointer", 1);
347     return 0;
348 }
349 
350 static int input_initialise(struct XenDevice *xendev)
351 {
352     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
353     int rc;
354 
355     rc = common_bind(&in->c);
356     if (rc != 0)
357 	return rc;
358 
359     qemu_add_kbd_event_handler(xenfb_key_event, in);
360     return 0;
361 }
362 
363 static void input_connected(struct XenDevice *xendev)
364 {
365     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
366 
367     if (xenstore_read_fe_int(xendev, "request-abs-pointer",
368                              &in->abs_pointer_wanted) == -1) {
369         in->abs_pointer_wanted = 0;
370     }
371 
372     if (in->qmouse) {
373         qemu_remove_mouse_event_handler(in->qmouse);
374     }
375     trace_xenfb_input_connected(xendev, in->abs_pointer_wanted);
376     in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
377 					      in->abs_pointer_wanted,
378 					      "Xen PVFB Mouse");
379 }
380 
381 static void input_disconnect(struct XenDevice *xendev)
382 {
383     struct XenInput *in = container_of(xendev, struct XenInput, c.xendev);
384 
385     if (in->qmouse) {
386 	qemu_remove_mouse_event_handler(in->qmouse);
387 	in->qmouse = NULL;
388     }
389     qemu_add_kbd_event_handler(NULL, NULL);
390     common_unbind(&in->c);
391 }
392 
393 static void input_event(struct XenDevice *xendev)
394 {
395     struct XenInput *xenfb = container_of(xendev, struct XenInput, c.xendev);
396     struct xenkbd_page *page = xenfb->c.page;
397 
398     /* We don't understand any keyboard events, so just ignore them. */
399     if (page->out_prod == page->out_cons)
400 	return;
401     page->out_cons = page->out_prod;
402     xen_pv_send_notify(&xenfb->c.xendev);
403 }
404 
405 /* -------------------------------------------------------------------- */
406 
407 static void xenfb_copy_mfns(int mode, int count, xen_pfn_t *dst, void *src)
408 {
409     uint32_t *src32 = src;
410     uint64_t *src64 = src;
411     int i;
412 
413     for (i = 0; i < count; i++)
414 	dst[i] = (mode == 32) ? src32[i] : src64[i];
415 }
416 
417 static int xenfb_map_fb(struct XenFB *xenfb)
418 {
419     struct xenfb_page *page = xenfb->c.page;
420     char *protocol = xenfb->c.xendev.protocol;
421     int n_fbdirs;
422     xen_pfn_t *pgmfns = NULL;
423     xen_pfn_t *fbmfns = NULL;
424     void *map, *pd;
425     int mode, ret = -1;
426 
427     /* default to native */
428     pd = page->pd;
429     mode = sizeof(unsigned long) * 8;
430 
431     if (!protocol) {
432 	/*
433 	 * Undefined protocol, some guesswork needed.
434 	 *
435 	 * Old frontends which don't set the protocol use
436 	 * one page directory only, thus pd[1] must be zero.
437 	 * pd[1] of the 32bit struct layout and the lower
438 	 * 32 bits of pd[0] of the 64bit struct layout have
439 	 * the same location, so we can check that ...
440 	 */
441 	uint32_t *ptr32 = NULL;
442 	uint32_t *ptr64 = NULL;
443 #if defined(__i386__)
444 	ptr32 = (void*)page->pd;
445 	ptr64 = ((void*)page->pd) + 4;
446 #elif defined(__x86_64__)
447 	ptr32 = ((void*)page->pd) - 4;
448 	ptr64 = (void*)page->pd;
449 #endif
450 	if (ptr32) {
451 	    if (ptr32[1] == 0) {
452 		mode = 32;
453 		pd   = ptr32;
454 	    } else {
455 		mode = 64;
456 		pd   = ptr64;
457 	    }
458 	}
459 #if defined(__x86_64__)
460     } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
461 	/* 64bit dom0, 32bit domU */
462 	mode = 32;
463 	pd   = ((void*)page->pd) - 4;
464 #elif defined(__i386__)
465     } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
466 	/* 32bit dom0, 64bit domU */
467 	mode = 64;
468 	pd   = ((void*)page->pd) + 4;
469 #endif
470     }
471 
472     if (xenfb->pixels) {
473         munmap(xenfb->pixels, xenfb->fbpages * XC_PAGE_SIZE);
474         xenfb->pixels = NULL;
475     }
476 
477     xenfb->fbpages = DIV_ROUND_UP(xenfb->fb_len, XC_PAGE_SIZE);
478     n_fbdirs = xenfb->fbpages * mode / 8;
479     n_fbdirs = DIV_ROUND_UP(n_fbdirs, XC_PAGE_SIZE);
480 
481     pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs);
482     fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages);
483 
484     xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
485     map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
486                                PROT_READ, n_fbdirs, pgmfns, NULL);
487     if (map == NULL)
488 	goto out;
489     xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
490     xenforeignmemory_unmap(xen_fmem, map, n_fbdirs);
491 
492     xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
493             PROT_READ, xenfb->fbpages, fbmfns, NULL);
494     if (xenfb->pixels == NULL)
495 	goto out;
496 
497     ret = 0; /* all is fine */
498 
499 out:
500     g_free(pgmfns);
501     g_free(fbmfns);
502     return ret;
503 }
504 
505 static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
506                               int width, int height, int depth,
507                               size_t fb_len, int offset, int row_stride)
508 {
509     size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
510     size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
511     size_t fb_pages = pd_len * XC_PAGE_SIZE / mfn_sz;
512     size_t fb_len_max = fb_pages * XC_PAGE_SIZE;
513     int max_width, max_height;
514 
515     if (fb_len_lim > fb_len_max) {
516         xen_pv_printf(&xenfb->c.xendev, 0,
517                       "fb size limit %zu exceeds %zu, corrected\n",
518                       fb_len_lim, fb_len_max);
519         fb_len_lim = fb_len_max;
520     }
521     if (fb_len_lim && fb_len > fb_len_lim) {
522         xen_pv_printf(&xenfb->c.xendev, 0,
523                       "frontend fb size %zu limited to %zu\n",
524                       fb_len, fb_len_lim);
525         fb_len = fb_len_lim;
526     }
527     if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
528         xen_pv_printf(&xenfb->c.xendev, 0,
529                       "can't handle frontend fb depth %d\n",
530                       depth);
531         return -1;
532     }
533     if (row_stride <= 0 || row_stride > fb_len) {
534         xen_pv_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n",
535                       row_stride);
536         return -1;
537     }
538     max_width = row_stride / (depth / 8);
539     if (width < 0 || width > max_width) {
540         xen_pv_printf(&xenfb->c.xendev, 0,
541                       "invalid frontend width %d limited to %d\n",
542                       width, max_width);
543         width = max_width;
544     }
545     if (offset < 0 || offset >= fb_len) {
546         xen_pv_printf(&xenfb->c.xendev, 0,
547                       "invalid frontend offset %d (max %zu)\n",
548                       offset, fb_len - 1);
549         return -1;
550     }
551     max_height = (fb_len - offset) / row_stride;
552     if (height < 0 || height > max_height) {
553         xen_pv_printf(&xenfb->c.xendev, 0,
554                       "invalid frontend height %d limited to %d\n",
555                       height, max_height);
556         height = max_height;
557     }
558     xenfb->fb_len = fb_len;
559     xenfb->row_stride = row_stride;
560     xenfb->depth = depth;
561     xenfb->width = width;
562     xenfb->height = height;
563     xenfb->offset = offset;
564     xenfb->up_fullscreen = 1;
565     xenfb->do_resize = 1;
566     xen_pv_printf(&xenfb->c.xendev, 1,
567                   "framebuffer %dx%dx%d offset %d stride %d\n",
568                   width, height, depth, offset, row_stride);
569     return 0;
570 }
571 
572 /* A convenient function for munging pixels between different depths */
573 #define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB)                        \
574     for (line = y ; line < (y+h) ; line++) {				\
575 	SRC_T *src = (SRC_T *)(xenfb->pixels				\
576 			       + xenfb->offset				\
577 			       + (line * xenfb->row_stride)		\
578 			       + (x * xenfb->depth / 8));		\
579 	DST_T *dst = (DST_T *)(data					\
580 			       + (line * linesize)			\
581 			       + (x * bpp / 8));			\
582 	int col;							\
583 	const int RSS = 32 - (RSB + GSB + BSB);				\
584 	const int GSS = 32 - (GSB + BSB);				\
585 	const int BSS = 32 - (BSB);					\
586 	const uint32_t RSM = (~0U) << (32 - RSB);			\
587 	const uint32_t GSM = (~0U) << (32 - GSB);			\
588 	const uint32_t BSM = (~0U) << (32 - BSB);			\
589 	const int RDS = 32 - (RDB + GDB + BDB);				\
590 	const int GDS = 32 - (GDB + BDB);				\
591 	const int BDS = 32 - (BDB);					\
592 	const uint32_t RDM = (~0U) << (32 - RDB);			\
593 	const uint32_t GDM = (~0U) << (32 - GDB);			\
594 	const uint32_t BDM = (~0U) << (32 - BDB);			\
595 	for (col = x ; col < (x+w) ; col++) {				\
596 	    uint32_t spix = *src;					\
597 	    *dst = (((spix << RSS) & RSM & RDM) >> RDS) |		\
598 		(((spix << GSS) & GSM & GDM) >> GDS) |			\
599 		(((spix << BSS) & BSM & BDM) >> BDS);			\
600 	    src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8);	\
601 	    dst = (DST_T *) ((unsigned long) dst + bpp / 8);		\
602 	}								\
603     }
604 
605 
606 /*
607  * This copies data from the guest framebuffer region, into QEMU's
608  * displaysurface. qemu uses 16 or 32 bpp.  In case the pv framebuffer
609  * uses something else we must convert and copy, otherwise we can
610  * supply the buffer directly and no thing here.
611  */
612 static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
613 {
614     DisplaySurface *surface = qemu_console_surface(xenfb->con);
615     int line, oops = 0;
616     int bpp = surface_bits_per_pixel(surface);
617     int linesize = surface_stride(surface);
618     uint8_t *data = surface_data(surface);
619 
620     if (!is_buffer_shared(surface)) {
621         switch (xenfb->depth) {
622         case 8:
623             if (bpp == 16) {
624                 BLT(uint8_t, uint16_t,   3, 3, 2,   5, 6, 5);
625             } else if (bpp == 32) {
626                 BLT(uint8_t, uint32_t,   3, 3, 2,   8, 8, 8);
627             } else {
628                 oops = 1;
629             }
630             break;
631         case 24:
632             if (bpp == 16) {
633                 BLT(uint32_t, uint16_t,  8, 8, 8,   5, 6, 5);
634             } else if (bpp == 32) {
635                 BLT(uint32_t, uint32_t,  8, 8, 8,   8, 8, 8);
636             } else {
637                 oops = 1;
638             }
639             break;
640         default:
641             oops = 1;
642 	}
643     }
644     if (oops) /* should not happen */
645         xen_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
646                       __FUNCTION__, xenfb->depth, bpp);
647 
648     dpy_gfx_update(xenfb->con, x, y, w, h);
649 }
650 
651 #ifdef XENFB_TYPE_REFRESH_PERIOD
652 static int xenfb_queue_full(struct XenFB *xenfb)
653 {
654     struct xenfb_page *page = xenfb->c.page;
655     uint32_t cons, prod;
656 
657     if (!page)
658         return 1;
659 
660     prod = page->in_prod;
661     cons = page->in_cons;
662     return prod - cons == XENFB_IN_RING_LEN;
663 }
664 
665 static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
666 {
667     uint32_t prod;
668     struct xenfb_page *page = xenfb->c.page;
669 
670     prod = page->in_prod;
671     /* caller ensures !xenfb_queue_full() */
672     xen_mb();                   /* ensure ring space available */
673     XENFB_IN_RING_REF(page, prod) = *event;
674     xen_wmb();                  /* ensure ring contents visible */
675     page->in_prod = prod + 1;
676 
677     xen_pv_send_notify(&xenfb->c.xendev);
678 }
679 
680 static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
681 {
682     union xenfb_in_event event;
683 
684     memset(&event, 0, sizeof(event));
685     event.type = XENFB_TYPE_REFRESH_PERIOD;
686     event.refresh_period.period = period;
687     xenfb_send_event(xenfb, &event);
688 }
689 #endif
690 
691 /*
692  * Periodic update of display.
693  * Also transmit the refresh interval to the frontend.
694  *
695  * Never ever do any qemu display operations
696  * (resize, screen update) outside this function.
697  * Our screen might be inactive.  When asked for
698  * an update we know it is active.
699  */
700 static void xenfb_update(void *opaque)
701 {
702     struct XenFB *xenfb = opaque;
703     DisplaySurface *surface;
704     int i;
705 
706     if (xenfb->c.xendev.be_state != XenbusStateConnected)
707         return;
708 
709     if (!xenfb->feature_update) {
710         /* we don't get update notifications, thus use the
711          * sledge hammer approach ... */
712         xenfb->up_fullscreen = 1;
713     }
714 
715     /* resize if needed */
716     if (xenfb->do_resize) {
717         pixman_format_code_t format;
718 
719         xenfb->do_resize = 0;
720         switch (xenfb->depth) {
721         case 16:
722         case 32:
723             /* console.c supported depth -> buffer can be used directly */
724             format = qemu_default_pixman_format(xenfb->depth, true);
725             surface = qemu_create_displaysurface_from
726                 (xenfb->width, xenfb->height, format,
727                  xenfb->row_stride, xenfb->pixels + xenfb->offset);
728             break;
729         default:
730             /* we must convert stuff */
731             surface = qemu_create_displaysurface(xenfb->width, xenfb->height);
732             break;
733         }
734         dpy_gfx_replace_surface(xenfb->con, surface);
735         xen_pv_printf(&xenfb->c.xendev, 1,
736                       "update: resizing: %dx%d @ %d bpp%s\n",
737                       xenfb->width, xenfb->height, xenfb->depth,
738                       is_buffer_shared(surface) ? " (shared)" : "");
739         xenfb->up_fullscreen = 1;
740     }
741 
742     /* run queued updates */
743     if (xenfb->up_fullscreen) {
744         xen_pv_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
745         xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
746     } else if (xenfb->up_count) {
747         xen_pv_printf(&xenfb->c.xendev, 3, "update: %d rects\n",
748                       xenfb->up_count);
749         for (i = 0; i < xenfb->up_count; i++)
750             xenfb_guest_copy(xenfb,
751                              xenfb->up_rects[i].x,
752                              xenfb->up_rects[i].y,
753                              xenfb->up_rects[i].w,
754                              xenfb->up_rects[i].h);
755     } else {
756         xen_pv_printf(&xenfb->c.xendev, 3, "update: nothing\n");
757     }
758     xenfb->up_count = 0;
759     xenfb->up_fullscreen = 0;
760 }
761 
762 static void xenfb_update_interval(void *opaque, uint64_t interval)
763 {
764     struct XenFB *xenfb = opaque;
765 
766     if (xenfb->feature_update) {
767 #ifdef XENFB_TYPE_REFRESH_PERIOD
768         if (xenfb_queue_full(xenfb)) {
769             return;
770         }
771         xenfb_send_refresh_period(xenfb, interval);
772 #endif
773     }
774 }
775 
776 /* QEMU display state changed, so refresh the framebuffer copy */
777 static void xenfb_invalidate(void *opaque)
778 {
779     struct XenFB *xenfb = opaque;
780     xenfb->up_fullscreen = 1;
781 }
782 
783 static void xenfb_handle_events(struct XenFB *xenfb)
784 {
785     uint32_t prod, cons, out_cons;
786     struct xenfb_page *page = xenfb->c.page;
787 
788     prod = page->out_prod;
789     out_cons = page->out_cons;
790     if (prod - out_cons > XENFB_OUT_RING_LEN) {
791         return;
792     }
793     xen_rmb();		/* ensure we see ring contents up to prod */
794     for (cons = out_cons; cons != prod; cons++) {
795 	union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
796         uint8_t type = event->type;
797 	int x, y, w, h;
798 
799 	switch (type) {
800 	case XENFB_TYPE_UPDATE:
801 	    if (xenfb->up_count == UP_QUEUE)
802 		xenfb->up_fullscreen = 1;
803 	    if (xenfb->up_fullscreen)
804 		break;
805 	    x = MAX(event->update.x, 0);
806 	    y = MAX(event->update.y, 0);
807 	    w = MIN(event->update.width, xenfb->width - x);
808 	    h = MIN(event->update.height, xenfb->height - y);
809 	    if (w < 0 || h < 0) {
810                 xen_pv_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
811 		break;
812 	    }
813 	    if (x != event->update.x ||
814                 y != event->update.y ||
815 		w != event->update.width ||
816 		h != event->update.height) {
817                 xen_pv_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
818 	    }
819 	    if (w == xenfb->width && h > xenfb->height / 2) {
820 		/* scroll detector: updated more than 50% of the lines,
821 		 * don't bother keeping track of the rectangles then */
822 		xenfb->up_fullscreen = 1;
823 	    } else {
824 		xenfb->up_rects[xenfb->up_count].x = x;
825 		xenfb->up_rects[xenfb->up_count].y = y;
826 		xenfb->up_rects[xenfb->up_count].w = w;
827 		xenfb->up_rects[xenfb->up_count].h = h;
828 		xenfb->up_count++;
829 	    }
830 	    break;
831 #ifdef XENFB_TYPE_RESIZE
832 	case XENFB_TYPE_RESIZE:
833 	    if (xenfb_configure_fb(xenfb, xenfb->fb_len,
834 				   event->resize.width,
835 				   event->resize.height,
836 				   event->resize.depth,
837 				   xenfb->fb_len,
838 				   event->resize.offset,
839 				   event->resize.stride) < 0)
840 		break;
841 	    xenfb_invalidate(xenfb);
842 	    break;
843 #endif
844 	}
845     }
846     xen_mb();		/* ensure we're done with ring contents */
847     page->out_cons = cons;
848 }
849 
850 static int fb_init(struct XenDevice *xendev)
851 {
852 #ifdef XENFB_TYPE_RESIZE
853     xenstore_write_be_int(xendev, "feature-resize", 1);
854 #endif
855     return 0;
856 }
857 
858 static int fb_initialise(struct XenDevice *xendev)
859 {
860     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
861     struct xenfb_page *fb_page;
862     int videoram;
863     int rc;
864 
865     if (xenstore_read_fe_int(xendev, "videoram", &videoram) == -1)
866 	videoram = 0;
867 
868     rc = common_bind(&fb->c);
869     if (rc != 0)
870 	return rc;
871 
872     fb_page = fb->c.page;
873     rc = xenfb_configure_fb(fb, videoram * 1024 * 1024U,
874 			    fb_page->width, fb_page->height, fb_page->depth,
875 			    fb_page->mem_length, 0, fb_page->line_length);
876     if (rc != 0)
877 	return rc;
878 
879     rc = xenfb_map_fb(fb);
880     if (rc != 0)
881 	return rc;
882 
883     fb->con = graphic_console_init(NULL, 0, &xenfb_ops, fb);
884 
885     if (xenstore_read_fe_int(xendev, "feature-update", &fb->feature_update) == -1)
886 	fb->feature_update = 0;
887     if (fb->feature_update)
888 	xenstore_write_be_int(xendev, "request-update", 1);
889 
890     xen_pv_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
891 		  fb->feature_update, videoram);
892     return 0;
893 }
894 
895 static void fb_disconnect(struct XenDevice *xendev)
896 {
897     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
898 
899     /*
900      * FIXME: qemu can't un-init gfx display (yet?).
901      *   Replacing the framebuffer with anonymous shared memory
902      *   instead.  This releases the guest pages and keeps qemu happy.
903      */
904     xenforeignmemory_unmap(xen_fmem, fb->pixels, fb->fbpages);
905     fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
906                       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
907                       -1, 0);
908     if (fb->pixels == MAP_FAILED) {
909         xen_pv_printf(xendev, 0,
910                 "Couldn't replace the framebuffer with anonymous memory errno=%d\n",
911                 errno);
912     }
913     common_unbind(&fb->c);
914     fb->feature_update = 0;
915     fb->bug_trigger    = 0;
916 }
917 
918 static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
919 {
920     struct XenFB *fb = container_of(xendev, struct XenFB, c.xendev);
921 
922     /*
923      * Set state to Connected *again* once the frontend switched
924      * to connected.  We must trigger the watch a second time to
925      * workaround a frontend bug.
926      */
927     if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
928         xendev->fe_state == XenbusStateConnected &&
929         xendev->be_state == XenbusStateConnected) {
930         xen_pv_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
931         xen_be_set_state(xendev, XenbusStateConnected);
932         fb->bug_trigger = 1; /* only once */
933     }
934 }
935 
936 static void fb_event(struct XenDevice *xendev)
937 {
938     struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
939 
940     xenfb_handle_events(xenfb);
941     xen_pv_send_notify(&xenfb->c.xendev);
942 }
943 
944 /* -------------------------------------------------------------------- */
945 
946 struct XenDevOps xen_kbdmouse_ops = {
947     .size       = sizeof(struct XenInput),
948     .init       = input_init,
949     .initialise = input_initialise,
950     .connected  = input_connected,
951     .disconnect = input_disconnect,
952     .event      = input_event,
953 };
954 
955 struct XenDevOps xen_framebuffer_ops = {
956     .size       = sizeof(struct XenFB),
957     .init       = fb_init,
958     .initialise = fb_initialise,
959     .disconnect = fb_disconnect,
960     .event      = fb_event,
961     .frontend_changed = fb_frontend_changed,
962 };
963 
964 static const GraphicHwOps xenfb_ops = {
965     .invalidate  = xenfb_invalidate,
966     .gfx_update  = xenfb_update,
967     .update_interval = xenfb_update_interval,
968 };
969