VirtualBox

Changeset 43680 in vbox


Ignore:
Timestamp:
Oct 18, 2012 1:31:00 PM (12 years ago)
Author:
vboxsync
Message:

BusLogic: Improved reset handling, added debugger info callback.

File:
1 edited

Legend:

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

    r43659 r43680  
    5151
    5252/* Size of the reply buffer. */
    53 #define BUSLOGIC_REPLY_SIZE_MAX 64
     53#define BUSLOGIC_REPLY_SIZE_MAX     64
    5454
    5555/*
     
    6767#define BUSLOGIC_SAVED_STATE_MINOR_PRE_ERROR_HANDLING 1
    6868
    69 /** The duration of software-initiated reset. Not documented, set to 2 ms. */
    70 #define BUSLOGIC_RESET_DURATION_NS      (2000*1000)
     69/** The duration of software-initiated reset. Not documented, set to 500 ms. */
     70#define BUSLOGIC_RESET_DURATION_NS      (500*1000*1000UL)
    7171
    7272/**
     
    353353
    354354    /** ISA I/O port base (disabled if zero). */
    355     RTIOPORT                        IOISABase;     //@todo: recalculate when restoring state
     355    RTIOPORT                        IOISABase;
    356356    /** Default ISA I/O port base in FW-compatible format. */
    357357    uint8_t                         uDefaultISABaseCode;
     
    743743    /** Device adapter status. */
    744744    uint8_t       uDeviceStatus;
    745     /** The device the request is send to. */
     745    /** The device the request is sent to. */
    746746    uint8_t       uTargetId;
    747747    /**The LUN in the device. */
     
    970970 * @returns nothing
    971971 * @param   pBusLogic   Pointer to the BusLogic device instance.
    972  */
    973 static void buslogicIntiateHardReset(PBUSLOGIC pBusLogic)
    974 {
    975     LogFlowFunc(("pBusLogic=%#p\n", pBusLogic));
    976 
    977     /* Remember when the guest initiated a reset. */
    978     pBusLogic->u64ResetTime = PDMDevHlpTMTimeVirtGetNano(pBusLogic->CTX_SUFF(pDevIns));
    979 
    980     buslogicHwReset(pBusLogic, false);
    981 
    982     /* We set the diagnostic active in the status register. */
    983     pBusLogic->regStatus |= BUSLOGIC_REGISTER_STATUS_DIAGNOSTIC_ACTIVE;
     972 * @param   fHardReset  Flag initiating a hard (vs. soft) reset.
     973 */
     974static void buslogicInitiateReset(PBUSLOGIC pBusLogic, bool fHardReset)
     975{
     976    LogFlowFunc(("pBusLogic=%#p fHardReset=%d\n", pBusLogic, fHardReset));
     977
     978    buslogicHwReset(pBusLogic, fHardReset);
     979
     980    if (fHardReset)
     981    {
     982        /* Set the diagnostic active bit in the status register and clear the ready state. */
     983        pBusLogic->regStatus |=  BUSLOGIC_REGISTER_STATUS_DIAGNOSTIC_ACTIVE;
     984        pBusLogic->regStatus &= ~BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY;
     985
     986        /* Remember when the guest initiated a reset (after we're done resetting). */
     987        pBusLogic->u64ResetTime = PDMDevHlpTMTimeVirtGetNano(pBusLogic->CTX_SUFF(pDevIns));
     988    }
    984989}
    985990
     
    13061311}
    13071312
     1313/* Convert sense buffer length taking into account shortcut values. */
     1314static uint32_t buslogicConvertSenseBufferLength(uint32_t cbSense)
     1315{
     1316    /* Convert special sense buffer length values. */
     1317    if (cbSense == 0)
     1318        cbSense = 14;   /* 0 means standard 14-byte buffer. */
     1319    else if (cbSense == 1)
     1320        cbSense = 0;    /* 1 means no sense data. */
     1321    else if (cbSense < 8)
     1322        AssertMsgFailed(("Reserved cbSense value of %d used!\n", cbSense));
     1323
     1324    return cbSense;
     1325}
     1326
    13081327/**
    13091328 * Free the sense buffer.
     
    13151334static void buslogicSenseBufferFree(PBUSLOGICTASKSTATE pTaskState, bool fCopy)
    13161335{
    1317     PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
    1318     RTGCPHYS GCPhysAddrSenseBuffer = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrSenseData;
    1319     uint32_t cbSenseBuffer = pTaskState->CommandControlBlockGuest.cbSenseData;
    1320 
    1321     /* Copy into guest memory. */
    1322     if (fCopy)
     1336    uint32_t    cbSenseBuffer;
     1337
     1338    cbSenseBuffer = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.cbSenseData);
     1339
     1340    /* Copy the sense buffer into guest memory if requested. */
     1341    if (fCopy && cbSenseBuffer)
     1342    {
     1343        PPDMDEVINS  pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
     1344        RTGCPHYS GCPhysAddrSenseBuffer = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrSenseData;
     1345        uint32_t cbSenseBuffer = pTaskState->CommandControlBlockGuest.cbSenseData;
     1346
    13231347        PDMDevHlpPhysWrite(pDevIns, GCPhysAddrSenseBuffer, pTaskState->pbSenseBuffer, cbSenseBuffer);
     1348    }
    13241349
    13251350    RTMemFree(pTaskState->pbSenseBuffer);
     
    13371362{
    13381363    PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
    1339     uint32_t cbSenseBuffer = pTaskState->CommandControlBlockGuest.cbSenseData;
     1364    uint32_t   cbSenseBuffer;
     1365
     1366    cbSenseBuffer = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.cbSenseData);
    13401367
    13411368    pTaskState->pbSenseBuffer = (uint8_t *)RTMemAllocZ(cbSenseBuffer);
     
    14631490
    14641491            pReply->uHostAdapterId = 7; /* The controller has always 7 as ID. */
    1465             //@todo: What should the DMA channel be?
    1466             pReply->fDmaChannel6  = 1;
     1492            pReply->fDmaChannel6  = 1;  /* DMA channel 6 is a good default. */
    14671493            /* The PCI IRQ is not necessarily representable in this structure.
    14681494             * If that is the case, the guest likely won't function correctly,
     
    15121538            PReplyInquireSetupInformation pReply = (PReplyInquireSetupInformation)pBusLogic->aReplyBuffer;
    15131539            memset(pReply, 0, sizeof(ReplyInquireSetupInformation));
     1540            pReply->fSynchronousInitiationEnabled = true;
     1541            pReply->fParityCheckingEnabled = true;
    15141542            pReply->cMailbox = pBusLogic->cMailbox;
    15151543            pReply->uSignature = 'B';
     
    17051733
    17061734            /* If the diagnostic active bit is set, we are in a guest-initiated
    1707              * hard or soft reset. If the guest reads the status register and
    1708              * waits for the host adapter ready bit to be set, we terminate the
    1709              * reset right away. However, guests may also expect the reset
    1710              * condition to clear automatically after a period of time.
     1735             * hard reset. If the guest reads the status register and waits for
     1736             * the host adapter ready bit to be set, we terminate the reset right
     1737             * away. However, guests may also expect the reset condition to clear
     1738             * automatically after a period of time, in which case we can't show
     1739             * the DIAG bit at all.
    17111740             */
    17121741            if (pBusLogic->regStatus & BUSLOGIC_REGISTER_STATUS_DIAGNOSTIC_ACTIVE)
     
    17161745                pBusLogic->regStatus &= ~BUSLOGIC_REGISTER_STATUS_DIAGNOSTIC_ACTIVE;
    17171746                pBusLogic->regStatus |= BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY;
     1747
    17181748                if (u64AccessTime - pBusLogic->u64ResetTime > BUSLOGIC_RESET_DURATION_NS)
    17191749                {
    1720                     /* Let the guest see the ready condition right away. */
    1721                     *pu32 &= ~BUSLOGIC_REGISTER_STATUS_DIAGNOSTIC_ACTIVE;
    1722                     *pu32 |= BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY;
     1750                    /* If reset already expired, let the guest see that right away. */
     1751                    *pu32 = pBusLogic->regStatus;
    17231752                    pBusLogic->u64ResetTime = 0;
    17241753                }
     
    17891818        case BUSLOGIC_REGISTER_CONTROL:
    17901819        {
     1820            if ((uVal & BUSLOGIC_REGISTER_CONTROL_HARD_RESET) || (uVal & BUSLOGIC_REGISTER_CONTROL_SOFT_RESET))
     1821            {
     1822#ifdef IN_RING3
     1823                bool    fHardReset = !!(uVal & BUSLOGIC_REGISTER_CONTROL_HARD_RESET);
     1824
     1825                LogRel(("BusLogic: %s reset\n", fHardReset ? "hard" : "soft"));
     1826                buslogicInitiateReset(pBusLogic, fHardReset);
     1827#else
     1828                rc = VINF_IOM_R3_IOPORT_WRITE;
     1829#endif
     1830                break;
     1831            }
     1832
    17911833            rc = PDMCritSectEnter(&pBusLogic->CritSectIntr, VINF_IOM_R3_IOPORT_WRITE);
    17921834            if (rc != VINF_SUCCESS)
     
    18021844
    18031845            PDMCritSectLeave(&pBusLogic->CritSectIntr);
    1804 
    1805             if ((uVal & BUSLOGIC_REGISTER_CONTROL_HARD_RESET) || (uVal & BUSLOGIC_REGISTER_CONTROL_SOFT_RESET))
    1806             {
    1807 #ifdef IN_RING3
    1808                 buslogicIntiateHardReset(pBusLogic);
    1809 #else
    1810                 rc = VINF_IOM_R3_IOPORT_WRITE;
    1811 #endif
    1812             }
    18131846
    18141847            break;
     
    22302263            {
    22312264                Log(("ISA I/O base: %x\n", uNewBase));
    2232                 LogRel(("buslogic: ISA I/O base: %x\n", uNewBase));
     2265                LogRel(("BusLogic: ISA I/O base: %x\n", uNewBase));
    22332266            }
    22342267            else
    22352268            {
    22362269                Log(("Disabling ISA I/O ports.\n"));
    2237                 LogRel(("buslogic: ISA I/O disabled\n"));
     2270                LogRel(("BusLogic: ISA I/O disabled\n"));
    22382271            }
    22392272        }
     
    24252458                AssertMsgFailed(("invalid completion status %d\n", rcCompletion));
    24262459        }
     2460#ifdef DEBUG
     2461            buslogicDumpCCBInfo(&pTaskState->CommandControlBlockGuest);
     2462#endif
     2463
    24272464        /* Remove task from the cache. */
    24282465        RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     
    25232560            pTaskState->PDMScsiRequest.paScatterGatherHead   = NULL;
    25242561        }
    2525         pTaskState->PDMScsiRequest.cbSenseBuffer         = pTaskState->CommandControlBlockGuest.cbSenseData;
     2562        pTaskState->PDMScsiRequest.cbSenseBuffer         = buslogicConvertSenseBufferLength(pTaskState->CommandControlBlockGuest.cbSenseData);
    25262563        pTaskState->PDMScsiRequest.pbSenseBuffer         = pTaskState->pbSenseBuffer;
    25272564        pTaskState->PDMScsiRequest.pvUser                = pTaskState;
     
    29753012}
    29763013
     3014/**
     3015 * BusLogic debugger info callback.
     3016 *
     3017 * @param   pDevIns     The device instance.
     3018 * @param   pHlp        The output helpers.
     3019 * @param   pszArgs     The arguments.
     3020 */
     3021static DECLCALLBACK(void) buslogicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     3022{
     3023    PBUSLOGIC   pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     3024    bool        fVerbose = false;
     3025
     3026    /* Parse arguments. */
     3027    if (pszArgs)
     3028        fVerbose = strstr(pszArgs, "verbose") != NULL;
     3029   
     3030    /* Show basic information. */
     3031    pHlp->pfnPrintf(pHlp,
     3032                    "%s#%d: PCI I/O=%RTiop ISA I/O=%RTiop MMIO=%RGp IRQ=%u GC=%RTbool R0=%RTbool\n",
     3033                    pDevIns->pReg->szName,
     3034                    pDevIns->iInstance,
     3035                    pThis->IOPortBase, pThis->IOISABase, pThis->MMIOBase,
     3036                    PCIDevGetInterruptLine(&pThis->dev),
     3037                    !!pThis->fGCEnabled, !!pThis->fR0Enabled);
     3038
     3039    /* Print mailbox state. */
     3040    if (pThis->regStatus & BUSLOGIC_REGISTER_STATUS_INITIALIZATION_REQUIRED)
     3041        pHlp->pfnPrintf(pHlp, "Mailbox not initialized\n");
     3042    else
     3043    {
     3044        pHlp->pfnPrintf(pHlp, "%u-bit mailbox with %u entries at %RGp\n",
     3045                        pThis->fMbxIs24Bit ? 24 : 32, pThis->cMailbox,
     3046                        pThis->GCPhysAddrMailboxOutgoingBase);
     3047    }
     3048
     3049    /* Print register contents. */
     3050    pHlp->pfnPrintf(pHlp, "Registers: STAT=%02x INTR=%02x GEOM=%02x\n",
     3051                    pThis->regStatus, pThis->regInterrupt, pThis->regGeometry);
     3052
     3053    /* Print the current command, if any. */
     3054    if (pThis->uOperationCode != 0xff )
     3055        pHlp->pfnPrintf(pHlp, "Current command: %02X\n", pThis->uOperationCode);
     3056}
     3057
    29773058/* -=-=-=-=- Helper -=-=-=-=- */
    29783059
     
    34623543    if (RT_FAILURE(rc))
    34633544        return PDMDEV_SET_ERROR(pDevIns, rc, N_("BusLogic cannot register save state handlers"));
     3545
     3546    /*
     3547     * Register the debugger info callback.
     3548     */
     3549    char szTmp[128];
     3550    RTStrPrintf(szTmp, sizeof(szTmp), "%s%d", pDevIns->pReg->szName, pDevIns->iInstance);
     3551    PDMDevHlpDBGFInfoRegister(pDevIns, szTmp, "BusLogic HBA info", buslogicInfo);
    34643552
    34653553    rc = buslogicHwReset(pThis, true);
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