HV: vuart: send msi for pci vuart type
if vuart type is pci-vuart, then use MSI interrupt split vuart_toggle_intr() control flow into vuart_trigger_level_intr() & trigger_vmcs9900_msix(), because MSI is edge triggered, no deassertion operation. Only trigger MSI for pci-vuart when assert interrupt. Tracked-On: #5394 Signed-off-by: Tao Yuhong <yuhong.tao@intel.com> Reviewed-by: Wang, Yu1 <yu1.wang@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
parent
55b7fae67a
commit
691abe90ff
|
@ -14,6 +14,23 @@
|
||||||
#define MCS9900_MMIO_BAR 0U
|
#define MCS9900_MMIO_BAR 0U
|
||||||
#define MCS9900_MSIX_BAR 1U
|
#define MCS9900_MSIX_BAR 1U
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre vdev != NULL
|
||||||
|
*/
|
||||||
|
void trigger_vmcs9900_msix(struct pci_vdev *vdev)
|
||||||
|
{
|
||||||
|
struct acrn_vm *vm = vpci2vm(vdev->vpci);
|
||||||
|
int32_t ret = -1;
|
||||||
|
struct msix_table_entry *entry = &vdev->msix.table_entries[0];
|
||||||
|
|
||||||
|
ret = vlapic_inject_msi(vm, entry->addr, entry->data);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
pr_warn("%2x:%2x.%dfaild injecting msi msi_addr:0x%lx msi_data:0x%x",
|
||||||
|
vdev->bdf.bits.b, vdev->bdf.bits.d, vdev->bdf.bits.f, entry->addr, entry->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t read_vmcs9900_cfg(const struct pci_vdev *vdev,
|
static int32_t read_vmcs9900_cfg(const struct pci_vdev *vdev,
|
||||||
uint32_t offset, uint32_t bytes,
|
uint32_t offset, uint32_t bytes,
|
||||||
uint32_t * val)
|
uint32_t * val)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <uart16550.h>
|
#include <uart16550.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
#include <vuart.h>
|
#include <vuart.h>
|
||||||
|
#include <vmcs9900.h>
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
|
|
||||||
|
@ -165,17 +166,11 @@ static struct acrn_vuart *find_vuart_by_port(struct acrn_vm *vm, uint16_t offset
|
||||||
return ret_vu;
|
return ret_vu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void vuart_trigger_level_intr(const struct acrn_vuart *vu, bool assert)
|
||||||
* Toggle the COM port's intr pin depending on whether or not we have an
|
|
||||||
* interrupt condition to report to the processor.
|
|
||||||
*/
|
|
||||||
void vuart_toggle_intr(const struct acrn_vuart *vu)
|
|
||||||
{
|
{
|
||||||
uint8_t intr_reason;
|
|
||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
uint32_t operation;
|
uint32_t operation;
|
||||||
|
|
||||||
intr_reason = vuart_intr_reason(vu);
|
|
||||||
vioapic_get_rte(vu->vm, vu->irq, &rte);
|
vioapic_get_rte(vu->vm, vu->irq, &rte);
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
|
@ -187,15 +182,35 @@ void vuart_toggle_intr(const struct acrn_vuart *vu)
|
||||||
* we want to make it as an known issue.
|
* we want to make it as an known issue.
|
||||||
*/
|
*/
|
||||||
if (rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) {
|
if (rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) {
|
||||||
operation = (intr_reason != IIR_NOPEND) ? GSI_SET_LOW : GSI_SET_HIGH;
|
operation = assert ? GSI_SET_LOW : GSI_SET_HIGH;
|
||||||
} else {
|
} else {
|
||||||
operation = (intr_reason != IIR_NOPEND) ? GSI_SET_HIGH : GSI_SET_LOW;
|
operation = assert ? GSI_SET_HIGH : GSI_SET_LOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpic_set_irqline(vm_pic(vu->vm), vu->irq, operation);
|
vpic_set_irqline(vm_pic(vu->vm), vu->irq, operation);
|
||||||
vioapic_set_irqline_lock(vu->vm, vu->irq, operation);
|
vioapic_set_irqline_lock(vu->vm, vu->irq, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Toggle the COM port's intr pin depending on whether or not we have an
|
||||||
|
* interrupt condition to report to the processor.
|
||||||
|
*/
|
||||||
|
void vuart_toggle_intr(const struct acrn_vuart *vu)
|
||||||
|
{
|
||||||
|
uint8_t intr_reason;
|
||||||
|
|
||||||
|
intr_reason = vuart_intr_reason(vu);
|
||||||
|
|
||||||
|
if ((vu->vdev != NULL) && (intr_reason != IIR_NOPEND)) {
|
||||||
|
/* FIXME: Toggle is for level trigger interrupt, for edge trigger need refine the logic later. */
|
||||||
|
trigger_vmcs9900_msix(vu->vdev);
|
||||||
|
} else if (intr_reason != IIR_NOPEND) {
|
||||||
|
vuart_trigger_level_intr(vu, true);
|
||||||
|
} else {
|
||||||
|
vuart_trigger_level_intr(vu, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool send_to_target(struct acrn_vuart *vu, uint8_t value_u8)
|
static bool send_to_target(struct acrn_vuart *vu, uint8_t value_u8)
|
||||||
{
|
{
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
|
|
|
@ -11,5 +11,6 @@
|
||||||
#define MCS9900_DEV 0x9900U
|
#define MCS9900_DEV 0x9900U
|
||||||
|
|
||||||
extern const struct pci_vdev_ops vmcs9900_ops;
|
extern const struct pci_vdev_ops vmcs9900_ops;
|
||||||
|
void trigger_vmcs9900_msix(struct pci_vdev *vdev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue