- Timestamp:
- Jul 25, 2023 8:20:54 AM (19 months ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
r100178 r100690 459 459 static const char *vmsvgaIndexToString(PVGASTATE pThis, uint32_t idxReg) 460 460 { 461 AssertCompile(SVGA_REG_TOP == 77); /* Ensure that the correct headers are used. */461 AssertCompile(SVGA_REG_TOP == 84); /* Ensure that the correct headers are used. */ 462 462 switch (idxReg) 463 463 { … … 545 545 SVGA_CASE_ID2STR(SVGA_REG_SCREENDMA); 546 546 SVGA_CASE_ID2STR(SVGA_REG_GBOBJECT_MEM_SIZE_KB); 547 SVGA_CASE_ID2STR(SVGA_REG_REGS_START_HIGH32); 548 SVGA_CASE_ID2STR(SVGA_REG_REGS_START_LOW32); 549 SVGA_CASE_ID2STR(SVGA_REG_FB_START_HIGH32); 550 SVGA_CASE_ID2STR(SVGA_REG_FB_START_LOW32); 551 SVGA_CASE_ID2STR(SVGA_REG_MSHINT); 552 SVGA_CASE_ID2STR(SVGA_REG_IRQ_STATUS); 553 SVGA_CASE_ID2STR(SVGA_REG_DIRTY_TRACKING); 547 554 SVGA_CASE_ID2STR(SVGA_REG_TOP); /* Must be 1 more than the last register */ 548 555 … … 1002 1009 * @param pDevIns The device instance. 1003 1010 * @param pThis The shared VGA/VMSVGA state. 1011 * @param idxReg The register index being read. 1004 1012 * @param pu32 Where to store the read value 1005 1013 */ 1006 static int vmsvgaReadPort(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t *pu32)1014 static int vmsvgaReadPort(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t idxReg, uint32_t *pu32) 1007 1015 { 1008 1016 #ifdef IN_RING3 … … 1012 1020 *pu32 = 0; 1013 1021 1014 /* Rough index register validation. */1015 uint32_t idxReg = pThis->svga.u32IndexReg;1016 #if !defined(IN_RING3) && defined(VBOX_STRICT)1017 ASSERT_GUEST_MSG_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg),1018 VINF_IOM_R3_IOPORT_READ);1019 #else1020 ASSERT_GUEST_MSG_STMT_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg),1021 STAM_REL_COUNTER_INC(&pThis->svga.StatRegUnknownRd),1022 VINF_SUCCESS);1023 #endif1024 RT_UNTRUSTED_VALIDATED_FENCE();1025 1026 1022 /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */ 1027 1023 if ( idxReg >= SVGA_REG_ID_0_TOP … … 1029 1025 { 1030 1026 idxReg += SVGA_PALETTE_BASE - SVGA_REG_ID_0_TOP; 1031 Log(("vmsvga WritePort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg));1027 Log(("vmsvgaReadPort: SVGA_ID_0 reg adj %#x -> %#x\n", pThis->svga.u32IndexReg, idxReg)); 1032 1028 } 1033 1029 … … 1573 1569 1574 1570 case SVGA_REG_FIFO_CAPS: 1575 case SVGA_REG_FENCE: /* Same as SVGA_FIFO_FENCE for PCI_ID_SVGA3. Our device is PCI_ID_SVGA2 so not supported. */ 1571 { 1572 if (pThis->fVmSvga3) 1573 *pu32 = SVGA_FIFO_CAP_FENCE 1574 | SVGA_FIFO_CAP_PITCHLOCK 1575 | SVGA_FIFO_CAP_CURSOR_BYPASS_3 1576 | SVGA_FIFO_CAP_RESERVE 1577 | SVGA_FIFO_CAP_GMR2 1578 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED 1579 | SVGA_FIFO_CAP_SCREEN_OBJECT_2; 1580 else 1581 *pu32 = 0; 1582 break; 1583 } 1584 case SVGA_REG_FENCE: 1585 { 1586 if (pThis->fVmSvga3) 1587 *pu32 = pThis->svga.u32FenceLast; 1588 else 1589 *pu32 = 0; 1590 break; 1591 } 1592 1576 1593 case SVGA_REG_RESERVED1: /* SVGA_REG_RESERVED* correspond to SVGA_REG_CURSOR4_*. Require SVGA_CAP2_EXTRA_REGS. */ 1577 1594 case SVGA_REG_RESERVED2: … … 1587 1604 *pu32 = _1G / _1K; 1588 1605 break; 1606 1607 case SVGA_REG_IRQ_STATUS: 1608 { 1609 if (pThis->fVmSvga3) 1610 *pu32 = pThis->svga.u32IrqStatus; 1611 else 1612 *pu32 = 0; 1613 break; 1614 } 1589 1615 1590 1616 default: … … 1771 1797 { 1772 1798 uint32_t RT_UNTRUSTED_VOLATILE_GUEST *pFIFO = pThisCC->svga.pau32FIFO; 1773 uint32_t uFifoPitchLock = p FIFO[SVGA_FIFO_PITCHLOCK];1799 uint32_t uFifoPitchLock = pThis->fVmSvga3 ? 0 : pFIFO[SVGA_FIFO_PITCHLOCK]; 1774 1800 uint32_t uRegPitchLock = pThis->svga.u32PitchLock; 1775 uint32_t uFifoMin = p FIFO[SVGA_FIFO_MIN];1801 uint32_t uFifoMin = pThis->fVmSvga3 ? 0 : pFIFO[SVGA_FIFO_MIN]; 1776 1802 1777 1803 /* The SVGA_FIFO_PITCHLOCK register is only valid if SVGA_FIFO_MIN points past … … 1853 1879 * @param pThis The shared VGA/VMSVGA state. 1854 1880 * @param pThisCC The VGA/VMSVGA state for the current context. 1881 * @param idxReg Rge register index being written. 1855 1882 * @param u32 Value to write 1856 1883 */ 1857 static VBOXSTRICTRC vmsvgaWritePort(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t u32)1884 static VBOXSTRICTRC vmsvgaWritePort(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t idxReg, uint32_t u32) 1858 1885 { 1859 1886 #ifdef IN_RING3 … … 1862 1889 VBOXSTRICTRC rc = VINF_SUCCESS; 1863 1890 RT_NOREF(pThisCC); 1864 1865 /* Rough index register validation. */1866 uint32_t idxReg = pThis->svga.u32IndexReg;1867 #if !defined(IN_RING3) && defined(VBOX_STRICT)1868 ASSERT_GUEST_MSG_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg),1869 VINF_IOM_R3_IOPORT_WRITE);1870 #else1871 ASSERT_GUEST_MSG_STMT_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg),1872 STAM_REL_COUNTER_INC(&pThis->svga.StatRegUnknownWr),1873 VINF_SUCCESS);1874 #endif1875 RT_UNTRUSTED_VALIDATED_FENCE();1876 1891 1877 1892 /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */ … … 1907 1922 if ( u32 == SVGA_ID_0 1908 1923 || u32 == SVGA_ID_1 1909 || u32 == SVGA_ID_2) 1924 || u32 == SVGA_ID_2 1925 || u32 == SVGA_ID_3) 1910 1926 pThis->svga.u32SVGAId = u32; 1911 1927 else … … 1942 1958 ASMAtomicOrU32(&pThis->svga.u32ActionFlags, VMSVGA_ACTION_CHANGEMODE); 1943 1959 # ifdef LOG_ENABLED 1944 uint32_t *pFIFO = pThisCC->svga.pau32FIFO; 1945 Log(("configured=%d busy=%d\n", pThis->svga.fConfigured, pFIFO[SVGA_FIFO_BUSY])); 1946 Log(("next %x stop %x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP])); 1960 if (!pThis->fVmSvga3) 1961 { 1962 uint32_t *pFIFO = pThisCC->svga.pau32FIFO; 1963 Log(("configured=%d busy=%d\n", pThis->svga.fConfigured, pFIFO[SVGA_FIFO_BUSY])); 1964 Log(("next %x stop %x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP])); 1965 } 1947 1966 # endif 1948 1967 … … 2394 2413 break; 2395 2414 2415 case SVGA_REG_IRQ_STATUS: 2416 { 2417 if (pThis->fVmSvga3) 2418 { 2419 LogFlow(("vmsvga3MmioWrite SVGA_IRQSTATUS_PORT %x: status %x -> %x\n", u32, pThis->svga.u32IrqStatus, pThis->svga.u32IrqStatus & ~u32)); 2420 ASMAtomicAndU32(&pThis->svga.u32IrqStatus, ~u32); 2421 /* Clear the irq in case all events have been cleared. */ 2422 if (!(pThis->svga.u32IrqStatus & pThis->svga.u32IrqMask)) 2423 { 2424 Log(("vmsvga3MmioWrite SVGA_IRQSTATUS_PORT: clearing IRQ\n")); 2425 PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0); 2426 } 2427 } 2428 break; 2429 } 2430 2396 2431 default: 2397 2432 { … … 2452 2487 2453 2488 case SVGA_VALUE_PORT: 2454 return vmsvgaReadPort(pDevIns, pThis, pu32); 2489 { 2490 /* Rough index register validation. */ 2491 uint32_t idxReg = pThis->svga.u32IndexReg; 2492 #if !defined(IN_RING3) && defined(VBOX_STRICT) 2493 ASSERT_GUEST_MSG_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg), 2494 VINF_IOM_R3_IOPORT_READ); 2495 #else 2496 ASSERT_GUEST_MSG_STMT_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg), 2497 STAM_REL_COUNTER_INC(&pThis->svga.StatRegUnknownRd), 2498 VINF_SUCCESS); 2499 #endif 2500 RT_UNTRUSTED_VALIDATED_FENCE(); 2501 2502 return vmsvgaReadPort(pDevIns, pThis, idxReg, pu32); 2503 } 2455 2504 2456 2505 case SVGA_BIOS_PORT: … … 2496 2545 2497 2546 case SVGA_VALUE_PORT: 2498 return vmsvgaWritePort(pDevIns, pThis, pThisCC, u32); 2547 { 2548 /* Rough index register validation. */ 2549 uint32_t idxReg = pThis->svga.u32IndexReg; 2550 #if !defined(IN_RING3) && defined(VBOX_STRICT) 2551 ASSERT_GUEST_MSG_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg), 2552 VINF_IOM_R3_IOPORT_WRITE); 2553 #else 2554 ASSERT_GUEST_MSG_STMT_RETURN(idxReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion, ("idxReg=%#x\n", idxReg), 2555 STAM_REL_COUNTER_INC(&pThis->svga.StatRegUnknownWr), 2556 VINF_SUCCESS); 2557 #endif 2558 RT_UNTRUSTED_VALIDATED_FENCE(); 2559 2560 return vmsvgaWritePort(pDevIns, pThis, pThisCC, idxReg, u32); 2561 } 2499 2562 2500 2563 case SVGA_BIOS_PORT: … … 2521 2584 2522 2585 return VINF_SUCCESS; 2586 } 2587 2588 /** 2589 * @callback_method_impl{FNIOMMMIONEWREAD} 2590 */ 2591 DECLCALLBACK(VBOXSTRICTRC) vmsvga3MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb) 2592 { 2593 PVGASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PVGASTATE); 2594 RT_NOREF_PV(pvUser); 2595 2596 /* Only dword accesses. */ 2597 VBOXSTRICTRC rcStrict; 2598 if (cb == sizeof(uint32_t)) 2599 { 2600 rcStrict = vmsvgaReadPort(pDevIns, pThis, (uint32_t)(off / sizeof(uint32_t)), (uint32_t *)pv); 2601 if (rcStrict == VINF_IOM_R3_IOPORT_READ) 2602 rcStrict = VINF_IOM_R3_MMIO_READ; 2603 } 2604 else 2605 { 2606 Log(("Ignoring non-dword I/O port read at %x cb=%d\n", off, cb)); 2607 rcStrict = VINF_IOM_MMIO_UNUSED_00; 2608 } 2609 return rcStrict; 2610 } 2611 2612 /** 2613 * @callback_method_impl{FNIOMMMIONEWWRITE} 2614 */ 2615 DECLCALLBACK(VBOXSTRICTRC) vmsvga3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb) 2616 { 2617 PVGASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PVGASTATE); 2618 PVGASTATECC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVGASTATECC); 2619 RT_NOREF_PV(pvUser); 2620 2621 /* Only dword accesses. */ 2622 VBOXSTRICTRC rcStrict; 2623 if (cb == sizeof(uint32_t)) 2624 { 2625 rcStrict = vmsvgaWritePort(pDevIns, pThis, pThisCC, (uint32_t)(off / sizeof(uint32_t)), *(uint32_t *)pv); 2626 if (rcStrict == VINF_IOM_R3_IOPORT_WRITE) 2627 rcStrict = VINF_IOM_R3_MMIO_WRITE; 2628 } 2629 else 2630 { 2631 Log(("Ignoring non-dword write at %x cb=%d\n", off, cb)); 2632 rcStrict = VINF_SUCCESS; 2633 } 2634 2635 return rcStrict; 2523 2636 } 2524 2637 … … 3628 3741 */ 3629 3742 /** @todo This code is very similar to the FIFO loop command processing. Think about merging. */ 3743 LogFlow(("cmdId=%u\n", cmdId)); 3630 3744 switch (cmdId) 3631 3745 { … … 3644 3758 Log(("SVGA_CMD_FENCE %#x\n", pCmd->fence)); 3645 3759 3646 uint32_t const offFifoMin = pFIFO[SVGA_FIFO_MIN]; 3647 if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin)) 3760 if (pThis->fVmSvga3) 3648 3761 { 3649 p FIFO[SVGA_FIFO_FENCE]= pCmd->fence;3762 pThis->svga.u32FenceLast = pCmd->fence; 3650 3763 3651 3764 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE) … … 3654 3767 *pu32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE; 3655 3768 } 3656 else if ( VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin) 3657 && (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL) 3658 && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmd->fence) 3769 else if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL) 3659 3770 { 3660 3771 Log(("fence goal reached irq (fence=%#x)\n", pCmd->fence)); … … 3663 3774 } 3664 3775 else 3665 Log(("SVGA_CMD_FENCE is bogus when offFifoMin is %#x!\n", offFifoMin)); 3776 { 3777 uint32_t const offFifoMin = pFIFO[SVGA_FIFO_MIN]; 3778 if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin)) 3779 { 3780 pFIFO[SVGA_FIFO_FENCE] = pCmd->fence; 3781 3782 if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE) 3783 { 3784 Log(("any fence irq\n")); 3785 *pu32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE; 3786 } 3787 else if ( VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin) 3788 && (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL) 3789 && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmd->fence) 3790 { 3791 Log(("fence goal reached irq (fence=%#x)\n", pCmd->fence)); 3792 *pu32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL; 3793 } 3794 } 3795 else 3796 Log(("SVGA_CMD_FENCE is bogus when offFifoMin is %#x!\n", offFifoMin)); 3797 } 3666 3798 break; 3667 3799 } … … 4545 4677 /* Caller already checked pThis->svga.fFIFOThreadSleeping, so we only have 4546 4678 to recheck it before doing the signalling. */ 4547 if ( vmsvgaR3FifoHasWork(pThisCC, ASMAtomicReadU32(&pThis->svga.uLastCursorUpdateCount))4679 if ( (pThis->fVmSvga3 || vmsvgaR3FifoHasWork(pThisCC, ASMAtomicReadU32(&pThis->svga.uLastCursorUpdateCount))) 4548 4680 && pThis->svga.fFIFOThreadSleeping 4549 4681 && !ASMAtomicReadBool(&pThis->svga.fBadGuest)) … … 5248 5380 5249 5381 /** 5382 * @callback_method_impl{PFNPDMTHREADDEV, The async FIFO handling thread.} 5383 */ 5384 static DECLCALLBACK(int) vmsvgaR3CmdBufLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 5385 { 5386 PVGASTATE pThis = PDMDEVINS_2_DATA(pDevIns, PVGASTATE); 5387 PVGASTATER3 pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVGASTATECC); 5388 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State; 5389 int rc; 5390 5391 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 5392 return VINF_SUCCESS; 5393 5394 /* 5395 * Special mode where we only execute an external command and the go back 5396 * to being suspended. Currently, all ext cmds ends up here, with the reset 5397 * one also being eligble for runtime execution further down as well. 5398 */ 5399 if (pThis->svga.fFifoExtCommandWakeup) 5400 { 5401 vmsvgaR3FifoHandleExtCmd(pDevIns, pThis, pThisCC); 5402 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 5403 if (pThis->svga.u8FIFOExtCommand == VMSVGA_FIFO_EXTCMD_NONE) 5404 PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->svga.hFIFORequestSem, RT_MS_1MIN); 5405 else 5406 vmsvgaR3FifoHandleExtCmd(pDevIns, pThis, pThisCC); 5407 return VINF_SUCCESS; 5408 } 5409 5410 5411 /* 5412 * Signal the semaphore to make sure we don't wait for 250ms after a 5413 * suspend & resume scenario (see vmsvgaR3FifoGetCmdPayload). 5414 */ 5415 PDMDevHlpSUPSemEventSignal(pDevIns, pThis->svga.hFIFORequestSem); 5416 5417 /* 5418 * Polling/sleep interval config. 5419 * 5420 * We wait for an a short interval if the guest has recently given us work 5421 * to do, but the interval increases the longer we're kept idle. Once we've 5422 * reached the refresh timer interval, we'll switch to extended waits, 5423 * depending on it or the guest to kick us into action when needed. 5424 * 5425 * Should the refresh time go fishing, we'll just continue increasing the 5426 * sleep length till we reaches the 250 ms max after about 16 seconds. 5427 */ 5428 RTMSINTERVAL const cMsMinSleep = 16; 5429 RTMSINTERVAL const cMsMaxSleep = 250; 5430 RTMSINTERVAL const cMsExtendedSleep = 15 * RT_MS_1SEC; /* Regular paranoia dictates that this cannot be indefinite. */ 5431 RTMSINTERVAL cMsSleep = cMsMaxSleep; 5432 5433 /* 5434 * The FIFO loop. 5435 */ 5436 LogFlow(("vmsvgaR3CmdBufLoop: started loop\n")); 5437 bool fBadOrDisabledFifo = ASMAtomicReadBool(&pThis->svga.fBadGuest); 5438 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 5439 { 5440 /* First check any pending actions. */ 5441 vmsvgaR3FifoPendingActions(pDevIns, pThis, pThisCC); 5442 5443 /* 5444 * Unless there's already work pending, go to sleep for a short while. 5445 * (See polling/sleep interval config above.) 5446 */ 5447 ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, true); 5448 Assert(pThis->cMilliesRefreshInterval > 0); 5449 if (cMsSleep < pThis->cMilliesRefreshInterval) 5450 rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->svga.hFIFORequestSem, cMsSleep); 5451 else 5452 { 5453 STAM_REL_PROFILE_START(&pSVGAState->StatFifoExtendedSleep, Acc); 5454 rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->svga.hFIFORequestSem, cMsExtendedSleep); 5455 STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoExtendedSleep, Acc); 5456 } 5457 ASMAtomicWriteBool(&pThis->svga.fFIFOThreadSleeping, false); 5458 AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED); 5459 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 5460 { 5461 LogFlow(("vmsvgaR3CmdBufLoop: thread state %x\n", pThread->enmState)); 5462 break; 5463 } 5464 5465 fBadOrDisabledFifo = ASMAtomicReadBool(&pThis->svga.fBadGuest); 5466 cMsSleep = cMsMinSleep; 5467 5468 Log(("vmsvgaR3CmdBufLoop: enabled=%d configured=%d busy=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured)); 5469 5470 /* 5471 * Handle external commands (currently only reset). 5472 */ 5473 if (pThis->svga.u8FIFOExtCommand != VMSVGA_FIFO_EXTCMD_NONE) 5474 { 5475 vmsvgaR3FifoHandleExtCmd(pDevIns, pThis, pThisCC); 5476 continue; 5477 } 5478 5479 /* 5480 * If guest misbehaves, then do nothing. 5481 */ 5482 if (ASMAtomicReadBool(&pThis->svga.fBadGuest)) 5483 { 5484 cMsSleep = cMsExtendedSleep; 5485 LogRelMax(1, ("VMSVGA: FIFO processing stopped because of the guest misbehavior\n")); 5486 continue; 5487 } 5488 5489 /* 5490 * The device must be enabled and configured. 5491 */ 5492 if ( !pThis->svga.fEnabled 5493 || !pThis->svga.fConfigured) 5494 { 5495 fBadOrDisabledFifo = true; 5496 cMsSleep = cMsMaxSleep; /* cheat */ 5497 continue; 5498 } 5499 5500 /* 5501 * Process all submitted command buffers. 5502 */ 5503 vmsvgaR3CmdBufProcessBuffers(pDevIns, pThis, pThisCC, pThread); 5504 } 5505 5506 return VINF_SUCCESS; 5507 } 5508 5509 5510 /** 5250 5511 * @callback_method_impl{PFNPDMTHREADWAKEUPDEV, 5251 5512 * Unblock the FIFO I/O thread so it can respond to a state change.} … … 5285 5546 if (pThis->svga.uHeight != VMSVGA_VAL_UNINITIALIZED) 5286 5547 { 5287 # if ndef DEBUG_bird /* BB-10.3.1 triggers this as it initializes everything to zero. Better just ignore it. */5548 # if 0 //ifndef DEBUG_bird /* BB-10.3.1 triggers this as it initializes everything to zero. Better just ignore it. */ 5288 5549 Assert(pThis->svga.cbScanline); 5289 5550 # endif … … 6469 6730 6470 6731 /* FIFO capabilities. */ 6471 *pu32FIFOCaps = SVGA_FIFO_CAP_FENCE 6472 | SVGA_FIFO_CAP_PITCHLOCK 6473 | SVGA_FIFO_CAP_CURSOR_BYPASS_3 6474 | SVGA_FIFO_CAP_RESERVE 6475 | SVGA_FIFO_CAP_GMR2 6476 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED 6477 | SVGA_FIFO_CAP_SCREEN_OBJECT_2; 6732 if (!pThis->fVmSvga3) 6733 *pu32FIFOCaps = SVGA_FIFO_CAP_FENCE 6734 | SVGA_FIFO_CAP_PITCHLOCK 6735 | SVGA_FIFO_CAP_CURSOR_BYPASS_3 6736 | SVGA_FIFO_CAP_RESERVE 6737 | SVGA_FIFO_CAP_GMR2 6738 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED 6739 | SVGA_FIFO_CAP_SCREEN_OBJECT_2; 6478 6740 } 6479 6741 … … 6587 6849 Log(("vmsvgaR3Reset\n")); 6588 6850 6589 /* Reset the FIFO processing as well as the 3d state (if we have one). */ 6590 pThisCC->svga.pau32FIFO[SVGA_FIFO_NEXT_CMD] = pThisCC->svga.pau32FIFO[SVGA_FIFO_STOP] = 0; /** @todo should probably let the FIFO thread do this ... */ 6851 if (!pThis->fVmSvga3) 6852 { 6853 /* Reset the FIFO processing as well as the 3d state (if we have one). */ 6854 pThisCC->svga.pau32FIFO[SVGA_FIFO_NEXT_CMD] = pThisCC->svga.pau32FIFO[SVGA_FIFO_STOP] = 0; /** @todo should probably let the FIFO thread do this ... */ 6855 } 6591 6856 6592 6857 PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect); /* Hack around lock order issue. FIFO thread might take the lock. */ … … 6609 6874 RT_BZERO(pThisCC->svga.pbVgaFrameBufferR3, VMSVGA_VGA_FB_BACKUP_SIZE); 6610 6875 6611 vmsvgaR3InitFIFO(pThis, pThisCC); 6876 if (!pThis->fVmSvga3) 6877 vmsvgaR3InitFIFO(pThis, pThisCC); 6612 6878 6613 6879 /* Initialize FIFO and register capabilities. */ … … 6615 6881 6616 6882 # ifdef VBOX_WITH_VMSVGA3D 6617 if (pThis->svga.f3DEnabled) 6883 if ( pThis->svga.f3DEnabled 6884 && !pThis->fVmSvga3) 6618 6885 vmsvgaR3InitFifo3DCaps(pThis, pThisCC); 6619 6886 # endif … … 6795 7062 6796 7063 /* Create the async IO thread. */ 6797 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->svga.pFIFOIOThread, pThis, vmsvgaR3FifoLoop, vmsvgaR3FifoLoopWakeUp, 0, 6798 RTTHREADTYPE_IO, "VMSVGA FIFO"); 7064 if (pThis->fVmSvga3) 7065 { 7066 /* 7067 * For SVGA 3 we use a different command processing loop because the standard FIFO loop would get riddled with 7068 * if (pThis->fVmsvga3) otherwise 7069 */ 7070 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->svga.pFIFOIOThread, pThis, vmsvgaR3CmdBufLoop, vmsvgaR3FifoLoopWakeUp, 0, 7071 RTTHREADTYPE_IO, "VMSVGA CMD"); 7072 } 7073 else 7074 rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->svga.pFIFOIOThread, pThis, vmsvgaR3FifoLoop, vmsvgaR3FifoLoopWakeUp, 0, 7075 RTTHREADTYPE_IO, "VMSVGA FIFO"); 6799 7076 if (RT_FAILURE(rc)) 6800 7077 { … … 7053 7330 if (!fLoadState) 7054 7331 { 7055 vmsvgaR3InitFIFO(pThis, pThisCC); 7332 if (!pThis->fVmSvga3) 7333 vmsvgaR3InitFIFO(pThis, pThisCC); 7056 7334 vmsvgaR3GetCaps(pThis, pThisCC, &pThis->svga.u32DeviceCaps, &pThis->svga.u32DeviceCaps2, &pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES]); 7057 7335 } … … 7070 7348 Assert( (pThis->svga.u32DeviceCaps & u32DeviceCaps) == pThis->svga.u32DeviceCaps 7071 7349 && (pThis->svga.u32DeviceCaps2 & u32DeviceCaps2) == pThis->svga.u32DeviceCaps2 7072 && (pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES] & u32FIFOCaps) == pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES]); 7350 && ( !pThis->fVmSvga3 7351 || (pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES] & u32FIFOCaps) == pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES])); 7073 7352 } 7074 7353 #endif 7075 7354 7076 7355 # ifdef VBOX_WITH_VMSVGA3D 7077 if (pThis->svga.f3DEnabled) 7356 if ( pThis->svga.f3DEnabled 7357 && !pThis->fVmSvga3) 7078 7358 { 7079 7359 PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State; -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h
r99535 r100690 58 58 #ifndef PCI_DEVICE_ID_VMWARE_SVGA2 59 59 # define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 60 #endif 61 #ifndef PCI_DEVICE_ID_VMWARE_SVGA3 62 # define PCI_DEVICE_ID_VMWARE_SVGA3 0x0406 60 63 #endif 61 64 … … 337 340 uint32_t u32GuestDriverVer2; 338 341 uint32_t u32GuestDriverVer3; 342 /** The last fence received. */ 343 uint32_t u32FenceLast; 339 344 /** Port io index register. */ 340 345 uint32_t u32IndexReg; … … 565 570 DECLCALLBACK(VBOXSTRICTRC) vmsvgaIORead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb); 566 571 DECLCALLBACK(VBOXSTRICTRC) vmsvgaIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb); 572 DECLCALLBACK(VBOXSTRICTRC) vmsvga3MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb); 573 DECLCALLBACK(VBOXSTRICTRC) vmsvga3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb); 567 574 568 575 DECLCALLBACK(void) vmsvgaR3PortSetViewport(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId, -
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r100108 r100690 6472 6472 "|VMSVGAPciBarLayout" 6473 6473 "|VMSVGAFifoSize" 6474 "|VmSvga3" 6475 "|VmSvgaExposeLegacyVga" 6474 6476 # endif 6475 6477 # ifdef VBOX_WITH_VMSVGA3D … … 6523 6525 Log(("VMSVGA: VMSVGAPciBarLayout = %d\n", pThis->fVMSVGAPciBarLayout)); 6524 6526 6527 rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "VmSvga3", &pThis->fVmSvga3, false); 6528 AssertLogRelRCReturn(rc, rc); 6529 Log(("VMSVGA: VmSvga3 = %RTbool\n", pThis->fVmSvga3)); 6530 6531 rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "VmSvgaExposeLegacyVga", &pThis->fLegacyVgaEnabled, true); 6532 AssertLogRelRCReturn(rc, rc); 6533 Log(("VMSVGA: VmSvgaExposeLegacyVga = %RTbool\n", pThis->fLegacyVgaEnabled)); 6534 6525 6535 rc = pHlp->pfnCFGMQueryU32Def(pCfg, "VMSVGAFifoSize", &pThis->svga.cbFIFO, VMSVGA_FIFO_SIZE); 6526 6536 AssertLogRelRCReturn(rc, rc); … … 6544 6554 if (pThis->fVMSVGAPciBarLayout) 6545 6555 { 6546 pThis->pciRegions.iIO = 0; 6547 pThis->pciRegions.iVRAM = 1; 6556 if (pThis->fVmSvga3) 6557 { 6558 pThis->pciRegions.iIO = 0; 6559 pThis->pciRegions.iVRAM = 2; 6560 } 6561 else 6562 { 6563 pThis->pciRegions.iIO = 0; 6564 pThis->pciRegions.iVRAM = 1; 6565 } 6548 6566 } 6549 6567 else … … 6572 6590 { 6573 6591 PDMPciDevSetVendorId(pPciDev, PCI_VENDOR_ID_VMWARE); 6574 PDMPciDevSetDeviceId(pPciDev, PCI_DEVICE_ID_VMWARE_SVGA2); 6592 if (pThis->fVmSvga3) 6593 PDMPciDevSetDeviceId(pPciDev, PCI_DEVICE_ID_VMWARE_SVGA3); 6594 else 6595 PDMPciDevSetDeviceId(pPciDev, PCI_DEVICE_ID_VMWARE_SVGA2); 6575 6596 } 6576 6597 else … … 6580 6601 } 6581 6602 PDMPciDevSetSubSystemVendorId(pPciDev, PCI_VENDOR_ID_VMWARE); 6582 PDMPciDevSetSubSystemId(pPciDev, PCI_DEVICE_ID_VMWARE_SVGA2); 6603 if (pThis->fVmSvga3) 6604 PDMPciDevSetSubSystemId(pPciDev, PCI_DEVICE_ID_VMWARE_SVGA3); 6605 else 6606 PDMPciDevSetSubSystemId(pPciDev, PCI_DEVICE_ID_VMWARE_SVGA2); 6583 6607 } 6584 6608 else … … 6659 6683 pThis->hIoPortVmSvga = NIL_IOMIOPORTHANDLE; 6660 6684 pThis->hMmio2VmSvgaFifo = NIL_PGMMMIO2HANDLE; 6685 pThis->hMmioSvga3 = NIL_IOMMMIOHANDLE; 6661 6686 if (pThis->fVMSVGAEnabled) 6662 6687 { 6663 /* Register the io command ports. */ 6664 rc = PDMDevHlpPCIIORegionCreateIo(pDevIns, pThis->pciRegions.iIO, 0x10, vmsvgaIOWrite, vmsvgaIORead, NULL /*pvUser*/, 6665 "VMSVGA", NULL /*paExtDescs*/, &pThis->hIoPortVmSvga); 6666 AssertRCReturn(rc, rc); 6667 6668 rc = PDMDevHlpPCIIORegionCreateMmio2Ex(pDevIns, pThis->pciRegions.iFIFO, pThis->svga.cbFIFO, 6669 PCI_ADDRESS_SPACE_MEM, 0 /*fFlags*/, vmsvgaR3PciIORegionFifoMapUnmap, 6670 "VMSVGA-FIFO", (void **)&pThisCC->svga.pau32FIFO, &pThis->hMmio2VmSvgaFifo); 6671 AssertRCReturn(rc, PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 6672 N_("Failed to create VMSVGA FIFO (%u bytes)"), pThis->svga.cbFIFO)); 6688 if (pThis->fVmSvga3) 6689 { 6690 /* Register the MMIO register region. */ 6691 rc = PDMDevHlpPCIIORegionCreateMmio(pDevIns, pThis->pciRegions.iIO, 4096, PCI_ADDRESS_SPACE_MEM, 6692 vmsvga3MmioWrite, vmsvga3MmioRead, NULL /*pvUser*/, 6693 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_ZEROED, 6694 "VMSVGA3-MMIO", &pThis->hMmioSvga3); 6695 AssertRCReturn(rc, rc); 6696 } 6697 else 6698 { 6699 /* Register the io command ports. */ 6700 rc = PDMDevHlpPCIIORegionCreateIo(pDevIns, pThis->pciRegions.iIO, 0x10, vmsvgaIOWrite, vmsvgaIORead, NULL /*pvUser*/, 6701 "VMSVGA", NULL /*paExtDescs*/, &pThis->hIoPortVmSvga); 6702 AssertRCReturn(rc, rc); 6703 6704 rc = PDMDevHlpPCIIORegionCreateMmio2Ex(pDevIns, pThis->pciRegions.iFIFO, pThis->svga.cbFIFO, 6705 PCI_ADDRESS_SPACE_MEM, 0 /*fFlags*/, vmsvgaR3PciIORegionFifoMapUnmap, 6706 "VMSVGA-FIFO", (void **)&pThisCC->svga.pau32FIFO, &pThis->hMmio2VmSvgaFifo); 6707 AssertRCReturn(rc, PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 6708 N_("Failed to create VMSVGA FIFO (%u bytes)"), pThis->svga.cbFIFO)); 6709 } 6673 6710 6674 6711 pPciDev->pfnRegionLoadChangeHookR3 = vgaR3PciRegionLoadChangeHook; … … 6685 6722 N_("Failed to allocate %u bytes of VRAM"), pThis->vram_size)); 6686 6723 6687 /* 6688 * Register I/O ports. 6689 */ 6724 if (pThis->fLegacyVgaEnabled) 6725 { 6726 /* 6727 * Register I/O ports. 6728 */ 6690 6729 # define REG_PORT(a_uPort, a_cPorts, a_pfnWrite, a_pfnRead, a_szDesc, a_phIoPort) do { \ 6691 6730 rc = PDMDevHlpIoPortCreateFlagsAndMap(pDevIns, a_uPort, a_cPorts, IOM_IOPORT_F_ABS, \ … … 6693 6732 AssertRCReturn(rc, rc); \ 6694 6733 } while (0) 6695 REG_PORT(0x3c0, 2, vgaIoPortArWrite, vgaIoPortArRead, "Attribute Controller", &pThis->hIoPortAr);6696 REG_PORT(0x3c2, 1, vgaIoPortMsrWrite, vgaIoPortSt00Read, "MSR / ST00", &pThis->hIoPortMsrSt00);6697 REG_PORT(0x3c3, 1, vgaIoPortUnusedWrite, vgaIoPortUnusedRead, "0x3c3", &pThis->hIoPort3c3);6698 REG_PORT(0x3c4, 2, vgaIoPortSrWrite, vgaIoPortSrRead, "Sequencer", &pThis->hIoPortSr);6699 REG_PORT(0x3c6, 4, vgaIoPortDacWrite, vgaIoPortDacRead, "DAC", &pThis->hIoPortDac);6700 REG_PORT(0x3ca, 4, vgaIoPortPosWrite, vgaIoPortPosRead, "Graphics Position", /*?*/ &pThis->hIoPortPos);6701 REG_PORT(0x3ce, 2, vgaIoPortGrWrite, vgaIoPortGrRead, "Graphics Controller", &pThis->hIoPortGr);6702 6703 /* Note! Ralf Brown lists 0x3b0-0x3b1, 0x3b2-0x3b3 and 0x3b6-0x3b7 as "the same as" 0x3b4-0x3b5. */6704 REG_PORT(0x3b4, 2, vgaIoPortMdaCrtWrite, vgaIoPortMdaCrtRead, "MDA CRT control", &pThis->hIoPortMdaCrt);6705 REG_PORT(0x3ba, 1, vgaIoPortMdaFcrWrite, vgaIoPortMdaStRead, "MDA feature/status", &pThis->hIoPortMdaFcrSt);6706 REG_PORT(0x3d4, 2, vgaIoPortCgaCrtWrite, vgaIoPortCgaCrtRead, "CGA CRT control", &pThis->hIoPortCgaCrt);6707 REG_PORT(0x3da, 1, vgaIoPortCgaFcrWrite, vgaIoPortCgaStRead, "CGA Feature / status", &pThis->hIoPortCgaFcrSt);6734 REG_PORT(0x3c0, 2, vgaIoPortArWrite, vgaIoPortArRead, "Attribute Controller", &pThis->hIoPortAr); 6735 REG_PORT(0x3c2, 1, vgaIoPortMsrWrite, vgaIoPortSt00Read, "MSR / ST00", &pThis->hIoPortMsrSt00); 6736 REG_PORT(0x3c3, 1, vgaIoPortUnusedWrite, vgaIoPortUnusedRead, "0x3c3", &pThis->hIoPort3c3); 6737 REG_PORT(0x3c4, 2, vgaIoPortSrWrite, vgaIoPortSrRead, "Sequencer", &pThis->hIoPortSr); 6738 REG_PORT(0x3c6, 4, vgaIoPortDacWrite, vgaIoPortDacRead, "DAC", &pThis->hIoPortDac); 6739 REG_PORT(0x3ca, 4, vgaIoPortPosWrite, vgaIoPortPosRead, "Graphics Position", /*?*/ &pThis->hIoPortPos); 6740 REG_PORT(0x3ce, 2, vgaIoPortGrWrite, vgaIoPortGrRead, "Graphics Controller", &pThis->hIoPortGr); 6741 6742 /* Note! Ralf Brown lists 0x3b0-0x3b1, 0x3b2-0x3b3 and 0x3b6-0x3b7 as "the same as" 0x3b4-0x3b5. */ 6743 REG_PORT(0x3b4, 2, vgaIoPortMdaCrtWrite, vgaIoPortMdaCrtRead, "MDA CRT control", &pThis->hIoPortMdaCrt); 6744 REG_PORT(0x3ba, 1, vgaIoPortMdaFcrWrite, vgaIoPortMdaStRead, "MDA feature/status", &pThis->hIoPortMdaFcrSt); 6745 REG_PORT(0x3d4, 2, vgaIoPortCgaCrtWrite, vgaIoPortCgaCrtRead, "CGA CRT control", &pThis->hIoPortCgaCrt); 6746 REG_PORT(0x3da, 1, vgaIoPortCgaFcrWrite, vgaIoPortCgaStRead, "CGA Feature / status", &pThis->hIoPortCgaFcrSt); 6708 6747 6709 6748 # ifdef CONFIG_BOCHS_VBE 6710 REG_PORT(0x1ce, 1, vgaIoPortWriteVbeIndex, vgaIoPortReadVbeIndex, "VBE Index", &pThis->hIoPortVbeIndex);6711 REG_PORT(0x1cf, 1, vgaIoPortWriteVbeData, vgaIoPortReadVbeData, "VBE Data", &pThis->hIoPortVbeData);6749 REG_PORT(0x1ce, 1, vgaIoPortWriteVbeIndex, vgaIoPortReadVbeIndex, "VBE Index", &pThis->hIoPortVbeIndex); 6750 REG_PORT(0x1cf, 1, vgaIoPortWriteVbeData, vgaIoPortReadVbeData, "VBE Data", &pThis->hIoPortVbeData); 6712 6751 # endif /* CONFIG_BOCHS_VBE */ 6713 6752 6714 6753 # ifdef VBOX_WITH_HGSMI 6715 /* Use reserved VGA IO ports for HGSMI. */6716 REG_PORT(VGA_PORT_HGSMI_HOST, 4, vgaR3IOPortHgsmiWrite, vgaR3IOPortHgmsiRead, "HGSMI host (3b0-3b3)", &pThis->hIoPortHgsmiHost);6717 REG_PORT(VGA_PORT_HGSMI_GUEST, 4, vgaR3IOPortHgsmiWrite, vgaR3IOPortHgmsiRead, "HGSMI guest (3d0-3d3)", &pThis->hIoPortHgsmiGuest);6754 /* Use reserved VGA IO ports for HGSMI. */ 6755 REG_PORT(VGA_PORT_HGSMI_HOST, 4, vgaR3IOPortHgsmiWrite, vgaR3IOPortHgmsiRead, "HGSMI host (3b0-3b3)", &pThis->hIoPortHgsmiHost); 6756 REG_PORT(VGA_PORT_HGSMI_GUEST, 4, vgaR3IOPortHgsmiWrite, vgaR3IOPortHgmsiRead, "HGSMI guest (3d0-3d3)", &pThis->hIoPortHgsmiGuest); 6718 6757 # endif /* VBOX_WITH_HGSMI */ 6719 6758 6720 6759 # undef REG_PORT 6721 6760 6722 /* vga bios */ 6723 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, VBE_PRINTF_PORT, 1 /*cPorts*/, vgaIoPortWriteBios, vgaIoPortReadBios, 6724 "VGA BIOS debug/panic", NULL /*paExtDescs*/, &pThis->hIoPortBios); 6725 AssertRCReturn(rc, rc); 6726 6727 /* 6728 * The MDA/CGA/EGA/VGA/whatever fixed MMIO area. 6729 */ 6730 rc = PDMDevHlpMmioCreateExAndMap(pDevIns, 0x000a0000, 0x00020000, 6731 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU | IOMMMIO_FLAGS_ABS, 6732 NULL /*pPciDev*/, UINT32_MAX /*iPciRegion*/, 6733 vgaMmioWrite, vgaMmioRead, vgaMmioFill, NULL /*pvUser*/, 6734 "VGA - VGA Video Buffer", &pThis->hMmioLegacy); 6735 AssertRCReturn(rc, rc); 6736 6737 /* 6738 * Get the VGA BIOS ROM file name. 6739 */ 6740 rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, "BiosRom", &pThisCC->pszVgaBiosFile); 6741 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 6742 { 6743 pThisCC->pszVgaBiosFile = NULL; 6744 rc = VINF_SUCCESS; 6745 } 6746 else if (RT_FAILURE(rc)) 6747 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Querying \"BiosRom\" as a string failed")); 6748 else if (!*pThisCC->pszVgaBiosFile) 6749 { 6750 PDMDevHlpMMHeapFree(pDevIns, pThisCC->pszVgaBiosFile); 6751 pThisCC->pszVgaBiosFile = NULL; 6752 } 6753 6754 /* 6755 * Determine the VGA BIOS ROM size, open specified ROM file in the process. 6756 */ 6757 RTFILE FileVgaBios = NIL_RTFILE; 6758 if (pThisCC->pszVgaBiosFile) 6759 { 6760 rc = RTFileOpen(&FileVgaBios, pThisCC->pszVgaBiosFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 6761 if (RT_SUCCESS(rc)) 6761 /* vga bios */ 6762 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, VBE_PRINTF_PORT, 1 /*cPorts*/, vgaIoPortWriteBios, vgaIoPortReadBios, 6763 "VGA BIOS debug/panic", NULL /*paExtDescs*/, &pThis->hIoPortBios); 6764 AssertRCReturn(rc, rc); 6765 6766 /* 6767 * The MDA/CGA/EGA/VGA/whatever fixed MMIO area. 6768 */ 6769 rc = PDMDevHlpMmioCreateExAndMap(pDevIns, 0x000a0000, 0x00020000, 6770 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU | IOMMMIO_FLAGS_ABS, 6771 NULL /*pPciDev*/, UINT32_MAX /*iPciRegion*/, 6772 vgaMmioWrite, vgaMmioRead, vgaMmioFill, NULL /*pvUser*/, 6773 "VGA - VGA Video Buffer", &pThis->hMmioLegacy); 6774 AssertRCReturn(rc, rc); 6775 6776 /* 6777 * Get the VGA BIOS ROM file name. 6778 */ 6779 rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, "BiosRom", &pThisCC->pszVgaBiosFile); 6780 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 6762 6781 { 6763 rc = RTFileQuerySize(FileVgaBios, &pThisCC->cbVgaBios); 6782 pThisCC->pszVgaBiosFile = NULL; 6783 rc = VINF_SUCCESS; 6784 } 6785 else if (RT_FAILURE(rc)) 6786 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Querying \"BiosRom\" as a string failed")); 6787 else if (!*pThisCC->pszVgaBiosFile) 6788 { 6789 PDMDevHlpMMHeapFree(pDevIns, pThisCC->pszVgaBiosFile); 6790 pThisCC->pszVgaBiosFile = NULL; 6791 } 6792 6793 /* 6794 * Determine the VGA BIOS ROM size, open specified ROM file in the process. 6795 */ 6796 RTFILE FileVgaBios = NIL_RTFILE; 6797 if (pThisCC->pszVgaBiosFile) 6798 { 6799 rc = RTFileOpen(&FileVgaBios, pThisCC->pszVgaBiosFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 6764 6800 if (RT_SUCCESS(rc)) 6765 6801 { 6766 if ( RT_ALIGN(pThisCC->cbVgaBios, _4K) != pThisCC->cbVgaBios 6767 || pThisCC->cbVgaBios > _64K 6768 || pThisCC->cbVgaBios < 16 * _1K) 6769 rc = VERR_TOO_MUCH_DATA; 6802 rc = RTFileQuerySize(FileVgaBios, &pThisCC->cbVgaBios); 6803 if (RT_SUCCESS(rc)) 6804 { 6805 if ( RT_ALIGN(pThisCC->cbVgaBios, _4K) != pThisCC->cbVgaBios 6806 || pThisCC->cbVgaBios > _64K 6807 || pThisCC->cbVgaBios < 16 * _1K) 6808 rc = VERR_TOO_MUCH_DATA; 6809 } 6770 6810 } 6771 } 6772 if (RT_FAILURE(rc)) 6811 if (RT_FAILURE(rc)) 6812 { 6813 /* 6814 * In case of failure simply fall back to the built-in VGA BIOS ROM. 6815 */ 6816 Log(("vgaConstruct: Failed to open VGA BIOS ROM file '%s', rc=%Rrc!\n", pThisCC->pszVgaBiosFile, rc)); 6817 RTFileClose(FileVgaBios); 6818 FileVgaBios = NIL_RTFILE; 6819 PDMDevHlpMMHeapFree(pDevIns, pThisCC->pszVgaBiosFile); 6820 pThisCC->pszVgaBiosFile = NULL; 6821 } 6822 } 6823 6824 /* 6825 * Attempt to get the VGA BIOS ROM data from file. 6826 */ 6827 if (pThisCC->pszVgaBiosFile) 6773 6828 { 6774 6829 /* 6775 * In case of failure simply fall back to the built-in VGA BIOS ROM.6830 * Allocate buffer for the VGA BIOS ROM data. 6776 6831 */ 6777 Log(("vgaConstruct: Failed to open VGA BIOS ROM file '%s', rc=%Rrc!\n", pThisCC->pszVgaBiosFile, rc)); 6832 pThisCC->pbVgaBios = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, pThisCC->cbVgaBios); 6833 if (pThisCC->pbVgaBios) 6834 { 6835 rc = RTFileRead(FileVgaBios, pThisCC->pbVgaBios, pThisCC->cbVgaBios, NULL); 6836 if (RT_FAILURE(rc)) 6837 { 6838 AssertMsgFailed(("RTFileRead(,,%d,NULL) -> %Rrc\n", pThisCC->cbVgaBios, rc)); 6839 PDMDevHlpMMHeapFree(pDevIns, pThisCC->pbVgaBios); 6840 pThisCC->pbVgaBios = NULL; 6841 } 6842 rc = VINF_SUCCESS; 6843 } 6844 else 6845 rc = VERR_NO_MEMORY; 6846 } 6847 else 6848 pThisCC->pbVgaBios = NULL; 6849 6850 /* cleanup */ 6851 if (FileVgaBios != NIL_RTFILE) 6778 6852 RTFileClose(FileVgaBios); 6779 FileVgaBios = NIL_RTFILE; 6780 PDMDevHlpMMHeapFree(pDevIns, pThisCC->pszVgaBiosFile); 6781 pThisCC->pszVgaBiosFile = NULL; 6782 } 6783 } 6784 6785 /* 6786 * Attempt to get the VGA BIOS ROM data from file. 6787 */ 6788 if (pThisCC->pszVgaBiosFile) 6789 { 6790 /* 6791 * Allocate buffer for the VGA BIOS ROM data. 6792 */ 6793 pThisCC->pbVgaBios = (uint8_t *)PDMDevHlpMMHeapAlloc(pDevIns, pThisCC->cbVgaBios); 6794 if (pThisCC->pbVgaBios) 6853 6854 /* If we were unable to get the data from file for whatever reason, fall 6855 back to the built-in ROM image. */ 6856 const uint8_t *pbVgaBiosBinary; 6857 uint64_t cbVgaBiosBinary; 6858 uint32_t fFlags = 0; 6859 if (pThisCC->pbVgaBios == NULL) 6795 6860 { 6796 rc = RTFileRead(FileVgaBios, pThisCC->pbVgaBios, pThisCC->cbVgaBios, NULL); 6797 if (RT_FAILURE(rc)) 6861 CPUMMICROARCH enmMicroarch = PDMDevHlpCpuGetGuestMicroarch(pDevIns); 6862 if ( enmMicroarch == kCpumMicroarch_Intel_8086 6863 || enmMicroarch == kCpumMicroarch_Intel_80186 6864 || enmMicroarch == kCpumMicroarch_NEC_V20 6865 || enmMicroarch == kCpumMicroarch_NEC_V30) 6798 6866 { 6799 AssertMsgFailed(("RTFileRead(,,%d,NULL) -> %Rrc\n", pThisCC->cbVgaBios, rc));6800 PDMDevHlpMMHeapFree(pDevIns, pThisCC->pbVgaBios);6801 pThisCC->pbVgaBios = NULL;6867 pbVgaBiosBinary = g_abVgaBiosBinary8086; 6868 cbVgaBiosBinary = g_cbVgaBiosBinary8086; 6869 LogRel(("VGA: Using the 8086 BIOS image!\n")); 6802 6870 } 6803 rc = VINF_SUCCESS; 6804 } 6805 else 6806 rc = VERR_NO_MEMORY; 6807 } 6808 else 6809 pThisCC->pbVgaBios = NULL; 6810 6811 /* cleanup */ 6812 if (FileVgaBios != NIL_RTFILE) 6813 RTFileClose(FileVgaBios); 6814 6815 /* If we were unable to get the data from file for whatever reason, fall 6816 back to the built-in ROM image. */ 6817 const uint8_t *pbVgaBiosBinary; 6818 uint64_t cbVgaBiosBinary; 6819 uint32_t fFlags = 0; 6820 if (pThisCC->pbVgaBios == NULL) 6821 { 6822 CPUMMICROARCH enmMicroarch = PDMDevHlpCpuGetGuestMicroarch(pDevIns); 6823 if ( enmMicroarch == kCpumMicroarch_Intel_8086 6824 || enmMicroarch == kCpumMicroarch_Intel_80186 6825 || enmMicroarch == kCpumMicroarch_NEC_V20 6826 || enmMicroarch == kCpumMicroarch_NEC_V30) 6827 { 6828 pbVgaBiosBinary = g_abVgaBiosBinary8086; 6829 cbVgaBiosBinary = g_cbVgaBiosBinary8086; 6830 LogRel(("VGA: Using the 8086 BIOS image!\n")); 6831 } 6832 else if (enmMicroarch == kCpumMicroarch_Intel_80286) 6833 { 6834 pbVgaBiosBinary = g_abVgaBiosBinary286; 6835 cbVgaBiosBinary = g_cbVgaBiosBinary286; 6836 LogRel(("VGA: Using the 286 BIOS image!\n")); 6871 else if (enmMicroarch == kCpumMicroarch_Intel_80286) 6872 { 6873 pbVgaBiosBinary = g_abVgaBiosBinary286; 6874 cbVgaBiosBinary = g_cbVgaBiosBinary286; 6875 LogRel(("VGA: Using the 286 BIOS image!\n")); 6876 } 6877 else 6878 { 6879 pbVgaBiosBinary = g_abVgaBiosBinary386; 6880 cbVgaBiosBinary = g_cbVgaBiosBinary386; 6881 LogRel(("VGA: Using the 386+ BIOS image.\n")); 6882 } 6883 fFlags = PGMPHYS_ROM_FLAGS_PERMANENT_BINARY; 6837 6884 } 6838 6885 else 6839 6886 { 6840 pbVgaBiosBinary = g_abVgaBiosBinary386; 6841 cbVgaBiosBinary = g_cbVgaBiosBinary386; 6842 LogRel(("VGA: Using the 386+ BIOS image.\n")); 6843 } 6844 fFlags = PGMPHYS_ROM_FLAGS_PERMANENT_BINARY; 6845 } 6846 else 6847 { 6848 pbVgaBiosBinary = pThisCC->pbVgaBios; 6849 cbVgaBiosBinary = pThisCC->cbVgaBios; 6850 } 6851 6852 AssertReleaseMsg(cbVgaBiosBinary <= _64K && cbVgaBiosBinary >= 32*_1K, ("cbVgaBiosBinary=%#x\n", cbVgaBiosBinary)); 6853 AssertReleaseMsg(RT_ALIGN_Z(cbVgaBiosBinary, GUEST_PAGE_SIZE) == cbVgaBiosBinary, ("cbVgaBiosBinary=%#x\n", cbVgaBiosBinary)); 6854 /* Note! Because of old saved states we'll always register at least 36KB of ROM. */ 6855 rc = PDMDevHlpROMRegister(pDevIns, 0x000c0000, RT_MAX(cbVgaBiosBinary, 36*_1K), pbVgaBiosBinary, cbVgaBiosBinary, 6856 fFlags, "VGA BIOS"); 6857 AssertRCReturn(rc, rc); 6887 pbVgaBiosBinary = pThisCC->pbVgaBios; 6888 cbVgaBiosBinary = pThisCC->cbVgaBios; 6889 } 6890 6891 AssertReleaseMsg(cbVgaBiosBinary <= _64K && cbVgaBiosBinary >= 32*_1K, ("cbVgaBiosBinary=%#x\n", cbVgaBiosBinary)); 6892 AssertReleaseMsg(RT_ALIGN_Z(cbVgaBiosBinary, GUEST_PAGE_SIZE) == cbVgaBiosBinary, ("cbVgaBiosBinary=%#x\n", cbVgaBiosBinary)); 6893 /* Note! Because of old saved states we'll always register at least 36KB of ROM. */ 6894 rc = PDMDevHlpROMRegister(pDevIns, 0x000c0000, RT_MAX(cbVgaBiosBinary, 36*_1K), pbVgaBiosBinary, cbVgaBiosBinary, 6895 fFlags, "VGA BIOS"); 6896 AssertRCReturn(rc, rc); 6897 } 6858 6898 6859 6899 /* … … 6892 6932 AssertLogRelRCReturn(rc, rc); 6893 6933 6894 /* 6895 * Compute buffer size for the VBE BIOS Extra Data. 6896 */ 6897 cb = sizeof(mode_info_list) + sizeof(ModeInfoListItem); 6898 6899 rc = pHlp->pfnCFGMQueryU32(pCfg, "HeightReduction", &cyReduction); 6900 if (RT_SUCCESS(rc) && cyReduction) 6901 cb *= 2; /* Default mode list will be twice long */ 6902 else 6903 cyReduction = 0; 6904 6905 rc = pHlp->pfnCFGMQueryU32(pCfg, "CustomVideoModes", &cCustomModes); 6906 if (RT_SUCCESS(rc) && cCustomModes) 6907 cb += sizeof(ModeInfoListItem) * cCustomModes; 6908 else 6909 cCustomModes = 0; 6910 6911 /* 6912 * Allocate and initialize buffer for the VBE BIOS Extra Data. 6913 */ 6914 AssertRelease(sizeof(VBEHEADER) + cb < 65536); 6915 pThisCC->cbVBEExtraData = (uint16_t)(sizeof(VBEHEADER) + cb); 6916 pThisCC->pbVBEExtraData = (uint8_t *)PDMDevHlpMMHeapAllocZ(pDevIns, pThisCC->cbVBEExtraData); 6917 if (!pThisCC->pbVBEExtraData) 6918 return VERR_NO_MEMORY; 6919 6920 pVBEDataHdr = (PVBEHEADER)pThisCC->pbVBEExtraData; 6921 pVBEDataHdr->u16Signature = VBEHEADER_MAGIC; 6922 pVBEDataHdr->cbData = cb; 6923 6924 pCurMode = (ModeInfoListItem *)(pVBEDataHdr + 1); 6925 for (i = 0; i < MODE_INFO_SIZE; i++) 6926 { 6927 uint32_t pixelWidth, reqSize; 6928 if (mode_info_list[i].info.MemoryModel == VBE_MEMORYMODEL_TEXT_MODE) 6929 pixelWidth = 2; 6934 if (pThis->fLegacyVgaEnabled) 6935 { 6936 /* 6937 * Compute buffer size for the VBE BIOS Extra Data. 6938 */ 6939 cb = sizeof(mode_info_list) + sizeof(ModeInfoListItem); 6940 6941 rc = pHlp->pfnCFGMQueryU32(pCfg, "HeightReduction", &cyReduction); 6942 if (RT_SUCCESS(rc) && cyReduction) 6943 cb *= 2; /* Default mode list will be twice long */ 6930 6944 else 6931 pixelWidth = (mode_info_list[i].info.BitsPerPixel +7) / 8; 6932 reqSize = mode_info_list[i].info.XResolution 6933 * mode_info_list[i].info.YResolution 6934 * pixelWidth; 6935 if (reqSize >= pThis->vram_size) 6936 continue; 6937 if (!reqSize) 6938 continue; 6939 if ( mode_info_list[i].info.XResolution > maxBiosXRes 6940 || mode_info_list[i].info.YResolution > maxBiosYRes) 6941 continue; 6942 *pCurMode = mode_info_list[i]; 6943 vgaR3AdjustModeInfo(pThis, pCurMode); 6944 pCurMode++; 6945 } 6946 6947 /* 6948 * Copy default modes with subtracted YResolution. 6949 */ 6950 if (cyReduction) 6951 { 6952 ModeInfoListItem *pDefMode = mode_info_list; 6953 Log(("vgaR3Construct: cyReduction=%u\n", cyReduction)); 6954 for (i = 0; i < MODE_INFO_SIZE; i++, pDefMode++) 6945 cyReduction = 0; 6946 6947 rc = pHlp->pfnCFGMQueryU32(pCfg, "CustomVideoModes", &cCustomModes); 6948 if (RT_SUCCESS(rc) && cCustomModes) 6949 cb += sizeof(ModeInfoListItem) * cCustomModes; 6950 else 6951 cCustomModes = 0; 6952 6953 /* 6954 * Allocate and initialize buffer for the VBE BIOS Extra Data. 6955 */ 6956 AssertRelease(sizeof(VBEHEADER) + cb < 65536); 6957 pThisCC->cbVBEExtraData = (uint16_t)(sizeof(VBEHEADER) + cb); 6958 pThisCC->pbVBEExtraData = (uint8_t *)PDMDevHlpMMHeapAllocZ(pDevIns, pThisCC->cbVBEExtraData); 6959 if (!pThisCC->pbVBEExtraData) 6960 return VERR_NO_MEMORY; 6961 6962 pVBEDataHdr = (PVBEHEADER)pThisCC->pbVBEExtraData; 6963 pVBEDataHdr->u16Signature = VBEHEADER_MAGIC; 6964 pVBEDataHdr->cbData = cb; 6965 6966 pCurMode = (ModeInfoListItem *)(pVBEDataHdr + 1); 6967 for (i = 0; i < MODE_INFO_SIZE; i++) 6955 6968 { 6956 6969 uint32_t pixelWidth, reqSize; 6957 if ( pDefMode->info.MemoryModel == VBE_MEMORYMODEL_TEXT_MODE)6970 if (mode_info_list[i].info.MemoryModel == VBE_MEMORYMODEL_TEXT_MODE) 6958 6971 pixelWidth = 2; 6959 6972 else 6960 pixelWidth = (pDefMode->info.BitsPerPixel + 7) / 8; 6961 reqSize = pDefMode->info.XResolution * pDefMode->info.YResolution * pixelWidth; 6973 pixelWidth = (mode_info_list[i].info.BitsPerPixel +7) / 8; 6974 reqSize = mode_info_list[i].info.XResolution 6975 * mode_info_list[i].info.YResolution 6976 * pixelWidth; 6962 6977 if (reqSize >= pThis->vram_size) 6963 6978 continue; 6964 if ( pDefMode->info.XResolution > maxBiosXRes 6965 || pDefMode->info.YResolution - cyReduction > maxBiosYRes) 6979 if (!reqSize) 6966 6980 continue; 6967 *pCurMode = *pDefMode; 6968 pCurMode->mode += 0x30; 6969 pCurMode->info.YResolution -= cyReduction; 6981 if ( mode_info_list[i].info.XResolution > maxBiosXRes 6982 || mode_info_list[i].info.YResolution > maxBiosYRes) 6983 continue; 6984 *pCurMode = mode_info_list[i]; 6985 vgaR3AdjustModeInfo(pThis, pCurMode); 6970 6986 pCurMode++; 6971 6987 } 6972 } 6973 6974 6975 /* 6976 * Add custom modes. 6977 */ 6978 if (cCustomModes) 6979 { 6980 uint16_t u16CurMode = VBE_VBOX_MODE_CUSTOM1; 6981 for (i = 1; i <= cCustomModes; i++) 6988 6989 /* 6990 * Copy default modes with subtracted YResolution. 6991 */ 6992 if (cyReduction) 6982 6993 { 6983 char szExtraDataKey[sizeof("CustomVideoModeXX")]; 6984 char *pszExtraData = NULL; 6985 6986 /* query and decode the custom mode string. */ 6987 RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%d", i); 6988 rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, szExtraDataKey, &pszExtraData); 6989 if (RT_SUCCESS(rc)) 6994 ModeInfoListItem *pDefMode = mode_info_list; 6995 Log(("vgaR3Construct: cyReduction=%u\n", cyReduction)); 6996 for (i = 0; i < MODE_INFO_SIZE; i++, pDefMode++) 6990 6997 { 6991 ModeInfoListItem *pDefMode = mode_info_list; 6992 unsigned int cx, cy, cBits, cParams, j; 6993 uint16_t u16DefMode; 6994 6995 cParams = sscanf(pszExtraData, "%ux%ux%u", &cx, &cy, &cBits); 6996 if ( cParams != 3 6997 || (cBits != 8 && cBits != 16 && cBits != 24 && cBits != 32)) 6998 { 6999 AssertMsgFailed(("Configuration error: Invalid mode data '%s' for '%s'! cBits=%d\n", pszExtraData, szExtraDataKey, cBits)); 7000 return VERR_VGA_INVALID_CUSTOM_MODE; 7001 } 7002 if (!cx || !cy) 7003 { 7004 AssertMsgFailed(("Configuration error: Invalid mode data '%s' for '%s'! cx=%u, cy=%u\n", pszExtraData, szExtraDataKey, cx, cy)); 7005 return VERR_VGA_INVALID_CUSTOM_MODE; 7006 } 7007 cbPitch = calc_line_pitch(cBits, cx); 7008 if (cy * cbPitch >= pThis->vram_size) 7009 { 7010 AssertMsgFailed(("Configuration error: custom video mode %dx%dx%dbits is too large for the virtual video memory of %dMb. Please increase the video memory size.\n", 7011 cx, cy, cBits, pThis->vram_size / _1M)); 7012 return VERR_VGA_INVALID_CUSTOM_MODE; 7013 } 7014 PDMDevHlpMMHeapFree(pDevIns, pszExtraData); 7015 7016 /* Use defaults from max@bpp mode. */ 7017 switch (cBits) 7018 { 7019 case 8: 7020 u16DefMode = VBE_VESA_MODE_1024X768X8; 7021 break; 7022 7023 case 16: 7024 u16DefMode = VBE_VESA_MODE_1024X768X565; 7025 break; 7026 7027 case 24: 7028 u16DefMode = VBE_VESA_MODE_1024X768X888; 7029 break; 7030 7031 case 32: 7032 u16DefMode = VBE_OWN_MODE_1024X768X8888; 7033 break; 7034 7035 default: /* gcc, shut up! */ 7036 AssertMsgFailed(("gone postal!\n")); 7037 continue; 7038 } 7039 7040 /* mode_info_list is not terminated */ 7041 for (j = 0; j < MODE_INFO_SIZE && pDefMode->mode != u16DefMode; j++) 7042 pDefMode++; 7043 Assert(j < MODE_INFO_SIZE); 7044 7045 *pCurMode = *pDefMode; 7046 pCurMode->mode = u16CurMode++; 7047 7048 /* adjust defaults */ 7049 pCurMode->info.XResolution = cx; 7050 pCurMode->info.YResolution = cy; 7051 pCurMode->info.BytesPerScanLine = cbPitch; 7052 pCurMode->info.LinBytesPerScanLine = cbPitch; 7053 vgaR3AdjustModeInfo(pThis, pCurMode); 7054 7055 /* commit it */ 6998 uint32_t pixelWidth, reqSize; 6999 if (pDefMode->info.MemoryModel == VBE_MEMORYMODEL_TEXT_MODE) 7000 pixelWidth = 2; 7001 else 7002 pixelWidth = (pDefMode->info.BitsPerPixel + 7) / 8; 7003 reqSize = pDefMode->info.XResolution * pDefMode->info.YResolution * pixelWidth; 7004 if (reqSize >= pThis->vram_size) 7005 continue; 7006 if ( pDefMode->info.XResolution > maxBiosXRes 7007 || pDefMode->info.YResolution - cyReduction > maxBiosYRes) 7008 continue; 7009 *pCurMode = *pDefMode; 7010 pCurMode->mode += 0x30; 7011 pCurMode->info.YResolution -= cyReduction; 7056 7012 pCurMode++; 7057 7013 } 7058 else if (rc != VERR_CFGM_VALUE_NOT_FOUND) 7014 } 7015 7016 7017 /* 7018 * Add custom modes. 7019 */ 7020 if (cCustomModes) 7021 { 7022 uint16_t u16CurMode = VBE_VBOX_MODE_CUSTOM1; 7023 for (i = 1; i <= cCustomModes; i++) 7059 7024 { 7060 AssertMsgFailed(("pHlp->pfnCFGMQueryStringAlloc(,'%s',) -> %Rrc\n", szExtraDataKey, rc)); 7061 return rc; 7062 } 7063 } /* foreach custom mode key */ 7064 } 7065 7066 /* 7067 * Add the "End of list" mode. 7068 */ 7069 memset(pCurMode, 0, sizeof(*pCurMode)); 7070 pCurMode->mode = VBE_VESA_MODE_END_OF_LIST; 7071 7072 /* 7073 * Register I/O Port for the VBE BIOS Extra Data. 7074 */ 7075 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, VBE_EXTRA_PORT, 1 /*cPorts*/, vbeR3IOPortWriteVbeExtra, vbeR3IoPortReadVbeExtra, 7076 "VBE BIOS Extra Data", NULL /*paExtDesc*/, &pThis->hIoPortVbeExtra); 7077 AssertRCReturn(rc, rc); 7078 7079 /* 7080 * Register I/O Port for the BIOS Logo. 7081 */ 7082 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, LOGO_IO_PORT, 1 /*cPorts*/, vbeR3IoPortWriteCmdLogo, vbeR3IoPortReadCmdLogo, 7083 "BIOS Logo", NULL /*paExtDesc*/, &pThis->hIoPortCmdLogo); 7084 AssertRCReturn(rc, rc); 7085 7086 /* 7087 * Register debugger info callbacks. 7088 */ 7089 PDMDevHlpDBGFInfoRegister(pDevIns, "vga", "Display basic VGA state.", vgaR3InfoState); 7090 PDMDevHlpDBGFInfoRegister(pDevIns, "vgatext", "Display VGA memory formatted as text.", vgaR3InfoText); 7091 PDMDevHlpDBGFInfoRegister(pDevIns, "vgacr", "Dump VGA CRTC registers.", vgaR3InfoCR); 7092 PDMDevHlpDBGFInfoRegister(pDevIns, "vgagr", "Dump VGA Graphics Controller registers.", vgaR3InfoGR); 7093 PDMDevHlpDBGFInfoRegister(pDevIns, "vgasr", "Dump VGA Sequencer registers.", vgaR3InfoSR); 7094 PDMDevHlpDBGFInfoRegister(pDevIns, "vgaar", "Dump VGA Attribute Controller registers.", vgaR3InfoAR); 7095 PDMDevHlpDBGFInfoRegister(pDevIns, "vgapl", "Dump planar graphics state.", vgaR3InfoPlanar); 7096 PDMDevHlpDBGFInfoRegister(pDevIns, "vgadac", "Dump VGA DAC registers.", vgaR3InfoDAC); 7097 PDMDevHlpDBGFInfoRegister(pDevIns, "vbe", "Dump VGA VBE registers.", vgaR3InfoVBE); 7025 char szExtraDataKey[sizeof("CustomVideoModeXX")]; 7026 char *pszExtraData = NULL; 7027 7028 /* query and decode the custom mode string. */ 7029 RTStrPrintf(szExtraDataKey, sizeof(szExtraDataKey), "CustomVideoMode%d", i); 7030 rc = pHlp->pfnCFGMQueryStringAlloc(pCfg, szExtraDataKey, &pszExtraData); 7031 if (RT_SUCCESS(rc)) 7032 { 7033 ModeInfoListItem *pDefMode = mode_info_list; 7034 unsigned int cx, cy, cBits, cParams, j; 7035 uint16_t u16DefMode; 7036 7037 cParams = sscanf(pszExtraData, "%ux%ux%u", &cx, &cy, &cBits); 7038 if ( cParams != 3 7039 || (cBits != 8 && cBits != 16 && cBits != 24 && cBits != 32)) 7040 { 7041 AssertMsgFailed(("Configuration error: Invalid mode data '%s' for '%s'! cBits=%d\n", pszExtraData, szExtraDataKey, cBits)); 7042 return VERR_VGA_INVALID_CUSTOM_MODE; 7043 } 7044 if (!cx || !cy) 7045 { 7046 AssertMsgFailed(("Configuration error: Invalid mode data '%s' for '%s'! cx=%u, cy=%u\n", pszExtraData, szExtraDataKey, cx, cy)); 7047 return VERR_VGA_INVALID_CUSTOM_MODE; 7048 } 7049 cbPitch = calc_line_pitch(cBits, cx); 7050 if (cy * cbPitch >= pThis->vram_size) 7051 { 7052 AssertMsgFailed(("Configuration error: custom video mode %dx%dx%dbits is too large for the virtual video memory of %dMb. Please increase the video memory size.\n", 7053 cx, cy, cBits, pThis->vram_size / _1M)); 7054 return VERR_VGA_INVALID_CUSTOM_MODE; 7055 } 7056 PDMDevHlpMMHeapFree(pDevIns, pszExtraData); 7057 7058 /* Use defaults from max@bpp mode. */ 7059 switch (cBits) 7060 { 7061 case 8: 7062 u16DefMode = VBE_VESA_MODE_1024X768X8; 7063 break; 7064 7065 case 16: 7066 u16DefMode = VBE_VESA_MODE_1024X768X565; 7067 break; 7068 7069 case 24: 7070 u16DefMode = VBE_VESA_MODE_1024X768X888; 7071 break; 7072 7073 case 32: 7074 u16DefMode = VBE_OWN_MODE_1024X768X8888; 7075 break; 7076 7077 default: /* gcc, shut up! */ 7078 AssertMsgFailed(("gone postal!\n")); 7079 continue; 7080 } 7081 7082 /* mode_info_list is not terminated */ 7083 for (j = 0; j < MODE_INFO_SIZE && pDefMode->mode != u16DefMode; j++) 7084 pDefMode++; 7085 Assert(j < MODE_INFO_SIZE); 7086 7087 *pCurMode = *pDefMode; 7088 pCurMode->mode = u16CurMode++; 7089 7090 /* adjust defaults */ 7091 pCurMode->info.XResolution = cx; 7092 pCurMode->info.YResolution = cy; 7093 pCurMode->info.BytesPerScanLine = cbPitch; 7094 pCurMode->info.LinBytesPerScanLine = cbPitch; 7095 vgaR3AdjustModeInfo(pThis, pCurMode); 7096 7097 /* commit it */ 7098 pCurMode++; 7099 } 7100 else if (rc != VERR_CFGM_VALUE_NOT_FOUND) 7101 { 7102 AssertMsgFailed(("pHlp->pfnCFGMQueryStringAlloc(,'%s',) -> %Rrc\n", szExtraDataKey, rc)); 7103 return rc; 7104 } 7105 } /* foreach custom mode key */ 7106 } 7107 7108 /* 7109 * Add the "End of list" mode. 7110 */ 7111 memset(pCurMode, 0, sizeof(*pCurMode)); 7112 pCurMode->mode = VBE_VESA_MODE_END_OF_LIST; 7113 7114 /* 7115 * Register I/O Port for the VBE BIOS Extra Data. 7116 */ 7117 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, VBE_EXTRA_PORT, 1 /*cPorts*/, vbeR3IOPortWriteVbeExtra, vbeR3IoPortReadVbeExtra, 7118 "VBE BIOS Extra Data", NULL /*paExtDesc*/, &pThis->hIoPortVbeExtra); 7119 AssertRCReturn(rc, rc); 7120 7121 /* 7122 * Register I/O Port for the BIOS Logo. 7123 */ 7124 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, LOGO_IO_PORT, 1 /*cPorts*/, vbeR3IoPortWriteCmdLogo, vbeR3IoPortReadCmdLogo, 7125 "BIOS Logo", NULL /*paExtDesc*/, &pThis->hIoPortCmdLogo); 7126 AssertRCReturn(rc, rc); 7127 7128 /* 7129 * Register debugger info callbacks. 7130 */ 7131 PDMDevHlpDBGFInfoRegister(pDevIns, "vga", "Display basic VGA state.", vgaR3InfoState); 7132 PDMDevHlpDBGFInfoRegister(pDevIns, "vgatext", "Display VGA memory formatted as text.", vgaR3InfoText); 7133 PDMDevHlpDBGFInfoRegister(pDevIns, "vgacr", "Dump VGA CRTC registers.", vgaR3InfoCR); 7134 PDMDevHlpDBGFInfoRegister(pDevIns, "vgagr", "Dump VGA Graphics Controller registers.", vgaR3InfoGR); 7135 PDMDevHlpDBGFInfoRegister(pDevIns, "vgasr", "Dump VGA Sequencer registers.", vgaR3InfoSR); 7136 PDMDevHlpDBGFInfoRegister(pDevIns, "vgaar", "Dump VGA Attribute Controller registers.", vgaR3InfoAR); 7137 PDMDevHlpDBGFInfoRegister(pDevIns, "vgapl", "Dump planar graphics state.", vgaR3InfoPlanar); 7138 PDMDevHlpDBGFInfoRegister(pDevIns, "vgadac", "Dump VGA DAC registers.", vgaR3InfoDAC); 7139 PDMDevHlpDBGFInfoRegister(pDevIns, "vbe", "Dump VGA VBE registers.", vgaR3InfoVBE); 7140 } 7098 7141 7099 7142 /* … … 7344 7387 AssertRCReturn(rc, rc); 7345 7388 7346 /* 7347 * Set I/O port callbacks for this context. 7348 * We just copy the ring-3 registration bits and remove the '&' before the handle. 7349 */ 7389 if (pThis->fLegacyVgaEnabled) 7390 { 7391 /* 7392 * Set I/O port callbacks for this context. 7393 * We just copy the ring-3 registration bits and remove the '&' before the handle. 7394 */ 7350 7395 # define REG_PORT(a_uPort, a_cPorts, a_pfnWrite, a_pfnRead, a_szDesc, a_hIoPort) do { \ 7351 7396 rc = PDMDevHlpIoPortSetUpContext(pDevIns, a_hIoPort, a_pfnWrite, a_pfnRead, NULL /*pvUser*/); \ … … 7353 7398 } while (0) 7354 7399 7355 REG_PORT(0x3c0, 2, vgaIoPortArWrite, vgaIoPortArRead, "Attribute Controller", pThis->hIoPortAr);7356 REG_PORT(0x3c2, 1, vgaIoPortMsrWrite, vgaIoPortSt00Read, "MSR / ST00", pThis->hIoPortMsrSt00);7357 REG_PORT(0x3c3, 1, vgaIoPortUnusedWrite, vgaIoPortUnusedRead, "0x3c3", pThis->hIoPort3c3);7358 REG_PORT(0x3c4, 2, vgaIoPortSrWrite, vgaIoPortSrRead, "Sequencer", pThis->hIoPortSr);7359 REG_PORT(0x3c6, 4, vgaIoPortDacWrite, vgaIoPortDacRead, "DAC", pThis->hIoPortDac);7360 REG_PORT(0x3ca, 4, vgaIoPortPosWrite, vgaIoPortPosRead, "Graphics Position", /*?*/ pThis->hIoPortPos);7361 REG_PORT(0x3ce, 2, vgaIoPortGrWrite, vgaIoPortGrRead, "Graphics Controller", pThis->hIoPortGr);7362 7363 REG_PORT(0x3b4, 2, vgaIoPortMdaCrtWrite, vgaIoPortMdaCrtRead, "MDA CRT control", pThis->hIoPortMdaCrt);7364 REG_PORT(0x3ba, 1, vgaIoPortMdaFcrWrite, vgaIoPortMdaStRead, "MDA feature/status", pThis->hIoPortMdaFcrSt);7365 REG_PORT(0x3d4, 2, vgaIoPortCgaCrtWrite, vgaIoPortCgaCrtRead, "CGA CRT control", pThis->hIoPortCgaCrt);7366 REG_PORT(0x3da, 1, vgaIoPortCgaFcrWrite, vgaIoPortCgaStRead, "CGA Feature / status", pThis->hIoPortCgaFcrSt);7400 REG_PORT(0x3c0, 2, vgaIoPortArWrite, vgaIoPortArRead, "Attribute Controller", pThis->hIoPortAr); 7401 REG_PORT(0x3c2, 1, vgaIoPortMsrWrite, vgaIoPortSt00Read, "MSR / ST00", pThis->hIoPortMsrSt00); 7402 REG_PORT(0x3c3, 1, vgaIoPortUnusedWrite, vgaIoPortUnusedRead, "0x3c3", pThis->hIoPort3c3); 7403 REG_PORT(0x3c4, 2, vgaIoPortSrWrite, vgaIoPortSrRead, "Sequencer", pThis->hIoPortSr); 7404 REG_PORT(0x3c6, 4, vgaIoPortDacWrite, vgaIoPortDacRead, "DAC", pThis->hIoPortDac); 7405 REG_PORT(0x3ca, 4, vgaIoPortPosWrite, vgaIoPortPosRead, "Graphics Position", /*?*/ pThis->hIoPortPos); 7406 REG_PORT(0x3ce, 2, vgaIoPortGrWrite, vgaIoPortGrRead, "Graphics Controller", pThis->hIoPortGr); 7407 7408 REG_PORT(0x3b4, 2, vgaIoPortMdaCrtWrite, vgaIoPortMdaCrtRead, "MDA CRT control", pThis->hIoPortMdaCrt); 7409 REG_PORT(0x3ba, 1, vgaIoPortMdaFcrWrite, vgaIoPortMdaStRead, "MDA feature/status", pThis->hIoPortMdaFcrSt); 7410 REG_PORT(0x3d4, 2, vgaIoPortCgaCrtWrite, vgaIoPortCgaCrtRead, "CGA CRT control", pThis->hIoPortCgaCrt); 7411 REG_PORT(0x3da, 1, vgaIoPortCgaFcrWrite, vgaIoPortCgaStRead, "CGA Feature / status", pThis->hIoPortCgaFcrSt); 7367 7412 7368 7413 # ifdef CONFIG_BOCHS_VBE 7369 REG_PORT(0x1ce, 1, vgaIoPortWriteVbeIndex, vgaIoPortReadVbeIndex, "VBE Index", pThis->hIoPortVbeIndex);7370 REG_PORT(0x1cf, 1, vgaIoPortWriteVbeData, vgaIoPortReadVbeData, "VBE Data", pThis->hIoPortVbeData);7414 REG_PORT(0x1ce, 1, vgaIoPortWriteVbeIndex, vgaIoPortReadVbeIndex, "VBE Index", pThis->hIoPortVbeIndex); 7415 REG_PORT(0x1cf, 1, vgaIoPortWriteVbeData, vgaIoPortReadVbeData, "VBE Data", pThis->hIoPortVbeData); 7371 7416 # endif /* CONFIG_BOCHS_VBE */ 7372 7417 7373 7418 # undef REG_PORT 7374 7419 7375 /* BIOS port: */ 7376 rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hIoPortBios, vgaIoPortWriteBios, vgaIoPortReadBios, NULL /*pvUser*/); 7377 AssertRCReturn(rc, rc); 7420 /* BIOS port: */ 7421 rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hIoPortBios, vgaIoPortWriteBios, vgaIoPortReadBios, NULL /*pvUser*/); 7422 AssertRCReturn(rc, rc); 7423 7424 /* 7425 * MMIO. 7426 */ 7427 rc = PDMDevHlpMmioSetUpContextEx(pDevIns, pThis->hMmioLegacy, vgaMmioWrite, vgaMmioRead, vgaMmioFill, NULL /*pvUser*/); 7428 AssertRCReturn(rc, rc); 7429 } 7378 7430 7379 7431 # ifdef VBOX_WITH_VMSVGA … … 7386 7438 else 7387 7439 AssertReturn(!pThis->fVMSVGAEnabled, VERR_INVALID_STATE); 7440 7441 if (pThis->hMmioSvga3 != NIL_IOMIOPORTHANDLE) 7442 { 7443 AssertReturn(pThis->fVMSVGAEnabled && pThis->fVmSvga3, VERR_INVALID_STATE); 7444 rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hMmioSvga3, vmsvga3MmioWrite, vmsvga3MmioRead, NULL /*pvUser*/); 7445 AssertRCReturn(rc, rc); 7446 } 7447 else 7448 AssertReturn(!pThis->fVMSVGAEnabled && !pThis->fVmSvga3, VERR_INVALID_STATE); 7388 7449 # endif 7389 7390 /*7391 * MMIO.7392 */7393 rc = PDMDevHlpMmioSetUpContextEx(pDevIns, pThis->hMmioLegacy, vgaMmioWrite, vgaMmioRead, vgaMmioFill, NULL /*pvUser*/);7394 AssertRCReturn(rc, rc);7395 7450 7396 7451 /* … … 7408 7463 # if defined(VBOX_WITH_VMSVGA) && !defined(IN_RC) 7409 7464 AssertCompile((RT_MAX(SVGA_FIFO_MIN, RT_MAX(SVGA_FIFO_PITCHLOCK, SVGA_FIFO_BUSY)) + 1) * sizeof(uint32_t) < GUEST_PAGE_SIZE); 7410 if (pThis->fVMSVGAEnabled) 7465 if ( pThis->fVMSVGAEnabled 7466 && !pThis->fVmSvga3) 7411 7467 { 7412 7468 rc = PDMDevHlpMmio2SetUpContext(pDevIns, pThis->hMmio2VmSvgaFifo, 0 /* off */, GUEST_PAGE_SIZE, -
trunk/src/VBox/Devices/Graphics/DevVGA.h
r98103 r100690 370 370 /** Flag indicating that there are dirty bits. This is used to optimize the handler resetting. */ 371 371 bool fHasDirtyBits; 372 /** Flag indicating that the VGA memory in the 0xa0000-0xbffff region has been remapped to allow direct access.373 * @todo This is just an unnecessary summmary of bmPageMapBitmap. */374 bool fRemappedVGA;375 372 /** Whether to render the guest VRAM to the framebuffer memory. False only for some LFB modes. */ 376 373 bool fRenderVRAM; … … 379 376 /** Set if state has been restored. */ 380 377 bool fStateLoaded; 378 /** Flag whether to expose the legacy VGA interface to the guest. */ 379 bool fLegacyVgaEnabled; 381 380 #ifdef VBOX_WITH_VMSVGA 382 381 /* Whether the SVGA emulation is enabled or not. */ … … 385 384 bool fVMSVGAPciId; 386 385 bool fVMSVGAPciBarLayout; 386 /** Flag whether the SVGA3 interface is exposed to the guest. */ 387 bool fVmSvga3; 387 388 #else 388 bool afPadding4[ 4];389 bool afPadding4[5]; 389 390 #endif 390 391 … … 516 517 /** VMSVGA: I/O port PCI region. */ 517 518 IOMIOPORTHANDLE hIoPortVmSvga; 519 /** VMSVGA3: MMIO PCI region for the registers. */ 520 IOMMMIOHANDLE hMmioSvga3; 518 521 /** VMSVGA: The MMIO2 handle of the FIFO PCI region. */ 519 522 PGMMMIO2HANDLE hMmio2VmSvgaFifo; -
trunk/src/VBox/Devices/Graphics/vmsvga_include/svga_reg.h
r96407 r100690 1 1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 2 /********************************************************** 3 * Copyright 1998-20 15VMware, Inc.3 * Copyright 1998-2021 VMware, Inc. 4 4 * 5 5 * Permission is hereby granted, free of charge, to any person … … 98 98 #define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver)) 99 99 100 /* Version 3 has the control bar instead of the FIFO */ 101 #define SVGA_VERSION_3 3 102 #define SVGA_ID_3 SVGA_MAKE_ID(SVGA_VERSION_3) 103 100 104 /* Version 2 let the address of the frame buffer be unsigned on Win32 */ 101 105 #define SVGA_VERSION_2 2 … … 129 133 * SVGA_CAP_IRQMASK capability is present. 130 134 */ 131 #define SVGA_IRQFLAG_ANY_FENCE 0x1 /* Any fence was passed */ 132 #define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */ 133 #define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */ 134 #define SVGA_IRQFLAG_COMMAND_BUFFER 0x8 /* Command buffer completed */ 135 #define SVGA_IRQFLAG_ERROR 0x10 /* Error while processing commands */ 135 #define SVGA_IRQFLAG_ANY_FENCE (1 << 0) /* Any fence was passed */ 136 #define SVGA_IRQFLAG_FIFO_PROGRESS (1 << 1) /* Made forward progress in the FIFO */ 137 #define SVGA_IRQFLAG_FENCE_GOAL (1 << 2) /* SVGA_FIFO_FENCE_GOAL reached */ 138 #define SVGA_IRQFLAG_COMMAND_BUFFER (1 << 3) /* Command buffer completed */ 139 #define SVGA_IRQFLAG_ERROR (1 << 4) /* Error while processing commands */ 140 #define SVGA_IRQFLAG_MAX (1 << 5) 136 141 137 142 /* … … 286 291 SVGA_REG_GBOBJECT_MEM_SIZE_KB = 76, 287 292 288 SVGA_REG_TOP = 77, /* Must be 1 more than the last register */ 293 /* 294 * These register are for the addresses of the memory BARs for SVGA3 295 */ 296 SVGA_REG_REGS_START_HIGH32 = 77, 297 SVGA_REG_REGS_START_LOW32 = 78, 298 SVGA_REG_FB_START_HIGH32 = 79, 299 SVGA_REG_FB_START_LOW32 = 80, 300 301 /* 302 * A hint register that recommends which quality level the guest should 303 * currently use to define multisample surfaces. 304 * 305 * If the register is SVGA_REG_MSHINT_DISABLED, 306 * the guest is only allowed to use SVGA3D_MS_QUALITY_FULL. 307 * 308 * Otherwise, this is a live value that can change while the VM is 309 * powered on with the hint suggestion for which quality level the guest 310 * should be using. Guests are free to ignore the hint and use either 311 * RESOLVE or FULL quality. 312 */ 313 SVGA_REG_MSHINT = 81, 314 315 SVGA_REG_IRQ_STATUS = 82, 316 SVGA_REG_DIRTY_TRACKING = 83, 317 318 SVGA_REG_TOP = 84, /* Must be 1 more than the last register */ 289 319 290 320 SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ … … 309 339 SVGA_REG_GUEST_DRIVER_ID_SUBMIT = MAX_UINT32, 310 340 } SVGARegGuestDriverId; 341 342 typedef enum SVGARegMSHint { 343 SVGA_REG_MSHINT_DISABLED = 0, 344 SVGA_REG_MSHINT_FULL = 1, 345 SVGA_REG_MSHINT_RESOLVED = 2, 346 } SVGARegMSHint; 347 348 typedef enum SVGARegDirtyTracking { 349 SVGA_REG_DIRTY_TRACKING_PER_IMAGE = 0, 350 SVGA_REG_DIRTY_TRACKING_PER_SURFACE = 1, 351 } SVGARegDirtyTracking; 311 352 312 353
Note:
See TracChangeset
for help on using the changeset viewer.