186797937017f52bff088d02edf64fb931177a7eaJun Nakajima/* 286797937017f52bff088d02edf64fb931177a7eaJun Nakajima * ioapic.c IOAPIC emulation logic 386797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 486797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Copyright (c) 2004-2005 Fabrice Bellard 586797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Split the ioapic logic from apic.c 786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Xiantao Zhang <xiantao.zhang@intel.com> 886797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 986797937017f52bff088d02edf64fb931177a7eaJun Nakajima * This library is free software; you can redistribute it and/or 1086797937017f52bff088d02edf64fb931177a7eaJun Nakajima * modify it under the terms of the GNU Lesser General Public 1186797937017f52bff088d02edf64fb931177a7eaJun Nakajima * License as published by the Free Software Foundation; either 1286797937017f52bff088d02edf64fb931177a7eaJun Nakajima * version 2 of the License, or (at your option) any later version. 1386797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 1486797937017f52bff088d02edf64fb931177a7eaJun Nakajima * This library is distributed in the hope that it will be useful, 1586797937017f52bff088d02edf64fb931177a7eaJun Nakajima * but WITHOUT ANY WARRANTY; without even the implied warranty of 1686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1786797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Lesser General Public License for more details. 1886797937017f52bff088d02edf64fb931177a7eaJun Nakajima * 1986797937017f52bff088d02edf64fb931177a7eaJun Nakajima * You should have received a copy of the GNU Lesser General Public 2086797937017f52bff088d02edf64fb931177a7eaJun Nakajima * License along with this library; if not, write to the Free Software 2186797937017f52bff088d02edf64fb931177a7eaJun Nakajima * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 2286797937017f52bff088d02edf64fb931177a7eaJun Nakajima */ 2386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 2486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "hw.h" 2586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "pc.h" 2686797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "qemu-timer.h" 2786797937017f52bff088d02edf64fb931177a7eaJun Nakajima#include "host-utils.h" 2886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 2986797937017f52bff088d02edf64fb931177a7eaJun Nakajima//#define DEBUG_IOAPIC 3086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 3186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_NUM_PINS 0x18 3286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_LVT_MASKED (1<<16) 3386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 3486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_TRIGGER_EDGE 0 3586797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_TRIGGER_LEVEL 1 3686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 3786797937017f52bff088d02edf64fb931177a7eaJun Nakajima/*io{apic,sapic} delivery mode*/ 3886797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_FIXED 0x0 3986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_LOWEST_PRIORITY 0x1 4086797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_PMI 0x2 4186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_NMI 0x4 4286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_INIT 0x5 4386797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_SIPI 0x5 4486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#define IOAPIC_DM_EXTINT 0x7 4586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 4686797937017f52bff088d02edf64fb931177a7eaJun Nakajimastruct IOAPICState { 4786797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t id; 4886797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t ioregsel; 4986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 5086797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint32_t irr; 5186797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint64_t ioredtbl[IOAPIC_NUM_PINS]; 5286797937017f52bff088d02edf64fb931177a7eaJun Nakajima}; 5386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 5486797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void ioapic_service(IOAPICState *s) 5586797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 5686797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t i; 5786797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t trig_mode; 5886797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t vector; 5986797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t delivery_mode; 6086797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint32_t mask; 6186797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint64_t entry; 6286797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t dest; 6386797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t dest_mode; 6486797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint8_t polarity; 6586797937017f52bff088d02edf64fb931177a7eaJun Nakajima 6686797937017f52bff088d02edf64fb931177a7eaJun Nakajima for (i = 0; i < IOAPIC_NUM_PINS; i++) { 6786797937017f52bff088d02edf64fb931177a7eaJun Nakajima mask = 1 << i; 6886797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (s->irr & mask) { 6986797937017f52bff088d02edf64fb931177a7eaJun Nakajima entry = s->ioredtbl[i]; 7086797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (!(entry & IOAPIC_LVT_MASKED)) { 7186797937017f52bff088d02edf64fb931177a7eaJun Nakajima trig_mode = ((entry >> 15) & 1); 7286797937017f52bff088d02edf64fb931177a7eaJun Nakajima dest = entry >> 56; 7386797937017f52bff088d02edf64fb931177a7eaJun Nakajima dest_mode = (entry >> 11) & 1; 7486797937017f52bff088d02edf64fb931177a7eaJun Nakajima delivery_mode = (entry >> 8) & 7; 7586797937017f52bff088d02edf64fb931177a7eaJun Nakajima polarity = (entry >> 13) & 1; 7686797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (trig_mode == IOAPIC_TRIGGER_EDGE) 7786797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->irr &= ~mask; 7886797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (delivery_mode == IOAPIC_DM_EXTINT) 7986797937017f52bff088d02edf64fb931177a7eaJun Nakajima vector = pic_read_irq(isa_pic); 8086797937017f52bff088d02edf64fb931177a7eaJun Nakajima else 8186797937017f52bff088d02edf64fb931177a7eaJun Nakajima vector = entry & 0xff; 8286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 8386797937017f52bff088d02edf64fb931177a7eaJun Nakajima apic_deliver_irq(dest, dest_mode, delivery_mode, 8486797937017f52bff088d02edf64fb931177a7eaJun Nakajima vector, polarity, trig_mode); 8586797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 8686797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 8786797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 8886797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 8986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 9086797937017f52bff088d02edf64fb931177a7eaJun Nakajimavoid ioapic_set_irq(void *opaque, int vector, int level) 9186797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 9286797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s = opaque; 9386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 9486797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* ISA IRQs map to GSI 1-1 except for IRQ0 which maps 9586797937017f52bff088d02edf64fb931177a7eaJun Nakajima * to GSI 2. GSI maps to ioapic 1-1. This is not 9686797937017f52bff088d02edf64fb931177a7eaJun Nakajima * the cleanest way of doing it but it should work. */ 9786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 9886797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (vector == 0) 9986797937017f52bff088d02edf64fb931177a7eaJun Nakajima vector = 2; 10086797937017f52bff088d02edf64fb931177a7eaJun Nakajima 10186797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (vector >= 0 && vector < IOAPIC_NUM_PINS) { 10286797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint32_t mask = 1 << vector; 10386797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint64_t entry = s->ioredtbl[vector]; 10486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 10586797937017f52bff088d02edf64fb931177a7eaJun Nakajima if ((entry >> 15) & 1) { 10686797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* level triggered */ 10786797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (level) { 10886797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->irr |= mask; 10986797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_service(s); 11086797937017f52bff088d02edf64fb931177a7eaJun Nakajima } else { 11186797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->irr &= ~mask; 11286797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 11386797937017f52bff088d02edf64fb931177a7eaJun Nakajima } else { 11486797937017f52bff088d02edf64fb931177a7eaJun Nakajima /* edge triggered */ 11586797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (level) { 11686797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->irr |= mask; 11786797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_service(s); 11886797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 11986797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 12086797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 12186797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 12286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 12386797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr) 12486797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 12586797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s = opaque; 12686797937017f52bff088d02edf64fb931177a7eaJun Nakajima int index; 12786797937017f52bff088d02edf64fb931177a7eaJun Nakajima uint32_t val = 0; 12886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 12986797937017f52bff088d02edf64fb931177a7eaJun Nakajima addr &= 0xff; 13086797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (addr == 0x00) { 13186797937017f52bff088d02edf64fb931177a7eaJun Nakajima val = s->ioregsel; 13286797937017f52bff088d02edf64fb931177a7eaJun Nakajima } else if (addr == 0x10) { 13386797937017f52bff088d02edf64fb931177a7eaJun Nakajima switch (s->ioregsel) { 13486797937017f52bff088d02edf64fb931177a7eaJun Nakajima case 0x00: 13586797937017f52bff088d02edf64fb931177a7eaJun Nakajima val = s->id << 24; 13686797937017f52bff088d02edf64fb931177a7eaJun Nakajima break; 13786797937017f52bff088d02edf64fb931177a7eaJun Nakajima case 0x01: 13886797937017f52bff088d02edf64fb931177a7eaJun Nakajima val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */ 13986797937017f52bff088d02edf64fb931177a7eaJun Nakajima break; 14086797937017f52bff088d02edf64fb931177a7eaJun Nakajima case 0x02: 14186797937017f52bff088d02edf64fb931177a7eaJun Nakajima val = 0; 14286797937017f52bff088d02edf64fb931177a7eaJun Nakajima break; 14386797937017f52bff088d02edf64fb931177a7eaJun Nakajima default: 14486797937017f52bff088d02edf64fb931177a7eaJun Nakajima index = (s->ioregsel - 0x10) >> 1; 14586797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (index >= 0 && index < IOAPIC_NUM_PINS) { 14686797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (s->ioregsel & 1) 14786797937017f52bff088d02edf64fb931177a7eaJun Nakajima val = s->ioredtbl[index] >> 32; 14886797937017f52bff088d02edf64fb931177a7eaJun Nakajima else 14986797937017f52bff088d02edf64fb931177a7eaJun Nakajima val = s->ioredtbl[index] & 0xffffffff; 15086797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 15186797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 15286797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef DEBUG_IOAPIC 15386797937017f52bff088d02edf64fb931177a7eaJun Nakajima printf("I/O APIC read: %08x = %08x\n", s->ioregsel, val); 15486797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 15586797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 15686797937017f52bff088d02edf64fb931177a7eaJun Nakajima return val; 15786797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 15886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 15986797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 16086797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 16186797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s = opaque; 16286797937017f52bff088d02edf64fb931177a7eaJun Nakajima int index; 16386797937017f52bff088d02edf64fb931177a7eaJun Nakajima 16486797937017f52bff088d02edf64fb931177a7eaJun Nakajima addr &= 0xff; 16586797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (addr == 0x00) { 16686797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->ioregsel = val; 16786797937017f52bff088d02edf64fb931177a7eaJun Nakajima return; 16886797937017f52bff088d02edf64fb931177a7eaJun Nakajima } else if (addr == 0x10) { 16986797937017f52bff088d02edf64fb931177a7eaJun Nakajima#ifdef DEBUG_IOAPIC 17086797937017f52bff088d02edf64fb931177a7eaJun Nakajima printf("I/O APIC write: %08x = %08x\n", s->ioregsel, val); 17186797937017f52bff088d02edf64fb931177a7eaJun Nakajima#endif 17286797937017f52bff088d02edf64fb931177a7eaJun Nakajima switch (s->ioregsel) { 17386797937017f52bff088d02edf64fb931177a7eaJun Nakajima case 0x00: 17486797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->id = (val >> 24) & 0xff; 17586797937017f52bff088d02edf64fb931177a7eaJun Nakajima return; 17686797937017f52bff088d02edf64fb931177a7eaJun Nakajima case 0x01: 17786797937017f52bff088d02edf64fb931177a7eaJun Nakajima case 0x02: 17886797937017f52bff088d02edf64fb931177a7eaJun Nakajima return; 17986797937017f52bff088d02edf64fb931177a7eaJun Nakajima default: 18086797937017f52bff088d02edf64fb931177a7eaJun Nakajima index = (s->ioregsel - 0x10) >> 1; 18186797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (index >= 0 && index < IOAPIC_NUM_PINS) { 18286797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (s->ioregsel & 1) { 18386797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->ioredtbl[index] &= 0xffffffff; 18486797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->ioredtbl[index] |= (uint64_t)val << 32; 18586797937017f52bff088d02edf64fb931177a7eaJun Nakajima } else { 18686797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->ioredtbl[index] &= ~0xffffffffULL; 18786797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->ioredtbl[index] |= val; 18886797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 18986797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_service(s); 19086797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 19186797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 19286797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 19386797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 19486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 19586797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void ioapic_save(QEMUFile *f, void *opaque) 19686797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 19786797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s = opaque; 19886797937017f52bff088d02edf64fb931177a7eaJun Nakajima int i; 19986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 20086797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_put_8s(f, &s->id); 20186797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_put_8s(f, &s->ioregsel); 20286797937017f52bff088d02edf64fb931177a7eaJun Nakajima for (i = 0; i < IOAPIC_NUM_PINS; i++) { 20386797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_put_be64s(f, &s->ioredtbl[i]); 20486797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 20586797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 20686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 20786797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic int ioapic_load(QEMUFile *f, void *opaque, int version_id) 20886797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 20986797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s = opaque; 21086797937017f52bff088d02edf64fb931177a7eaJun Nakajima int i; 21186797937017f52bff088d02edf64fb931177a7eaJun Nakajima 21286797937017f52bff088d02edf64fb931177a7eaJun Nakajima if (version_id != 1) 21386797937017f52bff088d02edf64fb931177a7eaJun Nakajima return -EINVAL; 21486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 21586797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_get_8s(f, &s->id); 21686797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_get_8s(f, &s->ioregsel); 21786797937017f52bff088d02edf64fb931177a7eaJun Nakajima for (i = 0; i < IOAPIC_NUM_PINS; i++) { 21886797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_get_be64s(f, &s->ioredtbl[i]); 21986797937017f52bff088d02edf64fb931177a7eaJun Nakajima } 22086797937017f52bff088d02edf64fb931177a7eaJun Nakajima return 0; 22186797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 22286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 22386797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic void ioapic_reset(void *opaque) 22486797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 22586797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s = opaque; 22686797937017f52bff088d02edf64fb931177a7eaJun Nakajima int i; 22786797937017f52bff088d02edf64fb931177a7eaJun Nakajima 22886797937017f52bff088d02edf64fb931177a7eaJun Nakajima memset(s, 0, sizeof(*s)); 22986797937017f52bff088d02edf64fb931177a7eaJun Nakajima for(i = 0; i < IOAPIC_NUM_PINS; i++) 23086797937017f52bff088d02edf64fb931177a7eaJun Nakajima s->ioredtbl[i] = 1 << 16; /* mask LVT */ 23186797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 23286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 23386797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic CPUReadMemoryFunc *ioapic_mem_read[3] = { 23486797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_readl, 23586797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_readl, 23686797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_readl, 23786797937017f52bff088d02edf64fb931177a7eaJun Nakajima}; 23886797937017f52bff088d02edf64fb931177a7eaJun Nakajima 23986797937017f52bff088d02edf64fb931177a7eaJun Nakajimastatic CPUWriteMemoryFunc *ioapic_mem_write[3] = { 24086797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_writel, 24186797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_writel, 24286797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_writel, 24386797937017f52bff088d02edf64fb931177a7eaJun Nakajima}; 24486797937017f52bff088d02edf64fb931177a7eaJun Nakajima 24586797937017f52bff088d02edf64fb931177a7eaJun NakajimaIOAPICState *ioapic_init(void) 24686797937017f52bff088d02edf64fb931177a7eaJun Nakajima{ 24786797937017f52bff088d02edf64fb931177a7eaJun Nakajima IOAPICState *s; 24886797937017f52bff088d02edf64fb931177a7eaJun Nakajima int io_memory; 24986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 25086797937017f52bff088d02edf64fb931177a7eaJun Nakajima s = qemu_mallocz(sizeof(IOAPICState)); 25186797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_reset(s); 25286797937017f52bff088d02edf64fb931177a7eaJun Nakajima 25386797937017f52bff088d02edf64fb931177a7eaJun Nakajima io_memory = cpu_register_io_memory(ioapic_mem_read, 25486797937017f52bff088d02edf64fb931177a7eaJun Nakajima ioapic_mem_write, s); 25586797937017f52bff088d02edf64fb931177a7eaJun Nakajima cpu_register_physical_memory(0xfec00000, 0x1000, io_memory); 25686797937017f52bff088d02edf64fb931177a7eaJun Nakajima 25786797937017f52bff088d02edf64fb931177a7eaJun Nakajima register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s); 25886797937017f52bff088d02edf64fb931177a7eaJun Nakajima qemu_register_reset(ioapic_reset, 0, s); 25986797937017f52bff088d02edf64fb931177a7eaJun Nakajima 26086797937017f52bff088d02edf64fb931177a7eaJun Nakajima return s; 26186797937017f52bff088d02edf64fb931177a7eaJun Nakajima} 262