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 "hw/i386/ioapic.h" 23 #include "hw/i386/ioapic_internal.h" 24 #include "hw/sysbus.h" 25 26 void ioapic_reset_common(DeviceState *dev) 27 { 28 IOAPICCommonState *s = IOAPIC_COMMON(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 = IOAPIC_COMMON(opaque); 42 IOAPICCommonClass *info = IOAPIC_COMMON_GET_CLASS(s); 43 44 if (info->pre_save) { 45 info->pre_save(s); 46 } 47 } 48 49 static int ioapic_dispatch_post_load(void *opaque, int version_id) 50 { 51 IOAPICCommonState *s = IOAPIC_COMMON(opaque); 52 IOAPICCommonClass *info = IOAPIC_COMMON_GET_CLASS(s); 53 54 if (info->post_load) { 55 info->post_load(s); 56 } 57 return 0; 58 } 59 60 static int ioapic_init_common(SysBusDevice *dev) 61 { 62 IOAPICCommonState *s = IOAPIC_COMMON(dev); 63 IOAPICCommonClass *info; 64 static int ioapic_no; 65 66 if (ioapic_no >= MAX_IOAPICS) { 67 return -1; 68 } 69 70 info = IOAPIC_COMMON_GET_CLASS(s); 71 info->init(s, ioapic_no); 72 73 sysbus_init_mmio(&s->busdev, &s->io_memory); 74 ioapic_no++; 75 76 return 0; 77 } 78 79 static const VMStateDescription vmstate_ioapic_common = { 80 .name = "ioapic", 81 .version_id = 3, 82 .minimum_version_id = 1, 83 .minimum_version_id_old = 1, 84 .pre_save = ioapic_dispatch_pre_save, 85 .post_load = ioapic_dispatch_post_load, 86 .fields = (VMStateField[]) { 87 VMSTATE_UINT8(id, IOAPICCommonState), 88 VMSTATE_UINT8(ioregsel, IOAPICCommonState), 89 VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */ 90 VMSTATE_UINT32_V(irr, IOAPICCommonState, 2), 91 VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICCommonState, IOAPIC_NUM_PINS), 92 VMSTATE_END_OF_LIST() 93 } 94 }; 95 96 static void ioapic_common_class_init(ObjectClass *klass, void *data) 97 { 98 SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); 99 DeviceClass *dc = DEVICE_CLASS(klass); 100 101 sc->init = ioapic_init_common; 102 dc->vmsd = &vmstate_ioapic_common; 103 dc->no_user = 1; 104 } 105 106 static const TypeInfo ioapic_common_type = { 107 .name = TYPE_IOAPIC_COMMON, 108 .parent = TYPE_SYS_BUS_DEVICE, 109 .instance_size = sizeof(IOAPICCommonState), 110 .class_size = sizeof(IOAPICCommonClass), 111 .class_init = ioapic_common_class_init, 112 .abstract = true, 113 }; 114 115 static void register_types(void) 116 { 117 type_register_static(&ioapic_common_type); 118 } 119 120 type_init(register_types) 121