DevPIC.cpp revision c58f1213e628a545081c70e26c6b67a841cff880
883N/A * available from http://www.virtualbox.org. This file is free software;
1574N/APDMBOTHCBDECL(int) picIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
883N/APDMBOTHCBDECL(int) picIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
883N/APDMBOTHCBDECL(int) picIOPortElcrRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
883N/APDMBOTHCBDECL(int) picIOPortElcrWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
#define DEBUG_PIC
typedef struct PicState {
} PicState;
typedef struct DEVPIC
#ifdef VBOX_WITH_STATISTICS
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
#ifdef LOG_ENABLED
int mask;
if (level) {
if (level) {
if (level)
int priority;
if (mask == 0)
priority = 0;
priority++;
return priority;
Log(("pic_get_irq%d: cur_priority=%x pending=%d\n", (s == pics) ? 0 : 1, cur_priority, (priority == 8) ? -1 : (priority + s->priority_add) & 7));
if (irq2 >= 0) {
if (irq >= 0)
/* If irq 2 is pending on the master pic, then there must be one pending on the slave pic too! Otherwise we'll get
#if defined(DEBUG_PIC)
return VINF_SUCCESS;
/** @note if an interrupt line state changes from unmasked to masked, then it must be deactivated when currently pending! */
if ( irq >= 0
pThis->aPics[0].elcr, pThis->aPics[0].last_irr, pThis->aPics[0].irr, pThis->aPics[0].imr, pThis->aPics[0].isr, pThis->aPics[0].irq_base));
pThis->aPics[1].elcr, pThis->aPics[1].last_irr, pThis->aPics[1].irr, pThis->aPics[1].imr, pThis->aPics[1].isr, pThis->aPics[1].irq_base));
if (s->auto_eoi) {
if (s->rotate_on_auto_eoi)
int irq;
int irq2;
int intno;
if (irq >= 0)
if (irq2 >= 0) {
Log2(("picGetInterrupt1: %x base=%x irq=%x uTagSrc=%#x\n", intno, pThis->aPics[1].irq_base, irq2, *puTagSrc));
Log2(("picGetInterrupt0: %x base=%x irq=%x uTagSrc=%#x\n", intno, pThis->aPics[0].irq_base, irq, *puTagSrc));
*puTagSrc = 0;
Log(("picGetInterrupt: 0x%02x pending 0:%d 1:%d\n", intno, pic_get_irq(&pThis->aPics[0]), pic_get_irq(&pThis->aPics[1])));
return intno;
if (addr == 0) {
pic_reset(s);
switch(cmd) {
switch(s->init_state) {
if (s->init4) {
s->init_state = 0;
s->init_state = 0;
Log(("pic_write: special_fully_nested_mode=%d auto_eoi=%d\n", s->special_fully_nested_mode, s->auto_eoi));
return rc;
int ret;
if (ret >= 0) {
ret = 0;
return ret;
unsigned int addr;
int ret;
if (s->poll) {
s->poll = 0;
if (addr == 0) {
if (s->read_reg_select)
return ret;
PDMBOTHCBDECL(int) picIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
int rc;
return rc;
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) picIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
int rc;
return rc;
return VINF_SUCCESS;
PDMBOTHCBDECL(int) picIOPortElcrRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
return VINF_SUCCESS;
return VERR_IOM_IOPORT_UNUSED;
PDMBOTHCBDECL(int) picIOPortElcrWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
return VINF_SUCCESS;
#ifdef IN_RING3
return VINF_SUCCESS;
static DECLCALLBACK(int) picLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t uVersion, uint32_t uPass)
return VINF_SUCCESS;
int rc;
bool fGCEnabled;
bool fR0Enabled;
if (fGCEnabled)
if (fR0Enabled)
if (fGCEnabled)
if (fR0Enabled)
rc = PDMDevHlpIOPortRegister(pDevIns, 0x20, 2, (void *)0, picIOPortWrite, picIOPortRead, NULL, NULL, "i8259 PIC #0");
return rc;
rc = PDMDevHlpIOPortRegister(pDevIns, 0xa0, 2, (void *)1, picIOPortWrite, picIOPortRead, NULL, NULL, "i8259 PIC #1");
return rc;
if (fGCEnabled)
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0x20, 2, 0, "picIOPortWrite", "picIOPortRead", NULL, NULL, "i8259 PIC #0");
return rc;
rc = PDMDevHlpIOPortRegisterRC(pDevIns, 0xa0, 2, 1, "picIOPortWrite", "picIOPortRead", NULL, NULL, "i8259 PIC #1");
return rc;
if (fR0Enabled)
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0x20, 2, 0, "picIOPortWrite", "picIOPortRead", NULL, NULL, "i8259 PIC #0");
return rc;
rc = PDMDevHlpIOPortRegisterR0(pDevIns, 0xa0, 2, 1, "picIOPortWrite", "picIOPortRead", NULL, NULL, "i8259 PIC #1");
return rc;
return rc;
return rc;
if (fGCEnabled)
return rc;
return rc;
if (fR0Enabled)
return rc;
return rc;
return rc;
#ifdef VBOX_WITH_STATISTICS
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqGC, STAMTYPE_COUNTER, "/Devices/PIC/SetIrqGC", STAMUNIT_OCCURENCES, "Number of PIC SetIrq calls in GC.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqHC, STAMTYPE_COUNTER, "/Devices/PIC/SetIrqHC", STAMUNIT_OCCURENCES, "Number of PIC SetIrq calls in HC.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveIRQ2, STAMTYPE_COUNTER, "/Devices/PIC/Masked/ActiveIRQ2", STAMUNIT_OCCURENCES, "Number of cleared irq 2.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveMasterIRQ, STAMTYPE_COUNTER, "/Devices/PIC/Masked/ActiveMaster", STAMUNIT_OCCURENCES, "Number of cleared master irqs.");
PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveSlaveIRQ, STAMTYPE_COUNTER, "/Devices/PIC/Masked/ActiveSlave", STAMUNIT_OCCURENCES, "Number of cleared slave 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(DEVPIC),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,