Changeset 109166 in vbox for trunk/src/VBox/VMM/tools/VBoxCpuReport-arm.cpp
- Timestamp:
- May 5, 2025 11:50:35 PM (7 days ago)
- svn:sync-xref-src-repo-rev:
- 168724
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/tools/VBoxCpuReport-arm.cpp
r109139 r109166 40 40 #include <VBox/sup.h> 41 41 42 #ifdef RT_OS_DARWIN 43 # include <Hypervisor/Hypervisor.h> 44 #endif 45 42 46 #include "VBoxCpuReport.h" 43 47 … … 84 88 static uint32_t g_cCmnSysRegVals = 0; 85 89 static SUPARMSYSREGVAL g_aCmnSysRegVals[256]; 90 91 static bool g_fOtherSysRegSource = false; 86 92 87 93 … … 190 196 READ_SYS_REG__TODO(3, 1, 0, 0, 1, CLIDR_EL1); 191 197 READ_SYS_REG__TODO(3, 1, 0, 0, 7, AIDR_EL1); 198 READ_SYS_REG_NAMED(3, 3, 0, 0, 1, CTR_EL0); 192 199 READ_SYS_REG_NAMED(3, 3, 0, 0, 7, DCZID_EL0); 193 200 READ_SYS_REG_NAMED(3, 3,14, 0, 0, CNTFRQ_EL0); 194 195 201 196 202 READ_SYS_REG_NAMED(3, 0, 0, 4, 0, ID_AA64PFR0_EL1); … … 310 316 311 317 318 static int populateSystemRegistersComplete(void) 319 { 320 vbCpuRepDebug("Detected %u variants across %u online CPUs\n", g_cVariations, g_cCores); 321 322 /* 323 * Now, destill similar register values and unique ones. 324 * This isn't too complicated since the arrays have been sorted. 325 */ 326 g_cCmnSysRegVals = 0; 327 328 uint32_t cMaxRegs = g_aVariations[0].cSysRegVals; 329 for (unsigned i = 0; i < g_cVariations; i++) 330 cMaxRegs = RT_MAX(cMaxRegs, g_aVariations[i].cSysRegVals); 331 332 struct 333 { 334 unsigned idxSrc; 335 unsigned idxDst; 336 } aState[RTCPUSET_MAX_CPUS] = { {0, 0} }; 337 338 for (;;) 339 { 340 /* Find the min & max register value. */ 341 uint32_t idRegMax = 0; 342 uint32_t idRegMin = UINT32_MAX; 343 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 344 { 345 unsigned const idxSrc = aState[iVar].idxSrc; 346 347 uint32_t const idReg = idxSrc < g_aVariations[iVar].cSysRegVals 348 ? g_aVariations[iVar].aSysRegVals[idxSrc].idReg : UINT32_MAX; 349 idRegMax = RT_MAX(idRegMax, idReg); 350 idRegMin = RT_MIN(idRegMin, idReg); 351 } 352 if (idRegMin == UINT32_MAX) 353 break; 354 355 /* Advance all arrays till we've reached idRegMax. */ 356 unsigned cMatchedMax = 0; 357 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 358 { 359 unsigned idxSrc = aState[iVar].idxSrc; 360 unsigned idxDst = aState[iVar].idxDst; 361 while ( idxSrc < g_aVariations[iVar].cSysRegVals 362 && g_aVariations[iVar].aSysRegVals[idxSrc].idReg < idRegMax) 363 g_aVariations[iVar].aSysRegVals[idxDst++] = g_aVariations[iVar].aSysRegVals[idxSrc++]; 364 cMatchedMax += idxSrc < g_aVariations[iVar].cSysRegVals 365 && g_aVariations[iVar].aSysRegVals[idxSrc].idReg == idRegMax; 366 aState[iVar].idxSrc = idxSrc; 367 aState[iVar].idxDst = idxDst; 368 } 369 if (idRegMax == UINT32_MAX) 370 break; 371 372 if (cMatchedMax == g_cVariations) 373 { 374 /* Check if all the values match. */ 375 uint64_t const uValue0 = g_aVariations[0].aSysRegVals[aState[0].idxSrc].uValue; 376 uint32_t const fFlags0 = g_aVariations[0].aSysRegVals[aState[0].idxSrc].fFlags; 377 unsigned cMatches = 1; 378 for (unsigned iVar = 1; iVar < g_cVariations; iVar++) 379 { 380 unsigned const idxSrc = aState[iVar].idxSrc; 381 Assert(idxSrc < g_aVariations[iVar].cSysRegVals); 382 Assert(g_aVariations[iVar].aSysRegVals[idxSrc].idReg == idRegMax); 383 cMatches += g_aVariations[iVar].aSysRegVals[idxSrc].uValue == uValue0 384 && g_aVariations[iVar].aSysRegVals[idxSrc].fFlags == fFlags0; 385 } 386 if (cMatches == g_cVariations) 387 { 388 g_aCmnSysRegVals[g_cCmnSysRegVals++] = g_aVariations[0].aSysRegVals[aState[0].idxSrc]; 389 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 390 aState[iVar].idxSrc += 1; 391 continue; 392 } 393 vbCpuRepDebug("%#x: missed #2\n", idRegMax); 394 } 395 else 396 vbCpuRepDebug("%#x: missed #1\n", idRegMax); 397 398 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 399 { 400 Assert(aState[iVar].idxSrc < g_aVariations[iVar].cSysRegVals); 401 g_aVariations[iVar].aSysRegVals[aState[iVar].idxDst++] 402 = g_aVariations[iVar].aSysRegVals[aState[iVar].idxSrc++]; 403 } 404 } 405 vbCpuRepDebug("Common register values: %u\n", g_cCmnSysRegVals); 406 407 /* Anything left in any of the arrays are considered unique and needs to be moved up. */ 408 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 409 { 410 unsigned idxSrc = aState[iVar].idxSrc; 411 unsigned idxDst = aState[iVar].idxDst; 412 Assert(idxDst <= idxSrc); 413 Assert(idxSrc == g_aVariations[iVar].cSysRegVals); 414 while (idxSrc < g_aVariations[iVar].cSysRegVals) 415 g_aVariations[iVar].aSysRegVals[idxDst++] = g_aVariations[iVar].aSysRegVals[idxSrc++]; 416 g_aVariations[iVar].cSysRegVals = idxDst; 417 vbCpuRepDebug("Var #%u register values: %u\n", iVar, idxDst); 418 } 419 return VINF_SUCCESS; 420 } 421 422 312 423 /** 313 424 * Populates g_aSysRegVals and g_cSysRegVals … … 324 435 * Get the registers for online each CPU in the system, sorting them. 325 436 */ 437 vbCpuRepDebug("Gathering CPU info via the support driver...\n"); 326 438 for (int idxCpu = 0, iVar = 0; idxCpu < RTCPUSET_MAX_CPUS; idxCpu++) 327 439 if (RTMpIsCpuOnline(idxCpu)) … … 400 512 } 401 513 402 vbCpuRepDebug("Detected %u variants across %u online CPUs\n", g_cVariations, g_cCores); 403 404 /* 405 * Now, destill similar register values and unique ones. 406 * This isn't too complicated since the arrays have been sorted. 407 */ 408 g_cCmnSysRegVals = 0; 409 410 uint32_t cMaxRegs = g_aVariations[0].cSysRegVals; 411 for (unsigned i = 0; i < g_cVariations; i++) 412 cMaxRegs = RT_MAX(cMaxRegs, g_aVariations[i].cSysRegVals); 413 414 struct 514 return populateSystemRegistersComplete(); 515 } 516 RTMsgErrorRc(rc, "Unable to initialize the support library (%Rrc).", rc); 517 518 #ifdef RT_OS_DARWIN 519 /* 520 * Create a VM and gather the information from it. 521 * 522 * As it turns out, this isn't much better than nemR3DarwinNativeInitVCpuOnEmt(), 523 * but it's something... 524 */ 525 hv_return_t rcHv = hv_vm_create(NULL); 526 if (rcHv == HV_SUCCESS) 527 { 528 /* Create a configuration so we can query . */ 529 hv_vcpu_config_t hVCpuCfg = hv_vcpu_config_create(); 530 if (hVCpuCfg == NULL) 531 vbCpuRepDebug("Warning! hv_vcpu_config_create failed\n"); 532 533 hv_vcpu_t hVCpu = UINT64_MAX / 2; 534 hv_vcpu_exit_t *pExitInfo = NULL; 535 rcHv = hv_vcpu_create(&hVCpu, &pExitInfo, NULL /*hConfig*/); 536 if (rcHv == HV_SUCCESS) 415 537 { 416 unsigned idxSrc; 417 unsigned idxDst; 418 } aState[RTCPUSET_MAX_CPUS] = { {0, 0} }; 419 420 for (;;) 538 vbCpuRepDebug("Gathering (guest) CPU info via hv_vm_create...\n"); 539 unsigned const iVar = 0; 540 g_cCores = g_aVariations[iVar].cCores = RTCpuSetCount(RTMpGetOnlineSet(&g_aVariations[iVar].bmMembers)); 541 g_cVariations = 1; 542 unsigned iReg = 0; 543 # define ADD_REG(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_uValue) do { \ 544 g_aVariations[iVar].aSysRegVals[iReg].fFlags = 0; \ 545 g_aVariations[iVar].aSysRegVals[iReg].idReg = ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2); \ 546 g_aVariations[iVar].aSysRegVals[iReg].uValue = a_uValue; \ 547 g_aVariations[iVar].cSysRegVals = ++iReg; \ 548 } while (0) 549 550 # define READ_SYS_REG_UNDEF_U(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2) do { \ 551 uint64_t uValue = 0; \ 552 hv_sys_reg_t const enmSysReg = (hv_sys_reg_t)ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2); \ 553 hv_return_t const rcHvGet = hv_vcpu_get_sys_reg(hVCpu, enmSysReg, &uValue); \ 554 if (rcHvGet == HV_SUCCESS) ADD_REG(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, uValue); \ 555 else vbCpuRepDebug("Warning! hv_vcpu_get_sys_reg(%u,%u,%u,%u,%u) failed on line %u: %#x (%d)\n", \ 556 a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, __LINE__, rcHvGet, rcHvGet); \ 557 } while (0) 558 559 # define READ_SYS_REG__TODO_U(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName) do { \ 560 uint64_t uValue = 0; \ 561 hv_sys_reg_t const enmSysReg = (hv_sys_reg_t)ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2); \ 562 hv_return_t const rcHvGet = hv_vcpu_get_sys_reg(hVCpu, enmSysReg, &uValue); \ 563 if (rcHvGet == HV_SUCCESS) ADD_REG(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, uValue); \ 564 else vbCpuRepDebug("Warning! hv_vcpu_get_sys_reg(" #a_SysRegName ") failed: %#x (%d)\n", rcHvGet, rcHvGet); \ 565 } while (0) 566 567 # define READ_SYS_REG__TODO_F(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName) do { \ 568 uint64_t uValue = 0; \ 569 hv_return_t const rcHvGet = hv_vcpu_config_get_feature_reg(hVCpuCfg, RT_CONCAT(HV_FEATURE_REG_,a_SysRegName), &uValue); \ 570 if (rcHvGet == HV_SUCCESS) ADD_REG(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, uValue); \ 571 else vbCpuRepDebug("Warning! hv_vcpu_get_sys_reg(" #a_SysRegName ") failed: %#x (%d)\n", rcHvGet, rcHvGet); \ 572 } while (0) 573 574 # define READ_SYS_REG_NAMED_U(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName) do { \ 575 AssertCompile( ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2) \ 576 == RT_CONCAT(ARMV8_AARCH64_SYSREG_,a_SysRegName)); \ 577 READ_SYS_REG__TODO_U(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName); \ 578 } while (0) 579 580 # define READ_SYS_REG_NAMED_F(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName) do { \ 581 AssertCompile( ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2) \ 582 == RT_CONCAT(ARMV8_AARCH64_SYSREG_,a_SysRegName)); \ 583 READ_SYS_REG__TODO_F(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName); \ 584 } while (0) 585 586 # define READ_SYS_REG_NAMED_B(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName) do { \ 587 AssertCompile( ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2) \ 588 == RT_CONCAT(ARMV8_AARCH64_SYSREG_,a_SysRegName)); \ 589 /* 1. sys_reg */ \ 590 uint64_t uValueSys = 0; \ 591 hv_sys_reg_t const enmSysReg = (hv_sys_reg_t)ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2); \ 592 hv_return_t const rcHvSys = hv_vcpu_get_sys_reg(hVCpu, enmSysReg, &uValueSys); \ 593 if (rcHvSys == HV_SUCCESS) ADD_REG(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, uValueSys); \ 594 else vbCpuRepDebug("Warning! hv_vcpu_get_sys_reg(" #a_SysRegName ") failed: %#x (%d)\n", rcHvSys, rcHvSys); \ 595 /* 2. feature: */ \ 596 uint64_t uValueFeature = 0; \ 597 hv_return_t const rcHvFeat = hv_vcpu_config_get_feature_reg(hVCpuCfg, RT_CONCAT(HV_FEATURE_REG_,a_SysRegName), &uValueFeature); \ 598 if (rcHvFeat != HV_SUCCESS) vbCpuRepDebug("Warning! hv_vcpu_config_get_feature_reg(" #a_SysRegName ") failed: %#x (%d)\n", rcHvFeat, rcHvFeat); \ 599 else if (rcHvSys != HV_SUCCESS) ADD_REG(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, uValueFeature); \ 600 else if (uValueFeature != uValueSys) \ 601 vbCpuRepDebug("Warning! ARMV8_AARCH64_SYSREG_" #a_SysRegName "=%#RX64 while HV_FEATURE_REG_" #a_SysRegName "=%#RX64, diff: %#RX64\n", \ 602 uValueSys, uValueFeature, uValueSys ^ uValueFeature); \ 603 } while (0) 604 605 # define READ_SYS_REG_NAMED_S(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName) do { \ 606 AssertCompile( ARMV8_AARCH64_SYSREG_ID_CREATE(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2) \ 607 == (uint32_t)RT_CONCAT(HV_SYS_REG_,a_SysRegName)); \ 608 READ_SYS_REG_NAMED_U(a_Op0, a_Op1, a_CRn, a_CRm, a_Op2, a_SysRegName); \ 609 } while (0) 610 611 READ_SYS_REG_NAMED_S(3, 0, 0, 0, 0, MIDR_EL1); 612 READ_SYS_REG_NAMED_S(3, 0, 0, 0, 5, MPIDR_EL1); 613 READ_SYS_REG_NAMED_U(3, 0, 0, 0, 6, REVIDR_EL1); 614 READ_SYS_REG__TODO_U(3, 1, 0, 0, 0, CCSIDR_EL1); 615 READ_SYS_REG__TODO_F(3, 1, 0, 0, 1, CLIDR_EL1); 616 READ_SYS_REG__TODO_U(3, 1, 0, 0, 7, AIDR_EL1); 617 READ_SYS_REG_NAMED_F(3, 3, 0, 0, 1, CTR_EL0); /** @todo */ 618 READ_SYS_REG_NAMED_F(3, 3, 0, 0, 7, DCZID_EL0); 619 READ_SYS_REG_NAMED_U(3, 3,14, 0, 0, CNTFRQ_EL0); 620 621 READ_SYS_REG_NAMED_B(3, 0, 0, 4, 0, ID_AA64PFR0_EL1); 622 READ_SYS_REG_NAMED_B(3, 0, 0, 4, 1, ID_AA64PFR1_EL1); 623 READ_SYS_REG_UNDEF_U(3, 0, 0, 4, 2); 624 READ_SYS_REG_UNDEF_U(3, 0, 0, 4, 3); 625 READ_SYS_REG_NAMED_U(3, 0, 0, 4, 4, ID_AA64ZFR0_EL1); // undefined in older SDKs. 626 READ_SYS_REG_NAMED_U(3, 0, 0, 4, 5, ID_AA64SMFR0_EL1); // undefined in older SDKs. 627 READ_SYS_REG_UNDEF_U(3, 0, 0, 4, 6); 628 READ_SYS_REG_UNDEF_U(3, 0, 0, 4, 7); 629 630 READ_SYS_REG_NAMED_B(3, 0, 0, 5, 0, ID_AA64DFR0_EL1); 631 READ_SYS_REG_NAMED_B(3, 0, 0, 5, 1, ID_AA64DFR1_EL1); 632 READ_SYS_REG_UNDEF_U(3, 0, 0, 5, 2); 633 READ_SYS_REG_UNDEF_U(3, 0, 0, 5, 3); 634 READ_SYS_REG_NAMED_U(3, 0, 0, 5, 4, ID_AA64AFR0_EL1); 635 READ_SYS_REG_NAMED_U(3, 0, 0, 5, 5, ID_AA64AFR1_EL1); 636 READ_SYS_REG_UNDEF_U(3, 0, 0, 5, 6); 637 READ_SYS_REG_UNDEF_U(3, 0, 0, 5, 7); 638 639 READ_SYS_REG_NAMED_B(3, 0, 0, 6, 0, ID_AA64ISAR0_EL1); 640 READ_SYS_REG_NAMED_B(3, 0, 0, 6, 1, ID_AA64ISAR1_EL1); 641 READ_SYS_REG_NAMED_U(3, 0, 0, 6, 2, ID_AA64ISAR2_EL1); 642 READ_SYS_REG__TODO_U(3, 0, 0, 6, 3, ID_AA64ISAR3_EL1); 643 READ_SYS_REG_UNDEF_U(3, 0, 0, 6, 4); 644 READ_SYS_REG_UNDEF_U(3, 0, 0, 6, 5); 645 READ_SYS_REG_UNDEF_U(3, 0, 0, 6, 6); 646 READ_SYS_REG_UNDEF_U(3, 0, 0, 6, 7); 647 648 READ_SYS_REG_NAMED_B(3, 0, 0, 7, 0, ID_AA64MMFR0_EL1); 649 READ_SYS_REG_NAMED_B(3, 0, 0, 7, 1, ID_AA64MMFR1_EL1); 650 READ_SYS_REG_NAMED_B(3, 0, 0, 7, 2, ID_AA64MMFR2_EL1); 651 READ_SYS_REG__TODO_U(3, 0, 0, 7, 3, ID_AA64MMFR3_EL1); 652 READ_SYS_REG__TODO_U(3, 0, 0, 7, 4, ID_AA64MMFR4_EL1); 653 READ_SYS_REG_UNDEF_U(3, 0, 0, 7, 5); 654 READ_SYS_REG_UNDEF_U(3, 0, 0, 7, 6); 655 READ_SYS_REG_UNDEF_U(3, 0, 0, 7, 7); 656 657 READ_SYS_REG__TODO_U(3, 1, 0, 0, 2, CCSIDR2_EL1); 658 READ_SYS_REG_NAMED_U(3, 0, 5, 3, 0, ERRIDR_EL1); 659 READ_SYS_REG__TODO_U(3, 1, 0, 0, 4, GMID_EL1); 660 661 READ_SYS_REG__TODO_U(3, 0, 10, 4, 4, MPAMIDR_EL1); 662 READ_SYS_REG__TODO_U(3, 0, 10, 4, 5, MPAMBWIDR_EL1); 663 664 READ_SYS_REG__TODO_U(3, 0, 9, 10, 7, PMBIDR_EL1); 665 READ_SYS_REG__TODO_U(3, 0, 9, 8, 7, PMSIDR_EL1); 666 667 READ_SYS_REG__TODO_U(3, 0, 9, 11, 7, TRBIDR_EL1); 668 669 /* Sort it. */ 670 RTSortShell(g_aVariations[iVar].aSysRegVals, g_aVariations[iVar].cSysRegVals, 671 sizeof(g_aVariations[iVar].aSysRegVals[0]), sysRegValSortCmp, NULL); 672 673 # undef ADD_REG 674 # undef READ_SYS_REG_UNDEF_U 675 # undef READ_SYS_REG__TODO_U 676 # undef READ_SYS_REG__TODO_F 677 # undef READ_SYS_REG_NAMED_U 678 # undef READ_SYS_REG_NAMED_F 679 # undef READ_SYS_REG_NAMED_B 680 # undef READ_SYS_REG_NAMED_S 681 hv_vcpu_destroy(hVCpu); 682 } 683 if (hVCpuCfg) 684 os_release(hVCpuCfg); 685 hv_vm_destroy(); 686 if (rcHv == HV_SUCCESS) /* from hv_vcpu_create */ 421 687 { 422 /* Find the min & max register value. */ 423 uint32_t idRegMax = 0; 424 uint32_t idRegMin = UINT32_MAX; 425 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 426 { 427 unsigned const idxSrc = aState[iVar].idxSrc; 428 429 uint32_t const idReg = idxSrc < g_aVariations[iVar].cSysRegVals 430 ? g_aVariations[iVar].aSysRegVals[idxSrc].idReg : UINT32_MAX; 431 idRegMax = RT_MAX(idRegMax, idReg); 432 idRegMin = RT_MIN(idRegMin, idReg); 433 } 434 if (idRegMin == UINT32_MAX) 435 break; 436 437 /* Advance all arrays till we've reached idRegMax. */ 438 unsigned cMatchedMax = 0; 439 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 440 { 441 unsigned idxSrc = aState[iVar].idxSrc; 442 unsigned idxDst = aState[iVar].idxDst; 443 while ( idxSrc < g_aVariations[iVar].cSysRegVals 444 && g_aVariations[iVar].aSysRegVals[idxSrc].idReg < idRegMax) 445 g_aVariations[iVar].aSysRegVals[idxDst++] = g_aVariations[iVar].aSysRegVals[idxSrc++]; 446 cMatchedMax += idxSrc < g_aVariations[iVar].cSysRegVals 447 && g_aVariations[iVar].aSysRegVals[idxSrc].idReg == idRegMax; 448 aState[iVar].idxSrc = idxSrc; 449 aState[iVar].idxDst = idxDst; 450 } 451 if (idRegMax == UINT32_MAX) 452 break; 453 454 if (cMatchedMax == g_cVariations) 455 { 456 /* Check if all the values match. */ 457 uint64_t const uValue0 = g_aVariations[0].aSysRegVals[aState[0].idxSrc].uValue; 458 uint32_t const fFlags0 = g_aVariations[0].aSysRegVals[aState[0].idxSrc].fFlags; 459 unsigned cMatches = 1; 460 for (unsigned iVar = 1; iVar < g_cVariations; iVar++) 461 { 462 unsigned const idxSrc = aState[iVar].idxSrc; 463 Assert(idxSrc < g_aVariations[iVar].cSysRegVals); 464 Assert(g_aVariations[iVar].aSysRegVals[idxSrc].idReg == idRegMax); 465 cMatches += g_aVariations[iVar].aSysRegVals[idxSrc].uValue == uValue0 466 && g_aVariations[iVar].aSysRegVals[idxSrc].fFlags == fFlags0; 467 } 468 if (cMatches == g_cVariations) 469 { 470 g_aCmnSysRegVals[g_cCmnSysRegVals++] = g_aVariations[0].aSysRegVals[aState[0].idxSrc]; 471 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 472 aState[iVar].idxSrc += 1; 473 continue; 474 } 475 vbCpuRepDebug("%#x: missed #2\n", idRegMax); 476 } 477 else 478 vbCpuRepDebug("%#x: missed #1\n", idRegMax); 479 480 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 481 { 482 Assert(aState[iVar].idxSrc < g_aVariations[iVar].cSysRegVals); 483 g_aVariations[iVar].aSysRegVals[aState[iVar].idxDst++] 484 = g_aVariations[iVar].aSysRegVals[aState[iVar].idxSrc++]; 485 } 688 g_fOtherSysRegSource = true; 689 return populateSystemRegistersComplete(); 486 690 } 487 vbCpuRepDebug("Common register values: %u\n", g_cCmnSysRegVals); 488 489 /* Anything left in any of the arrays are considered unique and needs to be moved up. */ 490 for (unsigned iVar = 0; iVar < g_cVariations; iVar++) 491 { 492 unsigned idxSrc = aState[iVar].idxSrc; 493 unsigned idxDst = aState[iVar].idxDst; 494 Assert(idxDst <= idxSrc); 495 Assert(idxSrc == g_aVariations[iVar].cSysRegVals); 496 while (idxSrc < g_aVariations[iVar].cSysRegVals) 497 g_aVariations[iVar].aSysRegVals[idxDst++] = g_aVariations[iVar].aSysRegVals[idxSrc++]; 498 g_aVariations[iVar].cSysRegVals = idxDst; 499 vbCpuRepDebug("Var #%u register values: %u\n", iVar, idxDst); 500 } 501 return rc; 691 return RTMsgErrorRc(rc, "hv_vcpu_create failed: %#x", rcHv); 502 692 } 503 return RTMsgErrorRc(rc, "Unable to initialize the support library (%Rrc).", rc); 504 //vbCpuRepDebug("warning: Unable to initialize the support library (%Rrc).\n", rc); 693 return RTMsgErrorRc(rc, "hv_vm_create failed: %#x", rcHv); 694 695 #elif defined(RT_OS_LINUX) 505 696 /** @todo On Linux we can query the registers exposed to ring-3... */ 697 return rc; 698 699 #else 700 return rc; 701 #endif 506 702 } 507 703 … … 510 706 const char *pszCpuDesc, uint32_t iVariation = UINT32_MAX) 511 707 { 512 if (! g_cCmnSysRegVals)708 if (!cSysRegVals) 513 709 return; 514 710 … … 668 864 } 669 865 if (g_aVariations[iVar].enmMicroarch == kCpumMicroarch_Invalid) 670 return RTMsgErrorRc(VERR_UNSUPPORTED_CPU, "%s part number not found: %#x (MIDR_EL1=%#x%s%s)", 671 CPUMCpuVendorName(g_aVariations[iVar].enmVendor), uPartNum, uMIdReg, 672 *pszCpuName ? " " : "", pszCpuName); 866 { 867 rc = RTMsgErrorRc(VERR_UNSUPPORTED_CPU, "%s part number not found: %#x (MIDR_EL1=%#x%s%s)", 868 CPUMCpuVendorName(g_aVariations[iVar].enmVendor), uPartNum, uMIdReg, 869 *pszCpuName ? " " : "", pszCpuName); 870 #ifdef RT_OS_DARWIN 871 /* Search by CPU name. */ 872 if (pszCpuName && g_fOtherSysRegSource) 873 for (size_t i = 0; i < cPartNums; i++) 874 if ( strcmp(paPartNums[i].pszName, pszCpuName) == 0 875 || strcmp(paPartNums[i].pszFullName, pszCpuName) == 0) 876 { 877 g_aVariations[iVar].enmCoreType = kCpumCoreType_Unknown; 878 g_aVariations[iVar].enmMicroarch = paPartNums[i].enmMicroarch; 879 g_aVariations[iVar].pszName = paPartNums[i].pszName; 880 g_aVariations[iVar].pszFullName = paPartNums[i].pszName; 881 break; 882 } 883 if (g_aVariations[iVar].enmMicroarch == kCpumMicroarch_Invalid) 884 #endif 885 return rc; 886 } 673 887 } 674 888 … … 768 982 " /*.enmVendor = */ CPUMCPUVENDOR_%s,\n" 769 983 " /*.enmMicroarch = */ kCpumMicroarch_%s,\n" 770 " /*.fFlags = */ 0,\n"984 " /*.fFlags = */ %s,\n" 771 985 " },\n" 772 986 " /*.paSysRegCmnVals = */ NULL_ALONE(g_aCmnSysRegVals_%s),\n" … … 782 996 vbCpuVendorToString(g_aVariations[0].enmVendor), 783 997 CPUMMicroarchName(g_aVariations[0].enmMicroarch), 998 !g_fOtherSysRegSource ? "0" : "CPUMDB_F_UNRELIABLE_INFO", 784 999 szNameC, 785 1000 szNameC,
Note:
See TracChangeset
for help on using the changeset viewer.