Changeset 7671 in vbox
- Timestamp:
- Apr 1, 2008 7:56:35 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r7641 r7671 53 53 #include <VBox/pgm.h> 54 54 #include <VBox/vm.h> /* for VM_IS_EMT */ 55 #include <VBox/DevPCNet.h> 55 56 #include <iprt/asm.h> 56 57 #include <iprt/assert.h> … … 229 230 #endif 230 231 232 /** The host context of the shared memory used for the private interface. */ 233 PPCNETGUESTSHAREDMEMORY pSharedMMIOHC; 234 /** The hypervisor/guest context of the shared memory used for the private interface. */ 235 GCPTRTYPE(PPCNETGUESTSHAREDMEMORY) pSharedMMIOGC; 236 237 /** True if host and guest admitted to use the private interface. */ 238 bool fPrivIfEnabled; 231 239 bool fGCEnabled; 232 240 bool fR0Enabled; 233 241 bool fAm79C973; 234 bool afAlignment[1];235 242 uint32_t u32LinkSpeed; 236 243 … … 594 601 uint8_t ownbyte; 595 602 596 if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 603 if (pData->fPrivIfEnabled) 604 { 605 /* RX/TX descriptors shared between host and guest => direct copy */ 606 uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO) 607 + (addr - pData->GCTDRA) 608 + pData->CTXSUFF(pSharedMMIO)->V.V1.u32OffTxDescriptors; 609 if (!(pv[7] & 0x80) && fRetIfNotOwn) 610 return false; 611 memcpy(tmd, pv, 16); 612 return true; 613 } 614 else if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 597 615 { 598 616 uint16_t xda[4]; … … 645 663 STAM_PROFILE_ADV_START(&pData->CTXSUFF(StatTmdStore), a); 646 664 PPDMDEVINS pDevIns = PCNETSTATE_2_DEVINS(pData); 647 if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 665 if (pData->fPrivIfEnabled) 666 { 667 /* RX/TX descriptors shared between host and guest => direct copy */ 668 uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO) 669 + (addr - pData->GCTDRA) 670 + pData->CTXSUFF(pSharedMMIO)->V.V1.u32OffTxDescriptors; 671 memcpy(pv, tmd, 16); 672 pv[7] &= ~0x80; 673 } 674 else if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 648 675 { 649 676 uint16_t xda[4]; … … 693 720 uint8_t ownbyte; 694 721 695 if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 722 if (pData->fPrivIfEnabled) 723 { 724 /* RX/TX descriptors shared between host and guest => direct copy */ 725 uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO) 726 + (addr - pData->GCRDRA) 727 + pData->CTXSUFF(pSharedMMIO)->V.V1.u32OffRxDescriptors; 728 if (!(pv[7] & 0x80) && fRetIfNotOwn) 729 return false; 730 memcpy(rmd, pv, 16); 731 return true; 732 } 733 else if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 696 734 { 697 735 uint16_t rda[4]; … … 742 780 { 743 781 PPDMDEVINS pDevIns = PCNETSTATE_2_DEVINS(pData); 744 if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 782 if (pData->fPrivIfEnabled) 783 { 784 /* RX/TX descriptors shared between host and guest => direct copy */ 785 uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO) 786 + (addr - pData->GCRDRA) 787 + pData->CTXSUFF(pSharedMMIO)->V.V1.u32OffRxDescriptors; 788 memcpy(pv, rmd, 16); 789 pv[7] &= ~0x80; 790 } 791 else if (RT_UNLIKELY(BCR_SWSTYLE(pData) == 0)) 745 792 { 746 793 uint16_t rda[4]; … … 814 861 815 862 #ifdef IN_RING3 863 864 /** 865 * Initialize the shared memory for the private guest interface. 866 */ 867 static void pcnetInitSharedMemory(PCNetState *pData) 868 { 869 uint32_t u32Off = 0; 870 memset(pData->pSharedMMIOHC, 0, sizeof(PCNETGUESTSHAREDMEMORY)); 871 pData->pSharedMMIOHC->u32Size = sizeof(PCNETGUESTSHAREDMEMORY); 872 pData->pSharedMMIOHC->u32Version = PCNET_GUEST_INTERFACE_VERSION; 873 u32Off = 2048; /* Leave some space for more fields within the header */ 874 pData->pSharedMMIOHC->V.V1.u32OffTxDescriptors = u32Off; 875 u32Off = RT_ALIGN(u32Off + PCNET_GUEST_TX_DESCRIPTOR_SIZE * PCNET_GUEST_MAX_TX_DESCRIPTORS, 32); 876 pData->pSharedMMIOHC->V.V1.u32OffRxDescriptors = u32Off; 877 u32Off = RT_ALIGN(u32Off + PCNET_GUEST_RX_DESCRIPTOR_SIZE * PCNET_GUEST_MAX_RX_DESCRIPTORS, 32); 878 /* Map the RX/TX descriptors into the hypervisor. Make sure we don't need too much space. */ 879 AssertRelease(u32Off <= 8192); 880 pData->pSharedMMIOHC->V.V1.u32OffTxBuffers = u32Off; 881 u32Off = RT_ALIGN(u32Off + PCNET_GUEST_NIC_BUFFER_SIZE * PCNET_GUEST_MAX_TX_DESCRIPTORS, 32); 882 pData->pSharedMMIOHC->V.V1.u32OffRxBuffers = u32Off; 883 pData->pSharedMMIOHC->fFlags = PCNET_GUEST_FLAGS_ADMIT_HOST; 884 u32Off = RT_ALIGN(u32Off + PCNET_GUEST_NIC_BUFFER_SIZE * PCNET_GUEST_MAX_RX_DESCRIPTORS, 32); 885 AssertRelease(u32Off <= PCNET_GUEST_SHARED_MEMORY_SIZE); 886 } 816 887 817 888 #define MULTICAST_FILTER_LEN 8 … … 1384 1455 } while (0) 1385 1456 1457 bool fPrivIfEnabled = pData->pSharedMMIOHC 1458 && !!(pData->pSharedMMIOHC->fFlags & PCNET_GUEST_FLAGS_ADMIT_GUEST); 1459 if (fPrivIfEnabled != pData->fPrivIfEnabled) 1460 { 1461 pData->fPrivIfEnabled = fPrivIfEnabled; 1462 LogRel(("PCNet#%d: %s private interface\n", PCNET_INST_NR, fPrivIfEnabled ? "Enabling" : "Disabling")); 1463 } 1386 1464 if (BCR_SSIZE32(pData)) 1387 1465 { … … 2223 2301 { 2224 2302 AssertMsg(fDropFrame, ("pcnetTransmit: Frame is too big!!! %d bytes\n", 2225 2303 pData->cbSendFrame + cb)); 2226 2304 fDropFrame = true; 2227 2305 } … … 2229 2307 { 2230 2308 Log(("#%d pcnetTransmit: stp: cb=%d xmtrc=%#x-%#x\n", PCNET_INST_NR, 2231 pData->cbSendFrame, iStart, CSR_XMTRC(pData)));2309 pData->cbSendFrame, iStart, CSR_XMTRC(pData))); 2232 2310 if (pcnetIsLinkUp(pData) && !fDropFrame) 2233 2311 { … … 3698 3776 3699 3777 /** 3778 * Callback function for mapping the MMIO region. 3779 * 3780 * @return VBox status code. 3781 * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance. 3782 * @param iRegion The region number. 3783 * @param GCPhysAddress Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an 3784 * I/O port, else it's a physical address. 3785 * This address is *NOT* relative to pci_mem_base like earlier! 3786 * @param cb Region size. 3787 * @param enmType One of the PCI_ADDRESS_SPACE_* values. 3788 */ 3789 static DECLCALLBACK(int) pcnetMMIOSharedMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, 3790 RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType) 3791 { 3792 if (GCPhysAddress != NIL_RTGCPHYS) 3793 return PDMDevHlpMMIO2Map(pPciDev->pDevIns, iRegion, GCPhysAddress); 3794 3795 /* nothing to clean up */ 3796 return VINF_SUCCESS; 3797 } 3798 3799 3800 /** 3700 3801 * PCNET status info callback. 3701 3802 * … … 4284 4385 pcnetTimerRestore(pDevIns, pData->pTimerRestore); 4285 4386 } 4387 if (pData->pSharedMMIOHC) 4388 pcnetInitSharedMemory(pData); 4286 4389 4287 4390 /** @todo How to flush the queues? */ … … 4299 4402 pData->pXmitQueueGC = PDMQueueGCPtr(pData->pXmitQueueHC); 4300 4403 pData->pCanRxQueueGC = PDMQueueGCPtr(pData->pCanRxQueueHC); 4404 pData->pSharedMMIOGC += offDelta; 4301 4405 #ifdef PCNET_NO_POLLING 4302 4406 *(RTHCUINTPTR *)&pData->pfnEMInterpretInstructionGC += offDelta; … … 4371 4475 * Validate configuration. 4372 4476 */ 4373 if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0CableConnected\0Am79C973\0LineSpeed\0GCEnabled\0R0Enabled\0 "))4477 if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0CableConnected\0Am79C973\0LineSpeed\0GCEnabled\0R0Enabled\0PrivIfEnabled\0")) 4374 4478 return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES, 4375 4479 N_("Invalid configuraton for pcnet device")); … … 4487 4591 if (VBOX_FAILURE(rc)) 4488 4592 return rc; 4593 4594 bool fPrivIfEnabled; 4595 rc = CFGMR3QueryBool(pCfgHandle, "PrivIfEnabled", &fPrivIfEnabled); 4596 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 4597 fPrivIfEnabled = true; 4598 else if (VBOX_FAILURE(rc)) 4599 return PDMDEV_SET_ERROR(pDevIns, rc, 4600 N_("Configuration error: Failed to get the \"PrivIfEnabled\" value")); 4601 4602 if (fPrivIfEnabled) 4603 { 4604 /* 4605 * Initialize shared memory between host and guest for descriptors and RX buffers. Most guests 4606 * should not care if there is an additional PCI ressource but just in case we made this configurable. 4607 */ 4608 rc = PDMDevHlpMMIO2Register(pDevIns, 2, PCNET_GUEST_SHARED_MEMORY_SIZE, (void**)&pData->pSharedMMIOHC, "PCNetShMem"); 4609 if (VBOX_FAILURE(rc)) 4610 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 4611 N_("Failed to allocate %u bytes of memory for the PCNet device"), PCNET_GUEST_SHARED_MEMORY_SIZE); 4612 rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, 2, 0, 8192, "PCNetShMem", &pData->pSharedMMIOGC); 4613 if (VBOX_FAILURE(rc)) 4614 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 4615 N_("Failed to map 8192 bytes of memory for the PCNet device into the hyper memory")); 4616 pcnetInitSharedMemory(pData); 4617 rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, PCNET_GUEST_SHARED_MEMORY_SIZE, 4618 PCI_ADDRESS_SPACE_MEM, pcnetMMIOSharedMap); 4619 if (VBOX_FAILURE(rc)) 4620 return rc; 4621 } 4489 4622 4490 4623 #ifdef PCNET_NO_POLLING
Note:
See TracChangeset
for help on using the changeset viewer.