root / hw / kvm / i8259.c @ edc92115
History | View | Annotate | Download (3.6 kB)
1 | 10b61882 | Jan Kiszka | /*
|
---|---|---|---|
2 | 10b61882 | Jan Kiszka | * KVM in-kernel PIC (i8259) support
|
3 | 10b61882 | Jan Kiszka | *
|
4 | 10b61882 | Jan Kiszka | * Copyright (c) 2011 Siemens AG
|
5 | 10b61882 | Jan Kiszka | *
|
6 | 10b61882 | Jan Kiszka | * Authors:
|
7 | 10b61882 | Jan Kiszka | * Jan Kiszka <jan.kiszka@siemens.com>
|
8 | 10b61882 | Jan Kiszka | *
|
9 | 10b61882 | Jan Kiszka | * This work is licensed under the terms of the GNU GPL version 2.
|
10 | 10b61882 | Jan Kiszka | * See the COPYING file in the top-level directory.
|
11 | 10b61882 | Jan Kiszka | */
|
12 | 10b61882 | Jan Kiszka | #include "hw/i8259_internal.h" |
13 | 10b61882 | Jan Kiszka | #include "hw/apic_internal.h" |
14 | 10b61882 | Jan Kiszka | #include "kvm.h" |
15 | 10b61882 | Jan Kiszka | |
16 | 10b61882 | Jan Kiszka | static void kvm_pic_get(PICCommonState *s) |
17 | 10b61882 | Jan Kiszka | { |
18 | 10b61882 | Jan Kiszka | struct kvm_irqchip chip;
|
19 | 10b61882 | Jan Kiszka | struct kvm_pic_state *kpic;
|
20 | 10b61882 | Jan Kiszka | int ret;
|
21 | 10b61882 | Jan Kiszka | |
22 | 10b61882 | Jan Kiszka | chip.chip_id = s->master ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE; |
23 | 10b61882 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, &chip); |
24 | 10b61882 | Jan Kiszka | if (ret < 0) { |
25 | 10b61882 | Jan Kiszka | fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
|
26 | 10b61882 | Jan Kiszka | abort(); |
27 | 10b61882 | Jan Kiszka | } |
28 | 10b61882 | Jan Kiszka | |
29 | 10b61882 | Jan Kiszka | kpic = &chip.chip.pic; |
30 | 10b61882 | Jan Kiszka | |
31 | 10b61882 | Jan Kiszka | s->last_irr = kpic->last_irr; |
32 | 10b61882 | Jan Kiszka | s->irr = kpic->irr; |
33 | 10b61882 | Jan Kiszka | s->imr = kpic->imr; |
34 | 10b61882 | Jan Kiszka | s->isr = kpic->isr; |
35 | 10b61882 | Jan Kiszka | s->priority_add = kpic->priority_add; |
36 | 10b61882 | Jan Kiszka | s->irq_base = kpic->irq_base; |
37 | 10b61882 | Jan Kiszka | s->read_reg_select = kpic->read_reg_select; |
38 | 10b61882 | Jan Kiszka | s->poll = kpic->poll; |
39 | 10b61882 | Jan Kiszka | s->special_mask = kpic->special_mask; |
40 | 10b61882 | Jan Kiszka | s->init_state = kpic->init_state; |
41 | 10b61882 | Jan Kiszka | s->auto_eoi = kpic->auto_eoi; |
42 | 10b61882 | Jan Kiszka | s->rotate_on_auto_eoi = kpic->rotate_on_auto_eoi; |
43 | 10b61882 | Jan Kiszka | s->special_fully_nested_mode = kpic->special_fully_nested_mode; |
44 | 10b61882 | Jan Kiszka | s->init4 = kpic->init4; |
45 | 10b61882 | Jan Kiszka | s->elcr = kpic->elcr; |
46 | 10b61882 | Jan Kiszka | s->elcr_mask = kpic->elcr_mask; |
47 | 10b61882 | Jan Kiszka | } |
48 | 10b61882 | Jan Kiszka | |
49 | 10b61882 | Jan Kiszka | static void kvm_pic_put(PICCommonState *s) |
50 | 10b61882 | Jan Kiszka | { |
51 | 10b61882 | Jan Kiszka | struct kvm_irqchip chip;
|
52 | 10b61882 | Jan Kiszka | struct kvm_pic_state *kpic;
|
53 | 10b61882 | Jan Kiszka | int ret;
|
54 | 10b61882 | Jan Kiszka | |
55 | 10b61882 | Jan Kiszka | chip.chip_id = s->master ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE; |
56 | 10b61882 | Jan Kiszka | |
57 | 10b61882 | Jan Kiszka | kpic = &chip.chip.pic; |
58 | 10b61882 | Jan Kiszka | |
59 | 10b61882 | Jan Kiszka | kpic->last_irr = s->last_irr; |
60 | 10b61882 | Jan Kiszka | kpic->irr = s->irr; |
61 | 10b61882 | Jan Kiszka | kpic->imr = s->imr; |
62 | 10b61882 | Jan Kiszka | kpic->isr = s->isr; |
63 | 10b61882 | Jan Kiszka | kpic->priority_add = s->priority_add; |
64 | 10b61882 | Jan Kiszka | kpic->irq_base = s->irq_base; |
65 | 10b61882 | Jan Kiszka | kpic->read_reg_select = s->read_reg_select; |
66 | 10b61882 | Jan Kiszka | kpic->poll = s->poll; |
67 | 10b61882 | Jan Kiszka | kpic->special_mask = s->special_mask; |
68 | 10b61882 | Jan Kiszka | kpic->init_state = s->init_state; |
69 | 10b61882 | Jan Kiszka | kpic->auto_eoi = s->auto_eoi; |
70 | 10b61882 | Jan Kiszka | kpic->rotate_on_auto_eoi = s->rotate_on_auto_eoi; |
71 | 10b61882 | Jan Kiszka | kpic->special_fully_nested_mode = s->special_fully_nested_mode; |
72 | 10b61882 | Jan Kiszka | kpic->init4 = s->init4; |
73 | 10b61882 | Jan Kiszka | kpic->elcr = s->elcr; |
74 | 10b61882 | Jan Kiszka | kpic->elcr_mask = s->elcr_mask; |
75 | 10b61882 | Jan Kiszka | |
76 | 10b61882 | Jan Kiszka | ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip); |
77 | 10b61882 | Jan Kiszka | if (ret < 0) { |
78 | 10b61882 | Jan Kiszka | fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
|
79 | 10b61882 | Jan Kiszka | abort(); |
80 | 10b61882 | Jan Kiszka | } |
81 | 10b61882 | Jan Kiszka | } |
82 | 10b61882 | Jan Kiszka | |
83 | 10b61882 | Jan Kiszka | static void kvm_pic_reset(DeviceState *dev) |
84 | 10b61882 | Jan Kiszka | { |
85 | 10b61882 | Jan Kiszka | PICCommonState *s = DO_UPCAST(PICCommonState, dev.qdev, dev); |
86 | 10b61882 | Jan Kiszka | |
87 | 10b61882 | Jan Kiszka | s->elcr = 0;
|
88 | aa24822b | Jan Kiszka | pic_reset_common(s); |
89 | 10b61882 | Jan Kiszka | |
90 | 10b61882 | Jan Kiszka | kvm_pic_put(s); |
91 | 10b61882 | Jan Kiszka | } |
92 | 10b61882 | Jan Kiszka | |
93 | 10b61882 | Jan Kiszka | static void kvm_pic_set_irq(void *opaque, int irq, int level) |
94 | 10b61882 | Jan Kiszka | { |
95 | 10b61882 | Jan Kiszka | int delivered;
|
96 | 10b61882 | Jan Kiszka | |
97 | 10b61882 | Jan Kiszka | delivered = kvm_irqchip_set_irq(kvm_state, irq, level); |
98 | 10b61882 | Jan Kiszka | apic_report_irq_delivered(delivered); |
99 | 10b61882 | Jan Kiszka | } |
100 | 10b61882 | Jan Kiszka | |
101 | 10b61882 | Jan Kiszka | static void kvm_pic_init(PICCommonState *s) |
102 | 10b61882 | Jan Kiszka | { |
103 | 10b61882 | Jan Kiszka | memory_region_init_reservation(&s->base_io, "kvm-pic", 2); |
104 | 10b61882 | Jan Kiszka | memory_region_init_reservation(&s->elcr_io, "kvm-elcr", 1); |
105 | 10b61882 | Jan Kiszka | } |
106 | 10b61882 | Jan Kiszka | |
107 | 10b61882 | Jan Kiszka | qemu_irq *kvm_i8259_init(ISABus *bus) |
108 | 10b61882 | Jan Kiszka | { |
109 | 10b61882 | Jan Kiszka | i8259_init_chip("kvm-i8259", bus, true); |
110 | 10b61882 | Jan Kiszka | i8259_init_chip("kvm-i8259", bus, false); |
111 | 10b61882 | Jan Kiszka | |
112 | 10b61882 | Jan Kiszka | return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS); |
113 | 10b61882 | Jan Kiszka | } |
114 | 10b61882 | Jan Kiszka | |
115 | 8f04ee08 | Anthony Liguori | static void kvm_i8259_class_init(ObjectClass *klass, void *data) |
116 | 8f04ee08 | Anthony Liguori | { |
117 | 8f04ee08 | Anthony Liguori | PICCommonClass *k = PIC_COMMON_CLASS(klass); |
118 | 39bffca2 | Anthony Liguori | DeviceClass *dc = DEVICE_CLASS(klass); |
119 | 8f04ee08 | Anthony Liguori | |
120 | 39bffca2 | Anthony Liguori | dc->reset = kvm_pic_reset; |
121 | 8f04ee08 | Anthony Liguori | k->init = kvm_pic_init; |
122 | 8f04ee08 | Anthony Liguori | k->pre_save = kvm_pic_get; |
123 | 8f04ee08 | Anthony Liguori | k->post_load = kvm_pic_put; |
124 | 8f04ee08 | Anthony Liguori | } |
125 | 8f04ee08 | Anthony Liguori | |
126 | 39bffca2 | Anthony Liguori | static TypeInfo kvm_i8259_info = {
|
127 | 8f04ee08 | Anthony Liguori | .name = "kvm-i8259",
|
128 | 39bffca2 | Anthony Liguori | .parent = TYPE_PIC_COMMON, |
129 | 4cafe606 | Jan Kiszka | .instance_size = sizeof(PICCommonState),
|
130 | 8f04ee08 | Anthony Liguori | .class_init = kvm_i8259_class_init, |
131 | 10b61882 | Jan Kiszka | }; |
132 | 10b61882 | Jan Kiszka | |
133 | 83f7d43a | Andreas Färber | static void kvm_pic_register_types(void) |
134 | 10b61882 | Jan Kiszka | { |
135 | 39bffca2 | Anthony Liguori | type_register_static(&kvm_i8259_info); |
136 | 10b61882 | Jan Kiszka | } |
137 | 10b61882 | Jan Kiszka | |
138 | 83f7d43a | Andreas Färber | type_init(kvm_pic_register_types) |