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