Changeset 39060 in vbox
- Timestamp:
- Oct 20, 2011 2:53:51 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 74482
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmdev.h
r38847 r39060 76 76 * 77 77 * @returns VBox status. 78 * @param pDevIns The device instance data. 79 * 80 * @remarks The device critical section is not entered. The routine may delete 78 * @param pDevIns The device instance data. 79 * 80 * @remarks The device critical section is not entered. The routine may delete 81 81 * the critical section, so the caller cannot exit it. 82 82 */ … … 100 100 * 101 101 * @remarks A relocation CANNOT fail. 102 * 103 * @remarks The device critical section is not entered. The relocations should 102 * 103 * @remarks The device critical section is not entered. The relocations should 104 104 * not normally require any locking. 105 105 */ … … 123 123 * @param cbOut Size of output data. 124 124 * @param pcbOut Where to store the actual size of the output data. 125 * 125 * 126 126 * @remarks Not used. 127 127 */ … … 137 137 * @returns VBox status. 138 138 * @param pDevIns The device instance data. 139 * 139 * 140 140 * @remarks Caller enters the device critical section. 141 141 */ … … 149 149 * @returns VBox status. 150 150 * @param pDevIns The device instance data. 151 * 151 * 152 152 * @remarks Caller enters the device critical section. 153 153 */ … … 162 162 * @param pDevIns The device instance data. 163 163 * @thread EMT(0) 164 * 164 * 165 165 * @remarks Caller enters the device critical section. 166 166 */ … … 174 174 * @returns VBox status. 175 175 * @param pDevIns The device instance data. 176 * 176 * 177 177 * @remarks Caller enters the device critical section. 178 178 */ … … 190 190 * @param pDevIns The device instance data. 191 191 * @thread EMT(0) 192 * 192 * 193 193 * @remarks Caller enters the device critical section. 194 194 */ … … 210 210 * @param iLUN The logical unit which is being detached. 211 211 * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines. 212 * 212 * 213 213 * @remarks Caller enters the device critical section. 214 214 */ … … 229 229 * @param iLUN The logical unit which is being detached. 230 230 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 231 * 231 * 232 232 * @remarks Caller enters the device critical section. 233 233 */ … … 243 243 * @param iLUN The logicial unit to query. 244 244 * @param ppBase Where to store the pointer to the base interface of the LUN. 245 * 245 * 246 246 * @remarks The device critical section is not entered. 247 247 */ … … 257 257 * @returns VBOX status code. 258 258 * @param pDevIns The device instance. 259 * 259 * 260 260 * @remarks Caller enters the device critical section. 261 261 */ … … 303 303 PFNPDMDEVDESTRUCT pfnDestruct; 304 304 /** Relocation command - optional. 305 * Critical section NOT entered. */ 305 * Critical section NOT entered. */ 306 306 PFNPDMDEVRELOCATE pfnRelocate; 307 307 /** I/O Control interface - optional. … … 309 309 PFNPDMDEVIOCTL pfnIOCtl; 310 310 /** Power on notification - optional. 311 * Critical section is entered. */ 311 * Critical section is entered. */ 312 312 PFNPDMDEVPOWERON pfnPowerOn; 313 /** Reset notification - optional. 314 * Critical section is entered. */ 313 /** Reset notification - optional. 314 * Critical section is entered. */ 315 315 PFNPDMDEVRESET pfnReset; 316 /** Suspend notification - optional. 317 * Critical section is entered. */ 316 /** Suspend notification - optional. 317 * Critical section is entered. */ 318 318 PFNPDMDEVSUSPEND pfnSuspend; 319 /** Resume notification - optional. 320 * Critical section is entered. */ 319 /** Resume notification - optional. 320 * Critical section is entered. */ 321 321 PFNPDMDEVRESUME pfnResume; 322 /** Attach command - optional. 323 * Critical section is entered. */ 322 /** Attach command - optional. 323 * Critical section is entered. */ 324 324 PFNPDMDEVATTACH pfnAttach; 325 /** Detach notification - optional. 326 * Critical section is entered. */ 325 /** Detach notification - optional. 326 * Critical section is entered. */ 327 327 PFNPDMDEVDETACH pfnDetach; 328 328 /** Query a LUN base interface - optional. 329 * Critical section is NOT entered. */ 329 * Critical section is NOT entered. */ 330 330 PFNPDMDEVQUERYINTERFACE pfnQueryInterface; 331 /** Init complete notification - optional. 332 * Critical section is entered. */ 331 /** Init complete notification - optional. 332 * Critical section is entered. */ 333 333 PFNPDMDEVINITCOMPLETE pfnInitComplete; 334 /** Power off notification - optional. 335 * Critical section is entered. */ 334 /** Power off notification - optional. 335 * Critical section is entered. */ 336 336 PFNPDMDEVPOWEROFF pfnPowerOff; 337 337 /** @todo */ … … 1133 1133 * @param u32Reg MSR to read. 1134 1134 * @param pu64Value Where to return the read value. 1135 * 1136 * @remarks Unlike the other callbacks, the PDM lock is not taken before 1137 * calling this method. 1135 1138 */ 1136 1139 DECLR3CALLBACKMEMBER(int, pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)); … … 3901 3904 /** The critical section for the device. 3902 3905 * 3903 * TM and IOM will enter this critical section before calling into the device 3904 * code. PDM will when doing power on, power off, reset, suspend and resume 3905 * notifications. SSM will currently not, but this will be changed later on. 3906 * TM and IOM will enter this critical section before calling into the device 3907 * code. PDM will when doing power on, power off, reset, suspend and resume 3908 * notifications. SSM will currently not, but this will be changed later on. 3906 3909 * 3907 3910 * The device gets a critical section automatically assigned to it before -
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r39053 r39060 552 552 } 553 553 554 555 /** 556 * apicWriteRegister helper for dealing with invalid register access. 557 * 558 * @returns Strict VBox status code. 559 * @param pDev The PDM device instance. 560 * @param pApic The APIC being written to. 561 * @param iReg The APIC register index. 562 * @param u64Value The value being written. 563 * @param rcBusy The busy return code to employ. See 564 * PDMCritSectEnter for a description. 565 * @param fMsr Set if called via MSR, clear if MMIO. 566 */ 567 static int apicWriteRegisterInvalid(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t u64Value, 568 int rcBusy, bool fMsr) 569 { 570 Log(("apicWriteRegisterInvalid/%u: iReg=%#x fMsr=%RTbool u64Value=%#llx\n", pApic->phys_id, iReg, fMsr, u64Value)); 571 int rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS, 572 "iReg=%#x fMsr=%RTbool u64Value=%#llx id=%u\n", iReg, fMsr, u64Value, pApic->phys_id); 573 APIC_LOCK(pDev, rcBusy); 574 pApic->esr |= ESR_ILLEGAL_ADDRESS; 575 APIC_UNLOCK(pDev); 576 return rc; 577 } 578 579 580 554 581 /** 555 582 * Writes to an APIC register via MMIO or MSR. … … 636 663 637 664 case 0x31: 638 APIC_LOCK(pDev, rcBusy);639 665 if (!fMsr) 666 { 667 APIC_LOCK(pDev, rcBusy); 640 668 pApic->icr[1] = (uint64_t)u64Value; 669 APIC_UNLOCK(pDev); 670 } 641 671 else 642 pApic->esr |= ESR_ILLEGAL_ADDRESS; 643 APIC_UNLOCK(pDev); 672 rc = apicWriteRegisterInvalid(pDev, pApic, iReg, u64Value, rcBusy, fMsr); 644 673 break; 645 674 … … 693 722 } 694 723 /* else: fall thru */ 724 695 725 default: 696 Log(("apicWriteRegister/%u: unknown index %#x\n", pApic->phys_id, iReg)); 697 rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS, 698 "unknown index %#x (id=%u)\n", iReg, pApic->phys_id); 699 pApic->esr |= ESR_ILLEGAL_ADDRESS; 726 rc = apicWriteRegisterInvalid(pDev, pApic, iReg, u64Value, rcBusy, fMsr); 700 727 break; 701 728 } … … 704 731 } 705 732 706 /** 707 * @interface_method_impl{PDMAPICREG,pfnWriteMSRR3} 708 */ 709 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value) 710 { 711 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 712 if (pDev->enmVersion < PDMAPICVERSION_X2APIC) 713 return VERR_EM_INTERPRETER; /** @todo tell the caller to raise hell (\#GP(0)). */ 714 715 APICState *pApic = getLapicById(pDev, idCpu); 716 uint32_t iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff; 717 return apicWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/); 718 } 719 720 721 /** 722 * @interface_method_impl{PDMAPICREG,pfnReadMSRR3} 723 */ 724 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value) 725 { 726 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 727 Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect))); 728 729 if (pDev->enmVersion < PDMAPICVERSION_X2APIC) 730 return VERR_EM_INTERPRETER; 731 732 uint32_t index = (u32Reg - MSR_IA32_APIC_START) & 0xff; 733 APICState *apic = getLapicById(pDev, idCpu); 734 uint64_t val = 0; 735 int rc = VINF_SUCCESS; 736 737 switch (index) 733 734 /** 735 * apicReadRegister helper for dealing with invalid register access. 736 * 737 * @returns Strict VBox status code. 738 * @param pDev The PDM device instance. 739 * @param pApic The APIC being read to. 740 * @param iReg The APIC register index. 741 * @param pu64Value Where to store the value we've read. 742 * @param rcBusy The busy return code to employ. See 743 * PDMCritSectEnter for a description. 744 * @param fMsr Set if called via MSR, clear if MMIO. 745 */ 746 static int apicReadRegisterInvalid(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t *pu64Value, 747 int rcBusy, bool fMsr) 748 { 749 Log(("apicReadRegisterInvalid/%u: iReg=%#x fMsr=%RTbool\n", pApic->phys_id, iReg, fMsr)); 750 int rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS, 751 "iReg=%#x fMsr=%RTbool id=%u\n", iReg, fMsr, pApic->phys_id); 752 APIC_LOCK(pDev, rcBusy); 753 pApic->esr |= ESR_ILLEGAL_ADDRESS; 754 APIC_UNLOCK(pDev); 755 *pu64Value = 0; 756 return rc; 757 } 758 759 760 /** 761 * Read from an APIC register via MMIO or MSR. 762 * 763 * @returns Strict VBox status code. 764 * @param pDev The PDM device instance. 765 * @param pApic The APIC being read to. 766 * @param iReg The APIC register index. 767 * @param pu64Value Where to store the value we've read. 768 * @param rcBusy The busy return code to employ. See 769 * PDMCritSectEnter for a description. 770 * @param fMsr Set if called via MSR, clear if MMIO. 771 */ 772 static int apicReadRegister(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t *pu64Value, 773 int rcBusy, bool fMsr) 774 { 775 Assert(!PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect))); 776 777 int rc = VINF_SUCCESS; 778 switch (iReg) 738 779 { 739 780 case 0x02: /* id */ 740 val = apic->id << 24; 741 break; 781 APIC_LOCK(pDev, rcBusy); 782 *pu64Value = pApic->id << 24; 783 APIC_UNLOCK(pDev); 784 break; 785 742 786 case 0x03: /* version */ 743 val = APIC_HW_VERSION 744 | ((APIC_LVT_NB - 1) << 16) /* Max LVT index */ 745 | (0 << 24) /* Support for EOI broadcast suppression */; 746 break; 787 APIC_LOCK(pDev, rcBusy); 788 *pu64Value = APIC_HW_VERSION 789 | ((APIC_LVT_NB - 1) << 16) /* Max LVT index */ 790 #if 0 791 | (0 << 24) /* Support for EOI broadcast suppression */ 792 #endif 793 ; 794 APIC_UNLOCK(pDev); 795 break; 796 747 797 case 0x08: 748 val = apic->tpr; 749 break; 798 APIC_LOCK(pDev, rcBusy); 799 *pu64Value = pApic->tpr; 800 APIC_UNLOCK(pDev); 801 break; 802 750 803 case 0x09: 751 val = apic_get_arb_pri(apic); 752 break; 804 *pu64Value = apic_get_arb_pri(pApic); 805 break; 806 753 807 case 0x0a: 754 808 /* ppr */ 755 val = apic_get_ppr(apic); 756 break; 809 APIC_LOCK(pDev, rcBusy); 810 *pu64Value = apic_get_ppr(pApic); 811 APIC_UNLOCK(pDev); 812 break; 813 757 814 case 0x0b: 758 val = 0; 759 break; 815 Log(("apicReadRegister: %x -> write only returning 0\n", iReg)); 816 *pu64Value = 0; 817 break; 818 760 819 case 0x0d: 761 val = (uint64_t)apic->log_dest << 24; 762 break; 820 APIC_LOCK(pDev, rcBusy); 821 *pu64Value = (uint64_t)pApic->log_dest << 24; 822 APIC_UNLOCK(pDev); 823 break; 824 763 825 case 0x0e: 764 826 /* Bottom 28 bits are always 1 */ 765 val = ((uint64_t)apic->dest_mode << 28) | 0xfffffff; 766 break; 827 APIC_LOCK(pDev, rcBusy); 828 *pu64Value = ((uint64_t)pApic->dest_mode << 28) | UINT32_C(0xfffffff); 829 APIC_UNLOCK(pDev); 830 break; 831 767 832 case 0x0f: 768 val = apic->spurious_vec; 769 break; 833 APIC_LOCK(pDev, rcBusy); 834 *pu64Value = pApic->spurious_vec; 835 APIC_UNLOCK(pDev); 836 break; 837 770 838 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: 771 val = apic->isr[index & 7]; 772 break; 839 APIC_LOCK(pDev, rcBusy); 840 *pu64Value = pApic->isr[iReg & 7]; 841 APIC_UNLOCK(pDev); 842 break; 843 773 844 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: 774 val = apic->tmr[index & 7]; 775 break; 845 APIC_LOCK(pDev, rcBusy); 846 *pu64Value = pApic->tmr[iReg & 7]; 847 APIC_UNLOCK(pDev); 848 break; 849 776 850 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: 777 val = apic->irr[index & 7]; 778 break; 851 APIC_LOCK(pDev, rcBusy); 852 *pu64Value = pApic->irr[iReg & 7]; 853 APIC_UNLOCK(pDev); 854 break; 855 779 856 case 0x28: 780 val = apic->esr; 781 break; 857 APIC_LOCK(pDev, rcBusy); 858 *pu64Value = pApic->esr; 859 APIC_UNLOCK(pDev); 860 break; 861 782 862 case 0x30: 783 863 /* Here one of the differences with regular APIC: ICR is single 64-bit register */ 784 val = ((uint64_t)apic->icr[1] << 32) | apic->icr[0]; 785 break; 864 APIC_LOCK(pDev, rcBusy); 865 if (fMsr) 866 *pu64Value = RT_MAKE_U64(pApic->icr[0], pApic->icr[1]); 867 else 868 *pu64Value = pApic->icr[0]; 869 APIC_UNLOCK(pDev); 870 break; 871 872 case 0x31: 873 if (fMsr) 874 rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr); 875 else 876 { 877 APIC_LOCK(pDev, rcBusy); 878 *pu64Value = pApic->icr[1]; 879 APIC_UNLOCK(pDev); 880 } 881 break; 882 786 883 case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: 787 val = apic->lvt[index - 0x32]; 788 break; 884 APIC_LOCK(pDev, rcBusy); 885 *pu64Value = pApic->lvt[iReg - 0x32]; 886 APIC_UNLOCK(pDev); 887 break; 888 789 889 case 0x38: 790 val = apic->initial_count; 791 break; 890 APIC_LOCK(pDev, rcBusy); 891 *pu64Value = pApic->initial_count; 892 APIC_UNLOCK(pDev); 893 break; 894 792 895 case 0x39: 793 val = apic_get_current_count(pDev, apic); 794 break; 896 APIC_AND_TM_LOCK(pDev, pApic, rcBusy); 897 *pu64Value = apic_get_current_count(pDev, pApic); 898 APIC_AND_TM_UNLOCK(pDev, pApic); 899 break; 900 795 901 case 0x3e: 796 val = apic->divide_conf; 797 break; 902 APIC_LOCK(pDev, rcBusy); 903 *pu64Value = pApic->divide_conf; 904 APIC_UNLOCK(pDev); 905 break; 906 798 907 case 0x3f: 799 /* Self IPI register is write only */ 800 Log(("apicReadMSR: read from write-only register %d ignored\n", index)); 801 break; 802 case 0x2f: 803 /** 804 * Correctable machine check exception vector, @todo: implement me! 805 */ 908 if (fMsr) 909 { 910 /* Self IPI register is write only */ 911 Log(("apicReadMSR: read from write-only register %d ignored\n", iReg)); 912 *pu64Value = 0; 913 } 914 else 915 rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr); 916 break; 917 case 0x2f: /** @todo Correctable machine check exception vector, implement me! */ 806 918 default: 807 919 /** … … 809 921 * i.e. LVT[5] 810 922 */ 811 Log(("apicReadMSR/%u: unknown index %#x\n", apic->phys_id, index)); 812 rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS, 813 "unknown index %#x (id=%u)\n", index, apic->phys_id); 814 apic->esr |= ESR_ILLEGAL_ADDRESS; 815 val = 0; 816 break; 817 } 818 *pu64Value = val; 923 rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr); 924 break; 925 } 819 926 return rc; 927 } 928 929 /** 930 * @interface_method_impl{PDMAPICREG,pfnWriteMSRR3} 931 */ 932 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value) 933 { 934 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 935 if (pDev->enmVersion < PDMAPICVERSION_X2APIC) 936 return VERR_EM_INTERPRETER; /** @todo tell the caller to raise hell (\#GP(0)). */ 937 938 APICState *pApic = getLapicById(pDev, idCpu); 939 uint32_t iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff; 940 return apicWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/); 941 } 942 943 944 /** 945 * @interface_method_impl{PDMAPICREG,pfnReadMSRR3} 946 */ 947 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value) 948 { 949 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 950 Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect))); 951 952 if (pDev->enmVersion < PDMAPICVERSION_X2APIC) 953 return VERR_EM_INTERPRETER; 954 955 APICState *pApic = getLapicById(pDev, idCpu); 956 uint32_t iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff; 957 return apicReadRegister(pDev, pApic, iReg, pu64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/); 820 958 } 821 959 … … 1234 1372 1235 1373 /** 1236 * May return to ring-3 to acquire the TM and PDM lock. 1237 */ 1238 static uint32_t apic_get_current_count(APICDeviceInfo const *pDev, APICState const *s) 1239 { 1240 int64_t d; 1374 * @remarks Caller (apicReadRegister) takes both the TM and APIC locks before 1375 * calling this function. 1376 */ 1377 static uint32_t apic_get_current_count(APICDeviceInfo const *pDev, APICState const *pApic) 1378 { 1379 int64_t d = (TMTimerGet(pApic->CTX_SUFF(pTimer)) - pApic->initial_count_load_time) 1380 >> pApic->count_shift; 1381 1241 1382 uint32_t val; 1242 1243 /* Acquire the timer lock w/ lock order kludge. */ 1244 PDMCritSectLeave(pDev->CTX_SUFF(pCritSect)); 1245 TMTimerLock(s->CTX_SUFF(pTimer), VINF_SUCCESS); 1246 PDMCritSectEnter(pDev->CTX_SUFF(pCritSect), VINF_SUCCESS); 1247 1248 d = (TMTimerGet(s->CTX_SUFF(pTimer)) - s->initial_count_load_time) >> 1249 s->count_shift; 1250 1251 if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) { 1383 if (pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) 1252 1384 /* periodic */ 1253 val = s->initial_count - (d % ((uint64_t)s->initial_count + 1)); 1254 } else { 1255 if (d >= s->initial_count) 1256 val = 0; 1257 else 1258 val = s->initial_count - d; 1259 } 1260 1261 TMTimerUnlock(s->CTX_SUFF(pTimer)); 1385 val = pApic->initial_count - (d % ((uint64_t)pApic->initial_count + 1)); 1386 else if (d >= pApic->initial_count) 1387 val = 0; 1388 else 1389 val = pApic->initial_count - d; 1262 1390 1263 1391 return val; … … 1387 1515 * We postpone stopping the timer when it's masked, this way we can 1388 1516 * avoid some timer work when the guest temporarily masks the timer. 1389 * (apic TimerCallback will stop it if still masked.)1517 * (apicR3TimerCallback will stop it if still masked.) 1390 1518 */ 1391 1519 if (fNew & APIC_LVT_MASKED) … … 1446 1574 * @param pvUser User argument pointing to the APIC instance. 1447 1575 */ 1448 static DECLCALLBACK(void) apic TimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)1576 static DECLCALLBACK(void) apicR3TimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 1449 1577 { 1450 1578 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); … … 1466 1594 pApic->fTimerArmed = true; 1467 1595 apicDoFrequencyHinting(pApic); 1468 Log2(("apic TimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));1596 Log2(("apicR3TimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time)); 1469 1597 } else { 1470 1598 /* single shot or disabled. */ … … 1478 1606 } 1479 1607 } 1480 # endif /* IN_RING3 */1481 1482 static int apic_mem_readl(APICDeviceInfo *pDev, APICState *s, RTGCPHYS addr, uint32_t *pu32)1483 {1484 int rc = VINF_SUCCESS;1485 int index = (addr >> 4) & 0xff;1486 uint32_t val;1487 1488 switch (index) {1489 case 0x02: /* id */1490 val = s->id << 24;1491 break;1492 case 0x03: /* version */1493 val = APIC_HW_VERSION | ((APIC_LVT_NB - 1) << 16);1494 break;1495 case 0x08:1496 val = s->tpr;1497 break;1498 case 0x09:1499 val = apic_get_arb_pri(s);1500 break;1501 case 0x0a:1502 /* ppr */1503 val = apic_get_ppr(s);1504 break;1505 case 0x0b:1506 Log(("apic_mem_readl %x %x -> write only returning 0\n", addr, index));1507 val = 0;1508 break;1509 case 0x0d:1510 val = s->log_dest << 24;1511 break;1512 case 0x0e:1513 /* Bottom 28 bits are always 1 */1514 val = (s->dest_mode << 28) | 0xfffffff;1515 break;1516 case 0x0f:1517 val = s->spurious_vec;1518 break;1519 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:1520 val = s->isr[index & 7];1521 break;1522 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:1523 val = s->tmr[index & 7];1524 break;1525 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:1526 val = s->irr[index & 7];1527 break;1528 case 0x28:1529 val = s->esr;1530 break;1531 case 0x30:1532 case 0x31:1533 val = s->icr[index & 1];1534 break;1535 case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:1536 val = s->lvt[index - 0x32];1537 break;1538 case 0x38:1539 val = s->initial_count;1540 break;1541 case 0x39:1542 val = apic_get_current_count(pDev, s);1543 break;1544 case 0x3e:1545 val = s->divide_conf;1546 break;1547 case 0x2f:1548 /** @todo1549 * Correctable machine check exception vector, implement me!1550 */1551 default:1552 s->esr |= ESR_ILLEGAL_ADDRESS;1553 *pu32 = 0;1554 Log(("APIC/%u: unknown index %#x (%RGp)\n", s->phys_id, index, addr));1555 return PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS,1556 "unknown index %#x (%RGp) (id=%u)\n", index, addr, s->phys_id);1557 }1558 #ifdef DEBUG_APIC1559 Log(("CPU%d: APIC read: %08x = %08x\n", s->phys_id, (uint32_t)addr, val));1560 #endif1561 *pu32 = val;1562 return rc;1563 }1564 1565 #ifdef IN_RING31566 1608 1567 1609 static void apic_save(SSMHANDLE* f, void *opaque) … … 1705 1747 #endif 1706 1748 #endif /* experimental */ 1707 APIC_LOCK(pDev, VINF_IOM_HC_MMIO_READ); 1708 int rc = apic_mem_readl(pDev, s, GCPhysAddr, (uint32_t *)pv); 1709 APIC_UNLOCK(pDev); 1749 1750 /* It does its own locking. */ 1751 uint64_t u64Value = 0; 1752 int rc = apicReadRegister(pDev, s, (GCPhysAddr >> 4) & 0xff, &u64Value, 1753 VINF_IOM_HC_MMIO_READ, false /*fMsr*/); 1754 *(uint32_t *)pv = (uint32_t)u64Value; 1710 1755 return rc; 1711 1756 } 1757 1712 1758 default: 1713 1759 AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */ … … 1749 1795 #ifdef IN_RING3 1750 1796 1751 /* Print a 8-dword LAPIC bit map (256 bits). */ 1752 static void lapicDumpVec(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp, unsigned start) 1753 { 1754 for (unsigned i = 0; i < 8; ++i) 1755 { 1756 uint32_t val; 1757 apic_mem_readl(pDev, lapic, start + (i << 4), &val); 1758 pHlp->pfnPrintf(pHlp, "%08X", val); 1759 } 1797 /** 1798 * Wrapper around apicReadRegister. 1799 * 1800 * @returns 64-bit register value. 1801 * @param pDev The PDM device instance. 1802 * @param pApic The Local APIC in question. 1803 * @param iReg The APIC register index. 1804 */ 1805 static uint64_t apicR3InfoReadReg(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg) 1806 { 1807 uint64_t u64Value; 1808 int rc = apicReadRegister(pDev, pApic, iReg, &u64Value, VINF_SUCCESS, true /*fMsr*/); 1809 AssertRCReturn(rc, UINT64_MAX); 1810 return u64Value; 1811 } 1812 1813 1814 /** 1815 * Print a 8-DWORD Local APIC bit map (256 bits). 1816 * 1817 * @param pDev The PDM device instance. 1818 * @param pApic The Local APIC in question. 1819 * @param pHlp The output helper. 1820 * @param iStartReg The register to start at. 1821 */ 1822 static void apicR3DumpVec(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp, uint32_t iStartReg) 1823 { 1824 for (uint32_t i = 0; i < 8; ++i) 1825 pHlp->pfnPrintf(pHlp, "%08x", apicR3InfoReadReg(pDev, pApic, iStartReg + i)); 1760 1826 pHlp->pfnPrintf(pHlp, "\n"); 1761 1827 } 1762 1828 1763 /* Print basic LAPIC state. */ 1764 static DECLCALLBACK(void) lapicInfoBasic(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp) 1765 { 1766 uint32_t val; 1767 unsigned max_lvt; 1768 1769 pHlp->pfnPrintf(pHlp, "Local APIC at %08X:\n", lapic->apicbase); 1770 apic_mem_readl(pDev, lapic, 0x20, &val); 1771 pHlp->pfnPrintf(pHlp, " LAPIC ID : %08X\n", val); 1772 pHlp->pfnPrintf(pHlp, " APIC ID = %02X\n", (val >> 24) & 0xff); 1773 apic_mem_readl(pDev, lapic, 0x30, &val); 1774 max_lvt = (val >> 16) & 0xff; 1775 pHlp->pfnPrintf(pHlp, " APIC VER : %08X\n", val); 1776 pHlp->pfnPrintf(pHlp, " version = %02X\n", val & 0xff); 1777 pHlp->pfnPrintf(pHlp, " lvts = %d\n", ((val >> 16) & 0xff) + 1); 1778 apic_mem_readl(pDev, lapic, 0x80, &val); 1779 pHlp->pfnPrintf(pHlp, " TPR : %08X\n", val); 1780 pHlp->pfnPrintf(pHlp, " task pri = %d/%d\n", (val >> 4) & 0xf, val & 0xf); 1781 apic_mem_readl(pDev, lapic, 0xA0, &val); 1782 pHlp->pfnPrintf(pHlp, " PPR : %08X\n", val); 1783 pHlp->pfnPrintf(pHlp, " cpu pri = %d/%d\n", (val >> 4) & 0xf, val & 0xf); 1784 apic_mem_readl(pDev, lapic, 0xD0, &val); 1785 pHlp->pfnPrintf(pHlp, " LDR : %08X\n", val); 1786 pHlp->pfnPrintf(pHlp, " log id = %02X\n", (val >> 24) & 0xff); 1787 apic_mem_readl(pDev, lapic, 0xE0, &val); 1788 pHlp->pfnPrintf(pHlp, " DFR : %08X\n", val); 1789 apic_mem_readl(pDev, lapic, 0xF0, &val); 1790 pHlp->pfnPrintf(pHlp, " SVR : %08X\n", val); 1791 pHlp->pfnPrintf(pHlp, " focus = %s\n", val & (1 << 9) ? "check off" : "check on"); 1792 pHlp->pfnPrintf(pHlp, " lapic = %s\n", val & (1 << 8) ? "ENABLED" : "DISABLED"); 1793 pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff); 1829 /** 1830 * Print basic Local APIC state. 1831 * 1832 * @param pDev The PDM device instance. 1833 * @param pApic The Local APIC in question. 1834 * @param pHlp The output helper. 1835 */ 1836 static void apicR3InfoBasic(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp) 1837 { 1838 uint64_t u64; 1839 1840 pHlp->pfnPrintf(pHlp, "Local APIC at %08llx:\n", pApic->apicbase); 1841 u64 = apicR3InfoReadReg(pDev, pApic, 0x2); 1842 pHlp->pfnPrintf(pHlp, " LAPIC ID : %08llx\n", u64); 1843 pHlp->pfnPrintf(pHlp, " APIC ID = %02llx\n", (u64 >> 24) & 0xff); 1844 u64 = apicR3InfoReadReg(pDev, pApic, 0x3); 1845 pHlp->pfnPrintf(pHlp, " APIC VER : %08llx\n", u64); 1846 pHlp->pfnPrintf(pHlp, " version = %02x\n", (int)RT_BYTE1(u64)); 1847 pHlp->pfnPrintf(pHlp, " lvts = %d\n", (int)RT_BYTE3(u64) + 1); 1848 u64 = apicR3InfoReadReg(pDev, pApic, 0x8); 1849 pHlp->pfnPrintf(pHlp, " TPR : %08llx\n", u64); 1850 pHlp->pfnPrintf(pHlp, " task pri = %lld/%lld\n", (u64 >> 4) & 0xf, u64 & 0xf); 1851 u64 = apicR3InfoReadReg(pDev, pApic, 0xA); 1852 pHlp->pfnPrintf(pHlp, " PPR : %08llx\n", u64); 1853 pHlp->pfnPrintf(pHlp, " cpu pri = %lld/%lld\n", (u64 >> 4) & 0xf, u64 & 0xf); 1854 u64 = apicR3InfoReadReg(pDev, pApic, 0xD); 1855 pHlp->pfnPrintf(pHlp, " LDR : %08llx\n", u64); 1856 pHlp->pfnPrintf(pHlp, " log id = %02llx\n", (u64 >> 24) & 0xff); 1857 pHlp->pfnPrintf(pHlp, " DFR : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0xE)); 1858 u64 = apicR3InfoReadReg(pDev, pApic, 0xF); 1859 pHlp->pfnPrintf(pHlp, " SVR : %08llx\n", u64); 1860 pHlp->pfnPrintf(pHlp, " focus = %s\n", u64 & RT_BIT(9) ? "check off" : "check on"); 1861 pHlp->pfnPrintf(pHlp, " lapic = %s\n", u64 & RT_BIT(8) ? "ENABLED" : "DISABLED"); 1862 pHlp->pfnPrintf(pHlp, " vector = %02x\n", (unsigned)RT_BYTE1(u64)); 1794 1863 pHlp->pfnPrintf(pHlp, " ISR : "); 1795 lapicDumpVec(pDev, lapic, pHlp, 0x100);1796 val = get_highest_priority_int(lapic->isr);1797 pHlp->pfnPrintf(pHlp, " highest = %02 X\n", val == ~0U ? 0 : val);1864 apicR3DumpVec(pDev, pApic, pHlp, 0x10); 1865 int iMax = get_highest_priority_int(pApic->isr); 1866 pHlp->pfnPrintf(pHlp, " highest = %02x\n", iMax == -1 ? 0 : iMax); 1798 1867 pHlp->pfnPrintf(pHlp, " IRR : "); 1799 lapicDumpVec(pDev, lapic, pHlp, 0x200); 1800 val = get_highest_priority_int(lapic->irr); 1801 pHlp->pfnPrintf(pHlp, " highest = %02X\n", val == ~0U ? 0 : val); 1802 apic_mem_readl(pDev, lapic, 0x320, &val); 1803 } 1804 1805 /* Print the more interesting LAPIC LVT entries. */ 1806 static DECLCALLBACK(void) lapicInfoLVT(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp) 1807 { 1808 static const char *s_apszDeliveryModes[] = 1868 apicR3DumpVec(pDev, pApic, pHlp, 0x20); 1869 iMax = get_highest_priority_int(pApic->irr); 1870 pHlp->pfnPrintf(pHlp, " highest = %02X\n", iMax == -1 ? 0 : iMax); 1871 } 1872 1873 1874 /** 1875 * Print the more interesting Local APIC LVT entries. 1876 * 1877 * @param pDev The PDM device instance. 1878 * @param pApic The Local APIC in question. 1879 * @param pHlp The output helper. 1880 */ 1881 static void apicR3InfoLVT(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp) 1882 { 1883 static const char * const s_apszDeliveryModes[] = 1809 1884 { 1810 1885 "Fixed ", "Reserved", "SMI", "Reserved", "NMI", "INIT", "Reserved", "ExtINT" 1811 1886 }; 1812 uint32_t val; 1813 1814 apic_mem_readl(pDev, lapic, 0x320, &val); 1815 pHlp->pfnPrintf(pHlp, " LVT Timer : %08X\n", val); 1816 pHlp->pfnPrintf(pHlp, " mode = %s\n", val & (1 << 17) ? "periodic" : "one-shot"); 1817 pHlp->pfnPrintf(pHlp, " mask = %d\n", (val >> 16) & 1); 1818 pHlp->pfnPrintf(pHlp, " status = %s\n", val & (1 << 12) ? "pending" : "idle"); 1819 pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff); 1820 apic_mem_readl(pDev, lapic, 0x350, &val); 1821 pHlp->pfnPrintf(pHlp, " LVT LINT0 : %08X\n", val); 1822 pHlp->pfnPrintf(pHlp, " mask = %d\n", (val >> 16) & 1); 1823 pHlp->pfnPrintf(pHlp, " trigger = %s\n", val & (1 << 15) ? "level" : "edge"); 1824 pHlp->pfnPrintf(pHlp, " rem irr = %d\n", (val >> 14) & 1); 1825 pHlp->pfnPrintf(pHlp, " polarty = %d\n", (val >> 13) & 1); 1826 pHlp->pfnPrintf(pHlp, " status = %s\n", val & (1 << 12) ? "pending" : "idle"); 1827 pHlp->pfnPrintf(pHlp, " delivry = %s\n", s_apszDeliveryModes[(val >> 8) & 7]); 1828 pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff); 1829 apic_mem_readl(pDev, lapic, 0x360, &val); 1830 pHlp->pfnPrintf(pHlp, " LVT LINT1 : %08X\n", val); 1831 pHlp->pfnPrintf(pHlp, " mask = %d\n", (val >> 16) & 1); 1832 pHlp->pfnPrintf(pHlp, " trigger = %s\n", val & (1 << 15) ? "level" : "edge"); 1833 pHlp->pfnPrintf(pHlp, " rem irr = %d\n", (val >> 14) & 1); 1834 pHlp->pfnPrintf(pHlp, " polarty = %d\n", (val >> 13) & 1); 1835 pHlp->pfnPrintf(pHlp, " status = %s\n", val & (1 << 12) ? "pending" : "idle"); 1836 pHlp->pfnPrintf(pHlp, " delivry = %s\n", s_apszDeliveryModes[(val >> 8) & 7]); 1837 pHlp->pfnPrintf(pHlp, " vector = %02X\n", val & 0xff); 1838 } 1839 1840 /* Print LAPIC timer state. */ 1841 static DECLCALLBACK(void) lapicInfoTimer(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp) 1842 { 1843 uint32_t val; 1844 unsigned divider; 1845 1887 uint64_t u64; 1888 1889 u64 = apicR3InfoReadReg(pDev, pApic, 0x32); 1890 pHlp->pfnPrintf(pHlp, " LVT Timer : %08llx\n", u64); 1891 pHlp->pfnPrintf(pHlp, " mode = %s\n", u64 & RT_BIT(17) ? "periodic" : "one-shot"); 1892 pHlp->pfnPrintf(pHlp, " mask = %llu\n", (u64 >> 16) & 1); 1893 pHlp->pfnPrintf(pHlp, " status = %s\n", u64 & RT_BIT(12) ? "pending" : "idle"); 1894 pHlp->pfnPrintf(pHlp, " vector = %02llx\n", u64 & 0xff); 1895 u64 = apicR3InfoReadReg(pDev, pApic, 0x35); 1896 pHlp->pfnPrintf(pHlp, " LVT LINT0 : %08llx\n", u64); 1897 pHlp->pfnPrintf(pHlp, " mask = %llu\n", (u64 >> 16) & 1); 1898 pHlp->pfnPrintf(pHlp, " trigger = %s\n", u64 & RT_BIT(15) ? "level" : "edge"); 1899 pHlp->pfnPrintf(pHlp, " rem irr = %llu\n", (u64 >> 14) & 1); 1900 pHlp->pfnPrintf(pHlp, " polarty = %llu\n", (u64 >> 13) & 1); 1901 pHlp->pfnPrintf(pHlp, " status = %s\n", u64 & RT_BIT(12) ? "pending" : "idle"); 1902 pHlp->pfnPrintf(pHlp, " delivry = %s\n", s_apszDeliveryModes[(u64 >> 8) & 7]); 1903 pHlp->pfnPrintf(pHlp, " vector = %02llx\n", u64 & 0xff); 1904 u64 = apicR3InfoReadReg(pDev, pApic, 0x36); 1905 pHlp->pfnPrintf(pHlp, " LVT LINT1 : %08llx\n", u64); 1906 pHlp->pfnPrintf(pHlp, " mask = %llu\n", (u64 >> 16) & 1); 1907 pHlp->pfnPrintf(pHlp, " trigger = %s\n", u64 & RT_BIT(15) ? "level" : "edge"); 1908 pHlp->pfnPrintf(pHlp, " rem irr = %lld\n", (u64 >> 14) & 1); 1909 pHlp->pfnPrintf(pHlp, " polarty = %lld\n", (u64 >> 13) & 1); 1910 pHlp->pfnPrintf(pHlp, " status = %s\n", u64 & RT_BIT(12) ? "pending" : "idle"); 1911 pHlp->pfnPrintf(pHlp, " delivry = %s\n", s_apszDeliveryModes[(u64 >> 8) & 7]); 1912 pHlp->pfnPrintf(pHlp, " vector = %02llx\n", u64 & 0xff); 1913 } 1914 1915 1916 /** 1917 * Print LAPIC timer state. 1918 * 1919 * @param pDev The PDM device instance. 1920 * @param pApic The Local APIC in question. 1921 * @param pHlp The output helper. 1922 */ 1923 static void apicR3InfoTimer(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp) 1924 { 1846 1925 pHlp->pfnPrintf(pHlp, "Local APIC timer:\n"); 1847 apic_mem_readl(pDev, lapic, 0x380, &val); 1848 pHlp->pfnPrintf(pHlp, " Initial count : %08X\n", val); 1849 apic_mem_readl(pDev, lapic, 0x390, &val); 1850 pHlp->pfnPrintf(pHlp, " Current count : %08X\n", val); 1851 apic_mem_readl(pDev, lapic, 0x3E0, &val); 1852 pHlp->pfnPrintf(pHlp, " Divide config : %08X\n", val); 1853 divider = ((val >> 1) & 0x04) | (val & 0x03); 1854 pHlp->pfnPrintf(pHlp, " divider = %d\n", divider == 7 ? 1 : 2 << divider); 1855 } 1856 1857 /** 1858 * Info handler, device version. Dumps Local APIC(s) state according to given argument. 1859 * 1860 * @param pDevIns Device instance which registered the info. 1861 * @param pHlp Callback functions for doing output. 1862 * @param pszArgs Argument string. Optional. 1863 */ 1864 static DECLCALLBACK(void) lapicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 1865 { 1866 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1867 APICState *lapic; 1868 1869 lapic = getLapic(pDev); 1926 pHlp->pfnPrintf(pHlp, " Initial count : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0x38)); 1927 pHlp->pfnPrintf(pHlp, " Current count : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0x39)); 1928 uint64_t u64 = apicR3InfoReadReg(pDev, pApic, 0x3e); 1929 pHlp->pfnPrintf(pHlp, " Divide config : %08llx\n", u64); 1930 unsigned uDivider = ((u64 >> 1) & 0x04) | (u64 & 0x03); 1931 pHlp->pfnPrintf(pHlp, " divider = %u\n", uDivider == 7 ? 1 : 2 << uDivider); 1932 } 1933 1934 1935 /** 1936 * @callback_method_impl{FNDBGFHANDLERDEV, 1937 * Dumps the Local APIC state according to given argument.} 1938 */ 1939 static DECLCALLBACK(void) apicR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 1940 { 1941 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1942 APICState *pApic = getLapic(pDev); 1870 1943 1871 1944 if (pszArgs == NULL || !strcmp(pszArgs, "basic")) 1872 lapicInfoBasic(pDev, lapic, pHlp);1945 apicR3InfoBasic(pDev, pApic, pHlp); 1873 1946 else if (!strcmp(pszArgs, "lvt")) 1874 lapicInfoLVT(pDev, lapic, pHlp);1947 apicR3InfoLVT(pDev, pApic, pHlp); 1875 1948 else if (!strcmp(pszArgs, "timer")) 1876 lapicInfoTimer(pDev, lapic, pHlp);1949 apicR3InfoTimer(pDev, pApic, pHlp); 1877 1950 else 1878 1951 pHlp->pfnPrintf(pHlp, "Invalid argument. Recognized arguments are 'basic', 'lvt', 'timer'.\n"); 1879 1952 } 1880 1953 1954 1881 1955 /** 1882 1956 * @copydoc FNSSMDEVLIVEEXEC 1883 1957 */ 1884 static DECLCALLBACK(int) apic LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)1958 static DECLCALLBACK(int) apicR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass) 1885 1959 { 1886 1960 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); … … 1894 1968 } 1895 1969 1970 1896 1971 /** 1897 1972 * @copydoc FNSSMDEVSAVEEXEC 1898 1973 */ 1899 static DECLCALLBACK(int) apic SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)1974 static DECLCALLBACK(int) apicR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 1900 1975 { 1901 1976 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1902 1977 1903 1978 /* config */ 1904 apic LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);1979 apicR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL); 1905 1980 1906 1981 /* save all APICs data, @todo: is it correct? */ … … 1913 1988 * @copydoc FNSSMDEVLOADEXEC 1914 1989 */ 1915 static DECLCALLBACK(int) apic LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)1990 static DECLCALLBACK(int) apicR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 1916 1991 { 1917 1992 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); … … 1957 2032 * @copydoc FNPDMDEVRESET 1958 2033 */ 1959 static DECLCALLBACK(void) apicR eset(PPDMDEVINS pDevIns)2034 static DECLCALLBACK(void) apicR3Reset(PPDMDEVINS pDevIns) 1960 2035 { 1961 2036 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); … … 1989 2064 } 1990 2065 2066 1991 2067 /** 1992 2068 * @copydoc FNPDMDEVRELOCATE 1993 2069 */ 1994 static DECLCALLBACK(void) apicR elocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)2070 static DECLCALLBACK(void) apicR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta) 1995 2071 { 1996 2072 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); … … 2003 2079 } 2004 2080 2005 DECLINLINE(void) initApicData(APICState* apic, uint8_t id) 2006 { 2007 int i; 2008 memset(apic, 0, sizeof(*apic)); 2009 2010 /* See comment in msi.h for LAPIC base info */ 2011 apic->apicbase = VBOX_MSI_ADDR_BASE | MSR_IA32_APICBASE_ENABLE; 2012 /* Mark first CPU as BSP */ 2013 if (id == 0) 2014 apic->apicbase |= MSR_IA32_APICBASE_BSP; 2015 for (i = 0; i < APIC_LVT_NB; i++) 2016 apic->lvt[i] = 1 << 16; /* mask LVT */ 2017 apic->spurious_vec = 0xff; 2018 apic->phys_id = apic->id = id; 2019 } 2081 2082 /** 2083 * Initializes the state of one local APIC. 2084 * 2085 * @param pApic The Local APIC state to init. 2086 * @param id The Local APIC ID. 2087 */ 2088 DECLINLINE(void) initApicData(APICState *pApic, uint8_t id) 2089 { 2090 memset(pApic, 0, sizeof(*pApic)); 2091 2092 /* See comment in msi.h for LAPIC base info. */ 2093 pApic->apicbase = VBOX_MSI_ADDR_BASE | MSR_IA32_APICBASE_ENABLE; 2094 if (id == 0) /* Mark first CPU as BSP. */ 2095 pApic->apicbase |= MSR_IA32_APICBASE_BSP; 2096 2097 for (int i = 0; i < APIC_LVT_NB; i++) 2098 pApic->lvt[i] = RT_BIT_32(16); /* mask LVT */ 2099 2100 pApic->spurious_vec = 0xff; 2101 pApic->phys_id = id; 2102 pApic->id = id; 2103 } 2104 2020 2105 2021 2106 /** 2022 2107 * @copydoc FNPDMDEVCONSTRUCT 2023 2108 */ 2024 static DECLCALLBACK(int) apic Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)2109 static DECLCALLBACK(int) apicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg) 2025 2110 { 2026 2111 PDMAPICREG ApicReg; … … 2173 2258 * The the CPUID feature bit. 2174 2259 */ 2175 /** @todo r=bird: See remark in the apicR eset. */2260 /** @todo r=bird: See remark in the apicR3Reset. */ 2176 2261 uint32_t u32Eax, u32Ebx, u32Ecx, u32Edx; 2177 2262 PDMDevHlpGetCpuId(pDevIns, 0, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx); … … 2225 2310 APICState *pApic = &pDev->paLapicsR3[i]; 2226 2311 pApic->pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_USER, "APIC Timer #%u", i); 2227 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apic TimerCallback, pApic,2312 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pApic, 2228 2313 TMTIMER_FLAGS_NO_CRIT_SECT, pApic->pszDesc, &pApic->pTimerR3); 2229 2314 if (RT_FAILURE(rc)) … … 2238 2323 */ 2239 2324 rc = PDMDevHlpSSMRegister3(pDevIns, APIC_SAVED_STATE_VERSION, sizeof(*pDev), 2240 apic LiveExec, apicSaveExec, apicLoadExec);2325 apicR3LiveExec, apicR3SaveExec, apicR3LoadExec); 2241 2326 if (RT_FAILURE(rc)) 2242 2327 return rc; … … 2245 2330 * Register debugger info callback. 2246 2331 */ 2247 PDMDevHlpDBGFInfoRegister(pDevIns, " lapic", "Display Local APIC state for current CPU. "2248 "Recognizes 'basic', 'lvt', 'timer' as arguments, defaulting to 'basic'.", lapicInfo);2332 PDMDevHlpDBGFInfoRegister(pDevIns, "apic", "Display Local APIC state for current CPU. " 2333 "Recognizes 'basic', 'lvt', 'timer' as arguments, defaulting to 'basic'.", apicR3Info); 2249 2334 2250 2335 #ifdef VBOX_WITH_STATISTICS … … 2300 2385 sizeof(APICState), 2301 2386 /* pfnConstruct */ 2302 apic Construct,2387 apicR3Construct, 2303 2388 /* pfnDestruct */ 2304 2389 NULL, 2305 2390 /* pfnRelocate */ 2306 apicR elocate,2391 apicR3Relocate, 2307 2392 /* pfnIOCtl */ 2308 2393 NULL, … … 2310 2395 NULL, 2311 2396 /* pfnReset */ 2312 apicR eset,2397 apicR3Reset, 2313 2398 /* pfnSuspend */ 2314 2399 NULL, -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r37475 r39060 336 336 { 337 337 AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)); 338 pdmLock(pVM);339 338 int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value); 340 pdmUnlock(pVM);341 339 return rc; 342 340 }
Note:
See TracChangeset
for help on using the changeset viewer.