Changeset 100102 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jun 7, 2023 5:54:44 PM (20 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin-armv8.cpp
r100076 r100102 46 46 #include "NEMInternal.h" 47 47 #include <VBox/vmm/vmcc.h> 48 #include <VBox/vmm/vmm.h> 48 49 #include "dtrace/VBoxVMM.h" 49 50 … … 58 59 #include <iprt/system.h> 59 60 #include <iprt/utf16.h> 61 62 #include <iprt/formats/arm-psci.h> 60 63 61 64 #include <mach/mach_time.h> … … 603 606 pVM->nem.s.fCreatedVm = true; 604 607 pVM->nem.s.u64CntFrqHz = ASMReadCntFrqEl0(); 608 609 /* Will be initialized in NEMHCResumeCpuTickOnAll() before executing guest code. */ 610 pVM->nem.s.u64VTimerOff = 0; 611 605 612 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 606 613 Log(("NEM: Marked active!\n")); … … 640 647 "Call to hv_vcpu_create failed on vCPU %u: %#x (%Rrc)", idCpu, hrc, nemR3DarwinHvSts2Rc(hrc)); 641 648 642 /* Will be initialized in NEMHCResumeCpuTickOnAll() before executing guest code. */ 643 pVCpu->nem.s.u64VTimerOff = 0; 649 hrc = hv_vcpu_set_sys_reg(pVCpu->nem.s.hVCpu, HV_SYS_REG_MPIDR_EL1, idCpu); 650 if (hrc != HV_SUCCESS) 651 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 652 "Setting MPIDR_EL1 failed on vCPU %u: %#x (%Rrc)", idCpu, hrc, nemR3DarwinHvSts2Rc(hrc)); 644 653 645 654 if (idCpu == 0) … … 997 1006 RT_NOREF(pVM); 998 1007 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 999 /** @todo Raise exception to EL1 if PSCI not configured. */ 1000 /** @todo Need a generic mechanism here to pass this to, GIM maybe?. Always return -1 for now (PSCI). */ 1001 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, true /*f64BitReg*/, false /*fSignExtend*/, (uint64_t)-1); 1008 if (u16Imm == 0) 1009 { 1010 /** @todo Raise exception to EL1 if PSCI not configured. */ 1011 /** @todo Need a generic mechanism here to pass this to, GIM maybe?. */ 1012 uint32_t uFunId = pVCpu->cpum.GstCtx.aGRegs[ARMV8_AARCH64_REG_X0].w; 1013 bool fHvc64 = RT_BOOL(uFunId & ARM_SMCCC_FUNC_ID_64BIT); RT_NOREF(fHvc64); 1014 uint32_t uEntity = ARM_SMCCC_FUNC_ID_ENTITY_GET(uFunId); 1015 uint32_t uFunNum = ARM_SMCCC_FUNC_ID_NUM_GET(uFunId); 1016 if (uEntity == ARM_SMCCC_FUNC_ID_ENTITY_STD_SEC_SERVICE) 1017 { 1018 switch (uFunNum) 1019 { 1020 case ARM_PSCI_FUNC_ID_PSCI_VERSION: 1021 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, ARM_PSCI_FUNC_ID_PSCI_VERSION_SET(1, 2)); 1022 break; 1023 case ARM_PSCI_FUNC_ID_SYSTEM_OFF: 1024 rcStrict = VINF_EM_OFF; 1025 break; 1026 case ARM_PSCI_FUNC_ID_SYSTEM_RESET: 1027 rcStrict = VINF_EM_RESET; 1028 break; 1029 case ARM_PSCI_FUNC_ID_CPU_ON: 1030 { 1031 uint64_t u64TgtCpu = nemR3DarwinGetGReg(pVCpu, ARMV8_AARCH64_REG_X1); 1032 RTGCPHYS GCPhysExecAddr = nemR3DarwinGetGReg(pVCpu, ARMV8_AARCH64_REG_X2); 1033 uint64_t u64CtxId = nemR3DarwinGetGReg(pVCpu, ARMV8_AARCH64_REG_X3); 1034 VMMR3CpuOn(pVM, u64TgtCpu & 0xff, GCPhysExecAddr, u64CtxId); 1035 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, true /*f64BitReg*/, false /*fSignExtend*/, ARM_PSCI_STS_SUCCESS); 1036 break; 1037 } 1038 default: 1039 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, (uint64_t)ARM_PSCI_STS_NOT_SUPPORTED); 1040 } 1041 } 1042 else 1043 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, (uint64_t)ARM_PSCI_STS_NOT_SUPPORTED); 1044 } 1045 /** @todo What to do if immediate is != 0? */ 1002 1046 1003 1047 return rcStrict; … … 1042 1086 && !(pVCpu->cpum.GstCtx.CntvCtlEl0 & ARMV8_CNTV_CTL_EL0_AARCH64_IMASK)) 1043 1087 { 1044 uint64_t cTicksVTimer = ASMReadTSC() - pVCpu->nem.s.u64VTimerOff;1088 uint64_t cTicksVTimer = mach_absolute_time() - pVM->nem.s.u64VTimerOff; 1045 1089 1046 1090 /* Check whether it expired and start executing guest code. */ … … 1057 1101 * between CPU load when the guest is idle and performance). 1058 1102 */ 1059 if (cNanoSecsVTimerToExpire < 5* RT_NS_1MS)1103 if (cNanoSecsVTimerToExpire < 2 * RT_NS_1MS) 1060 1104 return VINF_SUCCESS; 1061 1105 1062 1106 LogFlowFunc(("Set vTimer activation to cNanoSecsVTimerToExpire=%#RX64 (CntvCValEl0=%#RX64, u64VTimerOff=%#RX64 cTicksVTimer=%#RX64 u64CntFrqHz=%#RX64)\n", 1063 cNanoSecsVTimerToExpire, pVCpu->cpum.GstCtx.CntvCValEl0, pV Cpu->nem.s.u64VTimerOff, cTicksVTimer, pVM->nem.s.u64CntFrqHz));1107 cNanoSecsVTimerToExpire, pVCpu->cpum.GstCtx.CntvCValEl0, pVM->nem.s.u64VTimerOff, cTicksVTimer, pVM->nem.s.u64CntFrqHz)); 1064 1108 TMCpuSetVTimerNextActivation(pVCpu, cNanoSecsVTimerToExpire); 1065 1109 } … … 1240 1284 if (pVCpu->nem.s.fVTimerOffUpdate) 1241 1285 { 1242 /* 1243 * Program the new offset, first get the new TSC value with the old vTimer offset and then adjust the 1244 * the new offset to let the guest not notice the pause. 1245 */ 1246 uint64_t u64TscNew = mach_absolute_time() - pVCpu->nem.s.u64VTimerOff; 1247 Assert(u64TscNew >= pVM->nem.s.u64VTimerValuePaused); 1248 LogFlowFunc(("u64VTimerOffOld=%#RX64 u64TscNew=%#RX64 u64VTimerValuePaused=%#RX64 -> u64VTimerOff=%#RX64\n", 1249 pVCpu->nem.s.u64VTimerOff, u64TscNew, pVM->nem.s.u64VTimerValuePaused, 1250 pVCpu->nem.s.u64VTimerOff + (u64TscNew - pVM->nem.s.u64VTimerValuePaused))); 1251 1252 pVCpu->nem.s.u64VTimerOff += u64TscNew - pVM->nem.s.u64VTimerValuePaused; 1253 hv_return_t hrc = hv_vcpu_set_vtimer_offset(pVCpu->nem.s.hVCpu, pVCpu->nem.s.u64VTimerOff); 1286 hv_return_t hrc = hv_vcpu_set_vtimer_offset(pVCpu->nem.s.hVCpu, pVM->nem.s.u64VTimerOff); 1254 1287 if (hrc != HV_SUCCESS) 1255 1288 return nemR3DarwinHvSts2Rc(hrc); … … 1739 1772 if (puAux) 1740 1773 *puAux = 0; 1741 *pcTicks = mach_absolute_time() - pVCpu-> nem.s.u64VTimerOff; /* This is the host timer minus the offset. */1774 *pcTicks = mach_absolute_time() - pVCpu->pVMR3->nem.s.u64VTimerOff; /* This is the host timer minus the offset. */ 1742 1775 return VINF_SUCCESS; 1743 1776 } … … 1760 1793 AssertReturn(VM_IS_NEM_ENABLED(pVM), VERR_NEM_IPE_9); 1761 1794 1762 pVM->nem.s.u64VTimerValuePaused = uPausedTscValue; 1795 /* 1796 * Calculate the new offset, first get the new TSC value with the old vTimer offset and then adjust the 1797 * the new offset to let the guest not notice the pause. 1798 */ 1799 uint64_t u64TscNew = mach_absolute_time() - pVCpu->pVMR3->nem.s.u64VTimerOff; 1800 Assert(u64TscNew >= uPausedTscValue); 1801 LogFlowFunc(("u64VTimerOffOld=%#RX64 u64TscNew=%#RX64 u64VTimerValuePaused=%#RX64 -> u64VTimerOff=%#RX64\n", 1802 pVM->nem.s.u64VTimerOff, u64TscNew, uPausedTscValue, 1803 pVM->nem.s.u64VTimerOff + (u64TscNew - uPausedTscValue))); 1804 1805 pVM->nem.s.u64VTimerOff += u64TscNew - uPausedTscValue; 1763 1806 1764 1807 /*
Note:
See TracChangeset
for help on using the changeset viewer.