|
|
1.1 root 1: /*
2: * KVM in-kernel PIC (i8259) 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: #include "hw/i8259_internal.h"
13: #include "hw/apic_internal.h"
14: #include "kvm.h"
15:
16: static void kvm_pic_get(PICCommonState *s)
17: {
18: struct kvm_irqchip chip;
19: struct kvm_pic_state *kpic;
20: int ret;
21:
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);
24: if (ret < 0) {
25: fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
26: abort();
27: }
28:
29: kpic = &chip.chip.pic;
30:
31: s->last_irr = kpic->last_irr;
32: s->irr = kpic->irr;
33: s->imr = kpic->imr;
34: s->isr = kpic->isr;
35: s->priority_add = kpic->priority_add;
36: s->irq_base = kpic->irq_base;
37: s->read_reg_select = kpic->read_reg_select;
38: s->poll = kpic->poll;
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;
45: s->elcr = kpic->elcr;
46: s->elcr_mask = kpic->elcr_mask;
47: }
48:
49: static void kvm_pic_put(PICCommonState *s)
50: {
51: struct kvm_irqchip chip;
52: struct kvm_pic_state *kpic;
53: int ret;
54:
55: chip.chip_id = s->master ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE;
56:
57: kpic = &chip.chip.pic;
58:
59: kpic->last_irr = s->last_irr;
60: kpic->irr = s->irr;
61: kpic->imr = s->imr;
62: kpic->isr = s->isr;
63: kpic->priority_add = s->priority_add;
64: kpic->irq_base = s->irq_base;
65: kpic->read_reg_select = s->read_reg_select;
66: kpic->poll = s->poll;
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;
73: kpic->elcr = s->elcr;
74: kpic->elcr_mask = s->elcr_mask;
75:
76: ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, &chip);
77: if (ret < 0) {
78: fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret));
79: abort();
80: }
81: }
82:
83: static void kvm_pic_reset(DeviceState *dev)
84: {
85: PICCommonState *s = DO_UPCAST(PICCommonState, dev.qdev, dev);
86:
87: s->elcr = 0;
88: pic_reset_common(s);
89:
90: kvm_pic_put(s);
91: }
92:
93: static void kvm_pic_set_irq(void *opaque, int irq, int level)
94: {
95: int delivered;
96:
97: delivered = kvm_irqchip_set_irq(kvm_state, irq, level);
98: apic_report_irq_delivered(delivered);
99: }
100:
101: static void kvm_pic_init(PICCommonState *s)
102: {
103: memory_region_init_reservation(&s->base_io, "kvm-pic", 2);
104: memory_region_init_reservation(&s->elcr_io, "kvm-elcr", 1);
105: }
106:
107: qemu_irq *kvm_i8259_init(ISABus *bus)
108: {
109: i8259_init_chip("kvm-i8259", bus, true);
110: i8259_init_chip("kvm-i8259", bus, false);
111:
112: return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS);
113: }
114:
115: static void kvm_i8259_class_init(ObjectClass *klass, void *data)
116: {
117: PICCommonClass *k = PIC_COMMON_CLASS(klass);
118: DeviceClass *dc = DEVICE_CLASS(klass);
119:
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;
124: }
125:
126: static TypeInfo kvm_i8259_info = {
127: .name = "kvm-i8259",
128: .parent = TYPE_PIC_COMMON,
129: .instance_size = sizeof(PICCommonState),
130: .class_init = kvm_i8259_class_init,
131: };
132:
133: static void kvm_pic_register_types(void)
134: {
135: type_register_static(&kvm_i8259_info);
136: }
137:
138: type_init(kvm_pic_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.