|
|
1.1 ! root 1: /* ! 2: * KVM in-kernel IOPIC support ! 3: * ! 4: * Copyright (c) 2011 Siemens AG ! 5: * ! 6: * Authors: ! 7: * Jan Kiszka <[email protected]> ! 8: * ! 9: * This work is licensed under the terms of the GNU GPL version 2. ! 10: * See the COPYING file in the top-level directory. ! 11: */ ! 12: ! 13: #include "hw/pc.h" ! 14: #include "hw/ioapic_internal.h" ! 15: #include "hw/apic_internal.h" ! 16: #include "kvm.h" ! 17: ! 18: typedef struct KVMIOAPICState KVMIOAPICState; ! 19: ! 20: struct KVMIOAPICState { ! 21: IOAPICCommonState ioapic; ! 22: uint32_t kvm_gsi_base; ! 23: }; ! 24: ! 25: static void kvm_ioapic_get(IOAPICCommonState *s) ! 26: { ! 27: struct kvm_irqchip chip; ! 28: struct kvm_ioapic_state *kioapic; ! 29: int ret, i; ! 30: ! 31: chip.chip_id = KVM_IRQCHIP_IOAPIC; ! 32: ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, &chip); ! 33: if (ret < 0) { ! 34: fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ! 35: abort(); ! 36: } ! 37: ! 38: kioapic = &chip.chip.ioapic; ! 39: ! 40: s->id = kioapic->id; ! 41: s->ioregsel = kioapic->ioregsel; ! 42: s->irr = kioapic->irr; ! 43: for (i = 0; i < IOAPIC_NUM_PINS; i++) { ! 44: s->ioredtbl[i] = kioapic->redirtbl[i].bits; ! 45: } ! 46: } ! 47: ! 48: static void kvm_ioapic_put(IOAPICCommonState *s) ! 49: { ! 50: struct kvm_irqchip chip; ! 51: struct kvm_ioapic_state *kioapic; ! 52: int ret, i; ! 53: ! 54: chip.chip_id = KVM_IRQCHIP_IOAPIC; ! 55: kioapic = &chip.chip.ioapic; ! 56: ! 57: kioapic->id = s->id; ! 58: kioapic->ioregsel = s->ioregsel; ! 59: kioapic->base_address = s->busdev.mmio[0].addr; ! 60: kioapic->irr = s->irr; ! 61: for (i = 0; i < IOAPIC_NUM_PINS; i++) { ! 62: kioapic->redirtbl[i].bits = s->ioredtbl[i]; ! 63: } ! 64: ! 65: ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip); ! 66: if (ret < 0) { ! 67: fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); ! 68: abort(); ! 69: } ! 70: } ! 71: ! 72: static void kvm_ioapic_reset(DeviceState *dev) ! 73: { ! 74: IOAPICCommonState *s = DO_UPCAST(IOAPICCommonState, busdev.qdev, dev); ! 75: ! 76: ioapic_reset_common(dev); ! 77: kvm_ioapic_put(s); ! 78: } ! 79: ! 80: static void kvm_ioapic_set_irq(void *opaque, int irq, int level) ! 81: { ! 82: KVMIOAPICState *s = opaque; ! 83: int delivered; ! 84: ! 85: delivered = kvm_irqchip_set_irq(kvm_state, s->kvm_gsi_base + irq, level); ! 86: apic_report_irq_delivered(delivered); ! 87: } ! 88: ! 89: static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no) ! 90: { ! 91: memory_region_init_reservation(&s->io_memory, "kvm-ioapic", 0x1000); ! 92: ! 93: qdev_init_gpio_in(&s->busdev.qdev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS); ! 94: } ! 95: ! 96: static Property kvm_ioapic_properties[] = { ! 97: DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0), ! 98: DEFINE_PROP_END_OF_LIST() ! 99: }; ! 100: ! 101: static void kvm_ioapic_class_init(ObjectClass *klass, void *data) ! 102: { ! 103: IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); ! 104: DeviceClass *dc = DEVICE_CLASS(klass); ! 105: ! 106: k->init = kvm_ioapic_init; ! 107: k->pre_save = kvm_ioapic_get; ! 108: k->post_load = kvm_ioapic_put; ! 109: dc->reset = kvm_ioapic_reset; ! 110: dc->props = kvm_ioapic_properties; ! 111: } ! 112: ! 113: static TypeInfo kvm_ioapic_info = { ! 114: .name = "kvm-ioapic", ! 115: .parent = TYPE_IOAPIC_COMMON, ! 116: .instance_size = sizeof(KVMIOAPICState), ! 117: .class_init = kvm_ioapic_class_init, ! 118: }; ! 119: ! 120: static void kvm_ioapic_register_types(void) ! 121: { ! 122: type_register_static(&kvm_ioapic_info); ! 123: } ! 124: ! 125: type_init(kvm_ioapic_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.