DevAPIC.cpp revision 76c9fa8fefa7707b58893097e36b91fefdc8e4b3
891a081e38584dfb59697349fbf0aba2c4d4e1e2Christian Maeder * Advanced Programmable Interrupt Controller (APIC) Device and
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * I/O Advanced Programmable Interrupt Controller (IO-APIC) Device.
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * Copyright (C) 2006-2007 Sun Microsystems, Inc.
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * This file is part of VirtualBox Open Source Edition (OSE), as
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * available from http://www.virtualbox.org. This file is free software;
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * you can redistribute it and/or modify it under the terms of the GNU
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * General Public License (GPL) as published by the Free Software
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * Foundation, in version 2 as it comes in the "COPYING" file of the
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d1126d58419412635564085406d3779325b33ae0Till Mossakowski * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder * Clara, CA 95054 USA or visit http://www.sun.com if you need
7660d5932a1fb9677d07889714b677a059af2b2fChristian Maeder * additional information or have any questions.
8731f7b93b26083dc34a2c0937cd6493b42f2c2cTill Mossakowski * --------------------------------------------------------------------
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * This code is based on:
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski * apic.c revision 1.5 @@OSETODO
80664cc18425d67cd71be80f27f882fa16e43848Christian Maeder/*******************************************************************************
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder* Header Files *
0b7c8279c741857d1681160f8b4144a9430ffa7fTill Mossakowski*******************************************************************************/
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
2dfb9a95c5586f73abda1d0f369d6d154b159452Sonja Gröning/** @def APIC_LOCK
2dfb9a95c5586f73abda1d0f369d6d154b159452Sonja Gröning * Acquires the PDM lock. */
2dfb9a95c5586f73abda1d0f369d6d154b159452Sonja Gröning int rc2 = (pThis)->CTX_SUFF(pApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder/** @def APIC_LOCK_VOID
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder * Acquires the PDM lock and does not expect failure (i.e. ring-3 only!). */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder int rc2 = (pThis)->CTX_SUFF(pApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder/** @def APIC_UNLOCK
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * Releases the PDM lock. */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder (pThis)->CTX_SUFF(pApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder/** @def IOAPIC_LOCK
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * Acquires the PDM lock. */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder int rc2 = (pThis)->CTX_SUFF(pIoApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder/** @def IOAPIC_UNLOCK
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * Releases the PDM lock. */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder#define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
7660d5932a1fb9677d07889714b677a059af2b2fChristian Maeder/** @def LAPIC_BASE
7660d5932a1fb9677d07889714b677a059af2b2fChristian Maeder * Return address of first LAPIC state. */
7660d5932a1fb9677d07889714b677a059af2b2fChristian Maeder#define LAPIC_BASE(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder# define set_bit(pvBitmap, iBit) ASMBitSet(pvBitmap, iBit)
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder# define reset_bit(pvBitmap, iBit) ASMBitClear(pvBitmap, iBit)
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder# define fls_bit(value) (ASMBitLastSetU32(value) - 1)
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder# define ffs_bit(value) (ASMBitFirstSetU32(value) - 1)
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder#endif /* VBOX */
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder * APIC support
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder * Copyright (c) 2004-2005 Fabrice Bellard
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder * This library is free software; you can redistribute it and/or
6f08007ef2919f70c396c491f349ff3e536900bbChristian Maeder * modify it under the terms of the GNU Lesser General Public
8731f7b93b26083dc34a2c0937cd6493b42f2c2cTill Mossakowski * License as published by the Free Software Foundation; either
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * version 2 of the License, or (at your option) any later version.
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * This library is distributed in the hope that it will be useful,
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * but WITHOUT ANY WARRANTY; without even the implied warranty of
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * Lesser General Public License for more details.
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * You should have received a copy of the GNU Lesser General Public
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * License along with this library; if not, write to the Free Software
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder/* APIC Local Vector Table */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder/* APIC delivery modes */
10f1342d686ed68712a2b25ed65fa5a18f9c3db7Christian Maeder/* APIC destination mode */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maedertypedef struct APICState {
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder#endif /* !VBOX */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /* Task priority register (interrupt level) */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /* Logical APIC id */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /* Physical APIC id */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /** @todo: is it logical or physical? Not really used anyway now. */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder uint32_t tmr[8]; /* trigger mode register */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder uint32_t irr[8]; /* interrupt request register */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder int64_t initial_count_load_time, next_time;
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /** The APIC timer - R3 Ptr. */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /** The APIC timer - R0 Ptr. */
78d4b9e3558a2523c3335b1399385ac7d246f0c1Christian Maeder /** The APIC timer - RC Ptr. */
} APICState;
struct IOAPICState {
#ifdef VBOX
# ifdef VBOX_WITH_STATISTICS
#ifdef VBOX
# ifdef VBOX_WITH_STATISTICS
vector);
case PDMAPICVERSION_NONE:
case PDMAPICVERSION_APIC:
return MSR_IA32_APICBASE_ENABLE;
case PDMAPICVERSION_X2APIC:
return PDMAPICVERSION_NONE;
return PDMAPICVERSION_NONE;
return PDMAPICVERSION_APIC;
return PDMAPICVERSION_X2APIC;
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
#ifndef VBOX
static int apic_io_memory;
static int last_apic_id = 0;
#ifdef VBOX
PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
PDMBOTHCBDECL(int) ioapicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
PDMBOTHCBDECL(int) ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
#ifndef VBOX
LogFlow(("apic_bus_deliver mask=%x mode=%x vector=%x polarity=%x trigger_mode=%x\n", deliver_bitmask, delivery_mode, vector_num, polarity, trigger_mode));
switch (delivery_mode) {
case APIC_DM_LOWPRI:
if (deliver_bitmask)
case APIC_DM_FIXED:
case APIC_DM_SMI:
case APIC_DM_NMI:
case APIC_DM_INIT:
#ifdef VBOX
case APIC_DM_EXTINT:
#ifdef VBOX
#ifndef VBOX
#ifdef DEBUG_APIC
s->apicbase =
switch (newMode)
case PDMAPICVERSION_NONE:
case PDMAPICVERSION_APIC:
case PDMAPICVERSION_X2APIC:
#ifndef VBOX
#ifdef DEBUG_APIC
return s->apicbase;
apic_update_irq(s);
unsigned int ret = 0;
#ifdef HOST_I386
return ret;
int i, mask;
int i, mask;
return s->apicbase;
PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value)
return VERR_EM_INTERPRETER;
switch (index)
if (n == APIC_LVT_TIMER)
return VINF_SUCCESS;
PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)
return VERR_EM_INTERPRETER;
switch (index)
val = 0;
val = 0;
return VINF_SUCCESS;
LogFlow(("apicBusDeliverCallback: pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
if (tab[i] != 0) {
if (isrv < 0)
isrv = 0;
return ppr;
int isrv;
if (isrv < 0)
isrv = 0;
return isrv;
#ifdef VBOX
if (irrv < 0)
#ifndef VBOX
#ifdef VBOX
if (!dev)
if (irrv < 0)
bool fIrqIsActive = false;
bool fIrqWasActive = false;
if (trigger_mode)
int isrv;
if (isrv < 0)
#ifndef VBOX
if (dest_mode == 0)
uint32_t i;
apic++;
return mask;
for(i = 0; i < APIC_LVT_NB; i++)
s->tpr = 0;
s->log_dest = 0;
s->esr = 0;
s->divide_conf = 0;
s->count_shift = 0;
s->initial_count = 0;
s->initial_count_load_time = 0;
s->next_time = 0;
#ifndef VBOX
#ifndef VBOX
LogFlow(("apic_deliver dest=%x dest_mode=%x delivery_mode=%x vector_num=%x polarity=%x trigger_mode=%x\n", dest, dest_mode, delivery_mode, vector_num, polarity, trigger_mode));
switch (dest_shorthand) {
#ifndef VBOX
switch (delivery_mode) {
case APIC_DM_LOWPRI:
case APIC_DM_INIT:
#ifdef VBOX
case APIC_DM_SIPI:
#ifndef VBOX
#ifndef VBOX
if (!dev)
int intno;
goto done;
if (intno < 0) {
goto done;
goto done;
done:
return intno;
int64_t d;
#ifndef VBOX
s->count_shift;
s->count_shift;
if (d >= s->initial_count)
val = 0;
return val;
s->count_shift;
if (d >= s->initial_count)
goto no_timer;
#ifndef VBOX
#ifndef VBOX
#ifdef IN_RING3
#ifndef VBOX
#ifdef VBOX
#ifndef VBOX
#ifndef VBOX
APICState *s;
int index;
#ifndef VBOX
if (!env)
switch(index) {
val = 0;
#ifdef VBOX
#ifndef VBOX
#ifndef VBOX
#ifndef VBOX
#ifndef VBOX
val = 0;
#ifdef DEBUG_APIC
return val;
#ifndef VBOX
APICState *s;
static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, target_phys_addr_t addr, uint32_t val)
int index;
#ifndef VBOX
if (!env)
#ifdef DEBUG_APIC
switch(index) {
#ifdef VBOX
apic_update_irq(s);
#ifndef VBOX
#ifndef VBOX
if (n == APIC_LVT_TIMER)
#ifndef VBOX
#ifndef VBOX
#ifdef VBOX
return VINF_SUCCESS;
#ifdef IN_RING3
#ifdef VBOX
for (i = 0; i < APIC_LVT_NB; i++) {
#ifdef VBOX
#ifdef VBOX
return -EINVAL;
switch (version_id)
s->phys_id = 0;
return -EINVAL;
for (i = 0; i < APIC_LVT_NB; i++) {
#ifdef VBOX
return VINF_SUCCESS;
#ifndef VBOX
apic_init_ipi(s);
#ifndef VBOX
APICState *s;
apic_init_ipi(s);
if (apic_io_memory == 0) {
first_local_apic = s;
uint8_t i;
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
#ifndef VBOX
dest,
#ifdef VBOX
if (level) {
ioapic_service(s);
#ifdef VBOX
if (level) {
ioapic_service(s);
int index;
switch (s->ioregsel) {
val = 0;
#ifdef DEBUG_IOAPIC
return val;
int index;
#ifdef DEBUG_IOAPIC
switch (s->ioregsel) {
#ifdef VBOX
ioapic_service(s);
#ifdef IN_RING3
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
return -EINVAL;
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
#ifdef VBOX
memset(s, 0, sizeof(*s));
for(i = 0; i < IOAPIC_NUM_PINS; i++)
#ifdef VBOX
if (pDevIns)
if (pIoApicHlp)
#ifndef VBOX
IOAPICState *s;
int io_memory;
return NULL;
ioapic_reset(s);
ioapic_mem_write, s);
PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
#ifdef VBOX_WITH_SMP_GUESTS
switch (cb)
#ifndef IN_RING3
#ifdef IN_RC
pDevIns->pDevHlpR0->pfnPATMSetMMIOPatchInfo(pDevIns, GCPhysAddr, pDevIns + RT_OFFSETOF(APICState, tpr));
return VINF_PATM_HC_MMIO_PATCH_READ;
return VERR_INTERNAL_ERROR;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
#ifdef VBOX_WITH_SMP_GUESTS
switch (cb)
int rc;
return rc;
return VERR_INTERNAL_ERROR;
return VINF_SUCCESS;
#ifdef IN_RING3
return VINF_SUCCESS;
static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
AssertFailed();
return VINF_SUCCESS;
apic_init_ipi(s);
s->arb_id = 0;
if (s->phys_id == 0)
#ifdef VBOX_WITH_SMP_GUESTS
if (id == 0)
for (i = 0; i < APIC_LVT_NB; i++)
int rc;
uint32_t i;
bool fIOAPIC;
bool fGCEnabled;
bool fR0Enabled;
Log(("APIC: cCpus=%d fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", cCpus, fR0Enabled, fGCEnabled, fIOAPIC));
rc = MMHyperAlloc(pVM, cCpus*sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pThis->pLapicsR3);
return VERR_NO_MEMORY;
apic++;
if (fGCEnabled) {
if (fR0Enabled) {
return rc;
return rc;
if (fGCEnabled) {
return rc;
if (fR0Enabled) {
return rc;
return rc;
apic++;
return rc;
#ifdef VBOX_WITH_STATISTICS
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOReadGC, STAMTYPE_COUNTER, "/PDM/APIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of APIC MMIO reads in GC.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOReadHC, STAMTYPE_COUNTER, "/PDM/APIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO reads in HC.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOWriteGC, STAMTYPE_COUNTER, "/PDM/APIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in GC.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOWriteHC, STAMTYPE_COUNTER, "/PDM/APIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in HC.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveIrq, STAMTYPE_COUNTER, "/PDM/APIC/Masked/ActiveIRQ", STAMUNIT_OCCURENCES, "Number of cleared irqs.");
return VINF_SUCCESS;
PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
sizeof(APICState),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
PDMBOTHCBDECL(int) ioapicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
switch (cb)
IOAPIC_UNLOCK(s);
return VERR_INTERNAL_ERROR;
IOAPIC_UNLOCK(s);
return VINF_SUCCESS;
PDMBOTHCBDECL(int) ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
switch (cb)
IOAPIC_UNLOCK(s);
return VERR_INTERNAL_ERROR;
return VINF_SUCCESS;
#ifdef IN_RING3
return VINF_SUCCESS;
static DECLCALLBACK(int) ioapicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
AssertFailed();
return VINF_SUCCESS;
ioapic_reset(s);
IOAPIC_UNLOCK(s);
bool fGCEnabled;
bool fR0Enabled;
int rc;
ioapic_reset(s);
s->id = 0;
return rc;
return rc;
if (fGCEnabled) {
return rc;
if (fR0Enabled) {
return rc;
return rc;
#ifdef VBOX_WITH_STATISTICS
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadGC, STAMTYPE_COUNTER, "/PDM/IOAPIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in GC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadHC, STAMTYPE_COUNTER, "/PDM/IOAPIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in HC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteGC, STAMTYPE_COUNTER, "/PDM/IOAPIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in GC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteHC, STAMTYPE_COUNTER, "/PDM/IOAPIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in HC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqGC, STAMTYPE_COUNTER, "/PDM/IOAPIC/SetIrqGC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in GC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqHC, STAMTYPE_COUNTER, "/PDM/IOAPIC/SetIrqHC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in HC.");
return VINF_SUCCESS;
PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
sizeof(IOAPICState),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,