Changeset 105689 in vbox
- Timestamp:
- Aug 15, 2024 12:47:47 PM (6 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin-armv8.cpp
r103298 r105689 46 46 #include <VBox/vmm/vmcc.h> 47 47 #include <VBox/vmm/vmm.h> 48 #include <VBox/gic.h> 48 49 #include "dtrace/VBoxVMM.h" 49 50 … … 76 77 *********************************************************************************************************************************/ 77 78 79 #if MAC_OS_X_VERSION_MIN_REQUIRED < 150000 80 81 /* Since 15.0+ */ 82 typedef enum hv_gic_distributor_reg_t : uint16_t 83 { 84 HV_GIC_DISTRIBUTOR_REG_GICD_CTLR, 85 HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER0 86 /** @todo */ 87 } hv_gic_distributor_reg_t; 88 89 90 typedef enum hv_gic_icc_reg_t : uint16_t 91 { 92 HV_GIC_ICC_REG_AP0R0_EL1 93 /** @todo */ 94 } hv_gic_icc_reg_t; 95 96 97 typedef enum hv_gic_ich_reg_t : uint16_t 98 { 99 HV_GIC_ICH_REG_AP0R0_EL2 100 /** @todo */ 101 } hv_gic_ich_reg_t; 102 103 104 typedef enum hv_gic_icv_reg_t : uint16_t 105 { 106 HV_GIC_ICV_REG_AP0R0_EL1 107 /** @todo */ 108 } hv_gic_icv_reg_t; 109 110 111 typedef enum hv_gic_msi_reg_t : uint16_t 112 { 113 HV_GIC_REG_GICM_SET_SPI_NSR 114 /** @todo */ 115 } hv_gic_msi_reg_t; 116 117 118 typedef enum hv_gic_redistributor_reg_t : uint16_t 119 { 120 HV_GIC_REDISTRIBUTOR_REG_GICR_ICACTIVER0 121 /** @todo */ 122 } hv_gic_redistributor_reg_t; 123 124 125 typedef enum hv_gic_intid_t : uint16_t 126 { 127 HV_GIC_INT_EL1_PHYSICAL_TIMER = 23, 128 HV_GIC_INT_EL1_VIRTUAL_TIMER = 25, 129 HV_GIC_INT_EL2_PHYSICAL_TIMER = 26, 130 HV_GIC_INT_MAINTENANCE = 27, 131 HV_GIC_INT_PERFORMANCE_MONITOR = 30 132 } hv_gic_intid_t; 133 134 #endif 135 136 typedef hv_return_t FN_HV_VM_CONFIG_GET_EL2_SUPPORTED(bool *el2_supported); 137 typedef hv_return_t FN_HV_VM_CONFIG_GET_EL2_ENABLED(hv_vm_config_t config, bool *el2_enabled); 138 typedef hv_return_t FN_HV_VM_CONFIG_SET_EL2_ENABLED(hv_vm_config_t config, bool el2_enabled); 139 140 typedef struct hv_gic_config_s *hv_gic_config_t; 141 typedef hv_return_t FN_HV_GIC_CREATE(hv_gic_config_t gic_config); 142 typedef hv_return_t FN_HV_GIC_RESET(void); 143 typedef hv_gic_config_t FN_HV_GIC_CONFIG_CREATE(void); 144 typedef hv_return_t FN_HV_GIC_CONFIG_SET_DISTRIBUTOR_BASE(hv_gic_config_t config, hv_ipa_t distributor_base_address); 145 typedef hv_return_t FN_HV_GIC_CONFIG_SET_REDISTRIBUTOR_BASE(hv_gic_config_t config, hv_ipa_t redistributor_base_address); 146 typedef hv_return_t FN_HV_GIC_CONFIG_SET_MSI_REGION_BASE(hv_gic_config_t config, hv_ipa_t msi_region_base_address); 147 typedef hv_return_t FN_HV_GIC_CONFIG_SET_MSI_INTERRUPT_RANGE(hv_gic_config_t config, uint32_t msi_intid_base, uint32_t msi_intid_count); 148 149 typedef hv_return_t FN_HV_GIC_GET_REDISTRIBUTOR_BASE(hv_vcpu_t vcpu, hv_ipa_t *redistributor_base_address); 150 typedef hv_return_t FN_HV_GIC_GET_REDISTRIBUTOR_REGION_SIZE(size_t *redistributor_region_size); 151 typedef hv_return_t FN_HV_GIC_GET_REDISTRIBUTOR_SIZE(size_t *redistributor_size); 152 typedef hv_return_t FN_HV_GIC_GET_DISTRIBUTOR_SIZE(size_t *distributor_size); 153 typedef hv_return_t FN_HV_GIC_GET_DISTRIBUTOR_BASE_ALIGNMENT(size_t *distributor_base_alignment); 154 typedef hv_return_t FN_HV_GIC_GET_REDISTRIBUTOR_BASE_ALIGNMENT(size_t *redistributor_base_alignment); 155 typedef hv_return_t FN_HV_GIC_GET_MSI_REGION_BASE_ALIGNMENT(size_t *msi_region_base_alignment); 156 typedef hv_return_t FN_HV_GIC_GET_MSI_REGION_SIZE(size_t *msi_region_size); 157 typedef hv_return_t FN_HV_GIC_GET_SPI_INTERRUPT_RANGE(uint32_t *spi_intid_base, uint32_t *spi_intid_count); 158 159 typedef struct hv_gic_state_s *hv_gic_state_t; 160 typedef hv_gic_state_t FN_HV_GIC_STATE_CREATE(void); 161 typedef hv_return_t FN_HV_GIC_SET_STATE(const void *gic_state_data, size_t gic_state_size); 162 typedef hv_return_t FN_HV_GIC_STATE_GET_SIZE(hv_gic_state_t state, size_t *gic_state_size); 163 typedef hv_return_t FN_HV_GIC_STATE_GET_DATA(hv_gic_state_t state, void *gic_state_data); 164 165 typedef hv_return_t FN_HV_GIC_SEND_MSI(hv_ipa_t address, uint32_t intid); 166 typedef hv_return_t FN_HV_GIC_SET_SPI(uint32_t intid, bool level); 167 168 typedef hv_return_t FN_HV_GIC_GET_DISTRIBUTOR_REG(hv_gic_distributor_reg_t reg, uint64_t *value); 169 typedef hv_return_t FN_HV_GIC_GET_MSI_REG(hv_gic_msi_reg_t reg, uint64_t *value); 170 typedef hv_return_t FN_HV_GIC_GET_ICC_REG(hv_vcpu_t vcpu, hv_gic_icc_reg_t reg, uint64_t *value); 171 typedef hv_return_t FN_HV_GIC_GET_ICH_REG(hv_vcpu_t vcpu, hv_gic_ich_reg_t reg, uint64_t *value); 172 typedef hv_return_t FN_HV_GIC_GET_ICV_REG(hv_vcpu_t vcpu, hv_gic_icv_reg_t reg, uint64_t *value); 173 typedef hv_return_t FN_HV_GIC_GET_REDISTRIBUTOR_REG(hv_vcpu_t vcpu, hv_gic_redistributor_reg_t reg, uint64_t *value); 174 175 typedef hv_return_t FN_HV_GIC_SET_DISTRIBUTOR_REG(hv_gic_distributor_reg_t reg, uint64_t value); 176 typedef hv_return_t FN_HV_GIC_SET_MSI_REG(hv_gic_msi_reg_t reg, uint64_t value); 177 typedef hv_return_t FN_HV_GIC_SET_ICC_REG(hv_vcpu_t vcpu, hv_gic_icc_reg_t reg, uint64_t value); 178 typedef hv_return_t FN_HV_GIC_SET_ICH_REG(hv_vcpu_t vcpu, hv_gic_ich_reg_t reg, uint64_t value); 179 typedef hv_return_t FN_HV_GIC_SET_ICV_REG(hv_vcpu_t vcpu, hv_gic_icv_reg_t reg, uint64_t value); 180 typedef hv_return_t FN_HV_GIC_SET_REDISTRIBUTOR_REG(hv_vcpu_t vcpu, hv_gic_redistributor_reg_t reg, uint64_t value); 181 182 typedef hv_return_t FN_HV_GIC_GET_INTID(hv_gic_intid_t interrupt, uint32_t *intid); 78 183 79 184 /********************************************************************************************************************************* 80 185 * Global Variables * 81 186 *********************************************************************************************************************************/ 187 /** @name Optional APIs imported from Hypervisor.framework. 188 * @{ */ 189 static FN_HV_VM_CONFIG_GET_EL2_SUPPORTED *g_pfnHvVmConfigGetEl2Supported = NULL; /* Since 15.0 */ 190 static FN_HV_VM_CONFIG_GET_EL2_ENABLED *g_pfnHvVmConfigGetEl2Enabled = NULL; /* Since 15.0 */ 191 static FN_HV_VM_CONFIG_SET_EL2_ENABLED *g_pfnHvVmConfigSetEl2Enabled = NULL; /* Since 15.0 */ 192 193 static FN_HV_GIC_CREATE *g_pfnHvGicCreate = NULL; /* Since 15.0 */ 194 static FN_HV_GIC_RESET *g_pfnHvGicReset = NULL; /* Since 15.0 */ 195 static FN_HV_GIC_CONFIG_CREATE *g_pfnHvGicConfigCreate = NULL; /* Since 15.0 */ 196 static FN_HV_GIC_CONFIG_SET_DISTRIBUTOR_BASE *g_pfnHvGicConfigSetDistributorBase = NULL; /* Since 15.0 */ 197 static FN_HV_GIC_CONFIG_SET_REDISTRIBUTOR_BASE *g_pfnHvGicConfigSetRedistributorBase = NULL; /* Since 15.0 */ 198 static FN_HV_GIC_CONFIG_SET_MSI_REGION_BASE *g_pfnHvGicConfigSetMsiRegionBase = NULL; /* Since 15.0 */ 199 static FN_HV_GIC_CONFIG_SET_MSI_INTERRUPT_RANGE *g_pfnHvGicConfigSetMsiInterruptRange = NULL; /* Since 15.0 */ 200 static FN_HV_GIC_GET_REDISTRIBUTOR_BASE *g_pfnHvGicGetRedistributorBase = NULL; /* Since 15.0 */ 201 static FN_HV_GIC_GET_REDISTRIBUTOR_REGION_SIZE *g_pfnHvGicGetRedistributorRegionSize = NULL; /* Since 15.0 */ 202 static FN_HV_GIC_GET_REDISTRIBUTOR_SIZE *g_pfnHvGicGetRedistributorSize = NULL; /* Since 15.0 */ 203 static FN_HV_GIC_GET_DISTRIBUTOR_SIZE *g_pfnHvGicGetDistributorSize = NULL; /* Since 15.0 */ 204 static FN_HV_GIC_GET_DISTRIBUTOR_BASE_ALIGNMENT *g_pfnHvGicGetDistributorBaseAlignment = NULL; /* Since 15.0 */ 205 static FN_HV_GIC_GET_REDISTRIBUTOR_BASE_ALIGNMENT *g_pfnHvGicGetRedistributorBaseAlignment = NULL; /* Since 15.0 */ 206 static FN_HV_GIC_GET_MSI_REGION_BASE_ALIGNMENT *g_pfnHvGicGetMsiRegionBaseAlignment = NULL; /* Since 15.0 */ 207 static FN_HV_GIC_GET_MSI_REGION_SIZE *g_pfnHvGicGetMsiRegionSize = NULL; /* Since 15.0 */ 208 static FN_HV_GIC_GET_SPI_INTERRUPT_RANGE *g_pfnHvGicGetSpiInterruptRange = NULL; /* Since 15.0 */ 209 static FN_HV_GIC_STATE_CREATE *g_pfnHvGicStateCreate = NULL; /* Since 15.0 */ 210 static FN_HV_GIC_SET_STATE *g_pfnHvGicSetState = NULL; /* Since 15.0 */ 211 static FN_HV_GIC_STATE_GET_SIZE *g_pfnHvGicStateGetSize = NULL; /* Since 15.0 */ 212 static FN_HV_GIC_STATE_GET_DATA *g_pfnHvGicStateGetData = NULL; /* Since 15.0 */ 213 static FN_HV_GIC_SEND_MSI *g_pfnHvGicSendMsi = NULL; /* Since 15.0 */ 214 static FN_HV_GIC_SET_SPI *g_pfnHvGicSetSpi = NULL; /* Since 15.0 */ 215 static FN_HV_GIC_GET_DISTRIBUTOR_REG *g_pfnHvGicGetDistributorReg = NULL; /* Since 15.0 */ 216 static FN_HV_GIC_GET_MSI_REG *g_pfnHvGicGetMsiReg = NULL; /* Since 15.0 */ 217 static FN_HV_GIC_GET_ICC_REG *g_pfnHvGicGetIccReg = NULL; /* Since 15.0 */ 218 static FN_HV_GIC_GET_ICH_REG *g_pfnHvGicGetIchReg = NULL; /* Since 15.0 */ 219 static FN_HV_GIC_GET_ICV_REG *g_pfnHvGicGetIcvReg = NULL; /* Since 15.0 */ 220 static FN_HV_GIC_GET_REDISTRIBUTOR_REG *g_pfnHvGicGetRedistributorReg = NULL; /* Since 15.0 */ 221 static FN_HV_GIC_SET_DISTRIBUTOR_REG *g_pfnHvGicSetDistributorReg = NULL; /* Since 15.0 */ 222 static FN_HV_GIC_SET_MSI_REG *g_pfnHvGicSetMsiReg = NULL; /* Since 15.0 */ 223 static FN_HV_GIC_SET_ICC_REG *g_pfnHvGicSetIccReg = NULL; /* Since 15.0 */ 224 static FN_HV_GIC_SET_ICH_REG *g_pfnHvGicSetIchReg = NULL; /* Since 15.0 */ 225 static FN_HV_GIC_SET_ICV_REG *g_pfnHvGicSetIcvReg = NULL; /* Since 15.0 */ 226 static FN_HV_GIC_SET_REDISTRIBUTOR_REG *g_pfnHvGicSetRedistributorReg = NULL; /* Since 15.0 */ 227 static FN_HV_GIC_GET_INTID *g_pfnHvGicGetIntid = NULL; /* Since 15.0 */ 228 /** @} */ 229 230 231 /** 232 * Import instructions. 233 */ 234 static const struct 235 { 236 void **ppfn; /**< The function pointer variable. */ 237 const char *pszName; /**< The function name. */ 238 } g_aImports[] = 239 { 240 #define NEM_DARWIN_IMPORT(a_Pfn, a_Name) { (void **)&(a_Pfn), #a_Name } 241 NEM_DARWIN_IMPORT(g_pfnHvVmConfigGetEl2Supported, hv_vm_config_get_el2_supported), 242 NEM_DARWIN_IMPORT(g_pfnHvVmConfigGetEl2Enabled, hv_vm_config_get_el2_enabled), 243 NEM_DARWIN_IMPORT(g_pfnHvVmConfigSetEl2Enabled, hv_vm_config_set_el2_enabled), 244 245 NEM_DARWIN_IMPORT(g_pfnHvGicCreate, hv_gic_create), 246 NEM_DARWIN_IMPORT(g_pfnHvGicReset, hv_gic_reset), 247 NEM_DARWIN_IMPORT(g_pfnHvGicConfigCreate, hv_gic_config_create), 248 NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetDistributorBase, hv_gic_config_set_distributor_base), 249 NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetRedistributorBase, hv_gic_config_set_redistributor_base), 250 NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetMsiRegionBase, hv_gic_config_set_msi_region_base), 251 NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetMsiInterruptRange, hv_gic_config_set_msi_interrupt_range), 252 NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorBase, hv_gic_get_redistributor_base), 253 NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorRegionSize, hv_gic_get_redistributor_region_size), 254 NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorSize, hv_gic_get_redistributor_size), 255 NEM_DARWIN_IMPORT(g_pfnHvGicGetDistributorSize, hv_gic_get_distributor_size), 256 NEM_DARWIN_IMPORT(g_pfnHvGicGetDistributorBaseAlignment, hv_gic_get_distributor_base_alignment), 257 NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorBaseAlignment, hv_gic_get_redistributor_base_alignment), 258 NEM_DARWIN_IMPORT(g_pfnHvGicGetMsiRegionBaseAlignment, hv_gic_get_msi_region_base_alignment), 259 NEM_DARWIN_IMPORT(g_pfnHvGicGetMsiRegionSize, hv_gic_get_msi_region_size), 260 NEM_DARWIN_IMPORT(g_pfnHvGicGetSpiInterruptRange, hv_gic_get_spi_interrupt_range), 261 NEM_DARWIN_IMPORT(g_pfnHvGicStateCreate, hv_gic_state_create), 262 NEM_DARWIN_IMPORT(g_pfnHvGicSetState, hv_gic_set_state), 263 NEM_DARWIN_IMPORT(g_pfnHvGicStateGetSize, hv_gic_state_get_size), 264 NEM_DARWIN_IMPORT(g_pfnHvGicStateGetData, hv_gic_state_get_data), 265 NEM_DARWIN_IMPORT(g_pfnHvGicSendMsi, hv_gic_send_msi), 266 NEM_DARWIN_IMPORT(g_pfnHvGicSetSpi, hv_gic_set_spi), 267 NEM_DARWIN_IMPORT(g_pfnHvGicGetDistributorReg, hv_gic_get_distributor_reg), 268 NEM_DARWIN_IMPORT(g_pfnHvGicGetMsiReg, hv_gic_get_msi_reg), 269 NEM_DARWIN_IMPORT(g_pfnHvGicGetIccReg, hv_gic_get_icc_reg), 270 NEM_DARWIN_IMPORT(g_pfnHvGicGetIchReg, hv_gic_get_ich_reg), 271 NEM_DARWIN_IMPORT(g_pfnHvGicGetIcvReg, hv_gic_get_icv_reg), 272 NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorReg, hv_gic_get_redistributor_reg), 273 NEM_DARWIN_IMPORT(g_pfnHvGicSetDistributorReg, hv_gic_set_distributor_reg), 274 NEM_DARWIN_IMPORT(g_pfnHvGicSetMsiReg, hv_gic_set_msi_reg), 275 NEM_DARWIN_IMPORT(g_pfnHvGicSetIccReg, hv_gic_set_icc_reg), 276 NEM_DARWIN_IMPORT(g_pfnHvGicSetIchReg, hv_gic_set_ich_reg), 277 NEM_DARWIN_IMPORT(g_pfnHvGicSetIcvReg, hv_gic_set_icv_reg), 278 NEM_DARWIN_IMPORT(g_pfnHvGicSetRedistributorReg, hv_gic_set_redistributor_reg), 279 NEM_DARWIN_IMPORT(g_pfnHvGicGetIntid, hv_gic_get_intid) 280 #undef NEM_DARWIN_IMPORT 281 }; 282 283 284 /* 285 * Let the preprocessor alias the APIs to import variables for better autocompletion. 286 */ 287 #ifndef IN_SLICKEDIT 288 # define hv_vm_config_get_el2_supported g_pfnHvVmConfigGetEl2Supported 289 # define hv_vm_config_get_el2_enabled g_pfnHvVmConfigGetEl2Enabled 290 # define hv_vm_config_set_el2_enabled g_pfnHvVmConfigSetEl2Enabled 291 292 # define hv_gic_create g_pfnHvGicCreate 293 # define hv_gic_reset g_pfnHvGicReset 294 # define hv_gic_config_create g_pfnHvGicConfigCreate 295 # define hv_gic_config_set_distributor_base g_pfnHvGicConfigSetDistributorBase 296 # define hv_gic_config_set_redistributor_base g_pfnHvGicConfigSetRedistributorBase 297 # define hv_gic_config_set_msi_region_base g_pfnHvGicConfigSetMsiRegionBase 298 # define hv_gic_config_set_msi_interrupt_range g_pfnHvGicConfigSetMsiInterruptRange 299 # define hv_gic_get_redistributor_base g_pfnHvGicGetRedistributorBase 300 # define hv_gic_get_redistributor_region_size g_pfnHvGicGetRedistributorRegionSize 301 # define hv_gic_get_redistributor_size g_pfnHvGicGetRedistributorSize 302 # define hv_gic_get_distributor_size g_pfnHvGicGetDistributorSize 303 # define hv_gic_get_distributor_base_alignment g_pfnHvGicGetDistributorBaseAlignment 304 # define hv_gic_get_redistributor_base_alignment g_pfnHvGicGetRedistributorBaseAlignment 305 # define hv_gic_get_msi_region_base_alignment g_pfnHvGicGetMsiRegionBaseAlignment 306 # define hv_gic_get_msi_region_size g_pfnHvGicGetMsiRegionSize 307 # define hv_gic_get_spi_interrupt_range g_pfnHvGicGetSpiInterruptRange 308 # define hv_gic_state_create g_pfnHvGicStateCreate 309 # define hv_gic_set_state g_pfnHvGicSetState 310 # define hv_gic_state_get_size g_pfnHvGicStateGetSize 311 # define hv_gic_state_get_data g_pfnHvGicStateGetData 312 # define hv_gic_send_msi g_pfnHvGicSendMsi 313 # define hv_gic_set_spi g_pfnHvGicSetSpi 314 # define hv_gic_get_distributor_reg g_pfnHvGicGetDistributorReg 315 # define hv_gic_get_msi_reg g_pfnHvGicGetMsiReg 316 # define hv_gic_get_icc_reg g_pfnHvGicGetIccReg 317 # define hv_gic_get_ich_reg g_pfnHvGicGetIchReg 318 # define hv_gic_get_icv_reg g_pfnHvGicGetIcvReg 319 # define hv_gic_get_redistributor_reg g_pfnHvGicGetRedistributorReg 320 # define hv_gic_set_distributor_reg g_pfnHvGicSetDistributorReg 321 # define hv_gic_set_msi_reg g_pfnHvGicSetMsiReg 322 # define hv_gic_set_icc_reg g_pfnHvGicSetIccReg 323 # define hv_gic_set_ich_reg g_pfnHvGicSetIchReg 324 # define hv_gic_set_icv_reg g_pfnHvGicSetIcvReg 325 # define hv_gic_set_redistributor_reg g_pfnHvGicSetRedistributorReg 326 # define hv_gic_get_intid g_pfnHvGicGetIntid 327 #endif 328 329 82 330 /** The general registers. */ 83 331 static const struct … … 267 515 { HV_SYS_REG_MDCCINT_EL1, CPUMCTX_EXTRN_SYSREG_MISC, RT_UOFFSETOF(CPUMCTX, MDccInt.u64) } 268 516 517 }; 518 /** EL2 support system registers. */ 519 static const struct 520 { 521 uint16_t idSysReg; 522 uint32_t offCpumCtx; 523 } s_aCpumEl2SysRegs[] = 524 { 525 { ARMV8_AARCH64_SYSREG_CNTHCTL_EL2, RT_UOFFSETOF(CPUMCTX, CntHCtlEl2.u64) }, 526 { ARMV8_AARCH64_SYSREG_CNTHP_CTL_EL2, RT_UOFFSETOF(CPUMCTX, CntHpCtlEl2.u64) }, 527 { ARMV8_AARCH64_SYSREG_CNTHP_CVAL_EL2, RT_UOFFSETOF(CPUMCTX, CntHpCValEl2.u64) }, 528 { ARMV8_AARCH64_SYSREG_CNTHP_TVAL_EL2, RT_UOFFSETOF(CPUMCTX, CntHpTValEl2.u64) }, 529 { ARMV8_AARCH64_SYSREG_CNTVOFF_EL2, RT_UOFFSETOF(CPUMCTX, CntVOffEl2.u64) }, 530 { ARMV8_AARCH64_SYSREG_CPTR_EL2, RT_UOFFSETOF(CPUMCTX, CptrEl2.u64) }, 531 { ARMV8_AARCH64_SYSREG_ELR_EL2, RT_UOFFSETOF(CPUMCTX, ElrEl2.u64) }, 532 { ARMV8_AARCH64_SYSREG_ESR_EL2, RT_UOFFSETOF(CPUMCTX, EsrEl2.u64) }, 533 { ARMV8_AARCH64_SYSREG_FAR_EL2, RT_UOFFSETOF(CPUMCTX, FarEl2.u64) }, 534 { ARMV8_AARCH64_SYSREG_HCR_EL2, RT_UOFFSETOF(CPUMCTX, HcrEl2.u64) }, 535 { ARMV8_AARCH64_SYSREG_HPFAR_EL2, RT_UOFFSETOF(CPUMCTX, HpFarEl2.u64) }, 536 { ARMV8_AARCH64_SYSREG_MAIR_EL2, RT_UOFFSETOF(CPUMCTX, MairEl2.u64) }, 537 //{ ARMV8_AARCH64_SYSREG_MDCR_EL2, RT_UOFFSETOF(CPUMCTX, MdcrEl2.u64) }, 538 { ARMV8_AARCH64_SYSREG_SCTLR_EL2, RT_UOFFSETOF(CPUMCTX, SctlrEl2.u64) }, 539 { ARMV8_AARCH64_SYSREG_SPSR_EL2, RT_UOFFSETOF(CPUMCTX, SpsrEl2.u64) }, 540 { ARMV8_AARCH64_SYSREG_SP_EL2, RT_UOFFSETOF(CPUMCTX, SpEl2.u64) }, 541 { ARMV8_AARCH64_SYSREG_TCR_EL2, RT_UOFFSETOF(CPUMCTX, TcrEl2.u64) }, 542 { ARMV8_AARCH64_SYSREG_TPIDR_EL2, RT_UOFFSETOF(CPUMCTX, TpidrEl2.u64) }, 543 { ARMV8_AARCH64_SYSREG_TTBR0_EL2, RT_UOFFSETOF(CPUMCTX, Ttbr0El2.u64) }, 544 { ARMV8_AARCH64_SYSREG_TTBR1_EL2, RT_UOFFSETOF(CPUMCTX, Ttbr1El2.u64) }, 545 { ARMV8_AARCH64_SYSREG_VBAR_EL2, RT_UOFFSETOF(CPUMCTX, VBarEl2.u64) }, 546 { ARMV8_AARCH64_SYSREG_VMPIDR_EL2, RT_UOFFSETOF(CPUMCTX, VMpidrEl2.u64) }, 547 { ARMV8_AARCH64_SYSREG_VPIDR_EL2, RT_UOFFSETOF(CPUMCTX, VPidrEl2.u64) }, 548 { ARMV8_AARCH64_SYSREG_VTCR_EL2, RT_UOFFSETOF(CPUMCTX, VTcrEl2.u64) }, 549 { ARMV8_AARCH64_SYSREG_VTTBR_EL2, RT_UOFFSETOF(CPUMCTX, VTtbrEl2.u64) } 269 550 }; 270 551 /** ID registers. */ … … 551 832 #endif 552 833 Log3(("%s%s\n", szRegs, szInstr)); 834 835 if (pVM->nem.s.fEl2Enabled) 836 { 837 DBGFR3RegPrintf(pVM->pUVM, pVCpu->idCpu, &szRegs[0], sizeof(szRegs), 838 "sp_el2=%016VR{sp_el2} elr_el2=%016VR{elr_el2}\n" 839 "spsr_el2=%016VR{spsr_el2} tpidr_el2=%016VR{tpidr_el2}\n" 840 "sctlr_el2=%016VR{sctlr_el2} tcr_el2=%016VR{tcr_el2}\n" 841 "ttbr0_el2=%016VR{ttbr0_el2} ttbr1_el2=%016VR{ttbr1_el2}\n" 842 "esr_el2=%016VR{esr_el2} far_el2=%016VR{far_el2}\n" 843 "hcr_el2=%016VR{hcr_el2} tcr_el2=%016VR{tcr_el2}\n" 844 "vbar_el2=%016VR{vbar_el2} cptr_el2=%016VR{cptr_el2}\n" 845 ); 846 } 847 Log3(("%s%s\n", szRegs)); 553 848 } 554 849 } … … 625 920 626 921 if ( hrc == HV_SUCCESS 922 && (fWhat & CPUMCTX_EXTRN_SYSREG_EL2) 923 && pVM->nem.s.fEl2Enabled) 924 { 925 for (uint32_t i = 0; i < RT_ELEMENTS(s_aCpumEl2SysRegs); i++) 926 { 927 uint64_t *pu64 = (uint64_t *)((uint8_t *)&pVCpu->cpum.GstCtx + s_aCpumEl2SysRegs[i].offCpumCtx); 928 hrc |= hv_vcpu_get_sys_reg(pVCpu->nem.s.hVCpu, (hv_sys_reg_t)s_aCpumEl2SysRegs[i].idSysReg, pu64); 929 } 930 } 931 932 if ( hrc == HV_SUCCESS 627 933 && (fWhat & CPUMCTX_EXTRN_PSTATE)) 628 934 { … … 717 1023 718 1024 if ( hrc == HV_SUCCESS 1025 && !(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_SYSREG_EL2) 1026 && pVM->nem.s.fEl2Enabled) 1027 { 1028 for (uint32_t i = 0; i < RT_ELEMENTS(s_aCpumEl2SysRegs); i++) 1029 { 1030 uint64_t *pu64 = (uint64_t *)((uint8_t *)&pVCpu->cpum.GstCtx + s_aCpumEl2SysRegs[i].offCpumCtx); 1031 hrc |= hv_vcpu_set_sys_reg(pVCpu->nem.s.hVCpu, (hv_sys_reg_t)s_aCpumEl2SysRegs[i].idSysReg, *pu64); 1032 Assert(hrc == HV_SUCCESS); 1033 } 1034 } 1035 1036 if ( hrc == HV_SUCCESS 719 1037 && !(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_PSTATE)) 720 1038 hrc = hv_vcpu_set_reg(pVCpu->nem.s.hVCpu, HV_REG_CPSR, pVCpu->cpum.GstCtx.fPState); … … 722 1040 pVCpu->cpum.GstCtx.fExtrn |= CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_KEEPER_NEM; 723 1041 return nemR3DarwinHvSts2Rc(hrc); 1042 } 1043 1044 1045 /** 1046 * Worker for nemR3NativeInit that loads the Hypervisor.framework shared library. 1047 * 1048 * @returns VBox status code. 1049 * @param pErrInfo Where to always return error info. 1050 */ 1051 static int nemR3DarwinLoadHv(PRTERRINFO pErrInfo) 1052 { 1053 RTLDRMOD hMod = NIL_RTLDRMOD; 1054 static const char *s_pszHvPath = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor"; 1055 1056 int rc = RTLdrLoadEx(s_pszHvPath, &hMod, RTLDRLOAD_FLAGS_NO_UNLOAD | RTLDRLOAD_FLAGS_NO_SUFFIX, pErrInfo); 1057 if (RT_SUCCESS(rc)) 1058 { 1059 for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++) 1060 { 1061 int rc2 = RTLdrGetSymbol(hMod, g_aImports[i].pszName, (void **)g_aImports[i].ppfn); 1062 if (RT_SUCCESS(rc2)) 1063 { 1064 LogRel(("NEM: info: Found optional import Hypervisor!%s.\n", 1065 g_aImports[i].pszName)); 1066 } 1067 else 1068 { 1069 *g_aImports[i].ppfn = NULL; 1070 1071 LogRel(("NEM: info: Failed to import Hypervisor!%s: %Rrc\n", 1072 g_aImports[i].pszName, rc2)); 1073 } 1074 } 1075 if (RT_SUCCESS(rc)) 1076 { 1077 Assert(!RTErrInfoIsSet(pErrInfo)); 1078 } 1079 1080 RTLdrClose(hMod); 1081 } 1082 else 1083 { 1084 RTErrInfoAddF(pErrInfo, rc, "Failed to load Hypervisor.framwork: %s: %Rrc", s_pszHvPath, rc); 1085 rc = VERR_NEM_INIT_FAILED; 1086 } 1087 1088 return rc; 1089 } 1090 1091 1092 /** 1093 * Dumps some GIC information to the release log. 1094 */ 1095 static void nemR3DarwinDumpGicInfo(void) 1096 { 1097 size_t val = 0; 1098 hv_return_t hrc = hv_gic_get_redistributor_size(&val); 1099 LogRel(("GICNem: hv_gic_get_redistributor_size() -> hrc=%#x / size=%zu\n", hrc, val)); 1100 hrc = hv_gic_get_distributor_size(&val); 1101 LogRel(("GICNem: hv_gic_get_distributor_size() -> hrc=%#x / size=%zu\n", hrc, val)); 1102 hrc = hv_gic_get_distributor_base_alignment(&val); 1103 LogRel(("GICNem: hv_gic_get_distributor_base_alignment() -> hrc=%#x / size=%zu\n", hrc, val)); 1104 hrc = hv_gic_get_redistributor_base_alignment(&val); 1105 LogRel(("GICNem: hv_gic_get_redistributor_base_alignment() -> hrc=%#x / size=%zu\n", hrc, val)); 1106 hrc = hv_gic_get_msi_region_base_alignment(&val); 1107 LogRel(("GICNem: hv_gic_get_msi_region_base_alignment() -> hrc=%#x / size=%zu\n", hrc, val)); 1108 hrc = hv_gic_get_msi_region_size(&val); 1109 LogRel(("GICNem: hv_gic_get_msi_region_size() -> hrc=%#x / size=%zu\n", hrc, val)); 1110 uint32_t u32SpiIntIdBase = 0; 1111 uint32_t cSpiIntIds = 0; 1112 hrc = hv_gic_get_spi_interrupt_range(&u32SpiIntIdBase, &cSpiIntIds); 1113 LogRel(("GICNem: hv_gic_get_spi_interrupt_range() -> hrc=%#x / SpiIntIdBase=%u, cSpiIntIds=%u\n", hrc, u32SpiIntIdBase, cSpiIntIds)); 1114 1115 uint32_t u32IntId = 0; 1116 hrc = hv_gic_get_intid(HV_GIC_INT_EL1_PHYSICAL_TIMER, &u32IntId); 1117 LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_EL1_PHYSICAL_TIMER) -> hrc=%#x / IntId=%u\n", hrc, u32IntId)); 1118 hrc = hv_gic_get_intid(HV_GIC_INT_EL1_VIRTUAL_TIMER, &u32IntId); 1119 LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_EL1_VIRTUAL_TIMER) -> hrc=%#x / IntId=%u\n", hrc, u32IntId)); 1120 hrc = hv_gic_get_intid(HV_GIC_INT_EL2_PHYSICAL_TIMER, &u32IntId); 1121 LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_EL2_PHYSICAL_TIMER) -> hrc=%#x / IntId=%u\n", hrc, u32IntId)); 1122 hrc = hv_gic_get_intid(HV_GIC_INT_MAINTENANCE, &u32IntId); 1123 LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_MAINTENANCE) -> hrc=%#x / IntId=%u\n", hrc, u32IntId)); 1124 hrc = hv_gic_get_intid(HV_GIC_INT_PERFORMANCE_MONITOR, &u32IntId); 1125 LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_PERFORMANCE_MONITOR) -> hrc=%#x / IntId=%u\n", hrc, u32IntId)); 1126 } 1127 1128 1129 /** 1130 * Sets the given SPI inside the in-kernel KVM GIC. 1131 * 1132 * @returns VBox status code. 1133 * @param pVM The VM instance. 1134 * @param uIntId The SPI ID to update. 1135 * @param fAsserted Flag whether the interrupt is asserted (true) or not (false). 1136 */ 1137 VMMR3_INT_DECL(int) GICR3NemSpiSet(PVMCC pVM, uint32_t uIntId, bool fAsserted) 1138 { 1139 RT_NOREF(pVM); 1140 Assert(hv_gic_set_spi); 1141 1142 hv_return_t hrc = hv_gic_set_spi(uIntId + GIC_INTID_RANGE_SPI_START, fAsserted); 1143 return nemR3DarwinHvSts2Rc(hrc); 1144 } 1145 1146 1147 /** 1148 * Sets the given PPI inside the in-kernel KVM GIC. 1149 * 1150 * @returns VBox status code. 1151 * @param pVCpu The vCPU for whih the PPI state is updated. 1152 * @param uIntId The PPI ID to update. 1153 * @param fAsserted Flag whether the interrupt is asserted (true) or not (false). 1154 */ 1155 VMMR3_INT_DECL(int) GICR3NemPpiSet(PVMCPUCC pVCpu, uint32_t uIntId, bool fAsserted) 1156 { 1157 RT_NOREF(pVCpu, uIntId, fAsserted); 1158 1159 /* Should never be called as the PPIs are handled entirely in Hypervisor.framework/AppleHV. */ 1160 AssertFailed(); 1161 return VERR_NEM_IPE_9; 1162 } 1163 1164 1165 static int nemR3DarwinGicCreate(PVM pVM) 1166 { 1167 nemR3DarwinDumpGicInfo(); 1168 1169 //PCFGMNODE pGicDev = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/gic/0"); 1170 PCFGMNODE pGicCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/gic-nem/0/Config"); 1171 1172 hv_gic_config_t hGicCfg = hv_gic_config_create(); 1173 1174 /* 1175 * Query the MMIO ranges. 1176 */ 1177 RTGCPHYS GCPhysMmioBaseDist = 0; 1178 int rc = CFGMR3QueryU64(pGicCfg, "DistributorMmioBase", &GCPhysMmioBaseDist); 1179 if (RT_FAILURE(rc)) 1180 return VMSetError(pVM, rc, RT_SRC_POS, 1181 "Configuration error: Failed to get the \"DistributorMmioBase\" value\n"); 1182 1183 RTGCPHYS GCPhysMmioBaseReDist = 0; 1184 rc = CFGMR3QueryU64(pGicCfg, "RedistributorMmioBase", &GCPhysMmioBaseReDist); 1185 if (RT_FAILURE(rc)) 1186 return VMSetError(pVM, rc, RT_SRC_POS, 1187 "Configuration error: Failed to get the \"RedistributorMmioBase\" value\n"); 1188 1189 hv_return_t hrc = hv_gic_config_set_distributor_base(hGicCfg, GCPhysMmioBaseDist); 1190 if (hrc != HV_SUCCESS) 1191 return nemR3DarwinHvSts2Rc(hrc); 1192 1193 hrc = hv_gic_config_set_redistributor_base(hGicCfg, GCPhysMmioBaseReDist); 1194 if (hrc != HV_SUCCESS) 1195 return nemR3DarwinHvSts2Rc(hrc); 1196 1197 hrc = hv_gic_create(hGicCfg); 1198 os_release(hGicCfg); 1199 if (hrc != HV_SUCCESS) 1200 return nemR3DarwinHvSts2Rc(hrc); 1201 1202 /* Make sure the device is not instantiated as Hypervisor.framework provides it. */ 1203 //CFGMR3RemoveNode(pGicDev); 1204 return rc; 724 1205 } 725 1206 … … 755 1236 PRTERRINFO pErrInfo = RTErrInfoInitStatic(&ErrInfo); 756 1237 757 int rc = VINF_SUCCESS; 758 hv_return_t hrc = hv_vm_create(NULL); 1238 /* Resolve optional imports */ 1239 int rc = nemR3DarwinLoadHv(pErrInfo); 1240 if (RT_FAILURE(rc)) 1241 return rc; 1242 1243 /* 1244 * Need to enable nested virt here if supported and reset the CFGM value to false 1245 * if not supported. This ASSUMES that NEM is initialized before CPUM. 1246 */ 1247 PCFGMNODE pCfgCpum = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM/"); 1248 hv_vm_config_t hVmCfg = hv_vm_config_create(); 1249 1250 if (hv_vm_config_get_el2_supported) 1251 { 1252 bool fHvEl2Supported = false; 1253 hv_return_t hrc = hv_vm_config_get_el2_supported(&fHvEl2Supported); 1254 if ( hrc == HV_SUCCESS 1255 && fHvEl2Supported) 1256 { 1257 /** @cfgm{/CPUM/NestedHWVirt, bool, false} 1258 * Whether to expose the hardware virtualization (EL2/VHE) feature to the guest. 1259 * The default is false. Only supported on M3 and later and macOS 15.0+ (Sonoma). 1260 */ 1261 bool fNestedHWVirt = false; 1262 rc = CFGMR3QueryBoolDef(pCfgCpum, "NestedHWVirt", &fNestedHWVirt, false); 1263 AssertLogRelRCReturn(rc, rc); 1264 if (fNestedHWVirt) 1265 { 1266 hrc = hv_vm_config_set_el2_enabled(hVmCfg, fNestedHWVirt); 1267 if (hrc != HV_SUCCESS) 1268 return VMSetError(pVM, VERR_CPUM_INVALID_HWVIRT_CONFIG, RT_SRC_POS, 1269 "Cannot enable nested virtualization (hrc=%#x)!\n", hrc); 1270 else 1271 { 1272 pVM->nem.s.fEl2Enabled = true; 1273 LogRel(("NEM: Enabled nested virtualization (EL2) support\n")); 1274 } 1275 } 1276 } 1277 else 1278 { 1279 /* Ensure nested virt is not set. */ 1280 rc = CFGMR3RemoveValue(pCfgCpum, "NestedHWVirt"); 1281 1282 LogRel(("NEM: The host doesn't supported nested virtualization! (hrc=%#x fHvEl2Supported=%RTbool)\n", 1283 hrc, fHvEl2Supported)); 1284 } 1285 } 1286 else 1287 { 1288 /* Ensure nested virt is not set. */ 1289 rc = CFGMR3RemoveValue(pCfgCpum, "NestedHWVirt"); 1290 LogRel(("NEM: Hypervisor.framework doesn't supported nested virtualization!\n")); 1291 } 1292 1293 hv_return_t hrc = hv_vm_create(hVmCfg); 1294 os_release(hVmCfg); 759 1295 if (hrc == HV_SUCCESS) 760 1296 { … … 781 1317 return VMSetError(pVM, RT_SUCCESS_NP(rc) ? VERR_NEM_NOT_AVAILABLE : rc, RT_SRC_POS, "%s", pErrInfo->pszMsg); 782 1318 783 if (RTErrInfoIsSet(pErrInfo))1319 if (RTErrInfoIsSet(pErrInfo)) 784 1320 LogRel(("NEM: Not available: %s\n", pErrInfo->pszMsg)); 785 1321 return VINF_SUCCESS; … … 871 1407 AssertReturn(!pVM->nem.s.fCreatedEmts, VERR_WRONG_ORDER); 872 1408 AssertReturn(pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API, VERR_WRONG_ORDER); 1409 1410 /* Need to create the GIC here before any vCPU is created according to the Apple docs. */ 1411 if (hv_gic_create) 1412 { 1413 int rc = nemR3DarwinGicCreate(pVM); 1414 if (RT_FAILURE(rc)) 1415 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Creating the GIC failed: %Rrc", rc); 1416 } 873 1417 874 1418 /* … … 1209 1753 * @param uIss The instruction specific syndrome value. 1210 1754 */ 1211 static VBOXSTRICTRC nemR3DarwinHandleExitExceptionTrappedHvcInsn(PVM pVM, PVMCPU pVCpu, uint32_t uIss )1755 static VBOXSTRICTRC nemR3DarwinHandleExitExceptionTrappedHvcInsn(PVM pVM, PVMCPU pVCpu, uint32_t uIss, bool fAdvancePc = false) 1212 1756 { 1213 1757 uint16_t u16Imm = ARMV8_EC_ISS_AARCH64_TRAPPED_HVC_INSN_IMM_GET(uIss); … … 1278 1822 case ARM_PSCI_FUNC_ID_SYSTEM_RESET2: 1279 1823 case ARM_PSCI_FUNC_ID_CPU_ON: 1824 case ARM_PSCI_FUNC_ID_MIGRATE_INFO_TYPE: 1280 1825 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, 1281 1826 false /*f64BitReg*/, false /*fSignExtend*/, … … 1289 1834 break; 1290 1835 } 1836 case ARM_PSCI_FUNC_ID_MIGRATE_INFO_TYPE: 1837 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, ARM_PSCI_MIGRATE_INFO_TYPE_TOS_NOT_PRESENT); 1838 break; 1291 1839 default: 1292 1840 nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, (uint64_t)ARM_PSCI_STS_NOT_SUPPORTED); … … 1297 1845 } 1298 1846 /** @todo What to do if immediate is != 0? */ 1847 1848 if ( rcStrict == VINF_SUCCESS 1849 && fAdvancePc) 1850 pVCpu->cpum.GstCtx.Pc.u64 += sizeof(uint32_t); 1299 1851 1300 1852 return rcStrict; … … 1329 1881 case ARMV8_ESR_EL2_EC_AARCH64_HVC_INSN: 1330 1882 return nemR3DarwinHandleExitExceptionTrappedHvcInsn(pVM, pVCpu, uIss); 1883 case ARMV8_ESR_EL2_EC_AARCH64_SMC_INSN: 1884 return nemR3DarwinHandleExitExceptionTrappedHvcInsn(pVM, pVCpu, uIss, true); 1331 1885 case ARMV8_ESR_EL2_EC_TRAPPED_WFX: 1332 1886 {
Note:
See TracChangeset
for help on using the changeset viewer.