Changeset 100756 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jul 31, 2023 2:14:17 PM (17 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/GICR3.cpp
r100165 r100756 50 50 * Defined Constants And Macros * 51 51 *********************************************************************************************************************************/ 52 /** Some ancient version... */ 53 #define GIC_SAVED_STATE_VERSION 1 54 52 55 # define GIC_SYSREGRANGE(a_uFirst, a_uLast, a_szName) \ 53 56 { (a_uFirst), (a_uLast), kCpumSysRegRdFn_GicV3Icc, kCpumSysRegWrFn_GicV3Icc, 0, 0, 0, 0, 0, 0, a_szName, { 0 }, { 0 }, { 0 }, { 0 } } … … 153 156 154 157 /** 158 * Worker for saving per-VM GIC data. 159 * 160 * @returns VBox status code. 161 * @param pDevIns The device instance. 162 * @param pVM The cross context VM structure. 163 * @param pSSM The SSM handle. 164 */ 165 static int gicR3SaveVMData(PPDMDEVINS pDevIns, PVM pVM, PSSMHANDLE pSSM) 166 { 167 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 168 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 169 170 pHlp->pfnSSMPutU32( pSSM, pVM->cCpus); 171 pHlp->pfnSSMPutU32( pSSM, GIC_SPI_MAX); 172 pHlp->pfnSSMPutU32( pSSM, pGicDev->u32RegIGrp0); 173 pHlp->pfnSSMPutU32( pSSM, pGicDev->u32RegICfg0); 174 pHlp->pfnSSMPutU32( pSSM, pGicDev->u32RegICfg1); 175 pHlp->pfnSSMPutU32( pSSM, pGicDev->bmIntEnabled); 176 pHlp->pfnSSMPutU32( pSSM, pGicDev->bmIntPending); 177 pHlp->pfnSSMPutU32( pSSM, pGicDev->bmIntActive); 178 pHlp->pfnSSMPutMem( pSSM, (void *)&pGicDev->abIntPriority[0], sizeof(pGicDev->abIntPriority)); 179 pHlp->pfnSSMPutBool(pSSM, pGicDev->fIrqGrp0Enabled); 180 181 return pHlp->pfnSSMPutBool(pSSM, pGicDev->fIrqGrp1Enabled); 182 } 183 184 185 /** 186 * Worker for loading per-VM GIC data. 187 * 188 * @returns VBox status code. 189 * @param pDevIns The device instance. 190 * @param pVM The cross context VM structure. 191 * @param pSSM The SSM handle. 192 */ 193 static int gicR3LoadVMData(PPDMDEVINS pDevIns, PVM pVM, PSSMHANDLE pSSM) 194 { 195 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 196 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 197 198 /* Load and verify number of CPUs. */ 199 uint32_t cCpus; 200 int rc = pHlp->pfnSSMGetU32(pSSM, &cCpus); 201 AssertRCReturn(rc, rc); 202 if (cCpus != pVM->cCpus) 203 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cCpus: saved=%u config=%u"), cCpus, pVM->cCpus); 204 205 /* Load and verify maximum number of SPIs. */ 206 uint32_t cSpisMax; 207 rc = pHlp->pfnSSMGetU32(pSSM, &cSpisMax); 208 AssertRCReturn(rc, rc); 209 if (cSpisMax != GIC_SPI_MAX) 210 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cSpisMax: saved=%u config=%u"), 211 cSpisMax, GIC_SPI_MAX); 212 213 /* Load the state. */ 214 pHlp->pfnSSMGetU32V( pSSM, &pGicDev->u32RegIGrp0); 215 pHlp->pfnSSMGetU32V( pSSM, &pGicDev->u32RegICfg0); 216 pHlp->pfnSSMGetU32V( pSSM, &pGicDev->u32RegICfg1); 217 pHlp->pfnSSMGetU32V( pSSM, &pGicDev->bmIntEnabled); 218 pHlp->pfnSSMGetU32V( pSSM, &pGicDev->bmIntPending); 219 pHlp->pfnSSMGetU32V( pSSM, &pGicDev->bmIntActive); 220 pHlp->pfnSSMGetMem( pSSM, (void *)&pGicDev->abIntPriority[0], sizeof(pGicDev->abIntPriority)); 221 pHlp->pfnSSMGetBoolV(pSSM, &pGicDev->fIrqGrp0Enabled); 222 pHlp->pfnSSMGetBoolV(pSSM, &pGicDev->fIrqGrp1Enabled); 223 224 return VINF_SUCCESS; 225 } 226 227 228 /** 229 * @copydoc FNSSMDEVSAVEEXEC 230 */ 231 static DECLCALLBACK(int) gicR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 232 { 233 PVM pVM = PDMDevHlpGetVM(pDevIns); 234 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 235 236 AssertReturn(pVM, VERR_INVALID_VM_HANDLE); 237 238 LogFlow(("GIC: gicR3SaveExec\n")); 239 240 /* Save per-VM data. */ 241 int rc = gicR3SaveVMData(pDevIns, pVM, pSSM); 242 AssertRCReturn(rc, rc); 243 244 /* Save per-VCPU data.*/ 245 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 246 { 247 PVMCPU pVCpu = pVM->apCpusR3[idCpu]; 248 PGICCPU pGicVCpu = VMCPU_TO_GICCPU(pVCpu); 249 250 /* Load the redistributor state. */ 251 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->u32RegIGrp0); 252 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->u32RegICfg0); 253 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->u32RegICfg1); 254 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->bmIntEnabled); 255 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->bmIntPending); 256 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->bmIntActive); 257 pHlp->pfnSSMPutMem(pSSM, (void *)&pGicVCpu->abIntPriority[0], sizeof(pGicVCpu->abIntPriority)); 258 259 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->fIrqGrp0Enabled); 260 pHlp->pfnSSMPutU32(pSSM, pGicVCpu->fIrqGrp1Enabled); 261 pHlp->pfnSSMPutU8( pSSM, pGicVCpu->bInterruptPriority); 262 pHlp->pfnSSMPutU8( pSSM, pGicVCpu->bBinaryPointGrp0); 263 pHlp->pfnSSMPutU8( pSSM, pGicVCpu->bBinaryPointGrp1); 264 pHlp->pfnSSMPutMem(pSSM, (void *)&pGicVCpu->abRunningPriorities[0], sizeof(pGicVCpu->abRunningPriorities)); 265 pHlp->pfnSSMPutU8( pSSM, pGicVCpu->idxRunningPriority); 266 } 267 268 return rc; 269 } 270 271 272 /** 273 * @copydoc FNSSMDEVLOADEXEC 274 */ 275 static DECLCALLBACK(int) gicR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 276 { 277 PVM pVM = PDMDevHlpGetVM(pDevIns); 278 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 279 280 AssertReturn(pVM, VERR_INVALID_VM_HANDLE); 281 AssertReturn(uPass == SSM_PASS_FINAL, VERR_WRONG_ORDER); 282 283 LogFlow(("GIC: gicR3LoadExec: uVersion=%u uPass=%#x\n", uVersion, uPass)); 284 285 /* Weed out invalid versions. */ 286 if (uVersion != GIC_SAVED_STATE_VERSION) 287 { 288 LogRel(("GIC: gicR3LoadExec: Invalid/unrecognized saved-state version %u (%#x)\n", uVersion, uVersion)); 289 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 290 } 291 292 int rc = gicR3LoadVMData(pDevIns, pVM, pSSM); 293 AssertRCReturn(rc, rc); 294 295 /* 296 * Restore per CPU state. 297 * 298 * Note! PDM will restore the VMCPU_FF_INTERRUPT_IRQ and VMCPU_FF_INTERRUPT_FIQ flags for us. 299 * This code doesn't touch it. No devices should make us touch 300 * it later during the restore either, only during the 'done' phase. 301 */ 302 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 303 { 304 PVMCPU pVCpu = pVM->apCpusR3[idCpu]; 305 PGICCPU pGicVCpu = VMCPU_TO_GICCPU(pVCpu); 306 307 /* Load the redistributor state. */ 308 pHlp->pfnSSMGetU32V( pSSM, &pGicVCpu->u32RegIGrp0); 309 pHlp->pfnSSMGetU32V( pSSM, &pGicVCpu->u32RegICfg0); 310 pHlp->pfnSSMGetU32V( pSSM, &pGicVCpu->u32RegICfg1); 311 pHlp->pfnSSMGetU32V( pSSM, &pGicVCpu->bmIntEnabled); 312 pHlp->pfnSSMGetU32V( pSSM, &pGicVCpu->bmIntPending); 313 pHlp->pfnSSMGetU32V( pSSM, &pGicVCpu->bmIntActive); 314 pHlp->pfnSSMGetMem( pSSM, (void *)&pGicVCpu->abIntPriority[0], sizeof(pGicVCpu->abIntPriority)); 315 316 pHlp->pfnSSMGetBoolV( pSSM, &pGicVCpu->fIrqGrp0Enabled); 317 pHlp->pfnSSMGetBoolV( pSSM, &pGicVCpu->fIrqGrp1Enabled); 318 pHlp->pfnSSMGetU8V( pSSM, &pGicVCpu->bInterruptPriority); 319 pHlp->pfnSSMGetU8( pSSM, &pGicVCpu->bBinaryPointGrp0); 320 pHlp->pfnSSMGetU8( pSSM, &pGicVCpu->bBinaryPointGrp1); 321 pHlp->pfnSSMGetMem( pSSM, (void *)&pGicVCpu->abRunningPriorities[0], sizeof(pGicVCpu->abRunningPriorities)); 322 rc = pHlp->pfnSSMGetU8V(pSSM, &pGicVCpu->idxRunningPriority); 323 if (RT_FAILURE(rc)) 324 return rc; 325 } 326 327 return rc; 328 } 329 330 331 /** 155 332 * @interface_method_impl{PDMDEVREG,pfnReset} 156 333 */ … … 283 460 284 461 /* 462 * Register saved state callbacks. 463 */ 464 rc = PDMDevHlpSSMRegister(pDevIns, GIC_SAVED_STATE_VERSION, 0, gicR3SaveExec, gicR3LoadExec); 465 AssertRCReturn(rc, rc); 466 467 /* 285 468 * Register debugger info callbacks. 286 469 *
Note:
See TracChangeset
for help on using the changeset viewer.