VirtualBox

Changeset 3146 in vbox


Ignore:
Timestamp:
Jun 18, 2007 5:11:26 PM (18 years ago)
Author:
vboxsync
Message:

Emulate all weird aspects of the IRQ line multiplexing. No guest has
dared to even come close to requiring this, but who knows what the
future brings.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r3114 r3146  
    830830        if (!s->fIrqPending)
    831831            pCtl->BmDma.u8Status |= BM_STATUS_INT;
    832         s->fIrqPending = true;
    833832        /* Only actually set the IRQ line if updating the currently selected drive. */
    834833        if (s == &pCtl->aIfs[pCtl->iSelectedIf])
     
    842841        }
    843842    }
     843    s->fIrqPending = true;
    844844}
    845845
     
    851851    PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
    852852
    853     if (s->fIrqPending)
     853    if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
    854854    {
    855855        Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN));
    856         s->fIrqPending = false;
    857856        /* Only actually unset the IRQ line if updating the currently selected drive. */
    858857        if (s == &pCtl->aIfs[pCtl->iSelectedIf])
     
    864863        }
    865864    }
     865    s->fIrqPending = false;
    866866}
    867867
     
    30113011    s->cMultSectors = ATA_MAX_MULT_SECTORS;
    30123012    s->cNotifiedMediaChange = 0;
    3013     s->fIrqPending = true; /* Ensure that the interrupt is unset. */
    30143013    ataUnsetIRQ(s);
    30153014
     
    33683367                pCtl->iSelectedIf = (val >> 4) & 1;
    33693368                /* The IRQ line is multiplexed between the two drives, so
    3370                  * update the state when switching to another drive. */
    3371                 if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
     3369                 * update the state when switching to another drive. Only need
     3370                 * to update interrupt line if it is enabled and there is a
     3371                 * state change. */
     3372                if (    !(pCtl->aIfs[pCtl->iSelectedIf].uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ)
     3373                    &&  (   pCtl->aIfs[pCtl->iSelectedIf].fIrqPending
     3374                         !=  pCtl->aIfs[pCtl->iSelectedIf ^ 1].fIrqPending))
    33723375                {
    3373                     if (pCtl->irq == 16)
    3374                         PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
     3376                    if (pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
     3377                    {
     3378                        Log2(("%s: LUN#%d asserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
     3379                        /* The BMDMA unit unconditionally sets BM_STATUS_INT if
     3380                         * the interrupt line is asserted. It monitors the line
     3381                         * for a rising edge. */
     3382                        pCtl->BmDma.u8Status |= BM_STATUS_INT;
     3383                        if (pCtl->irq == 16)
     3384                            PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
     3385                        else
     3386                            PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
     3387                    }
    33753388                    else
    3376                         PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 1);
    3377                 }
    3378                 else
    3379                 {
    3380                     if (pCtl->irq == 16)
    3381                         PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
    3382                     else
    3383                         PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
     3389                    {
     3390                        Log2(("%s: LUN#%d deasserting IRQ (drive select change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
     3391                        if (pCtl->irq == 16)
     3392                            PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 0);
     3393                        else
     3394                            PDMDevHlpISASetIrqNoWait(pDevIns, pCtl->irq, 0);
     3395                    }
    33843396                }
    33853397            }
     
    36033615        AssertMsgFailed(("RESET handling is too complicated for GC\n"));
    36043616#endif /* IN_RING3 */
     3617    }
     3618
     3619    /* Change of interrupt disable flag. Update interrupt line if interrupt
     3620     * is pending on the current interface. */
     3621    if ((val ^ pCtl->aIfs[0].uATARegDevCtl) & ATA_DEVCTL_DISABLE_IRQ
     3622        &&  pCtl->aIfs[pCtl->iSelectedIf].fIrqPending)
     3623    {
     3624        if (!(val & ATA_DEVCTL_DISABLE_IRQ))
     3625        {
     3626            Log2(("%s: LUN#%d asserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
     3627            /* The BMDMA unit unconditionally sets BM_STATUS_INT if the
     3628             * interrupt line is asserted. It monitors the line for a rising
     3629             * edge. */
     3630            pCtl->BmDma.u8Status |= BM_STATUS_INT;
     3631            if (pCtl->irq == 16)
     3632                PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 1);
     3633            else
     3634                PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 1);
     3635        }
     3636        else
     3637        {
     3638            Log2(("%s: LUN#%d deasserting IRQ (interrupt disable change)\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN));
     3639            if (pCtl->irq == 16)
     3640                PDMDevHlpPCISetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), 0, 0);
     3641            else
     3642                PDMDevHlpISASetIrqNoWait(CONTROLLER_2_DEVINS(pCtl), pCtl->irq, 0);
     3643        }
    36053644    }
    36063645
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette