aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-07-22 18:49:18 +0200
committerJaroslav Hensl <jara@hensl.cz>2024-07-22 18:49:18 +0200
commit3a3ca1abfa25d3d595bbb966a261eaede765a80e (patch)
tree7c2a8327dde04975ff312f67bdc1b83d87535418
parentb62d9ec9bc8ba7db0fc191ba8458db3c70b253cf (diff)
downloadvmdisp9x-3a3ca1abfa25d3d595bbb966a261eaede765a80e.tar.gz
VMW vGPU10 (2d), IRQ work (in progress)
-rw-r--r--makefile4
-rw-r--r--vmware/svga.c130
-rw-r--r--vmware/svga.h5
-rw-r--r--vmware/svga_reg.h33
-rw-r--r--vmware/svga_ver.h27
-rw-r--r--vpicd.h82
-rw-r--r--vxd_lib.c45
-rw-r--r--vxd_lib.h6
-rw-r--r--vxd_strings.h21
-rw-r--r--vxd_svga.c244
-rw-r--r--vxd_svga_debug.h3
-rw-r--r--vxd_vdd.c23
-rw-r--r--vxd_vdd.h12
13 files changed, 514 insertions, 121 deletions
diff --git a/makefile b/makefile
index 39167f4..20cf9b3 100644
--- a/makefile
+++ b/makefile
@@ -12,7 +12,7 @@ OBJS += &
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 57
+VER_BUILD = 59
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
@@ -35,7 +35,7 @@ FIXER_CC = wcl386 -q drvfix.c -fe=$(FIXER_EXE)
#FLAGS += -DHWBLT
# Set DBGPRINT to add debug printf logging.
-#DBGPRINT = 1
+DBGPRINT = 1
!ifdef DBGPRINT
FLAGS += -DDBGPRINT
diff --git a/vmware/svga.c b/vmware/svga.c
index 8f320ae..c53f892 100644
--- a/vmware/svga.c
+++ b/vmware/svga.c
@@ -360,6 +360,31 @@ Bool SVGA_IsSVGA3()
return gSVGA.deviceId == PCI_DEVICE_ID_VMWARE_SVGA3;
}
+uint8 SVGA_Install_IRQ()
+{
+ if (gSVGA.capabilities & SVGA_CAP_IRQMASK)
+ {
+ uint8 irq = PCI_ConfigRead8(&gSVGA.pciAddr, 60/*offsetof(PCIConfigSpace, intrLine)*/);
+
+ /* Start out with all SVGA IRQs masked */
+ SVGA_WriteReg(SVGA_REG_IRQMASK, 0);
+
+ /* Clear all pending IRQs stored by the device */
+ outpd(gSVGA.ioBase + SVGA_IRQSTATUS_PORT, 0xFF);
+
+ /* Clear all pending IRQs stored by us */
+ SVGA_ClearIRQ();
+
+ /* Enable the IRQ */
+ //Intr_SetHandler(IRQ_VECTOR(irq), SVGAInterruptHandler);
+ //Intr_SetMask(irq, TRUE);
+
+ return irq;
+ }
+
+ return 0;
+}
+
/*
*-----------------------------------------------------------------------------
*
@@ -376,6 +401,10 @@ Bool SVGA_IsSVGA3()
*-----------------------------------------------------------------------------
*/
+#ifndef P_SIZE
+#define P_SIZE 0x1000
+#endif
+
void
SVGA_Enable(void)
{
@@ -388,8 +417,16 @@ SVGA_Enable(void)
* to the maximum number of registers supported by this driver
* release.
*/
+ uint32 fifo_min = 4;
+ if (gSVGA.capabilities & SVGA_CAP_EXTENDED_FIFO)
+ fifo_min = SVGA_ReadReg(SVGA_REG_MEM_REGS);
+
+ fifo_min *= sizeof(uint32);
+
+ if (fifo_min < P_SIZE)
+ fifo_min = P_SIZE;
- gSVGA.fifoMem[SVGA_FIFO_MIN] = SVGA_FIFO_NUM_REGS * sizeof(uint32);
+ gSVGA.fifoMem[SVGA_FIFO_MIN] = fifo_min;
gSVGA.fifoMem[SVGA_FIFO_MAX] = gSVGA.fifoSize;
//gSVGA.fifoMem[SVGA_FIFO_MAX] = 0xFFFCUL - gSVGA.fifoMem[SVGA_FIFO_MIN];
gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD] = gSVGA.fifoMem[SVGA_FIFO_MIN];
@@ -502,6 +539,16 @@ SVGA_SetModeLegacy(uint32 width, // IN
SVGA_WriteReg(SVGA_REG_HEIGHT, height);
SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, bpp);
SVGA_ReadReg(SVGA_REG_FB_OFFSET);
+
+ if(bpp == 32)
+ {
+ SVGA_WriteReg(SVGA_REG_TRACES, FALSE);
+ }
+ else
+ {
+ SVGA_WriteReg(SVGA_REG_TRACES, TRUE);
+ }
+
SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
gSVGA.pitch = SVGA_ReadReg(SVGA_REG_BYTES_PER_LINE);
}
@@ -785,6 +832,39 @@ void SVGA_Flush(void)
#endif
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SVGA_ClearIRQ --
+ *
+ * Clear all pending IRQs. Any IRQs which occurred prior to this
+ * function call will be ignored by the next SVGA_WaitForIRQ()
+ * call.
+ *
+ * Does not affect the current IRQ mask. This function is not
+ * useful unless the SVGA device has IRQ support.
+ *
+ * Results:
+ * Returns a mask of all the interrupt flags that were set prior
+ * to the clear.
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+uint32
+SVGA_ClearIRQ(void)
+{
+ uint32 flags = 0;
+ ///Atomic_Exchange(gSVGA.irq.pending, flags);
+ flags = gSVGA.irq.pending;
+ gSVGA.irq.pending = 0;
+
+ return flags;
+}
+
+
#if 0 /* JH: all commands using bounce buffer and fifo, better write them myself */
/*
@@ -1560,54 +1640,6 @@ SVGA_HasFencePassed(uint32 fence) // IN
/*
*-----------------------------------------------------------------------------
*
- * SVGA_ClearIRQ --
- *
- * Clear all pending IRQs. Any IRQs which occurred prior to this
- * function call will be ignored by the next SVGA_WaitForIRQ()
- * call.
- *
- * Does not affect the current IRQ mask. This function is not
- * useful unless the SVGA device has IRQ support.
- *
- * Results:
- * Returns a mask of all the interrupt flags that were set prior
- * to the clear.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-#ifndef REALLY_TINY
-/*
-uint32
-SVGA_ClearIRQ(void)
-{
- uint32 flags = 0;
- Atomic_Exchange(gSVGA.irq.pending, flags);
-
- return flags;
-}*/
-
-uint32 SVGA_ClearIRQ(void);
-#pragma aux SVGA_ClearIRQ = \
- ".386" \
- "push eax" \
- "xor eax, eax" \
- "xchg ptr gSVGA.irq.pending, eax" \
- "mov dx, ax" \
- "shr eax, 16" \
- "xchg dx, ax" \
- "xchg bx, ax" \
- "pop eax" \
- "xchg bx, ax" \
- value [dx ax] modify [bx];
-
-#endif
-
-/*
- *-----------------------------------------------------------------------------
- *
* SVGA_WaitForIRQ --
*
* Sleep until an SVGA interrupt occurs. When we wake up, return
diff --git a/vmware/svga.h b/vmware/svga.h
index 6fc4b72..fef77b6 100644
--- a/vmware/svga.h
+++ b/vmware/svga.h
@@ -108,6 +108,10 @@ typedef struct SVGADevice {
IntrContext newContext;
uint32 count;
} irq;
+#else
+ volatile struct {
+ uint32 pending;
+ } irq;
#endif
} SVGADevice;
@@ -144,6 +148,7 @@ void SVGA_DefaultFaultHandler(int vector);
Bool SVGA_IsSVGA3();
void SVGA_MapIO();
+uint8 SVGA_Install_IRQ();
void SVGA_Flush(void);
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
index 2d8b2a6..0962fca 100644
--- a/vmware/svga_reg.h
+++ b/vmware/svga_reg.h
@@ -125,6 +125,11 @@ typedef struct uint64 {
#define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */
#define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */
+#define SVGA_IRQFLAG_COMMAND_BUFFER 0x8
+#define SVGA_IRQFLAG_ERROR 0x10
+#define SVGA_IRQFLAG_REG_FENCE_GOAL 0x20
+#define SVGA_IRQFLAG_MAX 0x40
+
/*
* Registers
*/
@@ -237,6 +242,14 @@ enum {
the use of the current SVGA driver. */
};
+typedef enum SVGARegGuestDriverId {
+ SVGA_REG_GUEST_DRIVER_ID_UNKNOWN = 0,
+ SVGA_REG_GUEST_DRIVER_ID_WDDM = 1,
+ SVGA_REG_GUEST_DRIVER_ID_LINUX = 2,
+ SVGA_REG_GUEST_DRIVER_ID_MAX,
+
+ SVGA_REG_GUEST_DRIVER_ID_SUBMIT = MAX_UINT32,
+} SVGARegGuestDriverId;
/*
* Guest memory regions (GMRs):
@@ -662,6 +675,26 @@ struct SVGASignedPoint {
#define SVGA_CAP_NO_BB_RESTRICTION 0x40000000UL
#define SVGA_CAP_CAP2_REGISTER 0x80000000UL
+#define SVGA_CAP2_NONE 0x00000000
+#define SVGA_CAP2_GROW_OTABLE 0x00000001
+#define SVGA_CAP2_INTRA_SURFACE_COPY 0x00000002
+#define SVGA_CAP2_DX2 0x00000004
+#define SVGA_CAP2_GB_MEMSIZE_2 0x00000008
+#define SVGA_CAP2_SCREENDMA_REG 0x00000010
+#define SVGA_CAP2_OTABLE_PTDEPTH_2 0x00000020
+#define SVGA_CAP2_NON_MS_TO_MS_STRETCHBLT 0x00000040
+#define SVGA_CAP2_CURSOR_MOB 0x00000080
+#define SVGA_CAP2_MSHINT 0x00000100
+#define SVGA_CAP2_CB_MAX_SIZE_4MB 0x00000200
+#define SVGA_CAP2_DX3 0x00000400
+#define SVGA_CAP2_FRAME_TYPE 0x00000800
+#define SVGA_CAP2_COTABLE_COPY 0x00001000
+#define SVGA_CAP2_TRACE_FULL_FB 0x00002000
+#define SVGA_CAP2_EXTRA_REGS 0x00004000
+#define SVGA_CAP2_LO_STAGING 0x00008000
+#define SVGA_CAP2_VIDEO_BLT 0x00010000
+#define SVGA_CAP2_RESERVED 0x80000000
+
/*
* FIFO register indices.
*
diff --git a/vmware/svga_ver.h b/vmware/svga_ver.h
new file mode 100644
index 0000000..cee1732
--- /dev/null
+++ b/vmware/svga_ver.h
@@ -0,0 +1,27 @@
+#ifndef _SVGA_VER_H_
+#define _SVGA_VER_H_
+
+#define VMWGFX_DRIVER_DATE "20211206"
+#define VMWGFX_DRIVER_MAJOR 2
+#define VMWGFX_DRIVER_MINOR 20
+#define VMWGFX_DRIVER_PATCHLEVEL 0
+
+#define LINUX_VERSION_MAJOR 6
+#define LINUX_VERSION_PATCHLEVEL 9
+#define LINUX_VERSION_SUBLEVEL 10
+
+/* constants from linux driver */
+#define VMWGFX_MAX_DISPLAYS 16
+
+#define VMWGFX_NUM_GB_CONTEXT 256
+#define VMWGFX_NUM_GB_SHADER 20000
+#define VMWGFX_NUM_GB_SURFACE 32768
+#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_MAX_DISPLAYS
+#define VMWGFX_NUM_DXCONTEXT 256
+#define VMWGFX_NUM_DXQUERY 512
+#define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\
+ VMWGFX_NUM_GB_SHADER +\
+ VMWGFX_NUM_GB_SURFACE +\
+ VMWGFX_NUM_GB_SCREEN_TARGET)
+
+#endif
diff --git a/vpicd.h b/vpicd.h
new file mode 100644
index 0000000..523de86
--- /dev/null
+++ b/vpicd.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+
+Copyright (c) 2023 Jaroslav Hensl <emulator@emulace.cz>
+
+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.
+
+*****************************************************************************/
+#ifndef __VPICD_H__INCLUDED__
+#define __VPICD_H__INCLUDED__
+
+#pragma pack(push)
+#pragma pack(1)
+typedef struct _VPICD_IRQ_Descriptor
+{
+ WORD IRQ_Number;
+ WORD Options;
+ DWORD Hw_Int_Proc;
+ DWORD Virt_Int_Proc;
+ DWORD EOI_Proc;
+ DWORD Mask_Change_Proc;
+ DWORD IRET_Proc;
+ DWORD IRET_Time_Out;
+ DWORD Hw_Int_Ref;
+} VPICD_IRQ_Descriptor;
+#pragma pack(pop)
+
+#define VPICD_OPT_READ_HW_IRR 0x01
+#define VPICD_OPT_CAN_SHARE 0x02
+#define VPICD_OPT_VIRT_INT_REJECT 0x10
+#define VPICD_OPT_SHARE_PMODE_ONLY 0x20
+
+#define VPICD__Get_Version 0
+#define VPICD__Virtualize_IRQ 1
+#define VPICD__Set_Int_Request 2
+#define VPICD__Clear_Int_Request 3
+#define VPICD__Phys_EOI 4
+#define VPICD__Get_Complete_Status 5
+#define VPICD__Get_Status 6
+#define VPICD__Test_Phys_Request 7
+#define VPICD__Physically_Mask 8
+#define VPICD__Physically_Unmask 9
+#define VPICD__Set_Auto_Masking 10
+#define VPICD__Get_IRQ_Complete_Status 11
+#define VPICD__Convert_Handle_To_IRQ 12
+#define VPICD__Convert_IRQ_To_Int 13
+#define VPICD__Convert_Int_To_IRQ 14
+#define VPICD__Call_When_Hw_Int 15
+#define VPICD__Force_Default_Owner 16
+#define VPICD__Force_Default_Behavior 17
+#define VPICD__Auto_Mask_At_Inst_Swap 18
+#define VPICD__Begin_Inst_Page_Swap 19
+#define VPICD__End_Inst_Page_Swap 20
+#define VPICD__Virtual_EOI 21
+#define VPICD__Get_Virtualization_Count 22
+#define VPICD__Post_Sys_Critical_Init 23
+#define VPICD__VM_SlavePIC_Mask_Change 24
+#define VPICD__Clear_IR_Bits 25
+#define VPICD__Get_Level_Mask 26
+#define VPICD__Set_Level_Mask 27
+#define VPICD__Set_Irql_Mask 28
+#define VPICD__Set_Channel_Irql 29
+#define VPICD__Prepare_For_Shutdown 30
+#define VPICD__Register_Trigger_Handler 31
+
+
+#endif /* __VPICD_H__INCLUDED__ */
diff --git a/vxd_lib.c b/vxd_lib.c
index eade7b2..cff6666 100644
--- a/vxd_lib.c
+++ b/vxd_lib.c
@@ -27,6 +27,7 @@ THE SOFTWARE.
#include "winhack.h"
#include "vmm.h"
#include "vxd.h"
+#include "vpicd.h"
#include "svga_all.h"
@@ -474,3 +475,47 @@ DWORD __declspec(naked) __cdecl _RegQueryValueEx(DWORD hKey, char *lpszValueName
VMMJmp(_RegQueryValueEx);
}
+void Enable_Global_Trapping(DWORD port)
+{
+ static DWORD sPort = 0;
+ sPort = port;
+
+ _asm push edx
+ _asm mov edx, [sPort];
+ VMMCall(Enable_Global_Trapping);
+ _asm pop edx
+}
+
+void Disable_Global_Trapping(DWORD port)
+{
+ static DWORD sPort = 0;
+ sPort = port;
+
+ _asm push edx
+ _asm mov edx, [sPort];
+ VMMCall(Disable_Global_Trapping);
+ _asm pop edx
+}
+
+BOOL VPICD_Virtualize_IRQ(struct _VPICD_IRQ_Descriptor *vid)
+{
+ static VPICD_IRQ_Descriptor *svid;
+ static BOOL r;
+
+ r = 0;
+ svid = vid;
+
+ _asm {
+ push edi
+ mov edi, [svid]
+ };
+ VxDCall(VPICD, Virtualize_IRQ)
+ _asm {
+ jc Virtualize_IRQ_err
+ mov [r], 1
+ Virtualize_IRQ_err:
+ pop edi
+ };
+
+ return r;
+}
diff --git a/vxd_lib.h b/vxd_lib.h
index 7c9aef5..96453e5 100644
--- a/vxd_lib.h
+++ b/vxd_lib.h
@@ -58,6 +58,9 @@ void __cdecl _BuildDescriptorDWORDs(ULONG DESCBase, ULONG DESCLimit, ULONG DESCT
void __cdecl _Allocate_LDT_Selector(ULONG vm, ULONG DescHigh, ULONG DescLow, ULONG Count, ULONG flags, DWORD *outFirstSelector, DWORD *outSelectorTable);
void __cdecl _Allocate_GDT_Selector(ULONG DescHigh, ULONG DescLow, ULONG flags, DWORD *outFirstSelector, DWORD *outSelectorTable);
+void Enable_Global_Trapping(DWORD port);
+void Disable_Global_Trapping(DWORD port);
+
/**
* round size in bytes to number of pages
**/
@@ -86,3 +89,6 @@ void dbg_printf( const char *s, ... );
#define dbg_printf(s, ...)
#endif
+struct _VPICD_IRQ_Descriptor;
+
+BOOL VPICD_Virtualize_IRQ(struct _VPICD_IRQ_Descriptor *vid);
diff --git a/vxd_strings.h b/vxd_strings.h
index b6ebca2..4defcc1 100644
--- a/vxd_strings.h
+++ b/vxd_strings.h
@@ -134,6 +134,27 @@ DSTR(dbg_hw_mouse_move, "hw mouse: moving: %ld x %ld (visible: %d, valid: %d)\n"
DSTR(dbg_hw_mouse_show, "hw mouse: show (valid: %d)\n");
DSTR(dbg_hw_mouse_hide, "hw mouse: hide\n");
+DSTR(dbg_cb_flags, "CB: flags = %lX\n");
+
+DSTR(dbg_cb_start, "CB start success!\n");
+DSTR(dbg_cb_start_err, "CB start error: %d\n");
+DSTR(dbg_cb_stop, "CB stop!\n");
+DSTR(dbg_wait_cb, "... Waiting for CB at line: %ld\n");
+
+DSTR(dbg_ctr_start, "CB CTRL begin\n");
+DSTR(dbg_ctr_end, "CB CTRL end\n");
+
+DSTR(dbg_cb_stop_status, "CB stop status %ld\n");
+
+DSTR(dbg_irq, "IRQ!\n");
+
+DSTR(dbg_irq_install, "IRQ(%d) trap installed\n");
+DSTR(dbg_irq_install_fail, "IRQ(%d) found, but cannot be traped\n");
+
+DSTR(dbg_no_irq, "No IRQ enabled\n");
+
+DSTR(dbg_disable, "HW disable");
+
#undef DSTR
#endif
diff --git a/vxd_svga.c b/vxd_svga.c
index 0ffe4d2..9b5bd4a 100644
--- a/vxd_svga.c
+++ b/vxd_svga.c
@@ -30,6 +30,7 @@ THE SOFTWARE.
#include "winhack.h"
#include "vmm.h"
#include "vxd.h"
+#include "vpicd.h"
#include "vxd_lib.h"
#include "svga_all.h"
@@ -42,6 +43,8 @@ THE SOFTWARE.
#include "vxd_strings.h"
+#include "svga_ver.h"
+
/*
* consts
*/
@@ -71,6 +74,7 @@ THE SOFTWARE.
#define WAIT_FOR_CB(_cb, _forcesync) \
do{ \
DWORD wcnt; \
+ /*dbg_printf(dbg_wait_cb, __LINE__);*/ \
for(wcnt = 0; (_cb)->status == SVGA_CB_STATUS_NONE; wcnt++){ \
/*if(wcnt >= SVGA_TIMEOUT) break;*/ \
WAIT_FOR_CB_SYNC_ ## _forcesync \
@@ -81,6 +85,8 @@ THE SOFTWARE.
#define WAIT_FOR_CB_SYNC_0
#define WAIT_FOR_CB_SYNC_1 SVGA_Sync();
+static void SVGA_CB_start();
+
/*
* types
*/
@@ -134,6 +140,7 @@ static volatile SVGACBHeader *last_cb = NULL;
static uint64 cb_next_id = {0, 0};
static DWORD fence_next_id = 1;
void *cmdbuf = NULL;
+void *ctlbuf = NULL;
static DWORD cb_sem;
static svga_cache_state_t cache_state = {0, 0};
@@ -147,12 +154,12 @@ static DWORD present_fence = 0;
/* object table for GPU10 */
static SVGA_OT_info_entry_t otable_setup[SVGA_OTABLE_DX_MAX] = {
- {0, NULL, RoundToPages(SVGA3D_MAX_MOBS*sizeof(SVGAOTableMobEntry))*P_SIZE, 0}, /* SVGA_OTABLE_MOB */
- {0, NULL, RoundToPages(SVGA3D_MAX_SURFACE_IDS*sizeof(SVGAOTableSurfaceEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SURFACE */
- {0, NULL, RoundToPages(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableContextEntry))*P_SIZE, 0}, /* SVGA_OTABLE_CONTEXT */
- {0, NULL, 0, 0}, /* SVGA_OTABLE_SHADER - not used */
- {0, NULL, RoundToPages(VBOX_VIDEO_MAX_SCREENS*sizeof(SVGAOTableScreenTargetEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SCREENTARGET (VBOX_VIDEO_MAX_SCREENS) */
- {0, NULL, RoundToPages(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableDXContextEntry))*P_SIZE, 0}, /* SVGA_OTABLE_DXCONTEXT */
+ {0, NULL, RoundToPages(VMWGFX_NUM_MOB*sizeof(SVGAOTableMobEntry))*P_SIZE, 0}, /* SVGA_OTABLE_MOB */
+ {0, NULL, RoundToPages(VMWGFX_NUM_GB_SURFACE*sizeof(SVGAOTableSurfaceEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SURFACE */
+ {0, NULL, RoundToPages(VMWGFX_NUM_GB_CONTEXT*sizeof(SVGAOTableContextEntry))*P_SIZE, 0}, /* SVGA_OTABLE_CONTEXT */
+ {0, NULL, RoundToPages(VMWGFX_NUM_GB_SHADER *sizeof(SVGAOTableShaderEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SHADER - not used */
+ {0, NULL, RoundToPages(VMWGFX_NUM_GB_SCREEN_TARGET*sizeof(SVGAOTableScreenTargetEntry))*P_SIZE, 0}, /* SVGA_OTABLE_SCREENTARGET (VBOX_VIDEO_MAX_SCREENS) */
+ {0, NULL, RoundToPages(VMWGFX_NUM_DXCONTEXT*sizeof(SVGAOTableDXContextEntry))*P_SIZE, 0}, /* SVGA_OTABLE_DXCONTEXT */
};
static SVGA_OT_info_entry_t *otable = NULL;
@@ -611,14 +618,14 @@ void SVGA_fence_wait(DWORD fence_id)
/**
* Allocate memory for command buffer
**/
-DWORD *SVGA_CMB_alloc()
+static DWORD *SVGA_CMB_alloc_size(DWORD datasize)
{
DWORD phy;
SVGACBHeader *cb;
Begin_Critical_Section(0);
- cb = (SVGACBHeader*)_PageAllocate(RoundToPages(SVGA_CB_MAX_SIZE+sizeof(SVGACBHeader)), PG_SYS, 0, 0, 0x0, 0x100000, &phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+ cb = (SVGACBHeader*)_PageAllocate(RoundToPages(datasize+sizeof(SVGACBHeader)), PG_SYS, 0, 0, 0x0, 0x100000, &phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
if(cb)
{
@@ -653,6 +660,11 @@ void SVGA_CMB_free(DWORD *cmb)
End_Critical_Section();
}
+DWORD *SVGA_CMB_alloc()
+{
+ return SVGA_CMB_alloc_size(SVGA_CB_MAX_SIZE);
+}
+
void *SVGA_cmd_ptr(DWORD *buf, DWORD *pOffset, DWORD cmd, DWORD cmdsize)
{
DWORD pp = (*pOffset)/sizeof(DWORD);
@@ -699,7 +711,7 @@ void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_status_t
}
#ifdef DBGPRINT
-// debug_cmdbuf(cmb, cmb_size);
+ debug_cmdbuf(cmb, cmb_size);
// debug_cmdbuf_trace(cmb, cmb_size, SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
// debug_draw(cmb, cmb_size);
#endif
@@ -916,6 +928,23 @@ void SVGA_CMB_submit(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_status_t FBPTR st
End_Critical_Section();
}
+void SVGA_IRQ_proc()
+{
+ dbg_printf(dbg_irq);
+}
+
+void __declspec(naked) SVGA_IRQ_entry()
+{
+ _asm
+ {
+ pushad
+ call SVGA_IRQ_proc
+ popad
+ }
+
+ VxDJmp(VPICD, Set_Int_Request);
+}
+
BOOL SVGA_vxdcmd(DWORD cmd)
{
switch(cmd)
@@ -949,6 +978,32 @@ BOOL st_useable(DWORD bpp)
return FALSE;
}
+static void SVGA_write_driver_id()
+{
+ if(gSVGA.deviceVersionId >= SVGA_ID_2)
+ {
+ uint32 caps2 = SVGA_ReadReg(SVGA_REG_CAP2);
+
+ if((caps2 & SVGA_CAP2_DX2) != 0)
+ {
+ SVGA_WriteReg(SVGA_REG_GUEST_DRIVER_ID, SVGA_REG_GUEST_DRIVER_ID_LINUX);
+
+ SVGA_WriteReg(SVGA_REG_GUEST_DRIVER_VERSION1,
+ LINUX_VERSION_MAJOR << 24 |
+ LINUX_VERSION_PATCHLEVEL << 16 |
+ LINUX_VERSION_SUBLEVEL);
+
+ SVGA_WriteReg(SVGA_REG_GUEST_DRIVER_VERSION2,
+ VMWGFX_DRIVER_MAJOR << 24 |
+ VMWGFX_DRIVER_MINOR << 16 |
+ VMWGFX_DRIVER_PATCHLEVEL);
+
+ SVGA_WriteReg(SVGA_REG_GUEST_DRIVER_VERSION3, 0);
+
+ SVGA_WriteReg(SVGA_REG_GUEST_DRIVER_ID, SVGA_REG_GUEST_DRIVER_ID_SUBMIT);
+ }
+ }
+}
/**
* Init SVGA-II hardware
@@ -962,6 +1017,7 @@ BOOL SVGA_init_hw()
DWORD conf_rgb565bug = 1;
DWORD conf_cb = 1;
DWORD conf_hw_version = SVGA_VERSION_2;
+ uint8 irq = 0;
int rc;
@@ -1014,34 +1070,50 @@ BOOL SVGA_init_hw()
if(!SVGA_IsSVGA3())
gSVGA.fifoLinear = _MapPhysToLinear(gSVGA.fifoPhy, gSVGA.fifoSize, 0);
-#if 0
- /* allocate fifo bounce buffer */
- gSVGA.fifo.bounceLinear =
- _PageAllocate(
- (SVGA_BOUNCE_SIZE + PAGE_SIZE)/PAGE_SIZE,
- PG_SYS, 0, 0, 0x0, 0x100000, &(gSVGA.fifo.bouncePhy), PAGECONTIG | PAGEUSEALIGN | PAGEFIXED
- );
-#endif
-
/* system linear addres == PM32 address */
gSVGA.fbMem = (uint8 *)gSVGA.fbLinear;
if(!SVGA_IsSVGA3())
gSVGA.fifoMem = (uint32 *)gSVGA.fifoLinear;
-#if 0
- gSVGA.fifo.bounceMem = (uint8 *)(gSVGA.fifo.bounceLinear + PAGE_SIZE); /* first page is for CB header (if CB supported) */
-#endif
-
dbg_printf(dbg_mapping);
dbg_printf(dbg_mapping_map, gSVGA.fbPhy, gSVGA.fbMem);
dbg_printf(dbg_mapping_map, gSVGA.fifoPhy, gSVGA.fifoMem);
//dbg_printf(dbg_mapping_map, gSVGA.fifo.bouncePhy, gSVGA.fifo.bounceMem);
dbg_printf(dbg_siz, sizeof(gSVGA), sizeof(uint8 FARP *));
+ SVGA_write_driver_id();
+
+#if 0
+ irq = SVGA_Install_IRQ();
+ if(irq > 0)
+ {
+ VPICD_IRQ_Descriptor vid;
+ memset(&vid, 0, sizeof(vid));
+ vid.IRQ_Number = irq;
+ vid.Options = VPICD_OPT_CAN_SHARE;
+ vid.Hw_Int_Proc = (DWORD)SVGA_IRQ_entry;
+ vid.IRET_Time_Out = 500;
+
+ if(VPICD_Virtualize_IRQ(&vid))
+ {
+ dbg_printf(dbg_irq_install, irq);
+ }
+ else
+ {
+ dbg_printf(dbg_irq_install_fail, irq);
+ }
+ }
+ else
+ {
+ dbg_printf(dbg_no_irq);
+ }
+#endif
+
/* enable FIFO */
SVGA_Enable();
/* allocate GB tables, if supported */
+
if(SVGA_ReadReg(SVGA_REG_CAPABILITIES) & SVGA_CAP_GBOBJECTS)
{
SVGA_OTable_alloc();
@@ -1068,19 +1140,27 @@ BOOL SVGA_init_hw()
SVGA_DB_alloc();
+ /* allocate buffer for enable and disable CB */
+ ctlbuf = SVGA_CMB_alloc_size(64);
+
/* allocate CB for this driver */
cmdbuf = SVGA_CMB_alloc();
-
+
/* vGPU10 */
if(gb_support)
{
- SVGA_OTable_load();
+ SVGA_CB_start();
- if(st_surface_mb >= 8)
+ if(cb_support) /* SVGA_CB_start may fail */
{
- if(st_memory_allocate(st_surface_mb*1024*1024, &st_address))
+ SVGA_OTable_load();
+
+ if(st_surface_mb >= 8)
{
- st_used = TRUE;
+ if(st_memory_allocate(st_surface_mb*1024*1024, &st_address))
+ {
+ st_used = TRUE;
+ }
}
}
}
@@ -1127,6 +1207,11 @@ BOOL SVGA_init_hw()
dbg_printf(dbg_cache, cache_enabled);
+ if(irq > 0)
+ {
+ SVGA_WriteReg(SVGA_REG_IRQMASK, SVGA_IRQFLAG_COMMAND_BUFFER);
+ }
+
return TRUE;
}
@@ -1516,6 +1601,46 @@ void SVGA_flushcache()
End_Critical_Section();
}
+static DWORD SVGA_CB_ctr(DWORD data_size)
+{
+ SVGACBHeader *cb = ((SVGACBHeader *)ctlbuf)-1;
+
+ dbg_printf(dbg_ctr_start);
+
+ //Begin_Critical_Section(0);
+
+ cb->status = SVGA_CB_STATUS_NONE;
+ cb->errorOffset = 0;
+ cb->offset = 0; /* VMware modified this, needs to be clear */
+ cb->flags = SVGA_CB_FLAG_NO_IRQ;
+ cb->mustBeZero[0] = 0;
+ cb->mustBeZero[1] = 0;
+ cb->mustBeZero[2] = 0;
+ cb->mustBeZero[3] = 0;
+ cb->mustBeZero[4] = 0;
+ cb->mustBeZero[5] = 0;
+ cb->dxContext = 0;
+ cb->id.low = cb_next_id.low;
+ cb->id.hi = cb_next_id.hi;
+ cb->length = data_size;
+
+ SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0);
+ SVGA_WriteReg(SVGA_REG_COMMAND_LOW, (cb->ptr.pa.low - sizeof(SVGACBHeader)) | SVGA_CB_CONTEXT_DEVICE);
+ SVGA_Sync();
+
+ SVGA_cb_id_inc();
+
+ while(cb->status == SVGA_CB_STATUS_NONE)
+ {
+ SVGA_Sync();
+ }
+
+ //End_Critical_Section();
+
+ dbg_printf(dbg_ctr_end);
+
+ return cb->status;
+}
/**
* GPU10: start context0
@@ -1523,19 +1648,28 @@ void SVGA_flushcache()
**/
static void SVGA_CB_start()
{
- if(cb_support)
+ if(cb_support && cb_context0 == FALSE)
{
- cb_enable_t *cbe = cmdbuf;
- wait_for_cmdbuf();
-
+ cb_enable_t *cbe = ctlbuf;
+ DWORD status;
+
memset(cbe, 0, sizeof(cb_enable_t));
cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
cbe->cbstart.enable = 1;
cbe->cbstart.context = SVGA_CB_CONTEXT_0;
- submit_cmdbuf(sizeof(cb_enable_t), SVGA_CB_USE_CONTEXT_DEVICE|SVGA_CB_SYNC, 0);
+ status = SVGA_CB_ctr(sizeof(cb_enable_t));
- cb_context0 = TRUE;
+ if(status == SVGA_CB_STATUS_COMPLETED)
+ {
+ dbg_printf(dbg_cb_start);
+ cb_context0 = TRUE;
+ }
+ else
+ {
+ cb_support = FALSE;
+ dbg_printf(dbg_cb_start_err, status);
+ }
}
}
@@ -1549,15 +1683,18 @@ static void SVGA_CB_stop()
if(cb_support)
{
- cb_enable_t *cbe = cmdbuf;
- wait_for_cmdbuf();
-
+ DWORD status;
+ cb_enable_t *cbe = ctlbuf;
+
memset(cbe, 0, sizeof(cb_enable_t));
cbe->cmd = SVGA_DC_CMD_START_STOP_CONTEXT;
cbe->cbstart.enable = 0;
cbe->cbstart.context = SVGA_CB_CONTEXT_0;
- submit_cmdbuf(sizeof(cb_enable_t), SVGA_CB_USE_CONTEXT_DEVICE|SVGA_CB_SYNC, 0);
+ status = SVGA_CB_ctr(sizeof(cb_enable_t));
+ dbg_printf(dbg_cb_stop_status, status);
+
+ dbg_printf(dbg_cb_stop);
}
}
@@ -1645,7 +1782,7 @@ static void SVGA_defineScreen(DWORD w, DWORD h, DWORD bpp)
screen->screen.backingStore.ptr.offset = 0;
screen->screen.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
-
+
/* set GMR to same location as screen */
if(bpp >= 15/* || bpp < 32*/)
{
@@ -1813,22 +1950,35 @@ BOOL SVGA_setmode(DWORD w, DWORD h, DWORD bpp)
{
SVGA_SetModeLegacy(w, h, bpp);
}
+ /* VMware, vGPU10: OK, when screen has change, whoale GPU is reset including FIFO */
+ SVGA_Enable();
SVGA_Flush_CB_critical(); /* make sure, that is really set */
-
- has3D = SVGA3D_Init();
-
+
/* setting screen by fifo, this method is required in VB 6.1 */
if(SVGA_hasAccelScreen())
{
if(!st_useable(bpp))
{
SVGA_defineScreen(w, h, bpp);
+
+ /* reenable fifo */
+ SVGA_Enable();
}
SVGA_Flush_CB_critical();
}
+ /* start command buffer context 0 */
+ SVGA_CB_start();
+ if(gb_support && cb_context0)
+ {
+ // fixme: otables are probably reset too
+ //SVGA_OTable_load();
+ }
+
+ has3D = SVGA3D_Init();
+
/*
* JH: this is a bit stupid = all SVGA command cannot work with non 32 bpp.
* SVGA_CMD_UPDATE included. So if we're working in 32 bpp, we'll disable
@@ -1838,7 +1988,7 @@ BOOL SVGA_setmode(DWORD w, DWORD h, DWORD bpp)
* QEMU hasn't SVGA_REG_TRACES register and framebuffer cannot be se to
* 16 or 8 bpp = we supporting only 32 bpp moders if we're running under it.
*/
- if(!st_useable(bpp))
+/* if(!st_useable(bpp))
{
if(bpp == 32)
{
@@ -1848,20 +1998,18 @@ BOOL SVGA_setmode(DWORD w, DWORD h, DWORD bpp)
{
SVGA_WriteReg(SVGA_REG_TRACES, TRUE);
}
+ SVGA_WriteReg(SVGA_REG_TRACES, TRUE);
}
else
{
SVGA_WriteReg(SVGA_REG_TRACES, FALSE);
}
- SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);
+ SVGA_WriteReg(SVGA_REG_ENABLE, TRUE);*/
SVGA_Sync();
-
+
SVGA_Flush_CB_critical();
- /* start command buffer context 0 */
- SVGA_CB_start();
-
if(st_useable(bpp))
{
st_defineScreen(w, h, bpp);
@@ -2054,6 +2202,8 @@ void SVGA_HW_enable()
void SVGA_HW_disable()
{
+ dbg_printf(dbg_disable);
+
SVGA_CB_stop();
SVGA_Disable();
diff --git a/vxd_svga_debug.h b/vxd_svga_debug.h
index a67a3eb..62b389c 100644
--- a/vxd_svga_debug.h
+++ b/vxd_svga_debug.h
@@ -257,6 +257,7 @@ static char svga_cmd_tables[][64] = {
#define CMD3D_MIN 1040
#define CMD3D_MAX 1291
+static char dbg_bufinfo[] = "commands size: %d\n";
static char dbg_cmd3d[] = "cmd3D: %s (%d)\n";
static char dbg_cmd3d_trace[] = "cmd3D(%02ld): %s (%ld)\n";
//static char dbg_cmd_fence[] = "cmd FENCE\n";
@@ -267,6 +268,8 @@ void debug_cmdbuf(void *cmdbuf, DWORD cmd_size)
BYTE *ptr = cmdbuf;
BYTE *ptr_max = ptr + cmd_size;
+ dbg_printf(dbg_bufinfo, cmd_size);
+
while(ptr < ptr_max)
{
DWORD *cmd = (DWORD*)ptr;
diff --git a/vxd_vdd.c b/vxd_vdd.c
index 576d413..422b1c4 100644
--- a/vxd_vdd.c
+++ b/vxd_vdd.c
@@ -436,29 +436,6 @@ VDDPROC(VESA_SUPPORT, vesa_support)
}
-void Enable_Global_Trapping(DWORD port)
-{
- static DWORD sPort = 0;
- sPort = port;
-
- _asm push edx
- _asm mov edx, [sPort];
- VMMCall(Enable_Global_Trapping);
- _asm pop edx
-}
-
-
-void Disable_Global_Trapping(DWORD port)
-{
- static DWORD sPort = 0;
- sPort = port;
-
- _asm push edx
- _asm mov edx, [sPort];
- VMMCall(Disable_Global_Trapping);
- _asm pop edx
-}
-
VDDPROC(PRE_HIRES_TO_VGA, pre_hires_to_vga)
{
mode_changing = TRUE;
diff --git a/vxd_vdd.h b/vxd_vdd.h
index f25e2c1..eda2b9c 100644
--- a/vxd_vdd.h
+++ b/vxd_vdd.h
@@ -135,4 +135,16 @@ typedef struct {
void Enable_Global_Trapping(DWORD port);
void Disable_Global_Trapping(DWORD port);
+//
+// WIN32 IOCTLS
+//
+// The following defines are used with the Win32 function DeviceIOControl
+//
+#define VDD_IOCTL_SET_NOTIFY 0x10000001 // set mode change notify
+#define VDD_IOCTL_GET_DDHAL 0x10000002 // get DDHAL functions from miniVDD
+#define VDD_IOCTL_COPY_PROTECTION 0x10000003 // copy protection enable/disable
+#define VDD_IOCTL_I2C_OPEN 0x10000004 // open i2c port for access
+#define VDD_IOCTL_I2C_ACCESS 0x10000005 // read/write interface
+
+
#endif /* __VXD_VDD_H__INCLUDED__ */