]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/blob - hw/kvm/ioapic.c
sysbus: apic: ioapic: convert to QEMU Object Model
[lisovros/qemu_apohw.git] / hw / kvm / ioapic.c
1 /*
2  * KVM in-kernel IOPIC support
3  *
4  * Copyright (c) 2011 Siemens AG
5  *
6  * Authors:
7  *  Jan Kiszka          <jan.kiszka@siemens.com>
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 void kvm_ioapic_class_init(ObjectClass *klass, void *data)
97 {
98     IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
99
100     k->init      = kvm_ioapic_init;
101     k->pre_save  = kvm_ioapic_get;
102     k->post_load = kvm_ioapic_put;
103 }
104
105 static DeviceInfo kvm_ioapic_info = {
106     .name  = "kvm-ioapic",
107     .size = sizeof(KVMIOAPICState),
108     .reset = kvm_ioapic_reset,
109     .class_init = kvm_ioapic_class_init,
110     .props = (Property[]) {
111         DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
112         DEFINE_PROP_END_OF_LIST()
113     },
114 };
115
116 static void kvm_ioapic_register_device(void)
117 {
118     ioapic_qdev_register(&kvm_ioapic_info);
119 }
120
121 device_init(kvm_ioapic_register_device)