- Timestamp:
- Aug 7, 2019 12:48:58 AM (5 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r80149 r80168 60 60 #define VIRTIOSCSI_REGION_PCI_CAP 2 61 61 62 /**63 * Definitions that follow are based on the VirtIO 1.0 specification.64 * Struct names are the same. The field names have been adapted to VirtualBox65 * data type + camel case annotation, with the original field name from the66 * VirtIO specification in the field's comment.67 */68 69 62 #define MATCH_SCSI_CONFIG(member) \ 70 63 ((int)uOffset >= RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member) \ … … 75 68 76 69 #define LOG_ACCESSOR(member) \ 77 LogFunc(("Guest %s %s [%d:%d]: %.*Rhxs\n", \ 78 fWrite ? "wrote" : "read ", #member, mOffset, mOffset + cb, cb, pv)); 70 virtioLogMappedIoValue(__FUNCTION__, #member, pv, cb, uMemberOffset, fWrite, false, 0); 79 71 80 72 #define SCSI_CONFIG_ACCESSOR(member) \ 81 73 { \ 82 uint32_t mOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \74 uint32_t uMemberOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \ 83 75 if (fWrite) \ 84 memcpy(((char *)&pThis->virtioScsiConfig.member) + u Offset, (const char *)pv, cb); \76 memcpy(((char *)&pThis->virtioScsiConfig.member) + uMemberOffset, (const char *)pv, cb); \ 85 77 else \ 86 memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + u Offset), cb); \78 memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + uMemberOffset), cb); \ 87 79 LOG_ACCESSOR(member); \ 88 80 } … … 90 82 #define SCSI_CONFIG_ACCESSOR_READONLY(member) \ 91 83 { \ 92 uint32_t mOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \84 uint32_t uMemberOffset = uOffset - RT_OFFSETOF(VIRTIO_SCSI_CONFIG_T, member); \ 93 85 if (fWrite) \ 94 86 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \ 95 87 else \ 96 88 { \ 97 memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + u Offset), cb); \89 memcpy((char *)pv, (const char *)(((char *)&pThis->virtioScsiConfig.member) + uMemberOffset), cb); \ 98 90 LOG_ACCESSOR(member); \ 99 91 } \ 100 92 } 101 93 94 /** 95 * Definitions that follow are based on the VirtIO 1.0 specification. 96 * Struct names are the same. The field names have been adapted to VirtualBox 97 * data type + camel case annotation, with the original field name from the 98 * VirtIO specification in the field's comment. 99 */ 102 100 103 101 /** @name VirtIO 1.0 SCSI Host feature bits … … 112 110 * Features VirtIO 1.0 Host SCSI controller offers guest driver 113 111 */ 114 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED VIRTIOSCSI_F_INOUT \ 115 | VIRTIOSCSI_F_HOTPLUG \ 116 | VIRTIOSCSI_F_CHANGE \ 117 | VIRTIOSCSI_F_T10_PI \ 112 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED \ 113 (VIRTIOSCSI_F_INOUT | VIRTIOSCSI_F_HOTPLUG | VIRTIOSCSI_F_CHANGE | VIRTIOSCSI_F_T10_PI) 118 114 119 115 typedef struct virtio_scsi_config … … 167 163 } VIRTIO_SCSI_REQ_CMD_T, *PVIRTIO_SCSI_REQ_CMD_T; 168 164 169 /** Command-specific response values */ 165 /** @name VirtIO 1.0 SCSI req command-specific response values 166 * @{ */ 170 167 #define VIRTIOSCSI_S_OK 0 /* control, command */ 171 168 #define VIRTIOSCSI_S_OVERRUN 1 /* control */ … … 179 176 #define VIRTIOSCSI_S_FAILURE 9 /* control, command */ 180 177 #define VIRTIOSCSI_S_INCORRECT_LUN 12 /* command */ 181 182 183 /** task_attr */ 178 /** @} */ 179 180 181 /** @name VirtIO 1.0 SCSI Command-specific task_attr values 182 * @{ */ 184 183 #define VIRTIOSCSI_S_SIMPLE 0 185 184 #define VIRTIOSCSI_S_ORDERED 1 186 185 #define VIRTIOSCSI_S_HEAD 2 187 186 #define VIRTIOSCSI_S_ACA 3 187 /** @} */ 188 188 189 189 #define VIRTIOSCSI_T_TMF 0 … … 208 208 } VIRTIO_SCSI_CTRL_BUF_T, *PVIRTIO_SCSI_CTRL_BUF_T; 209 209 210 /* command-specific response values */211 210 /** @name VirtIO 1.0 SCSI tmf control command-specific response values 211 * @{ */ 212 212 #define VIRTIOSCSI_S_FUNCTION_COMPLETE 0 213 213 #define VIRTIOSCSI_S_FUNCTION_SUCCEEDED 10 214 214 #define VIRTIOSCSI_S_FUNCTION_REJECTED 11 215 /** @} */ 215 216 216 217 #define VIRTIOSCSI_T_AN_QUERY 1 /** Asynchronous notification query */ … … 242 243 uint8_t response; /** response */ 243 244 } VIRTIO_SCSI_CTRL_T, *PVIRTIO_SCSI_CTRL_T; 245 244 246 245 247 #define VIRTIOSCSI_T_NO_EVENT 0 … … 758 760 } 759 761 760 static int virtioScsiR3C onfigAccess(PVIRTIOSCSI pThis, uint32_t uOffset,762 static int virtioScsiR3CfgAccessed(PVIRTIOSCSI pThis, uint32_t uOffset, 761 763 const void *pv, size_t cb, uint8_t fWrite) 762 764 { … … 825 827 * @param pDevIns The device instance. 826 828 * @param uOffset Offset within device specific capabilities struct 827 * @param pv Buffer in which to save read data829 * @param pv Buffer in which to save read data 828 830 * @param cb Number of bytes to read 829 831 */ … … 836 838 // uOffset, cb)); 837 839 838 rc = virtioScsiR3C onfigAccess(pThis, uOffset, pv, cb, false);840 rc = virtioScsiR3CfgAccessed(pThis, uOffset, pv, cb, false); 839 841 840 842 return rc; … … 847 849 * @param pDevIns The device instance. 848 850 * @param uOffset Offset within device specific capabilities struct 849 * @param pv Buffer in which to save read data851 * @param pv Buffer in which to save read data 850 852 * @param cb Number of bytes to write 851 853 */ … … 858 860 // uOffset, cb)); 859 861 860 rc = virtioScsiR3C onfigAccess(pThis, uOffset, pv, cb, true);862 rc = virtioScsiR3CfgAccessed(pThis, uOffset, pv, cb, true); 861 863 862 864 return rc; -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r80148 r80168 28 28 #include <VBox/vmm/pdmdev.h> 29 29 #include "Virtio_1_0.h" 30 #include "Virtio_1_0_impl.h" 30 31 31 32 #define INSTANCE(pState) pState->szInstance … … 35 36 # define QUEUENAME(s, q) (q->pcszName) 36 37 #endif 37 38 39 /**40 * Returns true if physical address and access length are within the mapped capability struct.41 *42 * Actual Parameters:43 * [IN] pPhysCapStruct - Pointer to MMIO mapped capability struct44 * [IN] pCfgCap - Pointer to capability in PCI configuration area45 * [OUT] fMatched - True if GCPhysAddr is within the physically mapped capability.46 *47 * Implied parameters:48 * [IN] GCPhysAddr - Physical address accessed (via MMIO callback)49 * [IN] cb - Number of bytes to access50 * [OUT] result - true or false51 *52 */53 #define MATCH_VIRTIO_CAP_STRUCT(pGcPhysCapData, pCfgCap, fMatched) \54 bool fMatched = false; \55 if (pGcPhysCapData && pCfgCap && GCPhysAddr >= (RTGCPHYS)pGcPhysCapData \56 && GCPhysAddr < ((RTGCPHYS)pGcPhysCapData + ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \57 && cb <= ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \58 fMatched = true;59 60 /**61 * This macro resolves to boolean true if uoff is within the specified member offset and length.62 *63 * Actual Parameters:64 * [IN] member - Member of VIRTIO_PCI_COMMON_CFG_T65 *66 * Implied Parameters:67 * [IN] uoff - Offset into VIRTIO_PCI_COMMON_CFG_T68 * [IN] cb - Number of bytes to access69 * [OUT] result - true or false70 */71 #define COMMON_CFG(member) \72 (uoff >= RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \73 && uoff < (uint32_t)(RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \74 + RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member)) \75 && cb <= RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member) \76 - (uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member)))77 78 #define LOG_ACCESSOR(member) \79 LogFunc(("Guest %s %s[%d:%d]: %.*Rhxs\n", \80 fWrite ? "wrote" : "read ", #member, foff, foff + cb, cb, pv));81 82 #define LOG_INDEXED_ACCESSOR(member, idx) \83 LogFunc(("Guest %s %s[%d][%d:%d]: %.*Rhxs\n", \84 fWrite ? "wrote" : "read ", #member, idx, foff, foff + cb, cb, pv));85 86 #define ACCESSOR(member) \87 { \88 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \89 if (fWrite) \90 memcpy(((char *)&pVirtio->member) + uoff, (const char *)pv, cb); \91 else \92 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \93 LOG_ACCESSOR(member); \94 }95 96 #define ACCESSOR_WITH_IDX(member, idx) \97 { \98 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \99 if (fWrite) \100 memcpy(((char *)(pVirtio->member + idx)) + uoff, (const char *)pv, cb); \101 else \102 memcpy((char *)pv, (const char *)(((char *)(pVirtio->member + idx)) + uoff), cb); \103 LOG_INDEXED_ACCESSOR(member, idx); \104 }105 106 #define ACCESSOR_READONLY(member) \107 { \108 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \109 if (fWrite) \110 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \111 else \112 { \113 memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \114 LOG_ACCESSOR(member); \115 } \116 }117 118 #define ACCESSOR_READONLY_WITH_IDX(member, idx) \119 { \120 uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \121 if (fWrite) \122 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \123 else \124 { \125 memcpy((char *)pv, ((char *)(pVirtio->member + idx)) + uoff, cb); \126 LOG_INDEXED_ACCESSOR(member, idx); \127 } \128 }129 130 131 #ifdef VBOX_DEVICE_STRUCT_TESTCASE132 # define virtioDumpState(x, s) do {} while (0)133 #else134 # ifdef DEBUG /* This still needs to be migrated to VirtIO 1.0 */135 __attribute__((unused))136 static void virtioDumpState(PVIRTIOSTATE pState, const char *pcszCaller)137 {138 RT_NOREF2(pState, pcszCaller);139 /* PK TODO, dump state features, selector, status, ISR, queue info (iterate),140 descriptors, avail, used, size, indices, address141 each by variable name on new line, indented slightly */142 }143 #endif144 145 38 146 39 void virtQueueReadDesc(PVIRTIOSTATE pState, PVIRTQUEUE pVirtQueue, uint32_t idx, PVIRTQUEUEDESC pDesc) … … 466 359 * @param pSSM The handle to the saved state. 467 360 */ 468 int virtioSaveExec(PVIRTIOSTATE pState, PSSMHANDLE pSSM) 469 { 470 RT_NOREF2(pState, pSSM); 361 int virtioSaveExec(PVIRTIOSTATE pVirtio, PSSMHANDLE pSSM) 362 { 471 363 int rc = VINF_SUCCESS; 472 // virtioDumpState(pState, "virtioSaveExec"); 364 virtioDumpState(pVirtio, "virtioSaveExec"); 365 RT_NOREF(pSSM); 473 366 /* 474 367 * PK TODO save guest features, queue selector, sttus ISR, … … 490 383 * @param uPass The data pass. 491 384 */ 492 int virtioLoadExec(PVIRTIOSTATE p State, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, uint32_t nQueues)493 { 494 RT_NOREF5(p State, pSSM, uVersion, uPass, nQueues);385 int virtioLoadExec(PVIRTIOSTATE pVirtio, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass, uint32_t nQueues) 386 { 387 RT_NOREF5(pVirtio, pSSM, uVersion, uPass, nQueues); 495 388 int rc = VINF_SUCCESS; 389 virtioDumpState(pVirtio, "virtioLoadExec"); 496 390 497 391 /* … … 503 397 { 504 398 } 505 506 // virtioDumpState(pState, "virtioLoadExec");507 508 399 return rc; 509 400 } … … 612 503 { 613 504 RT_NOREF(pVirtio); 614 LogFunc((" "));505 LogFunc(("\n")); 615 506 pVirtio->uDeviceStatus = 0; 616 507 } … … 626 517 * @param cb Number of bytes to read or write 627 518 */ 628 629 630 int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uoff, unsigned cb, void const *pv) 631 { 632 int rv = VINF_SUCCESS; 519 int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uOffset, unsigned cb, void const *pv) 520 { 521 int rc = VINF_SUCCESS; 633 522 uint64_t val; 634 523 if (COMMON_CFG(uDeviceFeatures)) … … 638 527 else /* Guest READ pCommonCfg->uDeviceFeatures */ 639 528 { 640 uint32_t foff = uoff- RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatures);529 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatures); 641 530 switch(pVirtio->uDeviceFeaturesSelect) 642 531 { … … 644 533 val = pVirtio->uDeviceFeatures & 0xffffffff; 645 534 memcpy((void *)pv, (const void *)&val, cb); 646 LogFunc(("Guest read uDeviceFeatures(LO)[%d:%d]: %.*Rhxs\n", 647 foff, foff + cb, cb, pv)); 535 LOG_ACCESSOR(uDeviceFeatures); 648 536 break; 649 537 case 1: 650 538 val = (pVirtio->uDeviceFeatures >> 32) & 0xffffffff; 539 uIntraOff += 4; 651 540 memcpy((void *)pv, (const void *)&val, cb); 652 LogFunc(("Guest read uDeviceFeatures(HI)[%d:%d]: %.*Rhxs\n", 653 foff, foff + cb, cb, pv)); 541 LOG_ACCESSOR(uDeviceFeatures); 654 542 break; 655 543 default: 656 Log (("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n",544 LogFunc(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n", 657 545 pVirtio->uDeviceFeaturesSelect)); 546 return VERR_ACCESS_DENIED; 658 547 } 659 548 } … … 663 552 if (fWrite) /* Guest WRITE pCommonCfg->udriverFeatures */ 664 553 { 665 uint32_t foff = uoff- RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);554 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures); 666 555 switch(pVirtio->uDriverFeaturesSelect) 667 556 { 668 557 case 0: 669 558 memcpy(&pVirtio->uDriverFeatures, pv, cb); 670 LogFunc(("Guest wrote uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n", 671 foff, foff + cb, cb, pv)); 559 LOG_ACCESSOR(uDriverFeatures); 672 560 break; 673 561 case 1: 674 562 memcpy(((char *)&pVirtio->uDriverFeatures) + sizeof(uint32_t), pv, cb); 675 LogFunc(("Guest wrote uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n",676 foff, foff + cb, cb, pv));563 uIntraOff += 4; 564 LOG_ACCESSOR(uDriverFeatures); 677 565 break; 566 default: 567 LogFunc(("Guest wrote uDriverFeatures with out of range selector (%d), returning 0\n", 568 pVirtio->uDriverFeaturesSelect)); 569 return VERR_ACCESS_DENIED; 678 570 } 679 571 } 680 572 else /* Guest READ pCommonCfg->udriverFeatures */ 681 573 { 682 uint32_t foff = uoff- RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);574 uint32_t uIntraOff = uOffset - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures); 683 575 switch(pVirtio->uDriverFeaturesSelect) 684 576 { … … 686 578 val = pVirtio->uDriverFeatures & 0xffffffff; 687 579 memcpy((void *)pv, (const void *)&val, cb); 688 LogFunc(("Guest read uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n", 689 foff, foff + cb, cb, pv)); 580 LOG_ACCESSOR(uDriverFeatures); 690 581 break; 691 582 case 1: 692 583 val = (pVirtio->uDriverFeatures >> 32) & 0xffffffff; 584 uIntraOff += 4; 693 585 memcpy((void *)pv, (const void *)&val, cb); 694 LogFunc(("Guest read uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n", 695 foff, foff + cb, cb, pv)); 586 LOG_ACCESSOR(uDriverFeatures); 696 587 break; 697 588 default: 698 Log (("Guest read uDriverFeatures with out of range selector (%d), returning 0\n",589 LogFunc(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n", 699 590 pVirtio->uDriverFeaturesSelect)); 591 return VERR_ACCESS_DENIED; 700 592 } 701 593 } … … 704 596 { 705 597 if (fWrite) 706 Log(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n")); 598 { 599 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n")); 600 return VERR_ACCESS_DENIED; 601 } 707 602 else 708 603 { 604 uint32_t uIntraOff = 0; 709 605 *(uint16_t *)pv = MAX_QUEUES; 710 L og(("Guest read 0x%x from pVirtio->uNumQueues\n", MAX_QUEUES));606 LOG_ACCESSOR(uNumQueues); 711 607 } 712 608 } … … 716 612 { 717 613 pVirtio->uDeviceStatus = *(uint8_t *)pv; 718 LogFunc(("Driver wrote uDeviceStatus:\n")); 719 logDeviceStatus(pVirtio->uDeviceStatus); 614 LogFunc(("Guest wrote uDeviceStatus ................ (")); 615 virtioLogDeviceStatus(pVirtio->uDeviceStatus); 616 Log((")\n")); 720 617 if (pVirtio->uDeviceStatus == 0) 721 618 virtioResetDevice(pVirtio); … … 723 620 else /* Guest READ pCommonCfg->uDeviceStatus */ 724 621 { 725 LogFunc((" Driver read uDeviceStatus:\n"));622 LogFunc(("Guest read uDeviceStatus ................ (")); 726 623 *(uint32_t *)pv = pVirtio->uDeviceStatus; 727 logDeviceStatus(pVirtio->uDeviceStatus); 624 virtioLogDeviceStatus(pVirtio->uDeviceStatus); 625 Log((")\n")); 728 626 } 729 627 } … … 778 676 else 779 677 { 780 LogFunc(("Bad access by guest to virtio_pci_common_cfg: u off=%d, cb=%d\n", uoff, cb));781 r v= VERR_ACCESS_DENIED;782 } 783 return r v;678 LogFunc(("Bad access by guest to virtio_pci_common_cfg: uOffset=%d, cb=%d\n", uOffset, cb)); 679 rc = VERR_ACCESS_DENIED; 680 } 681 return rc; 784 682 } 785 683 … … 1153 1051 #endif 1154 1052 1155 #define CFGADDR2IDX(addr) ((uint64_t)addr - (uint64_t)&pVirtio->dev.abConfig)1156 1053 1157 1054 /* The following capability mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CFG_CAP_T) … … 1161 1058 * therefore does not contribute to the capabilities region (BAR) the other capabilities use. 1162 1059 */ 1060 #define CFGADDR2IDX(addr) ((uint64_t)addr - (uint64_t)&pVirtio->dev.abConfig) 1061 1163 1062 PVIRTIO_PCI_CAP_T pCfg; 1164 1063 … … 1251 1150 #endif /* IN_RING3 */ 1252 1151 1253 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */1254 -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r80148 r80168 73 73 #define VIRTIO_MSI_NO_VECTOR 0xffff 74 74 75 typedef DECLCALLBACK(uint32_t) FNGETHOSTFEATURES(void *pvState);76 typedef FNGETHOSTFEATURES *PFNGETHOSTFEATURES;77 78 79 75 /** Most of the following definitions attempt to adhere to the names and 80 76 * and forms used by the VirtIO 1.0 specification to increase the maintainability … … 440 436 void vringSetNotification( PVIRTIOSTATE pVirtio, PVIRTQUEUE pVirtQueue, bool fEnabled); 441 437 442 DECLINLINE(void) logDeviceStatus(uint8_t status)443 {444 if (status & VIRTIO_STATUS_ACKNOWLEDGE)445 Log((" ACKNOWLEDGE\n"));446 if (status & VIRTIO_STATUS_DRIVER)447 Log((" DRIVER\n"));448 if (status & VIRTIO_STATUS_DRIVER_OK)449 Log((" DRIVER_OK\n"));450 if (status & VIRTIO_STATUS_FEATURES_OK)451 Log((" FEATURES_OK\n"));452 if (status & VIRTIO_STATUS_FAILED)453 Log((" FAILED\n"));454 if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET)455 Log((" ACKNOWLEDGE\n"));456 if (status == 0)457 Log((" RESET\n"));458 Log(("\n"));459 }460 438 461 439 /* FROM Virtio 1.0 SPEC, NYI … … 477 455 */ 478 456 457 458 459 /** 460 * Formats the logging of a memory-mapped I/O input or output value 461 * 462 * @param pszFunc - To avoid displaying this function's name via __FUNCTION__ or LogFunc() 463 * @param pszMember - Name of struct member 464 * @param pv - pointer to value 465 * @param cb - size of value 466 * @param uOffset - offset into member where value starts 467 * @param fWrite - True if write I/O 468 * @param fHasIndex - True if the member is indexed 469 * @param idx - The index if fHasIndex 470 */ 471 DECLINLINE(void) virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, const void *pv, uint32_t cb, 472 uint32_t uOffset, bool fWrite, bool fHasIndex, uint32_t idx) 473 { 474 475 #define FMTHEX(fmtout, v, cNybs) \ 476 fmtout[cNybs] = '\0'; \ 477 for (uint8_t i = 0; i < cNybs; i++) \ 478 fmtout[(cNybs - i) -1] = "0123456789abcdef"[(val >> (i * 4)) & 0xf]; 479 480 #define MAX_STRING 64 481 char pszIdx[MAX_STRING] = { 0 }; 482 char pszDepiction[MAX_STRING] = { 0 }; 483 char pszFormattedVal[MAX_STRING] = { 0 }; 484 if (fHasIndex) 485 RTStrPrintf(pszIdx, sizeof(pszIdx), "[%d]", idx); 486 if (cb == 1 || cb == 2 || cb == 4 || cb == 8) 487 { 488 /* manually padding with 0's instead of \b due to different impl of %x precision than printf() */ 489 uint64_t val = 0; 490 memcpy((char *)&val, pv, cb); 491 FMTHEX(pszFormattedVal, val, cb * 2); 492 RTStrPrintf(pszDepiction, sizeof(pszDepiction), "%s%s[%d:%d]", pszMember, pszIdx, uOffset, uOffset + cb); 493 RTStrPrintf(pszDepiction, sizeof(pszDepiction), "%-30s", pszDepiction); 494 int first = 0; 495 for (uint8_t i = 0; i < sizeof(pszDepiction); i++) 496 if (pszDepiction[i] == ' ' && first++ != 0) 497 pszDepiction[i] = '.'; 498 Log(("%s: Guest %s %s 0x%s\n", \ 499 pszFunc, fWrite ? "wrote" : "read ", pszDepiction, pszFormattedVal)); 500 } 501 else /* odd number or oversized access, ... log inline hex-dump style */ 502 { 503 Log(("%s: Guest %s %s%s[%d:%d]: %.*Rhxs\n", \ 504 pszFunc, fWrite ? "wrote" : "read ", pszMember, 505 pszIdx, uOffset, uOffset + cb, cb, pv)); 506 } 507 } 508 509 typedef DECLCALLBACK(uint32_t) FNGETHOSTFEATURES(void *pvState); 510 typedef FNGETHOSTFEATURES *PFNGETHOSTFEATURES; 511 479 512 DECLINLINE(uint16_t) vringReadAvail(PVIRTIOSTATE pState, PVIRTQUEUE pVirtQueue) 480 513 {
Note:
See TracChangeset
for help on using the changeset viewer.