vmware_vga.c 38.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * QEMU VMware-SVGA "chipset".
 *
 * Copyright (c) 2007 Andrzej Zaborowski  <balrog@zabor.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
P
Peter Maydell 已提交
24
#include "qemu/osdep.h"
25
#include "qemu/units.h"
26
#include "qapi/error.h"
27 28
#include "hw/hw.h"
#include "hw/loader.h"
29
#include "trace.h"
30
#include "ui/vnc.h"
31
#include "hw/pci/pci.h"
32

J
Jan Kiszka 已提交
33
#undef VERBOSE
34 35 36 37
#define HW_RECT_ACCEL
#define HW_FILL_ACCEL
#define HW_MOUSE_ACCEL

38
#include "vga_int.h"
39 40

/* See http://vmware-svga.sf.net/ for some documentation on VMWare SVGA */
41 42

struct vmsvga_state_s {
43
    VGACommonState vga;
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

    int invalidated;
    int enable;
    int config;
    struct {
        int id;
        int x;
        int y;
        int on;
    } cursor;

    int index;
    int scratch_size;
    uint32_t *scratch;
    int new_width;
    int new_height;
60
    int new_depth;
61 62 63 64
    uint32_t guest;
    uint32_t svgaid;
    int syncing;

65
    MemoryRegion fifo_ram;
66 67 68
    uint8_t *fifo_ptr;
    unsigned int fifo_size;

G
Gerd Hoffmann 已提交
69 70 71 72 73
    uint32_t *fifo;
    uint32_t fifo_min;
    uint32_t fifo_max;
    uint32_t fifo_next;
    uint32_t fifo_stop;
74

B
BALATON Zoltan 已提交
75
#define REDRAW_FIFO_LEN  512
76 77 78 79 80 81
    struct vmsvga_rect_s {
        int x, y, w, h;
    } redraw_fifo[REDRAW_FIFO_LEN];
    int redraw_fifo_first, redraw_fifo_last;
};

82 83 84 85 86
#define TYPE_VMWARE_SVGA "vmware-svga"

#define VMWARE_SVGA(obj) \
    OBJECT_CHECK(struct pci_vmsvga_state_s, (obj), TYPE_VMWARE_SVGA)

87
struct pci_vmsvga_state_s {
88 89 90 91
    /*< private >*/
    PCIDevice parent_obj;
    /*< public >*/

92
    struct vmsvga_state_s chip;
93
    MemoryRegion io_bar;
94 95
};

B
BALATON Zoltan 已提交
96 97 98 99 100
#define SVGA_MAGIC              0x900000UL
#define SVGA_MAKE_ID(ver)       (SVGA_MAGIC << 8 | (ver))
#define SVGA_ID_0               SVGA_MAKE_ID(0)
#define SVGA_ID_1               SVGA_MAKE_ID(1)
#define SVGA_ID_2               SVGA_MAKE_ID(2)
101

B
BALATON Zoltan 已提交
102 103 104 105
#define SVGA_LEGACY_BASE_PORT   0x4560
#define SVGA_INDEX_PORT         0x0
#define SVGA_VALUE_PORT         0x1
#define SVGA_BIOS_PORT          0x2
106 107 108 109

#define SVGA_VERSION_2

#ifdef SVGA_VERSION_2
B
BALATON Zoltan 已提交
110 111 112 113 114
# define SVGA_ID                SVGA_ID_2
# define SVGA_IO_BASE           SVGA_LEGACY_BASE_PORT
# define SVGA_IO_MUL            1
# define SVGA_FIFO_SIZE         0x10000
# define SVGA_PCI_DEVICE_ID     PCI_DEVICE_ID_VMWARE_SVGA2
115
#else
B
BALATON Zoltan 已提交
116 117 118 119 120
# define SVGA_ID                SVGA_ID_1
# define SVGA_IO_BASE           SVGA_LEGACY_BASE_PORT
# define SVGA_IO_MUL            4
# define SVGA_FIFO_SIZE         0x10000
# define SVGA_PCI_DEVICE_ID     PCI_DEVICE_ID_VMWARE_SVGA
121 122 123 124 125 126 127 128 129 130 131
#endif

enum {
    /* ID 0, 1 and 2 registers */
    SVGA_REG_ID = 0,
    SVGA_REG_ENABLE = 1,
    SVGA_REG_WIDTH = 2,
    SVGA_REG_HEIGHT = 3,
    SVGA_REG_MAX_WIDTH = 4,
    SVGA_REG_MAX_HEIGHT = 5,
    SVGA_REG_DEPTH = 6,
B
BALATON Zoltan 已提交
132
    SVGA_REG_BITS_PER_PIXEL = 7,        /* Current bpp in the guest */
133 134 135 136 137 138 139 140 141 142 143 144
    SVGA_REG_PSEUDOCOLOR = 8,
    SVGA_REG_RED_MASK = 9,
    SVGA_REG_GREEN_MASK = 10,
    SVGA_REG_BLUE_MASK = 11,
    SVGA_REG_BYTES_PER_LINE = 12,
    SVGA_REG_FB_START = 13,
    SVGA_REG_FB_OFFSET = 14,
    SVGA_REG_VRAM_SIZE = 15,
    SVGA_REG_FB_SIZE = 16,

    /* ID 1 and 2 registers */
    SVGA_REG_CAPABILITIES = 17,
B
BALATON Zoltan 已提交
145
    SVGA_REG_MEM_START = 18,            /* Memory for command FIFO */
146
    SVGA_REG_MEM_SIZE = 19,
B
BALATON Zoltan 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
    SVGA_REG_CONFIG_DONE = 20,          /* Set when memory area configured */
    SVGA_REG_SYNC = 21,                 /* Write to force synchronization */
    SVGA_REG_BUSY = 22,                 /* Read to check if sync is done */
    SVGA_REG_GUEST_ID = 23,             /* Set guest OS identifier */
    SVGA_REG_CURSOR_ID = 24,            /* ID of cursor */
    SVGA_REG_CURSOR_X = 25,             /* Set cursor X position */
    SVGA_REG_CURSOR_Y = 26,             /* Set cursor Y position */
    SVGA_REG_CURSOR_ON = 27,            /* Turn cursor on/off */
    SVGA_REG_HOST_BITS_PER_PIXEL = 28,  /* Current bpp in the host */
    SVGA_REG_SCRATCH_SIZE = 29,         /* Number of scratch registers */
    SVGA_REG_MEM_REGS = 30,             /* Number of FIFO registers */
    SVGA_REG_NUM_DISPLAYS = 31,         /* Number of guest displays */
    SVGA_REG_PITCHLOCK = 32,            /* Fixed pitch for all modes */

    SVGA_PALETTE_BASE = 1024,           /* Base of SVGA color map */
162 163 164 165
    SVGA_PALETTE_END  = SVGA_PALETTE_BASE + 767,
    SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + 768,
};

B
BALATON Zoltan 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
#define SVGA_CAP_NONE                   0
#define SVGA_CAP_RECT_FILL              (1 << 0)
#define SVGA_CAP_RECT_COPY              (1 << 1)
#define SVGA_CAP_RECT_PAT_FILL          (1 << 2)
#define SVGA_CAP_LEGACY_OFFSCREEN       (1 << 3)
#define SVGA_CAP_RASTER_OP              (1 << 4)
#define SVGA_CAP_CURSOR                 (1 << 5)
#define SVGA_CAP_CURSOR_BYPASS          (1 << 6)
#define SVGA_CAP_CURSOR_BYPASS_2        (1 << 7)
#define SVGA_CAP_8BIT_EMULATION         (1 << 8)
#define SVGA_CAP_ALPHA_CURSOR           (1 << 9)
#define SVGA_CAP_GLYPH                  (1 << 10)
#define SVGA_CAP_GLYPH_CLIPPING         (1 << 11)
#define SVGA_CAP_OFFSCREEN_1            (1 << 12)
#define SVGA_CAP_ALPHA_BLEND            (1 << 13)
#define SVGA_CAP_3D                     (1 << 14)
#define SVGA_CAP_EXTENDED_FIFO          (1 << 15)
#define SVGA_CAP_MULTIMON               (1 << 16)
#define SVGA_CAP_PITCHLOCK              (1 << 17)
185 186 187 188 189 190 191 192 193

/*
 * FIFO offsets (seen as an array of 32-bit words)
 */
enum {
    /*
     * The original defined FIFO offsets
     */
    SVGA_FIFO_MIN = 0,
B
BALATON Zoltan 已提交
194
    SVGA_FIFO_MAX,      /* The distance from MIN to MAX must be at least 10K */
G
Gerd Hoffmann 已提交
195
    SVGA_FIFO_NEXT,
196 197 198 199 200 201 202 203 204 205 206 207
    SVGA_FIFO_STOP,

    /*
     * Additional offsets added as of SVGA_CAP_EXTENDED_FIFO
     */
    SVGA_FIFO_CAPABILITIES = 4,
    SVGA_FIFO_FLAGS,
    SVGA_FIFO_FENCE,
    SVGA_FIFO_3D_HWVERSION,
    SVGA_FIFO_PITCHLOCK,
};

B
BALATON Zoltan 已提交
208 209 210 211
#define SVGA_FIFO_CAP_NONE              0
#define SVGA_FIFO_CAP_FENCE             (1 << 0)
#define SVGA_FIFO_CAP_ACCELFRONT        (1 << 1)
#define SVGA_FIFO_CAP_PITCHLOCK         (1 << 2)
212

B
BALATON Zoltan 已提交
213 214
#define SVGA_FIFO_FLAG_NONE             0
#define SVGA_FIFO_FLAG_ACCELFRONT       (1 << 0)
215 216

/* These values can probably be changed arbitrarily.  */
B
BALATON Zoltan 已提交
217
#define SVGA_SCRATCH_SIZE               0x8000
218
#define SVGA_MAX_WIDTH                  ROUND_UP(2360, VNC_DIRTY_PIXELS_PER_BIT)
B
BALATON Zoltan 已提交
219
#define SVGA_MAX_HEIGHT                 1770
220 221

#ifdef VERBOSE
B
BALATON Zoltan 已提交
222
# define GUEST_OS_BASE          0x5001
223
static const char *vmsvga_guest_id[] = {
224 225 226 227 228 229 230 231 232
    [0x00] = "Dos",
    [0x01] = "Windows 3.1",
    [0x02] = "Windows 95",
    [0x03] = "Windows 98",
    [0x04] = "Windows ME",
    [0x05] = "Windows NT",
    [0x06] = "Windows 2000",
    [0x07] = "Linux",
    [0x08] = "OS/2",
233
    [0x09] = "an unknown OS",
234 235
    [0x0a] = "BSD",
    [0x0b] = "Whistler",
236 237 238 239 240 241 242 243 244
    [0x0c] = "an unknown OS",
    [0x0d] = "an unknown OS",
    [0x0e] = "an unknown OS",
    [0x0f] = "an unknown OS",
    [0x10] = "an unknown OS",
    [0x11] = "an unknown OS",
    [0x12] = "an unknown OS",
    [0x13] = "an unknown OS",
    [0x14] = "an unknown OS",
245
    [0x15] = "Windows 2003",
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
};
#endif

enum {
    SVGA_CMD_INVALID_CMD = 0,
    SVGA_CMD_UPDATE = 1,
    SVGA_CMD_RECT_FILL = 2,
    SVGA_CMD_RECT_COPY = 3,
    SVGA_CMD_DEFINE_BITMAP = 4,
    SVGA_CMD_DEFINE_BITMAP_SCANLINE = 5,
    SVGA_CMD_DEFINE_PIXMAP = 6,
    SVGA_CMD_DEFINE_PIXMAP_SCANLINE = 7,
    SVGA_CMD_RECT_BITMAP_FILL = 8,
    SVGA_CMD_RECT_PIXMAP_FILL = 9,
    SVGA_CMD_RECT_BITMAP_COPY = 10,
    SVGA_CMD_RECT_PIXMAP_COPY = 11,
    SVGA_CMD_FREE_OBJECT = 12,
    SVGA_CMD_RECT_ROP_FILL = 13,
    SVGA_CMD_RECT_ROP_COPY = 14,
    SVGA_CMD_RECT_ROP_BITMAP_FILL = 15,
    SVGA_CMD_RECT_ROP_PIXMAP_FILL = 16,
    SVGA_CMD_RECT_ROP_BITMAP_COPY = 17,
    SVGA_CMD_RECT_ROP_PIXMAP_COPY = 18,
    SVGA_CMD_DEFINE_CURSOR = 19,
    SVGA_CMD_DISPLAY_CURSOR = 20,
    SVGA_CMD_MOVE_CURSOR = 21,
    SVGA_CMD_DEFINE_ALPHA_CURSOR = 22,
    SVGA_CMD_DRAW_GLYPH = 23,
    SVGA_CMD_DRAW_GLYPH_CLIPPED = 24,
    SVGA_CMD_UPDATE_VERBOSE = 25,
    SVGA_CMD_SURFACE_FILL = 26,
    SVGA_CMD_SURFACE_COPY = 27,
    SVGA_CMD_SURFACE_ALPHA_BLEND = 28,
    SVGA_CMD_FRONT_ROP_FILL = 29,
    SVGA_CMD_FENCE = 30,
};

/* Legal values for the SVGA_REG_CURSOR_ON register in cursor bypass mode */
enum {
    SVGA_CURSOR_ON_HIDE = 0,
    SVGA_CURSOR_ON_SHOW = 1,
    SVGA_CURSOR_ON_REMOVE_FROM_FB = 2,
    SVGA_CURSOR_ON_RESTORE_TO_FB = 3,
};

G
Gerd Hoffmann 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
static inline bool vmsvga_verify_rect(DisplaySurface *surface,
                                      const char *name,
                                      int x, int y, int w, int h)
{
    if (x < 0) {
        fprintf(stderr, "%s: x was < 0 (%d)\n", name, x);
        return false;
    }
    if (x > SVGA_MAX_WIDTH) {
        fprintf(stderr, "%s: x was > %d (%d)\n", name, SVGA_MAX_WIDTH, x);
        return false;
    }
    if (w < 0) {
        fprintf(stderr, "%s: w was < 0 (%d)\n", name, w);
        return false;
    }
    if (w > SVGA_MAX_WIDTH) {
        fprintf(stderr, "%s: w was > %d (%d)\n", name, SVGA_MAX_WIDTH, w);
        return false;
    }
    if (x + w > surface_width(surface)) {
        fprintf(stderr, "%s: width was > %d (x: %d, w: %d)\n",
                name, surface_width(surface), x, w);
        return false;
    }

    if (y < 0) {
        fprintf(stderr, "%s: y was < 0 (%d)\n", name, y);
        return false;
    }
    if (y > SVGA_MAX_HEIGHT) {
        fprintf(stderr, "%s: y was > %d (%d)\n", name, SVGA_MAX_HEIGHT, y);
        return false;
    }
    if (h < 0) {
        fprintf(stderr, "%s: h was < 0 (%d)\n", name, h);
        return false;
    }
    if (h > SVGA_MAX_HEIGHT) {
        fprintf(stderr, "%s: h was > %d (%d)\n", name, SVGA_MAX_HEIGHT, h);
        return false;
    }
    if (y + h > surface_height(surface)) {
        fprintf(stderr, "%s: update height > %d (y: %d, h: %d)\n",
                name, surface_height(surface), y, h);
        return false;
    }

    return true;
}

342
static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
G
Gerd Hoffmann 已提交
343
                                      int x, int y, int w, int h)
344
{
345
    DisplaySurface *surface = qemu_console_surface(s->vga.con);
346 347 348 349 350 351 352
    int line;
    int bypl;
    int width;
    int start;
    uint8_t *src;
    uint8_t *dst;

353 354
    if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
        /* go for a fullscreen update as fallback */
355 356
        x = 0;
        y = 0;
357 358
        w = surface_width(surface);
        h = surface_height(surface);
359 360
    }

361 362 363
    bypl = surface_stride(surface);
    width = surface_bytes_per_pixel(surface) * w;
    start = surface_bytes_per_pixel(surface) * x + bypl * y;
364
    src = s->vga.vram_ptr + start;
365
    dst = surface_data(surface) + start;
366

B
BALATON Zoltan 已提交
367
    for (line = h; line > 0; line--, src += bypl, dst += bypl) {
368
        memcpy(dst, src, width);
B
BALATON Zoltan 已提交
369
    }
370
    dpy_gfx_update(s->vga.con, x, y, w, h);
371 372 373 374 375
}

static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
                int x, int y, int w, int h)
{
B
BALATON Zoltan 已提交
376 377
    struct vmsvga_rect_s *rect = &s->redraw_fifo[s->redraw_fifo_last++];

378 379 380 381 382 383 384 385 386 387
    s->redraw_fifo_last &= REDRAW_FIFO_LEN - 1;
    rect->x = x;
    rect->y = y;
    rect->w = w;
    rect->h = h;
}

static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
{
    struct vmsvga_rect_s *rect;
B
BALATON Zoltan 已提交
388

389 390 391 392 393 394 395
    if (s->invalidated) {
        s->redraw_fifo_first = s->redraw_fifo_last;
        return;
    }
    /* Overlapping region updates can be optimised out here - if someone
     * knows a smart algorithm to do that, please share.  */
    while (s->redraw_fifo_first != s->redraw_fifo_last) {
B
BALATON Zoltan 已提交
396
        rect = &s->redraw_fifo[s->redraw_fifo_first++];
397 398 399 400 401 402
        s->redraw_fifo_first &= REDRAW_FIFO_LEN - 1;
        vmsvga_update_rect(s, rect->x, rect->y, rect->w, rect->h);
    }
}

#ifdef HW_RECT_ACCEL
403
static inline int vmsvga_copy_rect(struct vmsvga_state_s *s,
404 405
                int x0, int y0, int x1, int y1, int w, int h)
{
406
    DisplaySurface *surface = qemu_console_surface(s->vga.con);
407
    uint8_t *vram = s->vga.vram_ptr;
408 409
    int bypl = surface_stride(surface);
    int bypp = surface_bytes_per_pixel(surface);
410
    int width = bypp * w;
411 412 413
    int line = h;
    uint8_t *ptr[2];

414 415 416 417 418 419 420
    if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/src", x0, y0, w, h)) {
        return -1;
    }
    if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/dst", x1, y1, w, h)) {
        return -1;
    }

421
    if (y1 > y0) {
422 423
        ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1);
        ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1);
424 425 426 427
        for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) {
            memmove(ptr[1], ptr[0], width);
        }
    } else {
428 429
        ptr[0] = vram + bypp * x0 + bypl * y0;
        ptr[1] = vram + bypp * x1 + bypl * y1;
430 431
        for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) {
            memmove(ptr[1], ptr[0], width);
432 433 434 435
        }
    }

    vmsvga_update_rect_delayed(s, x1, y1, w, h);
436
    return 0;
437 438 439 440
}
#endif

#ifdef HW_FILL_ACCEL
441
static inline int vmsvga_fill_rect(struct vmsvga_state_s *s,
442 443
                uint32_t c, int x, int y, int w, int h)
{
444 445 446
    DisplaySurface *surface = qemu_console_surface(s->vga.con);
    int bypl = surface_stride(surface);
    int width = surface_bytes_per_pixel(surface) * w;
447 448
    int line = h;
    int column;
449
    uint8_t *fst;
450 451 452 453
    uint8_t *dst;
    uint8_t *src;
    uint8_t col[4];

454 455 456 457
    if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) {
        return -1;
    }

458 459 460 461 462
    col[0] = c;
    col[1] = c >> 8;
    col[2] = c >> 16;
    col[3] = c >> 24;

463
    fst = s->vga.vram_ptr + surface_bytes_per_pixel(surface) * x + bypl * y;
464

465 466 467 468 469
    if (line--) {
        dst = fst;
        src = col;
        for (column = width; column > 0; column--) {
            *(dst++) = *(src++);
470
            if (src - col == surface_bytes_per_pixel(surface)) {
471
                src = col;
472 473
            }
        }
474 475 476 477 478
        dst = fst;
        for (; line > 0; line--) {
            dst += bypl;
            memcpy(dst, fst, width);
        }
479 480 481
    }

    vmsvga_update_rect_delayed(s, x, y, w, h);
482
    return 0;
483 484 485 486
}
#endif

struct vmsvga_cursor_definition_s {
G
Gerd Hoffmann 已提交
487 488
    uint32_t width;
    uint32_t height;
489
    int id;
G
Gerd Hoffmann 已提交
490
    uint32_t bpp;
491 492 493
    int hot_x;
    int hot_y;
    uint32_t mask[1024];
D
Dave Airlie 已提交
494
    uint32_t image[4096];
495 496
};

B
BALATON Zoltan 已提交
497 498
#define SVGA_BITMAP_SIZE(w, h)          ((((w) + 31) >> 5) * (h))
#define SVGA_PIXMAP_SIZE(w, h, bpp)     (((((w) * (bpp)) + 31) >> 5) * (h))
499 500 501 502 503

#ifdef HW_MOUSE_ACCEL
static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,
                struct vmsvga_cursor_definition_s *c)
{
504 505 506 507 508 509 510 511
    QEMUCursor *qc;
    int i, pixels;

    qc = cursor_alloc(c->width, c->height);
    qc->hot_x = c->hot_x;
    qc->hot_y = c->hot_y;
    switch (c->bpp) {
    case 1:
B
BALATON Zoltan 已提交
512 513
        cursor_set_mono(qc, 0xffffff, 0x000000, (void *)c->image,
                        1, (void *)c->mask);
514 515 516 517 518 519
#ifdef DEBUG
        cursor_print_ascii_art(qc, "vmware/mono");
#endif
        break;
    case 32:
        /* fill alpha channel from mask, set color to zero */
B
BALATON Zoltan 已提交
520 521
        cursor_set_mono(qc, 0x000000, 0x000000, (void *)c->mask,
                        1, (void *)c->mask);
522 523 524 525 526 527 528 529 530 531 532
        /* add in rgb values */
        pixels = c->width * c->height;
        for (i = 0; i < pixels; i++) {
            qc->data[i] |= c->image[i] & 0xffffff;
        }
#ifdef DEBUG
        cursor_print_ascii_art(qc, "vmware/32bit");
#endif
        break;
    default:
        fprintf(stderr, "%s: unhandled bpp %d, using fallback cursor\n",
B
BALATON Zoltan 已提交
533
                __func__, c->bpp);
534 535 536
        cursor_put(qc);
        qc = cursor_builtin_left_ptr();
    }
537

538
    dpy_cursor_define(s->vga.con, qc);
539
    cursor_put(qc);
540 541 542
}
#endif

543
static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
544
{
545
    int num;
B
BALATON Zoltan 已提交
546 547

    if (!s->config || !s->enable) {
548
        return 0;
B
BALATON Zoltan 已提交
549
    }
550

G
Gerd Hoffmann 已提交
551 552 553 554 555
    s->fifo_min  = le32_to_cpu(s->fifo[SVGA_FIFO_MIN]);
    s->fifo_max  = le32_to_cpu(s->fifo[SVGA_FIFO_MAX]);
    s->fifo_next = le32_to_cpu(s->fifo[SVGA_FIFO_NEXT]);
    s->fifo_stop = le32_to_cpu(s->fifo[SVGA_FIFO_STOP]);

556
    /* Check range and alignment.  */
G
Gerd Hoffmann 已提交
557
    if ((s->fifo_min | s->fifo_max | s->fifo_next | s->fifo_stop) & 3) {
558 559
        return 0;
    }
G
Gerd Hoffmann 已提交
560
    if (s->fifo_min < sizeof(uint32_t) * 4) {
561 562
        return 0;
    }
G
Gerd Hoffmann 已提交
563 564 565 566
    if (s->fifo_max > SVGA_FIFO_SIZE ||
        s->fifo_min >= SVGA_FIFO_SIZE ||
        s->fifo_stop >= SVGA_FIFO_SIZE ||
        s->fifo_next >= SVGA_FIFO_SIZE) {
567 568
        return 0;
    }
569
    if (s->fifo_max < s->fifo_min + 10 * KiB) {
570 571 572
        return 0;
    }

G
Gerd Hoffmann 已提交
573
    num = s->fifo_next - s->fifo_stop;
B
BALATON Zoltan 已提交
574
    if (num < 0) {
G
Gerd Hoffmann 已提交
575
        num += s->fifo_max - s->fifo_min;
B
BALATON Zoltan 已提交
576
    }
577
    return num >> 2;
578 579
}

580
static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
581
{
G
Gerd Hoffmann 已提交
582
    uint32_t cmd = s->fifo[s->fifo_stop >> 2];
B
BALATON Zoltan 已提交
583

G
Gerd Hoffmann 已提交
584 585 586
    s->fifo_stop += 4;
    if (s->fifo_stop >= s->fifo_max) {
        s->fifo_stop = s->fifo_min;
B
BALATON Zoltan 已提交
587
    }
G
Gerd Hoffmann 已提交
588
    s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop);
589 590 591
    return cmd;
}

592 593 594 595 596
static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s)
{
    return le32_to_cpu(vmsvga_fifo_read_raw(s));
}

597 598 599
static void vmsvga_fifo_run(struct vmsvga_state_s *s)
{
    uint32_t cmd, colour;
600
    int args, len, maxloop = 1024;
601 602
    int x, y, dx, dy, width, height;
    struct vmsvga_cursor_definition_s cursor;
603 604 605
    uint32_t cmd_start;

    len = vmsvga_fifo_length(s);
606
    while (len > 0 && --maxloop > 0) {
607
        /* May need to go back to the start of the command if incomplete */
G
Gerd Hoffmann 已提交
608
        cmd_start = s->fifo_stop;
609

610 611 612
        switch (cmd = vmsvga_fifo_read(s)) {
        case SVGA_CMD_UPDATE:
        case SVGA_CMD_UPDATE_VERBOSE:
613
            len -= 5;
B
BALATON Zoltan 已提交
614
            if (len < 0) {
615
                goto rewind;
B
BALATON Zoltan 已提交
616
            }
617

618 619 620 621 622 623 624 625
            x = vmsvga_fifo_read(s);
            y = vmsvga_fifo_read(s);
            width = vmsvga_fifo_read(s);
            height = vmsvga_fifo_read(s);
            vmsvga_update_rect_delayed(s, x, y, width, height);
            break;

        case SVGA_CMD_RECT_FILL:
626
            len -= 6;
B
BALATON Zoltan 已提交
627
            if (len < 0) {
628
                goto rewind;
B
BALATON Zoltan 已提交
629
            }
630

631 632 633 634 635 636
            colour = vmsvga_fifo_read(s);
            x = vmsvga_fifo_read(s);
            y = vmsvga_fifo_read(s);
            width = vmsvga_fifo_read(s);
            height = vmsvga_fifo_read(s);
#ifdef HW_FILL_ACCEL
637 638 639 640
            if (vmsvga_fill_rect(s, colour, x, y, width, height) == 0) {
                break;
            }
#endif
641
            args = 0;
642 643 644
            goto badcmd;

        case SVGA_CMD_RECT_COPY:
645
            len -= 7;
B
BALATON Zoltan 已提交
646
            if (len < 0) {
647
                goto rewind;
B
BALATON Zoltan 已提交
648
            }
649

650 651 652 653 654 655 656
            x = vmsvga_fifo_read(s);
            y = vmsvga_fifo_read(s);
            dx = vmsvga_fifo_read(s);
            dy = vmsvga_fifo_read(s);
            width = vmsvga_fifo_read(s);
            height = vmsvga_fifo_read(s);
#ifdef HW_RECT_ACCEL
657 658 659 660
            if (vmsvga_copy_rect(s, x, y, dx, dy, width, height) == 0) {
                break;
            }
#endif
661
            args = 0;
662 663 664
            goto badcmd;

        case SVGA_CMD_DEFINE_CURSOR:
665
            len -= 8;
B
BALATON Zoltan 已提交
666
            if (len < 0) {
667
                goto rewind;
B
BALATON Zoltan 已提交
668
            }
669

670 671 672 673 674 675 676
            cursor.id = vmsvga_fifo_read(s);
            cursor.hot_x = vmsvga_fifo_read(s);
            cursor.hot_y = vmsvga_fifo_read(s);
            cursor.width = x = vmsvga_fifo_read(s);
            cursor.height = y = vmsvga_fifo_read(s);
            vmsvga_fifo_read(s);
            cursor.bpp = vmsvga_fifo_read(s);
677

678
            args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
679 680 681
            if (cursor.width > 256
                || cursor.height > 256
                || cursor.bpp > 32
682
                || SVGA_BITMAP_SIZE(x, y) > ARRAY_SIZE(cursor.mask)
683
                || SVGA_PIXMAP_SIZE(x, y, cursor.bpp)
684
                    > ARRAY_SIZE(cursor.image)) {
685
                    goto badcmd;
B
BALATON Zoltan 已提交
686
            }
687 688

            len -= args;
B
BALATON Zoltan 已提交
689
            if (len < 0) {
690
                goto rewind;
B
BALATON Zoltan 已提交
691
            }
692

B
BALATON Zoltan 已提交
693
            for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args++) {
694
                cursor.mask[args] = vmsvga_fifo_read_raw(s);
B
BALATON Zoltan 已提交
695 696
            }
            for (args = 0; args < SVGA_PIXMAP_SIZE(x, y, cursor.bpp); args++) {
697
                cursor.image[args] = vmsvga_fifo_read_raw(s);
B
BALATON Zoltan 已提交
698
            }
699 700 701 702 703 704 705 706 707 708 709 710 711
#ifdef HW_MOUSE_ACCEL
            vmsvga_cursor_define(s, &cursor);
            break;
#else
            args = 0;
            goto badcmd;
#endif

        /*
         * Other commands that we at least know the number of arguments
         * for so we can avoid FIFO desync if driver uses them illegally.
         */
        case SVGA_CMD_DEFINE_ALPHA_CURSOR:
712
            len -= 6;
B
BALATON Zoltan 已提交
713
            if (len < 0) {
714
                goto rewind;
B
BALATON Zoltan 已提交
715
            }
716 717 718 719 720 721 722 723 724 725 726 727 728 729
            vmsvga_fifo_read(s);
            vmsvga_fifo_read(s);
            vmsvga_fifo_read(s);
            x = vmsvga_fifo_read(s);
            y = vmsvga_fifo_read(s);
            args = x * y;
            goto badcmd;
        case SVGA_CMD_RECT_ROP_FILL:
            args = 6;
            goto badcmd;
        case SVGA_CMD_RECT_ROP_COPY:
            args = 7;
            goto badcmd;
        case SVGA_CMD_DRAW_GLYPH_CLIPPED:
730
            len -= 4;
B
BALATON Zoltan 已提交
731
            if (len < 0) {
732
                goto rewind;
B
BALATON Zoltan 已提交
733
            }
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
            vmsvga_fifo_read(s);
            vmsvga_fifo_read(s);
            args = 7 + (vmsvga_fifo_read(s) >> 2);
            goto badcmd;
        case SVGA_CMD_SURFACE_ALPHA_BLEND:
            args = 12;
            goto badcmd;

        /*
         * Other commands that are not listed as depending on any
         * CAPABILITIES bits, but are not described in the README either.
         */
        case SVGA_CMD_SURFACE_FILL:
        case SVGA_CMD_SURFACE_COPY:
        case SVGA_CMD_FRONT_ROP_FILL:
        case SVGA_CMD_FENCE:
        case SVGA_CMD_INVALID_CMD:
            break; /* Nop */

        default:
754
            args = 0;
755
        badcmd:
756
            len -= args;
B
BALATON Zoltan 已提交
757
            if (len < 0) {
758
                goto rewind;
B
BALATON Zoltan 已提交
759 760
            }
            while (args--) {
761
                vmsvga_fifo_read(s);
B
BALATON Zoltan 已提交
762
            }
763
            printf("%s: Unknown command 0x%02x in SVGA command FIFO\n",
B
BALATON Zoltan 已提交
764
                   __func__, cmd);
765
            break;
766 767

        rewind:
G
Gerd Hoffmann 已提交
768 769
            s->fifo_stop = cmd_start;
            s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop);
770
            break;
771
        }
772
    }
773 774 775 776 777 778

    s->syncing = 0;
}

static uint32_t vmsvga_index_read(void *opaque, uint32_t address)
{
779
    struct vmsvga_state_s *s = opaque;
B
BALATON Zoltan 已提交
780

781 782 783 784 785
    return s->index;
}

static void vmsvga_index_write(void *opaque, uint32_t address, uint32_t index)
{
786
    struct vmsvga_state_s *s = opaque;
B
BALATON Zoltan 已提交
787

788 789 790 791 792 793
    s->index = index;
}

static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
{
    uint32_t caps;
794
    struct vmsvga_state_s *s = opaque;
795
    DisplaySurface *surface = qemu_console_surface(s->vga.con);
796
    PixelFormat pf;
797
    uint32_t ret;
B
BALATON Zoltan 已提交
798

799 800
    switch (s->index) {
    case SVGA_REG_ID:
801 802
        ret = s->svgaid;
        break;
803 804

    case SVGA_REG_ENABLE:
805 806
        ret = s->enable;
        break;
807 808

    case SVGA_REG_WIDTH:
809
        ret = s->new_width ? s->new_width : surface_width(surface);
810
        break;
811 812

    case SVGA_REG_HEIGHT:
813
        ret = s->new_height ? s->new_height : surface_height(surface);
814
        break;
815 816

    case SVGA_REG_MAX_WIDTH:
817 818
        ret = SVGA_MAX_WIDTH;
        break;
819 820

    case SVGA_REG_MAX_HEIGHT:
821 822
        ret = SVGA_MAX_HEIGHT;
        break;
823 824

    case SVGA_REG_DEPTH:
825
        ret = (s->new_depth == 32) ? 24 : s->new_depth;
826
        break;
827 828

    case SVGA_REG_BITS_PER_PIXEL:
829 830
    case SVGA_REG_HOST_BITS_PER_PIXEL:
        ret = s->new_depth;
831
        break;
832 833

    case SVGA_REG_PSEUDOCOLOR:
834 835
        ret = 0x0;
        break;
836 837

    case SVGA_REG_RED_MASK:
838 839
        pf = qemu_default_pixelformat(s->new_depth);
        ret = pf.rmask;
840
        break;
841

842
    case SVGA_REG_GREEN_MASK:
843 844
        pf = qemu_default_pixelformat(s->new_depth);
        ret = pf.gmask;
845
        break;
846

847
    case SVGA_REG_BLUE_MASK:
848 849
        pf = qemu_default_pixelformat(s->new_depth);
        ret = pf.bmask;
850
        break;
851 852

    case SVGA_REG_BYTES_PER_LINE:
853 854 855 856 857
        if (s->new_width) {
            ret = (s->new_depth * s->new_width) / 8;
        } else {
            ret = surface_stride(surface);
        }
858
        break;
859

860 861 862
    case SVGA_REG_FB_START: {
        struct pci_vmsvga_state_s *pci_vmsvga
            = container_of(s, struct pci_vmsvga_state_s, chip);
863
        ret = pci_get_bar_addr(PCI_DEVICE(pci_vmsvga), 1);
864
        break;
865
    }
866 867

    case SVGA_REG_FB_OFFSET:
868 869
        ret = 0x0;
        break;
870 871

    case SVGA_REG_VRAM_SIZE:
872 873
        ret = s->vga.vram_size; /* No physical VRAM besides the framebuffer */
        break;
874 875

    case SVGA_REG_FB_SIZE:
876 877
        ret = s->vga.vram_size;
        break;
878 879 880 881 882 883 884 885 886 887

    case SVGA_REG_CAPABILITIES:
        caps = SVGA_CAP_NONE;
#ifdef HW_RECT_ACCEL
        caps |= SVGA_CAP_RECT_COPY;
#endif
#ifdef HW_FILL_ACCEL
        caps |= SVGA_CAP_RECT_FILL;
#endif
#ifdef HW_MOUSE_ACCEL
888
        if (dpy_cursor_define_supported(s->vga.con)) {
889 890
            caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
                    SVGA_CAP_CURSOR_BYPASS;
891
        }
892
#endif
893 894
        ret = caps;
        break;
895

896 897 898
    case SVGA_REG_MEM_START: {
        struct pci_vmsvga_state_s *pci_vmsvga
            = container_of(s, struct pci_vmsvga_state_s, chip);
899
        ret = pci_get_bar_addr(PCI_DEVICE(pci_vmsvga), 2);
900
        break;
901
    }
902 903

    case SVGA_REG_MEM_SIZE:
904 905
        ret = s->fifo_size;
        break;
906 907

    case SVGA_REG_CONFIG_DONE:
908 909
        ret = s->config;
        break;
910 911 912

    case SVGA_REG_SYNC:
    case SVGA_REG_BUSY:
913 914
        ret = s->syncing;
        break;
915 916

    case SVGA_REG_GUEST_ID:
917 918
        ret = s->guest;
        break;
919 920

    case SVGA_REG_CURSOR_ID:
921 922
        ret = s->cursor.id;
        break;
923 924

    case SVGA_REG_CURSOR_X:
925 926
        ret = s->cursor.x;
        break;
927 928

    case SVGA_REG_CURSOR_Y:
929
        ret = s->cursor.y;
930
        break;
931 932

    case SVGA_REG_CURSOR_ON:
933 934
        ret = s->cursor.on;
        break;
935 936

    case SVGA_REG_SCRATCH_SIZE:
937 938
        ret = s->scratch_size;
        break;
939 940 941 942 943

    case SVGA_REG_MEM_REGS:
    case SVGA_REG_NUM_DISPLAYS:
    case SVGA_REG_PITCHLOCK:
    case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:
944 945
        ret = 0;
        break;
946 947 948

    default:
        if (s->index >= SVGA_SCRATCH_BASE &&
B
BALATON Zoltan 已提交
949
            s->index < SVGA_SCRATCH_BASE + s->scratch_size) {
950 951
            ret = s->scratch[s->index - SVGA_SCRATCH_BASE];
            break;
B
BALATON Zoltan 已提交
952 953
        }
        printf("%s: Bad register %02x\n", __func__, s->index);
954 955
        ret = 0;
        break;
956 957
    }

958 959 960 961 962 963 964 965
    if (s->index >= SVGA_SCRATCH_BASE) {
        trace_vmware_scratch_read(s->index, ret);
    } else if (s->index >= SVGA_PALETTE_BASE) {
        trace_vmware_palette_read(s->index, ret);
    } else {
        trace_vmware_value_read(s->index, ret);
    }
    return ret;
966 967 968 969
}

static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
{
970
    struct vmsvga_state_s *s = opaque;
B
BALATON Zoltan 已提交
971

972 973 974 975 976 977 978
    if (s->index >= SVGA_SCRATCH_BASE) {
        trace_vmware_scratch_write(s->index, value);
    } else if (s->index >= SVGA_PALETTE_BASE) {
        trace_vmware_palette_write(s->index, value);
    } else {
        trace_vmware_value_write(s->index, value);
    }
979 980
    switch (s->index) {
    case SVGA_REG_ID:
B
BALATON Zoltan 已提交
981
        if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) {
982
            s->svgaid = value;
B
BALATON Zoltan 已提交
983
        }
984 985 986
        break;

    case SVGA_REG_ENABLE:
987
        s->enable = !!value;
988
        s->invalidated = 1;
G
Gerd Hoffmann 已提交
989
        s->vga.hw_ops->invalidate(&s->vga);
990
        if (s->enable && s->config) {
991 992 993 994
            vga_dirty_log_stop(&s->vga);
        } else {
            vga_dirty_log_start(&s->vga);
        }
995 996 997
        break;

    case SVGA_REG_WIDTH:
998 999 1000 1001 1002 1003
        if (value <= SVGA_MAX_WIDTH) {
            s->new_width = value;
            s->invalidated = 1;
        } else {
            printf("%s: Bad width: %i\n", __func__, value);
        }
1004 1005 1006
        break;

    case SVGA_REG_HEIGHT:
1007 1008 1009 1010 1011 1012
        if (value <= SVGA_MAX_HEIGHT) {
            s->new_height = value;
            s->invalidated = 1;
        } else {
            printf("%s: Bad height: %i\n", __func__, value);
        }
1013 1014 1015
        break;

    case SVGA_REG_BITS_PER_PIXEL:
1016
        if (value != 32) {
1017
            printf("%s: Bad bits per pixel: %i bits\n", __func__, value);
1018
            s->config = 0;
1019
            s->invalidated = 1;
1020 1021 1022 1023 1024
        }
        break;

    case SVGA_REG_CONFIG_DONE:
        if (value) {
1025
            s->fifo = (uint32_t *) s->fifo_ptr;
1026
            vga_dirty_log_stop(&s->vga);
1027
        }
1028
        s->config = !!value;
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
        break;

    case SVGA_REG_SYNC:
        s->syncing = 1;
        vmsvga_fifo_run(s); /* Or should we just wait for update_display? */
        break;

    case SVGA_REG_GUEST_ID:
        s->guest = value;
#ifdef VERBOSE
        if (value >= GUEST_OS_BASE && value < GUEST_OS_BASE +
B
BALATON Zoltan 已提交
1040 1041 1042 1043
            ARRAY_SIZE(vmsvga_guest_id)) {
            printf("%s: guest runs %s.\n", __func__,
                   vmsvga_guest_id[value - GUEST_OS_BASE]);
        }
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
#endif
        break;

    case SVGA_REG_CURSOR_ID:
        s->cursor.id = value;
        break;

    case SVGA_REG_CURSOR_X:
        s->cursor.x = value;
        break;

    case SVGA_REG_CURSOR_Y:
        s->cursor.y = value;
        break;

    case SVGA_REG_CURSOR_ON:
        s->cursor.on |= (value == SVGA_CURSOR_ON_SHOW);
        s->cursor.on &= (value != SVGA_CURSOR_ON_HIDE);
#ifdef HW_MOUSE_ACCEL
1063
        if (value <= SVGA_CURSOR_ON_SHOW) {
1064
            dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on);
1065
        }
1066 1067 1068
#endif
        break;

1069
    case SVGA_REG_DEPTH:
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
    case SVGA_REG_MEM_REGS:
    case SVGA_REG_NUM_DISPLAYS:
    case SVGA_REG_PITCHLOCK:
    case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:
        break;

    default:
        if (s->index >= SVGA_SCRATCH_BASE &&
                s->index < SVGA_SCRATCH_BASE + s->scratch_size) {
            s->scratch[s->index - SVGA_SCRATCH_BASE] = value;
            break;
        }
B
BALATON Zoltan 已提交
1082
        printf("%s: Bad register %02x\n", __func__, s->index);
1083 1084 1085 1086 1087
    }
}

static uint32_t vmsvga_bios_read(void *opaque, uint32_t address)
{
B
BALATON Zoltan 已提交
1088
    printf("%s: what are we supposed to return?\n", __func__);
1089 1090 1091 1092 1093
    return 0xcafe;
}

static void vmsvga_bios_write(void *opaque, uint32_t address, uint32_t data)
{
B
BALATON Zoltan 已提交
1094
    printf("%s: what are we supposed to do with (%08x)?\n", __func__, data);
1095 1096
}

1097
static inline void vmsvga_check_size(struct vmsvga_state_s *s)
1098
{
1099 1100 1101
    DisplaySurface *surface = qemu_console_surface(s->vga.con);

    if (s->new_width != surface_width(surface) ||
1102 1103 1104
        s->new_height != surface_height(surface) ||
        s->new_depth != surface_bits_per_pixel(surface)) {
        int stride = (s->new_depth * s->new_width) / 8;
G
Gerd Hoffmann 已提交
1105 1106
        pixman_format_code_t format =
            qemu_default_pixman_format(s->new_depth, true);
1107 1108
        trace_vmware_setmode(s->new_width, s->new_height, s->new_depth);
        surface = qemu_create_displaysurface_from(s->new_width, s->new_height,
G
Gerd Hoffmann 已提交
1109 1110
                                                  format, stride,
                                                  s->vga.vram_ptr);
1111
        dpy_gfx_replace_surface(s->vga.con, surface);
1112 1113 1114 1115 1116 1117
        s->invalidated = 1;
    }
}

static void vmsvga_update_display(void *opaque)
{
1118
    struct vmsvga_state_s *s = opaque;
1119

1120 1121
    if (!s->enable || !s->config) {
        /* in standard vga mode */
G
Gerd Hoffmann 已提交
1122
        s->vga.hw_ops->gfx_update(&s->vga);
1123 1124 1125
        return;
    }

1126
    vmsvga_check_size(s);
1127 1128 1129 1130

    vmsvga_fifo_run(s);
    vmsvga_update_rect_flush(s);

1131
    if (s->invalidated) {
1132
        s->invalidated = 0;
G
Gerd Hoffmann 已提交
1133
        dpy_gfx_update_full(s->vga.con);
1134
    }
1135 1136
}

J
Jan Kiszka 已提交
1137
static void vmsvga_reset(DeviceState *dev)
1138
{
1139
    struct pci_vmsvga_state_s *pci = VMWARE_SVGA(dev);
J
Jan Kiszka 已提交
1140 1141
    struct vmsvga_state_s *s = &pci->chip;

1142 1143 1144 1145 1146 1147 1148 1149
    s->index = 0;
    s->enable = 0;
    s->config = 0;
    s->svgaid = SVGA_ID;
    s->cursor.on = 0;
    s->redraw_fifo_first = 0;
    s->redraw_fifo_last = 0;
    s->syncing = 0;
1150 1151

    vga_dirty_log_start(&s->vga);
1152 1153 1154 1155
}

static void vmsvga_invalidate_display(void *opaque)
{
1156
    struct vmsvga_state_s *s = opaque;
1157
    if (!s->enable) {
G
Gerd Hoffmann 已提交
1158
        s->vga.hw_ops->invalidate(&s->vga);
1159 1160 1161 1162 1163 1164
        return;
    }

    s->invalidated = 1;
}

A
Anthony Liguori 已提交
1165
static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
B
balrog 已提交
1166
{
1167
    struct vmsvga_state_s *s = opaque;
B
balrog 已提交
1168

G
Gerd Hoffmann 已提交
1169 1170
    if (s->vga.hw_ops->text_update) {
        s->vga.hw_ops->text_update(&s->vga, chardata);
B
BALATON Zoltan 已提交
1171
    }
B
balrog 已提交
1172 1173
}

J
Juan Quintela 已提交
1174
static int vmsvga_post_load(void *opaque, int version_id)
1175
{
J
Juan Quintela 已提交
1176
    struct vmsvga_state_s *s = opaque;
1177 1178

    s->invalidated = 1;
B
BALATON Zoltan 已提交
1179
    if (s->config) {
1180
        s->fifo = (uint32_t *) s->fifo_ptr;
B
BALATON Zoltan 已提交
1181
    }
1182 1183 1184
    return 0;
}

B
Blue Swirl 已提交
1185
static const VMStateDescription vmstate_vmware_vga_internal = {
J
Juan Quintela 已提交
1186 1187 1188 1189
    .name = "vmware_vga_internal",
    .version_id = 0,
    .minimum_version_id = 0,
    .post_load = vmsvga_post_load,
1190
    .fields = (VMStateField[]) {
1191
        VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s, NULL),
J
Juan Quintela 已提交
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
        VMSTATE_INT32(enable, struct vmsvga_state_s),
        VMSTATE_INT32(config, struct vmsvga_state_s),
        VMSTATE_INT32(cursor.id, struct vmsvga_state_s),
        VMSTATE_INT32(cursor.x, struct vmsvga_state_s),
        VMSTATE_INT32(cursor.y, struct vmsvga_state_s),
        VMSTATE_INT32(cursor.on, struct vmsvga_state_s),
        VMSTATE_INT32(index, struct vmsvga_state_s),
        VMSTATE_VARRAY_INT32(scratch, struct vmsvga_state_s,
                             scratch_size, 0, vmstate_info_uint32, uint32_t),
        VMSTATE_INT32(new_width, struct vmsvga_state_s),
        VMSTATE_INT32(new_height, struct vmsvga_state_s),
        VMSTATE_UINT32(guest, struct vmsvga_state_s),
        VMSTATE_UINT32(svgaid, struct vmsvga_state_s),
        VMSTATE_INT32(syncing, struct vmsvga_state_s),
1206
        VMSTATE_UNUSED(4), /* was fb_size */
J
Juan Quintela 已提交
1207 1208 1209 1210
        VMSTATE_END_OF_LIST()
    }
};

B
Blue Swirl 已提交
1211
static const VMStateDescription vmstate_vmware_vga = {
J
Juan Quintela 已提交
1212 1213 1214
    .name = "vmware_vga",
    .version_id = 0,
    .minimum_version_id = 0,
1215
    .fields = (VMStateField[]) {
1216
        VMSTATE_PCI_DEVICE(parent_obj, struct pci_vmsvga_state_s),
J
Juan Quintela 已提交
1217 1218 1219 1220 1221 1222
        VMSTATE_STRUCT(chip, struct pci_vmsvga_state_s, 0,
                       vmstate_vmware_vga_internal, struct vmsvga_state_s),
        VMSTATE_END_OF_LIST()
    }
};

G
Gerd Hoffmann 已提交
1223 1224 1225 1226 1227 1228
static const GraphicHwOps vmsvga_ops = {
    .invalidate  = vmsvga_invalidate_display,
    .gfx_update  = vmsvga_update_display,
    .text_update = vmsvga_text_update,
};

1229
static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,
1230
                        MemoryRegion *address_space, MemoryRegion *io)
1231 1232
{
    s->scratch_size = SVGA_SCRATCH_SIZE;
1233
    s->scratch = g_malloc(s->scratch_size * 4);
1234

1235
    s->vga.con = graphic_console_init(dev, 0, &vmsvga_ops, s);
1236

1237
    s->fifo_size = SVGA_FIFO_SIZE;
1238
    memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size,
1239
                           &error_fatal);
1240
    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
1241

1242
    vga_common_init(&s->vga, OBJECT(dev));
P
Paolo Bonzini 已提交
1243
    vga_init(&s->vga, OBJECT(dev), address_space, io, true);
A
Alex Williamson 已提交
1244
    vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
1245
    s->new_depth = 32;
1246 1247
}

1248
static uint64_t vmsvga_io_read(void *opaque, hwaddr addr, unsigned size)
1249
{
1250 1251 1252 1253 1254 1255 1256 1257
    struct vmsvga_state_s *s = opaque;

    switch (addr) {
    case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr);
    case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr);
    case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr);
    default: return -1u;
    }
1258 1259
}

A
Avi Kivity 已提交
1260
static void vmsvga_io_write(void *opaque, hwaddr addr,
1261
                            uint64_t data, unsigned size)
1262
{
1263
    struct vmsvga_state_s *s = opaque;
1264

1265 1266
    switch (addr) {
    case SVGA_IO_MUL * SVGA_INDEX_PORT:
B
Blue Swirl 已提交
1267 1268
        vmsvga_index_write(s, addr, data);
        break;
1269
    case SVGA_IO_MUL * SVGA_VALUE_PORT:
B
Blue Swirl 已提交
1270 1271
        vmsvga_value_write(s, addr, data);
        break;
1272
    case SVGA_IO_MUL * SVGA_BIOS_PORT:
B
Blue Swirl 已提交
1273 1274
        vmsvga_bios_write(s, addr, data);
        break;
1275
    }
1276 1277
}

1278 1279 1280 1281 1282 1283 1284
static const MemoryRegionOps vmsvga_io_ops = {
    .read = vmsvga_io_read,
    .write = vmsvga_io_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
1285 1286 1287 1288
        .unaligned = true,
    },
    .impl = {
        .unaligned = true,
1289 1290
    },
};
1291

1292
static void pci_vmsvga_realize(PCIDevice *dev, Error **errp)
1293
{
1294
    struct pci_vmsvga_state_s *s = VMWARE_SVGA(dev);
1295

1296 1297 1298
    dev->config[PCI_CACHE_LINE_SIZE] = 0x08;
    dev->config[PCI_LATENCY_TIMER] = 0x40;
    dev->config[PCI_INTERRUPT_LINE] = 0xff;          /* End */
1299

1300
    memory_region_init_io(&s->io_bar, NULL, &vmsvga_io_ops, &s->chip,
1301
                          "vmsvga-io", 0x10);
1302
    memory_region_set_flush_coalesced(&s->io_bar);
1303
    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
1304

1305 1306
    vmsvga_init(DEVICE(dev), &s->chip,
                pci_address_space(dev), pci_address_space_io(dev));
1307

1308
    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
1309
                     &s->chip.vga.vram);
1310
    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
1311
                     &s->chip.fifo_ram);
1312

1313 1314
    if (!dev->rom_bar) {
        /* compatibility with pc-0.13 and older */
P
Paolo Bonzini 已提交
1315
        vga_init_vbe(&s->chip.vga, OBJECT(dev), pci_address_space(dev));
1316
    }
1317
}
G
Gerd Hoffmann 已提交
1318

G
Gerd Hoffmann 已提交
1319 1320
static Property vga_vmware_properties[] = {
    DEFINE_PROP_UINT32("vgamem_mb", struct pci_vmsvga_state_s,
G
Gerd Hoffmann 已提交
1321
                       chip.vga.vram_size_mb, 16),
1322 1323
    DEFINE_PROP_BOOL("global-vmstate", struct pci_vmsvga_state_s,
                     chip.vga.global_vmstate, false),
G
Gerd Hoffmann 已提交
1324 1325 1326
    DEFINE_PROP_END_OF_LIST(),
};

1327 1328
static void vmsvga_class_init(ObjectClass *klass, void *data)
{
1329
    DeviceClass *dc = DEVICE_CLASS(klass);
1330 1331
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

1332
    k->realize = pci_vmsvga_realize;
1333 1334 1335 1336 1337 1338
    k->romfile = "vgabios-vmware.bin";
    k->vendor_id = PCI_VENDOR_ID_VMWARE;
    k->device_id = SVGA_PCI_DEVICE_ID;
    k->class_id = PCI_CLASS_DISPLAY_VGA;
    k->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
    k->subsystem_id = SVGA_PCI_DEVICE_ID;
1339 1340
    dc->reset = vmsvga_reset;
    dc->vmsd = &vmstate_vmware_vga;
G
Gerd Hoffmann 已提交
1341
    dc->props = vga_vmware_properties;
1342
    dc->hotpluggable = false;
1343
    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
1344 1345
}

1346
static const TypeInfo vmsvga_info = {
1347
    .name          = TYPE_VMWARE_SVGA,
1348 1349 1350
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(struct pci_vmsvga_state_s),
    .class_init    = vmsvga_class_init,
1351 1352 1353 1354
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
G
Gerd Hoffmann 已提交
1355 1356
};

A
Andreas Färber 已提交
1357
static void vmsvga_register_types(void)
G
Gerd Hoffmann 已提交
1358
{
1359
    type_register_static(&vmsvga_info);
G
Gerd Hoffmann 已提交
1360
}
A
Andreas Färber 已提交
1361 1362

type_init(vmsvga_register_types)