aboutsummaryrefslogtreecommitdiffstats
path: root/vmware
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-01-31 23:57:00 +0100
committerJaroslav Hensl <jara@hensl.cz>2024-01-31 23:57:00 +0100
commitcf7b049839923f86fed97cfe7d8c17952a3fe79a (patch)
tree70e5b14cbdcf92429a9608316768e7154e3a0b6f /vmware
parent4cc02044b5cd8d5a3791f847198b37817fc60b78 (diff)
downloadvmdisp9x-cf7b049839923f86fed97cfe7d8c17952a3fe79a.tar.gz
driver code refactoring / PART1: vmware code
Diffstat (limited to 'vmware')
-rw-r--r--vmware/pci32.c2
-rw-r--r--vmware/svga.c227
-rw-r--r--vmware/svga.h2
-rw-r--r--vmware/svga32.c2
-rw-r--r--vmware/svga_reg.h6
5 files changed, 121 insertions, 118 deletions
diff --git a/vmware/pci32.c b/vmware/pci32.c
deleted file mode 100644
index cd00f19..0000000
--- a/vmware/pci32.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define VXD32
-#include "pci.c"
diff --git a/vmware/svga.c b/vmware/svga.c
index 573a568..8f320ae 100644
--- a/vmware/svga.c
+++ b/vmware/svga.c
@@ -37,6 +37,10 @@
#include "svga_all.h"
#ifdef VXD32
+#include "code32.h"
+#endif
+
+#ifdef VXD32
#define IO_IN32
#define IO_OUT32
#include "io32.h"
@@ -64,11 +68,6 @@ void dbg_printf( const char *s, ... );
#define MAX(a, b) (((b) > (a)) ? (b) : (a))
#endif
-#ifdef VXD32
-#include "code32.h"
-#endif
-
-
SVGADevice gSVGA = {0};
static void SVGAFIFOFull(void);
@@ -190,7 +189,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
gSVGA.fifoPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 2);
} else {
- if(SVGA_IsSVGA3()) /* VMware SVGA2 */
+ if(SVGA_IsSVGA3()) /* VMware SVGA3 */
{
gSVGA.rmmio_start = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
gSVGA.rmmio_size = PCI_GetBARSize(&gSVGA.pciAddr, 0);
@@ -201,7 +200,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
gSVGA.fifoPhy = 0;
gSVGA.ioBase = 0;
}
- else /* VMware SVGA3 */
+ else /* VMware SVGA2 */
{
gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
@@ -280,6 +279,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
#ifdef VXD32
if (gSVGA.fbSize < 0x100000) {
SVGA_Panic("FB size very small, probably incorrect.");
+ return 4;
}
#endif
@@ -287,6 +287,7 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
{
if (gSVGA.fifoSize < 0x20000) {
SVGA_Panic("FIFO size very small, probably incorrect.");
+ return 5;
}
}
@@ -489,7 +490,7 @@ SVGA_Disable(void)
*/
void
-SVGA_SetMode(uint32 width, // IN
+SVGA_SetModeLegacy(uint32 width, // IN
uint32 height, // IN
uint32 bpp) // IN
{
@@ -681,6 +682,110 @@ SVGA_HasFIFOCap(unsigned long cap)
return (gSVGA.fifoMem[SVGA_FIFO_CAPABILITIES] & cap) != 0;
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_RingDoorbell --
+ *
+ * FIFO fences are fundamentally a host-to-guest notification
+ * mechanism. This is the opposite: we can explicitly wake up
+ * the host when we know there is work for it to do.
+ *
+ * Background: The host processes the SVGA command FIFO in a
+ * separate thread which runs asynchronously with the virtual
+ * machine's CPU and other I/O devices. When the SVGA device is
+ * idle, this thread is sleeping. It periodically wakes up to
+ * poll for new commands. This polling must occur for various
+ * reasons, but it's mostly related to the historical way in
+ * which the SVGA device processes 2D updates.
+ *
+ * This polling introduces significant latency between when the
+ * first new command is placed in an empty FIFO, and when the
+ * host begins processing it. Normally this isn't a huge problem
+ * since the host and guest run fairly asynchronously, but in
+ * a synchronization-heavy workload this can be a bottleneck.
+ *
+ * For example, imagine an application with a worst-case
+ * synchronization bottleneck: The guest enqueues a single FIFO
+ * command, then waits for that command to finish using
+ * SyncToFence, then the guest spends a little time doing
+ * CPU-intensive processing before the cycle repeats. The
+ * workload may be latency-bound if the host-to-guest or
+ * guest-to-host notifications ever block.
+ *
+ * One solution would be for the guest to explicitly wake up the
+ * SVGA3D device any time a command is enqueued. This would solve
+ * the latency bottleneck above, but it would be inefficient on
+ * single-CPU host machines. One could easily imagine a situation
+ * in which we wake up the host after enqueueing one FIFO
+ * command, the physical CPU context switches to the SVGA
+ * device's thread, the single command is processed, then we
+ * context switch back to running guest code.
+ *
+ * Our recommended solution is to wake up the host only either:
+ *
+ * - After a "significant" amount of work has been enqueued into
+ * the FIFO. For example, at least one 3D drawing command.
+ *
+ * - After a complete frame has been rendered.
+ *
+ * - Just before the guest sleeps for any reason.
+ *
+ * This function implements the above guest wakeups. It uses the
+ * SVGA_FIFO_BUSY register to quickly assess whether the SVGA
+ * device may be idle. If so, it asynchronously wakes up the host
+ * by writing to SVGA_REG_SYNC.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May wake up the SVGA3D device.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+SVGA_RingDoorbell(void)
+{
+ if (SVGA_IsFIFORegValid(SVGA_FIFO_BUSY) &&
+ gSVGA.fifoMem[SVGA_FIFO_BUSY] == FALSE) {
+
+ /* Remember that we already rang the doorbell. */
+ gSVGA.fifoMem[SVGA_FIFO_BUSY] = TRUE;
+
+ /*
+ * Asynchronously wake up the SVGA3D device. The second
+ * parameter is an arbitrary nonzero 'sync reason' which can be
+ * used for debugging, but which isn't part of the SVGA3D
+ * protocol proper and which isn't used by release builds of
+ * VMware products.
+ */
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_Flush --
+ *
+ * Force to apply all register changes. Useful if registry changes
+ * needs be applyed immediately
+ *
+ *-----------------------------------------------------------------------------
+ */
+void SVGA_Flush(void)
+{
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
+#ifndef VXD32
+ dbg_printf("SVGA_Flush\n");
+#endif
+}
+
+#if 0 /* JH: all commands using bounce buffer and fifo, better write them myself */
/*
*-----------------------------------------------------------------------------
@@ -1455,110 +1560,6 @@ SVGA_HasFencePassed(uint32 fence) // IN
/*
*-----------------------------------------------------------------------------
*
- * SVGA_RingDoorbell --
- *
- * FIFO fences are fundamentally a host-to-guest notification
- * mechanism. This is the opposite: we can explicitly wake up
- * the host when we know there is work for it to do.
- *
- * Background: The host processes the SVGA command FIFO in a
- * separate thread which runs asynchronously with the virtual
- * machine's CPU and other I/O devices. When the SVGA device is
- * idle, this thread is sleeping. It periodically wakes up to
- * poll for new commands. This polling must occur for various
- * reasons, but it's mostly related to the historical way in
- * which the SVGA device processes 2D updates.
- *
- * This polling introduces significant latency between when the
- * first new command is placed in an empty FIFO, and when the
- * host begins processing it. Normally this isn't a huge problem
- * since the host and guest run fairly asynchronously, but in
- * a synchronization-heavy workload this can be a bottleneck.
- *
- * For example, imagine an application with a worst-case
- * synchronization bottleneck: The guest enqueues a single FIFO
- * command, then waits for that command to finish using
- * SyncToFence, then the guest spends a little time doing
- * CPU-intensive processing before the cycle repeats. The
- * workload may be latency-bound if the host-to-guest or
- * guest-to-host notifications ever block.
- *
- * One solution would be for the guest to explicitly wake up the
- * SVGA3D device any time a command is enqueued. This would solve
- * the latency bottleneck above, but it would be inefficient on
- * single-CPU host machines. One could easily imagine a situation
- * in which we wake up the host after enqueueing one FIFO
- * command, the physical CPU context switches to the SVGA
- * device's thread, the single command is processed, then we
- * context switch back to running guest code.
- *
- * Our recommended solution is to wake up the host only either:
- *
- * - After a "significant" amount of work has been enqueued into
- * the FIFO. For example, at least one 3D drawing command.
- *
- * - After a complete frame has been rendered.
- *
- * - Just before the guest sleeps for any reason.
- *
- * This function implements the above guest wakeups. It uses the
- * SVGA_FIFO_BUSY register to quickly assess whether the SVGA
- * device may be idle. If so, it asynchronously wakes up the host
- * by writing to SVGA_REG_SYNC.
- *
- * Results:
- * None.
- *
- * Side effects:
- * May wake up the SVGA3D device.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-SVGA_RingDoorbell(void)
-{
- if (SVGA_IsFIFORegValid(SVGA_FIFO_BUSY) &&
- gSVGA.fifoMem[SVGA_FIFO_BUSY] == FALSE) {
-
- /* Remember that we already rang the doorbell. */
- gSVGA.fifoMem[SVGA_FIFO_BUSY] = TRUE;
-
- /*
- * Asynchronously wake up the SVGA3D device. The second
- * parameter is an arbitrary nonzero 'sync reason' which can be
- * used for debugging, but which isn't part of the SVGA3D
- * protocol proper and which isn't used by release builds of
- * VMware products.
- */
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- }
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * SVGA_Flush --
- *
- * Force to apply all register changes. Useful if registry changes
- * needs be applyed immediately
- *
- *-----------------------------------------------------------------------------
- */
-void SVGA_Flush(void)
-{
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- while (SVGA_ReadReg(SVGA_REG_BUSY) != FALSE);
-#ifndef VXD32
- dbg_printf("SVGA_Flush\n");
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
* SVGA_ClearIRQ --
*
* Clear all pending IRQs. Any IRQs which occurred prior to this
@@ -2091,3 +2092,5 @@ SVGA_VideoFlush(uint32 streamId) // IN
cmd->streamId = streamId;
SVGA_FIFOCommitAll();
}
+
+#endif /* 0 */
diff --git a/vmware/svga.h b/vmware/svga.h
index 733f3af..6fc4b72 100644
--- a/vmware/svga.h
+++ b/vmware/svga.h
@@ -137,7 +137,7 @@ int __loadds SVGA_Init(Bool enableFIFO);
int SVGA_Init(Bool enableFIFO, uint32 hwversion);
#endif
void SVGA_Enable(void);
-void SVGA_SetMode(uint32 width, uint32 height, uint32 bpp);
+void SVGA_SetModeLegacy(uint32 width, uint32 height, uint32 bpp);
void SVGA_Disable(void);
void SVGA_Panic(const char *err);
void SVGA_DefaultFaultHandler(int vector);
diff --git a/vmware/svga32.c b/vmware/svga32.c
deleted file mode 100644
index 1091735..0000000
--- a/vmware/svga32.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define VXD32
-#include "svga.c"
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
index ab904a7..2d8b2a6 100644
--- a/vmware/svga_reg.h
+++ b/vmware/svga_reg.h
@@ -460,6 +460,8 @@ typedef enum {
typedef enum {
SVGA_CB_FLAG_NONE = 0,
SVGA_CB_FLAG_NO_IRQ = 1 << 0,
+ SVGA_CB_FLAG_DX_CONTEXT = 1 << 1,
+ SVGA_CB_FLAG_MOB = 1 << 2,
SVGA_CB_FLAG_FORCE_UINT = MAX_UINT32,
} SVGACBFlags;
@@ -473,7 +475,9 @@ struct {
union {
uint64 pa; // PA
} ptr;
- uint32 mustBeZero[8];
+ uint32 offset; /* Valid if CMD_BUFFERS_2 cap set, must be zero otherwise, modified by device. */
+ uint32 dxContext; /* Valid if DX_CONTEXT flag set, must be zero otherwise */
+ uint32 mustBeZero[6];
} SVGACBHeader;
typedef enum {