Changeset 24125 in vbox for trunk/src/VBox/Devices/PC
- Timestamp:
- Oct 28, 2009 9:58:41 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r24082 r24125 390 390 uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity, 391 391 uint8_t u8TriggerMode); 392 PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level); 392 393 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value); 393 394 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value); … … 446 447 } 447 448 448 DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s )449 DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE) 449 450 { 450 451 LogFlow(("apic: clear interrupt flag\n")); 451 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns), 452 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns), enmType, 452 453 getCpuFromLapic(dev, s)); 453 454 } … … 961 962 return apic_bus_deliver(dev, apic_get_delivery_bitmask(dev, u8Dest, u8DestMode), 962 963 u8DeliveryMode, iVector, u8Polarity, u8TriggerMode); 964 } 965 966 /** 967 * Local interrupt delivery, for devices attached to the CPU's LINT0/LINT1 pin. 968 * Normally used for 8259A PIC and NMI. 969 */ 970 PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level) 971 { 972 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 973 APICState *s = getLapicById(dev, 0); 974 975 Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect))); 976 LogFlow(("apicLocalInterrupt: pDevIns=%p u8Pin=%x\n", pDevIns, u8Pin)); 977 978 /* If LAPIC is disabled, go straight to the CPU. */ 979 if (!(s->spurious_vec & APIC_SV_ENABLE)) 980 { 981 LogFlow(("apicLocalInterrupt: LAPIC disabled, delivering directly to CPU core.\n")); 982 if (u8Level) 983 cpuSetInterrupt(dev, s, PDMAPICIRQ_EXTINT); 984 else 985 cpuClearInterrupt(dev, s, PDMAPICIRQ_EXTINT); 986 987 return VINF_SUCCESS; 988 } 989 990 /* If LAPIC is enabled, interrupts are subject to LVT programming. */ 991 if (u8Pin > 1) 992 { 993 /* There are only two local interrupt pins. */ 994 AssertMsgFailed(("Invalid LAPIC pin %d\n", u8Pin)); 995 return VERR_INVALID_PARAMETER; 996 } 997 998 /* NB: We currently only deliver local interrupts to the first CPU. In theory they 999 * should be delivered to all CPUs and it is the guest's responsibility to ensure 1000 * no more than one CPU has the interrupt unmasked. 1001 */ 1002 uint32_t u32Lvec; 1003 1004 u32Lvec = s->lvt[APIC_LVT_LINT0 + u8Pin]; /* Fetch corresponding LVT entry. */ 1005 /* Drop int if entry is masked. May not be correct for level-triggered interrupts. */ 1006 if (!(u32Lvec & APIC_LVT_MASKED)) 1007 { uint8_t u8Delivery; 1008 PDMAPICIRQ enmType; 1009 1010 u8Delivery = (u32Lvec >> 8) & 7; 1011 switch (u8Delivery) 1012 { 1013 case APIC_DM_EXTINT: 1014 Assert(u8Pin == 0); /* PIC should be wired to LINT0. */ 1015 enmType = PDMAPICIRQ_EXTINT; 1016 break; 1017 case APIC_DM_NMI: 1018 Assert(u8Pin == 0); /* NMI should be wired to LINT1. */ 1019 enmType = PDMAPICIRQ_NMI; 1020 break; 1021 case APIC_DM_SMI: 1022 enmType = PDMAPICIRQ_SMI; 1023 break; 1024 1025 } 1026 LogFlow(("apicLocalInterrupt: setting local interrupt type %d\n", enmType)); 1027 cpuSetInterrupt(dev, s, enmType); 1028 } 1029 return VINF_SUCCESS; 963 1030 } 964 1031 … … 2744 2811 ApicReg.pfnReadMSRR3 = apicReadMSR; 2745 2812 ApicReg.pfnBusDeliverR3 = apicBusDeliverCallback; 2813 ApicReg.pfnLocalInterruptR3 = apicLocalInterrupt; 2746 2814 if (fGCEnabled) { 2747 2815 ApicReg.pszGetInterruptRC = "apicGetInterrupt"; … … 2754 2822 ApicReg.pszReadMSRRC = "apicReadMSR"; 2755 2823 ApicReg.pszBusDeliverRC = "apicBusDeliverCallback"; 2824 ApicReg.pszLocalInterruptRC = "apicLocalInterrupt"; 2756 2825 } else { 2757 2826 ApicReg.pszGetInterruptRC = NULL; … … 2764 2833 ApicReg.pszReadMSRRC = NULL; 2765 2834 ApicReg.pszBusDeliverRC = NULL; 2835 ApicReg.pszLocalInterruptRC = NULL; 2766 2836 } 2767 2837 if (fR0Enabled) { … … 2775 2845 ApicReg.pszReadMSRR0 = "apicReadMSR"; 2776 2846 ApicReg.pszBusDeliverR0 = "apicBusDeliverCallback"; 2847 ApicReg.pszLocalInterruptR0 = "apicLocalInterrupt"; 2777 2848 } else { 2778 2849 ApicReg.pszGetInterruptR0 = NULL; … … 2785 2856 ApicReg.pszReadMSRR0 = NULL; 2786 2857 ApicReg.pszBusDeliverR0 = NULL; 2858 ApicReg.pszLocalInterruptR0 = NULL; 2787 2859 } 2788 2860
Note:
See TracChangeset
for help on using the changeset viewer.