VirtualBox

Changeset 70602 in vbox


Ignore:
Timestamp:
Jan 16, 2018 5:04:30 PM (7 years ago)
Author:
vboxsync
Message:

DevVGA: cleanup in progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp

    r70600 r70602  
    105105{
    106106    VBVABUFFER *pVBVA;
     107    uint32_t    cbMaxData; /**< Maximum number of data bytes addressible relative to pVBVA. */
    107108    volatile int32_t i32State;
    108109    volatile int32_t i32EnableState;
     
    184185typedef struct VBOXVDMAHOST
    185186{
    186     PHGSMIINSTANCE pHgsmi;
     187    PHGSMIINSTANCE pHgsmi; /**< Same as VGASTATE::pHgsmi. */
    187188    PVGASTATE pVGAState;
    188189#ifdef VBOX_WITH_CRHGSMI
     
    386387    {
    387388        case VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE:
    388         {
    389389            VBoxVBVAExHPPause(pCmdVbva);
    390390            VBoxVBVAExHPDataCompleteCtl(pCmdVbva, pCtl, VINF_SUCCESS);
    391391            return true;
    392         }
     392
    393393        case VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME:
    394         {
    395394            VBoxVBVAExHPResume(pCmdVbva);
    396395            VBoxVBVAExHPDataCompleteCtl(pCmdVbva, pCtl, VINF_SUCCESS);
    397396            return true;
    398         }
     397
    399398        default:
    400399            return false;
     
    434433/**
    435434 * Worker for vboxVBVAExHPDataGet.
     435 *
     436 * @retval VINF_SUCCESS
     437 * @retval VINF_EOF
     438 * @retval VINF_TRY_AGAIN
     439 * @retval VERR_INVALID_STATE
     440 *
    436441 * @thread VDMA
    437  * @todo r=bird: revalidate this code.
    438  */
    439 static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
     442 */
     443static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppbCmd, uint32_t *pcbCmd)
    440444{
    441445    Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
    442446    Assert(pCmdVbva->i32EnableState > VBVAEXHOSTCONTEXT_ESTATE_PAUSED);
    443447
    444     VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
    445 
    446     uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
    447     uint32_t indexRecordFree = pVBVA->indexRecordFree;
    448 
    449     Log(("first = %d, free = %d\n", indexRecordFirst, indexRecordFree));
    450 
    451     if (indexRecordFirst == indexRecordFree)
    452     {
    453         /* No records to process. Return without assigning output variables. */
    454         return VINF_EOF;
    455     }
    456 
    457     uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[indexRecordFirst].cbRecord);
    458 
    459     /* A new record need to be processed. */
    460     if (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
    461     {
    462         /* the record is being recorded, try again */
    463         return VINF_TRY_AGAIN;
    464     }
    465 
    466     uint32_t cbRecord = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
    467 
    468     if (!cbRecord)
    469     {
    470         /* the record is being recorded, try again */
    471         return VINF_TRY_AGAIN;
    472     }
    473 
    474     /* we should not get partial commands here actually */
     448    VBVABUFFER volatile *pVBVA = pCmdVbva->pVBVA; /* This is shared with the guest, so careful! */
     449
     450    /*
     451     * Inspect records.
     452     */
     453    uint32_t idxRecordFirst = ASMAtomicUoReadU32(&pVBVA->indexRecordFirst);
     454    uint32_t idxRecordFree  = ASMAtomicReadU32(&pVBVA->indexRecordFree);
     455    Log(("first = %d, free = %d\n", idxRecordFirst, idxRecordFree));
     456    if (idxRecordFirst == idxRecordFree)
     457        return VINF_EOF; /* No records to process. Return without assigning output variables. */
     458    AssertReturn(idxRecordFirst < VBVA_MAX_RECORDS, VERR_INVALID_STATE);
     459
     460    /*
     461     * Read the record size and check that it has been completly recorded.
     462     */
     463    uint32_t const cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[idxRecordFirst].cbRecord);
     464    uint32_t const cbRecord        = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
     465    if (   (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
     466        || !cbRecord)
     467        return VINF_TRY_AGAIN; /* The record is being recorded, try again. */
    475468    Assert(cbRecord);
    476469
    477     /* The size of largest contiguous chunk in the ring biffer. */
    478     uint32_t u32BytesTillBoundary = pVBVA->cbData - pVBVA->off32Data;
    479 
    480     /* The pointer to data in the ring buffer. */
    481     uint8_t *pSrc = &pVBVA->au8Data[pVBVA->off32Data];
    482 
    483     /* Fetch or point the data. */
    484     if (u32BytesTillBoundary >= cbRecord)
    485     {
    486         /* The command does not cross buffer boundary. Return address in the buffer. */
    487         *ppCmd = pSrc;
    488         *pcbCmd = cbRecord;
    489         return VINF_SUCCESS;
    490     }
    491 
    492     LogRel(("CmdVbva: cross-bound writes unsupported\n"));
    493     return VERR_INVALID_STATE;
    494 }
    495 
     470    /*
     471     * Get and validate the data area.
     472     */
     473    uint32_t const offData   = ASMAtomicReadU32(&pVBVA->off32Data);
     474    uint32_t       cbMaxData = ASMAtomicReadU32(&pVBVA->cbData);
     475    AssertLogRelMsgStmt(cbMaxData <= pCmdVbva->cbMaxData, ("%#x vs %#x\n", cbMaxData, pCmdVbva->cbMaxData),
     476                        cbMaxData = pCmdVbva->cbMaxData);
     477    AssertLogRelMsgReturn(   cbRecord <= cbMaxData
     478                          && offData  <= cbMaxData - cbRecord,
     479                          ("offData=%#x cbRecord=%#x cbMaxData=%#x cbRecord\n", offData, cbRecord, cbMaxData),
     480                          VERR_INVALID_STATE);
     481
     482    /*
     483     * Just set the return values and we're done.
     484     */
     485    *ppbCmd  = (uint8_t *)&pVBVA->au8Data[offData];
     486    *pcbCmd = cbRecord;
     487    return VINF_SUCCESS;
     488}
     489
     490/**
     491 * Completion routine advancing our end of the ring and data buffers forward.
     492 *
     493 * @param   pCmdVbva            The VBVA context.
     494 * @param   cbCmd               The size of the data.
     495 */
    496496static void VBoxVBVAExHPDataCompleteCmd(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint32_t cbCmd)
    497497{
    498     VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
    499     pVBVA->off32Data = (pVBVA->off32Data + cbCmd) % pVBVA->cbData;
    500 
    501     pVBVA->indexRecordFirst = (pVBVA->indexRecordFirst + 1) % RT_ELEMENTS(pVBVA->aRecords);
     498    VBVABUFFER volatile *pVBVA       = pCmdVbva->pVBVA;
     499
     500    /* Move data head. */
     501    uint32_t const       cbData      = pVBVA->cbData;
     502    uint32_t const       offData     = pVBVA->off32Data;
     503    if (cbData > 0)
     504        ASMAtomicWriteU32(&pVBVA->off32Data, (offData + cbCmd) % cbData);
     505    else
     506        ASMAtomicWriteU32(&pVBVA->off32Data, 0);
     507
     508    /* Increment record pointer. */
     509    uint32_t const       idxRecFirst = pVBVA->indexRecordFirst;
     510    ASMAtomicWriteU32(&pVBVA->indexRecordFirst, (idxRecFirst + 1) % RT_ELEMENTS(pVBVA->aRecords));
    502511}
    503512
     
    707716 * @thread VDMA
    708717 */
    709 static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA)
     718static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA, uint8_t *pbVRam, uint32_t cbVRam)
    710719{
    711720    if (VBoxVBVAExHSIsEnabled(pCmdVbva))
     
    715724    }
    716725
    717     pCmdVbva->pVBVA = pVBVA;
    718     pCmdVbva->pVBVA->hostFlags.u32HostEvents = 0;
     726    uintptr_t offVRam = (uintptr_t)pVBVA - (uintptr_t)pbVRam;
     727    AssertLogRelMsgReturn(offVRam < cbVRam - sizeof(*pVBVA), ("%#p cbVRam=%#x\n", offVRam, cbVRam), VERR_OUT_OF_RANGE);
     728
     729    pCmdVbva->pVBVA     = pVBVA;
     730    pCmdVbva->cbMaxData = cbVRam - offVRam - RT_UOFFSETOF(VBVABUFFER, au8Data);
     731    pVBVA->hostFlags.u32HostEvents = 0;
    719732    ASMAtomicWriteS32(&pCmdVbva->i32EnableState, VBVAEXHOSTCONTEXT_ESTATE_ENABLED);
    720733    return VINF_SUCCESS;
     
    15171530    }
    15181531
    1519 /** @todo r=bird: This needs a closer look! */
    15201532    VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pVdma->pHgsmi, u32Offset);
    15211533    if (!pVBVA)
     
    15251537    }
    15261538
    1527     int rc = VBoxVBVAExHSEnable(&pVdma->CmdVbva, pVBVA);
     1539    int rc = VBoxVBVAExHSEnable(&pVdma->CmdVbva, pVBVA, pVdma->pVGAState->vram_ptrR3, pVdma->pVGAState->vram_size);
    15281540    if (RT_SUCCESS(rc))
    15291541    {
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