VirtualBox

Changeset 45970 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
May 9, 2013 5:27:59 PM (12 years ago)
Author:
vboxsync
Message:

Storage/LsiLogic: Fix Solaris 9 guests, it insists on downloading the firmware to the controller and checks for the firmware version afterwards

Location:
trunk/src/VBox/Devices
Files:
3 edited

Legend:

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

    r45959 r45970  
    2727#include <iprt/asm.h>
    2828#include <iprt/string.h>
     29#include <iprt/list.h>
    2930#ifdef IN_RING3
    3031# include <iprt/memcache.h>
     
    4546*******************************************************************************/
    4647/** The current saved state version. */
    47 #define LSILOGIC_SAVED_STATE_VERSION                4
     48#define LSILOGIC_SAVED_STATE_VERSION                5
     49/** The saved state version used by VirtualBox before the diagnostic
     50 * memory access was implemented. */
     51#define LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM   4
    4852/** The saved state version used by VirtualBox before the doorbell status flag
    4953 * was changed from bool to a 32bit enum. */
     
    97101/** Pointer to reply data. */
    98102typedef LSILOGICSCSIREPLY *PLSILOGICSCSIREPLY;
     103
     104/**
     105 * Memory region of the IOC.
     106 */
     107typedef struct LSILOGICMEMREGN
     108{
     109    /** List node. */
     110    RTLISTNODE    NodeList;
     111    /** 32bit address the region starts to describe. */
     112    uint32_t      u32AddrStart;
     113    /** 32bit address the region ends (inclusive). */
     114    uint32_t      u32AddrEnd;
     115    /** Data for this region - variable. */
     116    uint32_t      au32Data[1];
     117} LSILOGICMEMREGN;
     118/** Pointer to a memory region. */
     119typedef LSILOGICMEMREGN *PLSILOGICMEMREGN;
    99120
    100121/**
     
    170191    /** Flag whether the guest enabled event notification from the IOC. */
    171192    bool                 fEventNotificationEnabled;
     193    /** Flag whether the diagnostic address and RW registers are enabled. */
     194    bool                 fDiagRegsEnabled;
    172195
    173196    /** Queue to send tasks to R3. - R3 ptr */
     
    308331    bool volatile                  fRedo;
    309332    /** Alignment padding. */
    310     bool                            afPAdding2[HC_ARCH_BITS == 32 ? 2 : 6];
     333    bool                             afPadding2[HC_ARCH_BITS == 32 ? 2 : 6];
    311334    /** List of tasks which can be redone. */
    312335    R3PTRTYPE(volatile PLSILOGICREQ) pTasksRedoHead;
    313336
     337    /** Current address to read from or write to in the diagnostic memory region. */
     338    uint32_t                         u32DiagMemAddr;
     339
     340    uint32_t                         u32Padding3;
     341
     342    union
     343    {
     344        /** List of memory regions - PLSILOGICMEMREGN. */
     345        RTLISTANCHOR                 ListMemRegns;
     346        uint8_t                      u8Padding[2 * sizeof(RTUINTPTR)];
     347    };
    314348} LSILOGISCSI;
    315349/** Pointer to the device instance data of the LsiLogic emulation. */
     
    452486}
    453487
     488/**
     489 * Returns the number of frames in the reply free queue.
     490 *
     491 * @returns Number of frames in the reply free queue.
     492 * @param   pThis    Pointer to the LsiLogic device state.
     493 */
     494DECLINLINE(uint32_t) lsilogicReplyFreeQueueGetFrameCount(PLSILOGICSCSI pThis)
     495{
     496    uint32_t cReplyFrames = 0;
     497
     498    if (pThis->uReplyFreeQueueNextAddressRead <= pThis->uReplyFreeQueueNextEntryFreeWrite)
     499        cReplyFrames = pThis->uReplyFreeQueueNextEntryFreeWrite - pThis->uReplyFreeQueueNextAddressRead;
     500    else
     501        cReplyFrames = pThis->cReplyQueueEntries - pThis->uReplyFreeQueueNextAddressRead + pThis->uReplyFreeQueueNextEntryFreeWrite;
     502
     503    return cReplyFrames;
     504}
     505
     506/**
     507 * Returns the number of free entries in the reply post queue.
     508 *
     509 * @returns Number of frames in the reply free queue.
     510 * @param   pThis    Pointer to the LsiLogic device state.
     511 */
     512DECLINLINE(uint32_t) lsilogicReplyPostQueueGetFrameCount(PLSILOGICSCSI pThis)
     513{
     514    uint32_t cReplyFrames = 0;
     515
     516    if (pThis->uReplyPostQueueNextAddressRead <= pThis->uReplyPostQueueNextEntryFreeWrite)
     517        cReplyFrames = pThis->cReplyQueueEntries - pThis->uReplyPostQueueNextEntryFreeWrite + pThis->uReplyPostQueueNextAddressRead;
     518    else
     519        cReplyFrames = pThis->uReplyPostQueueNextEntryFreeWrite - pThis->uReplyPostQueueNextAddressRead;
     520
     521    return cReplyFrames;
     522}
     523
    454524#ifdef IN_RING3
    455525
     
    481551
    482552    /* Disable diagnostic access. */
    483     pThis->iDiagnosticAccess = 0;
     553    pThis->iDiagnosticAccess  = 0;
     554    pThis->fDiagnosticEnabled = false;
     555    pThis->fDiagRegsEnabled   = false;
    484556
    485557    /* Set default values. */
    486     pThis->cMaxDevices   = pThis->cDeviceStates;
    487     pThis->cMaxBuses     = 1;
    488     pThis->cbReplyFrame  = 128; /* @todo Figure out where it is needed. */
    489     pThis->u16NextHandle = 1;
    490     /** @todo: Put stuff to reset here. */
     558    pThis->cMaxDevices    = pThis->cDeviceStates;
     559    pThis->cMaxBuses      = 1;
     560    pThis->cbReplyFrame   = 128; /* @todo Figure out where it is needed. */
     561    pThis->u16NextHandle  = 1;
     562    pThis->u32DiagMemAddr = 0;
    491563
    492564    lsilogicR3ConfigurationPagesFree(pThis);
     
    555627    AssertRC(rc);
    556628
    557 # if 0
    558629    /* Check for a entry in the queue. */
    559     if (RT_UNLIKELY(pThis->uReplyPostQueueNextAddressRead != pThis->uReplyPostQueueNextEntryFreeWrite))
     630    if (!lsilogicReplyPostQueueGetFrameCount(pThis))
    560631    {
    561632        /* Set error code. */
     
    564635        return;
    565636    }
    566 # endif
    567637
    568638    /* We have a context reply. */
     
    615685        AssertRC(rc);
    616686
    617 #if 0
    618687        /* Check for a free reply frame. */
    619         if (RT_UNLIKELY(pThis->uReplyFreeQueueNextAddressRead != pThis->uReplyFreeQueueNextEntryFreeWrite))
     688        if (!lsilogicReplyFreeQueueGetFrameCount(pThis))
    620689        {
    621690            /* Set error code. */
     
    624693            return;
    625694        }
    626 #endif
    627695
    628696        uint32_t u32ReplyFrameAddressLow = pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead];
     
    644712        AssertRC(rc);
    645713
    646 #if 0
    647714        /* Check for a entry in the queue. */
    648         if (RT_UNLIKELY(pThis->uReplyPostQueueNextAddressRead != pThis->uReplyPostQueueNextEntryFreeWrite))
     715        if (!lsilogicReplyPostQueueGetFrameCount(pThis))
    649716        {
    650717            /* Set error code. */
     
    653720            return;
    654721        }
    655 #endif
    656722
    657723        /* We have a address reply. Set the 31th bit to indicate that. */
     
    677743}
    678744
    679 /**
    680  * Returns the number of frames in the reply free queue.
    681  *
    682  * @returns Number of frames in the reply free queue.
    683  * @param   pThis    Pointer to the LsiLogic device state.
    684  */
    685 DECLINLINE(uint32_t) lsilogicReplyFreeQueueGetFrameCount(PLSILOGICSCSI pThis)
    686 {
    687     uint32_t cReplyFrames = 0;
    688 
    689     if (pThis->uReplyFreeQueueNextAddressRead <= pThis->uReplyFreeQueueNextEntryFreeWrite)
    690         cReplyFrames = pThis->uReplyFreeQueueNextEntryFreeWrite - pThis->uReplyFreeQueueNextAddressRead;
     745#ifdef IN_RING3
     746
     747/**
     748 * Tries to find a memory region which covers the given address.
     749 *
     750 * @returns Pointer to memory region or NULL if not found.
     751 * @param   pThis           Pointer to the LsiLogic device state.
     752 * @param   u32Addr         The 32bit address to search for.
     753 */
     754static PLSILOGICMEMREGN lsilogicR3MemRegionFindByAddr(PLSILOGICSCSI pThis, uint32_t u32Addr)
     755{
     756    PLSILOGICMEMREGN pIt;
     757    PLSILOGICMEMREGN pRegion = NULL;
     758
     759    RTListForEach(&pThis->ListMemRegns, pIt, LSILOGICMEMREGN, NodeList)
     760    {
     761        if (   u32Addr >= pIt->u32AddrStart
     762            && u32Addr <= pIt->u32AddrEnd)
     763        {
     764            pRegion = pIt;
     765            break;
     766        }
     767    }
     768
     769    return pRegion;
     770}
     771
     772/**
     773 * Frees all allocated memory regions.
     774 *
     775 * @returns nothing.
     776 * @param   pThis           Pointer to the LsiLogic device state.
     777 */
     778static void lsilogicR3MemRegionsFree(PLSILOGICSCSI pThis)
     779{
     780    PLSILOGICMEMREGN pIt;
     781    PLSILOGICMEMREGN pItNext;
     782
     783    RTListForEachSafe(&pThis->ListMemRegns, pIt, pItNext, LSILOGICMEMREGN, NodeList)
     784    {
     785        RTListNodeRemove(&pIt->NodeList);
     786        RTMemFree(pIt);
     787    }
     788}
     789
     790/**
     791 * Inserts a given memory region into the list.
     792 *
     793 * @returns nothing.
     794 * @param   pThis           Pointer to the LsiLogic device state.
     795 * @param   pRegion         The region to insert.
     796 */
     797static void lsilogicR3MemRegionInsert(PLSILOGICSCSI pThis, PLSILOGICMEMREGN pRegion)
     798{
     799    PLSILOGICMEMREGN pIt;
     800    bool fInserted = false;
     801
     802    /* Insert at the right position. */
     803    RTListForEach(&pThis->ListMemRegns, pIt, LSILOGICMEMREGN, NodeList)
     804    {
     805        if (pRegion->u32AddrEnd < pIt->u32AddrStart)
     806        {
     807            RTListNodeInsertBefore(&pIt->NodeList, &pRegion->NodeList);
     808            fInserted = true;
     809            break;
     810        }
     811    }
     812    if (!fInserted)
     813        RTListAppend(&pThis->ListMemRegns, &pRegion->NodeList);
     814}
     815
     816/**
     817 * Count number of memory regions.
     818 *
     819 * @returns Number of memory regions.
     820 * @param   pThis           Pointer to the LsiLogic device state.
     821 */
     822static uint32_t lsilogicR3MemRegionsCount(PLSILOGICSCSI pThis)
     823{
     824    uint32_t cRegions = 0;
     825    PLSILOGICMEMREGN pIt;
     826
     827    RTListForEach(&pThis->ListMemRegns, pIt, LSILOGICMEMREGN, NodeList)
     828    {
     829        cRegions++;
     830    }
     831
     832    return cRegions;
     833}
     834
     835/**
     836 * Handles a write to the diagnostic data register.
     837 *
     838 * @returns nothing.
     839 * @param   pThis           Pointer to the LsiLogic device state.
     840 * @param   u32Data         Data to write.
     841 */
     842static void lsilogicR3DiagRegDataWrite(PLSILOGICSCSI pThis, uint32_t u32Data)
     843{
     844    PLSILOGICMEMREGN pRegion = lsilogicR3MemRegionFindByAddr(pThis, pThis->u32DiagMemAddr);
     845
     846    if (pRegion)
     847    {
     848        uint32_t offRegion = pThis->u32DiagMemAddr - pRegion->u32AddrStart;
     849
     850        AssertMsg(   offRegion % 4 == 0
     851                  && pThis->u32DiagMemAddr <= pRegion->u32AddrEnd,
     852                  ("Region offset not on a word boundary or crosses memory region\n"));
     853
     854        offRegion /= 4;
     855        pRegion->au32Data[offRegion] = u32Data;
     856    }
    691857    else
    692         cReplyFrames = pThis->cReplyQueueEntries - pThis->uReplyFreeQueueNextAddressRead + pThis->uReplyFreeQueueNextEntryFreeWrite;
    693 
    694     return cReplyFrames;
    695 }
    696 
    697 #ifdef IN_RING3
     858    {
     859        PLSILOGICMEMREGN pIt;
     860
     861        pRegion = NULL;
     862
     863        /* Create new region, first check whether we can extend another region. */
     864        RTListForEach(&pThis->ListMemRegns, pIt, LSILOGICMEMREGN, NodeList)
     865        {
     866            if (pThis->u32DiagMemAddr == pIt->u32AddrEnd + sizeof(uint32_t))
     867            {
     868                pRegion = pIt;
     869                break;
     870            }
     871        }
     872
     873        if (pRegion)
     874        {
     875            /* Reallocate. */
     876            RTListNodeRemove(&pRegion->NodeList);
     877
     878            uint32_t cRegionSizeOld = (pRegion->u32AddrEnd - pRegion->u32AddrStart) / 4 + 1;
     879            uint32_t cRegionSizeNew = cRegionSizeOld + 512;
     880            PLSILOGICMEMREGN pRegionNew = (PLSILOGICMEMREGN)RTMemRealloc(pRegion, RT_OFFSETOF(LSILOGICMEMREGN, au32Data[cRegionSizeNew]));
     881
     882            if (pRegionNew)
     883            {
     884                pRegion = pRegionNew;
     885                memset(&pRegion->au32Data[cRegionSizeOld], 0, 512 * sizeof(uint32_t));
     886                pRegion->au32Data[cRegionSizeOld] = u32Data;
     887                pRegion->u32AddrEnd = pRegion->u32AddrStart + (cRegionSizeNew - 1) * sizeof(uint32_t);
     888            }
     889            /* else: Silently fail, there is nothing we can do here and the guest might work nevertheless. */
     890
     891            lsilogicR3MemRegionInsert(pThis, pRegion);
     892        }
     893        else
     894        {
     895            /* Create completely new. */
     896            pRegion = (PLSILOGICMEMREGN)RTMemAllocZ(RT_OFFSETOF(LSILOGICMEMREGN, au32Data[512]));
     897            if (pRegion)
     898            {
     899                pRegion->u32AddrStart = pThis->u32DiagMemAddr;
     900                pRegion->u32AddrEnd   = pRegion->u32AddrStart + (512 - 1) * sizeof(uint32_t);
     901                pRegion->au32Data[0]  = u32Data;
     902
     903                lsilogicR3MemRegionInsert(pThis, pRegion);
     904            }
     905            /* else: Silently fail, there is nothing we can do here and the guest might work nevertheless. */
     906        }
     907
     908    }
     909
     910    /* Memory access is always 32bit big. */
     911    pThis->u32DiagMemAddr += sizeof(uint32_t);
     912}
     913
     914/**
     915 * Handles a read from the diagnostic data register.
     916 *
     917 * @returns nothing.
     918 * @param   pThis           Pointer to the LsiLogic device state.
     919 * @param   pu32Data        Where to store the data.
     920 */
     921static void lsilogicR3DiagRegDataRead(PLSILOGICSCSI pThis, uint32_t *pu32Data)
     922{
     923    PLSILOGICMEMREGN pRegion = lsilogicR3MemRegionFindByAddr(pThis, pThis->u32DiagMemAddr);
     924
     925    if (pRegion)
     926    {
     927        uint32_t offRegion = pThis->u32DiagMemAddr - pRegion->u32AddrStart;
     928
     929        AssertMsg(   offRegion % 4 == 0
     930                  && pThis->u32DiagMemAddr <= pRegion->u32AddrEnd,
     931                  ("Region offset not on a word boundary or crosses memory region\n"));
     932
     933        offRegion /= 4;
     934        *pu32Data = pRegion->au32Data[offRegion];
     935    }
     936    else /* No region, default value 0. */
     937        *pu32Data = 0;
     938
     939    /* Memory access is always 32bit big. */
     940    pThis->u32DiagMemAddr += sizeof(uint32_t);
     941}
     942
     943/**
     944 * Handles a write to the diagnostic memory address register.
     945 *
     946 * @returns nothing.
     947 * @param   pThis           Pointer to the LsiLogic device state.
     948 * @param   u32Addr         Address to write.
     949 */
     950static void lsilogicR3DiagRegAddressWrite(PLSILOGICSCSI pThis, uint32_t u32Addr)
     951{
     952    pThis->u32DiagMemAddr = u32Addr & ~UINT32_C(0x3); /* 32bit alignment. */
     953}
     954
     955/**
     956 * Handles a read from the diagnostic memory address register.
     957 *
     958 * @returns nothing.
     959 * @param   pThis           Pointer to the LsiLogic device state.
     960 * @param   pu32Addr        Where to store the current address.
     961 */
     962static void lsilogicR3DiagRegAddressRead(PLSILOGICSCSI pThis, uint32_t *pu32Addr)
     963{
     964    *pu32Addr = pThis->u32DiagMemAddr;
     965}
     966
    698967/**
    699968 * Processes a given Request from the guest
     
    7861055            pReply->IOCFacts.u16ReplyQueueDepth   = pThis->cReplyQueueEntries - 1; /* One entry is always free. */
    7871056            pReply->IOCFacts.u16RequestFrameSize  = 128;    /* @todo Figure out where it is needed. */
    788             pReply->IOCFacts.u16ProductID         = 0xcafe; /* Our own product ID :) */
    7891057            pReply->IOCFacts.u32CurrentHostMFAHighAddr = pThis->u32HostMFAHighAddr;
    7901058            pReply->IOCFacts.u16GlobalCredits     = pThis->cRequestQueueEntries - 1; /* One entry is always free. */
     
    7951063            pReply->IOCFacts.u8MaxDevices         = pThis->cMaxDevices;
    7961064            pReply->IOCFacts.u8MaxBuses           = pThis->cMaxBuses;
    797             pReply->IOCFacts.u32FwImageSize       = 0; /* No image needed. */
    798             pReply->IOCFacts.u32FWVersion         = 0;
     1065
     1066            /* Check for a valid firmware image in the IOC memory which was downlaoded by tzhe guest earlier. */
     1067            PLSILOGICMEMREGN pRegion = lsilogicR3MemRegionFindByAddr(pThis, LSILOGIC_FWIMGHDR_LOAD_ADDRESS);
     1068
     1069            if (pRegion)
     1070            {
     1071                uint32_t offImgHdr = (LSILOGIC_FWIMGHDR_LOAD_ADDRESS - pRegion->u32AddrStart) / 4;
     1072                PFwImageHdr pFwImgHdr = (PFwImageHdr)&pRegion->au32Data[offImgHdr];
     1073
     1074                /* Check for the signature. */
     1075                /** @todo: Checksum validation. */
     1076                if (   pFwImgHdr->u32Signature1 == LSILOGIC_FWIMGHDR_SIGNATURE1
     1077                    && pFwImgHdr->u32Signature2 == LSILOGIC_FWIMGHDR_SIGNATURE2
     1078                    && pFwImgHdr->u32Signature3 == LSILOGIC_FWIMGHDR_SIGNATURE3)
     1079                {
     1080                    LogFlowFunc(("IOC Facts: Found valid firmware image header in memory, using version (%#x), size (%d) and product ID (%#x) from there\n",
     1081                                 pFwImgHdr->u32FwVersion, pFwImgHdr->u32ImageSize, pFwImgHdr->u16ProductId));
     1082
     1083                    pReply->IOCFacts.u16ProductID         = pFwImgHdr->u16ProductId;
     1084                    pReply->IOCFacts.u32FwImageSize       = pFwImgHdr->u32ImageSize;
     1085                    pReply->IOCFacts.u32FWVersion         = pFwImgHdr->u32FwVersion;
     1086                }
     1087            }
     1088            else
     1089            {
     1090                pReply->IOCFacts.u16ProductID         = 0xcafe; /* Our own product ID :) */
     1091                pReply->IOCFacts.u32FwImageSize       = 0; /* No image needed. */
     1092                pReply->IOCFacts.u32FWVersion         = 0;
     1093            }
    7991094            break;
    8001095        }
     
    9031198
    9041199            pReply->FWDownload.u8MessageLength    = 5;
     1200            LogFlowFunc(("FW Download request issued\n"));
    9051201            break;
    9061202        }
     
    9171213    return rc;
    9181214}
     1215
    9191216#endif /* IN_RING3 */
    9201217
     
    11091406                pThis->fDiagnosticEnabled = false;
    11101407                pThis->iDiagnosticAccess  = 0;
     1408                pThis->fDiagRegsEnabled   = false;
    11111409            }
    11121410            else if ((u32 & 0xf) == g_lsilogicDiagnosticAccess[pThis->iDiagnosticAccess])
     
    11311429        case LSILOGIC_REG_HOST_DIAGNOSTIC:
    11321430        {
     1431            if (pThis->fDiagnosticEnabled)
     1432            {
    11331433#ifndef IN_RING3
    1134             return VINF_IOM_R3_IOPORT_WRITE;
     1434                return VINF_IOM_R3_MMIO_WRITE;
    11351435#else
    1136             if (u32 & LSILOGIC_REG_HOST_DIAGNOSTIC_RESET_ADAPTER)
     1436                if (u32 & LSILOGIC_REG_HOST_DIAGNOSTIC_RESET_ADAPTER)
     1437                    lsilogicR3HardReset(pThis);
     1438                else if (u32 & LSILOGIC_REG_HOST_DIAGNOSTIC_DIAG_RW_ENABLE)
     1439                    pThis->fDiagRegsEnabled = true;
     1440#endif
     1441            }
     1442            break;
     1443        }
     1444        case LSILOGIC_REG_DIAG_RW_DATA:
     1445        {
     1446            if (pThis->fDiagRegsEnabled)
    11371447            {
    1138                 lsilogicR3HardReset(pThis);
     1448#ifndef IN_RING3
     1449                return VINF_IOM_R3_MMIO_WRITE;
     1450#else
     1451                lsilogicR3DiagRegDataWrite(pThis, u32);
     1452#endif
    11391453            }
    11401454            break;
     1455        }
     1456        case LSILOGIC_REG_DIAG_RW_ADDRESS:
     1457        {
     1458            if (pThis->fDiagRegsEnabled)
     1459            {
     1460#ifndef IN_RING3
     1461                return VINF_IOM_R3_MMIO_WRITE;
     1462#else
     1463                lsilogicR3DiagRegAddressWrite(pThis, u32);
    11411464#endif
     1465            }
     1466            break;
    11421467        }
    11431468        default: /* Ignore. */
     
    12661591        {
    12671592            if (pThis->fDiagnosticEnabled)
    1268                 u32 = LSILOGIC_REG_HOST_DIAGNOSTIC_DRWE;
    1269             else
    1270                 u32 = 0;
    1271             break;
     1593                u32 |= LSILOGIC_REG_HOST_DIAGNOSTIC_DRWE;
     1594            if (pThis->fDiagRegsEnabled)
     1595                u32 |= LSILOGIC_REG_HOST_DIAGNOSTIC_DIAG_RW_ENABLE;
     1596            break;
     1597        }
     1598        case LSILOGIC_REG_DIAG_RW_DATA:
     1599        {
     1600            if (pThis->fDiagRegsEnabled)
     1601            {
     1602#ifndef IN_RING3
     1603                return VINF_IOM_R3_MMIO_READ;
     1604#else
     1605                lsilogicR3DiagRegDataRead(pThis, &u32);
     1606#endif
     1607            }
     1608        }
     1609        case LSILOGIC_REG_DIAG_RW_ADDRESS:
     1610        {
     1611            if (pThis->fDiagRegsEnabled)
     1612            {
     1613#ifndef IN_RING3
     1614                return VINF_IOM_R3_MMIO_READ;
     1615#else
     1616                lsilogicR3DiagRegAddressRead(pThis, &u32);
     1617#endif
     1618            }
    12721619        }
    12731620        case LSILOGIC_REG_TEST_BASE_ADDRESS: /* The spec doesn't say anything about these registers, so we just ignore them */
    1274         case LSILOGIC_REG_DIAG_RW_DATA:
    1275         case LSILOGIC_REG_DIAG_RW_ADDRESS:
    12761621        default: /* Ignore. */
    12771622        {
     
    13511696
    13521697    if (!(offReg & 3))
    1353     {
    13541698        rc = lsilogicRegisterWrite(pThis, offReg, u32);
    1355         if (rc == VINF_IOM_R3_MMIO_WRITE)
    1356             rc = VINF_IOM_R3_IOPORT_WRITE;
    1357     }
    13581699    else
    13591700    {
     
    14551796# endif /* LOG_ENABLED */
    14561797
     1798/**
     1799 * Walks the guest S/G buffer calling the given copy worker for every buffer.
     1800 *
     1801 * @returns nothing.
     1802 * @param   pDevIns      Device instance data.
     1803 * @param   pLsiReq      LSI request state.
     1804 * @param   cbCopy       How much bytes to copy.
     1805 * @param   pfnIoBufCopy Copy worker to call.
     1806 */
    14571807static void lsilogicSgBufWalker(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq, size_t cbCopy,
    14581808                                PFNLSILOGICIOBUFCOPY pfnIoBufCopy)
     
    15051855
    15061856            pfnIoBufCopy(pDevIns, GCPhysAddrDataBuffer, pbBuf, cbCopyThis);
    1507             pbBuf      += cbCopyThis;
    1508             cbCopyThis -= cbCopyThis;
     1857            pbBuf  += cbCopyThis;
     1858            cbCopy -= cbCopyThis;
    15091859
    15101860            /* Check if we reached the end of the list. */
     
    16331983
    16341984    AssertMsg(   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE
    1635               || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ,
     1985              || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ
     1986              || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE,
    16361987              ("Allocating I/O memory for a non I/O request is not allowed\n"));
    16371988
     
    16411992
    16421993    pLsiReq->SegIoBuf.cbSeg = cbTransfer;
    1643     if (uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE)
     1994    if (   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE
     1995        || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE)
    16441996        lsilogicCopyFromSgBuf(pDevIns, pLsiReq, cbTransfer);
    16451997
     
    16622014
    16632015    AssertMsg(   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE
    1664               || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ,
     2016              || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ
     2017              || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE,
    16652018              ("Allocating I/O memory for a non I/O request is not allowed\n"));
    16662019
    1667     if (   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ
     2020    if (   (   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ
     2021            || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE)
    16682022        && fCopyToGuest)
    16692023        lsilogicCopyToSgBuf(pDevIns, pLsiReq, pLsiReq->SegIoBuf.cbSeg);
     
    19532307                pLsiReq->IOCReply.SCSIIOError.u32ResponseInfo     = 0;
    19542308
    1955                 lsilogicFinishAddressReply(pThis, &pLsiReq->IOCReply, true);
     2309                lsilogicFinishAddressReply(pThis, &pLsiReq->IOCReply, false);
    19562310            }
    19572311        }
     
    39584312    SSMR3PutU16   (pSSM, pThis->u16NextHandle);
    39594313
     4314    /* Save diagnostic memory register and data regions. */
     4315    SSMR3PutU32   (pSSM, pThis->u32DiagMemAddr);
     4316    SSMR3PutU32   (pSSM, lsilogicR3MemRegionsCount(pThis));
     4317
     4318    PLSILOGICMEMREGN pIt = NULL;
     4319    RTListForEach(&pThis->ListMemRegns, pIt, LSILOGICMEMREGN, NodeList)
     4320    {
     4321        SSMR3PutU32(pSSM, pIt->u32AddrStart);
     4322        SSMR3PutU32(pSSM, pIt->u32AddrEnd);
     4323        SSMR3PutMem(pSSM, &pIt->au32Data[0], (pIt->u32AddrEnd - pIt->u32AddrStart + 1) * sizeof(uint32_t));
     4324    }
     4325
    39604326    PMptConfigurationPagesSupported pPages = pThis->pConfigurationPages;
    39614327
     
    40784444
    40794445    if (    uVersion != LSILOGIC_SAVED_STATE_VERSION
     4446        &&  uVersion != LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM
     4447        &&  uVersion != LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL
    40804448        &&  uVersion != LSILOGIC_SAVED_STATE_VERSION_PRE_SAS
    40814449        &&  uVersion != LSILOGIC_SAVED_STATE_VERSION_VBOX_30)
     
    42444612
    42454613        SSMR3GetU16(pSSM, &pThis->u16NextHandle);
     4614
     4615        if (uVersion > LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM)
     4616        {
     4617            uint32_t cMemRegions = 0;
     4618
     4619            /* Save diagnostic memory register and data regions. */
     4620            SSMR3GetU32   (pSSM, &pThis->u32DiagMemAddr);
     4621            SSMR3GetU32   (pSSM, &cMemRegions);
     4622
     4623            while (cMemRegions)
     4624            {
     4625                uint32_t u32AddrStart = 0;
     4626                uint32_t u32AddrEnd = 0;
     4627                uint32_t cRegion = 0;
     4628                PLSILOGICMEMREGN pRegion = NULL;
     4629
     4630                SSMR3GetU32(pSSM, &u32AddrStart);
     4631                SSMR3GetU32(pSSM, &u32AddrEnd);
     4632
     4633                cRegion = u32AddrEnd - u32AddrStart + 1;
     4634                pRegion = (PLSILOGICMEMREGN)RTMemAllocZ(RT_OFFSETOF(LSILOGICMEMREGN, au32Data[cRegion]));
     4635                if (pRegion)
     4636                {
     4637                    pRegion->u32AddrStart = u32AddrStart;
     4638                    pRegion->u32AddrEnd = u32AddrEnd;
     4639                    SSMR3GetMem(pSSM, &pRegion->au32Data[0], cRegion * sizeof(uint32_t));
     4640                    lsilogicR3MemRegionInsert(pThis, pRegion);
     4641                }
     4642                else
     4643                {
     4644                    /* Leave a log message but continue. */
     4645                    LogRel(("LsiLogic: Out of memory while restoring the state, might not work as expected\n"));
     4646                    SSMR3Skip(pSSM, cRegion * sizeof(uint32_t));
     4647                }
     4648                cMemRegions--;
     4649            }
     4650        }
    42464651
    42474652        /* Configuration pages */
     
    47375142
    47385143    lsilogicR3ConfigurationPagesFree(pThis);
     5144    lsilogicR3MemRegionsFree(pThis);
    47395145
    47405146    return VINF_SUCCESS;
     
    47545160     */
    47555161    pThis->hTaskCache = NIL_RTMEMCACHE;
     5162    RTListInit(&pThis->ListMemRegns);
    47565163
    47575164    /*
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h

    r45795 r45970  
    11531153AssertCompileSize(MptReplyUnion, 60);
    11541154
     1155/**
     1156 * Firmware image header.
     1157 */
     1158#pragma pack(1)
     1159typedef struct FwImageHdr
     1160{
     1161    /** ARM branch instruction. */
     1162    uint32_t    u32ArmBrInsn;
     1163    /** Signature part 1. */
     1164    uint32_t    u32Signature1;
     1165    /** Signature part 2. */
     1166    uint32_t    u32Signature2;
     1167    /** Signature part 3. */
     1168    uint32_t    u32Signature3;
     1169    /** Another ARM branch instruction. */
     1170    uint32_t    u32ArmBrInsn2;
     1171    /** Yet another ARM branch instruction. */
     1172    uint32_t    u32ArmBrInsn3;
     1173    /** Reserved. */
     1174    uint32_t    u32Reserved;
     1175    /** Checksum of the image. */
     1176    uint32_t    u32Checksum;
     1177    /** Vendor ID. */
     1178    uint16_t    u16VendorId;
     1179    /** Product ID. */
     1180    uint16_t    u16ProductId;
     1181    /** Firmware version. */
     1182    uint32_t    u32FwVersion;
     1183    /** Firmware sequencer Code version. */
     1184    uint32_t    u32SeqCodeVersion;
     1185    /** Image size in bytes including the header. */
     1186    uint32_t    u32ImageSize;
     1187    /** Offset of the first extended image header. */
     1188    uint32_t    u32NextImageHeaderOffset;
     1189    /** Start address of the image in IOC memory. */
     1190    uint32_t    u32LoadStartAddress;
     1191    /** Absolute start address of the Iop ARM. */
     1192    uint32_t    u32IopResetVectorValue;
     1193    /** Address of the IopResetVector register. */
     1194    uint32_t    u32IopResetVectorRegAddr;
     1195    /** Marker value for what utility. */
     1196    uint32_t    u32VersionNameWhat;
     1197    /** ASCII string of version. */
     1198    uint8_t     aszVersionName[256];
     1199    /** Marker value for what utility. */
     1200    uint32_t    u32VendorNameWhat;
     1201    /** ASCII string of vendor name. */
     1202    uint8_t     aszVendorName[256];
     1203} FwImageHdr, *PFwImageHdr;
     1204#pragma pack()
     1205AssertCompileSize(FwImageHdr, 584);
     1206
     1207/** First part of the signature. */
     1208#define LSILOGIC_FWIMGHDR_SIGNATURE1 UINT32_C(0x5aeaa55a)
     1209/** Second part of the signature. */
     1210#define LSILOGIC_FWIMGHDR_SIGNATURE2 UINT32_C(0xa55aeaa5)
     1211/** Third part of the signature. */
     1212#define LSILOGIC_FWIMGHDR_SIGNATURE3 UINT32_C(0x5aa55aea)
     1213/** Load address of the firmware image to watch for,
     1214 * seen used by Solaris 9. When this value is written to the
     1215 * diagnostic address register we know a firmware image is downloaded.
     1216 */
     1217#define LSILOGIC_FWIMGHDR_LOAD_ADDRESS UINT32_C(0x21ff5e00)
    11551218
    11561219/**
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r45808 r45970  
    15631563    GEN_CHECK_OFF(LSILOGICSCSI, fNotificationSend);
    15641564    GEN_CHECK_OFF(LSILOGICSCSI, fEventNotificationEnabled);
     1565    GEN_CHECK_OFF(LSILOGICSCSI, fDiagRegsEnabled);
    15651566    GEN_CHECK_OFF(LSILOGICSCSI, pNotificationQueueR3);
    15661567    GEN_CHECK_OFF(LSILOGICSCSI, pNotificationQueueR0);
     
    16161617    GEN_CHECK_OFF(LSILOGICSCSI, fRedo);
    16171618    GEN_CHECK_OFF(LSILOGICSCSI, pTasksRedoHead);
     1619    GEN_CHECK_OFF(LSILOGICSCSI, u32DiagMemAddr);
     1620    GEN_CHECK_OFF(LSILOGICSCSI, ListMemRegns);
    16181621#endif /* VBOX_WITH_LSILOGIC */
    16191622
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