VirtualBox

Changeset 100690 in vbox for trunk/src


Ignore:
Timestamp:
Jul 25, 2023 8:20:54 AM (19 months ago)
Author:
vboxsync
Message:

Devices/Graphics: Add support for the SVGA3 interface required for ARM, bugref:10458

Location:
trunk/src/VBox/Devices/Graphics
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp

    r100178 r100690  
    459459static const char *vmsvgaIndexToString(PVGASTATE pThis, uint32_t idxReg)
    460460{
    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. */
    462462    switch (idxReg)
    463463    {
     
    545545        SVGA_CASE_ID2STR(SVGA_REG_SCREENDMA);
    546546        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);
    547554        SVGA_CASE_ID2STR(SVGA_REG_TOP);                /* Must be 1 more than the last register */
    548555
     
    10021009 * @param   pDevIns     The device instance.
    10031010 * @param   pThis       The shared VGA/VMSVGA state.
     1011 * @param   idxReg      The register index being read.
    10041012 * @param   pu32        Where to store the read value
    10051013 */
    1006 static int vmsvgaReadPort(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t *pu32)
     1014static int vmsvgaReadPort(PPDMDEVINS pDevIns, PVGASTATE pThis, uint32_t idxReg, uint32_t *pu32)
    10071015{
    10081016#ifdef IN_RING3
     
    10121020    *pu32 = 0;
    10131021
    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 #else
    1020     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 #endif
    1024     RT_UNTRUSTED_VALIDATED_FENCE();
    1025 
    10261022    /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */
    10271023    if (   idxReg >= SVGA_REG_ID_0_TOP
     
    10291025    {
    10301026        idxReg += SVGA_PALETTE_BASE - SVGA_REG_ID_0_TOP;
    1031         Log(("vmsvgaWritePort: 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));
    10321028    }
    10331029
     
    15731569
    15741570        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
    15761593        case SVGA_REG_RESERVED1: /* SVGA_REG_RESERVED* correspond to SVGA_REG_CURSOR4_*. Require SVGA_CAP2_EXTRA_REGS. */
    15771594        case SVGA_REG_RESERVED2:
     
    15871604            *pu32 = _1G / _1K;
    15881605            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        }
    15891615
    15901616        default:
     
    17711797{
    17721798    uint32_t RT_UNTRUSTED_VOLATILE_GUEST *pFIFO = pThisCC->svga.pau32FIFO;
    1773     uint32_t uFifoPitchLock = pFIFO[SVGA_FIFO_PITCHLOCK];
     1799    uint32_t uFifoPitchLock = pThis->fVmSvga3 ? 0 : pFIFO[SVGA_FIFO_PITCHLOCK];
    17741800    uint32_t uRegPitchLock  = pThis->svga.u32PitchLock;
    1775     uint32_t uFifoMin       = pFIFO[SVGA_FIFO_MIN];
     1801    uint32_t uFifoMin       = pThis->fVmSvga3 ? 0 : pFIFO[SVGA_FIFO_MIN];
    17761802
    17771803    /* The SVGA_FIFO_PITCHLOCK register is only valid if SVGA_FIFO_MIN points past
     
    18531879 * @param   pThis       The shared VGA/VMSVGA state.
    18541880 * @param   pThisCC     The VGA/VMSVGA state for the current context.
     1881 * @param   idxReg      Rge register index being written.
    18551882 * @param   u32         Value to write
    18561883 */
    1857 static VBOXSTRICTRC vmsvgaWritePort(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t u32)
     1884static VBOXSTRICTRC vmsvgaWritePort(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t idxReg, uint32_t u32)
    18581885{
    18591886#ifdef IN_RING3
     
    18621889    VBOXSTRICTRC rc = VINF_SUCCESS;
    18631890    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 #else
    1871     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 #endif
    1875     RT_UNTRUSTED_VALIDATED_FENCE();
    18761891
    18771892    /* We must adjust the register number if we're in SVGA_ID_0 mode because the PALETTE range moved. */
     
    19071922            if (   u32 == SVGA_ID_0
    19081923                || u32 == SVGA_ID_1
    1909                 || u32 == SVGA_ID_2)
     1924                || u32 == SVGA_ID_2
     1925                || u32 == SVGA_ID_3)
    19101926                pThis->svga.u32SVGAId = u32;
    19111927            else
     
    19421958                    ASMAtomicOrU32(&pThis->svga.u32ActionFlags, VMSVGA_ACTION_CHANGEMODE);
    19431959# 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                }
    19471966# endif
    19481967
     
    23942413            break;
    23952414
     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
    23962431        default:
    23972432        {
     
    24522487
    24532488            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            }
    24552504
    24562505            case SVGA_BIOS_PORT:
     
    24962545
    24972546            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            }
    24992562
    25002563            case SVGA_BIOS_PORT:
     
    25212584
    25222585    return VINF_SUCCESS;
     2586}
     2587
     2588/**
     2589 * @callback_method_impl{FNIOMMMIONEWREAD}
     2590 */
     2591DECLCALLBACK(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 */
     2615DECLCALLBACK(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;
    25232636}
    25242637
     
    36283741         */
    36293742        /** @todo This code is very similar to the FIFO loop command processing. Think about merging. */
     3743        LogFlow(("cmdId=%u\n", cmdId));
    36303744        switch (cmdId)
    36313745        {
     
    36443758                Log(("SVGA_CMD_FENCE %#x\n", pCmd->fence));
    36453759
    3646                 uint32_t const offFifoMin = pFIFO[SVGA_FIFO_MIN];
    3647                 if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin))
     3760                if (pThis->fVmSvga3)
    36483761                {
    3649                     pFIFO[SVGA_FIFO_FENCE] = pCmd->fence;
     3762                    pThis->svga.u32FenceLast = pCmd->fence;
    36503763
    36513764                    if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
     
    36543767                        *pu32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
    36553768                    }
    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)
    36593770                    {
    36603771                        Log(("fence goal reached irq (fence=%#x)\n", pCmd->fence));
     
    36633774                }
    36643775                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                }
    36663798                break;
    36673799            }
     
    45454677    /* Caller already checked pThis->svga.fFIFOThreadSleeping, so we only have
    45464678       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)))
    45484680        && pThis->svga.fFIFOThreadSleeping
    45494681        && !ASMAtomicReadBool(&pThis->svga.fBadGuest))
     
    52485380
    52495381/**
     5382 * @callback_method_impl{PFNPDMTHREADDEV, The async FIFO handling thread.}
     5383 */
     5384static 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/**
    52505511 * @callback_method_impl{PFNPDMTHREADWAKEUPDEV,
    52515512 * Unblock the FIFO I/O thread so it can respond to a state change.}
     
    52855546        if (pThis->svga.uHeight != VMSVGA_VAL_UNINITIALIZED)
    52865547        {
    5287 # ifndef 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. */
    52885549            Assert(pThis->svga.cbScanline);
    52895550# endif
     
    64696730
    64706731    /* 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;
    64786740}
    64796741
     
    65876849    Log(("vmsvgaR3Reset\n"));
    65886850
    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    }
    65916856
    65926857    PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect); /* Hack around lock order issue. FIFO thread might take the lock. */
     
    66096874    RT_BZERO(pThisCC->svga.pbVgaFrameBufferR3, VMSVGA_VGA_FB_BACKUP_SIZE);
    66106875
    6611     vmsvgaR3InitFIFO(pThis, pThisCC);
     6876    if (!pThis->fVmSvga3)
     6877        vmsvgaR3InitFIFO(pThis, pThisCC);
    66126878
    66136879    /* Initialize FIFO and register capabilities. */
     
    66156881
    66166882# ifdef VBOX_WITH_VMSVGA3D
    6617     if (pThis->svga.f3DEnabled)
     6883    if (   pThis->svga.f3DEnabled
     6884        && !pThis->fVmSvga3)
    66186885        vmsvgaR3InitFifo3DCaps(pThis, pThisCC);
    66196886# endif
     
    67957062
    67967063    /* 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");
    67997076    if (RT_FAILURE(rc))
    68007077    {
     
    70537330    if (!fLoadState)
    70547331    {
    7055         vmsvgaR3InitFIFO(pThis, pThisCC);
     7332        if (!pThis->fVmSvga3)
     7333            vmsvgaR3InitFIFO(pThis, pThisCC);
    70567334        vmsvgaR3GetCaps(pThis, pThisCC, &pThis->svga.u32DeviceCaps, &pThis->svga.u32DeviceCaps2, &pThisCC->svga.pau32FIFO[SVGA_FIFO_CAPABILITIES]);
    70577335    }
     
    70707348        Assert(   (pThis->svga.u32DeviceCaps & u32DeviceCaps) == pThis->svga.u32DeviceCaps
    70717349               && (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]));
    70737352    }
    70747353#endif
    70757354
    70767355# ifdef VBOX_WITH_VMSVGA3D
    7077     if (pThis->svga.f3DEnabled)
     7356    if (   pThis->svga.f3DEnabled
     7357        && !pThis->fVmSvga3)
    70787358    {
    70797359        PVMSVGAR3STATE pSVGAState = pThisCC->svga.pSvgaR3State;
  • trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.h

    r99535 r100690  
    5858#ifndef PCI_DEVICE_ID_VMWARE_SVGA2
    5959# define PCI_DEVICE_ID_VMWARE_SVGA2      0x0405
     60#endif
     61#ifndef PCI_DEVICE_ID_VMWARE_SVGA3
     62# define PCI_DEVICE_ID_VMWARE_SVGA3      0x0406
    6063#endif
    6164
     
    337340    uint32_t                    u32GuestDriverVer2;
    338341    uint32_t                    u32GuestDriverVer3;
     342    /** The last fence received. */
     343    uint32_t                    u32FenceLast;
    339344    /** Port io index register. */
    340345    uint32_t                    u32IndexReg;
     
    565570DECLCALLBACK(VBOXSTRICTRC) vmsvgaIORead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb);
    566571DECLCALLBACK(VBOXSTRICTRC) vmsvgaIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb);
     572DECLCALLBACK(VBOXSTRICTRC) vmsvga3MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb);
     573DECLCALLBACK(VBOXSTRICTRC) vmsvga3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb);
    567574
    568575DECLCALLBACK(void) vmsvgaR3PortSetViewport(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId,
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r100108 r100690  
    64726472                                            "|VMSVGAPciBarLayout"
    64736473                                            "|VMSVGAFifoSize"
     6474                                            "|VmSvga3"
     6475                                            "|VmSvgaExposeLegacyVga"
    64746476# endif
    64756477# ifdef VBOX_WITH_VMSVGA3D
     
    65236525    Log(("VMSVGA: VMSVGAPciBarLayout = %d\n", pThis->fVMSVGAPciBarLayout));
    65246526
     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
    65256535    rc = pHlp->pfnCFGMQueryU32Def(pCfg, "VMSVGAFifoSize", &pThis->svga.cbFIFO, VMSVGA_FIFO_SIZE);
    65266536    AssertLogRelRCReturn(rc, rc);
     
    65446554    if (pThis->fVMSVGAPciBarLayout)
    65456555    {
    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        }
    65486566    }
    65496567    else
     
    65726590        {
    65736591            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);
    65756596        }
    65766597        else
     
    65806601        }
    65816602        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);
    65836607    }
    65846608    else
     
    66596683    pThis->hIoPortVmSvga    = NIL_IOMIOPORTHANDLE;
    66606684    pThis->hMmio2VmSvgaFifo = NIL_PGMMMIO2HANDLE;
     6685    pThis->hMmioSvga3       = NIL_IOMMMIOHANDLE;
    66616686    if (pThis->fVMSVGAEnabled)
    66626687    {
    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        }
    66736710
    66746711        pPciDev->pfnRegionLoadChangeHookR3 = vgaR3PciRegionLoadChangeHook;
     
    66856722                                                 N_("Failed to allocate %u bytes of VRAM"), pThis->vram_size));
    66866723
    6687     /*
    6688      * Register I/O ports.
    6689      */
     6724    if (pThis->fLegacyVgaEnabled)
     6725    {
     6726        /*
     6727         * Register I/O ports.
     6728         */
    66906729# define REG_PORT(a_uPort, a_cPorts, a_pfnWrite, a_pfnRead, a_szDesc, a_phIoPort) do { \
    66916730            rc = PDMDevHlpIoPortCreateFlagsAndMap(pDevIns, a_uPort, a_cPorts, IOM_IOPORT_F_ABS, \
     
    66936732            AssertRCReturn(rc, rc); \
    66946733        } 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);
    67086747
    67096748# 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);
    67126751# endif /* CONFIG_BOCHS_VBE */
    67136752
    67146753# 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);
    67186757# endif /* VBOX_WITH_HGSMI */
    67196758
    67206759# undef REG_PORT
    67216760
    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)
    67626781        {
    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);
    67646800            if (RT_SUCCESS(rc))
    67656801            {
    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                }
    67706810            }
    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)
    67736828        {
    67746829            /*
    6775              * In case of failure simply fall back to the built-in VGA BIOS ROM.
     6830             * Allocate buffer for the VGA BIOS ROM data.
    67766831             */
    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)
    67786852            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)
    67956860        {
    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)
    67986866            {
    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"));
    68026870            }
    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;
    68376884        }
    68386885        else
    68396886        {
    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    }
    68586898
    68596899    /*
     
    68926932    AssertLogRelRCReturn(rc, rc);
    68936933
    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 */
    69306944        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++)
    69556968        {
    69566969            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)
    69586971                pixelWidth = 2;
    69596972            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;
    69626977            if (reqSize >= pThis->vram_size)
    69636978                continue;
    6964             if (   pDefMode->info.XResolution > maxBiosXRes
    6965                 || pDefMode->info.YResolution - cyReduction > maxBiosYRes)
     6979            if (!reqSize)
    69666980                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);
    69706986            pCurMode++;
    69716987        }
    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)
    69826993        {
    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++)
    69906997            {
    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;
    70567012                pCurMode++;
    70577013            }
    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++)
    70597024            {
    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    }
    70987141
    70997142    /*
     
    73447387    AssertRCReturn(rc, rc);
    73457388
    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         */
    73507395# define REG_PORT(a_uPort, a_cPorts, a_pfnWrite, a_pfnRead, a_szDesc, a_hIoPort) do { \
    73517396            rc = PDMDevHlpIoPortSetUpContext(pDevIns, a_hIoPort, a_pfnWrite, a_pfnRead, NULL /*pvUser*/); \
     
    73537398        } while (0)
    73547399
    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);
    73677412
    73687413# 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);
    73717416# endif /* CONFIG_BOCHS_VBE */
    73727417
    73737418# undef REG_PORT
    73747419
    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    }
    73787430
    73797431# ifdef VBOX_WITH_VMSVGA
     
    73867438    else
    73877439        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);
    73887449# endif
    7389 
    7390     /*
    7391      * MMIO.
    7392      */
    7393     rc = PDMDevHlpMmioSetUpContextEx(pDevIns, pThis->hMmioLegacy, vgaMmioWrite, vgaMmioRead, vgaMmioFill, NULL /*pvUser*/);
    7394     AssertRCReturn(rc, rc);
    73957450
    73967451    /*
     
    74087463# if defined(VBOX_WITH_VMSVGA) && !defined(IN_RC)
    74097464    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)
    74117467    {
    74127468        rc = PDMDevHlpMmio2SetUpContext(pDevIns, pThis->hMmio2VmSvgaFifo, 0 /* off */, GUEST_PAGE_SIZE,
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r98103 r100690  
    370370    /** Flag indicating that there are dirty bits. This is used to optimize the handler resetting. */
    371371    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;
    375372    /** Whether to render the guest VRAM to the framebuffer memory. False only for some LFB modes. */
    376373    bool                        fRenderVRAM;
     
    379376    /** Set if state has been restored. */
    380377    bool                        fStateLoaded;
     378    /** Flag whether to expose the legacy VGA interface to the guest. */
     379    bool                        fLegacyVgaEnabled;
    381380#ifdef VBOX_WITH_VMSVGA
    382381    /* Whether the SVGA emulation is enabled or not. */
     
    385384    bool                        fVMSVGAPciId;
    386385    bool                        fVMSVGAPciBarLayout;
     386    /** Flag whether the SVGA3 interface is exposed to the guest. */
     387    bool                        fVmSvga3;
    387388#else
    388     bool                        afPadding4[4];
     389    bool                        afPadding4[5];
    389390#endif
    390391
     
    516517    /** VMSVGA: I/O port PCI region. */
    517518    IOMIOPORTHANDLE             hIoPortVmSvga;
     519    /** VMSVGA3: MMIO PCI region for the registers. */
     520    IOMMMIOHANDLE               hMmioSvga3;
    518521    /** VMSVGA: The MMIO2 handle of the FIFO PCI region. */
    519522    PGMMMIO2HANDLE              hMmio2VmSvgaFifo;
  • trunk/src/VBox/Devices/Graphics/vmsvga_include/svga_reg.h

    r96407 r100690  
    11/* SPDX-License-Identifier: GPL-2.0 OR MIT */
    22/**********************************************************
    3  * Copyright 1998-2015 VMware, Inc.
     3 * Copyright 1998-2021 VMware, Inc.
    44 *
    55 * Permission is hereby granted, free of charge, to any person
     
    9898#define SVGA_MAKE_ID(ver)  (SVGA_MAGIC << 8 | (ver))
    9999
     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
    100104/* Version 2 let the address of the frame buffer be unsigned on Win32 */
    101105#define SVGA_VERSION_2     2
     
    129133 * SVGA_CAP_IRQMASK capability is present.
    130134 */
    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)
    136141
    137142/*
     
    286291   SVGA_REG_GBOBJECT_MEM_SIZE_KB = 76,
    287292
    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 */
    289319
    290320   SVGA_PALETTE_BASE = 1024,        /* Base of SVGA color map */
     
    309339   SVGA_REG_GUEST_DRIVER_ID_SUBMIT  = MAX_UINT32,
    310340} SVGARegGuestDriverId;
     341
     342typedef enum SVGARegMSHint {
     343   SVGA_REG_MSHINT_DISABLED = 0,
     344   SVGA_REG_MSHINT_FULL     = 1,
     345   SVGA_REG_MSHINT_RESOLVED = 2,
     346} SVGARegMSHint;
     347
     348typedef enum SVGARegDirtyTracking {
     349   SVGA_REG_DIRTY_TRACKING_PER_IMAGE = 0,
     350   SVGA_REG_DIRTY_TRACKING_PER_SURFACE = 1,
     351} SVGARegDirtyTracking;
    311352
    312353
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette