Statistics
| Branch: | Revision:

root / hw / kvm / i8259.c @ 10b61882

History | View | Annotate | Download (3.3 kB)

1
/*
2
 * KVM in-kernel PIC (i8259) 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
#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
    pic_reset_common(s);
88
    s->elcr = 0;
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 PICCommonInfo kvm_i8259_info = {
116
    .isadev.qdev.name  = "kvm-i8259",
117
    .isadev.qdev.reset = kvm_pic_reset,
118
    .init       = kvm_pic_init,
119
    .pre_save   = kvm_pic_get,
120
    .post_load  = kvm_pic_put,
121
};
122

    
123
static void kvm_pic_register(void)
124
{
125
    pic_qdev_register(&kvm_i8259_info);
126
}
127

    
128
device_init(kvm_pic_register)