[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 12/28] ARM: GICv3: enable ITS and LPIs on the host
Now that the host part of the ITS code is in place, we can enable the ITS and also LPIs on each redistributor to get the show rolling. At this point there would be no LPIs mapped, as guests don't know about the ITS yet. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> --- xen/arch/arm/gic-v3-its.c | 34 ++++++++++++++++++++++++++++++++-- xen/arch/arm/gic-v3.c | 19 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c index f073ab5..2a7093f 100644 --- a/xen/arch/arm/gic-v3-its.c +++ b/xen/arch/arm/gic-v3-its.c @@ -62,6 +62,28 @@ static int its_send_command(struct host_its *hw_its, const void *its_cmd) return 0; } +/* Wait for an ITS to finish processing all commands. */ +static int gicv3_its_wait_commands(struct host_its *hw_its) +{ + s_time_t deadline = NOW() + MILLISECS(1000); + uint64_t readp, writep; + + do { + spin_lock(&hw_its->cmd_lock); + readp = readq_relaxed(hw_its->its_base + GITS_CREADR) & BUFPTR_MASK; + writep = readq_relaxed(hw_its->its_base + GITS_CWRITER) & BUFPTR_MASK; + spin_unlock(&hw_its->cmd_lock); + + if ( readp == writep ) + return 0; + + cpu_relax(); + udelay(1); + } while ( NOW() <= deadline ); + + return -ETIMEDOUT; +} + static uint64_t encode_rdbase(struct host_its *hw_its, int cpu, uint64_t reg) { reg &= ~GENMASK(51, 16); @@ -161,6 +183,10 @@ int gicv3_its_setup_collection(int cpu) ret = its_send_cmd_sync(its, cpu); if ( ret ) return ret; + + ret = gicv3_its_wait_commands(its); + if ( ret ) + return ret; } return 0; @@ -367,6 +393,10 @@ int gicv3_its_init(struct host_its *hw_its) return -ENOMEM; writeq_relaxed(0, hw_its->its_base + GITS_CWRITER); + /* Now enable interrupt translation and command processing on that ITS. */ + reg = readl_relaxed(hw_its->its_base + GITS_CTLR); + writel_relaxed(reg | GITS_CTLR_ENABLE, hw_its->its_base + GITS_CTLR); + /* * We issue the collection mapping calls upon initialising the * redistributors, which for CPU 0 happens before the ITS gets initialised @@ -381,7 +411,7 @@ int gicv3_its_init(struct host_its *hw_its) if ( ret ) return ret; - return 0; + return gicv3_its_wait_commands(hw_its); } static void remove_mapped_guest_device(struct its_devices *dev) @@ -424,7 +454,7 @@ int gicv3_its_map_host_events(struct host_its *its, if ( ret ) return ret; - return 0; + return gicv3_its_wait_commands(its); } int gicv3_its_map_guest_device(struct domain *d, int host_devid, diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index 5f825a6..23cf33d 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -647,6 +647,21 @@ static int gicv3_rdist_init_lpis(void __iomem * rdist_base) return gicv3_its_setup_collection(smp_processor_id()); } +/* Enable LPIs on this redistributor (only useful when the host has an ITS. */ +static bool gicv3_enable_lpis(void) +{ + uint32_t val; + + val = readl_relaxed(GICD_RDIST_BASE + GICR_TYPER); + if ( !(val & GICR_TYPER_PLPIS) ) + return false; + + val = readl_relaxed(GICD_RDIST_BASE + GICR_CTLR); + writel_relaxed(val | GICR_CTLR_ENABLE_LPIS, GICD_RDIST_BASE + GICR_CTLR); + + return true; +} + static int __init gicv3_populate_rdist(void) { int i; @@ -755,6 +770,10 @@ static int gicv3_cpu_init(void) if ( gicv3_enable_redist() ) return -ENODEV; + /* If the host has any ITSes, enable LPIs now. */ + if ( !list_empty(&host_its_list) ) + gicv3_enable_lpis(); + /* Set priority on PPI and SGI interrupts */ priority = (GIC_PRI_IPI << 24 | GIC_PRI_IPI << 16 | GIC_PRI_IPI << 8 | GIC_PRI_IPI); -- 2.9.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |