|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 1/4] xen/arm: its: collect quirk flags and honor dma-noncoherent
From: Mykola Kvach <mykola_kvach@xxxxxxxx>
Replace the per-quirk init callback with declarative flags in
struct its_quirk, and introduce gicv3_its_collect_quirks() to gather
the effective workaround flags from both the IIDR-matched quirk entry
and the "dma-noncoherent" device-tree property.
This lets non-coherent platforms force non-cacheable ITS table
attributes even when no IIDR quirk entry matches.
Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
---
xen/arch/arm/gic-v3-its.c | 70 ++++++++++++++++++++++++---------------
1 file changed, 43 insertions(+), 27 deletions(-)
diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
index 9ba068c46f..00524b43a3 100644
--- a/xen/arch/arm/gic-v3-its.c
+++ b/xen/arch/arm/gic-v3-its.c
@@ -57,71 +57,87 @@ struct its_device {
*/
struct its_quirk {
const char *desc;
- bool (*init)(struct host_its *hw_its);
uint32_t iidr;
uint32_t mask;
+ uint32_t flags;
};
static uint32_t __ro_after_init its_quirk_flags;
-static bool gicv3_its_enable_quirk_gen4(struct host_its *hw_its)
-{
- its_quirk_flags |= HOST_ITS_WORKAROUND_NC_NS |
- HOST_ITS_WORKAROUND_32BIT_ADDR;
-
- return true;
-}
-
static const struct its_quirk its_quirks[] = {
{
- .desc = "R-Car Gen4",
- .iidr = 0x0201743b,
- .mask = 0xffffffffU,
- .init = gicv3_its_enable_quirk_gen4,
+ .desc = "R-Car Gen4",
+ .iidr = 0x0201743b,
+ .mask = 0xffffffffU,
+ .flags = HOST_ITS_WORKAROUND_NC_NS |
+ HOST_ITS_WORKAROUND_32BIT_ADDR,
},
{
/* Sentinel. */
}
};
-static struct its_quirk* gicv3_its_find_quirk(uint32_t iidr)
+static const struct its_quirk *gicv3_its_find_quirk(uint32_t iidr)
{
- const struct its_quirk *quirks = its_quirks;
+ const struct its_quirk *quirk = its_quirks;
- for ( ; quirks->desc; quirks++ )
+ for ( ; quirk->desc; quirk++ )
{
- if ( quirks->iidr == (quirks->mask & iidr) )
- return (struct its_quirk *)quirks;
+ if ( quirk->iidr != (quirk->mask & iidr) )
+ continue;
+
+ return quirk;
}
return NULL;
}
-static void gicv3_its_enable_quirks(struct host_its *hw_its)
+static uint32_t gicv3_its_collect_quirks(const struct host_its *hw_its,
+ const struct its_quirk
**matched_quirk)
{
+ const struct its_quirk *quirk;
+ uint32_t flags = 0;
uint32_t iidr = readl_relaxed(hw_its->its_base + GITS_IIDR);
- const struct its_quirk *quirk = gicv3_its_find_quirk(iidr);
- if ( quirk && quirk->init(hw_its) )
+ quirk = gicv3_its_find_quirk(iidr);
+ if ( quirk )
+ flags |= quirk->flags;
+
+ if ( hw_its->dt_node &&
+ dt_property_read_bool(hw_its->dt_node, "dma-noncoherent") )
+ flags |= HOST_ITS_WORKAROUND_NC_NS;
+
+ if ( matched_quirk )
+ *matched_quirk = quirk;
+
+ return flags;
+}
+
+static void gicv3_its_enable_quirks(struct host_its *hw_its)
+{
+ const struct its_quirk *quirk;
+
+ its_quirk_flags = gicv3_its_collect_quirks(hw_its, &quirk);
+
+ if ( quirk )
printk("GICv3: enabling workaround for ITS: %s\n", quirk->desc);
}
static void gicv3_its_validate_quirks(void)
{
- const struct its_quirk *quirk = NULL, *prev = NULL;
+ uint32_t quirks, prev_quirks;
const struct host_its *hw_its;
if ( list_empty(&host_its_list) )
return;
hw_its = list_first_entry(&host_its_list, struct host_its, entry);
- prev = gicv3_its_find_quirk(readl_relaxed(hw_its->its_base + GITS_IIDR));
+ prev_quirks = gicv3_its_collect_quirks(hw_its, NULL);
- list_for_each_entry(hw_its, &host_its_list, entry)
+ list_for_each_entry_continue(hw_its, &host_its_list, entry)
{
- quirk = gicv3_its_find_quirk(readl_relaxed(hw_its->its_base +
GITS_IIDR));
- BUG_ON(quirk != prev);
- prev = quirk;
+ quirks = gicv3_its_collect_quirks(hw_its, NULL);
+ BUG_ON(quirks != prev_quirks);
}
}
--
2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |