Changeset 64655 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Nov 14, 2016 10:46:07 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 111904
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r64596 r64655 228 228 /* 7 */ { "write reserved bits of MSR", "", VINF_CPUM_R3_MSR_WRITE }, 229 229 /* 8 */ { "write an invalid value to MSR", "", VINF_CPUM_R3_MSR_WRITE }, 230 /* 9 */ { "write MSR", "disallowed by configuration", VINF_CPUM_R3_MSR_WRITE } 230 /* 9 */ { "write MSR", "disallowed by configuration", VINF_CPUM_R3_MSR_WRITE }, 231 /* 10 */ { "read MSR", "disallowed by configuration", VINF_CPUM_R3_MSR_READ } 231 232 }; 232 233 AssertCompile(RT_ELEMENTS(s_aAccess) == APICMSRACCESS_COUNT); … … 1858 1859 1859 1860 /** 1860 * @interface_method_impl{PDMAPICREG,pfnReadMsrR3} 1861 */ 1862 APICBOTHCBDECL(VBOXSTRICTRC) apicReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value) 1861 * Reads an APIC MSR. 1862 * 1863 * @returns Strict VBox status code. 1864 * @param pVCpu The cross context virtual CPU structure. 1865 * @param u32Reg The MSR being read. 1866 * @param pu64Value Where to store the read value. 1867 */ 1868 VMM_INT_DECL(VBOXSTRICTRC) APICReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value) 1863 1869 { 1864 1870 /* … … 1868 1874 Assert(u32Reg >= MSR_IA32_X2APIC_ID && u32Reg <= MSR_IA32_X2APIC_SELF_IPI); 1869 1875 Assert(pu64Value); 1870 RT_NOREF_PV(pDevIns); 1871 1876 1877 /* 1878 * Is the APIC enabled? 1879 */ 1872 1880 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 1881 if (apicIsEnabled(pVCpu)) 1882 { /* likely */ } 1883 else 1884 { 1885 return apicMsrAccessError(pVCpu, u32Reg, pApic->enmMaxMode == PDMAPICMODE_NONE ? 1886 APICMSRACCESS_READ_DISALLOWED_CONFIG : APICMSRACCESS_READ_RSVD_OR_UNKNOWN); 1887 } 1888 1873 1889 #ifndef IN_RING3 1874 1890 if (pApic->fRZEnabled) … … 1962 1978 1963 1979 /** 1964 * @interface_method_impl{PDMAPICREG,pfnWriteMsrR3} 1965 */ 1966 APICBOTHCBDECL(VBOXSTRICTRC) apicWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value) 1980 * Writes an APIC MSR. 1981 * 1982 * @returns Strict VBox status code. 1983 * @param pVCpu The cross context virtual CPU structure. 1984 * @param u32Reg The MSR being written. 1985 * @param pu64Value The value to write. 1986 */ 1987 VMM_INT_DECL(VBOXSTRICTRC) APICWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value) 1967 1988 { 1968 1989 /* … … 1971 1992 VMCPU_ASSERT_EMT(pVCpu); 1972 1993 Assert(u32Reg >= MSR_IA32_X2APIC_ID && u32Reg <= MSR_IA32_X2APIC_SELF_IPI); 1973 RT_NOREF_PV(pDevIns); 1974 1994 1995 /* 1996 * Is the APIC enabled? 1997 */ 1975 1998 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 1999 if (apicIsEnabled(pVCpu)) 2000 { /* likely */ } 2001 else 2002 { 2003 return apicMsrAccessError(pVCpu, u32Reg, pApic->enmMaxMode == PDMAPICMODE_NONE ? 2004 APICMSRACCESS_WRITE_DISALLOWED_CONFIG : APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN); 2005 } 2006 1976 2007 #ifndef IN_RING3 1977 2008 if (pApic->fRZEnabled) … … 2123 2154 2124 2155 /** 2125 * @interface_method_impl{PDMAPICREG,pfnSetBaseMsrR3} 2126 */ 2127 APICBOTHCBDECL(VBOXSTRICTRC) apicSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64BaseMsr) 2156 * Sets the APIC base MSR. 2157 * 2158 * @returns Strict VBox status code. 2159 * @param pVCpu The cross context virtual CPU structure. 2160 * @param u64BaseMsr The value to set. 2161 */ 2162 VMM_INT_DECL(VBOXSTRICTRC) APICSetBaseMsr(PVMCPU pVCpu, uint64_t u64BaseMsr) 2128 2163 { 2129 2164 Assert(pVCpu); 2130 NOREF(pDevIns);2131 2165 2132 2166 #ifdef IN_RING3 … … 2255 2289 2256 2290 #else /* !IN_RING3 */ 2257 RT_NOREF_PV(pDevIns);2258 2291 RT_NOREF_PV(pVCpu); 2259 2292 RT_NOREF_PV(u64BaseMsr); … … 2264 2297 2265 2298 /** 2266 * @interface_method_impl{PDMAPICREG,pfnGetBaseMsrR3} 2267 */ 2268 APICBOTHCBDECL(uint64_t) apicGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu) 2269 { 2270 RT_NOREF_PV(pDevIns); 2299 * Gets the APIC base MSR (no checks are performed wrt APIC hardware or its 2300 * state). 2301 * 2302 * @returns The base MSR value. 2303 * @param pVCpu The cross context virtual CPU structure. 2304 */ 2305 VMM_INT_DECL(uint64_t) APICGetBaseMsrNoCheck(PVMCPU pVCpu) 2306 { 2271 2307 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 2272 2273 2308 PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu); 2274 2309 return pApicCpu->uApicBaseMsr; … … 2277 2312 2278 2313 /** 2279 * @interface_method_impl{PDMAPICREG,pfnSetTprR3} 2280 */ 2281 APICBOTHCBDECL(void) apicSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr) 2282 { 2283 RT_NOREF_PV(pDevIns); 2284 apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */); 2314 * Gets the APIC base MSR. 2315 * 2316 * @returns Strict VBox status code. 2317 * @param pVCpu The cross context virtual CPU structure. 2318 * @param pu64Value Where to store the MSR value. 2319 */ 2320 VMM_INT_DECL(VBOXSTRICTRC) APICGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Value) 2321 { 2322 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 2323 2324 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 2325 if (pApic->enmMaxMode != PDMAPICMODE_NONE) 2326 { 2327 *pu64Value = APICGetBaseMsrNoCheck(pVCpu); 2328 return VINF_SUCCESS; 2329 } 2330 2331 #ifdef IN_RING3 2332 LogRelMax(5, ("APIC%u: Reading APIC base MSR (%#x) when there is no APIC -> #GP(0)\n", pVCpu->idCpu, MSR_IA32_APICBASE)); 2333 return VERR_CPUM_RAISE_GP_0; 2334 #else 2335 return VINF_CPUM_R3_MSR_WRITE; 2336 #endif 2337 } 2338 2339 2340 /** 2341 * Sets the TPR (Task Priority Register). 2342 * 2343 * @returns VBox status code. 2344 * @param pVCpu The cross context virtual CPU structure. 2345 * @param u8Tpr The TPR value to set. 2346 */ 2347 VMMDECL(int) APICSetTpr(PVMCPU pVCpu, uint8_t u8Tpr) 2348 { 2349 if (apicIsEnabled(pVCpu)) 2350 return VBOXSTRICTRC_VAL(apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */)); 2351 return VERR_PDM_NO_APIC_INSTANCE; 2285 2352 } 2286 2353 … … 2310 2377 2311 2378 /** 2312 * @interface_method_impl{PDMAPICREG,pfnGetTprR3} 2313 */ 2314 APICBOTHCBDECL(uint8_t) apicGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr) 2315 { 2316 RT_NOREF_PV(pDevIns); 2379 * Gets the APIC TPR (Task Priority Register). 2380 * 2381 * @returns VBox status code. 2382 * @param pVCpu The cross context virtual CPU structure. 2383 * @param pu8Tpr Where to store the TPR. 2384 * @param pfPending Where to store whether there is a pending interrupt 2385 * (optional, can be NULL). 2386 * @param pu8PendingIntr Where to store the highest-priority pending 2387 * interrupt (optional, can be NULL). 2388 */ 2389 VMMDECL(int) APICGetTpr(PVMCPU pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr) 2390 { 2317 2391 VMCPU_ASSERT_EMT(pVCpu); 2318 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu); 2319 2320 if (pfPending) 2321 { 2322 /* 2323 * Just return whatever the highest pending interrupt is in the IRR. 2324 * The caller is responsible for figuring out if it's masked by the TPR etc. 2325 */ 2326 *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr); 2327 } 2328 2329 return pXApicPage->tpr.u8Tpr; 2330 } 2331 2332 2333 /** 2334 * @interface_method_impl{PDMAPICREG,pfnGetTimerFreqR3} 2335 */ 2336 APICBOTHCBDECL(uint64_t) apicGetTimerFreq(PPDMDEVINS pDevIns) 2337 { 2338 PVM pVM = PDMDevHlpGetVM(pDevIns); 2339 PVMCPU pVCpu = &pVM->aCpus[0]; 2340 PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu); 2341 uint64_t uTimer = TMTimerGetFreq(pApicCpu->CTX_SUFF(pTimer)); 2342 return uTimer; 2343 } 2344 2345 2346 /** 2347 * @interface_method_impl{PDMAPICREG,pfnBusDeliverR3} 2348 * @remarks This is a private interface between the IOAPIC and the APIC. 2349 */ 2350 APICBOTHCBDECL(int) apicBusDeliver(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector, 2351 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc) 2392 if (apicIsEnabled(pVCpu)) 2393 { 2394 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu); 2395 if (pfPending) 2396 { 2397 /* 2398 * Just return whatever the highest pending interrupt is in the IRR. 2399 * The caller is responsible for figuring out if it's masked by the TPR etc. 2400 */ 2401 *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr); 2402 } 2403 2404 *pu8Tpr = pXApicPage->tpr.u8Tpr; 2405 return VINF_SUCCESS; 2406 } 2407 2408 *pu8Tpr = 0; 2409 return VERR_PDM_NO_APIC_INSTANCE; 2410 } 2411 2412 2413 /** 2414 * Gets the APIC timer frequency. 2415 * 2416 * @returns Strict VBox status code. 2417 * @param 2418 */ 2419 VMM_INT_DECL(int) APICGetTimerFreq(PVM pVM, uint64_t *pu64Value) 2420 { 2421 /* 2422 * Validate. 2423 */ 2424 Assert(pVM); 2425 AssertPtrReturn(pu64Value, VERR_INVALID_PARAMETER); 2426 2427 PVMCPU pVCpu = &pVM->aCpus[0]; 2428 if (apicIsEnabled(pVCpu)) 2429 { 2430 PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu); 2431 *pu64Value = TMTimerGetFreq(pApicCpu->CTX_SUFF(pTimer)); 2432 return VINF_SUCCESS; 2433 } 2434 return VERR_PDM_NO_APIC_INSTANCE; 2435 } 2436 2437 2438 /** 2439 * Delivers an interrupt message via the system bus. 2440 * 2441 * @returns VBox status code. 2442 * @param pVM The cross context VM structure. 2443 * @param uDest The destination mask. 2444 * @param uDestMode The destination mode. 2445 * @param uDeliveryMode The delivery mode. 2446 * @param uVector The interrupt vector. 2447 * @param uPolarity The interrupt line polarity. 2448 * @param uTriggerMode The trigger mode. 2449 * @param uTagSrc The interrupt tag (debugging). 2450 */ 2451 VMM_INT_DECL(int) APICBusDeliver(PVM pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector, 2452 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc) 2352 2453 { 2353 2454 NOREF(uPolarity); 2354 2455 NOREF(uTagSrc); 2355 PVM pVM = PDMDevHlpGetVM(pDevIns); 2456 2457 /* 2458 * If the APIC isn't enabled, do nothing and pretend success. 2459 */ 2460 if (apicIsEnabled(&pVM->aCpus[0])) 2461 { /* likely */ } 2462 else 2463 return VINF_SUCCESS; 2356 2464 2357 2465 /* … … 2382 2490 2383 2491 /** 2384 * @interface_method_impl{PDMAPICREG,pfnLocalInterruptR3} 2385 * @remarks This is a private interface between the PIC and the APIC. 2386 */ 2387 APICBOTHCBDECL(VBOXSTRICTRC) apicLocalInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ) 2388 { 2389 NOREF(pDevIns); 2492 * Assert/de-assert the local APIC's LINT0/LINT1 interrupt pins. 2493 * 2494 * @returns Strict VBox status code. 2495 * @param pVCpu The cross context virtual CPU structure. 2496 * @param u8Pin The interrupt pin (0 for LINT0 or 1 for LINT1). 2497 * @param u8Level The level (0 for low or 1 for high). 2498 * @param rcRZ The return code if the operation cannot be performed in 2499 * the current context. 2500 */ 2501 VMM_INT_DECL(VBOXSTRICTRC) APICLocalInterrupt(PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ) 2502 { 2390 2503 AssertReturn(u8Pin <= 1, VERR_INVALID_PARAMETER); 2391 2504 AssertReturn(u8Level <= 1, VERR_INVALID_PARAMETER); … … 2544 2657 2545 2658 /** 2546 * @interface_method_impl{PDMAPICREG,pfnGetInterruptR3} 2547 */ 2548 APICBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc) 2549 { 2550 RT_NOREF_PV(pDevIns); 2659 * Gets the next highest-priority interrupt from the APIC, marking it as an 2660 * "in-service" interrupt. 2661 * 2662 * @returns VBox status code. 2663 * @param pVCpu The cross context virtual CPU structure. 2664 * @param pu8Vector Where to store the vector. 2665 * @param pu32TagSrc The source tag (debugging). 2666 */ 2667 VMM_INT_DECL(int) APICGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc) 2668 { 2551 2669 VMCPU_ASSERT_EMT(pVCpu); 2552 2670 Assert(pu8Vector); … … 2905 3023 * interrupt shadow etc.) 2906 3024 */ 2907 VMM DECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr)3025 VMM_INT_DECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr) 2908 3026 { 2909 3027 VMCPU_ASSERT_EMT(pVCpu); … … 2937 3055 * in-service. 2938 3056 */ 2939 VMM DECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr)3057 VMM_INT_DECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr) 2940 3058 { 2941 3059 VMCPU_ASSERT_EMT(pVCpu); … … 3044 3162 * interrupt is pending. 3045 3163 */ 3046 VMM DECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)3164 VMM_INT_DECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr) 3047 3165 { 3048 3166 VMCPU_ASSERT_EMT(pVCpu); -
trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
r62606 r64655 22 22 #define LOG_GROUP LOG_GROUP_CPUM 23 23 #include <VBox/vmm/cpum.h> 24 #include <VBox/vmm/ pdmapi.h>24 #include <VBox/vmm/apic.h> 25 25 #include <VBox/vmm/hm.h> 26 26 #include <VBox/vmm/tm.h> … … 217 217 { 218 218 RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange); 219 return PDMApicGetBaseMsr(pVCpu, puValue, false /* fIgnoreErrors */);219 return APICGetBaseMsr(pVCpu, puValue); 220 220 } 221 221 … … 225 225 { 226 226 RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange); RT_NOREF_PV(uValue); RT_NOREF_PV(uRawValue); 227 return PDMApicSetBaseMsr(pVCpu, uValue);227 return APICSetBaseMsr(pVCpu, uValue); 228 228 } 229 229 … … 1215 1215 { 1216 1216 RT_NOREF_PV(pRange); 1217 return PDMApicReadMsr(pVCpu, idMsr, puValue);1217 return APICReadMsr(pVCpu, idMsr, puValue); 1218 1218 } 1219 1219 … … 1223 1223 { 1224 1224 RT_NOREF_PV(pRange); RT_NOREF_PV(uRawValue); 1225 return PDMApicWriteMsr(pVCpu, idMsr, uValue);1225 return APICWriteMsr(pVCpu, idMsr, uValue); 1226 1226 } 1227 1227 -
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r62601 r64655 24 24 #include <VBox/vmm/patm.h> 25 25 #include <VBox/vmm/dbgf.h> 26 #include <VBox/vmm/ pdm.h>26 #include <VBox/vmm/apic.h> 27 27 #include <VBox/vmm/pgm.h> 28 28 #include <VBox/vmm/mm.h> … … 1059 1059 { 1060 1060 uint8_t u8Tpr; 1061 int rc = PDMApicGetTPR(pVCpu, &u8Tpr, NULL /* pfPending */, NULL /* pu8PendingIrq */);1061 int rc = APICGetTpr(pVCpu, &u8Tpr, NULL /* pfPending */, NULL /* pu8PendingIrq */); 1062 1062 if (RT_FAILURE(rc)) 1063 1063 { … … 1066 1066 return rc; 1067 1067 } 1068 *pValue = u8Tpr >> 4; /* bits 7-4 contain the task priority that go in cr8, bits 3-0 */1068 *pValue = u8Tpr >> 4; /* bits 7-4 contain the task priority that go in cr8, bits 3-0 */ 1069 1069 break; 1070 1070 } -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r63560 r64655 3250 3250 3251 3251 case DISCREG_CR8: 3252 return PDMApicSetTPR(pVCpu, val << 4); /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */3252 return APICSetTpr(pVCpu, val << 4); /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */ 3253 3253 3254 3254 default: -
trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
r63651 r64655 560 560 case MSR_GIM_HV_APIC_FREQ: 561 561 { 562 int rc = PDMApicGetTimerFreq(pVM, puValue);562 int rc = APICGetTimerFreq(pVM, puValue); 563 563 if (RT_FAILURE(rc)) 564 564 return VERR_CPUM_RAISE_GP_0; -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r64545 r64655 96 96 #include <VBox/vmm/iem.h> 97 97 #include <VBox/vmm/cpum.h> 98 #include <VBox/vmm/apic.h> 98 99 #include <VBox/vmm/pdm.h> 99 100 #include <VBox/vmm/pgm.h> -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r64033 r64655 4958 4958 { 4959 4959 uint8_t uTpr; 4960 int rc = PDMApicGetTPR(pVCpu, &uTpr, NULL, NULL);4960 int rc = APICGetTpr(pVCpu, &uTpr, NULL, NULL); 4961 4961 if (RT_SUCCESS(rc)) 4962 4962 crX = uTpr >> 4; … … 5271 5271 5272 5272 if (!IEM_FULL_VERIFICATION_ENABLED(pVCpu)) 5273 PDMApicSetTPR(pVCpu, (uint8_t)uNewCrX << 4);5273 APICSetTpr(pVCpu, (uint8_t)uNewCrX << 4); 5274 5274 rcStrict = VINF_SUCCESS; 5275 5275 break; -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r64626 r64655 62 62 { 63 63 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC); 64 Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));65 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));66 64 uint32_t uTagSrc; 67 65 uint8_t uVector; 68 rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns),pVCpu, &uVector, &uTagSrc);66 rc = APICGetInterrupt(pVCpu, &uVector, &uTagSrc); 69 67 if (RT_SUCCESS(rc)) 70 68 { … … 260 258 261 259 /** 262 * Returns the presence of a Local APIC.263 *264 * @returns VBox true if a Local APIC is present.265 * @param pVM The cross context VM structure.266 */267 VMM_INT_DECL(bool) PDMHasApic(PVM pVM)268 {269 return pVM->pdm.s.Apic.CTX_SUFF(pDevIns) != NULL;270 }271 272 273 /**274 * Set the APIC base.275 *276 * @returns Strict VBox status code.277 * @param pVCpu The cross context virtual CPU structure.278 * @param u64Base The new base.279 */280 VMMDECL(VBOXSTRICTRC) PDMApicSetBaseMsr(PVMCPU pVCpu, uint64_t u64Base)281 {282 PVM pVM = pVCpu->CTX_SUFF(pVM);283 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))284 {285 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr));286 VBOXSTRICTRC rcStrict = pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u64Base);287 288 /* Update CPUM's copy of the APIC base. */289 PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);290 Assert(pCtx);291 pCtx->msrApicBase = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu);292 293 return rcStrict;294 }295 296 #ifdef IN_RING3297 LogRelMax(5, ("PDM: APIC%U: Writing APIC base MSR (%#x) invalid since there isn't an APIC -> #GP(0)\n", pVCpu->idCpu,298 MSR_IA32_APICBASE));299 return VERR_CPUM_RAISE_GP_0;300 #else301 return VINF_CPUM_R3_MSR_WRITE;302 #endif303 }304 305 306 /**307 * Get the APIC base MSR from the APIC device.308 *309 * @returns Strict VBox status code.310 * @param pVCpu The cross context virtual CPU structure.311 * @param pu64Base Where to store the APIC base.312 * @param fIgnoreErrors Whether to ignore errors (i.e. not a real guest MSR313 * access).314 */315 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors)316 {317 PVM pVM = pVCpu->CTX_SUFF(pVM);318 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))319 {320 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr));321 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);322 *pu64Base = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu);323 return VINF_SUCCESS;324 }325 326 *pu64Base = 0;327 if (fIgnoreErrors)328 return VINF_SUCCESS;329 330 #ifdef IN_RING3331 LogRelMax(5, ("PDM: APIC%u: Reading APIC base MSR (%#x) invalid without an APIC instance -> #GP(0)\n", pVCpu->idCpu,332 MSR_IA32_APICBASE));333 return VERR_CPUM_RAISE_GP_0;334 #else335 return VINF_CPUM_R3_MSR_WRITE;336 #endif337 }338 339 340 /**341 * Set the TPR (Task Priority Register).342 *343 * @returns VBox status code.344 * @param pVCpu The cross context virtual CPU structure.345 * @param u8TPR The new TPR.346 */347 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)348 {349 PVM pVM = pVCpu->CTX_SUFF(pVM);350 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))351 {352 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr));353 pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR);354 return VINF_SUCCESS;355 }356 return VERR_PDM_NO_APIC_INSTANCE;357 }358 359 360 /**361 * Get the TPR (Task Priority Register).362 *363 * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.364 * @param pVCpu The cross context virtual CPU structure.365 * @param pu8TPR Where to store the TRP.366 * @param pfPending Where to store whether there is a pending interrupt367 * (out, optional).368 * @param pu8PendingIntr Where to store the highest-priority pending369 * interrupt (out, optional).370 *371 * @remarks No-long-jump zone!!!372 */373 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr)374 {375 PVM pVM = pVCpu->CTX_SUFF(pVM);376 PPDMDEVINS pApicIns = pVM->pdm.s.Apic.CTX_SUFF(pDevIns);377 if (pApicIns)378 {379 /*380 * Note! We don't acquire the PDM lock here as we're just reading381 * information. Doing so causes massive contention as this382 * function is called very often by each and every VCPU.383 */384 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr));385 *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu, pfPending, pu8PendingIntr);386 return VINF_SUCCESS;387 }388 *pu8TPR = 0;389 return VERR_PDM_NO_APIC_INSTANCE;390 }391 392 393 /**394 * Write a MSR in APIC range.395 *396 * @returns Strict VBox status code.397 * @param pVCpu The cross context virtual CPU structure.398 * @param u32Reg MSR to write.399 * @param u64Value Value to write.400 */401 VMM_INT_DECL(VBOXSTRICTRC) PDMApicWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)402 {403 PVM pVM = pVCpu->CTX_SUFF(pVM);404 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))405 {406 AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMsr));407 return pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u32Reg, u64Value);408 }409 return VERR_CPUM_RAISE_GP_0;410 }411 412 413 /**414 * Read a MSR in APIC range.415 *416 * @returns Strict VBox status code.417 * @param pVCpu The cross context virtual CPU structure.418 * @param u32Reg MSR to read.419 * @param pu64Value Where to store the value read.420 */421 VMM_INT_DECL(VBOXSTRICTRC) PDMApicReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)422 {423 PVM pVM = pVCpu->CTX_SUFF(pVM);424 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))425 {426 AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMsr));427 return pVM->pdm.s.Apic.CTX_SUFF(pfnReadMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u32Reg, pu64Value);428 }429 return VERR_CPUM_RAISE_GP_0;430 }431 432 433 /**434 * Gets the frequency of the APIC timer.435 *436 * @returns VBox status code.437 * @param pVM The cross context VM structure.438 * @param pu64Value Where to store the frequency.439 */440 VMM_INT_DECL(int) PDMApicGetTimerFreq(PVM pVM, uint64_t *pu64Value)441 {442 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))443 {444 AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTimerFreq));445 *pu64Value = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTimerFreq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));446 return VINF_SUCCESS;447 }448 return VERR_PDM_NO_APIC_INSTANCE;449 }450 451 452 /**453 260 * Locks PDM. 454 261 * This might call back to Ring-3 in order to deal with lock contention in GC and R3.
Note:
See TracChangeset
for help on using the changeset viewer.