Changeset 45970 in vbox for trunk/src/VBox/Devices
- Timestamp:
- May 9, 2013 5:27:59 PM (12 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
r45959 r45970 27 27 #include <iprt/asm.h> 28 28 #include <iprt/string.h> 29 #include <iprt/list.h> 29 30 #ifdef IN_RING3 30 31 # include <iprt/memcache.h> … … 45 46 *******************************************************************************/ 46 47 /** 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 48 52 /** The saved state version used by VirtualBox before the doorbell status flag 49 53 * was changed from bool to a 32bit enum. */ … … 97 101 /** Pointer to reply data. */ 98 102 typedef LSILOGICSCSIREPLY *PLSILOGICSCSIREPLY; 103 104 /** 105 * Memory region of the IOC. 106 */ 107 typedef 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. */ 119 typedef LSILOGICMEMREGN *PLSILOGICMEMREGN; 99 120 100 121 /** … … 170 191 /** Flag whether the guest enabled event notification from the IOC. */ 171 192 bool fEventNotificationEnabled; 193 /** Flag whether the diagnostic address and RW registers are enabled. */ 194 bool fDiagRegsEnabled; 172 195 173 196 /** Queue to send tasks to R3. - R3 ptr */ … … 308 331 bool volatile fRedo; 309 332 /** Alignment padding. */ 310 bool afPAdding2[HC_ARCH_BITS == 32 ? 2 : 6];333 bool afPadding2[HC_ARCH_BITS == 32 ? 2 : 6]; 311 334 /** List of tasks which can be redone. */ 312 335 R3PTRTYPE(volatile PLSILOGICREQ) pTasksRedoHead; 313 336 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 }; 314 348 } LSILOGISCSI; 315 349 /** Pointer to the device instance data of the LsiLogic emulation. */ … … 452 486 } 453 487 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 */ 494 DECLINLINE(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 */ 512 DECLINLINE(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 454 524 #ifdef IN_RING3 455 525 … … 481 551 482 552 /* Disable diagnostic access. */ 483 pThis->iDiagnosticAccess = 0; 553 pThis->iDiagnosticAccess = 0; 554 pThis->fDiagnosticEnabled = false; 555 pThis->fDiagRegsEnabled = false; 484 556 485 557 /* 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; 491 563 492 564 lsilogicR3ConfigurationPagesFree(pThis); … … 555 627 AssertRC(rc); 556 628 557 # if 0558 629 /* Check for a entry in the queue. */ 559 if ( RT_UNLIKELY(pThis->uReplyPostQueueNextAddressRead != pThis->uReplyPostQueueNextEntryFreeWrite))630 if (!lsilogicReplyPostQueueGetFrameCount(pThis)) 560 631 { 561 632 /* Set error code. */ … … 564 635 return; 565 636 } 566 # endif567 637 568 638 /* We have a context reply. */ … … 615 685 AssertRC(rc); 616 686 617 #if 0618 687 /* Check for a free reply frame. */ 619 if ( RT_UNLIKELY(pThis->uReplyFreeQueueNextAddressRead != pThis->uReplyFreeQueueNextEntryFreeWrite))688 if (!lsilogicReplyFreeQueueGetFrameCount(pThis)) 620 689 { 621 690 /* Set error code. */ … … 624 693 return; 625 694 } 626 #endif627 695 628 696 uint32_t u32ReplyFrameAddressLow = pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead]; … … 644 712 AssertRC(rc); 645 713 646 #if 0647 714 /* Check for a entry in the queue. */ 648 if ( RT_UNLIKELY(pThis->uReplyPostQueueNextAddressRead != pThis->uReplyPostQueueNextEntryFreeWrite))715 if (!lsilogicReplyPostQueueGetFrameCount(pThis)) 649 716 { 650 717 /* Set error code. */ … … 653 720 return; 654 721 } 655 #endif656 722 657 723 /* We have a address reply. Set the 31th bit to indicate that. */ … … 677 743 } 678 744 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 */ 754 static 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 */ 778 static 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 */ 797 static 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 */ 822 static 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 */ 842 static 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 } 691 857 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 */ 921 static 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 */ 950 static 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 */ 962 static void lsilogicR3DiagRegAddressRead(PLSILOGICSCSI pThis, uint32_t *pu32Addr) 963 { 964 *pu32Addr = pThis->u32DiagMemAddr; 965 } 966 698 967 /** 699 968 * Processes a given Request from the guest … … 786 1055 pReply->IOCFacts.u16ReplyQueueDepth = pThis->cReplyQueueEntries - 1; /* One entry is always free. */ 787 1056 pReply->IOCFacts.u16RequestFrameSize = 128; /* @todo Figure out where it is needed. */ 788 pReply->IOCFacts.u16ProductID = 0xcafe; /* Our own product ID :) */789 1057 pReply->IOCFacts.u32CurrentHostMFAHighAddr = pThis->u32HostMFAHighAddr; 790 1058 pReply->IOCFacts.u16GlobalCredits = pThis->cRequestQueueEntries - 1; /* One entry is always free. */ … … 795 1063 pReply->IOCFacts.u8MaxDevices = pThis->cMaxDevices; 796 1064 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 } 799 1094 break; 800 1095 } … … 903 1198 904 1199 pReply->FWDownload.u8MessageLength = 5; 1200 LogFlowFunc(("FW Download request issued\n")); 905 1201 break; 906 1202 } … … 917 1213 return rc; 918 1214 } 1215 919 1216 #endif /* IN_RING3 */ 920 1217 … … 1109 1406 pThis->fDiagnosticEnabled = false; 1110 1407 pThis->iDiagnosticAccess = 0; 1408 pThis->fDiagRegsEnabled = false; 1111 1409 } 1112 1410 else if ((u32 & 0xf) == g_lsilogicDiagnosticAccess[pThis->iDiagnosticAccess]) … … 1131 1429 case LSILOGIC_REG_HOST_DIAGNOSTIC: 1132 1430 { 1431 if (pThis->fDiagnosticEnabled) 1432 { 1133 1433 #ifndef IN_RING3 1134 return VINF_IOM_R3_IOPORT_WRITE;1434 return VINF_IOM_R3_MMIO_WRITE; 1135 1435 #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) 1137 1447 { 1138 lsilogicR3HardReset(pThis); 1448 #ifndef IN_RING3 1449 return VINF_IOM_R3_MMIO_WRITE; 1450 #else 1451 lsilogicR3DiagRegDataWrite(pThis, u32); 1452 #endif 1139 1453 } 1140 1454 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); 1141 1464 #endif 1465 } 1466 break; 1142 1467 } 1143 1468 default: /* Ignore. */ … … 1266 1591 { 1267 1592 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 } 1272 1619 } 1273 1620 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:1276 1621 default: /* Ignore. */ 1277 1622 { … … 1351 1696 1352 1697 if (!(offReg & 3)) 1353 {1354 1698 rc = lsilogicRegisterWrite(pThis, offReg, u32); 1355 if (rc == VINF_IOM_R3_MMIO_WRITE)1356 rc = VINF_IOM_R3_IOPORT_WRITE;1357 }1358 1699 else 1359 1700 { … … 1455 1796 # endif /* LOG_ENABLED */ 1456 1797 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 */ 1457 1807 static void lsilogicSgBufWalker(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq, size_t cbCopy, 1458 1808 PFNLSILOGICIOBUFCOPY pfnIoBufCopy) … … 1505 1855 1506 1856 pfnIoBufCopy(pDevIns, GCPhysAddrDataBuffer, pbBuf, cbCopyThis); 1507 pbBuf 1508 cbCopy This-= cbCopyThis;1857 pbBuf += cbCopyThis; 1858 cbCopy -= cbCopyThis; 1509 1859 1510 1860 /* Check if we reached the end of the list. */ … … 1633 1983 1634 1984 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, 1636 1987 ("Allocating I/O memory for a non I/O request is not allowed\n")); 1637 1988 … … 1641 1992 1642 1993 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) 1644 1996 lsilogicCopyFromSgBuf(pDevIns, pLsiReq, cbTransfer); 1645 1997 … … 1662 2014 1663 2015 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, 1665 2018 ("Allocating I/O memory for a non I/O request is not allowed\n")); 1666 2019 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) 1668 2022 && fCopyToGuest) 1669 2023 lsilogicCopyToSgBuf(pDevIns, pLsiReq, pLsiReq->SegIoBuf.cbSeg); … … 1953 2307 pLsiReq->IOCReply.SCSIIOError.u32ResponseInfo = 0; 1954 2308 1955 lsilogicFinishAddressReply(pThis, &pLsiReq->IOCReply, true);2309 lsilogicFinishAddressReply(pThis, &pLsiReq->IOCReply, false); 1956 2310 } 1957 2311 } … … 3958 4312 SSMR3PutU16 (pSSM, pThis->u16NextHandle); 3959 4313 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 3960 4326 PMptConfigurationPagesSupported pPages = pThis->pConfigurationPages; 3961 4327 … … 4078 4444 4079 4445 if ( uVersion != LSILOGIC_SAVED_STATE_VERSION 4446 && uVersion != LSILOGIC_SAVED_STATE_VERSION_PRE_DIAG_MEM 4447 && uVersion != LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL 4080 4448 && uVersion != LSILOGIC_SAVED_STATE_VERSION_PRE_SAS 4081 4449 && uVersion != LSILOGIC_SAVED_STATE_VERSION_VBOX_30) … … 4244 4612 4245 4613 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 } 4246 4651 4247 4652 /* Configuration pages */ … … 4737 5142 4738 5143 lsilogicR3ConfigurationPagesFree(pThis); 5144 lsilogicR3MemRegionsFree(pThis); 4739 5145 4740 5146 return VINF_SUCCESS; … … 4754 5160 */ 4755 5161 pThis->hTaskCache = NIL_RTMEMCACHE; 5162 RTListInit(&pThis->ListMemRegns); 4756 5163 4757 5164 /* -
trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h
r45795 r45970 1153 1153 AssertCompileSize(MptReplyUnion, 60); 1154 1154 1155 /** 1156 * Firmware image header. 1157 */ 1158 #pragma pack(1) 1159 typedef 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() 1205 AssertCompileSize(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) 1155 1218 1156 1219 /** -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r45808 r45970 1563 1563 GEN_CHECK_OFF(LSILOGICSCSI, fNotificationSend); 1564 1564 GEN_CHECK_OFF(LSILOGICSCSI, fEventNotificationEnabled); 1565 GEN_CHECK_OFF(LSILOGICSCSI, fDiagRegsEnabled); 1565 1566 GEN_CHECK_OFF(LSILOGICSCSI, pNotificationQueueR3); 1566 1567 GEN_CHECK_OFF(LSILOGICSCSI, pNotificationQueueR0); … … 1616 1617 GEN_CHECK_OFF(LSILOGICSCSI, fRedo); 1617 1618 GEN_CHECK_OFF(LSILOGICSCSI, pTasksRedoHead); 1619 GEN_CHECK_OFF(LSILOGICSCSI, u32DiagMemAddr); 1620 GEN_CHECK_OFF(LSILOGICSCSI, ListMemRegns); 1618 1621 #endif /* VBOX_WITH_LSILOGIC */ 1619 1622
Note:
See TracChangeset
for help on using the changeset viewer.