Changeset 84123 in vbox
- Timestamp:
- May 1, 2020 8:43:46 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 137713
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp
r84117 r84123 1793 1793 struct 1794 1794 { 1795 uint32_t u4Rsvd0 : 4; /**< Bits 3:0 - Reserved. */ 1796 uint32_t u15Ptr : 15; /**< Bits 18:4 - Buffer pointer. */ 1797 uint32_t u13Rsvd0 : 13; /**< Bits 31:19 - Reserved. */ 1795 uint32_t off; /**< Bits 31:0 - Buffer pointer (offset; 16 byte aligned, 512 KB max). */ 1798 1796 uint32_t u32Rsvd0; /**< Bits 63:32 - Reserved. */ 1799 1797 } n; … … 2097 2095 /** @} */ 2098 2096 2097 /** @name Internal Book keeping. 2098 * @{ */ 2099 uint32_t cbCmdBufUsed; /**< Size of commands pending in the command buffer. */ 2100 uint32_t cbEvtLogUsed; /**< Size of entries pending in the event log buffer. */ 2101 /** @} */ 2102 2099 2103 /** @name MMIO: Command and Event Status register. 2100 2104 * @{ */ … … 2227 2231 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 2228 2232 /** 2229 * Gets the number of buffer entries given a base register's encodedlength.2233 * Gets the maximum number of buffer entries for the given buffer length. 2230 2234 * 2231 2235 * @returns Number of buffer entries. 2232 2236 * @param uEncodedLen The length (power-of-2 encoded). 2233 2237 */ 2234 DECLINLINE(uint32_t) iommuAmdGetB aseBufEntryCount(uint8_t uEncodedLen)2238 DECLINLINE(uint32_t) iommuAmdGetBufMaxEntries(uint8_t uEncodedLen) 2235 2239 { 2236 2240 Assert(uEncodedLen > 7); … … 2240 2244 2241 2245 /** 2242 * Gets the length of the buffer given a base register's encoded length.2246 * Gets the total length of the buffer given a base register's encoded length. 2243 2247 * 2244 2248 * @returns The length of the buffer in bytes. 2245 2249 * @param uEncodedLen The length (power-of-2 encoded). 2246 2250 */ 2247 DECLINLINE(uint32_t) iommuAmdGetB aseBufLength(uint8_t uEncodedLen)2251 DECLINLINE(uint32_t) iommuAmdGetBufLength(uint8_t uEncodedLen) 2248 2252 { 2249 2253 Assert(uEncodedLen > 7); … … 2474 2478 { 2475 2479 ASMAtomicOrU64(&pThis->Status.u64, IOMMU_STATUS_CMD_BUF_RUNNING); 2480 2476 2481 /* If the command buffer isn't empty, kick the command thread to start processing commands. */ 2477 if (pThis->CmdBuf HeadPtr.n.u15Ptr != pThis->CmdBufTailPtr.n.u15Ptr)2482 if (pThis->CmdBufTailPtr.n.off != pThis->CmdBufHeadPtr.n.off) 2478 2483 PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtCmdThread); 2479 2484 } … … 2721 2726 uint32_t const offBuf = u64Value & IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK; 2722 2727 CMD_BUF_BAR_T const CmdBufBar = pThis->CmdBufBaseAddr; 2723 uint32_t const cbBuf = iommuAmdGetBaseBufLength(CmdBufBar.n.u4Len); 2728 uint32_t const cbBuf = iommuAmdGetBufLength(CmdBufBar.n.u4Len); 2729 Assert(cbBuf <= _512K); 2724 2730 if (offBuf >= cbBuf) 2725 2731 { … … 2729 2735 } 2730 2736 2731 pThis->CmdBufHeadPtr. u64= offBuf;2737 pThis->CmdBufHeadPtr.au32[0] = offBuf; 2732 2738 LogFlow((IOMMU_LOG_PFX ": Set CmdBufHeadPtr to %#RX32\n", offBuf)); 2733 2739 return VINF_SUCCESS; … … 2743 2749 2744 2750 /* 2745 * IOMMU behavior is undefined when software advances this register equal or beyond its head pointer.2751 * IOMMU behavior is undefined when software writes a value outside the buffer length. 2746 2752 * In our emulation, we ignore the write entirely. 2747 2753 * See AMD IOMMU spec. 3.3.13 "Command and Event Log Pointer Registers". 2748 2754 */ 2749 2755 uint32_t const offBufTail = u64Value & IOMMU_CMD_BUF_HEAD_PTR_VALID_MASK; 2750 NOREF(offBufTail); 2751 NOREF(pThis); 2756 CMD_BUF_BAR_T const CmdBufBar = pThis->CmdBufBaseAddr; 2757 uint32_t const cbBuf = iommuAmdGetBufLength(CmdBufBar.n.u4Len); 2758 if (offBufTail >= cbBuf) 2759 { 2760 Log((IOMMU_LOG_PFX ": Setting CmdBufTailPtr (%#RX32) to a value that exceeds buffer length (%#RX32) -> Ignored\n", 2761 offBufTail, cbBuf)); 2762 return VINF_SUCCESS; 2763 } 2764 2765 pThis->CmdBufTailPtr.au32[0] = offBufTail; 2766 LogFlow((IOMMU_LOG_PFX ": Set CmdBufTailPtr to %#RX32\n", offBufTail)); 2752 2767 return VINF_SUCCESS; 2753 2768 } … … 3170 3185 && !Status.n.u1EvtOverflow) 3171 3186 { 3172 /* Figure out the event log entry offset. */ 3173 EVT_LOG_TAIL_PTR_T const TailPtr = pThis->EvtLogTailPtr; 3174 uint32_t const offEvtLogEntry = TailPtr.n.u15Ptr << 4; 3175 3176 /* Ensure the event log entry is within limits. */ 3177 uint32_t const uEvtLogLen = iommuAmdGetBaseBufLength(pThis->EvtLogBaseAddr.n.u4Len); 3178 if (offEvtLogEntry < uEvtLogLen) 3187 uint32_t const cbEvt = sizeof(*pEvent); 3188 3189 /* Get the offset we need to write the event to in memory (circular buffer offset). */ 3190 uint32_t const offEvt = pThis->EvtLogTailPtr.n.off; 3191 Assert(!(offEvt & ~IOMMU_CMD_BUF_TAIL_PTR_VALID_MASK)); 3192 3193 /* Ensure we have space in the event log. */ 3194 uint32_t const cbEvtLog = iommuAmdGetBufLength(pThis->EvtLogBaseAddr.n.u4Len); 3195 uint32_t const cbUsed = pThis->cbEvtLogUsed; 3196 if (cbUsed + cbEvt < cbEvtLog) 3179 3197 { 3180 3198 /* Write the event log entry to memory. */ 3181 3199 RTGCPHYS const GCPhysEvtLog = pThis->EvtLogBaseAddr.n.u40Base << X86_PAGE_4K_SHIFT; 3182 RTGCPHYS const GCPhysEvtLogEntry = GCPhysEvtLog + offEvt LogEntry;3183 int rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhysEvtLogEntry, pEvent, sizeof(*pEvent));3200 RTGCPHYS const GCPhysEvtLogEntry = GCPhysEvtLog + offEvt; 3201 int rc = PDMDevHlpPCIPhysWrite(pDevIns, GCPhysEvtLogEntry, pEvent, cbEvt); 3184 3202 if (RT_FAILURE(rc)) 3185 3203 Log((IOMMU_LOG_PFX ": Failed to write event log entry at %#RGp. rc=%Rrc\n", GCPhysEvtLogEntry, rc)); 3186 3204 3187 3205 /* Increment the event log tail pointer. */ 3188 pThis->EvtLogTailPtr.n.u15Ptr += sizeof(*pEvent); 3206 pThis->EvtLogTailPtr.n.off = (offEvt + cbEvt) % cbEvtLog; 3207 3208 /* Increment the size of entries pending in the event log. */ 3209 pThis->cbEvtLogUsed += cbEvt; 3189 3210 3190 3211 /* Indicate that an event log entry was written. */ … … 3611 3632 CMD_BUF_BAR_T const CmdBufBar = pThis->CmdBufBaseAddr; 3612 3633 uint8_t const uEncodedLen = CmdBufBar.n.u4Len; 3613 uint32_t const cEntries = iommuAmdGetB aseBufEntryCount(uEncodedLen);3614 uint32_t const cbBuffer = iommuAmdGetB aseBufLength(uEncodedLen);3634 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 3635 uint32_t const cbBuffer = iommuAmdGetBufLength(uEncodedLen); 3615 3636 pHlp->pfnPrintf(pHlp, " Command buffer BAR = %#RX64\n", CmdBufBar.u64); 3616 3637 if (fVerbose) … … 3625 3646 EVT_LOG_BAR_T const EvtLogBar = pThis->EvtLogBaseAddr; 3626 3647 uint8_t const uEncodedLen = EvtLogBar.n.u4Len; 3627 uint32_t const cEntries = iommuAmdGetB aseBufEntryCount(uEncodedLen);3628 uint32_t const cbBuffer = iommuAmdGetB aseBufLength(uEncodedLen);3648 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 3649 uint32_t const cbBuffer = iommuAmdGetBufLength(uEncodedLen); 3629 3650 pHlp->pfnPrintf(pHlp, " Event log BAR = %#RX64\n", EvtLogBar.u64); 3630 3651 if (fVerbose) … … 3747 3768 PPR_LOG_BAR_T PprLogBar = pThis->PprLogBaseAddr; 3748 3769 uint8_t const uEncodedLen = PprLogBar.n.u4Len; 3749 uint32_t const cEntries = iommuAmdGetB aseBufEntryCount(uEncodedLen);3750 uint32_t const cbBuffer = iommuAmdGetB aseBufLength(uEncodedLen);3770 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 3771 uint32_t const cbBuffer = iommuAmdGetBufLength(uEncodedLen); 3751 3772 pHlp->pfnPrintf(pHlp, " PPR Log BAR = %#RX64\n", PprLogBar.u64); 3752 3773 if (fVerbose) … … 3783 3804 GALOG_BAR_T const GALogBar = pThis->GALogBaseAddr; 3784 3805 uint8_t const uEncodedLen = GALogBar.n.u4Len; 3785 uint32_t const cEntries = iommuAmdGetB aseBufEntryCount(uEncodedLen);3786 uint32_t const cbBuffer = iommuAmdGetB aseBufLength(uEncodedLen);3806 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 3807 uint32_t const cbBuffer = iommuAmdGetBufLength(uEncodedLen); 3787 3808 pHlp->pfnPrintf(pHlp, " Guest Log BAR = %#RX64\n", GALogBar.u64); 3788 3809 if (fVerbose) … … 3804 3825 PPR_LOG_B_BAR_T PprLogBBar = pThis->PprLogBBaseAddr; 3805 3826 uint8_t const uEncodedLen = PprLogBBar.n.u4Len; 3806 uint32_t const cEntries = iommuAmdGetB aseBufEntryCount(uEncodedLen);3807 uint32_t const cbBuffer = iommuAmdGetB aseBufLength(uEncodedLen);3827 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 3828 uint32_t const cbBuffer = iommuAmdGetBufLength(uEncodedLen); 3808 3829 pHlp->pfnPrintf(pHlp, " PPR Log B BAR = %#RX64\n", PprLogBBar.u64); 3809 3830 if (fVerbose) … … 3818 3839 EVT_LOG_B_BAR_T EvtLogBBar = pThis->EvtLogBBaseAddr; 3819 3840 uint8_t const uEncodedLen = EvtLogBBar.n.u4Len; 3820 uint32_t const cEntries = iommuAmdGetB aseBufEntryCount(uEncodedLen);3821 uint32_t const cbBuffer = iommuAmdGetB aseBufLength(uEncodedLen);3841 uint32_t const cEntries = iommuAmdGetBufMaxEntries(uEncodedLen); 3842 uint32_t const cbBuffer = iommuAmdGetBufLength(uEncodedLen); 3822 3843 pHlp->pfnPrintf(pHlp, " Event Log B BAR = %#RX64\n", EvtLogBBar.u64); 3823 3844 if (fVerbose) … … 3996 4017 CMD_BUF_HEAD_PTR_T const CmdBufHeadPtr = pThis->CmdBufHeadPtr; 3997 4018 pHlp->pfnPrintf(pHlp, " Command Buffer Head Pointer = %#RX64\n", CmdBufHeadPtr.u64); 3998 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufHeadPtr.n. u15Ptr);4019 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufHeadPtr.n.off); 3999 4020 } 4000 4021 /* Command Buffer Tail Pointer Register. */ … … 4002 4023 CMD_BUF_HEAD_PTR_T const CmdBufTailPtr = pThis->CmdBufTailPtr; 4003 4024 pHlp->pfnPrintf(pHlp, " Command Buffer Tail Pointer = %#RX64\n", CmdBufTailPtr.u64); 4004 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufTailPtr.n. u15Ptr);4025 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", CmdBufTailPtr.n.off); 4005 4026 } 4006 4027 /* Event Log Head Pointer Register. */ … … 4008 4029 EVT_LOG_HEAD_PTR_T const EvtLogHeadPtr = pThis->EvtLogHeadPtr; 4009 4030 pHlp->pfnPrintf(pHlp, " Event Log Head Pointer = %#RX64\n", EvtLogHeadPtr.u64); 4010 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogHeadPtr.n. u15Ptr);4031 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogHeadPtr.n.off); 4011 4032 } 4012 4033 /* Event Log Tail Pointer Register. */ … … 4014 4035 EVT_LOG_TAIL_PTR_T const EvtLogTailPtr = pThis->EvtLogTailPtr; 4015 4036 pHlp->pfnPrintf(pHlp, " Event Log Head Pointer = %#RX64\n", EvtLogTailPtr.u64); 4016 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogTailPtr.n. u15Ptr);4037 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogTailPtr.n.off); 4017 4038 } 4018 4039 /* Status Register. */ … … 4044 4065 PPR_LOG_HEAD_PTR_T const PprLogHeadPtr = pThis->PprLogHeadPtr; 4045 4066 pHlp->pfnPrintf(pHlp, " PPR Log Head Pointer = %#RX64\n", PprLogHeadPtr.u64); 4046 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogHeadPtr.n. u15Ptr);4067 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogHeadPtr.n.off); 4047 4068 } 4048 4069 /* PPR Log Tail Pointer. */ … … 4050 4071 PPR_LOG_TAIL_PTR_T const PprLogTailPtr = pThis->PprLogTailPtr; 4051 4072 pHlp->pfnPrintf(pHlp, " PPR Log Tail Pointer = %#RX64\n", PprLogTailPtr.u64); 4052 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogTailPtr.n. u15Ptr);4073 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogTailPtr.n.off); 4053 4074 } 4054 4075 /* Guest Virtual-APIC Log Head Pointer. */ … … 4068 4089 PPR_LOG_B_HEAD_PTR_T const PprLogBHeadPtr = pThis->PprLogBHeadPtr; 4069 4090 pHlp->pfnPrintf(pHlp, " PPR Log B Head Pointer = %#RX64\n", PprLogBHeadPtr.u64); 4070 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBHeadPtr.n. u15Ptr);4091 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBHeadPtr.n.off); 4071 4092 } 4072 4093 /* PPR Log B Tail Pointer. */ … … 4074 4095 PPR_LOG_B_TAIL_PTR_T const PprLogBTailPtr = pThis->PprLogBTailPtr; 4075 4096 pHlp->pfnPrintf(pHlp, " PPR Log B Tail Pointer = %#RX64\n", PprLogBTailPtr.u64); 4076 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBTailPtr.n. u15Ptr);4097 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", PprLogBTailPtr.n.off); 4077 4098 } 4078 4099 /* Event Log B Head Pointer. */ … … 4080 4101 EVT_LOG_B_HEAD_PTR_T const EvtLogBHeadPtr = pThis->EvtLogBHeadPtr; 4081 4102 pHlp->pfnPrintf(pHlp, " Event Log B Head Pointer = %#RX64\n", EvtLogBHeadPtr.u64); 4082 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBHeadPtr.n. u15Ptr);4103 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBHeadPtr.n.off); 4083 4104 } 4084 4105 /* Event Log B Tail Pointer. */ … … 4086 4107 EVT_LOG_B_TAIL_PTR_T const EvtLogBTailPtr = pThis->EvtLogBTailPtr; 4087 4108 pHlp->pfnPrintf(pHlp, " Event Log B Tail Pointer = %#RX64\n", EvtLogBTailPtr.u64); 4088 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBTailPtr.n. u15Ptr);4109 pHlp->pfnPrintf(pHlp, " Pointer = %#x\n", EvtLogBTailPtr.n.off); 4089 4110 } 4090 4111 /* PPR Log Auto Response Register. */ … … 4207 4228 pThis->EvtLogHeadPtr.u64 = 0; 4208 4229 pThis->EvtLogTailPtr.u64 = 0; 4230 4231 pThis->cbCmdBufUsed = 0; 4232 pThis->cbEvtLogUsed = 0; 4209 4233 4210 4234 pThis->Status.u64 = 0;
Note:
See TracChangeset
for help on using the changeset viewer.