?? vmware_vga.c
字號:
/* * 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. */#include "hw.h"#include "console.h"#include "pci.h"#define VERBOSE#define EMBED_STDVGA#undef DIRECT_VRAM#define HW_RECT_ACCEL#define HW_FILL_ACCEL#define HW_MOUSE_ACCEL#ifdef EMBED_STDVGA# include "vga_int.h"#endifstruct vmsvga_state_s {#ifdef EMBED_STDVGA VGA_STATE_COMMON#endif int width; int height; int invalidated; int depth; int bypp; int enable; int config; struct { int id; int x; int y; int on; } cursor;#ifndef EMBED_STDVGA DisplayState *ds; int vram_size;#endif uint8_t *vram; int index; int scratch_size; uint32_t *scratch; int new_width; int new_height; uint32_t guest; uint32_t svgaid; uint32_t wred; uint32_t wgreen; uint32_t wblue; int syncing; int fb_size; union { uint32_t *fifo; struct __attribute__((__packed__)) { uint32_t min; uint32_t max; uint32_t next_cmd; uint32_t stop; /* Add registers here when adding capabilities. */ uint32_t fifo[0]; } *cmd; };#define REDRAW_FIFO_LEN 512 struct vmsvga_rect_s { int x, y, w, h; } redraw_fifo[REDRAW_FIFO_LEN]; int redraw_fifo_first, redraw_fifo_last;};struct pci_vmsvga_state_s { PCIDevice card; struct vmsvga_state_s chip;};#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)#define SVGA_LEGACY_BASE_PORT 0x4560#define SVGA_INDEX_PORT 0x0#define SVGA_VALUE_PORT 0x1#define SVGA_BIOS_PORT 0x2#define SVGA_VERSION_2#ifdef SVGA_VERSION_2# 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_MEM_BASE 0xe0000000# define SVGA_PCI_DEVICE_ID PCI_DEVICE_ID_VMWARE_SVGA2#else# 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_MEM_BASE 0xe0000000# define SVGA_PCI_DEVICE_ID PCI_DEVICE_ID_VMWARE_SVGA#endifenum { /* 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, SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */ 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, SVGA_REG_MEM_START = 18, /* Memory for command FIFO */ SVGA_REG_MEM_SIZE = 19, 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 */ SVGA_PALETTE_END = SVGA_PALETTE_BASE + 767, SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + 768,};#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)/* * FIFO offsets (seen as an array of 32-bit words) */enum { /* * The original defined FIFO offsets */ SVGA_FIFO_MIN = 0, SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */ SVGA_FIFO_NEXT_CMD, 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,};#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)#define SVGA_FIFO_FLAG_NONE 0#define SVGA_FIFO_FLAG_ACCELFRONT (1 << 0)/* These values can probably be changed arbitrarily. */#define SVGA_SCRATCH_SIZE 0x8000#define SVGA_MAX_WIDTH 2360#define SVGA_MAX_HEIGHT 1770#ifdef VERBOSE# define GUEST_OS_BASE 0x5001static const char *vmsvga_guest_id[] = { [0x00 ... 0x15] = "an unknown OS", [0x00] = "Dos", [0x01] = "Windows 3.1", [0x02] = "Windows 95", [0x03] = "Windows 98", [0x04] = "Windows ME", [0x05] = "Windows NT", [0x06] = "Windows 2000", [0x08] = "OS/2", [0x0a] = "BSD", [0x0b] = "Whistler", [0x15] = "Windows 2003",};#endifenum { 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,};static inline void vmsvga_update_rect(struct vmsvga_state_s *s, int x, int y, int w, int h){#ifndef DIRECT_VRAM int line = h; int bypl = s->bypp * s->width; int width = s->bypp * w; int start = s->bypp * x + bypl * y; uint8_t *src = s->vram + start; uint8_t *dst = s->ds->data + start; for (; line > 0; line --, src += bypl, dst += bypl) memcpy(dst, src, width);#endif dpy_update(s->ds, x, y, w, h);}static inline void vmsvga_update_screen(struct vmsvga_state_s *s){#ifndef DIRECT_VRAM memcpy(s->ds->data, s->vram, s->bypp * s->width * s->height);#endif dpy_update(s->ds, 0, 0, s->width, s->height);}#ifdef DIRECT_VRAM# define vmsvga_update_rect_delayed vmsvga_update_rect#elsestatic inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s, int x, int y, int w, int h){ struct vmsvga_rect_s *rect = &s->redraw_fifo[s->redraw_fifo_last ++]; s->redraw_fifo_last &= REDRAW_FIFO_LEN - 1; rect->x = x; rect->y = y; rect->w = w; rect->h = h;}#endifstatic inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s){ struct vmsvga_rect_s *rect; 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) { rect = &s->redraw_fifo[s->redraw_fifo_first ++]; s->redraw_fifo_first &= REDRAW_FIFO_LEN - 1; vmsvga_update_rect(s, rect->x, rect->y, rect->w, rect->h); }}#ifdef HW_RECT_ACCELstatic inline void vmsvga_copy_rect(struct vmsvga_state_s *s, int x0, int y0, int x1, int y1, int w, int h){# ifdef DIRECT_VRAM uint8_t *vram = s->ds->data;# else uint8_t *vram = s->vram;# endif int bypl = s->bypp * s->width; int width = s->bypp * w; int line = h; uint8_t *ptr[2];# ifdef DIRECT_VRAM if (s->ds->dpy_copy) s->ds->dpy_copy(s->ds, x0, y0, x1, y1, w, h); else# endif { if (y1 > y0) { ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1); ptr[1] = vram + s->bypp * x1 + bypl * (y1 + h - 1); for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) memmove(ptr[1], ptr[0], width); } else { ptr[0] = vram + s->bypp * x0 + bypl * y0; ptr[1] = vram + s->bypp * x1 + bypl * y1; for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) memmove(ptr[1], ptr[0], width); } } vmsvga_update_rect_delayed(s, x1, y1, w, h);}#endif#ifdef HW_FILL_ACCELstatic inline void vmsvga_fill_rect(struct vmsvga_state_s *s, uint32_t c, int x, int y, int w, int h){# ifdef DIRECT_VRAM uint8_t *vram = s->ds->data;# else uint8_t *vram = s->vram;# endif int bypp = s->bypp; int bypl = bypp * s->width; int width = bypp * w; int line = h; int column; uint8_t *fst = vram + bypp * x + bypl * y; uint8_t *dst;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -