Added Eric Petit's VMware graphics driver - thanks!
Made the following changes from the version I got from Eric: * made BppForSpace() in DriverInterface.h inline to remove some warnings * renamed driver source files to lower case. * removed Be Inc. copyright from kernel driver as I couldn't see anything coming from Be Inc. there - correct me if I was wrong, Eric. * Minor other changes like added missing header guards. * The README provided in the main directory is only included in the accelerant directory. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19793 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <[email protected]>
|
||||
*/
|
||||
|
||||
#ifndef DRIVERINTERFACE_H
|
||||
#define DRIVERINTERFACE_H
|
||||
|
||||
#include <GraphicsDefs.h>
|
||||
#include <Accelerant.h>
|
||||
#include <Drivers.h>
|
||||
#include <PCI.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include "vm_device_version.h"
|
||||
#include "svga_reg.h"
|
||||
|
||||
#define MAX_SAMPLE_DEVICE_NAME_LENGTH 32
|
||||
#define CURSOR_ID 1
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Benaphores */
|
||||
|
||||
typedef struct {
|
||||
sem_id sem;
|
||||
int32 ben;
|
||||
} Benaphore;
|
||||
#define INIT_BEN(x) x.sem = create_sem(0, "VMware "#x); x.ben = 0;
|
||||
#define ACQUIRE_BEN(x) if((atomic_add(&(x.ben), 1)) >= 1) acquire_sem(x.sem);
|
||||
#define RELEASE_BEN(x) if((atomic_add(&(x.ben), -1)) > 1) release_sem(x.sem);
|
||||
#define DELETE_BEN(x) delete_sem(x.sem);
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Utils */
|
||||
|
||||
#define ROUND_TO_PAGE_SIZE(x) (((x)+(B_PAGE_SIZE)-1)&~((B_PAGE_SIZE)-1))
|
||||
|
||||
static inline int
|
||||
BppForSpace(int space)
|
||||
{
|
||||
switch (space) {
|
||||
case B_RGB32:
|
||||
return 32;
|
||||
case B_RGB24:
|
||||
return 24;
|
||||
case B_RGB16:
|
||||
return 16;
|
||||
case B_RGB15:
|
||||
return 15;
|
||||
case B_CMAP8:
|
||||
return 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Request codes for ioctl() */
|
||||
|
||||
enum {
|
||||
VMWARE_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
||||
VMWARE_FIFO_START,
|
||||
VMWARE_FIFO_STOP,
|
||||
VMWARE_FIFO_SYNC,
|
||||
VMWARE_SET_MODE,
|
||||
VMWARE_SHOW_CURSOR,
|
||||
VMWARE_MOVE_CURSOR,
|
||||
};
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Structure shared between the kernel driver and the accelerant */
|
||||
|
||||
typedef struct {
|
||||
/* Device info and capabilities */
|
||||
uint16 vendorId;
|
||||
uint16 deviceId;
|
||||
uint8 revision;
|
||||
uint32 maxWidth;
|
||||
uint32 maxHeight;
|
||||
void *fbDma;
|
||||
uint32 fbSize;
|
||||
void *fifoDma;
|
||||
uint32 fifoSize;
|
||||
uint32 fifoMin;
|
||||
uint32 capabilities;
|
||||
uint32 fifoCapabilities;
|
||||
uint32 fifoFlags;
|
||||
|
||||
/* For registers access */
|
||||
uint16 indexPort;
|
||||
uint16 valuePort;
|
||||
|
||||
/* Mapped areas */
|
||||
area_id fbArea;
|
||||
void *fb;
|
||||
area_id fifoArea;
|
||||
void *fifo;
|
||||
|
||||
/* This changes when we switch to another mode */
|
||||
uint32 fbOffset;
|
||||
uint32 bytesPerRow;
|
||||
|
||||
/* Current display mode */
|
||||
display_mode dm;
|
||||
|
||||
Benaphore engineLock;
|
||||
Benaphore fifoLock;
|
||||
uint32 fifoNext;
|
||||
} SharedInfo;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* Copyright 1998-2001, VMware, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* svga_reg.h --
|
||||
*
|
||||
* SVGA hardware definitions
|
||||
*/
|
||||
|
||||
#ifndef _SVGA_REG_H_
|
||||
#define _SVGA_REG_H_
|
||||
|
||||
/*
|
||||
* Memory and port addresses and fundamental constants
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note-- MAX_WIDTH and MAX_HEIGHT are largely ignored by the code. This
|
||||
* isn't such a bad thing for forward compatibility. --Jeremy.
|
||||
*/
|
||||
#define SVGA_MAX_WIDTH 2360
|
||||
#define SVGA_MAX_HEIGHT 1770
|
||||
#define SVGA_MAX_BITS_PER_PIXEL 32
|
||||
#define SVGA_MAX_DEPTH 24
|
||||
|
||||
#define SVGA_FB_MAX_SIZE \
|
||||
((((SVGA_MAX_WIDTH * SVGA_MAX_HEIGHT * \
|
||||
SVGA_MAX_BITS_PER_PIXEL / 8) >> PAGE_SHIFT) + 1) << PAGE_SHIFT)
|
||||
|
||||
#define SVGA_MAX_PSEUDOCOLOR_DEPTH 8
|
||||
#define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
|
||||
#define SVGA_NUM_PALETTE_REGS (3 * SVGA_MAX_PSEUDOCOLORS)
|
||||
|
||||
#define SVGA_MAGIC 0x900000UL
|
||||
#define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver))
|
||||
|
||||
/* Version 2 let the address of the frame buffer be unsigned on Win32 */
|
||||
#define SVGA_VERSION_2 2
|
||||
#define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2)
|
||||
|
||||
/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
|
||||
PALETTE_BASE has moved */
|
||||
#define SVGA_VERSION_1 1
|
||||
#define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1)
|
||||
|
||||
/* Version 0 is the initial version */
|
||||
#define SVGA_VERSION_0 0
|
||||
#define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0)
|
||||
|
||||
/* Invalid SVGA_ID_ */
|
||||
#define SVGA_ID_INVALID 0xFFFFFFFF
|
||||
|
||||
/* More backwards compatibility, old location of color map: */
|
||||
#define SVGA_OLD_PALETTE_BASE 17
|
||||
|
||||
/* Base and Offset gets us headed the right way for PCI Base Addr Registers */
|
||||
#define SVGA_LEGACY_BASE_PORT 0x4560
|
||||
#define SVGA_INDEX_PORT 0x0
|
||||
#define SVGA_VALUE_PORT 0x1
|
||||
#define SVGA_BIOS_PORT 0x2
|
||||
#define SVGA_NUM_PORTS 0x3
|
||||
|
||||
/* This port is deprecated, but retained because of old drivers. */
|
||||
#define SVGA_LEGACY_ACCEL_PORT 0x3
|
||||
|
||||
/* Legal values for the SVGA_REG_CURSOR_ON register in cursor bypass mode */
|
||||
#define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */
|
||||
#define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */
|
||||
#define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */
|
||||
#define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */
|
||||
|
||||
/*
|
||||
* Registers
|
||||
*/
|
||||
|
||||
enum {
|
||||
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 0 implementation only had the above registers, then the palette */
|
||||
|
||||
SVGA_REG_CAPABILITIES = 17,
|
||||
SVGA_REG_MEM_START = 18, /* Memory for command FIFO and bitmaps */
|
||||
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_REG_TOP = 33, /* Must be 1 more than the last register */
|
||||
|
||||
SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */
|
||||
/* Next 768 (== 256*3) registers exist for colormap */
|
||||
SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS
|
||||
/* Base of scratch registers */
|
||||
/* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage:
|
||||
First 4 are reserved for VESA BIOS Extension; any remaining are for
|
||||
the use of the current SVGA driver. */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Capabilities
|
||||
*/
|
||||
|
||||
#define SVGA_CAP_NONE 0x00000
|
||||
#define SVGA_CAP_RECT_FILL 0x00001
|
||||
#define SVGA_CAP_RECT_COPY 0x00002
|
||||
#define SVGA_CAP_RECT_PAT_FILL 0x00004
|
||||
#define SVGA_CAP_LEGACY_OFFSCREEN 0x00008
|
||||
#define SVGA_CAP_RASTER_OP 0x00010
|
||||
#define SVGA_CAP_CURSOR 0x00020
|
||||
#define SVGA_CAP_CURSOR_BYPASS 0x00040
|
||||
#define SVGA_CAP_CURSOR_BYPASS_2 0x00080
|
||||
#define SVGA_CAP_8BIT_EMULATION 0x00100
|
||||
#define SVGA_CAP_ALPHA_CURSOR 0x00200
|
||||
#define SVGA_CAP_GLYPH 0x00400
|
||||
#define SVGA_CAP_GLYPH_CLIPPING 0x00800
|
||||
#define SVGA_CAP_OFFSCREEN_1 0x01000
|
||||
#define SVGA_CAP_ALPHA_BLEND 0x02000
|
||||
#define SVGA_CAP_3D 0x04000
|
||||
#define SVGA_CAP_EXTENDED_FIFO 0x08000
|
||||
#define SVGA_CAP_MULTIMON 0x10000
|
||||
#define SVGA_CAP_PITCHLOCK 0x20000
|
||||
|
||||
/*
|
||||
* Raster op codes (same encoding as X) used by FIFO drivers.
|
||||
*/
|
||||
|
||||
#define SVGA_ROP_CLEAR 0x00 /* 0 */
|
||||
#define SVGA_ROP_AND 0x01 /* src AND dst */
|
||||
#define SVGA_ROP_AND_REVERSE 0x02 /* src AND NOT dst */
|
||||
#define SVGA_ROP_COPY 0x03 /* src */
|
||||
#define SVGA_ROP_AND_INVERTED 0x04 /* NOT src AND dst */
|
||||
#define SVGA_ROP_NOOP 0x05 /* dst */
|
||||
#define SVGA_ROP_XOR 0x06 /* src XOR dst */
|
||||
#define SVGA_ROP_OR 0x07 /* src OR dst */
|
||||
#define SVGA_ROP_NOR 0x08 /* NOT src AND NOT dst */
|
||||
#define SVGA_ROP_EQUIV 0x09 /* NOT src XOR dst */
|
||||
#define SVGA_ROP_INVERT 0x0a /* NOT dst */
|
||||
#define SVGA_ROP_OR_REVERSE 0x0b /* src OR NOT dst */
|
||||
#define SVGA_ROP_COPY_INVERTED 0x0c /* NOT src */
|
||||
#define SVGA_ROP_OR_INVERTED 0x0d /* NOT src OR dst */
|
||||
#define SVGA_ROP_NAND 0x0e /* NOT src OR NOT dst */
|
||||
#define SVGA_ROP_SET 0x0f /* 1 */
|
||||
#define SVGA_ROP_UNSUPPORTED 0x10
|
||||
|
||||
#define SVGA_NUM_SUPPORTED_ROPS 16
|
||||
#define SVGA_ROP_ALL (MASK(SVGA_NUM_SUPPORTED_ROPS))
|
||||
#define SVGA_IS_VALID_ROP(rop) (rop < SVGA_NUM_SUPPORTED_ROPS)
|
||||
|
||||
/*
|
||||
* Ops
|
||||
* For each pixel, the four channels of the image are computed with:
|
||||
*
|
||||
* C = Ca * Fa + Cb * Fb
|
||||
*
|
||||
* where C, Ca, Cb are the values of the respective channels and Fa
|
||||
* and Fb come from the following table:
|
||||
*
|
||||
* BlendOp Fa Fb
|
||||
* ------------------------------------------
|
||||
* Clear 0 0
|
||||
* Src 1 0
|
||||
* Dst 0 1
|
||||
* Over 1 1-Aa
|
||||
* OverReverse 1-Ab 1
|
||||
* In Ab 0
|
||||
* InReverse 0 Aa
|
||||
* Out 1-Ab 0
|
||||
* OutReverse 0 1-Aa
|
||||
* Atop Ab 1-Aa
|
||||
* AtopReverse 1-Ab Aa
|
||||
* Xor 1-Ab 1-Aa
|
||||
* Add 1 1
|
||||
* Saturate min(1,(1-Ab)/Aa) 1
|
||||
*
|
||||
* Flags
|
||||
* You can use the following flags to achieve additional affects:
|
||||
*
|
||||
* Flag Effect
|
||||
* ------------------------------------------
|
||||
* ConstantSourceAlpha Ca = Ca * Param0
|
||||
* ConstantDestAlpha Cb = Cb * Param1
|
||||
*
|
||||
* Flag effects resolve before the op. For example
|
||||
* BlendOp == Add && Flags == ConstantSourceAlpha |
|
||||
* ConstantDestAlpha results in:
|
||||
*
|
||||
* C = (Ca * Param0) + (Cb * Param1)
|
||||
*/
|
||||
|
||||
#define SVGA_BLENDOP_CLEAR 0
|
||||
#define SVGA_BLENDOP_SRC 1
|
||||
#define SVGA_BLENDOP_DST 2
|
||||
#define SVGA_BLENDOP_OVER 3
|
||||
#define SVGA_BLENDOP_OVER_REVERSE 4
|
||||
#define SVGA_BLENDOP_IN 5
|
||||
#define SVGA_BLENDOP_IN_REVERSE 6
|
||||
#define SVGA_BLENDOP_OUT 7
|
||||
#define SVGA_BLENDOP_OUT_REVERSE 8
|
||||
#define SVGA_BLENDOP_ATOP 9
|
||||
#define SVGA_BLENDOP_ATOP_REVERSE 10
|
||||
#define SVGA_BLENDOP_XOR 11
|
||||
#define SVGA_BLENDOP_ADD 12
|
||||
#define SVGA_BLENDOP_SATURATE 13
|
||||
|
||||
#define SVGA_NUM_BLENDOPS 14
|
||||
#define SVGA_IS_VALID_BLENDOP(op) (op >= 0 && op < SVGA_NUM_BLENDOPS)
|
||||
|
||||
#define SVGA_BLENDFLAG_CONSTANT_SOURCE_ALPHA 0x01
|
||||
#define SVGA_BLENDFLAG_CONSTANT_DEST_ALPHA 0x02
|
||||
#define SVGA_NUM_BLENDFLAGS 2
|
||||
#define SVGA_BLENDFLAG_ALL (MASK(SVGA_NUM_BLENDFLAGS))
|
||||
#define SVGA_IS_VALID_BLENDFLAG(flag) ((flag & ~SVGA_BLENDFLAG_ALL) == 0)
|
||||
|
||||
|
||||
/*
|
||||
* FIFO offsets (viewed 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, /* Check SVGA3dHardwareVersion in svga3d_reg.h */
|
||||
SVGA_FIFO_PITCHLOCK,
|
||||
|
||||
/*
|
||||
* Always keep this last. It's not an offset with semantic value, but
|
||||
* rather a convenient way to produce the value of fifo[SVGA_FIFO_NUM_REGS]
|
||||
*/
|
||||
|
||||
SVGA_FIFO_NUM_REGS
|
||||
};
|
||||
|
||||
/*
|
||||
* FIFO Capabilities
|
||||
*
|
||||
* Fence -- Fence register and command are supported
|
||||
* Accel Front -- Front buffer only commands are supported
|
||||
* Pitch Lock -- Pitch lock register is supported
|
||||
*/
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/*
|
||||
* FIFO Flags
|
||||
*
|
||||
* Accel Front -- Driver should use front buffer only commands
|
||||
*/
|
||||
|
||||
#define SVGA_FIFO_FLAG_NONE 0
|
||||
#define SVGA_FIFO_FLAG_ACCELFRONT (1<<0)
|
||||
|
||||
|
||||
/*
|
||||
* Drawing object ID's, in the range 0 to SVGA_MAX_ID
|
||||
*/
|
||||
|
||||
#define SVGA_MAX_ID 499
|
||||
|
||||
/*
|
||||
* Macros to compute variable length items (sizes in 32-bit words, except
|
||||
* for SVGA_GLYPH_SCANLINE_SIZE, which is in bytes).
|
||||
*/
|
||||
|
||||
#define SVGA_BITMAP_SIZE(w,h) ((((w)+31) >> 5) * (h))
|
||||
#define SVGA_BITMAP_SCANLINE_SIZE(w) (( (w)+31 ) >> 5)
|
||||
#define SVGA_PIXMAP_SIZE(w,h,bpp) ((( ((w)*(bpp))+31 ) >> 5) * (h))
|
||||
#define SVGA_PIXMAP_SCANLINE_SIZE(w,bpp) (( ((w)*(bpp))+31 ) >> 5)
|
||||
#define SVGA_GLYPH_SIZE(w,h) ((((((w) + 7) >> 3) * (h)) + 3) >> 2)
|
||||
#define SVGA_GLYPH_SCANLINE_SIZE(w) (((w) + 7) >> 3)
|
||||
|
||||
/*
|
||||
* Increment from one scanline to the next of a bitmap or pixmap
|
||||
*/
|
||||
#define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32))
|
||||
#define SVGA_PIXMAP_INCREMENT(w,bpp) ((( ((w)*(bpp))+31 ) >> 5) * sizeof (uint32))
|
||||
|
||||
/*
|
||||
* Transparent color for DRAW_GLYPH_CLIPPED
|
||||
*/
|
||||
#define SVGA_COLOR_TRANSPARENT (~0)
|
||||
|
||||
/*
|
||||
* Commands in the command FIFO
|
||||
*/
|
||||
|
||||
#define SVGA_CMD_INVALID_CMD 0
|
||||
/* FIFO layout:
|
||||
<nothing> (well, undefined) */
|
||||
|
||||
#define SVGA_CMD_UPDATE 1
|
||||
/* FIFO layout:
|
||||
X, Y, Width, Height */
|
||||
|
||||
#define SVGA_CMD_RECT_FILL 2
|
||||
/* FIFO layout:
|
||||
Color, X, Y, Width, Height */
|
||||
|
||||
#define SVGA_CMD_RECT_COPY 3
|
||||
/* FIFO layout:
|
||||
Source X, Source Y, Dest X, Dest Y, Width, Height */
|
||||
|
||||
#define SVGA_CMD_DEFINE_BITMAP 4
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Width, Height, <scanlines> */
|
||||
|
||||
#define SVGA_CMD_DEFINE_BITMAP_SCANLINE 5
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Width, Height, Line #, scanline */
|
||||
|
||||
#define SVGA_CMD_DEFINE_PIXMAP 6
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Width, Height, Depth, <scanlines> */
|
||||
|
||||
#define SVGA_CMD_DEFINE_PIXMAP_SCANLINE 7
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Width, Height, Depth, Line #, scanline */
|
||||
|
||||
#define SVGA_CMD_RECT_BITMAP_FILL 8
|
||||
/* FIFO layout:
|
||||
Bitmap ID, X, Y, Width, Height, Foreground, Background */
|
||||
|
||||
#define SVGA_CMD_RECT_PIXMAP_FILL 9
|
||||
/* FIFO layout:
|
||||
Pixmap ID, X, Y, Width, Height */
|
||||
|
||||
#define SVGA_CMD_RECT_BITMAP_COPY 10
|
||||
/* FIFO layout:
|
||||
Bitmap ID, Source X, Source Y, Dest X, Dest Y,
|
||||
Width, Height, Foreground, Background */
|
||||
|
||||
#define SVGA_CMD_RECT_PIXMAP_COPY 11
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Source X, Source Y, Dest X, Dest Y, Width, Height */
|
||||
|
||||
#define SVGA_CMD_FREE_OBJECT 12
|
||||
/* FIFO layout:
|
||||
Object (pixmap, bitmap, ...) ID */
|
||||
|
||||
#define SVGA_CMD_RECT_ROP_FILL 13
|
||||
/* FIFO layout:
|
||||
Color, X, Y, Width, Height, ROP */
|
||||
|
||||
#define SVGA_CMD_RECT_ROP_COPY 14
|
||||
/* FIFO layout:
|
||||
Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
|
||||
|
||||
#define SVGA_CMD_RECT_ROP_BITMAP_FILL 15
|
||||
/* FIFO layout:
|
||||
ID, X, Y, Width, Height, Foreground, Background, ROP */
|
||||
|
||||
#define SVGA_CMD_RECT_ROP_PIXMAP_FILL 16
|
||||
/* FIFO layout:
|
||||
ID, X, Y, Width, Height, ROP */
|
||||
|
||||
#define SVGA_CMD_RECT_ROP_BITMAP_COPY 17
|
||||
/* FIFO layout:
|
||||
ID, Source X, Source Y,
|
||||
Dest X, Dest Y, Width, Height, Foreground, Background, ROP */
|
||||
|
||||
#define SVGA_CMD_RECT_ROP_PIXMAP_COPY 18
|
||||
/* FIFO layout:
|
||||
ID, Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
|
||||
|
||||
#define SVGA_CMD_DEFINE_CURSOR 19
|
||||
/* FIFO layout:
|
||||
ID, Hotspot X, Hotspot Y, Width, Height,
|
||||
Depth for AND mask, Depth for XOR mask,
|
||||
<scanlines for AND mask>, <scanlines for XOR mask> */
|
||||
|
||||
#define SVGA_CMD_DISPLAY_CURSOR 20
|
||||
/* FIFO layout:
|
||||
ID, On/Off (1 or 0) */
|
||||
|
||||
#define SVGA_CMD_MOVE_CURSOR 21
|
||||
/* FIFO layout:
|
||||
X, Y */
|
||||
|
||||
#define SVGA_CMD_DEFINE_ALPHA_CURSOR 22
|
||||
/* FIFO layout:
|
||||
ID, Hotspot X, Hotspot Y, Width, Height,
|
||||
<scanlines> */
|
||||
|
||||
#define SVGA_CMD_DRAW_GLYPH 23
|
||||
/* FIFO layout:
|
||||
X, Y, W, H, FGCOLOR, <stencil buffer> */
|
||||
|
||||
#define SVGA_CMD_DRAW_GLYPH_CLIPPED 24
|
||||
/* FIFO layout:
|
||||
X, Y, W, H, FGCOLOR, BGCOLOR, <cliprect>, <stencil buffer>
|
||||
Transparent color expands are done by setting BGCOLOR to ~0 */
|
||||
|
||||
#define SVGA_CMD_UPDATE_VERBOSE 25
|
||||
/* FIFO layout:
|
||||
X, Y, Width, Height, Reason */
|
||||
|
||||
#define SVGA_CMD_SURFACE_FILL 26
|
||||
/* FIFO layout:
|
||||
color, dstSurfaceOffset, x, y, w, h, rop */
|
||||
|
||||
#define SVGA_CMD_SURFACE_COPY 27
|
||||
/* FIFO layout:
|
||||
srcSurfaceOffset, dstSurfaceOffset, srcX, srcY,
|
||||
destX, destY, w, h, rop */
|
||||
|
||||
#define SVGA_CMD_SURFACE_ALPHA_BLEND 28
|
||||
/* FIFO layout:
|
||||
srcSurfaceOffset, dstSurfaceOffset, srcX, srcY,
|
||||
destX, destY, w, h, op (SVGA_BLENDOP*), flags (SVGA_BLENDFLAGS*),
|
||||
param1, param2 */
|
||||
|
||||
#define SVGA_CMD_FRONT_ROP_FILL 29
|
||||
/* FIFO layout:
|
||||
Color, X, Y, Width, Height, ROP */
|
||||
|
||||
#define SVGA_CMD_FENCE 30
|
||||
/* FIFO layout:
|
||||
Fence value */
|
||||
|
||||
#define SVGA_CMD_MAX 31
|
||||
|
||||
#define SVGA_CMD_MAX_ARGS 64
|
||||
|
||||
/*
|
||||
* Location and size of SVGA frame buffer and the FIFO.
|
||||
*/
|
||||
#define SVGA_VRAM_MAX_SIZE (16 * 1024 * 1024)
|
||||
|
||||
#define SVGA_VRAM_SIZE_WS (16 * 1024 * 1024) // 16 MB
|
||||
#define SVGA_MEM_SIZE_WS (2 * 1024 * 1024) // 2 MB
|
||||
#define SVGA_VRAM_SIZE_SERVER (4 * 1024 * 1024) // 4 MB
|
||||
#define SVGA_MEM_SIZE_SERVER (256 * 1024) // 256 KB
|
||||
|
||||
#if /* defined(VMX86_WGS) || */ defined(VMX86_SERVER)
|
||||
#define SVGA_VRAM_SIZE SVGA_VRAM_SIZE_SERVER
|
||||
#define SVGA_MEM_SIZE SVGA_MEM_SIZE_SERVER
|
||||
#else
|
||||
#define SVGA_VRAM_SIZE SVGA_VRAM_SIZE_WS
|
||||
#define SVGA_MEM_SIZE SVGA_MEM_SIZE_WS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SVGA_FB_START is the default starting address of the SVGA frame
|
||||
* buffer in the guest's physical address space.
|
||||
* SVGA_FB_START_BIGMEM is the starting address of the SVGA frame
|
||||
* buffer for VMs that have a large amount of physical memory.
|
||||
*
|
||||
* The address of SVGA_FB_START is set to 2GB - (SVGA_FB_MAX_SIZE + SVGA_MEM_SIZE),
|
||||
* thus the SVGA frame buffer sits at [SVGA_FB_START .. 2GB-1] in the
|
||||
* physical address space. Our older SVGA drivers for NT treat the
|
||||
* address of the frame buffer as a signed integer. For backwards
|
||||
* compatibility, we keep the default location of the frame buffer
|
||||
* at under 2GB in the address space. This restricts VMs to have "only"
|
||||
* up to ~2031MB (i.e., up to SVGA_FB_START) of physical memory.
|
||||
*
|
||||
* For VMs that want more memory than the ~2031MB, we place the SVGA
|
||||
* frame buffer at SVGA_FB_START_BIGMEM. This allows VMs to have up
|
||||
* to 3584MB, at least as far as the SVGA frame buffer is concerned
|
||||
* (note that there may be other issues that limit the VM memory
|
||||
* size). PCI devices use high memory addresses, so we have to put
|
||||
* SVGA_FB_START_BIGMEM low enough so that it doesn't overlap with any
|
||||
* of these devices. Placing SVGA_FB_START_BIGMEM at 0xE0000000
|
||||
* should leave plenty of room for the PCI devices.
|
||||
*
|
||||
* NOTE: All of that is only true for the 0710 chipset. As of the 0405
|
||||
* chipset, the framebuffer start is determined solely based on the value
|
||||
* the guest BIOS or OS programs into the PCI base address registers.
|
||||
*/
|
||||
#define SVGA_FB_LEGACY_START 0x7EFC0000
|
||||
#define SVGA_FB_LEGACY_START_BIGMEM 0xE0000000
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 1998-2001, VMware, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef VM_DEVICE_VERSION_H
|
||||
#define VM_DEVICE_VERSION_H
|
||||
|
||||
#define PCI_VENDOR_ID_VMWARE 0x15AD
|
||||
#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
|
||||
#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
|
||||
|
||||
#endif /* VM_DEVICE_VERSION_H */
|
||||
@@ -12,5 +12,6 @@ SubInclude HAIKU_TOP src add-ons accelerants tdfx ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants skeleton ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants vesa ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants via ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants vmware ;
|
||||
|
||||
SubIncludeGPL HAIKU_TOP src add-ons accelerants atimach64 ;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <[email protected]>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
void
|
||||
SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
|
||||
{
|
||||
int i;
|
||||
blit_params * b;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
b = &list[i];
|
||||
#if 0
|
||||
TRACE("BLIT %dx%d, %dx%d->%dx%d\n", b->width + 1, b->height + 1,
|
||||
b->src_left, b->src_top, b->dest_left, b->dest_top);
|
||||
#endif
|
||||
FifoBeginWrite();
|
||||
FifoWrite(SVGA_CMD_RECT_COPY);
|
||||
FifoWrite(b->src_left);
|
||||
FifoWrite(b->src_top);
|
||||
FifoWrite(b->dest_left);
|
||||
FifoWrite(b->dest_top);
|
||||
FifoWrite(b->width + 1);
|
||||
FifoWrite(b->height + 1);
|
||||
FifoEndWrite();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FILL_RECTANGLE(engine_token *et, uint32 colorIndex,
|
||||
fill_rect_params *list, uint32 count)
|
||||
{
|
||||
int i;
|
||||
fill_rect_params * f;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
f = &list[i];
|
||||
#if 0
|
||||
TRACE("FILL %lX, %dx%d->%dx%d\n", colorIndex,
|
||||
f->left, f->top, f->right, f->bottom);
|
||||
#endif
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FILL_SPAN(engine_token * et, uint32 colorIndex, uint16 * list, uint32 count)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
status_t
|
||||
SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x,
|
||||
uint16 hot_y, uint8 * andMask, uint8 * xorMask)
|
||||
{
|
||||
int i, shift;
|
||||
uint32 * alphaCursor;
|
||||
|
||||
TRACE("SET_CURSOR_SHAPE (%d, %d, %d, %d)\n", width, height, hot_x, hot_y);
|
||||
|
||||
/* Sanity check */
|
||||
if (hot_x >= width || hot_y >= height)
|
||||
return B_ERROR;
|
||||
|
||||
/* Build ARGB image */
|
||||
alphaCursor = calloc(1, height * width * sizeof(uint32));
|
||||
shift = 7;
|
||||
for (i = 0; i < height * width; i++) {
|
||||
if (!((*andMask >> shift) & 1)) {
|
||||
/* Opaque */
|
||||
alphaCursor[i] |= 0xFF000000;
|
||||
if (!((*xorMask >> shift) & 1))
|
||||
/* White */
|
||||
alphaCursor[i] |= 0x00FFFFFF;
|
||||
}
|
||||
if (--shift < 0) {
|
||||
shift = 7;
|
||||
andMask++;
|
||||
xorMask++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Give it to VMware */
|
||||
FifoBeginWrite();
|
||||
FifoWrite(SVGA_CMD_DEFINE_ALPHA_CURSOR);
|
||||
FifoWrite(CURSOR_ID);
|
||||
FifoWrite(hot_x);
|
||||
FifoWrite(hot_y);
|
||||
FifoWrite(width);
|
||||
FifoWrite(height);
|
||||
for (i = 0; i < height * width; i++)
|
||||
FifoWrite(alphaCursor[i]);
|
||||
FifoEndWrite();
|
||||
|
||||
free(alphaCursor);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MOVE_CURSOR(uint16 x, uint16 y)
|
||||
{
|
||||
uint16 pos[2];
|
||||
|
||||
//TRACE("MOVE_CURSOR (%d, %d)\n", x, y);
|
||||
|
||||
pos[0] = x;
|
||||
pos[1] = y;
|
||||
ioctl(gFd, VMWARE_MOVE_CURSOR, pos, sizeof(pos));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SHOW_CURSOR(bool isVisible)
|
||||
{
|
||||
TRACE("SHOW_CURSOR (%d)\n", isVisible);
|
||||
|
||||
ioctl(gFd, VMWARE_SHOW_CURSOR, &isVisible, sizeof(bool));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
static engine_token vmwareEngineToken = {1, B_2D_ACCELERATION, NULL};
|
||||
|
||||
uint32
|
||||
ACCELERANT_ENGINE_COUNT()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token * st,
|
||||
engine_token ** et)
|
||||
{
|
||||
ACQUIRE_BEN(gSi->engineLock);
|
||||
if (st)
|
||||
SYNC_TO_TOKEN(st);
|
||||
*et = &vmwareEngineToken;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RELEASE_ENGINE(engine_token * et, sync_token * st)
|
||||
{
|
||||
if (st)
|
||||
GET_SYNC_TOKEN(et, st);
|
||||
RELEASE_BEN(gSi->engineLock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WAIT_ENGINE_IDLE()
|
||||
{
|
||||
FifoSync();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GET_SYNC_TOKEN(engine_token * et, sync_token * st)
|
||||
{
|
||||
st->engine_id = et->engine_id;
|
||||
st->counter = 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SYNC_TO_TOKEN(sync_token * st)
|
||||
{
|
||||
WAIT_ENGINE_IDLE();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* UpdateThread: we explicitely need to tell VMware what and when
|
||||
* something should be refreshed from the frame buffer. Since the
|
||||
* app_server doesn't tell us what it's doing, we simply force a full
|
||||
* screen update every 1/50 second */
|
||||
|
||||
static int32
|
||||
UpdateThread(void *data)
|
||||
{
|
||||
bigtime_t begin, end, wait;
|
||||
|
||||
while (!gUpdateThreadDie) {
|
||||
begin = system_time();
|
||||
FifoUpdateFullscreen();
|
||||
end = system_time();
|
||||
|
||||
/* 50 Hz refresh */
|
||||
wait = 20000 - (end - begin);
|
||||
if (wait > 0)
|
||||
snooze(wait);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FifoPrintCapabilities(int c)
|
||||
{
|
||||
TRACE("fifo capabilities:\n");
|
||||
if (c & SVGA_FIFO_CAP_FENCE) TRACE("FENCE\n");
|
||||
if (c & SVGA_FIFO_CAP_ACCELFRONT) TRACE("ACCELFRONT\n");
|
||||
if (c & SVGA_FIFO_CAP_PITCHLOCK) TRACE("PITCHLOCK\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoInit()
|
||||
{
|
||||
uint32 *fifo = gSi->fifo;
|
||||
|
||||
/* Stop update thread, if any */
|
||||
if (gUpdateThread > B_OK) {
|
||||
status_t exitValue;
|
||||
gUpdateThreadDie = 1;
|
||||
wait_for_thread(gUpdateThread, &exitValue);
|
||||
}
|
||||
|
||||
gSi->fifoCapabilities = 0;
|
||||
gSi->fifoFlags = 0;
|
||||
if (gSi->capabilities & SVGA_CAP_EXTENDED_FIFO) {
|
||||
gSi->fifoCapabilities = fifo[SVGA_FIFO_CAPABILITIES];
|
||||
gSi->fifoFlags = fifo[SVGA_FIFO_FLAGS];
|
||||
FifoPrintCapabilities(gSi->fifoCapabilities);
|
||||
}
|
||||
|
||||
fifo[SVGA_FIFO_MIN] = gSi->fifoMin * 4;
|
||||
fifo[SVGA_FIFO_MAX] = gSi->fifoSize;
|
||||
fifo[SVGA_FIFO_NEXT_CMD] = fifo[SVGA_FIFO_MIN];
|
||||
fifo[SVGA_FIFO_STOP] = fifo[SVGA_FIFO_MIN];
|
||||
|
||||
gSi->fifoNext = fifo[SVGA_FIFO_NEXT_CMD];
|
||||
|
||||
/* Launch a new update thread */
|
||||
gUpdateThreadDie = 0;
|
||||
gUpdateThread = spawn_thread(UpdateThread, "VMware",
|
||||
B_REAL_TIME_DISPLAY_PRIORITY, NULL);
|
||||
resume_thread(gUpdateThread);
|
||||
|
||||
TRACE("init fifo: %ld -> %ld\n",
|
||||
fifo[SVGA_FIFO_MIN], fifo[SVGA_FIFO_MAX]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoSync()
|
||||
{
|
||||
ioctl(gFd, VMWARE_FIFO_SYNC, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoBeginWrite()
|
||||
{
|
||||
ACQUIRE_BEN(gSi->fifoLock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoWrite(uint32 value)
|
||||
{
|
||||
uint32 *fifo = gSi->fifo;
|
||||
uint32 fifoCapacity = fifo[SVGA_FIFO_MAX] - fifo[SVGA_FIFO_MIN];
|
||||
|
||||
/* If the fifo is full, sync it */
|
||||
if (fifo[SVGA_FIFO_STOP] == fifo[SVGA_FIFO_NEXT_CMD] + 4 ||
|
||||
fifo[SVGA_FIFO_STOP] + fifoCapacity == fifo[SVGA_FIFO_NEXT_CMD] + 4)
|
||||
FifoSync();
|
||||
|
||||
fifo[gSi->fifoNext / 4] = value;
|
||||
gSi->fifoNext = (gSi->fifoNext + 4) % fifoCapacity;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoEndWrite()
|
||||
{
|
||||
uint32 *fifo = gSi->fifo;
|
||||
|
||||
fifo[SVGA_FIFO_NEXT_CMD] = gSi->fifoNext;
|
||||
RELEASE_BEN(gSi->fifoLock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoUpdateFullscreen()
|
||||
{
|
||||
FifoBeginWrite();
|
||||
FifoWrite(SVGA_CMD_UPDATE);
|
||||
FifoWrite(0);
|
||||
FifoWrite(0);
|
||||
FifoWrite(gSi->dm.virtual_width);
|
||||
FifoWrite(gSi->dm.virtual_height);
|
||||
FifoEndWrite();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
void *
|
||||
get_accelerant_hook(uint32 feature, void *data)
|
||||
{
|
||||
switch (feature) {
|
||||
#define HOOK(x) case B_##x: return (void *)x
|
||||
#define ZERO(x) case B_##x: return (void *)0
|
||||
|
||||
/* initialization */
|
||||
HOOK(INIT_ACCELERANT);
|
||||
HOOK(CLONE_ACCELERANT);
|
||||
|
||||
HOOK(ACCELERANT_CLONE_INFO_SIZE);
|
||||
HOOK(GET_ACCELERANT_CLONE_INFO);
|
||||
HOOK(UNINIT_ACCELERANT);
|
||||
//HOOK(GET_ACCELERANT_DEVICE_INFO);
|
||||
HOOK(ACCELERANT_RETRACE_SEMAPHORE);
|
||||
|
||||
/* mode configuration */
|
||||
HOOK(ACCELERANT_MODE_COUNT);
|
||||
HOOK(GET_MODE_LIST);
|
||||
HOOK(PROPOSE_DISPLAY_MODE);
|
||||
HOOK(SET_DISPLAY_MODE);
|
||||
HOOK(GET_DISPLAY_MODE);
|
||||
HOOK(GET_FRAME_BUFFER_CONFIG);
|
||||
HOOK(GET_PIXEL_CLOCK_LIMITS);
|
||||
ZERO(MOVE_DISPLAY);
|
||||
HOOK(SET_INDEXED_COLORS);
|
||||
ZERO(GET_TIMING_CONSTRAINTS);
|
||||
|
||||
/* Power Managment (SetDisplayMode.c) */
|
||||
HOOK(DPMS_CAPABILITIES);
|
||||
HOOK(DPMS_MODE);
|
||||
HOOK(SET_DPMS_MODE);
|
||||
|
||||
/* Cursor managment (Cursor.c) */
|
||||
#if 0
|
||||
if (gSi->capabilities & SVGA_CAP_ALPHA_CURSOR) {
|
||||
HOOK(SET_CURSOR_SHAPE);
|
||||
HOOK(MOVE_CURSOR);
|
||||
HOOK(SHOW_CURSOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* synchronization */
|
||||
HOOK(ACCELERANT_ENGINE_COUNT);
|
||||
HOOK(ACQUIRE_ENGINE);
|
||||
HOOK(RELEASE_ENGINE);
|
||||
HOOK(WAIT_ENGINE_IDLE);
|
||||
HOOK(GET_SYNC_TOKEN);
|
||||
HOOK(SYNC_TO_TOKEN);
|
||||
|
||||
/* 2D acceleration (Acceleration.c) */
|
||||
if (gSi->capabilities & SVGA_CAP_RECT_COPY)
|
||||
HOOK(SCREEN_TO_SCREEN_BLIT);
|
||||
ZERO(FILL_RECTANGLE);
|
||||
ZERO(INVERT_RECTANGLE);
|
||||
ZERO(FILL_SPAN);
|
||||
ZERO(SCREEN_TO_SCREEN_TRANSPARENT_BLIT);
|
||||
ZERO(SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT);
|
||||
|
||||
#undef HOOK
|
||||
#undef ZERO
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
status_t
|
||||
GET_DISPLAY_MODE(display_mode *currentMode)
|
||||
{
|
||||
TRACE("GET_DISPLAY_MODE\n");
|
||||
|
||||
*currentMode = gSi->dm;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb)
|
||||
{
|
||||
TRACE("GET_FRAME_BUFFER_CONFIG\n");
|
||||
|
||||
afb->frame_buffer = gSi->fb + gSi->fbOffset;
|
||||
afb->frame_buffer_dma = gSi->fbDma + gSi->fbOffset;
|
||||
afb->bytes_per_row = gSi->bytesPerRow;
|
||||
|
||||
TRACE("fb: %p, fb_dma: %p, row: %d bytes\n", afb->frame_buffer,
|
||||
afb->frame_buffer_dma, afb->bytes_per_row);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high)
|
||||
{
|
||||
TRACE("GET_PIXEL_CLOCK_LIMITS\n");
|
||||
|
||||
/* ? */
|
||||
*low = 1;
|
||||
*high = 0xFFFFFFFF;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
sem_id
|
||||
ACCELERANT_RETRACE_SEMAPHORE()
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
int gFd;
|
||||
SharedInfo * gSi;
|
||||
area_id gSharedArea;
|
||||
int gAccelerantIsClone;
|
||||
thread_id gUpdateThread = B_ERROR;
|
||||
volatile int gUpdateThreadDie;
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
#ifndef GLOBAL_DATA_H
|
||||
#define GLOBAL_DATA_H
|
||||
|
||||
|
||||
#include <support/Debug.h>
|
||||
#undef TRACE
|
||||
#define TRACE(a...) _sPrintf("VMware: " ##a)
|
||||
|
||||
#include "DriverInterface.h"
|
||||
#include "generic.h"
|
||||
|
||||
/* Global variables */
|
||||
extern int gFd;
|
||||
extern SharedInfo *gSi;
|
||||
extern area_id gSharedArea;
|
||||
extern int gAccelerantIsClone;
|
||||
extern thread_id gUpdateThread;
|
||||
extern volatile int gUpdateThreadDie;
|
||||
|
||||
/* Fifo.c */
|
||||
void FifoInit();
|
||||
void FifoSync();
|
||||
void FifoBeginWrite();
|
||||
void FifoWrite(uint32 value);
|
||||
void FifoEndWrite();
|
||||
void FifoUpdateFullscreen();
|
||||
|
||||
#endif // GLOBAL_DATA_H
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "unistd.h"
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h"
|
||||
#include "fcntl.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
/* Initialization code shared between primary and cloned accelerants */
|
||||
static
|
||||
status_t InitCommon(int fd)
|
||||
{
|
||||
status_t ret;
|
||||
|
||||
/* Memorize the file descriptor */
|
||||
gFd = fd;
|
||||
|
||||
/* Contact driver and get a pointer to the registers and shared data */
|
||||
if ((ret = ioctl(fd, VMWARE_GET_PRIVATE_DATA, &gSharedArea,
|
||||
sizeof(area_id))) != B_OK) {
|
||||
TRACE("VMWARE_GET_PRIVATE_DATA failed (%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Clone the shared area for our use */
|
||||
if ((gSharedArea = clone_area("VMware shared", (void **)&gSi,
|
||||
B_ANY_ADDRESS, B_READ_AREA|B_WRITE_AREA, gSharedArea)) < 0) {
|
||||
TRACE("could not clone shared area (%d)\n", gSharedArea);
|
||||
return gSharedArea;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UninitCommon()
|
||||
{
|
||||
delete_area(gSharedArea);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
INIT_ACCELERANT(int fd)
|
||||
{
|
||||
status_t ret;
|
||||
|
||||
TRACE("INIT_ACCELERANT (%d)\n", fd);
|
||||
|
||||
gAccelerantIsClone = 0;
|
||||
|
||||
/* Common initialization for the primary accelerant and clones */
|
||||
if ((ret = InitCommon(fd)) == B_OK) {
|
||||
/* Init semaphores */
|
||||
INIT_BEN(gSi->engineLock);
|
||||
INIT_BEN(gSi->fifoLock);
|
||||
}
|
||||
|
||||
TRACE("INIT_ACCELERANT: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
ACCELERANT_CLONE_INFO_SIZE()
|
||||
{
|
||||
return MAX_SAMPLE_DEVICE_NAME_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GET_ACCELERANT_CLONE_INFO(void *data)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CLONE_ACCELERANT(void *data)
|
||||
{
|
||||
/* TODO */
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UNINIT_ACCELERANT()
|
||||
{
|
||||
UninitCommon();
|
||||
if (gAccelerantIsClone)
|
||||
close(gFd);
|
||||
else if (gUpdateThread > B_OK) {
|
||||
status_t exitValue;
|
||||
gUpdateThreadDie = 1;
|
||||
wait_for_thread(gUpdateThread, &exitValue);
|
||||
}
|
||||
ioctl(gFd, VMWARE_FIFO_STOP, NULL, 0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
SubDir HAIKU_TOP src add-ons accelerants vmware ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders [ FDirName graphics vmware ] ;
|
||||
UsePrivateHeaders graphics ;
|
||||
|
||||
Addon vmware.accelerant : accelerants :
|
||||
Acceleration.c
|
||||
Cursor.c
|
||||
EngineManagment.c
|
||||
Fifo.c
|
||||
GetAccelerantHook.c
|
||||
GetModeInfo.c
|
||||
GlobalData.c
|
||||
InitAccelerant.c
|
||||
ProposeDisplayMode.c
|
||||
SetDisplayMode.c
|
||||
: false
|
||||
;
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include <string.h>
|
||||
|
||||
#define MODE_FLAGS (B_8_BIT_DAC|B_PARALLEL_ACCESS)
|
||||
#define MODE_COUNT (sizeof(kModeList) / sizeof(display_mode))
|
||||
|
||||
static const display_mode kModeList[] =
|
||||
{ { { 19660, 640, 672, 744, 776, 480, 490, 494, 505, 0 }, B_RGB32_LITTLE, 640, 480, 0, 0, MODE_FLAGS }, /* 640x480@50Hz */
|
||||
{ { 25250, 800, 832, 920, 952, 500, 511, 515, 526, 0 }, B_RGB32_LITTLE, 800, 500, 0, 0, MODE_FLAGS }, /* 800x500@50Hz */
|
||||
{ { 30970, 800, 832, 944, 976, 600, 613, 618, 631, 0 }, B_RGB32_LITTLE, 800, 600, 0, 0, MODE_FLAGS }, /* 800x600@50Hz */
|
||||
{ { 41980, 1024, 1056, 1208, 1240, 640, 653, 659, 673, 0 }, B_RGB32_LITTLE, 1024, 640, 0, 0, MODE_FLAGS }, /* 1024x640@50Hz */
|
||||
{ { 51850, 1024, 1056, 1248, 1280, 768, 784, 791, 807, 0 }, B_RGB32_LITTLE, 1024, 768, 0, 0, MODE_FLAGS }, /* 1024x768@50Hz */
|
||||
{ { 59420, 1280, 1312, 1536, 1568, 720, 735, 741, 757, 0 }, B_RGB32_LITTLE, 1280, 720, 0, 0, MODE_FLAGS }, /* 1280x720@50Hz */
|
||||
{ { 64050, 1280, 1312, 1552, 1584, 768, 784, 791, 807, 0 }, B_RGB32_LITTLE, 1280, 768, 0, 0, MODE_FLAGS }, /* 1280x768@50Hz */
|
||||
{ { 65740, 1152, 1184, 1432, 1464, 854, 872, 879, 897, 0 }, B_RGB32_LITTLE, 1152, 854, 0, 0, MODE_FLAGS }, /* 1152x854@50Hz */
|
||||
{ { 67260, 1280, 1312, 1560, 1592, 800, 817, 824, 841, 0 }, B_RGB32_LITTLE, 1280, 800, 0, 0, MODE_FLAGS }, /* 1280x800@50Hz */
|
||||
{ { 86730, 1440, 1472, 1800, 1832, 900, 919, 927, 946, 0 }, B_RGB32_LITTLE, 1440, 900, 0, 0, MODE_FLAGS }, /* 1440x900@50Hz */
|
||||
{ { 90890, 1280, 1312, 1656, 1688, 1024, 1045, 1054, 1076, 0 }, B_RGB32_LITTLE, 1280, 1024, 0, 0, MODE_FLAGS }, /* 1280x1024@50Hz */
|
||||
{ { 102150, 1400, 1432, 1816, 1848, 1050, 1072, 1081, 1103, 0 }, B_RGB32_LITTLE, 1400, 1050, 0, 0, MODE_FLAGS }, /* 1400x1050@50Hz */
|
||||
{ { 121680, 1680, 1712, 2168, 2200, 1050, 1072, 1081, 1103, 0 }, B_RGB32_LITTLE, 1680, 1050, 0, 0, MODE_FLAGS }, /* 1680x1050@50Hz */
|
||||
{ { 137970, 1600, 1632, 2152, 2184, 1200, 1225, 1235, 1261, 0 }, B_RGB32_LITTLE, 1600, 1200, 0, 0, MODE_FLAGS }, /* 1600x1200@50Hz */
|
||||
{ { 164500, 1920, 1952, 2576, 2608, 1200, 1225, 1235, 1261, 0 }, B_RGB32_LITTLE, 1920, 1200, 0, 0, MODE_FLAGS }, /* 1920x1200@50Hz */
|
||||
{ { 179080, 1792, 1824, 2504, 2536, 1344, 1372, 1383, 1412, 0 }, B_RGB32_LITTLE, 1792, 1344, 0, 0, MODE_FLAGS }, /* 1792x1344@50Hz */
|
||||
{ { 194330, 1856, 1888, 2624, 2656, 1392, 1421, 1432, 1462, 0 }, B_RGB32_LITTLE, 1856, 1392, 0, 0, MODE_FLAGS }, /* 1856x1392@50Hz */
|
||||
{ { 210640, 1920, 1952, 2752, 2784, 1440, 1470, 1482, 1513, 0 }, B_RGB32_LITTLE, 1920, 1440, 0, 0, MODE_FLAGS }, /* 1920x1440@50Hz */
|
||||
{ { 245600, 2048, 2080, 3008, 3040, 1536, 1568, 1581, 1613, 0 }, B_RGB32_LITTLE, 2048, 1536, 0, 0, MODE_FLAGS }, /* 2048x1536@50Hz */
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low,
|
||||
const display_mode *high)
|
||||
{
|
||||
TRACE("PROPOSE_DISPLAY_MODE\n");
|
||||
|
||||
/* Arbitrary - I don't know if VMware really has a lower limit */
|
||||
if (target->virtual_width < 320 || target->virtual_height < 240)
|
||||
return B_ERROR;
|
||||
|
||||
if (target->virtual_width > gSi->maxWidth ||
|
||||
target->virtual_height > gSi->maxHeight)
|
||||
return B_ERROR;
|
||||
|
||||
if (target->space != B_RGB32_LITTLE)
|
||||
return B_ERROR;
|
||||
|
||||
/* Any such mode is OK, even if it isn't in our propose list */
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
ACCELERANT_MODE_COUNT()
|
||||
{
|
||||
TRACE("ACCELERANT_MODE_COUNT: %d\n", MODE_COUNT);
|
||||
return MODE_COUNT;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GET_MODE_LIST(display_mode * dm)
|
||||
{
|
||||
TRACE("GET_MODE_LIST\n");
|
||||
memcpy(dm, kModeList, sizeof(kModeList));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,541 @@
|
||||
|
||||
Copyright (C) 1999-2002 VMware, Inc.
|
||||
All Rights Reserved
|
||||
|
||||
The code here may be used/distributed under the terms of the standard
|
||||
XFree86 license.
|
||||
|
||||
|
||||
VMware SVGA Device Interface and Programming Model
|
||||
--------------------------------------------------
|
||||
|
||||
|
||||
Include Files
|
||||
-------------
|
||||
|
||||
svga_reg.h
|
||||
SVGA register definitions, SVGA capabilities, and FIFO command definitions.
|
||||
|
||||
svga_limits.h
|
||||
Included by svga_reg.h, defines maximum frame buffer and memory region
|
||||
sizes.
|
||||
|
||||
guest_os.h
|
||||
Values for the GUEST_ID register.
|
||||
|
||||
vm_basic_types.h
|
||||
Common type definitions.
|
||||
|
||||
vm_device_version.h
|
||||
PCI vendor ID's and related information.
|
||||
|
||||
|
||||
Programming the VMware SVGA Device
|
||||
----------------------------------
|
||||
|
||||
1. Reading/writing a register:
|
||||
|
||||
The SVGA registers are addressed by an index/value pair of 32 bit
|
||||
registers in the IO address space.
|
||||
|
||||
The 0710 VMware SVGA chipset (PCI device ID PCI_DEVICE_ID_VMWARE_SVGA) has
|
||||
its index and value ports hardcoded at:
|
||||
|
||||
index: SVGA_LEGACY_BASE_PORT + 4 * SVGA_INDEX_PORT
|
||||
value: SVGA_LEGACY_BASE_PORT + 4 * SVGA_VALUE_PORT
|
||||
|
||||
The 0405 VMware SVGA chipset (PCI device ID PCI_DEVICE_ID_VMWARE_SVGA2)
|
||||
determines its index and value ports as a function of the first base
|
||||
address register in its PCI configuration space as:
|
||||
|
||||
index: <Base Address Register 0> + SVGA_INDEX_PORT
|
||||
value: <Base Address Register 0> + SVGA_VALUE_PORT
|
||||
|
||||
To read a register:
|
||||
Set the index port to the index of the register, using a dword OUT
|
||||
Do a dword IN from the value port
|
||||
|
||||
To write a register:
|
||||
Set the index port to the index of the register, using a dword OUT
|
||||
Do a dword OUT to the value port
|
||||
|
||||
Example, setting the width to 1024:
|
||||
|
||||
mov eax, SVGA_REG_WIDTH
|
||||
mov edx, <SVGA Address Port>
|
||||
out dx, eax
|
||||
mov eax, 1024
|
||||
mov edx, <SVGA Value Port>
|
||||
out dx, eax
|
||||
|
||||
2. Initialization
|
||||
Check the version number
|
||||
loop:
|
||||
Write into SVGA_REG_ID the maximum SVGA_ID_* the driver supports.
|
||||
Read from SVGA_REG_ID.
|
||||
Check if it is the value you wrote.
|
||||
If yes, VMware SVGA device supports it
|
||||
If no, decrement SVGA_ID_* and goto loop
|
||||
This algorithm converges.
|
||||
|
||||
Map the frame buffer and the command FIFO
|
||||
Read SVGA_REG_FB_START, SVGA_REG_FB_SIZE, SVGA_REG_MEM_START,
|
||||
SVGA_REG_MEM_SIZE.
|
||||
Map the frame buffer (FB) and the FIFO memory (MEM)
|
||||
|
||||
Get the device capabilities and frame buffer dimensions
|
||||
Read SVGA_REG_CAPABILITIES, SVGA_REG_MAX_WIDTH, SVGA_REG_MAX_HEIGHT,
|
||||
and SVGA_REG_HOST_BITS_PER_PIXEL / SVGA_REG_BITS_PER_PIXEL.
|
||||
|
||||
Note: The capabilities can and do change without the PCI device ID
|
||||
changing or the SVGA_REG_ID changing. A driver should always check
|
||||
the capabilities register when loading before expecting any
|
||||
capabilities-determined feature to be available. See below for a list
|
||||
of capabilities as of this writing.
|
||||
|
||||
Note: If SVGA_CAP_8BIT_EMULATION is not set, then it is possible that
|
||||
SVGA_REG_HOST_BITS_PER_PIXEL does not exist and
|
||||
SVGA_REG_BITS_PER_PIXEL should be read instead.
|
||||
|
||||
Report the Guest Operating System
|
||||
Write SVGA_REG_GUEST_ID with the appropriate value from <guest_os.h>.
|
||||
While not required in any way, this is useful information for the
|
||||
virtual machine to have available for reporting and sanity checking
|
||||
purposes.
|
||||
|
||||
SetMode
|
||||
Set SVGA_REG_WIDTH, SVGA_REG_HEIGHT, SVGA_REG_BITS_PER_PIXEL
|
||||
Read SVGA_REG_FB_OFFSET
|
||||
(SVGA_REG_FB_OFFSET is the offset from SVGA_REG_FB_START of the
|
||||
visible portion of the frame buffer)
|
||||
Read SVGA_REG_BYTES_PER_LINE, SVGA_REG_DEPTH, SVGA_REG_PSEUDOCOLOR,
|
||||
SVGA_REG_RED_MASK, SVGA_REG_GREEN_MASK, SVGA_REG_BLUE_MASK
|
||||
|
||||
Note: SVGA_REG_BITS_PER_PIXEL is readonly if
|
||||
SVGA_CAP_8BIT_EMULATION is not set in the capabilities register. Even
|
||||
if it is set, values other than 8 and SVGA_REG_HOST_BITS_PER_PIXEL
|
||||
will be ignored.
|
||||
|
||||
Enable SVGA
|
||||
Set SVGA_REG_ENABLE to 1
|
||||
(to disable SVGA, set SVGA_REG_ENABLE to 0. Setting SVGA_REG_ENABLE
|
||||
to 0 also enables VGA.)
|
||||
|
||||
Initialize the command FIFO
|
||||
The FIFO is exclusively dword (32-bit) aligned. The first four
|
||||
dwords define the portion of the MEM area that is used for the
|
||||
command FIFO. These are values are all in byte offsets from the
|
||||
start of the MEM area.
|
||||
|
||||
A minimum sized FIFO would have these values:
|
||||
mem[SVGA_FIFO_MIN] = 16;
|
||||
mem[SVGA_FIFO_MAX] = 16 + (10 * 1024);
|
||||
mem[SVGA_FIFO_NEXT_CMD] = 16;
|
||||
mem[SVGA_FIFO_STOP] = 16;
|
||||
|
||||
Set SVGA_REG_CONFIG_DONE to 1 after these values have been set.
|
||||
|
||||
Note: Setting SVGA_REG_CONFIG_DONE to 0 will stop the device from
|
||||
reading the FIFO until it is reinitialized and SVGA_REG_CONFIG_DONE is
|
||||
set to 1 again.
|
||||
|
||||
3. SVGA command FIFO protocol
|
||||
The FIFO is empty when SVGA_FIFO_NEXT_CMD == SVGA_FIFO_STOP. The
|
||||
driver writes commands to the FIFO starting at the offset specified
|
||||
by SVGA_FIFO_NEXT_CMD, and then increments SVGA_FIFO_NEXT_CMD.
|
||||
|
||||
The FIFO is full when SVGA_FIFO_NEXT_CMD is one word before SVGA_FIFO_STOP.
|
||||
|
||||
When the FIFO becomes full, the FIFO should be sync'd
|
||||
|
||||
To sync the FIFO
|
||||
Write SVGA_REG_SYNC
|
||||
Read SVGA_REG_BUSY
|
||||
Wait for the value in SVGA_REG_BUSY to be 0
|
||||
|
||||
The FIFO should be sync'd before the driver touches the frame buffer, to
|
||||
guarantee that any outstanding BLT's are completed.
|
||||
|
||||
4. Cursor
|
||||
When SVGA_CAP_CURSOR is set, hardware cursor support is available. In
|
||||
practice, SVGA_CAP_CURSOR will only be set when SVGA_CAP_CURSOR_BYPASS is
|
||||
also set and drivers supporting a hardware cursor should only worry about
|
||||
SVGA_CAP_CURSOR_BYPASS and only use the FIFO to define the cursor. See
|
||||
below for more information.
|
||||
|
||||
5. Pseudocolor
|
||||
When the read-only register SVGA_REG_PSEUDOCOLOR is 1, the device is in a
|
||||
colormapped mode whose index width and color width are both SVGA_REG_DEPTH.
|
||||
Thus far, 8 is the only depth at which pseudocolor is ever used.
|
||||
|
||||
In pseudocolor, the colormap is programmed by writing to the SVGA palette
|
||||
registers. These start at SVGA_PALETTE_BASE and are interpreted as
|
||||
follows:
|
||||
|
||||
SVGA_PALETTE_BASE + 3*n - The nth red component
|
||||
SVGA_PALETTE_BASE + 3*n + 1 - The nth green component
|
||||
SVGA_PALETTE_BASE + 3*n + 2 - The nth blue component
|
||||
|
||||
And n ranges from 0 to ((1<<SVGA_REG_DEPTH) - 1).
|
||||
|
||||
|
||||
Drawing to the Screen
|
||||
---------------------
|
||||
|
||||
After initialization, the driver can write directly to the frame buffer. The
|
||||
updated frame buffer is not displayed immediately, but only when an update
|
||||
command is sent. The update command (SVGA_CMD_UPDATE) defines the rectangle
|
||||
in the frame buffer that has been modified by the driver, and causes that
|
||||
rectangle to be updated on the screen.
|
||||
|
||||
A complete driver can be developed this way. For increased performance,
|
||||
additional commands are available to accelerate common operations. The two
|
||||
most useful are SVGA_CMD_RECT_FILL and SVGA_CMD_RECT_COPY.
|
||||
|
||||
After issuing an accelerated command, the FIFO should be sync'd, as described
|
||||
above, before writing to the frame buffer.
|
||||
|
||||
Addendum on 7/11/2000
|
||||
---------------------
|
||||
|
||||
SVGA_REG_FB_OFFSET and SVGA_REG_BYTES_PER_LINE may change after SVGA_REG_WIDTH
|
||||
or SVGA_REG_HEIGHT is set. Also the VGA registers must be written to after
|
||||
setting SVGA_REG_ENABLE to 0 to change the display to a VGA mode.
|
||||
|
||||
Addendum on 11/29/2001
|
||||
---------------------
|
||||
|
||||
Actually, after changing any of SVGA_REG_WIDTH, SVGA_REG_HEIGHT, and
|
||||
SVGA_REG_BITS_PER_PIXEL, all of the registers listed in the 'SetMode'
|
||||
initialization section above should be reread. Additionally, when changing
|
||||
modes, it can be convenient to set SVGA_REG_ENABLE to 0, change
|
||||
SVGA_REG_WIDTH, SVGA_REG_HEIGHT, and SVGA_REG_BITS_PER_PIXEL (if available),
|
||||
and then set SVGA_REG_ENABLE to 1 again.
|
||||
|
||||
|
||||
Capabilities
|
||||
------------
|
||||
|
||||
The capabilities register (SVGA_REG_CAPABILITIES) is an array of bits that
|
||||
indicates the capabilities of the SVGA emulation. A driver should check
|
||||
SVGA_REG_CAPABILITIES every time it loads before relying on any feature that
|
||||
is only optionally available.
|
||||
|
||||
Some of the capabilities determine which FIFO commands are available. This
|
||||
table shows which capability indicates support for which command.
|
||||
|
||||
FIFO Command Capability
|
||||
------------ ----------
|
||||
|
||||
SVGA_CMD_RECT_FILL SVGA_CAP_RECT_FILL
|
||||
SVGA_CMD_RECT_COPY SVGA_CAP_RECT_COPY
|
||||
SVGA_CMD_DEFINE_BITMAP SVGA_CAP_OFFSCREEN
|
||||
SVGA_CMD_DEFINE_BITMAP_SCANLINE SVGA_CAP_OFFSCREEN
|
||||
SVGA_CMD_DEFINE_PIXMAP SVGA_CAP_OFFSCREEN
|
||||
SVGA_CMD_DEFINE_PIXMAP_SCANLINE SVGA_CAP_OFFSCREEN
|
||||
SVGA_CMD_RECT_BITMAP_FILL SVGA_CAP_RECT_PAT_FILL
|
||||
SVGA_CMD_RECT_PIXMAP_FILL SVGA_CAP_RECT_PAT_FILL
|
||||
SVGA_CMD_RECT_BITMAP_COPY SVGA_CAP_RECT_PAT_FILL
|
||||
SVGA_CMD_RECT_PIXMAP_COPY SVGA_CAP_RECT_PAT_FILL
|
||||
SVGA_CMD_FREE_OBJECT SVGA_CAP_OFFSCREEN
|
||||
SVGA_CMD_RECT_ROP_FILL SVGA_CAP_RECT_FILL +
|
||||
SVGA_CAP_RASTER_OP
|
||||
SVGA_CMD_RECT_ROP_COPY SVGA_CAP_RECT_COPY +
|
||||
SVGA_CAP_RASTER_OP
|
||||
SVGA_CMD_RECT_ROP_BITMAP_FILL SVGA_CAP_RECT_PAT_FILL +
|
||||
SVGA_CAP_RASTER_OP
|
||||
SVGA_CMD_RECT_ROP_PIXMAP_FILL SVGA_CAP_RECT_PAT_FILL +
|
||||
SVGA_CAP_RASTER_OP
|
||||
SVGA_CMD_RECT_ROP_BITMAP_COPY SVGA_CAP_RECT_PAT_FILL +
|
||||
SVGA_CAP_RASTER_OP
|
||||
SVGA_CMD_RECT_ROP_PIXMAP_COPY SVGA_CAP_RECT_PAT_FILL +
|
||||
SVGA_CAP_RASTER_OP
|
||||
SVGA_CMD_DEFINE_CURSOR SVGA_CAP_CURSOR
|
||||
SVGA_CMD_DISPLAY_CURSOR SVGA_CAP_CURSOR
|
||||
SVGA_CMD_MOVE_CURSOR SVGA_CAP_CURSOR
|
||||
SVGA_CMD_DEFINE_ALPHA_CURSOR SVGA_CAP_ALPHA_CURSOR
|
||||
SVGA_CMD_DRAW_GLYPH SVGA_CAP_GLYPH
|
||||
SVGA_CMD_DRAW_GLYPH_CLIPPED SVGA_CAP_GLYPH_CLIPPING
|
||||
|
||||
Note: SVGA_CMD_DISPLAY_CURSOR and SVGA_CMD_MOVE_CURSOR should not be used.
|
||||
Drivers wishing hardware cursor support should use cursor bypass (see below).
|
||||
|
||||
Other capabilities indicate other functionality as described below:
|
||||
|
||||
SVGA_CAP_CURSOR_BYPASS
|
||||
The hardware cursor can be drawn via SVGA Registers (without requiring
|
||||
the FIFO be synchronized and will be drawn potentially before any
|
||||
outstanding unprocessed FIFO commands).
|
||||
|
||||
Note: Without SVGA_CAP_CURSOR_BYPASS_2, cursors drawn this way still
|
||||
appear in the guest's framebuffer and need to be turned off before any
|
||||
save under / overlapping drawing and turned back on after. This can
|
||||
cause very noticeable cursor flicker.
|
||||
|
||||
SVGA_CAP_CURSOR_BYPASS_2
|
||||
Instead of turning the cursor off and back on around any overlapping
|
||||
drawing, the driver can write SVGA_CURSOR_ON_REMOVE_FROM_FB and
|
||||
SVGA_CURSOR_ON_RESTORE_TO_FB to SVGA_REG_CURSOR_ON. In almost all
|
||||
cases these are NOPs and the cursor will be remain visible without
|
||||
appearing in the guest framebuffer. In 'direct graphics' modes like
|
||||
Linux host fullscreen local displays, however, the cursor will still
|
||||
be drawn in the framebuffer, still flicker, and be drawn incorrectly
|
||||
if a driver does not use SVGA_CURSOR_ON_REMOVE_FROM_FB / RESTORE_TO_FB.
|
||||
|
||||
SVGA_CAP_8BIT_EMULATION
|
||||
SVGA_REG_BITS_PER_PIXEL is writable and can be set to either 8 or
|
||||
SVGA_REG_HOST_BITS_PER_PIXEL. Otherwise the only SVGA modes available
|
||||
inside a virtual machine must match the host's bits per pixel.
|
||||
|
||||
Note: Some versions which lack SVGA_CAP_8BIT_EMULATION also lack the
|
||||
SVGA_REG_HOST_BITS_PER_PIXEL and a driver should assume
|
||||
SVGA_REG_BITS_PER_PIXEL is both read-only and initialized to the only
|
||||
available value if SVGA_CAP_8BIT_EMULATION is not set.
|
||||
|
||||
SVGA_CAP_OFFSCREEN_1
|
||||
SVGA_CMD_RECT_FILL, SVGA_CMD_RECT_COPY, SVGA_CMD_RECT_ROP_FILL,
|
||||
SVGA_CMD_RECT_ROP_COPY can operate with a source or destination (or
|
||||
both) in offscreen memory.
|
||||
|
||||
Usable offscreen memory is a rectangle located below the last scanline
|
||||
of the visible memory:
|
||||
x1 = 0
|
||||
y1 = (SVGA_REG_FB_SIZE + SVGA_REG_BYTES_PER_LINE - 1) /
|
||||
SVGA_REG_BYTES_PER_LINE
|
||||
x2 = SVGA_REG_BYTES_PER_LINE / SVGA_REG_DEPTH
|
||||
y2 = SVGA_REG_VRAM_SIZE / SVGA_REG_BYTES_PER_LINE
|
||||
|
||||
|
||||
Cursor Handling
|
||||
---------------
|
||||
|
||||
Starting with GSX Server Beta 3 (after 11/15/2000), hardware cursor support
|
||||
was added. Actually, both a hardware cursor via the FIFO (SVGA_CAP_CURSOR)
|
||||
and a hardware cursor via the SVGA registers (SVGA_CAP_CURSOR_BYPASS) were
|
||||
added. SVGA_CAP_CURSOR was never available without SVGA_CAP_CURSOR_BYPASS and
|
||||
the FIFO hardware cursor should never be used and may be removed without
|
||||
warning in the future.
|
||||
|
||||
Cursor bypass is programmed using the two FIFO commands SVGA_CMD_DEFINE_CURSOR
|
||||
and SVGA_CMD_DEFINE_ALPHA_CURSOR in conjunction with the SVGA registers
|
||||
SVGA_REG_CURSOR_ID, SVGA_REG_CURSOR_X, SVGA_REG_CURSOR_Y, and
|
||||
SVGA_REG_CURSOR_ON.
|
||||
|
||||
A driver defines an AND/XOR hardware cursor using SVGA_CMD_DEFINE_CURSOR to
|
||||
assign an ID and establish the AND and XOR masks with the hardware. A driver
|
||||
uses SVGA_CMD_DEFINE_ALPHA_CURSOR to define a 32 bit mask whose top 8 bits are
|
||||
used to blend the cursor image with the pixels it covers. Alpha cursor
|
||||
support is only available when SVGA_CAP_ALPHA_CURSOR is set.
|
||||
|
||||
Once a cursor is defined, a driver can draw it to the screen at any time by
|
||||
writing the SVGA_REG_CURSOR_ID register with the ID used when the cursor was
|
||||
defined, writing SVGA_REG_CURSOR_X and SVGA_REG_CURSOR_Y with the location of
|
||||
the cursor, and SVGA_CURSOR_ON_SHOW to SVGA_REG_CURSOR_ON. The drawing occurs
|
||||
when SVGA_REG_CURSOR_ON is written.
|
||||
|
||||
Writing SVGA_CURSOR_ON_HIDE to SVGA_REG_CURSOR_ON will turn the cursor off and
|
||||
make it vanish from the display and, if present, from the framebuffer.
|
||||
SVGA_CURSOR_ON_REMOVE_FROM_FB will ensure the cursor is not in the
|
||||
framebuffer, but will only turn it off if there's no other way to remove it.
|
||||
SVGA_CURSOR_ON_RESTORE_TO_FB is the complement to
|
||||
SVGA_CURSOR_ON_REMOVE_FROM_FB. Whenever possible, the device will not put the
|
||||
cursor in the framebuffer and Remove From / Restore To will be NOPs.
|
||||
|
||||
Note: The cursor must be out of the frame buffer before the driver (or any
|
||||
agent in the virtual machine) touches an overlapping portion of the frame
|
||||
buffer, because it is actually drawn into the frame buffer memory in the
|
||||
case of direct graphics mode (e.g. full screen mode on Linux). The cursor
|
||||
does not have to be touched before issuing an accelerated command via the
|
||||
command FIFO, this case is handled by the SVGA device.
|
||||
|
||||
Note: If SVGA_CAP_CURSOR_BYPASS2 is not present, the driver must use
|
||||
SVGA_CURSOR_ON_HIDE and SVGA_CURSOR_ON_HIDE to be certain the cursor is out of
|
||||
the framebuffer.
|
||||
|
||||
|
||||
Driver Version Numbers
|
||||
----------------------
|
||||
|
||||
The SVGA drivers use the following convention for their version numbers:
|
||||
|
||||
Version 10.0 - The first version that uses the FIFO
|
||||
Version 10.1 - The version that uses the hardware cursor emulation via the FIFO
|
||||
Version 10.2 - The version that uses the cursor that bypasses the FIFO
|
||||
Version 10.3 - The version that can also support the 0405 chipset
|
||||
Version 10.4 - The version that knows about SVGA_CAP_CURSOR_BYPASS2
|
||||
Version 10.5 - [Never released or well defined]
|
||||
Version 10.6 - The version that knows about SVGA_CAP_8BIT_EMULATION
|
||||
Version 10.7 - The version that knows about SVGA_CAP_ALPHA_CURSOR
|
||||
Version 10.8 - The version that knows about SVGA_CAP_GLYPH
|
||||
Version 10.9 - The version that knows about SVGA_CAP_OFFSCREEN_1
|
||||
|
||||
Note that this is merely the convention used by SVGA drivers written and
|
||||
maintained by VMware, Inc. and describes the capabilities of the driver, not
|
||||
the virtual hardware. An SVGA driver can only use the intersection of the
|
||||
functionality it supports and the functionality available in the virtual SVGA
|
||||
hardware.
|
||||
|
||||
|
||||
Frequently Asked Questions
|
||||
--------------------------
|
||||
|
||||
1. My driver doesn't display anything, what's going on?
|
||||
|
||||
First check if you are issuing an SVGA_CMD_UPDATE after drawing to
|
||||
the screen. Another check you can do is to run your driver in full
|
||||
screen mode on a Linux host. In this case you are drawing directly
|
||||
on the frame buffer, so what you draw to the screen will be immediately
|
||||
visible. If nothing is visible in this case, then most likely your
|
||||
driver hasn't mapped the frame buffer correctly.
|
||||
|
||||
A discrepancy between what you get in full screen mode and what you
|
||||
get in window mode indicates that you have a missing or incorrect
|
||||
update command.
|
||||
|
||||
|
||||
2. What's the difference between bitmaps and pixmaps?
|
||||
|
||||
Pixmaps have the same depth as the screen, while bitmaps have depth one.
|
||||
When a bitmap is drawn, the command also takes two colors, foreground and
|
||||
background. The set bits in the bitmap are replaced with the foreground
|
||||
color, and the unset bits are replaced with the background color.
|
||||
|
||||
Pixmaps, on the other hand, can be directly copied to the screen.
|
||||
|
||||
|
||||
3. What's the significance of the ROP in the commands SVGA_CMD_RECT_ROP_FILL,
|
||||
SVGA_CMD_RECT_ROP_BITMAP_COPY, etc. ?
|
||||
|
||||
The ROP in the ...ROP... commands is a raster operation. It has the same
|
||||
significance (and encoding) as it does in X. The ROP value SVGA_ROP_COPY
|
||||
means the source is copied to the destination, which makes these commands the
|
||||
same as their non-ROP counterparts. The most commonly used raster operation
|
||||
other than copy is probably SVGA_ROP_XOR, which combines the source and
|
||||
destination using exclusive-or.
|
||||
|
||||
|
||||
4. Tell me more about bitmaps and pixmaps. For example, the macro
|
||||
SVGA_CMD_DEFINE_BITMAP has a field <scanlines>. What should this be
|
||||
set to? Likewise with SVGA_CMD_DEFINE_PIXMAP. And when should the
|
||||
SCANLINE macros be used?
|
||||
|
||||
OK, I'll use pixmaps as an example. First you have to define the pixmap:
|
||||
|
||||
#define SVGA_CMD_DEFINE_PIXMAP 6
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Width, Height, Depth, <scanlines> */
|
||||
|
||||
The ID is something you choose, which you subsequently use to refer to
|
||||
this pixmap. It must be an integer between 0 and SVGA_MAX_ID.
|
||||
|
||||
The width and height and depth are the dimensions of the pixmap. For now,
|
||||
the depth of the pixmap has to match the depth of the screen.
|
||||
|
||||
The scanlines are the pixels that make up the pixmap, arranged one row
|
||||
at a time. Each row is required to be 32-bit aligned. The macros
|
||||
SVGA_PIXMAP_SCANLINE_SIZE and SVGA_PIXMAP_SIZE give the size of a
|
||||
single scanline, and the size of the entire pixmap, respectively, in
|
||||
32-bit words.
|
||||
|
||||
The second step is to use it:
|
||||
|
||||
#define SVGA_CMD_RECT_PIXMAP_FILL 9
|
||||
/* FIFO layout:
|
||||
Pixmap ID, X, Y, Width, Height */
|
||||
|
||||
The ID here is the one you chose when defining the pixmap. X, Y,
|
||||
Width, and Height define a rectangle on the screen that is to be filled
|
||||
with the pixmap. The pixmap is screen aligned, which means that the
|
||||
coordinates in the pixmap are defined by the screen coordinates modulo
|
||||
the pixmap dimensions.
|
||||
|
||||
If you want a different alignment between the screen and the pixmap,
|
||||
then you can use this command, which allows the pixmap coordinates to
|
||||
be defined:
|
||||
|
||||
#define SVGA_CMD_RECT_PIXMAP_COPY 11
|
||||
/* FIFO layout:
|
||||
Pixmap ID, Source X, Source Y, Dest X, Dest Y, Width,
|
||||
Height */
|
||||
|
||||
The Source X and Source Y are pixmap coordinates, and the Dest X and
|
||||
Dest Y are screen coordinates.
|
||||
|
||||
|
||||
5. OK, now it works briefly, then stops displaying anything. Also,
|
||||
my log file is filled with lines like:
|
||||
Unknown Command 0xff in SVGA command FIFO
|
||||
What's happening?
|
||||
|
||||
The most common problem at this point is that the FIFO gets out
|
||||
of sync. This can happen if the amount of data in the FIFO doesn't
|
||||
match what the VMware SVGA device expects. To track this down, try
|
||||
to isolate the particular command which causes the problem.
|
||||
|
||||
Another way this can happen is if the wraparound in the FIFO isn't
|
||||
done correctly. Here is some example code for writing to the FIFO
|
||||
(mem is an array of 32-bit integers that points to the FIFO memory
|
||||
region):
|
||||
|
||||
while (TRUE) {
|
||||
fifo_min = mem[SVGA_FIFO_MIN] / 4;
|
||||
fifo_max = mem[SVGA_FIFO_MAX] / 4;
|
||||
fifo_next = mem[SVGA_FIFO_NEXT_CMD] / 4;
|
||||
fifo_stop = mem[SVGA_FIFO_STOP] / 4;
|
||||
|
||||
tmp_next = fifo_next+1;
|
||||
if (tmp_next == fifo_max)
|
||||
tmp_next = fifo_min; // Wraparound
|
||||
|
||||
if (tmp_next == fifo_stop) {
|
||||
sync_fifo(); // FIFO full
|
||||
continue; // retry
|
||||
}
|
||||
|
||||
mem[fifo_next] = item;
|
||||
mem[SVGA_FIFO_NEXT_CMD] = tmp_next * 4;
|
||||
break;
|
||||
}
|
||||
|
||||
This isn't the most efficient code, but it should work. It's important
|
||||
to do the increment with wraparound before the FIFO full check, and to
|
||||
check FIFO full before updating the next command pointer.
|
||||
|
||||
|
||||
6. My driver tries to switch modes and either nothing happens or the
|
||||
display becomes completely garbled. What's going on?
|
||||
|
||||
When you change modes, make very sure you reread all of the registers listed
|
||||
above under SetMode. Getting the pitch (SVGA_REG_BYTES_PER_LINE) incorrect
|
||||
will cause a heavily garbled display. Also, if you change
|
||||
SVGA_REG_BITS_PER_PIXEL, make certain that SVGA_CAP_8BIT_EMULATION is present
|
||||
in the SVGA_REG_CAPABILITIES register. Also, even with 8 bit emulation, the
|
||||
driver must still use either 8 bpp or SVGA_REG_HOST_BITS_PER_PIXEL bpp,
|
||||
nothing else.
|
||||
|
||||
|
||||
7. Why does my driver's hardware cursor work when my virtual machine is in
|
||||
window mode, but draw/erase incorrectly or in garbled locations in fullscreen
|
||||
mode?
|
||||
|
||||
You need to make sure you use SVGA_CURSOR_ON_REMOVE_FROM_FB and
|
||||
SVGA_CURSOR_ON_RESTORE_TO_FB _every_ time your driver or the virtual machine
|
||||
touches a region of the framebuffer that overlaps the cursor. If you forget
|
||||
to remove it then it can show up when doing save-under operations or get mixed
|
||||
in with other drawing. If you forget to restore it then can disappear. You
|
||||
also need to make sure SVGA_CAP_CURSOR_BYPASS2 is available, or else you will
|
||||
have to use SVGA_CURSOR_ON_SHOW and SVGA_CURSOR_ON_HIDE (which will flicker,
|
||||
even in window mode), or else a software cursor. Newer version of the virtual
|
||||
SVGA hardware will never put the hardware cursor in the framebuffer while in
|
||||
window mode, so everything will appear to work correctly there.
|
||||
|
||||
|
||||
8. Why do my accelerated glyphs look funny? OR Why does the fifo complain
|
||||
about invalid commands when I draw accelerated glyphs?
|
||||
|
||||
The bitmap data passed to SVGA_CMD_DRAW_GLYPH_* must not have any per-scanline
|
||||
alignment. If there are any remaining bits left in the last byte of a scanline,
|
||||
the first bits of the next scanline should use them.
|
||||
|
||||
The bitmap data as a whole must be 4 byte aligned.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
status_t
|
||||
SET_DISPLAY_MODE(display_mode * modeToSet)
|
||||
{
|
||||
display_mode bounds, target;
|
||||
int bpp;
|
||||
|
||||
TRACE("SET_DISPLAY_MODE\n");
|
||||
|
||||
/* Ask for the specific mode */
|
||||
target = bounds = *modeToSet;
|
||||
if (PROPOSE_DISPLAY_MODE(&target, &bounds, &bounds) == B_ERROR)
|
||||
return B_ERROR;
|
||||
|
||||
bpp = BppForSpace(target.space);
|
||||
|
||||
TRACE("setting %dx%dx%d\n", target.virtual_width,
|
||||
target.virtual_height, bpp);
|
||||
|
||||
gSi->dm = target;
|
||||
|
||||
/* Disable SVGA while we switch */
|
||||
ioctl(gFd, VMWARE_FIFO_STOP, NULL, 0);
|
||||
|
||||
/* Re-init fifo */
|
||||
FifoInit();
|
||||
|
||||
/* Set resolution. This also updates the frame buffer config in the
|
||||
* shared area */
|
||||
ioctl(gFd, VMWARE_SET_MODE, &target, sizeof(target));
|
||||
|
||||
/* Blank the screen to avoid ugly glitches until the app_server redraws */
|
||||
memset(gSi->fb, 0, target.virtual_height * gSi->bytesPerRow);
|
||||
FifoUpdateFullscreen();
|
||||
|
||||
/* Re-enable SVGA */
|
||||
ioctl(gFd, VMWARE_FIFO_START, NULL, 0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MOVE_DISPLAY(uint16 hDisplayStart, uint16 vDisplayStart)
|
||||
{
|
||||
TRACE("MOVE_DISPLAY (%d, %d)\n", hDisplayStart, vDisplayStart);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags)
|
||||
{
|
||||
TRACE("SET_INDEXED_COLORS\n");
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* DPMS_CAPABILITIES: reports DPMS capabilities (on, stand by,
|
||||
* suspend, off) */
|
||||
uint32
|
||||
DPMS_CAPABILITIES()
|
||||
{
|
||||
/* We stay always on */
|
||||
return B_DPMS_ON;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* DPMS_MODE: reports the current DPMS mode */
|
||||
uint32
|
||||
DPMS_MODE()
|
||||
{
|
||||
return B_DPMS_ON;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* SET_DPMS_MODE: puts the display into one of the DPMS modes */
|
||||
status_t
|
||||
SET_DPMS_MODE(uint32 flags)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
#ifndef GENERIC_H
|
||||
#define GENERIC_H
|
||||
|
||||
status_t INIT_ACCELERANT(int fd);
|
||||
ssize_t ACCELERANT_CLONE_INFO_SIZE(void);
|
||||
void GET_ACCELERANT_CLONE_INFO(void *data);
|
||||
status_t CLONE_ACCELERANT(void *data);
|
||||
void UNINIT_ACCELERANT(void);
|
||||
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi);
|
||||
sem_id ACCELERANT_RETRACE_SEMAPHORE(void);
|
||||
|
||||
uint32 ACCELERANT_MODE_COUNT(void);
|
||||
status_t GET_MODE_LIST(display_mode *dm);
|
||||
status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const display_mode *high);
|
||||
status_t SET_DISPLAY_MODE(display_mode *mode_to_set);
|
||||
status_t GET_DISPLAY_MODE(display_mode *current_mode);
|
||||
status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *a_frame_buffer);
|
||||
status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high);
|
||||
status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start);
|
||||
status_t GET_TIMING_CONSTRAINTS(display_timing_constraints *dtc);
|
||||
void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags);
|
||||
|
||||
uint32 DPMS_CAPABILITIES(void);
|
||||
uint32 DPMS_MODE(void);
|
||||
status_t SET_DPMS_MODE(uint32 dpms_flags);
|
||||
|
||||
status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask);
|
||||
void MOVE_CURSOR(uint16 x, uint16 y);
|
||||
void SHOW_CURSOR(bool is_visible);
|
||||
|
||||
uint32 ACCELERANT_ENGINE_COUNT(void);
|
||||
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et);
|
||||
status_t RELEASE_ENGINE(engine_token *et, sync_token *st);
|
||||
void WAIT_ENGINE_IDLE(void);
|
||||
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st);
|
||||
status_t SYNC_TO_TOKEN(sync_token *st);
|
||||
|
||||
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count);
|
||||
void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
|
||||
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count);
|
||||
|
||||
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count);
|
||||
|
||||
#endif
|
||||
@@ -12,5 +12,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics tdfx ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics skeleton ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics vesa ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics via ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics vmware ;
|
||||
|
||||
SubIncludeGPL HAIKU_TOP src add-ons kernel drivers graphics atimach64 ;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers graphics vmware ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders [ FDirName graphics vmware ] ;
|
||||
UsePrivateHeaders [ FDirName graphics common ] ;
|
||||
UsePrivateHeaders graphics ;
|
||||
|
||||
KernelAddon vmware :
|
||||
driver.c
|
||||
device.c
|
||||
;
|
||||
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <PCI.h>
|
||||
#include <OS.h>
|
||||
#include <graphic_driver.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define get_pci(o, s) (*gPciBus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s))
|
||||
#define set_pci(o, s, v) (*gPciBus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v))
|
||||
|
||||
|
||||
static void
|
||||
PrintCapabilities(uint32 c)
|
||||
{
|
||||
TRACE("capabilities:\n");
|
||||
if (c & SVGA_CAP_RECT_FILL) TRACE("RECT_FILL\n");
|
||||
if (c & SVGA_CAP_RECT_COPY) TRACE("RECT_COPY\n");
|
||||
if (c & SVGA_CAP_RECT_PAT_FILL) TRACE("RECT_PAT_FILL\n");
|
||||
if (c & SVGA_CAP_LEGACY_OFFSCREEN) TRACE("LEGACY_OFFSCREEN\n");
|
||||
if (c & SVGA_CAP_RASTER_OP) TRACE("RASTER_OP\n");
|
||||
if (c & SVGA_CAP_CURSOR) TRACE("CURSOR\n");
|
||||
if (c & SVGA_CAP_CURSOR_BYPASS) TRACE("CURSOR_BYPASS\n");
|
||||
if (c & SVGA_CAP_CURSOR_BYPASS_2) TRACE("CURSOR_BYPASS_2\n");
|
||||
if (c & SVGA_CAP_8BIT_EMULATION) TRACE("8BIT_EMULATION\n");
|
||||
if (c & SVGA_CAP_ALPHA_CURSOR) TRACE("ALPHA_CURSOR\n");
|
||||
if (c & SVGA_CAP_GLYPH) TRACE("GLYPH\n");
|
||||
if (c & SVGA_CAP_GLYPH_CLIPPING) TRACE("GLYPH_CLIPPING\n");
|
||||
if (c & SVGA_CAP_OFFSCREEN_1) TRACE("OFFSCREEN_1\n");
|
||||
if (c & SVGA_CAP_ALPHA_BLEND) TRACE("ALPHA_BLEND\n");
|
||||
if (c & SVGA_CAP_3D) TRACE("3D\n");
|
||||
if (c & SVGA_CAP_EXTENDED_FIFO) TRACE("EXTENDED_FIFO\n");
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
CheckCapabilities()
|
||||
{
|
||||
SharedInfo *si = gPd->si;
|
||||
uint32 id;
|
||||
|
||||
/* Needed to read/write registers */
|
||||
si->indexPort = gPd->pcii.u.h0.base_registers[0] + SVGA_INDEX_PORT;
|
||||
si->valuePort = gPd->pcii.u.h0.base_registers[0] + SVGA_VALUE_PORT;
|
||||
TRACE("index port: %d, value port: %d\n",
|
||||
si->indexPort, si->valuePort);
|
||||
|
||||
/* This should be SVGA II according to the PCI device_id,
|
||||
* but just in case... */
|
||||
WriteReg(SVGA_REG_ID, SVGA_ID_2);
|
||||
if ((id = ReadReg(SVGA_REG_ID)) != SVGA_ID_2) {
|
||||
TRACE("SVGA_REG_ID is %ld, not %d\n", id, SVGA_REG_ID);
|
||||
return B_ERROR;
|
||||
}
|
||||
TRACE("SVGA_REG_ID OK\n");
|
||||
|
||||
/* Grab some info */
|
||||
si->maxWidth = ReadReg(SVGA_REG_MAX_WIDTH);
|
||||
si->maxHeight = ReadReg(SVGA_REG_MAX_HEIGHT);
|
||||
TRACE("max resolution: %ldx%ld\n", si->maxWidth, si->maxHeight);
|
||||
si->fbDma = (void *)ReadReg(SVGA_REG_FB_START);
|
||||
si->fbSize = ReadReg(SVGA_REG_VRAM_SIZE);
|
||||
TRACE("frame buffer: %p, size %ld\n", si->fbDma, si->fbSize);
|
||||
si->fifoDma = (void *)ReadReg(SVGA_REG_MEM_START);
|
||||
si->fifoSize = ReadReg(SVGA_REG_MEM_SIZE) & ~3;
|
||||
TRACE("fifo: %p, size %ld\n", si->fifoDma, si->fifoSize);
|
||||
si->capabilities = ReadReg(SVGA_REG_CAPABILITIES);
|
||||
PrintCapabilities(si->capabilities);
|
||||
si->fifoMin = (si->capabilities & SVGA_CAP_EXTENDED_FIFO) ?
|
||||
ReadReg(SVGA_REG_MEM_REGS) : 4;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
MapDevice()
|
||||
{
|
||||
SharedInfo *si = gPd->si;
|
||||
int writeCombined = 1;
|
||||
|
||||
/* Map the frame buffer */
|
||||
si->fbArea = map_physical_memory("VMware frame buffer",
|
||||
si->fbDma, si->fbSize, B_ANY_KERNEL_BLOCK_ADDRESS|B_MTR_WC,
|
||||
B_READ_AREA|B_WRITE_AREA, (void **)&si->fb);
|
||||
if (si->fbArea < 0) {
|
||||
/* Try again without write combining */
|
||||
writeCombined = 0;
|
||||
si->fbArea = map_physical_memory("VMware frame buffer",
|
||||
si->fbDma, si->fbSize, B_ANY_KERNEL_BLOCK_ADDRESS,
|
||||
B_READ_AREA|B_WRITE_AREA, (void **)&si->fb);
|
||||
}
|
||||
if (si->fbArea < 0) {
|
||||
TRACE("failed to map frame buffer\n");
|
||||
return si->fbArea;
|
||||
}
|
||||
TRACE("frame buffer mapped: %p->%p, area %ld, size %ld, write "
|
||||
"combined: %d\n", si->fbDma, si->fb, si->fbArea,
|
||||
si->fbSize, writeCombined);
|
||||
|
||||
/* Map the fifo */
|
||||
si->fifoArea = map_physical_memory("VMware fifo",
|
||||
si->fifoDma, si->fifoSize, B_ANY_KERNEL_BLOCK_ADDRESS,
|
||||
B_READ_AREA|B_WRITE_AREA, (void **)&si->fifo);
|
||||
if (si->fifoArea < 0) {
|
||||
TRACE("failed to map fifo\n");
|
||||
delete_area(si->fbArea);
|
||||
return si->fifoArea;
|
||||
}
|
||||
TRACE("fifo mapped: %p->%p, area %ld, size %ld\n", si->fifoDma,
|
||||
si->fifo, si->fifoArea, si->fifoSize);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UnmapDevice()
|
||||
{
|
||||
SharedInfo *si = gPd->si;
|
||||
pci_info *pcii = &gPd->pcii;
|
||||
uint32 tmpUlong;
|
||||
|
||||
/* Disable memory mapped IO */
|
||||
tmpUlong = get_pci(PCI_command, 2);
|
||||
tmpUlong &= ~PCI_command_memory;
|
||||
set_pci(PCI_command, 2, tmpUlong);
|
||||
|
||||
/* Delete the areas */
|
||||
if (si->fifoArea >= 0)
|
||||
delete_area(si->fifoArea);
|
||||
if (si->fbArea >= 0)
|
||||
delete_area(si->fbArea);
|
||||
si->fifoArea = si->fbArea = -1;
|
||||
si->fb = si->fifo = NULL;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
CreateShared()
|
||||
{
|
||||
gPd->sharedArea = create_area("VMware shared", (void **)&gPd->si,
|
||||
B_ANY_KERNEL_ADDRESS, ROUND_TO_PAGE_SIZE(sizeof(SharedInfo)),
|
||||
B_FULL_LOCK, 0);
|
||||
if (gPd->sharedArea < B_OK) {
|
||||
TRACE("failed to create shared area\n");
|
||||
return gPd->sharedArea;
|
||||
}
|
||||
TRACE("shared area created\n");
|
||||
|
||||
memset(gPd->si, 0, sizeof(SharedInfo));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FreeShared()
|
||||
{
|
||||
delete_area(gPd->sharedArea);
|
||||
gPd->sharedArea = -1;
|
||||
gPd->si = NULL;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
OpenHook(const char *name, uint32 flags, void **cookie)
|
||||
{
|
||||
status_t ret = B_OK;
|
||||
pci_info *pcii = &gPd->pcii;
|
||||
uint32 tmpUlong;
|
||||
|
||||
TRACE("OpenHook (%s, %ld)\n", name, flags);
|
||||
ACQUIRE_BEN(gPd->kernel);
|
||||
|
||||
if (gPd->isOpen)
|
||||
goto markAsOpen;
|
||||
|
||||
/* Enable memory mapped IO and VGA I/O */
|
||||
tmpUlong = get_pci(PCI_command, 2);
|
||||
tmpUlong |= PCI_command_memory;
|
||||
tmpUlong |= PCI_command_io;
|
||||
set_pci(PCI_command, 2, tmpUlong);
|
||||
|
||||
if ((ret = CreateShared()) != B_OK)
|
||||
goto done;
|
||||
if ((ret = CheckCapabilities()) != B_OK)
|
||||
goto freeShared;
|
||||
if ((ret = MapDevice()) != B_OK)
|
||||
goto freeShared;
|
||||
|
||||
markAsOpen:
|
||||
gPd->isOpen++;
|
||||
*cookie = gPd;
|
||||
goto done;
|
||||
|
||||
freeShared:
|
||||
FreeShared();
|
||||
|
||||
done:
|
||||
RELEASE_BEN(gPd->kernel);
|
||||
TRACE("OpenHook: %ld\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* ReadHook, WriteHook, CloseHook: do nothing */
|
||||
|
||||
static status_t
|
||||
ReadHook(void *dev, off_t pos, void *buf, size_t *len)
|
||||
{
|
||||
*len = 0;
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
static status_t
|
||||
WriteHook(void *dev, off_t pos, const void *buf, size_t *len)
|
||||
{
|
||||
*len = 0;
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
static status_t
|
||||
CloseHook(void *dev)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* FreeHook: closes down the device */
|
||||
|
||||
static status_t
|
||||
FreeHook(void *dev)
|
||||
{
|
||||
TRACE("FreeHook\n");
|
||||
ACQUIRE_BEN(gPd->kernel);
|
||||
|
||||
if (gPd->isOpen < 2) {
|
||||
UnmapDevice();
|
||||
FreeShared();
|
||||
}
|
||||
gPd->isOpen--;
|
||||
|
||||
RELEASE_BEN(gPd->kernel);
|
||||
TRACE("FreeHook ends\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* ControlHook: responds the the ioctl from the accelerant */
|
||||
|
||||
static status_t
|
||||
ControlHook(void *dev, uint32 msg, void *buf, size_t len)
|
||||
{
|
||||
SharedInfo *si = gPd->si;
|
||||
|
||||
switch (msg) {
|
||||
case B_GET_ACCELERANT_SIGNATURE:
|
||||
strcpy((char *)buf, "vmware.accelerant");
|
||||
return B_OK;
|
||||
|
||||
case VMWARE_GET_PRIVATE_DATA:
|
||||
*((area_id *)buf) = gPd->sharedArea;
|
||||
return B_OK;
|
||||
|
||||
case VMWARE_FIFO_START:
|
||||
WriteReg(SVGA_REG_ENABLE, 1);
|
||||
WriteReg(SVGA_REG_CONFIG_DONE, 1);
|
||||
return B_OK;
|
||||
|
||||
case VMWARE_FIFO_STOP:
|
||||
WriteReg(SVGA_REG_CONFIG_DONE, 0);
|
||||
WriteReg(SVGA_REG_ENABLE, 0);
|
||||
return B_OK;
|
||||
|
||||
case VMWARE_FIFO_SYNC:
|
||||
WriteReg(SVGA_REG_SYNC, 1);
|
||||
while (ReadReg(SVGA_REG_BUSY));
|
||||
return B_OK;
|
||||
|
||||
case VMWARE_SET_MODE:
|
||||
{
|
||||
display_mode *dm = buf;
|
||||
WriteReg(SVGA_REG_WIDTH, dm->virtual_width);
|
||||
WriteReg(SVGA_REG_HEIGHT, dm->virtual_height);
|
||||
WriteReg(SVGA_REG_BITS_PER_PIXEL, BppForSpace(dm->space));
|
||||
si->fbOffset = ReadReg(SVGA_REG_FB_OFFSET);
|
||||
si->bytesPerRow = ReadReg(SVGA_REG_BYTES_PER_LINE);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case VMWARE_MOVE_CURSOR:
|
||||
{
|
||||
uint16 *pos = buf;
|
||||
WriteReg(SVGA_REG_CURSOR_ID, CURSOR_ID);
|
||||
WriteReg(SVGA_REG_CURSOR_X, pos[0]);
|
||||
WriteReg(SVGA_REG_CURSOR_Y, pos[1]);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case VMWARE_SHOW_CURSOR:
|
||||
{
|
||||
bool show = *((bool *)buf);
|
||||
WriteReg(SVGA_REG_CURSOR_ON, show ? SVGA_CURSOR_ON_HIDE :
|
||||
SVGA_CURSOR_ON_SHOW);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("ioctl: %ld, %p, %ld\n", msg, buf, len);
|
||||
return B_DEV_INVALID_IOCTL;
|
||||
}
|
||||
|
||||
|
||||
device_hooks gGraphicsDeviceHooks =
|
||||
{
|
||||
OpenHook,
|
||||
CloseHook,
|
||||
FreeHook,
|
||||
ControlHook,
|
||||
ReadHook,
|
||||
WriteHook,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <PCI.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
DeviceData *gPd;
|
||||
pci_module_info *gPciBus;
|
||||
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
status_t ret = B_ERROR;
|
||||
pci_info pcii;
|
||||
int i;
|
||||
|
||||
TRACE("init_hardware\n");
|
||||
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPciBus) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
for (i = 0; (*gPciBus->get_nth_pci_info)(i, &pcii) == B_OK; i++) {
|
||||
if (pcii.vendor_id == PCI_VENDOR_ID_VMWARE &&
|
||||
pcii.device_id == PCI_DEVICE_ID_VMWARE_SVGA2) {
|
||||
ret = B_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
|
||||
TRACE("init_hardware: %ld\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_driver(void)
|
||||
{
|
||||
status_t ret = B_OK;
|
||||
int i;
|
||||
|
||||
TRACE("init_driver\n");
|
||||
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPciBus) != B_OK) {
|
||||
ret = B_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(gPd = calloc(1, sizeof(DeviceData)))) {
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
ret = B_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Remember the PCI information */
|
||||
for (i = 0; (*gPciBus->get_nth_pci_info)(i, &gPd->pcii) == B_OK; i++)
|
||||
if (gPd->pcii.vendor_id == PCI_VENDOR_ID_VMWARE &&
|
||||
gPd->pcii.device_id == PCI_DEVICE_ID_VMWARE_SVGA2)
|
||||
break;
|
||||
|
||||
/* Create a benaphore for exclusive access in OpenHook/FreeHook */
|
||||
INIT_BEN(gPd->kernel);
|
||||
|
||||
/* The device name */
|
||||
gPd->names[0] = strdup("graphics/vmware");
|
||||
gPd->names[1] = NULL;
|
||||
|
||||
/* Usual initializations */
|
||||
gPd->isOpen = 0;
|
||||
gPd->sharedArea = -1;
|
||||
gPd->si = NULL;
|
||||
|
||||
done:
|
||||
TRACE("init_driver: %ld\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const char **
|
||||
publish_devices(void)
|
||||
{
|
||||
TRACE("publish_devices\n");
|
||||
return (const char **)gPd->names;
|
||||
}
|
||||
|
||||
|
||||
device_hooks *
|
||||
find_device(const char *name)
|
||||
{
|
||||
TRACE("find_device (%s)\n", name);
|
||||
if (gPd->names[0] && !strcmp(gPd->names[0], name))
|
||||
return &gGraphicsDeviceHooks;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_driver()
|
||||
{
|
||||
TRACE("uninit_driver\n");
|
||||
free(gPd);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
*/
|
||||
#ifndef DRIVER_H
|
||||
#define DRIVER_H
|
||||
|
||||
|
||||
#define TRACE(a...) dprintf("VMware: " ##a)
|
||||
|
||||
#include "DriverInterface.h"
|
||||
|
||||
typedef struct {
|
||||
char *names[2];
|
||||
Benaphore kernel;
|
||||
uint32 isOpen;
|
||||
area_id sharedArea;
|
||||
SharedInfo *si;
|
||||
pci_info pcii;
|
||||
} DeviceData;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Global variables */
|
||||
|
||||
extern DeviceData *gPd;
|
||||
extern pci_module_info *gPciBus;
|
||||
extern device_hooks gGraphicsDeviceHooks;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Access to 32 bit registers in the IO address space. */
|
||||
|
||||
static inline uint32
|
||||
inl(uint16 port)
|
||||
{
|
||||
uint32 ret;
|
||||
__asm__ __volatile__("inl %w1, %0" : "=a" (ret) : "Nd" (port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
outl(uint16 port, uint32 value)
|
||||
{
|
||||
__asm__ __volatile__("outl %1, %w0" :: "Nd" (port), "a" (value));
|
||||
}
|
||||
|
||||
static inline uint32
|
||||
ReadReg(uint32 index)
|
||||
{
|
||||
outl(gPd->si->indexPort, index);
|
||||
return inl(gPd->si->valuePort);
|
||||
}
|
||||
|
||||
static inline void
|
||||
WriteReg(uint32 index, uint32 value)
|
||||
{
|
||||
outl(gPd->si->indexPort, index);
|
||||
outl(gPd->si->valuePort, value);
|
||||
}
|
||||
|
||||
#endif // DRIVER_H
|
||||
Reference in New Issue
Block a user