- Timestamp:
- Sep 12, 2008 3:08:00 PM (16 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevACPI.cpp
r12311 r12428 159 159 uint16_t pm1a_sts; 160 160 uint16_t pm1a_ctl; 161 uint16_t Alignment0; 161 /** Number of logical CPUs in guest */ 162 uint16_t cCpus; 162 163 int64_t pm_timer_initial; 163 164 PTMTIMERR3 tsR3; … … 199 200 /** Pointer to the driver connector interface */ 200 201 R3PTRTYPE(PPDMIACPICONNECTOR) pDrv; 201 #if 0202 /** Number of logical CPUs in guest */203 uint16_t cCpus;204 #endif205 202 }; 206 203 … … 403 400 404 401 /** Multiple APIC Description Table */ 402 #ifdef VBOX_WITH_SMP_GUESTS 403 404 #define PCAT_COMPAT 0x1 /**< system has also a dual-8259 setup */ 405 406 /* 407 * This structure looks somewhat convoluted due layout of MADT table in MP case. 408 * There extpected to be multiple LAPIC records for each CPU, thus we cannot 409 * use regular C structure and proxy to raw memory instead. 410 */ 411 class ACPITBLMADT 412 { 413 /* 414 * All actual data stored in dynamically allocated memory pointed by this field. 415 */ 416 uint8_t* pData; 417 /* 418 * Number of CPU entries in this MADT. 419 */ 420 uint32_t cCpus; 421 422 public: 423 /* 424 * Address of ACPI header 425 */ 426 inline ACPITBLHEADER* header_addr() const 427 { 428 return (ACPITBLHEADER*)pData; 429 } 430 431 /* 432 * Address of local APIC for each CPU. Note that different CPUs address different LAPICs, 433 * although address is the same for all of them. 434 */ 435 inline uint32_t* u32LAPIC_addr() const 436 { 437 return (uint32_t*)(header_addr() + 1); 438 } 439 440 /* 441 * Address of APIC flags 442 */ 443 inline uint32_t* u32Flags_addr() const 444 { 445 return (uint32_t*)(u32LAPIC_addr() + 1); 446 } 447 448 /* 449 * Address of per-CPU LAPIC descriptions 450 */ 451 inline ACPITBLLAPIC* LApics_addr() const 452 { 453 return (ACPITBLLAPIC*)(u32Flags_addr() + 1); 454 } 455 456 /* 457 * Address of IO APIC description 458 */ 459 inline ACPITBLIOAPIC* IOApic_addr() const 460 { 461 return (ACPITBLIOAPIC*)(LApics_addr() + cCpus); 462 } 463 464 /* 465 * Size of MADT. 466 * Note that this function assumes IOApic to be the last field in structure. 467 */ 468 inline uint32_t size() const 469 { 470 return (uint8_t*)(IOApic_addr() + 1)-(uint8_t*)header_addr(); 471 } 472 473 /* 474 * Raw data of MADT. 475 */ 476 inline const uint8_t* data() const 477 { 478 return pData; 479 } 480 481 /* 482 * Size of MADT for given ACPI config, useful to compute layout. 483 */ 484 static uint32_t sizeFor(ACPIState *s) 485 { 486 return ACPITBLMADT(s->cCpus).size(); 487 } 488 489 /* 490 * Constructor, only works in Ring 3, doesn't look like a big deal. 491 */ 492 ACPITBLMADT(uint16_t cpus) 493 { 494 cCpus = cpus; 495 pData = 0; 496 #ifdef IN_RING3 497 uint32_t sSize = size(); 498 pData = (uint8_t*)RTMemAllocZ(sSize); 499 #else 500 AssertMsgFailed(("cannot use in inner rings")); 501 #endif 502 } 503 504 ~ACPITBLMADT() 505 { 506 #ifdef IN_RING3 507 RTMemFree(pData); 508 #else 509 AssertMsgFailed(("cannot use in inner rings")); 510 #endif 511 } 512 }; 513 #else 405 514 struct ACPITBLMADT 406 515 { … … 413 522 }; 414 523 AssertCompileSize(ACPITBLMADT, 64); 524 #endif 415 525 416 526 #pragma pack() … … 644 754 static void acpiSetupMADT (ACPIState *s, RTGCPHYS32 addr) 645 755 { 756 #if VBOX_WITH_SMP_GUESTS 757 uint16_t cpus = s->cCpus; 758 ACPITBLMADT madt(cpus); 759 760 acpiPrepareHeader(madt.header_addr(), "APIC", madt.size(), 2); 761 762 *madt.u32LAPIC_addr() = RT_H2LE_U32(0xfee00000); 763 *madt.u32Flags_addr() = RT_H2LE_U32(PCAT_COMPAT); 764 765 ACPITBLLAPIC* lapic = madt.LApics_addr(); 766 for (uint16_t i = 0; i < cpus; i++) 767 { 768 lapic->u8Type = 0; 769 lapic->u8Length = sizeof(ACPITBLLAPIC); 770 lapic->u8ProcId = i; 771 lapic->u8ApicId = i; 772 lapic->u32Flags = RT_H2LE_U32(LAPIC_ENABLED); 773 lapic++; 774 } 775 776 ACPITBLIOAPIC* ioapic = madt.IOApic_addr(); 777 778 ioapic->u8Type = 1; 779 ioapic->u8Length = sizeof(ACPITBLIOAPIC); 780 ioapic->u8IOApicId = cpus; 781 ioapic->u8Reserved = 0; 782 ioapic->u32Address = RT_H2LE_U32(0xfec00000); 783 ioapic->u32GSIB = RT_H2LE_U32(0); 784 785 madt.header_addr()->u8Checksum = acpiChecksum (madt.data(), madt.size()); 786 acpiPhyscpy (s, addr, madt.data(), madt.size()); 787 788 #else 646 789 ACPITBLMADT madt; 647 790 … … 670 813 madt.header.u8Checksum = acpiChecksum ((uint8_t*)&madt, sizeof(madt)); 671 814 acpiPhyscpy (s, addr, &madt, sizeof(madt)); 815 #endif 672 816 } 673 817 … … 1512 1656 N_("Configuration error: Invalid \"RamSize\", maximum allowed " 1513 1657 "value is 4095MB")); 1514 1515 1658 rsdt_addr = 0; 1516 1659 xsdt_addr = RT_ALIGN_32 (rsdt_addr + rsdt_tbl_len, 16); … … 1520 1663 { 1521 1664 apic_addr = RT_ALIGN_32 (facs_addr + sizeof(ACPITBLFACS), 16); 1665 #ifdef VBOX_WITH_SMP_GUESTS 1666 /* 1667 * @todo r=nike maybe some refactoring needed to compute tables layout, 1668 * but as this code is executed only once it doesn't make sense to optimize much 1669 */ 1670 dsdt_addr = RT_ALIGN_32 (apic_addr + ACPITBLMADT::sizeFor(s), 16); 1671 #else 1522 1672 dsdt_addr = RT_ALIGN_32 (apic_addr + sizeof(ACPITBLMADT), 16); 1673 #endif 1523 1674 } 1524 1675 else … … 1598 1749 N_("Configuration error: Failed to read \"IOAPIC\"")); 1599 1750 1600 #if 01601 1751 rc = CFGMR3QueryU16Def(pCfgHandle, "NumCPUs", &s->cCpus, 1); 1602 1752 if (RT_FAILURE(rc)) 1603 1753 return PDMDEV_SET_ERROR(pDevIns, rc, 1604 1754 N_("Configuration error: Querying \"NumCPUs\" as integer failed")); 1605 #endif1606 1755 1607 1756 /* query whether we are supposed to present an FDC controller */ -
trunk/src/VBox/Devices/PC/DevPcBios.cpp
r12311 r12428 1397 1397 1398 1398 #ifdef VBOX_WITH_SMP_GUESTS 1399 pThis->cCpus = 2; 1400 LogRel(("Running with %d CPUs\n", pThis->cCpus)); 1399 LogRel(("[SMP] BIOS with %d CPUs\n", pThis->cCpus)); 1401 1400 #else 1402 1401 if (pThis->cCpus != 1) -
trunk/src/VBox/Main/ConsoleImpl2.cpp
r12028 r12428 134 134 hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs); H(); 135 135 136 #ifdef VBOX_WITH_SMP_GUESTS 137 /* @todo: r=nike: Testing code, should use actual getter when ready */ 138 uint16_t cNumCpus = 2; 139 #else 140 uint16_t cNumCpus = 1; 141 #endif 136 142 137 143 /* … … 151 157 rc = CFGMR3InsertBytes(pRoot, "UUID", pUuid, sizeof(*pUuid)); RC_CHECK(); 152 158 rc = CFGMR3InsertInteger(pRoot, "RamSize", cRamMBs * _1M); RC_CHECK(); 159 rc = CFGMR3InsertInteger(pRoot, "NumCPUs", cNumCpus); RC_CHECK(); 153 160 rc = CFGMR3InsertInteger(pRoot, "TimerMillies", 10); RC_CHECK(); 154 161 rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled", 1); /* boolean */ RC_CHECK(); … … 272 279 rc = CFGMR3InsertNode(pInst, "Config", &pBiosCfg); RC_CHECK(); 273 280 rc = CFGMR3InsertInteger(pBiosCfg, "RamSize", cRamMBs * _1M); RC_CHECK(); 281 rc = CFGMR3InsertInteger(pBiosCfg, "NumCPUs", cNumCpus); RC_CHECK(); 274 282 rc = CFGMR3InsertString(pBiosCfg, "HardDiskDevice", "piix3ide"); RC_CHECK(); 275 283 rc = CFGMR3InsertString(pBiosCfg, "FloppyDevice", "i82078"); RC_CHECK(); … … 457 465 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK(); 458 466 rc = CFGMR3InsertInteger(pCfg, "RamSize", cRamMBs * _1M); RC_CHECK(); 467 rc = CFGMR3InsertInteger(pCfg, "NumCPUs", cNumCpus); RC_CHECK(); 468 459 469 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); RC_CHECK(); 460 470 rc = CFGMR3InsertInteger(pCfg, "FdcEnabled", fFdcEnabled); RC_CHECK();
Note:
See TracChangeset
for help on using the changeset viewer.