aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <emulator@emulace.cz>2023-09-17 09:39:36 +0200
committerJaroslav Hensl <emulator@emulace.cz>2023-09-17 09:39:36 +0200
commitafcbef900e37e3d50d7fbd0a1af7b1de39140471 (patch)
tree1191e642e552ce27a413451fb168b358c5ad99b0
parentacde242b61c662d3f234fc051f059fa58875f5fd (diff)
downloadvmdisp9x-afcbef900e37e3d50d7fbd0a1af7b1de39140471.tar.gz
SVGA-III (stubs)
-rw-r--r--modes.c101
-rw-r--r--vmdisp9x.inf6
-rw-r--r--vmware/pci.c19
-rw-r--r--vmware/pci.h1
-rw-r--r--vmware/svga.c95
-rw-r--r--vmware/svga.h9
-rw-r--r--vmware/svga_reg.h1
-rw-r--r--vmwsvxd.c27
-rw-r--r--vxdcall.h4
9 files changed, 203 insertions, 60 deletions
diff --git a/modes.c b/modes.c
index 789faa4..a0d2e4a 100644
--- a/modes.c
+++ b/modes.c
@@ -433,50 +433,60 @@ extern void __loadds SVGA_UpdateRect(LONG x, LONG y, LONG w, LONG h)
}
}
-/* Initialize SVGA structure and map FIFO to memory */
-static int __loadds SVGA_full_init()
+void SVGA_MapIO()
{
- int rc = 0;
DWORD bounce_sel = 0;
DWORD fifo_base_sel = 0;
-
- dbg_printf("VMWare SVGA-II init\n");
-
- rc = SVGA_Init(FALSE);
-
- if(rc != 0)
- {
- return rc;
- }
-
+ DWORD rmmio_sel = 0;
+
/* get system linear addresses from PM32 RING-0 driver */
- VXD_get_addr(&gSVGA.fbLinear, &gSVGA.fifoLinear, &gSVGA.fifo.bounceLinear);
-
- /* get user flags */
- VXD_get_flags(&gSVGA.userFlags);
-
- dbg_printf("VXD: received %lX %lX %lX\n",
- gSVGA.fbLinear,
- gSVGA.fifoLinear,
- gSVGA.fifo.bounceLinear);
-
- /* map fifo to PM16 memory */
- fifo_base_sel = DPMI_AllocLDTDesc(1);
- if(fifo_base_sel)
+ if(SVGA_IsSvga3())
{
- DPMI_SetSegLimit(fifo_base_sel, 0xFFFF);
- DPMI_SetSegBase(fifo_base_sel, gSVGA.fifoLinear);
- gSVGA.fifoMem = fifo_base_sel :> 0x0;
+ VXD_get_addr(&gSVGA.fbLinear, &gSVGA.rmmio_linear, &gSVGA.fifo.bounceLinear);
+
+ dbg_printf("VXD (SVGA3): received %lX %lX (%lX) %lX\n",
+ gSVGA.fbLinear,
+ gSVGA.rmmio_linear,
+ gSVGA.rmmio_size,
+ gSVGA.fifo.bounceLinear);
+
+ rmmio_sel = DPMI_AllocLDTDesc(1);
+ if(rmmio_sel)
+ {
+ DPMI_SetSegLimit(rmmio_sel, gSVGA.rmmio_size);
+ DPMI_SetSegBase(rmmio_sel, gSVGA.rmmio_linear);
+
+ gSVGA.rmmio = rmmio_sel :> 0x0;
+ }
+
}
-
- /* from PM16 cannot be accesed full fifo buffer properly, so allocate selector to maping as 64K sector */
- gSVGA.fifoSel = DPMI_AllocLDTDesc(1);
- if(gSVGA.fifoSel)
+ else
{
- DPMI_SetSegLimit(gSVGA.fifoSel, 0xFFFF);
- DPMI_SetSegBase(gSVGA.fifoSel, gSVGA.fifoLinear);
-
- gSVGA.fifoAct = 0;
+ VXD_get_addr(&gSVGA.fbLinear, &gSVGA.fifoLinear, &gSVGA.fifo.bounceLinear);
+
+ dbg_printf("VXD: received %lX %lX %lX\n",
+ gSVGA.fbLinear,
+ gSVGA.fifoLinear,
+ gSVGA.fifo.bounceLinear);
+
+ /* map fifo to PM16 memory */
+ fifo_base_sel = DPMI_AllocLDTDesc(1);
+ if(fifo_base_sel)
+ {
+ DPMI_SetSegLimit(fifo_base_sel, 0xFFFF);
+ DPMI_SetSegBase(fifo_base_sel, gSVGA.fifoLinear);
+ gSVGA.fifoMem = fifo_base_sel :> 0x0;
+ }
+
+ /* from PM16 cannot be accesed full fifo buffer properly, so allocate selector to maping as 64K sector */
+ gSVGA.fifoSel = DPMI_AllocLDTDesc(1);
+ if(gSVGA.fifoSel)
+ {
+ DPMI_SetSegLimit(gSVGA.fifoSel, 0xFFFF);
+ DPMI_SetSegBase(gSVGA.fifoSel, gSVGA.fifoLinear);
+
+ gSVGA.fifoAct = 0;
+ }
}
bounce_sel = DPMI_AllocLDTDesc(1);
@@ -487,7 +497,24 @@ static int __loadds SVGA_full_init()
gSVGA.fifo.bounceMem = bounce_sel :> 0x0;
}
+}
+
+/* Initialize SVGA structure and map FIFO to memory */
+static int __loadds SVGA_full_init()
+{
+ int rc = 0;
+ dbg_printf("VMWare SVGA-II init\n");
+
+ rc = SVGA_Init(FALSE);
+
+ if(rc != 0)
+ {
+ return rc;
+ }
+ /* get user flags */
+ VXD_get_flags(&gSVGA.userFlags);
+
//SVGA_Enable();
return 0;
diff --git a/vmdisp9x.inf b/vmdisp9x.inf
index 2a7a754..f457f0c 100644
--- a/vmdisp9x.inf
+++ b/vmdisp9x.inf
@@ -51,7 +51,8 @@ qemumini.vxd=1
[Mfg.VM]
%VBoxVideoVGA.DeviceDesc%=VBox, PCI\VEN_80EE&DEV_BEEF&SUBSYS_00000000
%VBoxVideoSVGA.DeviceDesc%=VBoxSvga, PCI\VEN_80EE&DEV_BEEF&SUBSYS_040515AD
-%VBoxVideoVM.DeviceDesc%=VMSvga, PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD
+%VBoxVideoVM2.DeviceDesc%=VMSvga, PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD
+;svga3:%VBoxVideoVM3.DeviceDesc%=VMSvga, PCI\VEN_15AD&DEV_0406&SUBSYS_040615AD
%QemuStd.DeviceDesc%=Qemu, PCI\VEN_1234&DEV_1111
[VBox]
@@ -344,5 +345,6 @@ HKR,"MODES\32\5120,4096"
Mfg="VirtualBox"
VBoxVideoVGA.DeviceDesc="VBox VGA PCI Adapter"
VBoxVideoSVGA.DeviceDesc="VBox SVGA PCI Adapter"
-VBoxVideoVM.DeviceDesc="VMWare SVGA-II PCI Adapter"
+VBoxVideoVM2.DeviceDesc="VMWare SVGA-II PCI Adapter"
+VBoxVideoVM3.DeviceDesc="VMWare SVGA-III PCI Adapter"
QemuStd.DeviceDesc="QEMU STD VGA PCI Adapter"
diff --git a/vmware/pci.c b/vmware/pci.c
index 07ff86b..502e76f 100644
--- a/vmware/pci.c
+++ b/vmware/pci.c
@@ -238,6 +238,25 @@ PCI_GetBARAddr(const PCIAddress FARP *addr, int index)
return bar & ~mask;
}
+/* from https://wiki.osdev.org/PCI#Address_and_size_of_the_BAR */
+uint32
+PCI_GetBARSize(const PCIAddress FARP *addr, int index)
+{
+ uint32 bar_size = 0;
+ uint32 bar_orig = PCI_ConfigRead32(addr, 16+4*index);
+ uint32 mask = (bar_orig & PCI_CONF_BAR_IO) ? 0x3 : 0xf;
+
+ PCI_ConfigWrite32(addr, 16+4*index, 0xFFFFFFFFUL);
+ bar_size = PCI_ConfigRead32(addr, 16+4*index);
+
+ /* restore original value */
+ PCI_ConfigWrite32(addr, 16+4*index, bar_orig);
+
+ bar_size &= ~mask;
+
+ return (~bar_size) + 1;
+}
+
uint32
PCI_GetSubsystem(const PCIAddress FARP *addr)
{
diff --git a/vmware/pci.h b/vmware/pci.h
index e62d059..5df646f 100644
--- a/vmware/pci.h
+++ b/vmware/pci.h
@@ -96,6 +96,7 @@ Bool PCI_ScanBus(PCIScanState FARP *state);
Bool PCI_FindDevice(uint16 vendorId, uint16 deviceId, PCIAddress FARP *addrOut);
void PCI_SetBAR(const PCIAddress FARP *addr, int index, uint32 value);
uint32 PCI_GetBARAddr(const PCIAddress FARP *addr, int index);
+uint32 PCI_GetBARSize(const PCIAddress FARP *addr, int index);
void PCI_SetMemEnable(const PCIAddress FARP *addr, Bool enable);
uint32 PCI_GetSubsystem(const PCIAddress FARP *addr);
diff --git a/vmware/svga.c b/vmware/svga.c
index 0f7b791..573a568 100644
--- a/vmware/svga.c
+++ b/vmware/svga.c
@@ -130,8 +130,17 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
{
int vga_found = 0;
- if (PCI_FindDevice(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA2,
- &gSVGA.pciAddr)) {
+ if (PCI_FindDevice(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA3, &gSVGA.pciAddr)) {
+ gSVGA.vendorId = PCI_VENDOR_ID_VMWARE;
+ gSVGA.deviceId = PCI_DEVICE_ID_VMWARE_SVGA3;
+#ifndef VXD32
+ dbg_printf("PCI VMWare SVGA-III: %X:%X\n", gSVGA.vendorId, gSVGA.deviceId);
+#endif
+
+ vga_found = 1;
+ }
+
+ if (PCI_FindDevice(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA2, &gSVGA.pciAddr)) {
gSVGA.vendorId = PCI_VENDOR_ID_VMWARE;
gSVGA.deviceId = PCI_DEVICE_ID_VMWARE_SVGA2;
#ifndef VXD32
@@ -172,17 +181,40 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
*/
PCI_SetMemEnable(&gSVGA.pciAddr, TRUE);
- if(gSVGA.deviceId == PCI_DEVICE_ID_VBOX_VGA) {
+
+ if(gSVGA.deviceId == PCI_DEVICE_ID_VBOX_VGA) { /* VBOX SVGA */
/* VBox SVGA have swapped IO and VRAM in PCI BAR */
gSVGA.fbPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
+ gSVGA.vramSize = PCI_GetBARSize(&gSVGA.pciAddr, 0);
gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 1);
+ gSVGA.fifoPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 2);
+
} else {
- gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
- gSVGA.fbPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 1);
+ if(SVGA_IsSVGA3()) /* VMware SVGA2 */
+ {
+ gSVGA.rmmio_start = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
+ gSVGA.rmmio_size = PCI_GetBARSize(&gSVGA.pciAddr, 0);
+
+ gSVGA.fbPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 2);
+ gSVGA.vramSize = PCI_GetBARSize(&gSVGA.pciAddr, 2);
+
+ gSVGA.fifoPhy = 0;
+ gSVGA.ioBase = 0;
+ }
+ else /* VMware SVGA3 */
+ {
+ gSVGA.ioBase = PCI_GetBARAddr(&gSVGA.pciAddr, 0);
+
+ gSVGA.fbPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 1);
+ gSVGA.vramSize = PCI_GetBARSize(&gSVGA.pciAddr, 1);
+
+ gSVGA.fifoPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 2);
+ }
}
- gSVGA.fifoPhy = PCI_GetBARAddr(&gSVGA.pciAddr, 2);
+
dbg_printf(dbg_addr, gSVGA.ioBase, gSVGA.fbPhy, gSVGA.fifoPhy);
+ SVGA_MapIO();
#ifdef VXD32 /* version negotiation is done in PM32 driver now */
/*
@@ -196,7 +228,14 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
if(hwversion == 0)
{
- hwversion = SVGA_VERSION_2;
+ if(gSVGA.deviceId == PCI_DEVICE_ID_VMWARE_SVGA3)
+ {
+ hwversion = SVGA_VERSION_3;
+ }
+ else
+ {
+ hwversion = SVGA_VERSION_2;
+ }
}
gSVGA.deviceVersionId = SVGA_MAKE_ID(hwversion);
@@ -226,9 +265,12 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
* does not support the FIFO buffer at all.
*/
+/*
gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE);
+*/
gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE);
+ gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE);
/*
* Sanity-check the FIFO and framebuffer sizes.
@@ -241,8 +283,11 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
}
#endif
- if (gSVGA.fifoSize < 0x20000) {
- SVGA_Panic("FIFO size very small, probably incorrect.");
+ if(SVGA_IsSVGA3())
+ {
+ if (gSVGA.fifoSize < 0x20000) {
+ SVGA_Panic("FIFO size very small, probably incorrect.");
+ }
}
/*
@@ -279,9 +324,9 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
Intr_SetMask(irq, TRUE);
}
#endif
- gSVGA.fifoLinear = 0;
+ /*gSVGA.fifoLinear = 0;
gSVGA.fifoSel = 0;
- gSVGA.fifoAct = 0;
+ gSGA.fifoAct = 0;*/
#ifdef VXD32
gSVGA.userFlags = 0;
@@ -309,6 +354,11 @@ SVGA_Init(Bool enableFIFO, uint32 hwversion)
return 0;
}
+Bool SVGA_IsSVGA3()
+{
+ return gSVGA.deviceId == PCI_DEVICE_ID_VMWARE_SVGA3;
+}
+
/*
*-----------------------------------------------------------------------------
*
@@ -533,8 +583,16 @@ SVGA_DefaultFaultHandler(int vector) // IN
uint32
SVGA_ReadReg(uint32 index) // IN
{
- outpd(gSVGA.ioBase + SVGA_INDEX_PORT, index);
- return inpd(gSVGA.ioBase + SVGA_VALUE_PORT);
+ if(SVGA_IsSVGA3())
+ {
+ return gSVGA.rmmio[index];
+ }
+ else
+ {
+ /* locking? */
+ outpd(gSVGA.ioBase + SVGA_INDEX_PORT, index);
+ return inpd(gSVGA.ioBase + SVGA_VALUE_PORT);
+ }
}
@@ -559,8 +617,15 @@ void
SVGA_WriteReg(uint32 index, // IN
uint32 value) // IN
{
- outpd(gSVGA.ioBase + SVGA_INDEX_PORT, index);
- outpd(gSVGA.ioBase + SVGA_VALUE_PORT, value);
+ if(SVGA_IsSVGA3())
+ {
+ gSVGA.rmmio[index] = value;
+ }
+ else
+ {
+ outpd(gSVGA.ioBase + SVGA_INDEX_PORT, index);
+ outpd(gSVGA.ioBase + SVGA_VALUE_PORT, value);
+ }
}
diff --git a/vmware/svga.h b/vmware/svga.h
index 8a62800..733f3af 100644
--- a/vmware/svga.h
+++ b/vmware/svga.h
@@ -93,6 +93,12 @@ typedef struct SVGADevice {
uint16 deviceId;
/* adapter in QEMU works only on 32bit */
uint32 userFlags;
+
+ /* SVGA3 */
+ uint32 rmmio_start;
+ uint32 rmmio_size;
+ uint32 rmmio_linear;
+ volatile uint32 FARP *rmmio;
#ifndef REALLY_TINY
volatile struct {
@@ -136,6 +142,9 @@ void SVGA_Disable(void);
void SVGA_Panic(const char *err);
void SVGA_DefaultFaultHandler(int vector);
+Bool SVGA_IsSVGA3();
+void SVGA_MapIO();
+
void SVGA_Flush(void);
uint32 SVGA_ReadReg(uint32 index);
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
index 0c2e13e..ab904a7 100644
--- a/vmware/svga_reg.h
+++ b/vmware/svga_reg.h
@@ -45,6 +45,7 @@ typedef struct uint64 {
*/
#define PCI_VENDOR_ID_VMWARE 0x15AD
#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
+#define PCI_DEVICE_ID_VMWARE_SVGA3 0x0406
#define PCI_VENDOR_ID_INNOTEK 0x80EE
#define PCI_DEVICE_ID_VBOX_VGA 0xBEEF
diff --git a/vmwsvxd.c b/vmwsvxd.c
index 912aabd..f36941d 100644
--- a/vmwsvxd.c
+++ b/vmwsvxd.c
@@ -1023,7 +1023,14 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
break;
case VMWSVXD_PM16_GET_ADDR:
state->Client_ECX = gSVGA.fbLinear;
- state->Client_EDI = gSVGA.fifoLinear;
+ if(SVGA_IsSVGA3())
+ {
+ state->Client_EDI = gSVGA.rmmio_linear;
+ }
+ else
+ {
+ state->Client_EDI = gSVGA.fifoLinear;
+ }
state->Client_ESI = gSVGA.fifo.bounceLinear + PAGE_SIZE; /* first page is for CB header (if CB supported) */
rc = 1;
@@ -1215,6 +1222,15 @@ BOOL RegReadConf(const char *value, DWORD *out)
return rv;
}
+void SVGA_MapIO()
+{
+ if(SVGA_IsSVGA3)
+ {
+ gSVGA.rmmio_linear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.vramSize, 0);
+ gSVGA.rmmio = (uint32 FARP*)gSVGA.rmmio_linear;
+ }
+}
+
/* init device and fill dispatch table */
void Device_Dynamic_Init_proc(DWORD VM)
{
@@ -1284,7 +1300,8 @@ void Device_Dynamic_Init_proc(DWORD VM)
gSVGA.fbLinear = _MapPhysToLinear(gSVGA.fbPhy, gSVGA.vramSize, 0);
/* map phys FIFO to linear */
- gSVGA.fifoLinear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.fifoSize, 0);
+ if(!SVGA_IsSVGA3())
+ gSVGA.fifoLinear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.fifoSize, 0);
/* allocate fifo bounce buffer */
gSVGA.fifo.bounceLinear =
@@ -1295,7 +1312,9 @@ void Device_Dynamic_Init_proc(DWORD VM)
/* system linear addres == PM32 address */
gSVGA.fbMem = (uint8 *)gSVGA.fbLinear;
- gSVGA.fifoMem = (uint32 *)gSVGA.fifoLinear;
+ if(!SVGA_IsSVGA3())
+ gSVGA.fifoMem = (uint32 *)gSVGA.fifoLinear;
+
gSVGA.fifo.bounceMem = (uint8 *)(gSVGA.fifo.bounceLinear + PAGE_SIZE); /* first page is for CB header (if CB supported) */
@@ -1567,8 +1586,6 @@ void Device_Init_proc()
/* shutdown procedure */
void Device_Exit_proc(DWORD VM)
{
- uint32 *screen_id;
-
dbg_printf(dbg_destroy);
/* stop context 0 */
diff --git a/vxdcall.h b/vxdcall.h
index 8ce33a7..f2ba75d 100644
--- a/vxdcall.h
+++ b/vxdcall.h
@@ -15,7 +15,9 @@ void VXD_get_flags(DWORD __far *lpFlags);
BOOL VXD_FIFOCommit(DWORD bytes, BOOL sync);
#define VXD_FIFOCommitAll() \
- if(VXD_FIFOCommit(gSVGA.fifo.reservedSize, FALSE)){gSVGA.fifo.reservedSize = 0;}else{SVGA_FIFOCommitAll();}
+ if(VXD_FIFOCommit(gSVGA.fifo.reservedSize, FALSE)){gSVGA.fifo.reservedSize = 0;}
+
+// if(VXD_FIFOCommit(gSVGA.fifo.reservedSize, FALSE)){gSVGA.fifo.reservedSize = 0;}else{SVGA_FIFOCommitAll();}
#define VXD_FIFOCommitSync() \
VXD_FIFOCommit(gSVGA.fifo.reservedSize, TRUE);gSVGA.fifo.reservedSize = 0