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