DevIoApic.cpp revision 2be9d7aaf29390865922e4200cd20e2fb6063f6b
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * I/O Advanced Programmable Interrupt Controller (IO-APIC) Device.
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Copyright (C) 2006-2010 Oracle Corporation
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * available from http://www.virtualbox.org. This file is free software;
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * you can redistribute it and/or modify it under the terms of the GNU
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * General Public License (GPL) as published by the Free Software
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * --------------------------------------------------------------------
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * This code is based on:
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * apic.c revision 1.5 @@OSETODO
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * APIC support
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Copyright (c) 2004-2005 Fabrice Bellard
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * This library is free software; you can redistribute it and/or
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * modify it under the terms of the GNU Lesser General Public
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * License as published by the Free Software Foundation; either
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * version 2 of the License, or (at your option) any later version.
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * This library is distributed in the hope that it will be useful,
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * but WITHOUT ANY WARRANTY; without even the implied warranty of
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Lesser General Public License for more details.
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * You should have received a copy of the GNU Lesser General Public
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * License along with this library; if not, write to the Free Software
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync/*******************************************************************************
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync* Header Files *
f61a261b5992db888292208635137b8657391212vboxsync*******************************************************************************/
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync/*******************************************************************************
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync* Defined Constants And Macros *
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync*******************************************************************************/
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync/** @def IOAPIC_LOCK
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Acquires the PDM lock. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync int rc2 = (pThis)->CTX_SUFF(pIoApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync } while (0)
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync/** @def IOAPIC_UNLOCK
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync * Releases the PDM lock. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync#define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync } while (0)
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync# define set_bit(pvBitmap, iBit) ASMBitSet(pvBitmap, iBit)
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync# define reset_bit(pvBitmap, iBit) ASMBitClear(pvBitmap, iBit)
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync# define fls_bit(value) (ASMBitLastSetU32(value) - 1)
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync# define ffs_bit(value) (ASMBitFirstSetU32(value) - 1)
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync/*******************************************************************************
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync* Structures and Typedefs *
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync*******************************************************************************/
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync /** The device instance - R3 Ptr. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync /** The IOAPIC helpers - R3 Ptr. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync /** The device instance - R0 Ptr. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync /** The IOAPIC helpers - R0 Ptr. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync /** The device instance - RC Ptr. */
cd28d44115468d6e014e0f8ec7bed13fc061e210vboxsync /** The IOAPIC helpers - RC Ptr. */
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
uint8_t i;
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
dest,
if (level) {
ioapic_service(s);
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) {
ioapic_service(s);
#ifdef IN_RING3
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
memset(s, 0, sizeof(*s));
for(i = 0; i < IOAPIC_NUM_PINS; i++)
if (pDevIns)
if (pIoApicHlp)
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 const *pv, unsigned cb)
switch (cb)
IOAPIC_UNLOCK(s);
return VERR_INTERNAL_ERROR;
IOAPIC_UNLOCK(s);
return VINF_SUCCESS;
dest,
#ifdef IN_RING3
unsigned max_redir;
val = s->id << 24; /* Would be nice to call ioapic_mem_readl() directly, but that's not so simple. */
val = 0;
pHlp->pfnPrintf(pHlp, " idx dst_mode dst_addr mask trigger rirr polarity dlvr_st dlvr_mode vector\n");
for (i = 0; i <= max_redir; ++i)
return VINF_SUCCESS;
static DECLCALLBACK(int) ioapicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
AssertFailed();
return VINF_SUCCESS;
ioapic_reset(s);
IOAPIC_UNLOCK(s);
bool fGCEnabled;
bool fR0Enabled;
int rc;
ioapic_reset(s);
return rc;
return rc;
if (fGCEnabled) {
return rc;
if (fR0Enabled) {
return rc;
return rc;
#ifdef VBOX_WITH_STATISTICS
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOReadGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in GC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOReadHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOReadHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO reads in HC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOWriteGC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in GC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatMMIOWriteHC, STAMTYPE_COUNTER, "/Devices/IOAPIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of IOAPIC MMIO writes in HC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqGC, STAMTYPE_COUNTER, "/Devices/IOAPIC/SetIrqGC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in GC.");
PDMDevHlpSTAMRegister(pDevIns, &s->StatSetIrqHC, STAMTYPE_COUNTER, "/Devices/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,