diff options
author | Jaroslav Hensl <jara@hensl.cz> | 2024-07-22 18:49:18 +0200 |
---|---|---|
committer | Jaroslav Hensl <jara@hensl.cz> | 2024-07-22 18:49:18 +0200 |
commit | 3a3ca1abfa25d3d595bbb966a261eaede765a80e (patch) | |
tree | 7c2a8327dde04975ff312f67bdc1b83d87535418 | |
parent | b62d9ec9bc8ba7db0fc191ba8458db3c70b253cf (diff) | |
download | vmdisp9x-3a3ca1abfa25d3d595bbb966a261eaede765a80e.tar.gz |
VMW vGPU10 (2d), IRQ work (in progress)
-rw-r--r-- | makefile | 4 | ||||
-rw-r--r-- | vmware/svga.c | 130 | ||||
-rw-r--r-- | vmware/svga.h | 5 | ||||
-rw-r--r-- | vmware/svga_reg.h | 33 | ||||
-rw-r--r-- | vmware/svga_ver.h | 27 | ||||
-rw-r--r-- | vpicd.h | 82 | ||||
-rw-r--r-- | vxd_lib.c | 45 | ||||
-rw-r--r-- | vxd_lib.h | 6 | ||||
-rw-r--r-- | vxd_strings.h | 21 | ||||
-rw-r--r-- | vxd_svga.c | 244 | ||||
-rw-r--r-- | vxd_svga_debug.h | 3 | ||||
-rw-r--r-- | vxd_vdd.c | 23 | ||||
-rw-r--r-- | vxd_vdd.h | 12 |
13 files changed, 514 insertions, 121 deletions
@@ -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 @@ -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__ */
@@ -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;
+}
@@ -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
@@ -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;
@@ -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;
@@ -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__ */
|