#include <xen/lib.h>
#include <xen/delay.h>
+#include <xen/libfdt/libfdt.h>
#include <xen/mm.h>
#include <xen/rbtree.h>
#include <xen/sched.h>
return pirq;
}
+/*
+ * Create the respective guest DT nodes from a list of host ITSes.
+ * This copies the reg property, so the guest sees the ITS at the same address
+ * as the host.
+ */
+int gicv3_its_make_hwdom_dt_nodes(const struct domain *d,
+ const struct dt_device_node *gic,
+ void *fdt)
+{
+ uint32_t len;
+ int res;
+ const void *prop = NULL;
+ const struct dt_device_node *its = NULL;
+ const struct host_its *its_data;
+
+ if ( list_empty(&host_its_list) )
+ return 0;
+
+ /* The sub-nodes require the ranges property */
+ prop = dt_get_property(gic, "ranges", &len);
+ if ( !prop )
+ {
+ printk(XENLOG_ERR "Can't find ranges property for the gic node\n");
+ return -FDT_ERR_XEN(ENOENT);
+ }
+
+ res = fdt_property(fdt, "ranges", prop, len);
+ if ( res )
+ return res;
+
+ list_for_each_entry(its_data, &host_its_list, entry)
+ {
+ its = its_data->dt_node;
+
+ res = fdt_begin_node(fdt, its->name);
+ if ( res )
+ return res;
+
+ res = fdt_property_string(fdt, "compatible", "arm,gic-v3-its");
+ if ( res )
+ return res;
+
+ res = fdt_property(fdt, "msi-controller", NULL, 0);
+ if ( res )
+ return res;
+
+ if ( its->phandle )
+ {
+ res = fdt_property_cell(fdt, "phandle", its->phandle);
+ if ( res )
+ return res;
+ }
+
+ /* Use the same reg regions as the ITS node in host DTB. */
+ prop = dt_get_property(its, "reg", &len);
+ if ( !prop )
+ {
+ printk(XENLOG_ERR "GICv3: Can't find ITS reg property.\n");
+ res = -FDT_ERR_XEN(ENOENT);
+ return res;
+ }
+
+ res = fdt_property(fdt, "reg", prop, len);
+ if ( res )
+ return res;
+
+ fdt_end_node(fdt);
+ }
+
+ return res;
+}
+
/* Scan the DT for any ITS nodes and create a list of host ITSes out of it. */
void gicv3_its_dt_init(const struct dt_device_node *node)
{
int vgic_v3_its_init_domain(struct domain *d);
void vgic_v3_its_free_domain(struct domain *d);
+/* Create the appropriate DT nodes for a hardware domain. */
+int gicv3_its_make_hwdom_dt_nodes(const struct domain *d,
+ const struct dt_device_node *gic,
+ void *fdt);
+
/*
* Map a device on the host by allocating an ITT on the host (ITS).
* "nr_event" specifies how many events (interrupts) this device will need.
{
}
+static inline int gicv3_its_make_hwdom_dt_nodes(const struct domain *d,
+ const struct dt_device_node *gic,
+ void *fdt)
+{
+ return 0;
+}
+
#endif /* CONFIG_HAS_ITS */
#endif