These changes are the raw update to qemu-2.6.
[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 "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 }