vmware_vga.c 38.4 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 "qapi/error.h"
26 27
#include "hw/hw.h"
#include "hw/loader.h"
28
#include "trace.h"
29
#include "ui/console.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;
    }
G
Gerd Hoffmann 已提交
569
    if (s->fifo_max < s->fifo_min + 10 * 1024) {
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 682 683 684 685
            if (cursor.width > 256
                || cursor.height > 256
                || cursor.bpp > 32
                || SVGA_BITMAP_SIZE(x, y)
                    > sizeof(cursor.mask) / sizeof(cursor.mask[0])
                || SVGA_PIXMAP_SIZE(x, y, cursor.bpp)
                    > sizeof(cursor.image) / sizeof(cursor.image[0])) {
686
                    goto badcmd;
B
BALATON Zoltan 已提交
687
            }
688 689

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

B
BALATON Zoltan 已提交
694
            for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args++) {
695
                cursor.mask[args] = vmsvga_fifo_read_raw(s);
B
BALATON Zoltan 已提交
696 697
            }
            for (args = 0; args < SVGA_PIXMAP_SIZE(x, y, cursor.bpp); args++) {
698
                cursor.image[args] = vmsvga_fifo_read_raw(s);
B
BALATON Zoltan 已提交
699
            }
700 701 702 703 704 705 706 707 708 709 710 711 712
#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:
713
            len -= 6;
B
BALATON Zoltan 已提交
714
            if (len < 0) {
715
                goto rewind;
B
BALATON Zoltan 已提交
716
            }
717 718 719 720 721 722 723 724 725 726 727 728 729 730
            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:
731
            len -= 4;
B
BALATON Zoltan 已提交
732
            if (len < 0) {
733
                goto rewind;
B
BALATON Zoltan 已提交
734
            }
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
            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:
755
            args = 0;
756
        badcmd:
757
            len -= args;
B
BALATON Zoltan 已提交
758
            if (len < 0) {
759
                goto rewind;
B
BALATON Zoltan 已提交
760 761
            }
            while (args--) {
762
                vmsvga_fifo_read(s);
B
BALATON Zoltan 已提交
763
            }
764
            printf("%s: Unknown command 0x%02x in SVGA command FIFO\n",
B
BALATON Zoltan 已提交
765
                   __func__, cmd);
766
            break;
767 768

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

    s->syncing = 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    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
889
        if (dpy_cursor_define_supported(s->vga.con)) {
890 891
            caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
                    SVGA_CAP_CURSOR_BYPASS;
892
        }
893
#endif
894 895
        ret = caps;
        break;
896

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

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

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

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

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

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

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

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

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

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

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

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

959 960 961 962 963 964 965 966
    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;
967 968 969 970
}

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

973 974 975 976 977 978 979
    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);
    }
980 981
    switch (s->index) {
    case SVGA_REG_ID:
B
BALATON Zoltan 已提交
982
        if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) {
983
            s->svgaid = value;
B
BALATON Zoltan 已提交
984
        }
985 986 987
        break;

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

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

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

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

    case SVGA_REG_CONFIG_DONE:
        if (value) {
1026
            s->fifo = (uint32_t *) s->fifo_ptr;
1027
            vga_dirty_log_stop(&s->vga);
1028
        }
1029
        s->config = !!value;
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
        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 已提交
1041 1042 1043 1044
            ARRAY_SIZE(vmsvga_guest_id)) {
            printf("%s: guest runs %s.\n", __func__,
                   vmsvga_guest_id[value - GUEST_OS_BASE]);
        }
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
#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
1064
        if (value <= SVGA_CURSOR_ON_SHOW) {
1065
            dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on);
1066
        }
1067 1068 1069
#endif
        break;

1070
    case SVGA_REG_DEPTH:
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
    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 已提交
1083
        printf("%s: Bad register %02x\n", __func__, s->index);
1084 1085 1086 1087 1088
    }
}

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

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

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

    if (s->new_width != surface_width(surface) ||
1103 1104 1105
        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 已提交
1106 1107
        pixman_format_code_t format =
            qemu_default_pixman_format(s->new_depth, true);
1108 1109
        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 已提交
1110 1111
                                                  format, stride,
                                                  s->vga.vram_ptr);
1112
        dpy_gfx_replace_surface(s->vga.con, surface);
1113 1114 1115 1116 1117 1118
        s->invalidated = 1;
    }
}

static void vmsvga_update_display(void *opaque)
{
1119
    struct vmsvga_state_s *s = opaque;
1120
    DisplaySurface *surface;
1121

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

1128
    vmsvga_check_size(s);
1129
    surface = qemu_console_surface(s->vga.con);
1130 1131 1132 1133

    vmsvga_fifo_run(s);
    vmsvga_update_rect_flush(s);

1134
    if (s->invalidated) {
1135
        s->invalidated = 0;
1136 1137
        dpy_gfx_update(s->vga.con, 0, 0,
                   surface_width(surface), surface_height(surface));
1138
    }
1139 1140
}

J
Jan Kiszka 已提交
1141
static void vmsvga_reset(DeviceState *dev)
1142
{
1143
    struct pci_vmsvga_state_s *pci = VMWARE_SVGA(dev);
J
Jan Kiszka 已提交
1144 1145
    struct vmsvga_state_s *s = &pci->chip;

1146 1147 1148 1149 1150 1151 1152 1153
    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;
1154 1155

    vga_dirty_log_start(&s->vga);
1156 1157 1158 1159
}

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

    s->invalidated = 1;
}

A
Anthony Liguori 已提交
1169
static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
B
balrog 已提交
1170
{
1171
    struct vmsvga_state_s *s = opaque;
B
balrog 已提交
1172

G
Gerd Hoffmann 已提交
1173 1174
    if (s->vga.hw_ops->text_update) {
        s->vga.hw_ops->text_update(&s->vga, chardata);
B
BALATON Zoltan 已提交
1175
    }
B
balrog 已提交
1176 1177
}

J
Juan Quintela 已提交
1178
static int vmsvga_post_load(void *opaque, int version_id)
1179
{
J
Juan Quintela 已提交
1180
    struct vmsvga_state_s *s = opaque;
1181 1182

    s->invalidated = 1;
B
BALATON Zoltan 已提交
1183
    if (s->config) {
1184
        s->fifo = (uint32_t *) s->fifo_ptr;
B
BALATON Zoltan 已提交
1185
    }
1186 1187 1188
    return 0;
}

B
Blue Swirl 已提交
1189
static const VMStateDescription vmstate_vmware_vga_internal = {
J
Juan Quintela 已提交
1190 1191 1192 1193
    .name = "vmware_vga_internal",
    .version_id = 0,
    .minimum_version_id = 0,
    .post_load = vmsvga_post_load,
1194
    .fields = (VMStateField[]) {
1195
        VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s, NULL),
J
Juan Quintela 已提交
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
        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),
1210
        VMSTATE_UNUSED(4), /* was fb_size */
J
Juan Quintela 已提交
1211 1212 1213 1214
        VMSTATE_END_OF_LIST()
    }
};

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

G
Gerd Hoffmann 已提交
1227 1228 1229 1230 1231 1232
static const GraphicHwOps vmsvga_ops = {
    .invalidate  = vmsvga_invalidate_display,
    .gfx_update  = vmsvga_update_display,
    .text_update = vmsvga_text_update,
};

1233
static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,
1234
                        MemoryRegion *address_space, MemoryRegion *io)
1235 1236
{
    s->scratch_size = SVGA_SCRATCH_SIZE;
1237
    s->scratch = g_malloc(s->scratch_size * 4);
1238

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

1241
    s->fifo_size = SVGA_FIFO_SIZE;
1242
    memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size,
1243
                           &error_fatal);
1244
    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
1245

G
Gerd Hoffmann 已提交
1246
    vga_common_init(&s->vga, OBJECT(dev), true);
P
Paolo Bonzini 已提交
1247
    vga_init(&s->vga, OBJECT(dev), address_space, io, true);
A
Alex Williamson 已提交
1248
    vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
1249
    s->new_depth = 32;
1250 1251
}

1252
static uint64_t vmsvga_io_read(void *opaque, hwaddr addr, unsigned size)
1253
{
1254 1255 1256 1257 1258 1259 1260 1261
    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;
    }
1262 1263
}

A
Avi Kivity 已提交
1264
static void vmsvga_io_write(void *opaque, hwaddr addr,
1265
                            uint64_t data, unsigned size)
1266
{
1267
    struct vmsvga_state_s *s = opaque;
1268

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

1282 1283 1284 1285 1286 1287 1288
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,
1289 1290 1291 1292
        .unaligned = true,
    },
    .impl = {
        .unaligned = true,
1293 1294
    },
};
1295

1296
static void pci_vmsvga_realize(PCIDevice *dev, Error **errp)
1297
{
1298
    struct pci_vmsvga_state_s *s = VMWARE_SVGA(dev);
1299

1300 1301 1302
    dev->config[PCI_CACHE_LINE_SIZE] = 0x08;
    dev->config[PCI_LATENCY_TIMER] = 0x40;
    dev->config[PCI_INTERRUPT_LINE] = 0xff;          /* End */
1303

1304
    memory_region_init_io(&s->io_bar, NULL, &vmsvga_io_ops, &s->chip,
1305
                          "vmsvga-io", 0x10);
1306
    memory_region_set_flush_coalesced(&s->io_bar);
1307
    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
1308

1309 1310
    vmsvga_init(DEVICE(dev), &s->chip,
                pci_address_space(dev), pci_address_space_io(dev));
1311

1312
    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
1313
                     &s->chip.vga.vram);
1314
    pci_register_bar(dev, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
1315
                     &s->chip.fifo_ram);
1316

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

G
Gerd Hoffmann 已提交
1323 1324
static Property vga_vmware_properties[] = {
    DEFINE_PROP_UINT32("vgamem_mb", struct pci_vmsvga_state_s,
G
Gerd Hoffmann 已提交
1325
                       chip.vga.vram_size_mb, 16),
G
Gerd Hoffmann 已提交
1326 1327 1328
    DEFINE_PROP_END_OF_LIST(),
};

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

1334
    k->realize = pci_vmsvga_realize;
1335 1336 1337 1338 1339 1340
    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;
1341 1342
    dc->reset = vmsvga_reset;
    dc->vmsd = &vmstate_vmware_vga;
G
Gerd Hoffmann 已提交
1343
    dc->props = vga_vmware_properties;
1344
    dc->hotpluggable = false;
1345
    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
1346 1347
}

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

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

type_init(vmsvga_register_types)