]> git.proxmox.com Git - mirror_qemu.git/blobdiff - hw/intc/openpic_kvm.c
memory: Rename memory_region_init_ram() to memory_region_init_ram_nomigrate()
[mirror_qemu.git] / hw / intc / openpic_kvm.c
index 6775879e0f964327f8efcf7ab0a281c1be6945e7..0518e017c49f8705bfcbe7140c38f1bd3b3d1a46 100644 (file)
  * THE SOFTWARE.
  */
 
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
 #include <sys/ioctl.h>
 #include "exec/address-spaces.h"
 #include "hw/hw.h"
@@ -31,6 +35,8 @@
 #include "sysemu/kvm.h"
 #include "qemu/log.h"
 
+#define GCR_RESET        0x80000000
+
 #define KVM_OPENPIC(obj) \
     OBJECT_CHECK(KVMOpenPICState, (obj), TYPE_KVM_OPENPIC)
 
@@ -43,6 +49,7 @@ typedef struct KVMOpenPICState {
     MemoryListener mem_listener;
     uint32_t fd;
     uint32_t model;
+    hwaddr mapped;
 } KVMOpenPICState;
 
 static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
@@ -50,11 +57,6 @@ static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
     kvm_set_irq(kvm_state, n_IRQ, level);
 }
 
-static void kvm_openpic_reset(DeviceState *d)
-{
-    qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
-}
-
 static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val,
                               unsigned size)
 {
@@ -74,6 +76,14 @@ static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val,
     }
 }
 
+static void kvm_openpic_reset(DeviceState *d)
+{
+    KVMOpenPICState *opp = KVM_OPENPIC(d);
+
+    /* Trigger the GCR.RESET bit to reset the PIC */
+    kvm_openpic_write(opp, 0x1020, GCR_RESET, sizeof(uint32_t));
+}
+
 static uint64_t kvm_openpic_read(void *opaque, hwaddr addr, unsigned size)
 {
     KVMOpenPICState *opp = opaque;
@@ -118,7 +128,21 @@ static void kvm_openpic_region_add(MemoryListener *listener,
         abort();
     }
 
+    /* Ignore events on regions that are not us */
+    if (section->mr != &opp->mem) {
+        return;
+    }
+
+    if (opp->mapped) {
+        /*
+         * We can only map the MPIC once. Since we are already mapped,
+         * the best we can do is ignore new maps.
+         */
+        return;
+    }
+
     reg_base = section->offset_within_address_space;
+    opp->mapped = reg_base;
 
     attr.group = KVM_DEV_MPIC_GRP_MISC;
     attr.attr = KVM_DEV_MPIC_BASE_ADDR;
@@ -140,6 +164,20 @@ static void kvm_openpic_region_del(MemoryListener *listener,
     uint64_t reg_base = 0;
     int ret;
 
+    /* Ignore events on regions that are not us */
+    if (section->mr != &opp->mem) {
+        return;
+    }
+
+    if (section->offset_within_address_space != opp->mapped) {
+        /*
+         * We can only map the MPIC once. This mapping was a secondary
+         * one that we couldn't fulfill. Ignore it.
+         */
+        return;
+    }
+    opp->mapped = 0;
+
     attr.group = KVM_DEV_MPIC_GRP_MISC;
     attr.attr = KVM_DEV_MPIC_BASE_ADDR;
     attr.addr = (uint64_t)(unsigned long)&reg_base;
@@ -155,7 +193,7 @@ static void kvm_openpic_init(Object *obj)
 {
     KVMOpenPICState *opp = KVM_OPENPIC(obj);
 
-    memory_region_init_io(&opp->mem, &kvm_openpic_mem_ops, opp,
+    memory_region_init_io(&opp->mem, OBJECT(opp), &kvm_openpic_mem_ops, opp,
                           "kvm-openpic", 0x40000);
 }
 
@@ -200,11 +238,11 @@ static void kvm_openpic_realize(DeviceState *dev, Error **errp)
     qdev_init_gpio_in(dev, kvm_openpic_set_irq, OPENPIC_MAX_IRQ);
 
     opp->mem_listener.region_add = kvm_openpic_region_add;
-    opp->mem_listener.region_add = kvm_openpic_region_del;
+    opp->mem_listener.region_del = kvm_openpic_region_del;
     memory_listener_register(&opp->mem_listener, &address_space_memory);
 
     /* indicate pic capabilities */
-    msi_supported = true;
+    msi_nonbroken = true;
     kvm_kernel_irqchip = true;
     kvm_async_interrupts_allowed = true;
 
@@ -214,7 +252,6 @@ static void kvm_openpic_realize(DeviceState *dev, Error **errp)
         kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
     }
 
-    kvm_irqfds_allowed = true;
     kvm_msi_via_irqfd_allowed = true;
     kvm_gsi_routing_allowed = true;
 
@@ -224,13 +261,9 @@ static void kvm_openpic_realize(DeviceState *dev, Error **errp)
 int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
 {
     KVMOpenPICState *opp = KVM_OPENPIC(d);
-    struct kvm_enable_cap encap = {};
-
-    encap.cap = KVM_CAP_IRQ_MPIC;
-    encap.args[0] = opp->fd;
-    encap.args[1] = cs->cpu_index;
 
-    return kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &encap);
+    return kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_MPIC, 0, opp->fd,
+                               kvm_arch_vcpu_id(cs));
 }
 
 static Property kvm_openpic_properties[] = {
@@ -246,6 +279,7 @@ static void kvm_openpic_class_init(ObjectClass *oc, void *data)
     dc->realize = kvm_openpic_realize;
     dc->props = kvm_openpic_properties;
     dc->reset = kvm_openpic_reset;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
 static const TypeInfo kvm_openpic_info = {