2 * KVM in-kernel PIC (i8259) support
4 * Copyright (c) 2011 Siemens AG
7 * Jan Kiszka <jan.kiszka@siemens.com>
9 * This work is licensed under the terms of the GNU GPL version 2.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "hw/isa/i8259_internal.h"
15 #include "qemu/module.h"
16 #include "hw/i386/apic_internal.h"
18 #include "sysemu/kvm.h"
20 #define TYPE_KVM_I8259 "kvm-i8259"
21 #define KVM_PIC_CLASS(class) \
22 OBJECT_CLASS_CHECK(KVMPICClass, (class), TYPE_KVM_I8259)
23 #define KVM_PIC_GET_CLASS(obj) \
24 OBJECT_GET_CLASS(KVMPICClass, (obj), TYPE_KVM_I8259)
28 * @parent_realize: The parent's realizefn.
30 typedef struct KVMPICClass
{
31 PICCommonClass parent_class
;
33 DeviceRealize parent_realize
;
36 static void kvm_pic_get(PICCommonState
*s
)
38 struct kvm_irqchip chip
;
39 struct kvm_pic_state
*kpic
;
42 chip
.chip_id
= s
->master
? KVM_IRQCHIP_PIC_MASTER
: KVM_IRQCHIP_PIC_SLAVE
;
43 ret
= kvm_vm_ioctl(kvm_state
, KVM_GET_IRQCHIP
, &chip
);
45 fprintf(stderr
, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret
));
49 kpic
= &chip
.chip
.pic
;
51 s
->last_irr
= kpic
->last_irr
;
55 s
->priority_add
= kpic
->priority_add
;
56 s
->irq_base
= kpic
->irq_base
;
57 s
->read_reg_select
= kpic
->read_reg_select
;
59 s
->special_mask
= kpic
->special_mask
;
60 s
->init_state
= kpic
->init_state
;
61 s
->auto_eoi
= kpic
->auto_eoi
;
62 s
->rotate_on_auto_eoi
= kpic
->rotate_on_auto_eoi
;
63 s
->special_fully_nested_mode
= kpic
->special_fully_nested_mode
;
64 s
->init4
= kpic
->init4
;
66 s
->elcr_mask
= kpic
->elcr_mask
;
69 static void kvm_pic_put(PICCommonState
*s
)
71 struct kvm_irqchip chip
;
72 struct kvm_pic_state
*kpic
;
75 chip
.chip_id
= s
->master
? KVM_IRQCHIP_PIC_MASTER
: KVM_IRQCHIP_PIC_SLAVE
;
77 kpic
= &chip
.chip
.pic
;
79 kpic
->last_irr
= s
->last_irr
;
83 kpic
->priority_add
= s
->priority_add
;
84 kpic
->irq_base
= s
->irq_base
;
85 kpic
->read_reg_select
= s
->read_reg_select
;
87 kpic
->special_mask
= s
->special_mask
;
88 kpic
->init_state
= s
->init_state
;
89 kpic
->auto_eoi
= s
->auto_eoi
;
90 kpic
->rotate_on_auto_eoi
= s
->rotate_on_auto_eoi
;
91 kpic
->special_fully_nested_mode
= s
->special_fully_nested_mode
;
92 kpic
->init4
= s
->init4
;
94 kpic
->elcr_mask
= s
->elcr_mask
;
96 ret
= kvm_vm_ioctl(kvm_state
, KVM_SET_IRQCHIP
, &chip
);
98 fprintf(stderr
, "KVM_SET_IRQCHIP failed: %s\n", strerror(ret
));
103 static void kvm_pic_reset(DeviceState
*dev
)
105 PICCommonState
*s
= PIC_COMMON(dev
);
113 static void kvm_pic_set_irq(void *opaque
, int irq
, int level
)
117 pic_stat_update_irq(irq
, level
);
118 delivered
= kvm_set_irq(kvm_state
, irq
, level
);
119 apic_report_irq_delivered(delivered
);
122 static void kvm_pic_realize(DeviceState
*dev
, Error
**errp
)
124 PICCommonState
*s
= PIC_COMMON(dev
);
125 KVMPICClass
*kpc
= KVM_PIC_GET_CLASS(dev
);
127 memory_region_init_io(&s
->base_io
, OBJECT(dev
), NULL
, NULL
, "kvm-pic", 2);
128 memory_region_init_io(&s
->elcr_io
, OBJECT(dev
), NULL
, NULL
, "kvm-elcr", 1);
130 kpc
->parent_realize(dev
, errp
);
133 qemu_irq
*kvm_i8259_init(ISABus
*bus
)
135 i8259_init_chip(TYPE_KVM_I8259
, bus
, true);
136 i8259_init_chip(TYPE_KVM_I8259
, bus
, false);
138 return qemu_allocate_irqs(kvm_pic_set_irq
, NULL
, ISA_NUM_IRQS
);
141 static void kvm_i8259_class_init(ObjectClass
*klass
, void *data
)
143 KVMPICClass
*kpc
= KVM_PIC_CLASS(klass
);
144 PICCommonClass
*k
= PIC_COMMON_CLASS(klass
);
145 DeviceClass
*dc
= DEVICE_CLASS(klass
);
147 dc
->reset
= kvm_pic_reset
;
148 device_class_set_parent_realize(dc
, kvm_pic_realize
, &kpc
->parent_realize
);
149 k
->pre_save
= kvm_pic_get
;
150 k
->post_load
= kvm_pic_put
;
153 static const TypeInfo kvm_i8259_info
= {
154 .name
= TYPE_KVM_I8259
,
155 .parent
= TYPE_PIC_COMMON
,
156 .instance_size
= sizeof(PICCommonState
),
157 .class_init
= kvm_i8259_class_init
,
158 .class_size
= sizeof(KVMPICClass
),
161 static void kvm_pic_register_types(void)
163 type_register_static(&kvm_i8259_info
);
166 type_init(kvm_pic_register_types
)