]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/blob - hw/ioapic_common.c
4a7624c0852a17be9e16f0ad529b3a7f6eb6b3bc
[lisovros/qemu_apohw.git] / hw / ioapic_common.c
1 /*
2  *  IOAPIC emulation logic - common bits of emulated and KVM kernel model
3  *
4  *  Copyright (c) 2004-2005 Fabrice Bellard
5  *  Copyright (c) 2009      Xiantao Zhang, Intel
6  *  Copyright (c) 2011      Jan Kiszka, Siemens AG
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "ioapic.h"
23 #include "ioapic_internal.h"
24 #include "sysbus.h"
25
26 void ioapic_reset_common(DeviceState *dev)
27 {
28     IOAPICCommonState *s = DO_UPCAST(IOAPICCommonState, busdev.qdev, dev);
29     int i;
30
31     s->id = 0;
32     s->ioregsel = 0;
33     s->irr = 0;
34     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
35         s->ioredtbl[i] = 1 << IOAPIC_LVT_MASKED_SHIFT;
36     }
37 }
38
39 static void ioapic_dispatch_pre_save(void *opaque)
40 {
41     IOAPICCommonState *s = opaque;
42     IOAPICCommonInfo *info =
43         DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
44
45     if (info->pre_save) {
46         info->pre_save(s);
47     }
48 }
49
50 static int ioapic_dispatch_post_load(void *opaque, int version_id)
51 {
52     IOAPICCommonState *s = opaque;
53     IOAPICCommonInfo *info =
54         DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
55
56     if (info->post_load) {
57         info->post_load(s);
58     }
59     return 0;
60 }
61
62 static int ioapic_init_common(SysBusDevice *dev)
63 {
64     IOAPICCommonState *s = FROM_SYSBUS(IOAPICCommonState, dev);
65     IOAPICCommonInfo *info;
66     static int ioapic_no;
67
68     if (ioapic_no >= MAX_IOAPICS) {
69         return -1;
70     }
71
72     info = DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
73     info->init(s, ioapic_no);
74
75     sysbus_init_mmio(&s->busdev, &s->io_memory);
76     ioapic_no++;
77
78     return 0;
79 }
80
81 static const VMStateDescription vmstate_ioapic_common = {
82     .name = "ioapic",
83     .version_id = 3,
84     .minimum_version_id = 1,
85     .minimum_version_id_old = 1,
86     .pre_save = ioapic_dispatch_pre_save,
87     .post_load = ioapic_dispatch_post_load,
88     .fields = (VMStateField[]) {
89         VMSTATE_UINT8(id, IOAPICCommonState),
90         VMSTATE_UINT8(ioregsel, IOAPICCommonState),
91         VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */
92         VMSTATE_UINT32_V(irr, IOAPICCommonState, 2),
93         VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICCommonState, IOAPIC_NUM_PINS),
94         VMSTATE_END_OF_LIST()
95     }
96 };
97
98 void ioapic_qdev_register(IOAPICCommonInfo *info)
99 {
100     info->busdev.init = ioapic_init_common;
101     info->busdev.qdev.vmsd = &vmstate_ioapic_common;
102     info->busdev.qdev.no_user = 1;
103     sysbus_register_withprop(&info->busdev);
104 }