* 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"
#include "hw/ppc/openpic.h"
+#include "hw/ppc/openpic_kvm.h"
#include "hw/pci/msi.h"
#include "hw/sysbus.h"
#include "sysemu/kvm.h"
#include "qemu/log.h"
+#define GCR_RESET 0x80000000
+
#define KVM_OPENPIC(obj) \
OBJECT_CHECK(KVMOpenPICState, (obj), TYPE_KVM_OPENPIC)
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)
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)
{
}
}
+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;
uint64_t reg_base;
int ret;
- if (section->address_space != &address_space_memory) {
- 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;
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)®_base;
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;
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;
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 = {