Changeset 17572 in vbox
- Timestamp:
- Mar 9, 2009 12:58:21 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevACPI.cpp
r17542 r17572 20 20 */ 21 21 22 /******************************************************************************* 23 * Header Files * 24 *******************************************************************************/ 22 25 #define LOG_GROUP LOG_GROUP_DEV_ACPI 23 26 #include <VBox/pdmdev.h> … … 39 42 /* the compiled DSL */ 40 43 #if defined(IN_RING3) && !defined(VBOX_DEVICE_STRUCT_TESTCASE) 41 # include <vboxaml.hex>44 # include <vboxaml.hex> 42 45 #endif /* !IN_RING3 */ 43 46 44 #define IO_READ_PROTO(name) \ 45 PDMBOTHCBDECL(int) name (PPDMDEVINS pDevIns, void *pvUser, \ 46 RTIOPORT Port, uint32_t *pu32, unsigned cb) 47 48 #define IO_WRITE_PROTO(name) \ 49 PDMBOTHCBDECL(int) name (PPDMDEVINS pDevIns, void *pvUser, \ 50 RTIOPORT Port, uint32_t u32, unsigned cb) 51 47 48 49 /******************************************************************************* 50 * Defined Constants And Macros * 51 *******************************************************************************/ 52 52 #define DEBUG_HEX 0x3000 53 53 #define DEBUG_CHR 0x3001 … … 156 156 #define STA_BATTERY_PRESENT_MASK RT_BIT(4) /**< the battery is present */ 157 157 158 struct ACPIState 158 159 /******************************************************************************* 160 * Structures and Typedefs * 161 *******************************************************************************/ 162 /** 163 * The ACPI device state. 164 */ 165 typedef struct ACPIState 159 166 { 160 167 PCIDevice dev; … … 214 221 /** Pointer to the driver connector interface */ 215 222 R3PTRTYPE(PPDMIACPICONNECTOR) pDrv; 216 } ;223 } ACPIState; 217 224 218 225 #pragma pack(1) … … 414 421 415 422 #ifdef VBOX_WITH_SMP_GUESTS 416 # ifdef IN_RING3 /**@todo r=bird: Move this down to where it's used. */417 418 # define PCAT_COMPAT0x1 /**< system has also a dual-8259 setup */423 # ifdef IN_RING3 /**@todo r=bird: Move this down to where it's used. */ 424 425 # define PCAT_COMPAT 0x1 /**< system has also a dual-8259 setup */ 419 426 420 427 /** … … 430 437 * All actual data stored in dynamically allocated memory pointed by this field. 431 438 */ 432 uint8_t * pData;439 uint8_t *m_pbData; 433 440 /** 434 441 * Number of CPU entries in this MADT. 435 442 */ 436 uint32_t cCpus;437 438 443 uint32_t m_cCpus; 444 445 public: 439 446 /** 440 447 * Address of ACPI header 441 448 */ 442 inline ACPITBLHEADER * header_addr() const443 { 444 return (ACPITBLHEADER *)pData;449 inline ACPITBLHEADER *header_addr(void) const 450 { 451 return (ACPITBLHEADER *)m_pbData; 445 452 } 446 453 … … 449 456 * although address is the same for all of them. 450 457 */ 451 inline uint32_t * u32LAPIC_addr() const452 { 453 return (uint32_t*)(header_addr() + 1);458 inline uint32_t *u32LAPIC_addr(void) const 459 { 460 return (uint32_t *)(header_addr() + 1); 454 461 } 455 462 … … 457 464 * Address of APIC flags 458 465 */ 459 inline uint32_t * u32Flags_addr() const460 { 461 return (uint32_t *)(u32LAPIC_addr() + 1);466 inline uint32_t *u32Flags_addr(void) const 467 { 468 return (uint32_t *)(u32LAPIC_addr() + 1); 462 469 } 463 470 … … 465 472 * Address of per-CPU LAPIC descriptions 466 473 */ 467 inline ACPITBLLAPIC * LApics_addr() const468 { 469 return (ACPITBLLAPIC *)(u32Flags_addr() + 1);474 inline ACPITBLLAPIC *LApics_addr(void) const 475 { 476 return (ACPITBLLAPIC *)(u32Flags_addr() + 1); 470 477 } 471 478 … … 473 480 * Address of IO APIC description 474 481 */ 475 inline ACPITBLIOAPIC * IOApic_addr() const476 { 477 return (ACPITBLIOAPIC *)(LApics_addr() +cCpus);482 inline ACPITBLIOAPIC *IOApic_addr(void) const 483 { 484 return (ACPITBLIOAPIC *)(LApics_addr() + m_cCpus); 478 485 } 479 486 … … 482 489 * Note that this function assumes IOApic to be the last field in structure. 483 490 */ 484 inline uint32_t size( ) const485 { 486 return (uint8_t *)(IOApic_addr() + 1)-(uint8_t*)header_addr();491 inline uint32_t size(void) const 492 { 493 return (uint8_t *)(IOApic_addr() + 1) - (uint8_t *)header_addr(); 487 494 } 488 495 … … 490 497 * Raw data of MADT. 491 498 */ 492 inline const uint8_t * data() const493 { 494 return pData;499 inline const uint8_t *data(void) const 500 { 501 return m_pbData; 495 502 } 496 503 … … 506 513 * Constructor, only works in Ring 3, doesn't look like a big deal. 507 514 */ 508 AcpiTableMADT(uint16_t cpus) 509 { 510 cCpus = cpus; 511 pData = 0; 512 uint32_t sSize = size(); 513 pData = (uint8_t*)RTMemAllocZ(sSize); 515 AcpiTableMADT(uint32_t cCpus) 516 { 517 m_cCpus = cCpus; 518 uint32_t cb = size(); 519 m_pbData = (uint8_t *)RTMemAllocZ(cb); 514 520 } 515 521 516 522 ~AcpiTableMADT() 517 523 { 518 RTMemFree( pData);524 RTMemFree(m_pbData); 519 525 } 520 526 }; 521 # endif /* IN_RING3 */527 # endif /* IN_RING3 */ 522 528 523 529 #else /* !VBOX_WITH_SMP_GUESTS */ … … 528 534 uint32_t u32LAPIC; /**< local APIC address */ 529 535 uint32_t u32Flags; /**< Flags */ 530 # define PCAT_COMPAT0x1 /**< system has also a dual-8259 setup */536 # define PCAT_COMPAT 0x1 /**< system has also a dual-8259 setup */ 531 537 ACPITBLLAPIC LApic; 532 538 ACPITBLIOAPIC IOApic; … … 538 544 539 545 540 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 546 #ifndef VBOX_DEVICE_STRUCT_TESTCASE /* exclude the rest of the file */ 547 /******************************************************************************* 548 * Internal Functions * 549 *******************************************************************************/ 541 550 __BEGIN_DECLS 542 IO_READ_PROTO (acpiPMTmrRead);551 PDMBOTHCBDECL(int) acpiPMTmrRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 543 552 #ifdef IN_RING3 544 IO_READ_PROTO (acpiPm1aEnRead);545 IO_WRITE_PROTO (acpiPM1aEnWrite);546 IO_READ_PROTO (acpiPm1aStsRead);547 IO_WRITE_PROTO (acpiPM1aStsWrite);548 IO_READ_PROTO (acpiPm1aCtlRead);549 IO_WRITE_PROTO (acpiPM1aCtlWrite);550 IO_WRITE_PROTO (acpiSmiWrite);551 IO_WRITE_PROTO (acpiBatIndexWrite);552 IO_READ_PROTO (acpiBatDataRead);553 IO_READ_PROTO (acpiSysInfoDataRead);554 IO_WRITE_PROTO (acpiSysInfoDataWrite);555 IO_READ_PROTO (acpiGpe0EnRead);556 IO_WRITE_PROTO (acpiGpe0EnWrite);557 IO_READ_PROTO (acpiGpe0StsRead);558 IO_WRITE_PROTO (acpiGpe0StsWrite);559 IO_WRITE_PROTO (acpiResetWrite);553 PDMBOTHCBDECL(int) acpiPm1aEnRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 554 PDMBOTHCBDECL(int) acpiPM1aEnWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 555 PDMBOTHCBDECL(int) acpiPm1aStsRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 556 PDMBOTHCBDECL(int) acpiPM1aStsWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 557 PDMBOTHCBDECL(int) acpiPm1aCtlRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 558 PDMBOTHCBDECL(int) acpiPM1aCtlWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 559 PDMBOTHCBDECL(int) acpiSmiWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 560 PDMBOTHCBDECL(int) acpiBatIndexWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 561 PDMBOTHCBDECL(int) acpiBatDataRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 562 PDMBOTHCBDECL(int) acpiSysInfoDataRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 563 PDMBOTHCBDECL(int) acpiSysInfoDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 564 PDMBOTHCBDECL(int) acpiGpe0EnRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 565 PDMBOTHCBDECL(int) acpiGpe0EnWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 566 PDMBOTHCBDECL(int) acpiGpe0StsRead( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); 567 PDMBOTHCBDECL(int) acpiGpe0StsWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 568 PDMBOTHCBDECL(int) acpiResetWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 560 569 # ifdef DEBUG_ACPI 561 IO_WRITE_PROTO (acpiDhexWrite);562 IO_WRITE_PROTO (acpiDchrWrite);570 PDMBOTHCBDECL(int) acpiDhexWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 571 PDMBOTHCBDECL(int) acpiDchrWrite( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); 563 572 # endif 564 #endif 573 #endif /* IN_RING3 */ 565 574 __END_DECLS 566 575 576 567 577 #ifdef IN_RING3 568 578 569 579 /* Simple acpiChecksum: all the bytes must add up to 0. */ 570 static uint8_t acpiChecksum 580 static uint8_t acpiChecksum(const uint8_t * const data, size_t len) 571 581 { 572 582 uint8_t sum = 0; … … 576 586 } 577 587 578 static void acpiPrepareHeader 579 588 static void acpiPrepareHeader(ACPITBLHEADER *header, const char au8Signature[4], 589 uint32_t u32Length, uint8_t u8Revision) 580 590 { 581 591 memcpy(header->au8Signature, au8Signature, 4); … … 601 611 } 602 612 603 static void acpiPhyscpy 604 { 605 PDMDevHlpPhysWrite 606 } 607 608 /* Differentiated System Description Table (DSDT) */609 static void acpiSetupDSDT 610 { 611 acpiPhyscpy 612 } 613 614 /* Firmware ACPI Control Structure (FACS) */615 static void acpiSetupFACS 613 static void acpiPhyscpy(ACPIState *s, RTGCPHYS32 dst, const void * const src, size_t size) 614 { 615 PDMDevHlpPhysWrite(s->pDevIns, dst, src, size); 616 } 617 618 /** Differentiated System Description Table (DSDT) */ 619 static void acpiSetupDSDT(ACPIState *s, RTGCPHYS32 addr) 620 { 621 acpiPhyscpy(s, addr, AmlCode, sizeof(AmlCode)); 622 } 623 624 /** Firmware ACPI Control Structure (FACS) */ 625 static void acpiSetupFACS(ACPIState *s, RTGCPHYS32 addr) 616 626 { 617 627 ACPITBLFACS facs; 618 628 619 memset 620 memcpy 629 memset(&facs, 0, sizeof(facs)); 630 memcpy(facs.au8Signature, "FACS", 4); 621 631 facs.u32Length = RT_H2LE_U32(sizeof(ACPITBLFACS)); 622 632 facs.u32HWSignature = RT_H2LE_U32(0); … … 627 637 facs.u8Version = 1; 628 638 629 acpiPhyscpy (s, addr, (const uint8_t*)&facs, sizeof(facs));630 } 631 632 /* Fixed ACPI Description Table (FADT aka FACP) */633 static void acpiSetupFADT 639 acpiPhyscpy(s, addr, (const uint8_t *)&facs, sizeof(facs)); 640 } 641 642 /** Fixed ACPI Description Table (FADT aka FACP) */ 643 static void acpiSetupFADT(ACPIState *s, RTGCPHYS32 addr, uint32_t facs_addr, uint32_t dsdt_addr) 634 644 { 635 645 ACPITBLFADT fadt; 636 646 637 memset 638 acpiPrepareHeader 647 memset(&fadt, 0, sizeof(fadt)); 648 acpiPrepareHeader(&fadt.header, "FACP", sizeof(fadt), 4); 639 649 fadt.u32FACS = RT_H2LE_U32(facs_addr); 640 650 fadt.u32DSDT = RT_H2LE_U32(dsdt_addr); … … 689 699 acpiWriteGenericAddr(&fadt.X_GPE0BLK, 1, 16, 0, 1, GPE0_BLK); 690 700 acpiWriteGenericAddr(&fadt.X_GPE1BLK, 0, 0, 0, 0, GPE1_BLK); 691 fadt.header.u8Checksum = acpiChecksum ((uint8_t*)&fadt, sizeof(fadt));692 acpiPhyscpy 693 } 694 695 /* 701 fadt.header.u8Checksum = acpiChecksum((uint8_t *)&fadt, sizeof(fadt)); 702 acpiPhyscpy(s, addr, &fadt, sizeof(fadt)); 703 } 704 705 /** 696 706 * Root System Description Table. 697 707 * The RSDT and XSDT tables are basically identical. The only difference is 32 vs 64 bits 698 708 * addresses for description headers. RSDT is for ACPI 1.0. XSDT for ACPI 2.0 and up. 699 709 */ 700 static int acpiSetupRSDT 710 static int acpiSetupRSDT(ACPIState *s, RTGCPHYS32 addr, unsigned int nb_entries, uint32_t *addrs) 701 711 { 702 712 ACPITBLRSDT *rsdt; 703 713 const size_t size = sizeof(ACPITBLHEADER) + nb_entries * sizeof(rsdt->u32Entry[0]); 704 714 705 rsdt = (ACPITBLRSDT*)RTMemAllocZ 715 rsdt = (ACPITBLRSDT*)RTMemAllocZ(size); 706 716 if (!rsdt) 707 717 return PDMDEV_SET_ERROR(s->pDevIns, VERR_NO_TMP_MEMORY, N_("Cannot allocate RSDT")); 708 718 709 acpiPrepareHeader 719 acpiPrepareHeader(&rsdt->header, "RSDT", (uint32_t)size, 1); 710 720 for (unsigned int i = 0; i < nb_entries; ++i) 711 721 { … … 713 723 Log(("Setup RSDT: [%d] = %x\n", i, rsdt->u32Entry[i])); 714 724 } 715 rsdt->header.u8Checksum = acpiChecksum 716 acpiPhyscpy 717 RTMemFree 718 return VINF_SUCCESS; 719 } 720 721 /* Extended System Description Table. */722 static int acpiSetupXSDT 725 rsdt->header.u8Checksum = acpiChecksum((uint8_t*)rsdt, size); 726 acpiPhyscpy(s, addr, rsdt, size); 727 RTMemFree(rsdt); 728 return VINF_SUCCESS; 729 } 730 731 /** Extended System Description Table. */ 732 static int acpiSetupXSDT(ACPIState *s, RTGCPHYS32 addr, unsigned int nb_entries, uint32_t *addrs) 723 733 { 724 734 ACPITBLXSDT *xsdt; 725 735 const size_t size = sizeof(ACPITBLHEADER) + nb_entries * sizeof(xsdt->u64Entry[0]); 726 736 727 xsdt = (ACPITBLXSDT*)RTMemAllocZ 737 xsdt = (ACPITBLXSDT*)RTMemAllocZ(size); 728 738 if (!xsdt) 729 739 return VERR_NO_TMP_MEMORY; 730 740 731 acpiPrepareHeader 741 acpiPrepareHeader(&xsdt->header, "XSDT", (uint32_t)size, 1 /* according to ACPI 3.0 specs */); 732 742 for (unsigned int i = 0; i < nb_entries; ++i) 733 743 { … … 735 745 Log(("Setup XSDT: [%d] = %RX64\n", i, xsdt->u64Entry[i])); 736 746 } 737 xsdt->header.u8Checksum = acpiChecksum 738 acpiPhyscpy 739 RTMemFree 740 return VINF_SUCCESS; 741 } 742 743 /* Root System Description Pointer (RSDP) */744 static void acpiSetupRSDP 747 xsdt->header.u8Checksum = acpiChecksum((uint8_t*)xsdt, size); 748 acpiPhyscpy(s, addr, xsdt, size); 749 RTMemFree(xsdt); 750 return VINF_SUCCESS; 751 } 752 753 /** Root System Description Pointer (RSDP) */ 754 static void acpiSetupRSDP(ACPITBLRSDP *rsdp, uint32_t rsdt_addr, uint64_t xsdt_addr) 745 755 { 746 756 memset(rsdp, 0, sizeof(*rsdp)); … … 756 766 rsdp->u32Length = RT_H2LE_U32(sizeof(ACPITBLRSDP)); 757 767 rsdp->u64XSDT = RT_H2LE_U64(xsdt_addr); 758 rsdp->u8ExtChecksum = acpiChecksum ((uint8_t*)rsdp, sizeof(ACPITBLRSDP)); 759 } 760 761 /* Multiple APIC Description Table. */ 762 /** @todo All hardcoded, should set this up based on the actual VM config!!!!! */ 763 /** @note APIC without IO-APIC hangs Windows Vista therefore we setup both */ 764 static void acpiSetupMADT (ACPIState *s, RTGCPHYS32 addr) 768 rsdp->u8ExtChecksum = acpiChecksum((uint8_t*)rsdp, sizeof(ACPITBLRSDP)); 769 } 770 771 /** 772 * Multiple APIC Description Table. 773 * 774 * @note APIC without IO-APIC hangs Windows Vista therefore we setup both 775 * 776 * @todo All hardcoded, should set this up based on the actual VM config!!!!! 777 */ 778 static void acpiSetupMADT(ACPIState *s, RTGCPHYS32 addr) 765 779 { 766 780 #ifdef VBOX_WITH_SMP_GUESTS … … 793 807 ioapic->u32GSIB = RT_H2LE_U32(0); 794 808 795 madt.header_addr()->u8Checksum = acpiChecksum 796 acpiPhyscpy 809 madt.header_addr()->u8Checksum = acpiChecksum(madt.data(), madt.size()); 810 acpiPhyscpy(s, addr, madt.data(), madt.size()); 797 811 798 812 #else /* !VBOX_WITH_SMP_GUESTS */ … … 821 835 madt.IOApic.u32GSIB = RT_H2LE_U32(0); 822 836 823 madt.header.u8Checksum = acpiChecksum 824 acpiPhyscpy 837 madt.header.u8Checksum = acpiChecksum((uint8_t*)&madt, sizeof(madt)); 838 acpiPhyscpy(s, addr, &madt, sizeof(madt)); 825 839 #endif /* !VBOX_WITH_SMP_GUESTS */ 826 840 } 827 841 828 842 /* SCI IRQ */ 829 DECLINLINE(void) acpiSetIrq 843 DECLINLINE(void) acpiSetIrq(ACPIState *s, int level) 830 844 { 831 845 if (s->pm1a_ctl & SCI_EN) 832 PDMDevHlpPCISetIrq 833 } 834 835 DECLINLINE(uint32_t) pm1a_pure_en 846 PDMDevHlpPCISetIrq(s->pDevIns, -1, level); 847 } 848 849 DECLINLINE(uint32_t) pm1a_pure_en(uint32_t en) 836 850 { 837 851 return en & ~(RSR_EN | IGN_EN); 838 852 } 839 853 840 DECLINLINE(uint32_t) pm1a_pure_sts 854 DECLINLINE(uint32_t) pm1a_pure_sts(uint32_t sts) 841 855 { 842 856 return sts & ~(RSR_STS | IGN_STS); 843 857 } 844 858 845 DECLINLINE(int) pm1a_level 846 { 847 return (pm1a_pure_en (s->pm1a_en) & pm1a_pure_sts(s->pm1a_sts)) != 0;848 } 849 850 DECLINLINE(int) gpe0_level 859 DECLINLINE(int) pm1a_level(ACPIState *s) 860 { 861 return (pm1a_pure_en(s->pm1a_en) & pm1a_pure_sts(s->pm1a_sts)) != 0; 862 } 863 864 DECLINLINE(int) gpe0_level(ACPIState *s) 851 865 { 852 866 return (s->gpe0_en & s->gpe0_sts) != 0; 853 867 } 854 868 855 static void update_pm1a 869 static void update_pm1a(ACPIState *s, uint32_t sts, uint32_t en) 856 870 { 857 871 int old_level, new_level; 858 872 859 if (gpe0_level 873 if (gpe0_level(s)) 860 874 return; 861 875 862 old_level = pm1a_level 863 new_level = (pm1a_pure_en (en) & pm1a_pure_sts(sts)) != 0;876 old_level = pm1a_level(s); 877 new_level = (pm1a_pure_en(en) & pm1a_pure_sts(sts)) != 0; 864 878 865 879 s->pm1a_en = en; … … 867 881 868 882 if (new_level != old_level) 869 acpiSetIrq 870 } 871 872 static void update_gpe0 883 acpiSetIrq(s, new_level); 884 } 885 886 static void update_gpe0(ACPIState *s, uint32_t sts, uint32_t en) 873 887 { 874 888 int old_level, new_level; 875 889 876 if (pm1a_level 890 if (pm1a_level(s)) 877 891 return; 878 892 … … 884 898 885 899 if (new_level != old_level) 886 acpiSetIrq 887 } 888 889 static int acpiPowerDown 900 acpiSetIrq(s, new_level); 901 } 902 903 static int acpiPowerDown(ACPIState *s) 890 904 { 891 905 int rc = PDMDevHlpVMPowerOff(s->pDevIns); 892 if (RT_FAILURE 893 AssertMsgFailed 906 if (RT_FAILURE(rc)) 907 AssertMsgFailed(("Could not power down the VM. rc = %Rrc\n", rc)); 894 908 return rc; 895 909 } … … 908 922 ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface); 909 923 s->fPowerButtonHandled = false; 910 update_pm1a 924 update_pm1a(s, s->pm1a_sts | PWRBTN_STS, s->pm1a_en); 911 925 return VINF_SUCCESS; 912 926 } … … 949 963 { 950 964 ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface); 951 update_pm1a 965 update_pm1a(s, s->pm1a_sts | SLPBTN_STS, s->pm1a_en); 952 966 return VINF_SUCCESS; 953 967 } 954 968 955 969 /* PM1a_EVT_BLK enable */ 956 static uint32_t acpiPm1aEnReadw 970 static uint32_t acpiPm1aEnReadw(ACPIState *s, uint32_t addr) 957 971 { 958 972 uint16_t val = s->pm1a_en; 959 Log 973 Log(("acpi: acpiPm1aEnReadw -> %#x\n", val)); 960 974 return val; 961 975 } 962 976 963 static void acpiPM1aEnWritew 964 { 965 Log 977 static void acpiPM1aEnWritew(ACPIState *s, uint32_t addr, uint32_t val) 978 { 979 Log(("acpi: acpiPM1aEnWritew <- %#x (%#x)\n", val, val & ~(RSR_EN | IGN_EN))); 966 980 val &= ~(RSR_EN | IGN_EN); 967 update_pm1a 981 update_pm1a(s, s->pm1a_sts, val); 968 982 } 969 983 970 984 /* PM1a_EVT_BLK status */ 971 static uint32_t acpiPm1aStsReadw 985 static uint32_t acpiPm1aStsReadw(ACPIState *s, uint32_t addr) 972 986 { 973 987 uint16_t val = s->pm1a_sts; 974 Log 988 Log(("acpi: acpiPm1aStsReadw -> %#x\n", val)); 975 989 return val; 976 990 } 977 991 978 static void acpiPM1aStsWritew 979 { 980 Log 992 static void acpiPM1aStsWritew(ACPIState *s, uint32_t addr, uint32_t val) 993 { 994 Log(("acpi: acpiPM1aStsWritew <- %#x (%#x)\n", val, val & ~(RSR_STS | IGN_STS))); 981 995 if (val & PWRBTN_STS) 982 996 s->fPowerButtonHandled = true; /* Remember that the guest handled the last power button event */ 983 997 val = s->pm1a_sts & ~(val & ~(RSR_STS | IGN_STS)); 984 update_pm1a 998 update_pm1a(s, val, s->pm1a_en); 985 999 } 986 1000 987 1001 /* PM1a_CTL_BLK */ 988 static uint32_t acpiPm1aCtlReadw 1002 static uint32_t acpiPm1aCtlReadw(ACPIState *s, uint32_t addr) 989 1003 { 990 1004 uint16_t val = s->pm1a_ctl; 991 Log 1005 Log(("acpi: acpiPm1aCtlReadw -> %#x\n", val)); 992 1006 return val; 993 1007 } 994 1008 995 static int acpiPM1aCtlWritew 1009 static int acpiPM1aCtlWritew(ACPIState *s, uint32_t addr, uint32_t val) 996 1010 { 997 1011 uint32_t uSleepState; 998 1012 999 Log 1013 Log(("acpi: acpiPM1aCtlWritew <- %#x (%#x)\n", val, val & ~(RSR_CNT | IGN_CNT))); 1000 1014 s->pm1a_ctl = val & ~(RSR_CNT | IGN_CNT); 1001 1015 … … 1009 1023 break; 1010 1024 case 0x05: /* S5 */ 1011 LogRel 1012 return acpiPowerDown 1025 LogRel(("Entering S5 (power down)\n")); 1026 return acpiPowerDown(s); 1013 1027 default: 1014 AssertMsgFailed 1028 AssertMsgFailed(("Unknown sleep state %#x\n", uSleepState)); 1015 1029 break; 1016 1030 } … … 1020 1034 1021 1035 /* GPE0_BLK */ 1022 static uint32_t acpiGpe0EnReadb 1036 static uint32_t acpiGpe0EnReadb(ACPIState *s, uint32_t addr) 1023 1037 { 1024 1038 uint8_t val = s->gpe0_en; 1025 Log 1039 Log(("acpi: acpiGpe0EnReadl -> %#x\n", val)); 1026 1040 return val; 1027 1041 } 1028 1042 1029 static void acpiGpe0EnWriteb 1030 { 1031 Log 1032 update_gpe0 1033 } 1034 1035 static uint32_t acpiGpe0StsReadb 1043 static void acpiGpe0EnWriteb(ACPIState *s, uint32_t addr, uint32_t val) 1044 { 1045 Log(("acpi: acpiGpe0EnWritel <- %#x\n", val)); 1046 update_gpe0(s, s->gpe0_sts, val); 1047 } 1048 1049 static uint32_t acpiGpe0StsReadb(ACPIState *s, uint32_t addr) 1036 1050 { 1037 1051 uint8_t val = s->gpe0_sts; 1038 Log 1052 Log(("acpi: acpiGpe0StsReadl -> %#x\n", val)); 1039 1053 return val; 1040 1054 } 1041 1055 1042 static void acpiGpe0StsWriteb 1056 static void acpiGpe0StsWriteb(ACPIState *s, uint32_t addr, uint32_t val) 1043 1057 { 1044 1058 val = s->gpe0_sts & ~val; 1045 update_gpe0 1046 Log 1059 update_gpe0(s, val, s->gpe0_en); 1060 Log(("acpi: acpiGpe0StsWritel <- %#x\n", val)); 1047 1061 } 1048 1062 … … 1064 1078 1065 1079 /* SMI */ 1066 static void acpiSmiWriteU8 1067 { 1068 Log 1080 static void acpiSmiWriteU8(ACPIState *s, uint32_t addr, uint32_t val) 1081 { 1082 Log(("acpi: acpiSmiWriteU8 %#x\n", val)); 1069 1083 if (val == ACPI_ENABLE) 1070 1084 s->pm1a_ctl |= SCI_EN; … … 1072 1086 s->pm1a_ctl &= ~SCI_EN; 1073 1087 else 1074 Log 1075 } 1076 1077 static uint32_t find_rsdp_space 1088 Log(("acpi: acpiSmiWriteU8 %#x <- unknown value\n", val)); 1089 } 1090 1091 static uint32_t find_rsdp_space(void) 1078 1092 { 1079 1093 return 0xe0000; 1080 1094 } 1081 1095 1082 static void acpiPMTimerReset 1096 static void acpiPMTimerReset(ACPIState *s) 1083 1097 { 1084 1098 uint64_t interval, freq; 1085 1099 1086 freq = TMTimerGetFreq 1087 interval = ASMMultU64ByU32DivByU32 1088 Log 1089 TMTimerSet (s->CTX_SUFF(ts), TMTimerGet(s->CTX_SUFF(ts)) + interval);1090 } 1091 1092 static DECLCALLBACK(void) acpiTimer 1093 { 1094 ACPIState *s = PDMINS_2_DATA 1095 1096 Log 1097 1098 1099 1100 update_pm1a 1101 acpiPMTimerReset 1100 freq = TMTimerGetFreq(s->CTX_SUFF(ts)); 1101 interval = ASMMultU64ByU32DivByU32(0xffffffff, freq, PM_TMR_FREQ); 1102 Log(("interval = %RU64\n", interval)); 1103 TMTimerSet(s->CTX_SUFF(ts), TMTimerGet(s->CTX_SUFF(ts)) + interval); 1104 } 1105 1106 static DECLCALLBACK(void) acpiTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer) 1107 { 1108 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 1109 1110 Log(("acpi: pm timer sts %#x (%d), en %#x (%d)\n", 1111 s->pm1a_sts, (s->pm1a_sts & TMR_STS) != 0, 1112 s->pm1a_en, (s->pm1a_en & TMR_EN) != 0)); 1113 1114 update_pm1a(s, s->pm1a_sts | TMR_STS, s->pm1a_en); 1115 acpiPMTimerReset(s); 1102 1116 } 1103 1117 … … 1105 1119 * _BST method. 1106 1120 */ 1107 static void acpiFetchBatteryStatus 1121 static void acpiFetchBatteryStatus(ACPIState *s) 1108 1122 { 1109 1123 uint32_t *p = s->au8BatteryInfo; … … 1116 1130 if (!s->pDrv) 1117 1131 return; 1118 rc = s->pDrv->pfnQueryBatteryStatus 1119 1120 AssertRC 1132 rc = s->pDrv->pfnQueryBatteryStatus(s->pDrv, &fPresent, &hostRemainingCapacity, 1133 &hostBatteryState, &hostPresentRate); 1134 AssertRC(rc); 1121 1135 1122 1136 /* default values */ … … 1137 1151 * _BIF method. 1138 1152 */ 1139 static void acpiFetchBatteryInfo 1153 static void acpiFetchBatteryInfo(ACPIState *s) 1140 1154 { 1141 1155 uint32_t *p = s->au8BatteryInfo; … … 1155 1169 * _STA method. 1156 1170 */ 1157 static uint32_t acpiGetBatteryDeviceStatus 1171 static uint32_t acpiGetBatteryDeviceStatus(ACPIState *s) 1158 1172 { 1159 1173 bool fPresent; /* battery present? */ … … 1165 1179 if (!s->pDrv) 1166 1180 return 0; 1167 rc = s->pDrv->pfnQueryBatteryStatus 1168 1169 AssertRC 1181 rc = s->pDrv->pfnQueryBatteryStatus(s->pDrv, &fPresent, &hostRemainingCapacity, 1182 &hostBatteryState, &hostPresentRate); 1183 AssertRC(rc); 1170 1184 1171 1185 return fPresent … … 1178 1192 } 1179 1193 1180 static uint32_t acpiGetPowerSource 1194 static uint32_t acpiGetPowerSource(ACPIState *s) 1181 1195 { 1182 1196 PDMACPIPOWERSOURCE ps; … … 1185 1199 if (!s->pDrv) 1186 1200 return AC_ONLINE; 1187 int rc = s->pDrv->pfnQueryPowerSource 1188 AssertRC 1201 int rc = s->pDrv->pfnQueryPowerSource(s->pDrv, &ps); 1202 AssertRC(rc); 1189 1203 return ps == PDM_ACPI_POWER_SOURCE_BATTERY ? AC_OFFLINE : AC_ONLINE; 1190 1204 } 1191 1205 1192 IO_WRITE_PROTO (acpiBatIndexWrite)1206 PDMBOTHCBDECL(int) acpiBatIndexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1193 1207 { 1194 1208 ACPIState *s = (ACPIState *)pvUser; … … 1204 1218 u32 >>= 2; 1205 1219 } 1206 Assert 1220 Assert(u32 < BAT_INDEX_LAST); 1207 1221 s->uBatteryIndex = u32; 1208 1222 break; … … 1214 1228 } 1215 1229 1216 IO_READ_PROTO (acpiBatDataRead)1230 PDMBOTHCBDECL(int) acpiBatDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1217 1231 { 1218 1232 ACPIState *s = (ACPIState *)pvUser; … … 1253 1267 1254 1268 default: 1255 AssertMsgFailed 1269 AssertMsgFailed(("Invalid battery index %d\n", s->uBatteryIndex)); 1256 1270 break; 1257 1271 } … … 1263 1277 } 1264 1278 1265 IO_WRITE_PROTO (acpiSysInfoIndexWrite)1279 PDMBOTHCBDECL(int) acpiSysInfoIndexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1266 1280 { 1267 1281 ACPIState *s = (ACPIState *)pvUser; 1268 1282 1269 1283 Log(("system_index = %d, %d\n", u32, u32 >> 2)); 1270 switch (cb) { 1271 case 4: 1272 if (u32 == SYSTEM_INFO_INDEX_VALID || u32 == SYSTEM_INFO_INDEX_INVALID) 1273 s->uSystemInfoIndex = u32; 1274 else 1275 { 1276 /* see comment at the declaration of u8IndexShift */ 1277 if (s->u8IndexShift == 0) 1284 switch (cb) 1285 { 1286 case 4: 1287 if (u32 == SYSTEM_INFO_INDEX_VALID || u32 == SYSTEM_INFO_INDEX_INVALID) 1288 s->uSystemInfoIndex = u32; 1289 else 1278 1290 { 1279 if (((u32 >> 2) < SYSTEM_INFO_INDEX_LAST) && ((u32 & 0x3)) == 0) 1291 /* see comment at the declaration of u8IndexShift */ 1292 if (s->u8IndexShift == 0) 1280 1293 { 1281 s->u8IndexShift = 2; 1294 if (((u32 >> 2) < SYSTEM_INFO_INDEX_LAST) && ((u32 & 0x3)) == 0) 1295 { 1296 s->u8IndexShift = 2; 1297 } 1282 1298 } 1299 1300 u32 >>= s->u8IndexShift; 1301 Assert(u32 < SYSTEM_INFO_INDEX_LAST); 1302 s->uSystemInfoIndex = u32; 1283 1303 } 1284 1285 u32 >>= s->u8IndexShift; 1286 Assert (u32 < SYSTEM_INFO_INDEX_LAST); 1287 s->uSystemInfoIndex = u32; 1288 } 1289 break; 1290 1291 default: 1292 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); 1293 break; 1294 } 1295 return VINF_SUCCESS; 1296 } 1297 1298 IO_READ_PROTO (acpiSysInfoDataRead) 1304 break; 1305 1306 default: 1307 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); 1308 break; 1309 } 1310 return VINF_SUCCESS; 1311 } 1312 1313 PDMBOTHCBDECL(int) acpiSysInfoDataRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1299 1314 { 1300 1315 ACPIState *s = (ACPIState *)pvUser; … … 1348 1363 case SYSTEM_INFO_INDEX_CPU3_STATUS: 1349 1364 #ifdef VBOX_WITH_SMP_GUESTS 1350 *pu32 = (s->fShowCpu &&1351 s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS < cCpus)1352 ? (STA_DEVICE_PRESENT_MASK1353 1354 1355 | STA_DEVICE_FUNCTIONING_PROPERLY_MASK)1356 1365 *pu32 = s->fShowCpu 1366 && s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS < s->cCpus 1367 ? STA_DEVICE_PRESENT_MASK 1368 | STA_DEVICE_ENABLED_MASK 1369 | STA_DEVICE_SHOW_IN_UI_MASK 1370 | STA_DEVICE_FUNCTIONING_PROPERLY_MASK 1371 : 0; 1357 1372 #else 1358 1373 *pu32 = 0; … … 1366 1381 1367 1382 default: 1368 AssertMsgFailed 1383 AssertMsgFailed(("Invalid system info index %d\n", s->uSystemInfoIndex)); 1369 1384 break; 1370 1385 } … … 1379 1394 } 1380 1395 1381 IO_WRITE_PROTO (acpiSysInfoDataWrite)1396 PDMBOTHCBDECL(int) acpiSysInfoDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1382 1397 { 1383 1398 ACPIState *s = (ACPIState *)pvUser; … … 1408 1423 } 1409 1424 1425 /** @todo Don't call functions, but do the job in the read/write handlers 1426 * here! */ 1427 1410 1428 /* IO Helpers */ 1411 IO_READ_PROTO (acpiPm1aEnRead)1429 PDMBOTHCBDECL(int) acpiPm1aEnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1412 1430 { 1413 1431 switch (cb) 1414 1432 { 1415 1433 case 2: 1416 *pu32 = acpiPm1aEnReadw 1434 *pu32 = acpiPm1aEnReadw((ACPIState*)pvUser, Port); 1417 1435 break; 1418 1436 default: … … 1422 1440 } 1423 1441 1424 IO_READ_PROTO (acpiPm1aStsRead)1442 PDMBOTHCBDECL(int) acpiPm1aStsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1425 1443 { 1426 1444 switch (cb) 1427 1445 { 1428 1446 case 2: 1429 *pu32 = acpiPm1aStsReadw 1447 *pu32 = acpiPm1aStsReadw((ACPIState*)pvUser, Port); 1430 1448 break; 1431 1449 default: … … 1435 1453 } 1436 1454 1437 IO_READ_PROTO (acpiPm1aCtlRead)1455 PDMBOTHCBDECL(int) acpiPm1aCtlRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1438 1456 { 1439 1457 switch (cb) 1440 1458 { 1441 1459 case 2: 1442 *pu32 = acpiPm1aCtlReadw 1460 *pu32 = acpiPm1aCtlReadw((ACPIState*)pvUser, Port); 1443 1461 break; 1444 1462 default: … … 1448 1466 } 1449 1467 1450 IO_WRITE_PROTO (acpiPM1aEnWrite)1468 PDMBOTHCBDECL(int) acpiPM1aEnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1451 1469 { 1452 1470 switch (cb) 1453 1471 { 1454 1472 case 2: 1455 acpiPM1aEnWritew 1473 acpiPM1aEnWritew((ACPIState*)pvUser, Port, u32); 1456 1474 break; 1457 1475 default: … … 1462 1480 } 1463 1481 1464 IO_WRITE_PROTO (acpiPM1aStsWrite)1482 PDMBOTHCBDECL(int) acpiPM1aStsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1465 1483 { 1466 1484 switch (cb) 1467 1485 { 1468 1486 case 2: 1469 acpiPM1aStsWritew 1487 acpiPM1aStsWritew((ACPIState*)pvUser, Port, u32); 1470 1488 break; 1471 1489 default: … … 1476 1494 } 1477 1495 1478 IO_WRITE_PROTO (acpiPM1aCtlWrite)1496 PDMBOTHCBDECL(int) acpiPM1aCtlWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1479 1497 { 1480 1498 switch (cb) 1481 1499 { 1482 1500 case 2: 1483 return acpiPM1aCtlWritew 1501 return acpiPM1aCtlWritew((ACPIState*)pvUser, Port, u32); 1484 1502 default: 1485 1503 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); … … 1494 1512 * PMTMR readable from host/guest. 1495 1513 */ 1496 IO_READ_PROTO (acpiPMTmrRead)1514 PDMBOTHCBDECL(int) acpiPMTmrRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1497 1515 { 1498 1516 if (cb == 4) 1499 1517 { 1500 ACPIState *s = PDMINS_2_DATA 1501 int64_t now = TMTimerGet 1518 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 1519 int64_t now = TMTimerGet(s->CTX_SUFF(ts)); 1502 1520 int64_t elapsed = now - s->pm_timer_initial; 1503 1521 1504 *pu32 = ASMMultU64ByU32DivByU32 (elapsed, PM_TMR_FREQ, TMTimerGetFreq(s->CTX_SUFF(ts)));1505 Log 1522 *pu32 = ASMMultU64ByU32DivByU32(elapsed, PM_TMR_FREQ, TMTimerGetFreq(s->CTX_SUFF(ts))); 1523 Log(("acpi: acpiPMTmrRead -> %#x\n", *pu32)); 1506 1524 return VINF_SUCCESS; 1507 1525 } … … 1511 1529 #ifdef IN_RING3 1512 1530 1513 IO_READ_PROTO (acpiGpe0StsRead)1531 PDMBOTHCBDECL(int) acpiGpe0StsRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1514 1532 { 1515 1533 switch (cb) 1516 1534 { 1517 1535 case 1: 1518 *pu32 = acpiGpe0StsReadb 1536 *pu32 = acpiGpe0StsReadb((ACPIState*)pvUser, Port); 1519 1537 break; 1520 1538 default: … … 1524 1542 } 1525 1543 1526 IO_READ_PROTO (acpiGpe0EnRead)1544 PDMBOTHCBDECL(int) acpiGpe0EnRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) 1527 1545 { 1528 1546 switch (cb) 1529 1547 { 1530 1548 case 1: 1531 *pu32 = acpiGpe0EnReadb 1549 *pu32 = acpiGpe0EnReadb((ACPIState*)pvUser, Port); 1532 1550 break; 1533 1551 default: … … 1537 1555 } 1538 1556 1539 IO_WRITE_PROTO (acpiGpe0StsWrite)1557 PDMBOTHCBDECL(int) acpiGpe0StsWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1540 1558 { 1541 1559 switch (cb) 1542 1560 { 1543 1561 case 1: 1544 acpiGpe0StsWriteb 1562 acpiGpe0StsWriteb((ACPIState*)pvUser, Port, u32); 1545 1563 break; 1546 1564 default: … … 1551 1569 } 1552 1570 1553 IO_WRITE_PROTO (acpiGpe0EnWrite)1571 PDMBOTHCBDECL(int) acpiGpe0EnWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1554 1572 { 1555 1573 switch (cb) 1556 1574 { 1557 1575 case 1: 1558 acpiGpe0EnWriteb 1576 acpiGpe0EnWriteb((ACPIState*)pvUser, Port, u32); 1559 1577 break; 1560 1578 default: … … 1565 1583 } 1566 1584 1567 IO_WRITE_PROTO (acpiSmiWrite)1585 PDMBOTHCBDECL(int) acpiSmiWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1568 1586 { 1569 1587 switch (cb) 1570 1588 { 1571 1589 case 1: 1572 acpiSmiWriteU8 1590 acpiSmiWriteU8((ACPIState*)pvUser, Port, u32); 1573 1591 break; 1574 1592 default: … … 1579 1597 } 1580 1598 1581 IO_WRITE_PROTO (acpiResetWrite)1599 PDMBOTHCBDECL(int) acpiResetWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1582 1600 { 1583 1601 switch (cb) 1584 1602 { 1585 1603 case 1: 1586 return acpiResetWriteU8 1604 return acpiResetWriteU8((ACPIState*)pvUser, Port, u32); 1587 1605 default: 1588 1606 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); … … 1594 1612 #ifdef DEBUG_ACPI 1595 1613 1596 IO_WRITE_PROTO (acpiDhexWrite)1614 PDMBOTHCBDECL(int) acpiDhexWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1597 1615 { 1598 1616 switch (cb) 1599 1617 { 1600 1618 case 1: 1601 Log 1619 Log(("%#x\n", u32 & 0xff)); 1602 1620 break; 1603 1621 case 2: 1604 Log 1622 Log(("%#6x\n", u32 & 0xffff)); 1605 1623 case 4: 1606 Log 1624 Log(("%#10x\n", u32)); 1607 1625 break; 1608 1626 default: … … 1613 1631 } 1614 1632 1615 IO_WRITE_PROTO (acpiDchrWrite)1633 PDMBOTHCBDECL(int) acpiDchrWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1616 1634 { 1617 1635 switch (cb) 1618 1636 { 1619 1637 case 1: 1620 Log 1638 Log(("%c", u32 & 0xff)); 1621 1639 break; 1622 1640 default: … … 1635 1653 static const SSMFIELD g_AcpiSavedStateFields[] = 1636 1654 { 1637 SSMFIELD_ENTRY 1638 SSMFIELD_ENTRY 1639 SSMFIELD_ENTRY 1640 SSMFIELD_ENTRY 1641 SSMFIELD_ENTRY 1642 SSMFIELD_ENTRY 1643 SSMFIELD_ENTRY 1644 SSMFIELD_ENTRY 1645 SSMFIELD_ENTRY (ACPIState, u64RamSize),1646 SSMFIELD_ENTRY 1647 SSMFIELD_ENTRY 1648 SSMFIELD_ENTRY 1649 SSMFIELD_ENTRY_TERM 1655 SSMFIELD_ENTRY(ACPIState, pm1a_en), 1656 SSMFIELD_ENTRY(ACPIState, pm1a_sts), 1657 SSMFIELD_ENTRY(ACPIState, pm1a_ctl), 1658 SSMFIELD_ENTRY(ACPIState, pm_timer_initial), 1659 SSMFIELD_ENTRY(ACPIState, gpe0_en), 1660 SSMFIELD_ENTRY(ACPIState, gpe0_sts), 1661 SSMFIELD_ENTRY(ACPIState, uBatteryIndex), 1662 SSMFIELD_ENTRY(ACPIState, uSystemInfoIndex), 1663 SSMFIELD_ENTRY(ACPIState, u64RamSize), /** @todo not necessary to save this. */ 1664 SSMFIELD_ENTRY(ACPIState, u8IndexShift), 1665 SSMFIELD_ENTRY(ACPIState, u8UseIOApic), 1666 SSMFIELD_ENTRY(ACPIState, uSleepState), 1667 SSMFIELD_ENTRY_TERM() 1650 1668 }; 1651 1669 1652 static DECLCALLBACK(int) acpi_save_state 1653 { 1654 ACPIState *s = PDMINS_2_DATA 1655 return SSMR3PutStruct 1656 } 1657 1658 static DECLCALLBACK(int) acpi_load_state 1659 1660 { 1661 ACPIState *s = PDMINS_2_DATA 1670 static DECLCALLBACK(int) acpi_save_state(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle) 1671 { 1672 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 1673 return SSMR3PutStruct(pSSMHandle, s, &g_AcpiSavedStateFields[0]); 1674 } 1675 1676 static DECLCALLBACK(int) acpi_load_state(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, 1677 uint32_t u32Version) 1678 { 1679 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 1662 1680 int rc; 1663 1681 … … 1665 1683 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1666 1684 1667 rc = SSMR3GetStruct 1668 if (RT_SUCCESS 1669 { 1670 acpiFetchBatteryStatus 1671 acpiFetchBatteryInfo 1672 acpiPMTimerReset 1685 rc = SSMR3GetStruct(pSSMHandle, s, &g_AcpiSavedStateFields[0]); 1686 if (RT_SUCCESS(rc)) 1687 { 1688 acpiFetchBatteryStatus(s); 1689 acpiFetchBatteryInfo(s); 1690 acpiPMTimerReset(s); 1673 1691 } 1674 1692 return rc; … … 1701 1719 * Create the ACPI tables. 1702 1720 */ 1703 static int acpiPlantTables 1721 static int acpiPlantTables(ACPIState *s) 1704 1722 { 1705 1723 int rc; … … 1718 1736 xsdt_tbl_len += cAddr*8; /* each entry: 64 bits phys. address. */ 1719 1737 1720 rc = CFGMR3QueryU64 1721 if (RT_FAILURE 1738 rc = CFGMR3QueryU64(s->pDevIns->pCfgHandle, "RamSize", &s->u64RamSize); 1739 if (RT_FAILURE(rc)) 1722 1740 return PDMDEV_SET_ERROR(s->pDevIns, rc, 1723 1741 N_("Configuration error: Querying " … … 1725 1743 1726 1744 uint32_t cbRamHole; 1727 rc = CFGMR3QueryU32Def 1728 if (RT_FAILURE 1729 return PDMDEV_SET_ERROR 1730 N_("Configuration error: Querying \"RamHoleSize\" as integer failed"));1745 rc = CFGMR3QueryU32Def(s->pDevIns->pCfgHandle, "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT); 1746 if (RT_FAILURE(rc)) 1747 return PDMDEV_SET_ERROR(s->pDevIns, rc, 1748 N_("Configuration error: Querying \"RamHoleSize\" as integer failed")); 1731 1749 const uint64_t offRamHole = _4G - cbRamHole; 1732 1750 1733 1751 #if 0 /** @todo 4GB: This needs adjusting fixing! I've disabled it to test big mem configs. */ 1734 if (s->u64RamSize > (0xffffffff -0x10000))1752 if (s->u64RamSize > UINT32_C(0xffffffff) - UINT32_C(0x10000)) 1735 1753 return PDMDEV_SET_ERROR(s->pDevIns, VERR_OUT_OF_RANGE, 1736 1754 N_("Configuration error: Invalid \"RamSize\", maximum allowed " … … 1739 1757 1740 1758 rsdt_addr = 0; 1741 xsdt_addr = RT_ALIGN_32 1742 fadt_addr = RT_ALIGN_32 1743 facs_addr = RT_ALIGN_32 1759 xsdt_addr = RT_ALIGN_32(rsdt_addr + rsdt_tbl_len, 16); 1760 fadt_addr = RT_ALIGN_32(xsdt_addr + xsdt_tbl_len, 16); 1761 facs_addr = RT_ALIGN_32(fadt_addr + sizeof(ACPITBLFADT), 16); 1744 1762 if (s->u8UseIOApic) 1745 1763 { 1746 apic_addr = RT_ALIGN_32 1764 apic_addr = RT_ALIGN_32(facs_addr + sizeof(ACPITBLFACS), 16); 1747 1765 #ifdef VBOX_WITH_SMP_GUESTS 1748 1766 /** … … 1750 1768 * but as this code is executed only once it doesn't make sense to optimize much 1751 1769 */ 1752 dsdt_addr = RT_ALIGN_32 1770 dsdt_addr = RT_ALIGN_32(apic_addr + AcpiTableMADT::sizeFor(s), 16); 1753 1771 #else 1754 dsdt_addr = RT_ALIGN_32 1772 dsdt_addr = RT_ALIGN_32(apic_addr + sizeof(ACPITBLMADT), 16); 1755 1773 #endif 1756 1774 } 1757 1775 else 1758 1776 { 1759 dsdt_addr = RT_ALIGN_32 1760 } 1761 1762 last_addr = RT_ALIGN_32 1777 dsdt_addr = RT_ALIGN_32(facs_addr + sizeof(ACPITBLFACS), 16); 1778 } 1779 1780 last_addr = RT_ALIGN_32(dsdt_addr + sizeof(AmlCode), 16); 1763 1781 if (last_addr > 0x10000) 1764 1782 return PDMDEV_SET_ERROR(s->pDevIns, VERR_TOO_MUCH_DATA, … … 1767 1785 Log(("RSDP 0x%08X\n", find_rsdp_space())); 1768 1786 #if 1 /** @todo 4GB: Quick hack, may need revising. */ 1769 addend = (uint32_t) RT_MIN(s->u64RamSize, offRamHole) - 0x10000;1787 addend = (uint32_t)RT_MIN(s->u64RamSize, offRamHole) - 0x10000; 1770 1788 #else 1771 addend = (uint32_t) 1789 addend = (uint32_t)s->u64RamSize - 0x10000; 1772 1790 #endif 1773 1791 Log(("RSDT 0x%08X XSDT 0x%08X\n", rsdt_addr + addend, xsdt_addr + addend)); 1774 1792 Log(("FACS 0x%08X FADT 0x%08X\n", facs_addr + addend, fadt_addr + addend)); 1775 1793 Log(("DSDT 0x%08X\n", dsdt_addr + addend)); 1776 acpiSetupRSDP 1777 acpiSetupDSDT 1778 acpiSetupFACS 1779 acpiSetupFADT 1794 acpiSetupRSDP((ACPITBLRSDP*)s->au8RSDPPage, rsdt_addr + addend, xsdt_addr + addend); 1795 acpiSetupDSDT(s, dsdt_addr + addend); 1796 acpiSetupFACS(s, facs_addr + addend); 1797 acpiSetupFADT(s, fadt_addr + addend, facs_addr + addend, dsdt_addr + addend); 1780 1798 1781 1799 rsdt_addrs[0] = fadt_addr + addend; 1782 1800 if (s->u8UseIOApic) 1783 1801 { 1784 acpiSetupMADT 1802 acpiSetupMADT(s, apic_addr + addend); 1785 1803 rsdt_addrs[1] = apic_addr + addend; 1786 1804 } 1787 1805 1788 rc = acpiSetupRSDT 1806 rc = acpiSetupRSDT(s, rsdt_addr + addend, cAddr, rsdt_addrs); 1789 1807 if (RT_FAILURE(rc)) 1790 1808 return rc; 1791 return acpiSetupXSDT 1809 return acpiSetupXSDT(s, xsdt_addr + addend, cAddr, rsdt_addrs); 1792 1810 } 1793 1811 … … 1805 1823 * iInstance it's expected to be used a bit in this function. 1806 1824 */ 1807 static DECLCALLBACK(int) acpiConstruct 1825 static DECLCALLBACK(int) acpiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle) 1808 1826 { 1809 1827 int rc; 1810 ACPIState *s = PDMINS_2_DATA 1828 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 1811 1829 uint32_t rsdp_addr; 1812 1830 PCIDevice *dev; … … 1815 1833 1816 1834 /* Validate and read the configuration. */ 1817 if (!CFGMR3AreValuesValid 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1835 if (!CFGMR3AreValuesValid(pCfgHandle, 1836 "RamSize\0" 1837 "RamHoleSize\0" 1838 "IOAPIC\0" 1839 "NumCPUs\0" 1840 "GCEnabled\0" 1841 "R0Enabled\0" 1842 "HpetEnabled\0" 1843 "SmcEnabled\0" 1844 "FdcEnabled\0" 1845 )) 1828 1846 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 1829 1847 N_("Configuration error: Invalid config key for ACPI device")); … … 1832 1850 1833 1851 /* query whether we are supposed to present an IOAPIC */ 1834 rc = CFGMR3QueryU8Def 1835 if (RT_FAILURE 1852 rc = CFGMR3QueryU8Def(pCfgHandle, "IOAPIC", &s->u8UseIOApic, 1); 1853 if (RT_FAILURE(rc)) 1836 1854 return PDMDEV_SET_ERROR(pDevIns, rc, 1837 1855 N_("Configuration error: Failed to read \"IOAPIC\"")); … … 1843 1861 1844 1862 /* query whether we are supposed to present an FDC controller */ 1845 rc = CFGMR3QueryBoolDef 1846 if (RT_FAILURE 1863 rc = CFGMR3QueryBoolDef(pCfgHandle, "FdcEnabled", &s->fUseFdc, true); 1864 if (RT_FAILURE(rc)) 1847 1865 return PDMDEV_SET_ERROR(pDevIns, rc, 1848 1866 N_("Configuration error: Failed to read \"FdcEnabled\"")); 1849 1867 1850 1868 /* query whether we are supposed to present HPET */ 1851 rc = CFGMR3QueryBoolDef 1869 rc = CFGMR3QueryBoolDef(pCfgHandle, "HpetEnabled", &s->fUseHpet, false); 1852 1870 if (RT_FAILURE(rc)) 1853 1871 return PDMDEV_SET_ERROR(pDevIns, rc, 1854 1872 N_("Configuration error: Failed to read \"HpetEnabled\"")); 1855 1873 /* query whether we are supposed to present SMC */ 1856 rc = CFGMR3QueryBoolDef 1874 rc = CFGMR3QueryBoolDef(pCfgHandle, "SmcEnabled", &s->fUseSmc, false); 1857 1875 if (RT_FAILURE(rc)) 1858 1876 return PDMDEV_SET_ERROR(pDevIns, rc, … … 1861 1879 s->fShowCpu = s->fUseSmc; 1862 1880 1863 rc = CFGMR3QueryBool 1881 rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &fGCEnabled); 1864 1882 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 1865 1883 fGCEnabled = true; 1866 else if (RT_FAILURE 1884 else if (RT_FAILURE(rc)) 1867 1885 return PDMDEV_SET_ERROR(pDevIns, rc, 1868 1886 N_("Configuration error: Failed to read \"GCEnabled\"")); … … 1876 1894 1877 1895 /* */ 1878 rsdp_addr = find_rsdp_space 1896 rsdp_addr = find_rsdp_space(); 1879 1897 if (!rsdp_addr) 1880 1898 return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, 1881 1899 N_("Can not find space for RSDP. ACPI is disabled")); 1882 1900 1883 rc = acpiPlantTables 1884 if (RT_FAILURE 1901 rc = acpiPlantTables(s); 1902 if (RT_FAILURE(rc)) 1885 1903 return rc; 1886 1904 1887 rc = PDMDevHlpROMRegister 1888 if (RT_FAILURE 1905 rc = PDMDevHlpROMRegister(pDevIns, rsdp_addr, 0x1000, s->au8RSDPPage, false /* fShadow */, "ACPI RSDP"); 1906 if (RT_FAILURE(rc)) 1889 1907 return rc; 1890 1908 1891 1909 #define R(addr, cnt, writer, reader, description) \ 1892 do { 1893 rc = PDMDevHlpIOPortRegister 1894 NULL, NULL, description); 1895 if (RT_FAILURE (rc))\1896 return rc; 1910 do { \ 1911 rc = PDMDevHlpIOPortRegister(pDevIns, addr, cnt, s, writer, reader, \ 1912 NULL, NULL, description); \ 1913 if (RT_FAILURE(rc)) \ 1914 return rc; \ 1897 1915 } while (0) 1898 #define L (GPE0_BLK_LEN / 2)1899 1900 R 1901 R 1902 R 1903 R 1904 R 1916 #define L (GPE0_BLK_LEN / 2) 1917 1918 R(PM1a_EVT_BLK+2, 1, acpiPM1aEnWrite, acpiPm1aEnRead, "ACPI PM1a Enable"); 1919 R(PM1a_EVT_BLK, 1, acpiPM1aStsWrite, acpiPm1aStsRead, "ACPI PM1a Status"); 1920 R(PM1a_CTL_BLK, 1, acpiPM1aCtlWrite, acpiPm1aCtlRead, "ACPI PM1a Control"); 1921 R(PM_TMR_BLK, 1, NULL, acpiPMTmrRead, "ACPI PM Timer"); 1922 R(SMI_CMD, 1, acpiSmiWrite, NULL, "ACPI SMI"); 1905 1923 #ifdef DEBUG_ACPI 1906 R 1907 R 1924 R(DEBUG_HEX, 1, acpiDhexWrite, NULL, "ACPI Debug hex"); 1925 R(DEBUG_CHR, 1, acpiDchrWrite, NULL, "ACPI Debug char"); 1908 1926 #endif 1909 R 1910 R 1911 R 1912 R 1913 R 1914 R 1915 R 1927 R(BAT_INDEX, 1, acpiBatIndexWrite, NULL, "ACPI Battery status index"); 1928 R(BAT_DATA, 1, NULL, acpiBatDataRead, "ACPI Battery status data"); 1929 R(SYSI_INDEX, 1, acpiSysInfoIndexWrite, NULL, "ACPI system info index"); 1930 R(SYSI_DATA, 1, acpiSysInfoDataWrite, acpiSysInfoDataRead, "ACPI system info data"); 1931 R(GPE0_BLK + L, L, acpiGpe0EnWrite, acpiGpe0EnRead, "ACPI GPE0 Enable"); 1932 R(GPE0_BLK, L, acpiGpe0StsWrite, acpiGpe0StsRead, "ACPI GPE0 Status"); 1933 R(ACPI_RESET_BLK, 1, acpiResetWrite, NULL, "ACPI Reset"); 1916 1934 #undef L 1917 1935 #undef R … … 1920 1938 if (fGCEnabled) 1921 1939 { 1922 rc = PDMDevHlpIOPortRegisterGC 1923 1940 rc = PDMDevHlpIOPortRegisterGC(pDevIns, PM_TMR_BLK, 1, 0, NULL, "acpiPMTmrRead", 1941 NULL, NULL, "ACPI PM Timer"); 1924 1942 AssertRCReturn(rc, rc); 1925 1943 } … … 1928 1946 if (fR0Enabled) 1929 1947 { 1930 rc = PDMDevHlpIOPortRegisterR0 1931 1948 rc = PDMDevHlpIOPortRegisterR0(pDevIns, PM_TMR_BLK, 1, 0, NULL, "acpiPMTmrRead", 1949 NULL, NULL, "ACPI PM Timer"); 1932 1950 AssertRCReturn(rc, rc); 1933 1951 } 1934 1952 1935 rc = PDMDevHlpTMTimerCreate 1953 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, acpiTimer, "ACPI Timer", &s->tsR3); 1936 1954 if (RT_FAILURE(rc)) 1937 1955 { … … 1940 1958 } 1941 1959 1942 s->tsR0 = TMTimerR0Ptr 1943 s->tsRC = TMTimerRCPtr 1944 s->pm_timer_initial = TMTimerGet 1945 acpiPMTimerReset 1960 s->tsR0 = TMTimerR0Ptr(s->tsR3); 1961 s->tsRC = TMTimerRCPtr(s->tsR3); 1962 s->pm_timer_initial = TMTimerGet(s->tsR3); 1963 acpiPMTimerReset(s); 1946 1964 1947 1965 dev = &s->dev; … … 1971 1989 dev->config[0x3c] = SCI_INT; 1972 1990 1973 rc = PDMDevHlpPCIRegister 1974 if (RT_FAILURE 1991 rc = PDMDevHlpPCIRegister(pDevIns, dev); 1992 if (RT_FAILURE(rc)) 1975 1993 return rc; 1976 1994 1977 rc = PDMDevHlpSSMRegister 1978 1995 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance, 4, sizeof(*s), 1996 NULL, acpi_save_state, NULL, NULL, acpi_load_state, NULL); 1979 1997 if (RT_FAILURE(rc)) 1980 1998 return rc; … … 1994 2012 * Get the corresponding connector interface 1995 2013 */ 1996 rc = PDMDevHlpDriverAttach 1997 if (RT_SUCCESS 2014 rc = PDMDevHlpDriverAttach(pDevIns, 0, &s->IBase, &s->pDrvBase, "ACPI Driver Port"); 2015 if (RT_SUCCESS(rc)) 1998 2016 { 1999 s->pDrv = (PPDMIACPICONNECTOR)s->pDrvBase->pfnQueryInterface (s->pDrvBase, 2000 PDMINTERFACE_ACPI_CONNECTOR); 2017 s->pDrv = (PPDMIACPICONNECTOR)s->pDrvBase->pfnQueryInterface(s->pDrvBase, PDMINTERFACE_ACPI_CONNECTOR); 2001 2018 if (!s->pDrv) 2002 2019 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_MISSING_INTERFACE, … … 2005 2022 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2006 2023 { 2007 Log 2008 2024 Log(("acpi: %s/%d: warning: no driver attached to LUN #0!\n", 2025 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance)); 2009 2026 rc = VINF_SUCCESS; 2010 2027 } 2011 2028 else 2012 return PDMDEV_SET_ERROR(pDevIns, rc, 2013 N_("Failed to attach LUN #0")); 2029 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach LUN #0")); 2014 2030 2015 2031 return rc; … … 2019 2035 * Relocates the GC pointer members. 2020 2036 */ 2021 static DECLCALLBACK(void) acpiRelocate 2022 { 2023 ACPIState *s = PDMINS_2_DATA 2024 s->tsRC = TMTimerRCPtr 2025 } 2026 2027 static DECLCALLBACK(void) acpiReset 2028 { 2029 ACPIState *s = PDMINS_2_DATA 2037 static DECLCALLBACK(void) acpiRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta) 2038 { 2039 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 2040 s->tsRC = TMTimerRCPtr(s->CTX_SUFF(ts)); 2041 } 2042 2043 static DECLCALLBACK(void) acpiReset(PPDMDEVINS pDevIns) 2044 { 2045 ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *); 2030 2046 2031 2047 s->pm1a_en = 0; 2032 2048 s->pm1a_sts = 0; 2033 2049 s->pm1a_ctl = 0; 2034 s->pm_timer_initial = TMTimerGet 2050 s->pm_timer_initial = TMTimerGet(s->CTX_SUFF(ts)); 2035 2051 acpiPMTimerReset(s); 2036 2052 s->uBatteryIndex = 0;
Note:
See TracChangeset
for help on using the changeset viewer.