Changeset 39890 in vbox for trunk/src/VBox/Devices/VMMDev
- Timestamp:
- Jan 26, 2012 7:42:19 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 75940
- Location:
- trunk/src/VBox/Devices/VMMDev
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r39882 r39890 87 87 88 88 /** The saved state version. */ 89 #define VMMDEV_SAVED_STATE_VERSION 14 89 #define VMMDEV_SAVED_STATE_VERSION 15 90 /** The saved state version which is missing the guest facility statuses. */ 91 #define VMMDEV_SAVED_STATE_VERSION_MISSING_FACILITY_STATUSES 14 90 92 /** The saved state version which is missing the guestInfo2 bits. */ 91 #define VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2 1393 #define VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2 13 92 94 /** The saved state version used by VirtualBox 3.0. 93 95 * This doesn't have the config part. */ 94 #define VMMDEV_SAVED_STATE_VERSION_VBOX_30 1196 #define VMMDEV_SAVED_STATE_VERSION_VBOX_30 11 95 97 96 98 … … 532 534 533 535 pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, uFullVersion, pszName, pInfo2->additionsRevision, pInfo2->additionsFeatures); 536 537 return VINF_SUCCESS; 538 } 539 540 /** 541 * Allocates a new facility status entry, initializing it to inactive. 542 * 543 * @returns Pointer to a facility status entry on success, NULL on failure 544 * (table full). 545 * @param pThis The VMMDev instance data. 546 * @param uFacility The facility type code - VBoxGuestFacilityType. 547 * @param fFixed This is set when allocating the standard entries 548 * from the constructor. 549 * @param pTimeSpecNow Optionally giving the entry timestamp to use (ctor). 550 */ 551 static PVMMDEVFACILITYSTATUSENTRY 552 vmmdevAllocFacilityStatusEntry(VMMDevState *pThis, uint32_t uFacility, bool fFixed, PCRTTIMESPEC pTimeSpecNow) 553 { 554 /* If full, expunge one inactive entry. */ 555 if (pThis->cFacilityStatuses == RT_ELEMENTS(pThis->aFacilityStatuses)) 556 { 557 uint32_t i = pThis->cFacilityStatuses; 558 while (i-- > 0) 559 { 560 if ( pThis->aFacilityStatuses[i].uStatus == VBoxGuestFacilityStatus_Inactive 561 && !pThis->aFacilityStatuses[i].fFixed) 562 { 563 pThis->cFacilityStatuses--; 564 int cToMove = pThis->cFacilityStatuses - i; 565 if (cToMove) 566 memmove(&pThis->aFacilityStatuses[i], &pThis->aFacilityStatuses[i + 1], 567 cToMove * sizeof(pThis->aFacilityStatuses[i])); 568 RT_ZERO(pThis->aFacilityStatuses[pThis->cFacilityStatuses]); 569 break; 570 } 571 } 572 573 if (pThis->cFacilityStatuses == RT_ELEMENTS(pThis->aFacilityStatuses)) 574 return NULL; 575 } 576 577 /* Find location in array (it's sorted). */ 578 uint32_t i = pThis->cFacilityStatuses; 579 while (i-- > 0) 580 if (pThis->aFacilityStatuses[i].uFacility < uFacility) 581 break; 582 i++; 583 584 /* Move. */ 585 int cToMove = pThis->cFacilityStatuses - i; 586 if (cToMove > 0) 587 memmove(&pThis->aFacilityStatuses[i + 1], &pThis->aFacilityStatuses[i], 588 cToMove * sizeof(pThis->aFacilityStatuses[i])); 589 pThis->cFacilityStatuses++; 590 591 /* Initialize. */ 592 pThis->aFacilityStatuses[i].uFacility = uFacility; 593 pThis->aFacilityStatuses[i].uStatus = VBoxGuestFacilityStatus_Inactive; 594 pThis->aFacilityStatuses[i].fFixed = fFixed; 595 pThis->aFacilityStatuses[i].fPadding = 0; 596 pThis->aFacilityStatuses[i].fFlags = 0; 597 pThis->aFacilityStatuses[i].uPadding = 0; 598 if (pTimeSpecNow) 599 pThis->aFacilityStatuses[i].TimeSpecTS = *pTimeSpecNow; 600 else 601 RTTimeSpecSetNano(&pThis->aFacilityStatuses[i].TimeSpecTS, 0); 602 603 return &pThis->aFacilityStatuses[i]; 604 605 } 606 607 /** 608 * Gets a facility status entry, allocating a new one if not already present. 609 * 610 * @returns Pointer to a facility status entry on success, NULL on failure 611 * (table full). 612 * @param pThis The VMMDev instance data. 613 * @param uFacility The facility type code - VBoxGuestFacilityType. 614 */ 615 static PVMMDEVFACILITYSTATUSENTRY vmmdevGetFacilityStatusEntry(VMMDevState *pThis, uint32_t uFacility) 616 { 617 /** @todo change to binary search. */ 618 uint32_t i = pThis->cFacilityStatuses; 619 while (i-- > 0) 620 { 621 if (pThis->aFacilityStatuses[i].uFacility == uFacility) 622 return &pThis->aFacilityStatuses[i]; 623 if (pThis->aFacilityStatuses[i].uFacility < uFacility) 624 break; 625 } 626 return vmmdevAllocFacilityStatusEntry(pThis, uFacility, false /*fFixed*/, NULL); 627 } 628 629 /** 630 * Handles VMMDevReq_ReportGuestStatus. 631 * 632 * @returns VBox status code that the guest should see. 633 * @param pThis The VMMDev instance data. 634 * @param pRequestHeader The header of the request to handle. 635 */ 636 static int vmmdevReqHandler_ReportGuestStatus(VMMDevState *pThis, VMMDevRequestHeader *pRequestHeader) 637 { 638 /* 639 * Validate input. 640 */ 641 AssertMsgReturn(pRequestHeader->size == sizeof(VMMDevReportGuestStatus), ("%u\n", pRequestHeader->size), VERR_INVALID_PARAMETER); 642 VBoxGuestStatus *pStatus = &((VMMDevReportGuestStatus *)pRequestHeader)->guestStatus; 643 AssertMsgReturn( pStatus->facility > VBoxGuestFacilityType_Unknown 644 && pStatus->facility <= VBoxGuestFacilityType_All, 645 ("%d\n", pStatus->facility), 646 VERR_INVALID_PARAMETER); 647 AssertMsgReturn(pStatus->status == (VBoxGuestFacilityStatus)(uint16_t)pStatus->status, 648 ("%#x (%u)\n", pStatus->status, pStatus->status), 649 VERR_OUT_OF_RANGE); 650 651 /* 652 * Do the update. 653 */ 654 RTTIMESPEC Now; 655 RTTimeNow(&Now); 656 if (pStatus->facility == VBoxGuestFacilityType_All) 657 { 658 uint32_t i = pThis->cFacilityStatuses; 659 while (i-- > 0) 660 { 661 pThis->aFacilityStatuses[i].TimeSpecTS = Now; 662 pThis->aFacilityStatuses[i].uStatus = (uint16_t)pStatus->status; 663 pThis->aFacilityStatuses[i].fFlags = pStatus->flags; 664 } 665 } 666 else 667 { 668 PVMMDEVFACILITYSTATUSENTRY pEntry = vmmdevGetFacilityStatusEntry(pThis, pStatus->facility); 669 if (!pEntry) 670 { 671 static int g_cLogEntries = 0; 672 if (g_cLogEntries++ < 10) 673 LogRel(("VMM: Facility table is full - facility=%u status=%u.\n", pStatus->facility, pStatus->status)); 674 return VERR_OUT_OF_RESOURCES; 675 } 676 677 pEntry->TimeSpecTS = Now; 678 pEntry->uStatus = (uint16_t)pStatus->status; 679 pEntry->fFlags = pStatus->flags; 680 } 681 682 if (pThis->pDrv) 683 pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, pStatus->facility, pStatus->status, pStatus->flags, &Now); 534 684 535 685 return VINF_SUCCESS; … … 727 877 728 878 case VMMDevReq_ReportGuestStatus: 729 { 730 if (pRequestHeader->size != sizeof(VMMDevReportGuestStatus)) 731 { 732 AssertMsgFailed(("VMMDev guest status structure has an invalid size!\n")); 733 pRequestHeader->rc = VERR_INVALID_PARAMETER; 734 } 735 else 736 { 737 /** @todo r=bird: VMMDev (or GuestImpl.cpp) needs to remember this stuff and 738 * tell Main after a state restore! */ 739 VBoxGuestStatus *guestStatus = &((VMMDevReportGuestStatus*)pRequestHeader)->guestStatus; 740 pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, guestStatus); 741 742 pRequestHeader->rc = VINF_SUCCESS; 743 } 744 break; 745 } 879 pRequestHeader->rc = vmmdevReqHandler_ReportGuestStatus(pThis, pRequestHeader); 880 break; 746 881 747 882 /* Report guest capabilities */ … … 2719 2854 SSMR3PutU32(pSSM, pThis->guestInfo2.fFeatures); 2720 2855 SSMR3PutStrZ(pSSM, pThis->guestInfo2.szName); 2856 SSMR3PutU32(pSSM, pThis->cFacilityStatuses); 2857 for (uint32_t i = 0; i < pThis->cFacilityStatuses; i++) 2858 { 2859 SSMR3PutU32(pSSM, pThis->aFacilityStatuses[i].uFacility); 2860 SSMR3PutU32(pSSM, pThis->aFacilityStatuses[i].fFlags); 2861 SSMR3PutU16(pSSM, pThis->aFacilityStatuses[i].uStatus); 2862 SSMR3PutS64(pSSM, RTTimeSpecGetNano(&pThis->aFacilityStatuses[i].TimeSpecTS)); 2863 } 2721 2864 2722 2865 return VINF_SUCCESS; … … 2812 2955 } 2813 2956 2957 if (uVersion > VMMDEV_SAVED_STATE_VERSION_MISSING_FACILITY_STATUSES) 2958 { 2959 uint32_t cFacilityStatuses; 2960 rc = SSMR3GetU32(pSSM, &cFacilityStatuses); 2961 AssertRCReturn(rc, rc); 2962 2963 for (uint32_t i = 0; i < cFacilityStatuses; i++) 2964 { 2965 uint32_t uFacility, fFlags; 2966 uint16_t uStatus; 2967 int64_t iTimeStampNano; 2968 2969 SSMR3GetU32(pSSM, &uFacility); 2970 SSMR3GetU32(pSSM, &fFlags); 2971 SSMR3GetU16(pSSM, &uStatus); 2972 rc = SSMR3GetS64(pSSM, &iTimeStampNano); 2973 AssertRCReturn(rc, rc); 2974 2975 PVMMDEVFACILITYSTATUSENTRY pEntry = vmmdevGetFacilityStatusEntry(pThis, uFacility); 2976 AssertLogRelMsgReturn(pEntry, 2977 ("VMMDev: Ran out of entries restoring the guest facility statuses. Saved state has %u.\n", cFacilityStatuses), 2978 VERR_OUT_OF_RESOURCES); 2979 pEntry->uStatus = uStatus; 2980 pEntry->fFlags = fFlags; 2981 RTTimeSpecSetNano(&pEntry->TimeSpecTS, iTimeStampNano); 2982 } 2983 } 2984 2985 2814 2986 /* 2815 2987 * On a resume, we send the capabilities changed message so … … 2848 3020 pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo); 2849 3021 } 3022 3023 for (uint32_t i = 0; i < pThis->cFacilityStatuses; i++) /* ascending order! */ 3024 if ( pThis->aFacilityStatuses[i].uStatus != VBoxGuestFacilityStatus_Inactive 3025 || !pThis->aFacilityStatuses[i].fFixed) 3026 pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, 3027 pThis->aFacilityStatuses[i].uFacility, 3028 pThis->aFacilityStatuses[i].uStatus, 3029 pThis->aFacilityStatuses[i].fFlags, 3030 &pThis->aFacilityStatuses[i].TimeSpecTS); 2850 3031 } 2851 3032 if (pThis->pDrv) … … 2938 3119 pThis->fu32AdditionsOk = false; 2939 3120 memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo)); 3121 RT_ZERO(pThis->guestInfo2); 3122 3123 /* Clear facilities. No need to tell Main as it will get a 3124 pfnUpdateGuestInfo callback. */ 3125 RTTIMESPEC TimeStampNow; 3126 RTTimeNow(&TimeStampNow); 3127 uint32_t iFacility = pThis->cFacilityStatuses; 3128 while (iFacility-- > 0) 3129 { 3130 pThis->aFacilityStatuses[iFacility].uStatus = VBoxGuestFacilityStatus_Inactive; 3131 pThis->aFacilityStatuses[iFacility].TimeSpecTS = TimeStampNow; 3132 } 2940 3133 2941 3134 /* clear pending display change request. */ … … 3056 3249 /* interrupt on pin 0 */ 3057 3250 PCIDevSetInterruptPin(&pThis->dev, 0x01); 3251 3252 RTTIMESPEC TimeStampNow; 3253 RTTimeNow(&TimeStampNow); 3254 vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxGuestDriver, true /*fFixed*/, &TimeStampNow); 3255 vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxService, true /*fFixed*/, &TimeStampNow); 3256 vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxTrayClient, true /*fFixed*/, &TimeStampNow); 3257 vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_Seamless, true /*fFixed*/, &TimeStampNow); 3258 vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_Graphics, true /*fFixed*/, &TimeStampNow); 3259 Assert(pThis->cFacilityStatuses == 5); 3058 3260 3059 3261 /* -
trunk/src/VBox/Devices/VMMDev/VMMDevState.h
r39882 r39890 79 79 } Judge; 80 80 } VMMDEVCREDS; 81 82 83 /** 84 * Facility status entry. 85 */ 86 typedef struct VMMDEVFACILITYSTATUSENTRY 87 { 88 /** The facility, see VBoxGuestFacilityType. */ 89 uint32_t uFacility; 90 /** The status, see VBoxGuestFacilityStatus. */ 91 uint16_t uStatus; 92 /** Whether this entry is fixed and cannot be reused when inactive. */ 93 bool fFixed; 94 /** Explicit alignment padding / reserved for future use. MBZ. */ 95 bool fPadding; 96 /** The facility flags (yet to be defined). */ 97 uint32_t fFlags; 98 /** Explicit alignment padding / reserved for future use. MBZ. */ 99 uint32_t uPadding; 100 /** Last update timestamp. */ 101 RTTIMESPEC TimeSpecTS; 102 } VMMDEVFACILITYSTATUSENTRY; 103 /** Pointer to a facility status entry. */ 104 typedef VMMDEVFACILITYSTATUSENTRY *PVMMDEVFACILITYSTATUSENTRY; 81 105 82 106 … … 170 194 uint32_t uRevision; 171 195 uint32_t fFeatures; 172 uint32_t uPadding;173 196 char szName[128]; 174 197 } guestInfo2; 198 199 /** Array of guest facility statuses. */ 200 VMMDEVFACILITYSTATUSENTRY aFacilityStatuses[32]; 201 /** The number of valid entries in the facility status array. */ 202 uint32_t cFacilityStatuses; 175 203 176 204 /** Information reported by guest via VMMDevReportGuestCapabilities. */ … … 320 348 AssertCompileMemberAlignment(VMMDevState, cbGuestRAM, 8); 321 349 AssertCompileMemberAlignment(VMMDevState, enmCpuHotPlugEvent, 4); 350 AssertCompileMemberAlignment(VMMDevState, aFacilityStatuses, 8); 322 351 #ifndef VBOX_WITHOUT_TESTING_FEATURES 323 352 AssertCompileMemberAlignment(VMMDevState, TestingData.Value.u64Value, 8);
Note:
See TracChangeset
for help on using the changeset viewer.