Changeset 70602 in vbox
- Timestamp:
- Jan 16, 2018 5:04:30 PM (7 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
r70600 r70602 105 105 { 106 106 VBVABUFFER *pVBVA; 107 uint32_t cbMaxData; /**< Maximum number of data bytes addressible relative to pVBVA. */ 107 108 volatile int32_t i32State; 108 109 volatile int32_t i32EnableState; … … 184 185 typedef struct VBOXVDMAHOST 185 186 { 186 PHGSMIINSTANCE pHgsmi; 187 PHGSMIINSTANCE pHgsmi; /**< Same as VGASTATE::pHgsmi. */ 187 188 PVGASTATE pVGAState; 188 189 #ifdef VBOX_WITH_CRHGSMI … … 386 387 { 387 388 case VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE: 388 {389 389 VBoxVBVAExHPPause(pCmdVbva); 390 390 VBoxVBVAExHPDataCompleteCtl(pCmdVbva, pCtl, VINF_SUCCESS); 391 391 return true; 392 } 392 393 393 case VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME: 394 {395 394 VBoxVBVAExHPResume(pCmdVbva); 396 395 VBoxVBVAExHPDataCompleteCtl(pCmdVbva, pCtl, VINF_SUCCESS); 397 396 return true; 398 } 397 399 398 default: 400 399 return false; … … 434 433 /** 435 434 * Worker for vboxVBVAExHPDataGet. 435 * 436 * @retval VINF_SUCCESS 437 * @retval VINF_EOF 438 * @retval VINF_TRY_AGAIN 439 * @retval VERR_INVALID_STATE 440 * 436 441 * @thread VDMA 437 * @todo r=bird: revalidate this code. 438 */ 439 static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd) 442 */ 443 static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppbCmd, uint32_t *pcbCmd) 440 444 { 441 445 Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING); 442 446 Assert(pCmdVbva->i32EnableState > VBVAEXHOSTCONTEXT_ESTATE_PAUSED); 443 447 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. */ 475 468 Assert(cbRecord); 476 469 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 */ 496 496 static void VBoxVBVAExHPDataCompleteCmd(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint32_t cbCmd) 497 497 { 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)); 502 511 } 503 512 … … 707 716 * @thread VDMA 708 717 */ 709 static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA )718 static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA, uint8_t *pbVRam, uint32_t cbVRam) 710 719 { 711 720 if (VBoxVBVAExHSIsEnabled(pCmdVbva)) … … 715 724 } 716 725 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; 719 732 ASMAtomicWriteS32(&pCmdVbva->i32EnableState, VBVAEXHOSTCONTEXT_ESTATE_ENABLED); 720 733 return VINF_SUCCESS; … … 1517 1530 } 1518 1531 1519 /** @todo r=bird: This needs a closer look! */1520 1532 VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pVdma->pHgsmi, u32Offset); 1521 1533 if (!pVBVA) … … 1525 1537 } 1526 1538 1527 int rc = VBoxVBVAExHSEnable(&pVdma->CmdVbva, pVBVA );1539 int rc = VBoxVBVAExHSEnable(&pVdma->CmdVbva, pVBVA, pVdma->pVGAState->vram_ptrR3, pVdma->pVGAState->vram_size); 1528 1540 if (RT_SUCCESS(rc)) 1529 1541 {
Note:
See TracChangeset
for help on using the changeset viewer.

