2009-04-13 02:05:42 -05:00
|
|
|
/**********************************************************
|
|
|
|
* Copyright 2008-2009 VMware, Inc. All rights reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person
|
|
|
|
* obtaining a copy of this software and associated documentation
|
|
|
|
* files (the "Software"), to deal in the Software without
|
|
|
|
* restriction, including without limitation the rights to use, copy,
|
|
|
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
|
|
* of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*
|
|
|
|
**********************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* svga.h --
|
|
|
|
*
|
|
|
|
* This is a simple example driver for the VMware SVGA device.
|
|
|
|
* It handles initialization, register accesses, low-level
|
|
|
|
* command FIFO writes, and host/guest synchronization.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SVGA_H__
|
|
|
|
#define __SVGA_H__
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "pci.h"
|
|
|
|
#include "intr.h"
|
|
|
|
#include "svga_reg.h"
|
|
|
|
#include "svga_escape.h"
|
|
|
|
#include "svga_overlay.h"
|
|
|
|
#include "svga3d_reg.h"
|
|
|
|
|
|
|
|
typedef struct SVGADevice {
|
|
|
|
PCIAddress pciAddr;
|
|
|
|
uint32 ioBase;
|
|
|
|
uint32 *fifoMem;
|
|
|
|
uint8 *fbMem;
|
|
|
|
uint32 fifoSize;
|
|
|
|
uint32 fbSize;
|
|
|
|
|
|
|
|
uint32 deviceVersionId;
|
|
|
|
uint32 capabilities;
|
|
|
|
|
|
|
|
uint32 width;
|
|
|
|
uint32 height;
|
|
|
|
uint32 bpp;
|
|
|
|
uint32 pitch;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
uint32 reservedSize;
|
|
|
|
Bool usingBounceBuffer;
|
|
|
|
uint8 bounceBuffer[1024 * 1024];
|
|
|
|
uint32 nextFence;
|
|
|
|
} fifo;
|
|
|
|
|
Hopefully fix Metalkit refdriver SVGA_WaitForIRQ hangs
There's been a longstanding bug in the IRQ handling code
in the Metalkit version of the SVGA reference driver, which
occasionally caused tests to hang.
I looked at the disassembly of SVGA_WaitForIRQ and friends, and
I found one big problem and one smaller problem:
The 'switchContext' flag is used to tell the IRQ handler
whether it should branch to the saved context or not. This
value *must* be written before we halt, or we can deadlock.
Unfortunately, the value wasn't marked as 'volatile', and the
compiler was optimizing out this assignment entirely! This
means that 'flags' will never get set, and we'll be in an
infinite loop.
Given this bug, I'm not sure why WaitForIRQ ever worked.
It's possible that we were fine if the IRQ had already arrived
by the time WaitForIRQ was called, but we'd deadlock if we
actually ended up waiting. If this is the case, it also means
that fence-stress isn't doing a very good job of stressing the
IRQ code.
The other, much less severe problem: The stack frames for
WaitForIRQInternal and SaveContext may have been partially
overlapping, since gcc was allocating 0x10 bytes on the
stack before calling SaveContext. The proper solution is
probably just to rewrite all of this in assembly, but for
now I just increased the number of padding words on the
stack by adding extra NULL parameters to WaitForIRQInternal.
2009-05-07 17:35:49 -05:00
|
|
|
volatile struct {
|
2009-04-13 02:05:42 -05:00
|
|
|
uint32 pending;
|
|
|
|
uint32 switchContext;
|
|
|
|
IntrContext oldContext;
|
|
|
|
IntrContext newContext;
|
|
|
|
uint32 count;
|
|
|
|
} irq;
|
|
|
|
|
|
|
|
} SVGADevice;
|
|
|
|
|
|
|
|
extern SVGADevice gSVGA;
|
|
|
|
|
|
|
|
void SVGA_Init(void);
|
|
|
|
void SVGA_SetMode(uint32 width, uint32 height, uint32 bpp);
|
|
|
|
void SVGA_Disable(void);
|
|
|
|
void SVGA_Panic(const char *err);
|
|
|
|
void SVGA_DefaultFaultHandler(int vector);
|
|
|
|
|
|
|
|
uint32 SVGA_ReadReg(uint32 index);
|
|
|
|
void SVGA_WriteReg(uint32 index, uint32 value);
|
|
|
|
uint32 SVGA_ClearIRQ(void);
|
|
|
|
uint32 SVGA_WaitForIRQ();
|
|
|
|
|
|
|
|
Bool SVGA_IsFIFORegValid(int reg);
|
|
|
|
Bool SVGA_HasFIFOCap(int cap);
|
|
|
|
|
|
|
|
void *SVGA_FIFOReserve(uint32 bytes);
|
|
|
|
void *SVGA_FIFOReserveCmd(uint32 type, uint32 bytes);
|
|
|
|
void *SVGA_FIFOReserveEscape(uint32 nsid, uint32 bytes);
|
|
|
|
void SVGA_FIFOCommit(uint32 bytes);
|
|
|
|
void SVGA_FIFOCommitAll(void);
|
|
|
|
|
|
|
|
uint32 SVGA_InsertFence(void);
|
|
|
|
void SVGA_SyncToFence(uint32 fence);
|
|
|
|
Bool SVGA_HasFencePassed(uint32 fence);
|
|
|
|
void SVGA_RingDoorbell(void);
|
|
|
|
|
|
|
|
/* 2D commands */
|
|
|
|
|
|
|
|
void SVGA_Update(uint32 x, uint32 y, uint32 width, uint32 height);
|
|
|
|
void SVGA_BeginDefineCursor(const SVGAFifoCmdDefineCursor *cursorInfo,
|
|
|
|
void **andMask, void **xorMask);
|
|
|
|
void SVGA_BeginDefineAlphaCursor(const SVGAFifoCmdDefineAlphaCursor *cursorInfo,
|
|
|
|
void **data);
|
|
|
|
void SVGA_MoveCursor(uint32 visible, uint32 x, uint32 y);
|
|
|
|
|
|
|
|
void SVGA_BeginVideoSetRegs(uint32 streamId, uint32 numItems,
|
|
|
|
SVGAEscapeVideoSetRegs **setRegs);
|
|
|
|
void SVGA_VideoSetAllRegs(uint32 streamId, SVGAOverlayUnit *regs, uint32 maxReg);
|
|
|
|
void SVGA_VideoSetReg(uint32 streamId, uint32 registerId, uint32 value);
|
|
|
|
void SVGA_VideoFlush(uint32 streamId);
|
|
|
|
|
|
|
|
#endif /* __SVGA_H__ */
|