VirtualBox

Changeset 3146

Show
Ignore:
Timestamp:
06/18/07 19:11:26 (2 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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy