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 void ioapic_common_realize(DeviceState *dev, Error **errp) 61 { 62 IOAPICCommonState *s = IOAPIC_COMMON(dev); 63 IOAPICCommonClass *info; 64 static int ioapic_no; 65 66 if (ioapic_no >= MAX_IOAPICS) { 67 error_setg(errp, "Only %d ioapics allowed", MAX_IOAPICS); 68 return; 69 } 70 71 info = IOAPIC_COMMON_GET_CLASS(s); 72 info->init(s, ioapic_no); 73 74 sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory); 75 ioapic_no++; 76 } 77 78 static const VMStateDescription vmstate_ioapic_common = { 79 .name = "ioapic", 80 .version_id = 3, 81 .minimum_version_id = 1, 82 .minimum_version_id_old = 1, 83 .pre_save = ioapic_dispatch_pre_save, 84 .post_load = ioapic_dispatch_post_load, 85 .fields = (VMStateField[]) { 86 VMSTATE_UINT8(id, IOAPICCommonState), 87 VMSTATE_UINT8(ioregsel, IOAPICCommonState), 88 VMSTATE_UNUSED_V(2, 8), /* to account for qemu-kvm's v2 format */ 89 VMSTATE_UINT32_V(irr, IOAPICCommonState, 2), 90 VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICCommonState, IOAPIC_NUM_PINS), 91 VMSTATE_END_OF_LIST() 92 } 93 }; 94 95 static void ioapic_common_class_init(ObjectClass *klass, void *data) 96 { 97 DeviceClass *dc = DEVICE_CLASS(klass); 98 99 dc->realize = ioapic_common_realize; 100 dc->vmsd = &vmstate_ioapic_common; 101 dc->no_user = 1; 102 } 103 104 static const TypeInfo ioapic_common_type = { 105 .name = TYPE_IOAPIC_COMMON, 106 .parent = TYPE_SYS_BUS_DEVICE, 107 .instance_size = sizeof(IOAPICCommonState), 108 .class_size = sizeof(IOAPICCommonClass), 109 .class_init = ioapic_common_class_init, 110 .abstract = true, 111 }; 112 113 static void register_types(void) 114 { 115 type_register_static(&ioapic_common_type); 116 } 117 118 type_init(register_types) 119