This patch adds infrastructure to support interrupts from PAPR virtual IO
devices. This includes correctly advertising those interrupts in the
device tree, and implementing the H_VIO_SIGNAL hypercall, used to
enable and disable individual device interrupts.
Signed-off-by: David Gibson<address@hidden>
---
hw/spapr.c | 2 +-
hw/spapr_vio.c | 34 ++++++++++++++++++++++++++++++++++
hw/spapr_vio.h | 6 ++++++
3 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/hw/spapr.c b/hw/spapr.c
index be30def..5b19963 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -62,7 +62,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t
ramsize,
uint32_t start_prop = cpu_to_be32(initrd_base);
uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
- char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr";
+ char hypertas_prop[] =
"hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt";
uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
int i;
char *modelname;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 0ed63f4..45edd94 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -105,6 +105,15 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
}
}
+ if (dev->qirq) {
+ uint32_t ints_prop[] = {cpu_to_be32(dev->vio_irq_num), 0};
+
+ ret = fdt_setprop(fdt, node_off, "interrupts", ints_prop,
+ sizeof(ints_prop));
+ if (ret< 0)
+ return ret;
+ }
+
if (info->devnode) {
ret = (info->devnode)(dev, fdt, node_off);
if (ret< 0) {
@@ -140,6 +149,28 @@ void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo
*info)
qdev_register(&info->qdev);
}
+static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
+ target_ulong opcode,
+ target_ulong *args)
+{
+ target_ulong reg = args[0];
+ target_ulong mode = args[1];
+ VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+ VIOsPAPRDeviceInfo *info;
+
+ if (!dev)