Remove the vmware graphics and mouse drivers.
They are now available as a package in HaikuDepot.
This commit is contained in:
parent
7291c0a8d9
commit
1554429045
@ -15,4 +15,3 @@ SubInclude HAIKU_TOP src add-ons accelerants radeon_hd ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants s3 ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants vesa ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants via ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants vmware ;
|
||||
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
* Michael Pfeiffer <laplace@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
void
|
||||
SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
blit_params *b;
|
||||
|
||||
FifoBeginWrite();
|
||||
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
|
||||
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();
|
||||
FifoSync();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FILL_RECTANGLE(engine_token *et, uint32 colorIndex,
|
||||
fill_rect_params *list, uint32 count)
|
||||
{
|
||||
uint32 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 */
|
||||
}
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
* Michael Pfeiffer <laplace@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "GlobalData.h"
|
||||
|
||||
|
||||
static void
|
||||
WriteScanline(void * scanline, uint16 sizeInBytes)
|
||||
{
|
||||
uint32* words = (uint32*)scanline;
|
||||
/* sizeInBytes must be a multiple of 4 */
|
||||
uint16 sizeInWords = sizeInBytes / 4;
|
||||
uint16 i;
|
||||
for (i = 0; i < sizeInWords; i ++)
|
||||
FifoWrite(words[i]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
WriteAndMask(uint8 * andMask, uint16 width, uint16 height, uint8 * scanline,
|
||||
uint16 scanlineSize)
|
||||
{
|
||||
uint16 y;
|
||||
uint16 bpr = (width + 7) / 8;
|
||||
for (y = 0; y < height; y ++) {
|
||||
// copy andMask into scanline to avoid
|
||||
// out of bounds access at last row
|
||||
memcpy(scanline, &andMask[y * bpr], bpr);
|
||||
WriteScanline(scanline, scanlineSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
WriteXorMask(uint8 * andMask, uint8 * xorMask, uint16 width, uint16 height,
|
||||
uint8 * scanline, uint16 scanlineSize)
|
||||
{
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
uint16 bpr = (width + 7) / 8;
|
||||
for (y = 0; y < height; y ++) {
|
||||
uint8 * andMaskRow = &andMask[y * bpr];
|
||||
// copy xorMask into scanline to avoid
|
||||
// out of bounds access at last row
|
||||
memcpy(scanline, &xorMask[y * bpr], bpr);
|
||||
// in case of a 1 bit in andMask
|
||||
// the meaning of the corresponding bit
|
||||
// in xorMask is the opposite in the
|
||||
// emulated graphics HW (1 = white, 0 =
|
||||
// black). Be API: 1 = black, 0 = white.
|
||||
for (x = 0; x < width; x ++) {
|
||||
uint8 bit = 7 - x % 8;
|
||||
uint8 bitMask = 1 << bit;
|
||||
uint16 byte = x / 8;
|
||||
if ((andMaskRow[byte] & bitMask) == 0)
|
||||
scanline[byte] = scanline[byte] ^ bitMask;
|
||||
}
|
||||
WriteScanline(scanline, scanlineSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x,
|
||||
uint16 hot_y, uint8 * andMask, uint8 * xorMask)
|
||||
{
|
||||
|
||||
uint16 scanlineSize;
|
||||
uint8 * scanline;
|
||||
|
||||
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;
|
||||
|
||||
scanlineSize = 4 * ((width + 31) / 32);
|
||||
scanline = calloc(1, scanlineSize);
|
||||
if (scanline == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
FifoBeginWrite();
|
||||
FifoWrite(SVGA_CMD_DEFINE_CURSOR);
|
||||
FifoWrite(CURSOR_ID);
|
||||
FifoWrite(hot_x);
|
||||
FifoWrite(hot_y);
|
||||
FifoWrite(width);
|
||||
FifoWrite(height);
|
||||
FifoWrite(1);
|
||||
FifoWrite(1);
|
||||
WriteAndMask(andMask, width, height, scanline, scanlineSize);
|
||||
WriteXorMask(andMask, xorMask, width, height, scanline, scanlineSize);
|
||||
FifoEndWrite();
|
||||
FifoSync();
|
||||
|
||||
free(scanline);
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* 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(void)
|
||||
{
|
||||
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: %" B_PRId32 " -> %" B_PRId32 "\n",
|
||||
fifo[SVGA_FIFO_MIN], fifo[SVGA_FIFO_MAX]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoSync(void)
|
||||
{
|
||||
ioctl(gFd, VMWARE_FIFO_SYNC, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoBeginWrite(void)
|
||||
{
|
||||
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 = fifo[SVGA_FIFO_MIN] +
|
||||
(gSi->fifoNext + 4 - fifo[SVGA_FIFO_MIN]) % fifoCapacity;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoEndWrite(void)
|
||||
{
|
||||
uint32 *fifo = gSi->fifo;
|
||||
|
||||
fifo[SVGA_FIFO_NEXT_CMD] = gSi->fifoNext;
|
||||
RELEASE_BEN(gSi->fifoLock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FifoUpdateFullscreen(void)
|
||||
{
|
||||
FifoBeginWrite();
|
||||
FifoWrite(SVGA_CMD_UPDATE);
|
||||
FifoWrite(0);
|
||||
FifoWrite(0);
|
||||
FifoWrite(gSi->dm.virtual_width);
|
||||
FifoWrite(gSi->dm.virtual_height);
|
||||
FifoEndWrite();
|
||||
}
|
||||
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated.
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Be Incorporated
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
* Michael Pfeiffer <laplace@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#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
|
||||
#define HOOK_IF(x, cap) case B_##x: if (gSi->capabilities & cap) return (void *)x; else 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) */
|
||||
HOOK_IF(SET_CURSOR_SHAPE, SVGA_CAP_CURSOR_BYPASS);
|
||||
HOOK_IF(MOVE_CURSOR, SVGA_CAP_CURSOR_BYPASS);
|
||||
HOOK_IF(SHOW_CURSOR, SVGA_CAP_CURSOR_BYPASS);
|
||||
|
||||
/* 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) */
|
||||
HOOK_IF(SCREEN_TO_SCREEN_BLIT, SVGA_CAP_RECT_COPY);
|
||||
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;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* 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 <SupportDefs.h>
|
||||
#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 = (uint8 *)gSi->fb + gSi->fbOffset;
|
||||
afb->frame_buffer_dma = (uint8 *)gSi->fbDma + gSi->fbOffset;
|
||||
afb->bytes_per_row = gSi->bytesPerRow;
|
||||
|
||||
TRACE("fb: %p, fb_dma: %p, row: %" B_PRIu32 " 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;
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* 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;
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
void FifoSync(void);
|
||||
void FifoBeginWrite(void);
|
||||
void FifoWrite(uint32 value);
|
||||
void FifoEndWrite(void);
|
||||
void FifoUpdateFullscreen(void);
|
||||
|
||||
#endif // GLOBAL_DATA_H
|
@ -1,140 +0,0 @@
|
||||
/*
|
||||
* 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 <SupportDefs.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(gFd, VMWARE_GET_PRIVATE_DATA, &gSharedArea,
|
||||
sizeof(area_id))) != B_OK) {
|
||||
TRACE("VMWARE_GET_PRIVATE_DATA failed (%" B_PRIx32 "\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 (%" B_PRId32 ")\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: %" B_PRIx32 "\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
ACCELERANT_CLONE_INFO_SIZE()
|
||||
{
|
||||
return B_PATH_NAME_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GET_ACCELERANT_CLONE_INFO(void *data)
|
||||
{
|
||||
TRACE("GET_ACCELERANT_CLONE_INFO (%d)\n", gFd);
|
||||
|
||||
// TODO: I have no idea why this doesn't work: gFd is 0 here !?!?
|
||||
//ioctl(gFd, VMWARE_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
|
||||
strlcpy(data, "graphics/vmware", B_PATH_NAME_LENGTH);
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CLONE_ACCELERANT(void *data)
|
||||
{
|
||||
int fd;
|
||||
char path[B_PATH_NAME_LENGTH];
|
||||
status_t ret;
|
||||
|
||||
// create full device name
|
||||
strcpy(path, "/dev/");
|
||||
strlcat(path, (const char *)data, sizeof(path));
|
||||
|
||||
TRACE("CLONE_ACCELERANT: %s\n", (const char *)path);
|
||||
|
||||
fd = open(path, B_READ_WRITE);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
gAccelerantIsClone = 1;
|
||||
|
||||
/* 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("CLONE_ACCELERANT: %" B_PRIx32 "\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons accelerants vmware ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders [ FDirName graphics vmware ] ;
|
||||
UsePrivateHeaders graphics ;
|
||||
|
||||
Addon vmware.accelerant :
|
||||
Acceleration.c
|
||||
Cursor.c
|
||||
EngineManagment.c
|
||||
Fifo.c
|
||||
GetAccelerantHook.c
|
||||
GetModeInfo.c
|
||||
GlobalData.c
|
||||
InitAccelerant.c
|
||||
ProposeDisplayMode.c
|
||||
SetDisplayMode.c
|
||||
;
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* 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 <SupportDefs.h>
|
||||
#include "GlobalData.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 */
|
||||
{ { 19660, 640, 672, 744, 776, 480, 490, 494, 505, 0 }, B_CMAP8, 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;
|
||||
|
||||
/* 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: %" B_PRIuSIZE "\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;
|
||||
}
|
||||
|
@ -1,541 +0,0 @@
|
||||
|
||||
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.
|
||||
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* 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 "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)
|
||||
{
|
||||
// TODO: Take first and count into account.
|
||||
// Currently we always pass 256 colors (random, most of the times) to the driver. Cool!
|
||||
uint8 colors[256];
|
||||
uint32 i;
|
||||
TRACE("SET_INDEXED_COLORS\n");
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
colors[i + first] = color_data[i];
|
||||
}
|
||||
|
||||
ioctl(gFd, VMWARE_SET_PALETTE, colors, sizeof(count));
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* 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;
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,5 +1,4 @@
|
||||
SubDir HAIKU_TOP src add-ons input_server filters ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons input_server filters screen_saver ;
|
||||
SubInclude HAIKU_TOP src add-ons input_server filters vmware_mouse ;
|
||||
SubInclude HAIKU_TOP src add-ons input_server filters shortcut_catcher ;
|
||||
|
@ -1,5 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons input_server filters vmware_mouse ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
Addon vmware_mouse : VMWareMouse.cpp : be input_server [ TargetLibsupc++ ] ;
|
@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Lotz <mmlr@mlotz.ch>
|
||||
*/
|
||||
|
||||
#include "VMWareMouse.h"
|
||||
#include "VMWareTypes.h"
|
||||
|
||||
#include <Message.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include <new>
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
#define DEBUG_PREFIX "VMWareMouseFilter: "
|
||||
#define TRACE(x...) /*syslog(DEBUG_PREFIX x)*/
|
||||
#define TRACE_ALWAYS(x...) syslog(LOG_INFO, DEBUG_PREFIX x)
|
||||
#define TRACE_ERROR(x...) syslog(LOG_ERR, DEBUG_PREFIX x)
|
||||
|
||||
|
||||
// #pragma mark - Public BInputServerFilter API
|
||||
|
||||
|
||||
VMWareMouseFilter::VMWareMouseFilter()
|
||||
:
|
||||
BInputServerFilter()
|
||||
{
|
||||
fIsEnabled = _Enable();
|
||||
}
|
||||
|
||||
|
||||
VMWareMouseFilter::~VMWareMouseFilter()
|
||||
{
|
||||
if (fIsEnabled)
|
||||
_Disable();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
VMWareMouseFilter::InitCheck()
|
||||
{
|
||||
if (fIsEnabled)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
VMWareMouseFilter::Filter(BMessage *message, BList *outList)
|
||||
{
|
||||
if (!fIsEnabled)
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
switch(message->what) {
|
||||
case B_MOUSE_UP:
|
||||
case B_MOUSE_DOWN:
|
||||
case B_MOUSE_MOVED:
|
||||
{
|
||||
uint16 status, numWords;
|
||||
_GetStatus(&status, &numWords);
|
||||
if (status == VMWARE_ERROR) {
|
||||
TRACE_ERROR("error indicated when reading status, resetting\n");
|
||||
_Disable();
|
||||
fIsEnabled = _Enable();
|
||||
break;
|
||||
}
|
||||
|
||||
if (numWords == 0) {
|
||||
// no actual data availabe, spurious event happens on fast move
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
int32 x, y;
|
||||
_GetPosition(x, y);
|
||||
_ScalePosition(x, y);
|
||||
|
||||
if (x < 0 || y < 0) {
|
||||
TRACE_ERROR("got invalid coordinates %ld, %ld\n", x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("setting position to %ld, %ld\n", x, y);
|
||||
message->RemoveName("where");
|
||||
message->AddPoint("where", BPoint(x, y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - VMWare Communication
|
||||
|
||||
|
||||
void
|
||||
VMWareMouseFilter::_ExecuteCommand(union packet_u &packet)
|
||||
{
|
||||
packet.command.magic = VMWARE_PORT_MAGIC;
|
||||
packet.command.port = VMWARE_PORT_NUMBER;
|
||||
|
||||
int dummy;
|
||||
#ifdef __x86_64__
|
||||
asm volatile (
|
||||
"pushq %%rbx;"
|
||||
"pushq %%rax;"
|
||||
"movl 12(%%rax), %%edx;"
|
||||
"movl 8(%%rax), %%ecx;"
|
||||
"movl 4(%%rax), %%ebx;"
|
||||
"movl (%%rax), %%eax;"
|
||||
"inl %%dx, %%eax;"
|
||||
"xchgq %%rax, (%%rsp);"
|
||||
"movl %%edx, 12(%%rax);"
|
||||
"movl %%ecx, 8(%%rax);"
|
||||
"movl %%ebx, 4(%%rax);"
|
||||
"popq %%rbx;"
|
||||
"movl %%ebx, (%%rax);"
|
||||
"popq %%rbx;"
|
||||
: "=a"(dummy)
|
||||
: "0"(&packet)
|
||||
: "rcx", "rdx", "memory");
|
||||
#else
|
||||
asm volatile (
|
||||
"pushl %%ebx;"
|
||||
"pushl %%eax;"
|
||||
"movl 12(%%eax), %%edx;"
|
||||
"movl 8(%%eax), %%ecx;"
|
||||
"movl 4(%%eax), %%ebx;"
|
||||
"movl (%%eax), %%eax;"
|
||||
"inl %%dx, %%eax;"
|
||||
"xchgl %%eax, (%%esp);"
|
||||
"movl %%edx, 12(%%eax);"
|
||||
"movl %%ecx, 8(%%eax);"
|
||||
"movl %%ebx, 4(%%eax);"
|
||||
"popl (%%eax);"
|
||||
"popl %%ebx;"
|
||||
: "=a"(dummy)
|
||||
: "0"(&packet)
|
||||
: "ecx", "edx", "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
VMWareMouseFilter::_Enable()
|
||||
{
|
||||
union packet_u packet;
|
||||
packet.command.command = VMWARE_COMMAND_POINTER_COMMAND;
|
||||
packet.command.value = VMWARE_VALUE_READ_ID;
|
||||
_ExecuteCommand(packet);
|
||||
|
||||
uint16 numWords;
|
||||
_GetStatus(NULL, &numWords);
|
||||
if (numWords == 0) {
|
||||
TRACE_ERROR("didn't get back data on reading version id\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
packet.command.command = VMWARE_COMMAND_POINTER_DATA;
|
||||
packet.command.value = 1; // read size, 1 word
|
||||
_ExecuteCommand(packet);
|
||||
|
||||
if (packet.version.version != VMWARE_VERSION_ID) {
|
||||
TRACE_ERROR("got back unexpected version 0x%08lx\n",
|
||||
packet.version.version);
|
||||
return false;
|
||||
}
|
||||
|
||||
// request absolute data
|
||||
packet.command.command = VMWARE_COMMAND_POINTER_COMMAND;
|
||||
packet.command.value = VMWARE_VALUE_REQUEST_ABSOLUTE;
|
||||
_ExecuteCommand(packet);
|
||||
|
||||
TRACE_ALWAYS("successfully enabled\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMWareMouseFilter::_Disable()
|
||||
{
|
||||
union packet_u packet;
|
||||
packet.command.command = VMWARE_COMMAND_POINTER_COMMAND;
|
||||
packet.command.value = VMWARE_VALUE_DISABLE;
|
||||
_ExecuteCommand(packet);
|
||||
|
||||
uint16 status;
|
||||
_GetStatus(&status, NULL);
|
||||
if (status != VMWARE_ERROR) {
|
||||
TRACE_ERROR("didn't get expected status value after disabling\n");
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_ALWAYS("successfully disabled\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMWareMouseFilter::_GetStatus(uint16 *status, uint16 *numWords)
|
||||
{
|
||||
union packet_u packet;
|
||||
packet.command.command = VMWARE_COMMAND_POINTER_STATUS;
|
||||
packet.command.value = 0;
|
||||
_ExecuteCommand(packet);
|
||||
|
||||
if (status != NULL)
|
||||
*status = packet.status.status;
|
||||
if (numWords != NULL)
|
||||
*numWords = packet.status.num_words;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMWareMouseFilter::_GetPosition(int32 &x, int32 &y)
|
||||
{
|
||||
union packet_u packet;
|
||||
packet.command.command = VMWARE_COMMAND_POINTER_DATA;
|
||||
packet.command.value = 4; // read size, 4 words
|
||||
_ExecuteCommand(packet);
|
||||
x = packet.data.x;
|
||||
y = packet.data.y;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VMWareMouseFilter::_ScalePosition(int32 &x, int32 &y)
|
||||
{
|
||||
static BScreen screen;
|
||||
BRect frame = screen.Frame();
|
||||
x = (int32)(x * (frame.Width() / 65535) + 0.5);
|
||||
y = (int32)(y * (frame.Height() / 65535) + 0.5);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Instatiation Entry Point
|
||||
|
||||
|
||||
extern "C"
|
||||
BInputServerFilter *instantiate_input_filter()
|
||||
{
|
||||
return new (std::nothrow) VMWareMouseFilter();
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Lotz <mmlr@mlotz.ch>
|
||||
*/
|
||||
#ifndef VMWARE_MOUSE_H
|
||||
#define VMWARE_MOUSE_H
|
||||
|
||||
#include <InputServerFilter.h>
|
||||
|
||||
class VMWareMouseFilter : public BInputServerFilter {
|
||||
public:
|
||||
VMWareMouseFilter();
|
||||
virtual ~VMWareMouseFilter();
|
||||
|
||||
virtual status_t InitCheck();
|
||||
virtual filter_result Filter(BMessage *msg, BList *outList);
|
||||
|
||||
private:
|
||||
void _ExecuteCommand(union packet_u &packet);
|
||||
|
||||
bool _Enable();
|
||||
void _Disable();
|
||||
|
||||
void _GetStatus(uint16 *status, uint16 *numWords);
|
||||
void _GetPosition(int32 &x, int32 &y);
|
||||
void _ScalePosition(int32 &x, int32 &y);
|
||||
|
||||
bool fIsEnabled;
|
||||
};
|
||||
|
||||
#endif // VMWARE_MOUSE_H
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Lotz <mmlr@mlotz.ch>
|
||||
*/
|
||||
#ifndef VMWARE_TYPES_H
|
||||
#define VMWARE_TYPES_H
|
||||
|
||||
#define VMWARE_PORT_MAGIC 0x564d5868
|
||||
#define VMWARE_PORT_NUMBER 0x5658
|
||||
|
||||
#define VMWARE_VERSION_ID 0x3442554a
|
||||
#define VMWARE_ERROR 0xffff
|
||||
|
||||
#define VMWARE_VALUE_DISABLE 0x000000f5
|
||||
#define VMWARE_VALUE_READ_ID 0x45414552
|
||||
#define VMWARE_VALUE_REQUEST_ABSOLUTE 0x53424152
|
||||
|
||||
#define VMWARE_COMMAND_POINTER_DATA 39
|
||||
#define VMWARE_COMMAND_POINTER_STATUS 40
|
||||
#define VMWARE_COMMAND_POINTER_COMMAND 41
|
||||
|
||||
|
||||
struct command_s {
|
||||
uint32 magic;
|
||||
uint32 value;
|
||||
uint32 command;
|
||||
uint32 port;
|
||||
} _PACKED;
|
||||
|
||||
|
||||
struct data_s {
|
||||
uint16 buttons;
|
||||
uint16 flags;
|
||||
int32 x; // signed when relative
|
||||
int32 y; // signed when relative
|
||||
int32 z; // always signed
|
||||
} _PACKED;
|
||||
|
||||
|
||||
struct status_s {
|
||||
uint16 num_words;
|
||||
uint16 status;
|
||||
uint32 unused[2];
|
||||
} _PACKED;
|
||||
|
||||
|
||||
struct version_s {
|
||||
uint32 version;
|
||||
uint32 unused[3];
|
||||
} _PACKED;
|
||||
|
||||
|
||||
union packet_u {
|
||||
struct command_s command;
|
||||
struct data_s data;
|
||||
struct status_s status;
|
||||
struct version_s version;
|
||||
};
|
||||
|
||||
#endif // VMWARE_TYPES_H
|
@ -16,4 +16,3 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics s3 ;
|
||||
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 ;
|
||||
|
@ -1,16 +0,0 @@
|
||||
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
|
||||
;
|
||||
|
||||
if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
LinkAgainst vmware : $(TARGET_HAIKU_COMPATIBILITY_LIBS) ;
|
||||
}
|
@ -1,384 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Eric Petit <eric.petit@lapsus.org>
|
||||
* Michael Pfeiffer <laplace@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#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",
|
||||
(addr_t)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",
|
||||
(addr_t)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",
|
||||
(addr_t)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;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
UpdateCursor(SharedInfo *si)
|
||||
{
|
||||
WriteReg(SVGA_REG_CURSOR_ID, CURSOR_ID);
|
||||
WriteReg(SVGA_REG_CURSOR_X, si->cursorX);
|
||||
WriteReg(SVGA_REG_CURSOR_Y, si->cursorY);
|
||||
WriteReg(SVGA_REG_CURSOR_ON, si->cursorShow ? SVGA_CURSOR_ON_SHOW :
|
||||
SVGA_CURSOR_ON_HIDE);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* 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);
|
||||
ReadReg(SVGA_REG_DEPTH);
|
||||
ReadReg(SVGA_REG_PSEUDOCOLOR);
|
||||
ReadReg(SVGA_REG_RED_MASK);
|
||||
ReadReg(SVGA_REG_GREEN_MASK);
|
||||
ReadReg(SVGA_REG_BLUE_MASK);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case VMWARE_SET_PALETTE:
|
||||
{
|
||||
uint8 *color = (uint8 *)buf;
|
||||
uint32 i;
|
||||
if (ReadReg(SVGA_REG_PSEUDOCOLOR) != 1)
|
||||
return B_ERROR;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
WriteReg(SVGA_PALETTE_BASE + 3 * i, *color++);
|
||||
WriteReg(SVGA_PALETTE_BASE + 3 * i + 1, *color++);
|
||||
WriteReg(SVGA_PALETTE_BASE + 3 * i + 2, *color++);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case VMWARE_MOVE_CURSOR:
|
||||
{
|
||||
uint16 *pos = buf;
|
||||
si->cursorX = pos[0];
|
||||
si->cursorY = pos[1];
|
||||
UpdateCursor(si);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case VMWARE_SHOW_CURSOR:
|
||||
{
|
||||
si->cursorShow = *((bool *)buf);
|
||||
UpdateCursor(si);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case VMWARE_GET_DEVICE_NAME:
|
||||
dprintf("device: VMWARE_GET_DEVICE_NAME %s\n", gPd->names[0]);
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
if (user_strlcpy((char *)buf, gPd->names[0],
|
||||
B_PATH_NAME_LENGTH) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
#else
|
||||
strlcpy((char *)buf, gPd->names[0], B_PATH_NAME_LENGTH);
|
||||
#endif
|
||||
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
|
||||
};
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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 = ENODEV;
|
||||
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) {
|
||||
ret = B_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != B_OK) {
|
||||
free(gPd);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
DELETE_BEN(gPd->kernel);
|
||||
free(gPd->names[0]);
|
||||
free(gPd);
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* 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
|
Loading…
Reference in New Issue
Block a user