unsigned int apic, unsigned int reg);
int amd_iommu_msi_msg_update_ire(
struct msi_desc *msi_desc, struct msi_msg *msg);
-void amd_iommu_read_msi_from_ire(
- struct msi_desc *msi_desc, struct msi_msg *msg);
int amd_setup_hpet_msi(struct msi_desc *msi_desc);
void amd_iommu_dump_intremap_tables(unsigned char key);
return rc;
}
-void amd_iommu_read_msi_from_ire(
- struct msi_desc *msi_desc, struct msi_msg *msg)
-{
- unsigned int offset = msg->data & (INTREMAP_MAX_ENTRIES - 1);
- const struct pci_dev *pdev = msi_desc->dev;
- u16 bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
- u16 seg = pdev ? pdev->seg : hpet_sbdf.seg;
- const struct amd_iommu *iommu = _find_iommu_for_device(seg, bdf);
- union irte_ptr entry;
-
- if ( IS_ERR_OR_NULL(iommu) )
- return;
-
- entry = get_intremap_entry(iommu, get_dma_requestor_id(seg, bdf), offset);
-
- if ( msi_desc->msi_attrib.type == PCI_CAP_ID_MSI )
- {
- int nr = msi_desc->msi_attrib.entry_nr;
-
- ASSERT(!(offset & (msi_desc[-nr].msi.nvec - 1)));
- offset |= nr;
- }
-
- msg->data &= ~(INTREMAP_MAX_ENTRIES - 1);
- /* The IntType fields match for both formats. */
- msg->data |= MASK_INSR(entry.ptr32->flds.int_type,
- MSI_DATA_DELIVERY_MODE_MASK);
- if ( iommu->ctrl.ga_en )
- {
- msg->data |= MASK_INSR(entry.ptr128->full.vector,
- MSI_DATA_VECTOR_MASK);
- msg->dest32 = get_full_dest(entry.ptr128);
- }
- else
- {
- msg->data |= MASK_INSR(entry.ptr32->flds.vector,
- MSI_DATA_VECTOR_MASK);
- msg->dest32 = entry.ptr32->flds.dest;
- }
-}
-
int amd_iommu_free_intremap_table(
const struct amd_iommu *iommu, struct ivrs_mappings *ivrs_mapping,
uint16_t bdf)
.update_ire_from_apic = amd_iommu_ioapic_update_ire,
.update_ire_from_msi = amd_iommu_msi_msg_update_ire,
.read_apic_from_ire = amd_iommu_read_ioapic_from_ire,
- .read_msi_from_ire = amd_iommu_read_msi_from_ire,
.setup_hpet_msi = amd_setup_hpet_msi,
.adjust_irq_affinities = iov_adjust_irq_affinities,
.suspend = amd_iommu_suspend,
? iommu_call(&iommu_ops, update_ire_from_msi, msi_desc, msg) : 0;
}
-void iommu_read_msi_from_ire(
- struct msi_desc *msi_desc, struct msi_msg *msg)
-{
- if ( iommu_intremap )
- iommu_vcall(&iommu_ops, read_msi_from_ire, msi_desc, msg);
-}
-
static int iommu_add_device(struct pci_dev *pdev)
{
const struct domain_iommu *hd;
struct msi_desc;
struct msi_msg;
-void msi_msg_read_remap_rte(struct msi_desc *, struct msi_msg *);
int msi_msg_write_remap_rte(struct msi_desc *, struct msi_msg *);
int intel_setup_hpet_msi(struct msi_desc *);
}
}
-static int remap_entry_to_msi_msg(
- struct vtd_iommu *iommu, struct msi_msg *msg, unsigned int index)
-{
- struct iremap_entry *iremap_entry = NULL, *iremap_entries;
- struct msi_msg_remap_entry *remap_rte;
- unsigned long flags;
-
- remap_rte = (struct msi_msg_remap_entry *) msg;
- index += (remap_rte->address_lo.index_15 << 15) |
- remap_rte->address_lo.index_0_14;
-
- if ( index >= IREMAP_ENTRY_NR )
- {
- dprintk(XENLOG_ERR VTDPREFIX,
- "MSI index (%d) for remap table is invalid\n",
- index);
- return -EFAULT;
- }
-
- spin_lock_irqsave(&iommu->intremap.lock, flags);
-
- GET_IREMAP_ENTRY(iommu->intremap.maddr, index,
- iremap_entries, iremap_entry);
-
- if ( iremap_entry->val == 0 )
- {
- dprintk(XENLOG_ERR VTDPREFIX,
- "MSI index (%d) has an empty entry\n",
- index);
- unmap_vtd_domain_page(iremap_entries);
- spin_unlock_irqrestore(&iommu->intremap.lock, flags);
- return -EFAULT;
- }
-
- msg->address_hi = MSI_ADDR_BASE_HI;
- msg->address_lo =
- MSI_ADDR_BASE_LO |
- ((iremap_entry->remap.dm == 0) ?
- MSI_ADDR_DESTMODE_PHYS:
- MSI_ADDR_DESTMODE_LOGIC) |
- ((iremap_entry->remap.dlm != dest_LowestPrio) ?
- MSI_ADDR_REDIRECTION_CPU:
- MSI_ADDR_REDIRECTION_LOWPRI);
- if ( x2apic_enabled )
- msg->dest32 = iremap_entry->remap.dst;
- else
- msg->dest32 = (iremap_entry->remap.dst >> 8) & 0xff;
- msg->address_lo |= MSI_ADDR_DEST_ID(msg->dest32);
-
- msg->data =
- MSI_DATA_TRIGGER_EDGE |
- MSI_DATA_LEVEL_ASSERT |
- ((iremap_entry->remap.dlm != dest_LowestPrio) ?
- MSI_DATA_DELIVERY_FIXED:
- MSI_DATA_DELIVERY_LOWPRI) |
- iremap_entry->remap.vector;
-
- unmap_vtd_domain_page(iremap_entries);
- spin_unlock_irqrestore(&iommu->intremap.lock, flags);
- return 0;
-}
-
static int msi_msg_to_remap_entry(
struct vtd_iommu *iommu, struct pci_dev *pdev,
struct msi_desc *msi_desc, struct msi_msg *msg)
return 0;
}
-void msi_msg_read_remap_rte(
- struct msi_desc *msi_desc, struct msi_msg *msg)
-{
- struct pci_dev *pdev = msi_desc->dev;
- struct acpi_drhd_unit *drhd = NULL;
-
- drhd = pdev ? acpi_find_matched_drhd_unit(pdev)
- : hpet_to_drhd(msi_desc->hpet_id);
- if ( drhd )
- remap_entry_to_msi_msg(drhd->iommu, msg,
- msi_desc->msi_attrib.type == PCI_CAP_ID_MSI
- ? msi_desc->msi_attrib.entry_nr : 0);
-}
-
int msi_msg_write_remap_rte(
struct msi_desc *msi_desc, struct msi_msg *msg)
{
.update_ire_from_apic = io_apic_write_remap_rte,
.update_ire_from_msi = msi_msg_write_remap_rte,
.read_apic_from_ire = io_apic_read_remap_rte,
- .read_msi_from_ire = msi_msg_read_remap_rte,
.setup_hpet_msi = intel_setup_hpet_msi,
.adjust_irq_affinities = adjust_vtd_irq_affinities,
.suspend = vtd_suspend,
struct msi_msg;
int iommu_update_ire_from_msi(struct msi_desc *msi_desc, struct msi_msg *msg);
-void iommu_read_msi_from_ire(struct msi_desc *msi_desc, struct msi_msg *msg);
#define PT_IRQ_TIME_OUT MILLISECS(8)
#endif /* HAS_PCI */