mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 11:47:30 +00:00
hv: Add Interrupt Remapping Enable/Disable APIs
This patch adds IR enable/disable APIs. Upon boot, enabling IR is deferred until the first interrupt source is programmed. This is done for UEFI platforms as UEFI bootloader depends on timer interrupt and the programming of timer interrupt source is done before ACRN gets a chance to run during boot. Tracked-On: #2426 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
970821462b
commit
f122d6bd32
@ -408,6 +408,25 @@ static bool dmar_unit_support_aw(const struct dmar_drhd_rt *dmar_unit, uint32_t
|
||||
return (((1U << aw) & iommu_cap_sagaw(dmar_unit->cap)) != 0U);
|
||||
}
|
||||
|
||||
static void dmar_enable_intr_remapping(struct dmar_drhd_rt *dmar_unit)
|
||||
{
|
||||
uint32_t status = 0;
|
||||
|
||||
spinlock_obtain(&(dmar_unit->lock));
|
||||
if ((dmar_unit->gcmd & DMA_GCMD_IRE) == 0U) {
|
||||
dmar_unit->gcmd |= DMA_GCMD_IRE;
|
||||
iommu_write32(dmar_unit, DMAR_GCMD_REG, dmar_unit->gcmd);
|
||||
/* 32-bit register */
|
||||
dmar_wait_completion(dmar_unit, DMAR_GSTS_REG, DMA_GSTS_IRES, false, &status);
|
||||
#if DBG_IOMMU
|
||||
status = iommu_read32(dmar_unit, DMAR_GSTS_REG);
|
||||
#endif
|
||||
}
|
||||
|
||||
spinlock_release(&(dmar_unit->lock));
|
||||
dev_dbg(ACRN_DBG_IOMMU, "%s: gsr:0x%x", __func__, status);
|
||||
}
|
||||
|
||||
static void dmar_enable_translation(struct dmar_drhd_rt *dmar_unit)
|
||||
{
|
||||
uint32_t status = 0;
|
||||
@ -428,6 +447,21 @@ static void dmar_enable_translation(struct dmar_drhd_rt *dmar_unit)
|
||||
dev_dbg(ACRN_DBG_IOMMU, "%s: gsr:0x%x", __func__, status);
|
||||
}
|
||||
|
||||
static void dmar_disable_intr_remapping(struct dmar_drhd_rt *dmar_unit)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
spinlock_obtain(&(dmar_unit->lock));
|
||||
if ((dmar_unit->gcmd & DMA_GCMD_IRE) != 0U) {
|
||||
dmar_unit->gcmd &= ~DMA_GCMD_IRE;
|
||||
iommu_write32(dmar_unit, DMAR_GCMD_REG, dmar_unit->gcmd);
|
||||
/* 32-bit register */
|
||||
dmar_wait_completion(dmar_unit, DMAR_GSTS_REG, DMA_GSTS_IRES, true, &status);
|
||||
}
|
||||
|
||||
spinlock_release(&(dmar_unit->lock));
|
||||
}
|
||||
|
||||
static void dmar_disable_translation(struct dmar_drhd_rt *dmar_unit)
|
||||
{
|
||||
uint32_t status;
|
||||
@ -999,6 +1033,7 @@ static void dmar_disable(struct dmar_drhd_rt *dmar_unit)
|
||||
dmar_disable_qi(dmar_unit);
|
||||
dmar_disable_translation(dmar_unit);
|
||||
dmar_fault_event_mask(dmar_unit);
|
||||
dmar_disable_intr_remapping(dmar_unit);
|
||||
}
|
||||
|
||||
static void dmar_suspend(struct dmar_drhd_rt *dmar_unit)
|
||||
@ -1026,6 +1061,7 @@ static void dmar_resume(struct dmar_drhd_rt *dmar_unit)
|
||||
}
|
||||
dmar_prepare(dmar_unit);
|
||||
dmar_enable(dmar_unit);
|
||||
dmar_enable_intr_remapping(dmar_unit);
|
||||
}
|
||||
|
||||
static int32_t add_iommu_device(struct iommu_domain *domain, uint16_t segment, uint8_t bus, uint8_t devfun)
|
||||
@ -1375,6 +1411,7 @@ int32_t dmar_assign_irte(struct intr_source intr_src, union dmar_ir_entry irte,
|
||||
pr_err("IR table is not set for dmar unit");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
dmar_enable_intr_remapping(dmar_unit);
|
||||
irte.bits.svt = 0x1UL;
|
||||
irte.bits.sq = 0x0UL;
|
||||
irte.bits.sid = sid.value;
|
||||
|
Loading…
Reference in New Issue
Block a user