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