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.
12 #include "hw/i8259_internal.h"
13 #include "hw/apic_internal.h"
14 #include "sysemu/kvm.h"
16 static void kvm_pic_get(PICCommonState
*s
)
18 struct kvm_irqchip chip
;
19 struct kvm_pic_state
*kpic
;
22 chip
.chip_id
= s
->master
? KVM_IRQCHIP_PIC_MASTER
: KVM_IRQCHIP_PIC_SLAVE
;
23 ret
= kvm_vm_ioctl(kvm_state
, KVM_GET_IRQCHIP
, &chip
);
25 fprintf(stderr
, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret
));
29 kpic
= &chip
.chip
.pic
;
31 s
->last_irr
= kpic
->last_irr
;
35 s
->priority_add
= kpic
->priority_add
;
36 s
->irq_base
= kpic
->irq_base
;
37 s
->read_reg_select
= kpic
->read_reg_select
;
39 s
->special_mask
= kpic
->special_mask
;
40 s
->init_state
= kpic
->init_state
;
41 s
->auto_eoi
= kpic
->auto_eoi
;
42 s
->rotate_on_auto_eoi
= kpic
->rotate_on_auto_eoi
;
43 s
->special_fully_nested_mode
= kpic
->special_fully_nested_mode
;
44 s
->init4
= kpic
->init4
;
46 s
->elcr_mask
= kpic
->elcr_mask
;
49 static void kvm_pic_put(PICCommonState
*s
)
51 struct kvm_irqchip chip
;
52 struct kvm_pic_state
*kpic
;
55 chip
.chip_id
= s
->master
? KVM_IRQCHIP_PIC_MASTER
: KVM_IRQCHIP_PIC_SLAVE
;
57 kpic
= &chip
.chip
.pic
;
59 kpic
->last_irr
= s
->last_irr
;
63 kpic
->priority_add
= s
->priority_add
;
64 kpic
->irq_base
= s
->irq_base
;
65 kpic
->read_reg_select
= s
->read_reg_select
;
67 kpic
->special_mask
= s
->special_mask
;
68 kpic
->init_state
= s
->init_state
;
69 kpic
->auto_eoi
= s
->auto_eoi
;
70 kpic
->rotate_on_auto_eoi
= s
->rotate_on_auto_eoi
;
71 kpic
->special_fully_nested_mode
= s
->special_fully_nested_mode
;
72 kpic
->init4
= s
->init4
;
74 kpic
->elcr_mask
= s
->elcr_mask
;
76 ret
= kvm_vm_ioctl(kvm_state
, KVM_SET_IRQCHIP
, &chip
);
78 fprintf(stderr
, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret
));
83 static void kvm_pic_reset(DeviceState
*dev
)
85 PICCommonState
*s
= DO_UPCAST(PICCommonState
, dev
.qdev
, dev
);
93 static void kvm_pic_set_irq(void *opaque
, int irq
, int level
)
97 delivered
= kvm_set_irq(kvm_state
, irq
, level
);
98 apic_report_irq_delivered(delivered
);
101 static void kvm_pic_init(PICCommonState
*s
)
103 memory_region_init_reservation(&s
->base_io
, "kvm-pic", 2);
104 memory_region_init_reservation(&s
->elcr_io
, "kvm-elcr", 1);
107 qemu_irq
*kvm_i8259_init(ISABus
*bus
)
109 i8259_init_chip("kvm-i8259", bus
, true);
110 i8259_init_chip("kvm-i8259", bus
, false);
112 return qemu_allocate_irqs(kvm_pic_set_irq
, NULL
, ISA_NUM_IRQS
);
115 static void kvm_i8259_class_init(ObjectClass
*klass
, void *data
)
117 PICCommonClass
*k
= PIC_COMMON_CLASS(klass
);
118 DeviceClass
*dc
= DEVICE_CLASS(klass
);
120 dc
->reset
= kvm_pic_reset
;
121 k
->init
= kvm_pic_init
;
122 k
->pre_save
= kvm_pic_get
;
123 k
->post_load
= kvm_pic_put
;
126 static const TypeInfo kvm_i8259_info
= {
128 .parent
= TYPE_PIC_COMMON
,
129 .instance_size
= sizeof(PICCommonState
),
130 .class_init
= kvm_i8259_class_init
,
133 static void kvm_pic_register_types(void)
135 type_register_static(&kvm_i8259_info
);
138 type_init(kvm_pic_register_types
)