VirtualBox

Changeset 44567 in vbox


Ignore:
Timestamp:
Feb 6, 2013 1:58:43 PM (12 years ago)
Author:
vboxsync
Message:

DevE1000: Use IOMMMIO_FLAGS_READ_DWORD and IOMMMIO_FLAGS_WRITE_ONLY_DWORD, allowing us to simplify the registry access function (with one I/O port exception).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r44546 r44567  
    55715571
    55725572/**
    5573  * Handle register read operation.
     5573 * Handle unaligned register read operation.
    55745574 *
    55755575 * Looks up and calls appropriate handler.
     
    55825582 * @param   cb          Number of bytes to read.
    55835583 * @thread  EMT
    5584  */
    5585 static int e1kRegRead(PE1KSTATE pThis, uint32_t offReg, void *pv, uint32_t cb)
     5584 * @remarks IOM takes care of unaligned and small reads via MMIO.  For I/O port
     5585 *          accesses we have to take care of that ourselves.
     5586 */
     5587static int e1kRegReadUnaligned(PE1KSTATE pThis, uint32_t offReg, void *pv, uint32_t cb)
    55865588{
    55875589    uint32_t    u32    = 0;
    5588     uint32_t    mask   = 0;
    55895590    uint32_t    shift;
    55905591    int         rc     = VINF_SUCCESS;
     
    56015602
    56025603    /*
    5603      * To be able to write bytes and short word we convert them
    5604      * to properly shifted 32-bit words and masks. The idea is
    5605      * to keep register-specific handlers simple. Most accesses
    5606      * will be 32-bit anyway.
     5604     * To be able to read bytes and short word we convert them to properly
     5605     * shifted 32-bit words and masks.  The idea is to keep register-specific
     5606     * handlers simple. Most accesses will be 32-bit anyway.
    56075607     */
     5608    uint32_t mask;
    56085609    switch (cb)
    56095610    {
     5611        case 4: mask = 0xFFFFFFFF; break;
     5612        case 2: mask = 0x0000FFFF; break;
    56105613        case 1: mask = 0x000000FF; break;
    5611         case 2: mask = 0x0000FFFF; break;
    5612         case 4: mask = 0xFFFFFFFF; break;
    56135614        default:
    56145615            return PDMDevHlpDBGFStop(pThis->CTX_SUFF(pDevIns), RT_SRC_POS,
    5615                                      "%s e1kRegRead: unsupported op size: offset=%#10x cb=%#10x\n",
    5616                                      pThis->szPrf, offReg, cb);
     5616                                     "unsupported op size: offset=%#10x cb=%#10x\n", offReg, cb);
    56175617    }
    56185618    if (index != -1)
     
    56245624            mask <<= shift;
    56255625            if (!mask)
    5626                 return PDMDevHlpDBGFStop(pThis->CTX_SUFF(pDevIns), RT_SRC_POS,
    5627                                          "%s e1kRegRead: Zero mask: offset=%#10x cb=%#10x\n",
    5628                                          pThis->szPrf, offReg, cb);
     5626                return PDMDevHlpDBGFStop(pThis->CTX_SUFF(pDevIns), RT_SRC_POS, "Zero mask: offset=%#10x cb=%#10x\n", offReg, cb);
    56295627            /*
    56305628             * Read it. Pass the mask so the handler knows what has to be read.
     
    56605658
    56615659/**
    5662  * Handle register write operation.
     5660 * Handle 4 byte aligned and sized read operation.
    56635661 *
    56645662 * Looks up and calls appropriate handler.
     
    56685666 * @param   pThis       The device state structure.
    56695667 * @param   offReg      Register offset in memory-mapped frame.
    5670  * @param   pv          Where to fetch the value.
    5671  * @param   cb          Number of bytes to write.
     5668 * @param   pu32        Where to store the result.
    56725669 * @thread  EMT
    56735670 */
    5674 static int e1kRegWrite(PE1KSTATE pThis, uint32_t offReg, void const *pv, unsigned cb)
    5675 {
    5676     int         rc     = VINF_SUCCESS;
    5677     int         index  = e1kRegLookup(pThis, offReg);
     5671static int e1kRegReadAlignedU32(PE1KSTATE pThis, uint32_t offReg, uint32_t *pu32)
     5672{
     5673    Assert(!(offReg & 3));
    56785674
    56795675    /*
    5680      * From the spec:
    5681      * For registers that should be accessed as 32-bit double words, partial writes (less than a 32-bit
    5682      * double word) is ignored. Partial reads return all 32 bits of data regardless of the byte enables.
     5676     * Lookup the register and check that it's readable.
    56835677     */
    5684 
    5685     if (cb != 4)
    5686     {
    5687         E1kLog(("%s e1kRegWrite: Spec violation: unsupported op size: offset=%#10x cb=%#10x, ignored.\n",
    5688                 pThis->szPrf, offReg, cb));
    5689         return VINF_SUCCESS;
    5690     }
    5691     if (offReg & 3)
    5692     {
    5693         E1kLog(("%s e1kRegWrite: Spec violation: misaligned offset: %#10x cb=%#10x, ignored.\n",
    5694                 pThis->szPrf, offReg, cb));
    5695         return VINF_SUCCESS;
    5696     }
    5697 
    5698     uint32_t u32 = *(uint32_t const *)pv;
    5699     if (index != -1)
    5700     {
    5701         if (g_aE1kRegMap[index].writable)
     5678    int rc     = VINF_SUCCESS;
     5679    int idxReg = e1kRegLookup(pThis, offReg);
     5680    if (RT_LIKELY(idxReg != -1))
     5681    {
     5682        if (RT_UNLIKELY(g_aE1kRegMap[idxReg].readable))
     5683        {
     5684            /*
     5685             * Read it. Pass the mask so the handler knows what has to be read.
     5686             * Mask out irrelevant bits.
     5687             */
     5688            //rc = e1kCsEnter(pThis, VERR_SEM_BUSY, RT_SRC_POS);
     5689            //if (RT_UNLIKELY(rc != VINF_SUCCESS))
     5690            //    return rc;
     5691            //pThis->fDelayInts = false;
     5692            //pThis->iStatIntLost += pThis->iStatIntLostOne;
     5693            //pThis->iStatIntLostOne = 0;
     5694            rc = g_aE1kRegMap[idxReg].pfnRead(pThis, offReg & 0xFFFFFFFC, idxReg, pu32);
     5695            //e1kCsLeave(pThis);
     5696            E1kLog2(("%s At %08X read  ffffffff          from %s (%s)\n",
     5697                    pThis->szPrf, offReg, g_aE1kRegMap[idxReg].abbrev, g_aE1kRegMap[idxReg].name));
     5698            if (IOM_SUCCESS(rc))
     5699                STAM_COUNTER_INC(&pThis->aStatRegReads[idxReg]);
     5700        }
     5701        else
     5702            E1kLog(("%s At %08X read (%s) attempt from non-existing register\n", pThis->szPrf, offReg));
     5703    }
     5704    else
     5705        E1kLog(("%s At %08X read attempt from non-existing register\n", pThis->szPrf, offReg));
     5706    return rc;
     5707}
     5708
     5709/**
     5710 * Handle 4 byte sized and aligned register write operation.
     5711 *
     5712 * Looks up and calls appropriate handler.
     5713 *
     5714 * @returns VBox status code.
     5715 *
     5716 * @param   pThis       The device state structure.
     5717 * @param   offReg      Register offset in memory-mapped frame.
     5718 * @param   u32Value    The value to write.
     5719 * @thread  EMT
     5720 */
     5721static int e1kRegWriteAlignedU32(PE1KSTATE pThis, uint32_t offReg, uint32_t u32Value)
     5722{
     5723    int         rc    = VINF_SUCCESS;
     5724    int         index = e1kRegLookup(pThis, offReg);
     5725    if (RT_LIKELY(index != -1))
     5726    {
     5727        if (RT_LIKELY(g_aE1kRegMap[index].writable))
    57025728        {
    57035729            /*
     
    57065732             */
    57075733            E1kLog2(("%s At %08X write          %08X  to  %s (%s)\n",
    5708                      pThis->szPrf, offReg, u32, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
     5734                     pThis->szPrf, offReg, u32Value, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
    57095735            //rc = e1kCsEnter(pThis, VERR_SEM_BUSY, RT_SRC_POS);
    5710             if (RT_UNLIKELY(rc != VINF_SUCCESS))
    5711                 return rc;
     5736            //if (RT_UNLIKELY(rc != VINF_SUCCESS))
     5737            //    return rc;
    57125738            //pThis->fDelayInts = false;
    57135739            //pThis->iStatIntLost += pThis->iStatIntLostOne;
    57145740            //pThis->iStatIntLostOne = 0;
    5715             rc = g_aE1kRegMap[index].pfnWrite(pThis, offReg, index, u32);
     5741            rc = g_aE1kRegMap[index].pfnWrite(pThis, offReg, index, u32Value);
    57165742            //e1kCsLeave(pThis);
    57175743        }
    57185744        else
    57195745            E1kLog(("%s At %08X write attempt (%08X) to  read-only register %s (%s)\n",
    5720                     pThis->szPrf, offReg, u32, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
     5746                    pThis->szPrf, offReg, u32Value, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
    57215747        if (IOM_SUCCESS(rc))
    57225748            STAM_COUNTER_INC(&pThis->aStatRegWrites[index]);
     
    57245750    else
    57255751        E1kLog(("%s At %08X write attempt (%08X) to  non-existing register\n",
    5726                 pThis->szPrf, offReg, u32));
     5752                pThis->szPrf, offReg, u32Value));
    57275753    return rc;
    57285754}
     
    57325758
    57335759/**
    5734  * I/O handler for memory-mapped read operations.
    5735  *
    5736  * @returns VBox status code.
    5737  *
    5738  * @param   pDevIns     The device instance.
    5739  * @param   pvUser      User argument.
    5740  * @param   GCPhysAddr  Physical address (in GC) where the read starts.
    5741  * @param   pv          Where to store the result.
    5742  * @param   cb          Number of bytes read.
    5743  * @thread  EMT
     5760 * @callback_method_impl{FNIOMMMIOREAD}
    57445761 */
    57455762PDMBOTHCBDECL(int) e1kMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
     
    57475764    NOREF(pvUser);
    57485765    PE1KSTATE pThis  = PDMINS_2_DATA(pDevIns, PE1KSTATE);
     5766    STAM_PROFILE_ADV_START(&pThis->CTX_SUFF_Z(StatMMIORead), a);
     5767
    57495768    uint32_t  offReg = GCPhysAddr - pThis->addrMMReg;
    5750     STAM_PROFILE_ADV_START(&pThis->CTX_SUFF_Z(StatMMIORead), a);
    5751 
    57525769    Assert(offReg < E1K_MM_SIZE);
    5753 
    5754     int rc = e1kRegRead(pThis, offReg, pv, cb);
     5770    Assert(cb == 4);
     5771    Assert(!(GCPhysAddr & 3));
     5772
     5773    int rc = e1kRegReadAlignedU32(pThis, offReg, (uint32_t *)pv);
     5774
    57555775    STAM_PROFILE_ADV_STOP(&pThis->CTX_SUFF_Z(StatMMIORead), a);
    57565776    return rc;
     
    57585778
    57595779/**
    5760  * Memory mapped I/O Handler for write operations.
    5761  *
    5762  * @returns VBox status code.
    5763  *
    5764  * @param   pDevIns     The device instance.
    5765  * @param   pvUser      User argument.
    5766  * @param   GCPhysAddr  Physical address (in GC) where the read starts.
    5767  * @param   pv          Where to fetch the value.
    5768  * @param   cb          Number of bytes to write.
    5769  * @thread  EMT
     5780 * @callback_method_impl{FNIOMMMIOWRITE}
    57705781 */
    57715782PDMBOTHCBDECL(int) e1kMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
     
    57735784    NOREF(pvUser);
    57745785    PE1KSTATE pThis  = PDMINS_2_DATA(pDevIns, PE1KSTATE);
    5775     uint32_t  offReg = GCPhysAddr - pThis->addrMMReg;
    5776     int       rc;
    57775786    STAM_PROFILE_ADV_START(&pThis->CTX_SUFF_Z(StatMMIOWrite), a);
    57785787
     5788    uint32_t offReg = GCPhysAddr - pThis->addrMMReg;
    57795789    Assert(offReg < E1K_MM_SIZE);
    5780     if (cb != 4)
    5781     {
    5782         E1kLog(("%s e1kMMIOWrite: invalid op size: offset=%#10x cb=%#10x", pDevIns, offReg, cb));
    5783         rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "e1kMMIOWrite: invalid op size: offset=%#10x cb=%#10x\n", offReg, cb);
    5784     }
    5785     else
    5786         rc = e1kRegWrite(pThis, offReg, pv, cb);
     5790    Assert(cb == 4);
     5791    Assert(!(GCPhysAddr & 3));
     5792
     5793    int rc = e1kRegWriteAlignedU32(pThis, offReg, *(uint32_t const *)pv);
    57875794
    57885795    STAM_PROFILE_ADV_STOP(&pThis->CTX_SUFF_Z(StatMMIOWrite), a);
     
    57915798
    57925799/**
    5793  * Port I/O Handler for IN operations.
    5794  *
    5795  * @returns VBox status code.
    5796  *
    5797  * @param   pDevIns     The device instance.
    5798  * @param   pvUser      Pointer to the device state structure.
    5799  * @param   port        Port number used for the IN operation.
    5800  * @param   pu32        Where to store the result.
    5801  * @param   cb          Number of bytes read.
    5802  * @thread  EMT
    5803  */
    5804 PDMBOTHCBDECL(int) e1kIOPortIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t *pu32, unsigned cb)
     5800 * @callback_method_impl{FNIOMIOPORTIN}
     5801 */
     5802PDMBOTHCBDECL(int) e1kIOPortIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb)
    58055803{
    58065804    PE1KSTATE   pThis = PDMINS_2_DATA(pDevIns, PE1KSTATE);
    5807     int         rc    = VINF_SUCCESS;
     5805    int         rc;
    58085806    STAM_PROFILE_ADV_START(&pThis->CTX_SUFF_Z(StatIORead), a);
    58095807
    5810     port -= pThis->addrIOPort;
    5811     if (cb != 4)
    5812     {
    5813         E1kLog(("%s e1kIOPortIn: invalid op size: port=%RTiop cb=%08x", pThis->szPrf, port, cb));
    5814         rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "%s e1kIOPortIn: invalid op size: port=%RTiop cb=%08x\n", pThis->szPrf, port, cb);
    5815     }
    5816     else
    5817         switch (port)
     5808    uPort -= pThis->addrIOPort;
     5809    if (RT_LIKELY(cb == 4))
     5810        switch (uPort)
    58185811        {
    58195812            case 0x00: /* IOADDR */
    58205813                *pu32 = pThis->uSelectedReg;
    58215814                E1kLog2(("%s e1kIOPortIn: IOADDR(0), selecting register %#010x, val=%#010x\n", pThis->szPrf, pThis->uSelectedReg, *pu32));
     5815                rc = VINF_SUCCESS;
    58225816                break;
     5817
    58235818            case 0x04: /* IODATA */
    5824                 rc = e1kRegRead(pThis, pThis->uSelectedReg, pu32, cb);
    5825                 /** @todo wrong return code triggers assertions in the debug build; fix please */
     5819                if (!(pThis->uSelectedReg & 3))
     5820                    rc = e1kRegReadAlignedU32(pThis, pThis->uSelectedReg, pu32);
     5821                else /** @todo r=bird: I wouldn't be surprised if this unaligned branch wasn't necessary. */
     5822                    rc = e1kRegReadUnaligned(pThis, pThis->uSelectedReg, pu32, cb);
    58265823                if (rc == VINF_IOM_R3_MMIO_READ)
    58275824                    rc = VINF_IOM_R3_IOPORT_READ;
    5828 
    58295825                E1kLog2(("%s e1kIOPortIn: IODATA(4), reading from selected register %#010x, val=%#010x\n", pThis->szPrf, pThis->uSelectedReg, *pu32));
    58305826                break;
     5827
    58315828            default:
    5832                 E1kLog(("%s e1kIOPortIn: invalid port %#010x\n", pThis->szPrf, port));
    5833         //*pRC = VERR_IOM_IOPORT_UNUSED;
    5834         }
    5835 
     5829                E1kLog(("%s e1kIOPortIn: invalid port %#010x\n", pThis->szPrf, uPort));
     5830                //rc = VERR_IOM_IOPORT_UNUSED; /* Why not? */
     5831                rc = VINF_SUCCESS;
     5832        }
     5833    else
     5834    {
     5835        E1kLog(("%s e1kIOPortIn: invalid op size: uPort=%RTiop cb=%08x", pThis->szPrf, uPort, cb));
     5836        rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "%s e1kIOPortIn: invalid op size: uPort=%RTiop cb=%08x\n", pThis->szPrf, uPort, cb);
     5837    }
    58365838    STAM_PROFILE_ADV_STOP(&pThis->CTX_SUFF_Z(StatIORead), a);
    58375839    return rc;
     
    58405842
    58415843/**
    5842  * Port I/O Handler for OUT operations.
    5843  *
    5844  * @returns VBox status code.
    5845  *
    5846  * @param   pDevIns     The device instance.
    5847  * @param   pvUser      User argument.
    5848  * @param   Port        Port number used for the IN operation.
    5849  * @param   u32         The value to output.
    5850  * @param   cb          The value size in bytes.
    5851  * @thread  EMT
    5852  */
    5853 PDMBOTHCBDECL(int) e1kIOPortOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT port, uint32_t u32, unsigned cb)
     5844 * @callback_method_impl{FNIOMIOPORTOUT}
     5845 */
     5846PDMBOTHCBDECL(int) e1kIOPortOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb)
    58545847{
    58555848    PE1KSTATE   pThis = PDMINS_2_DATA(pDevIns, PE1KSTATE);
    5856     int         rc    = VINF_SUCCESS;
     5849    int         rc;
    58575850    STAM_PROFILE_ADV_START(&pThis->CTX_SUFF_Z(StatIOWrite), a);
    58585851
    5859     E1kLog2(("%s e1kIOPortOut: port=%RTiop value=%08x\n", pThis->szPrf, port, u32));
    5860     if (cb != 4)
    5861     {
    5862         E1kLog(("%s e1kIOPortOut: invalid op size: port=%RTiop cb=%08x\n", pThis->szPrf, port, cb));
    5863         rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "invalid op size: port=%RTiop cb=%#x\n", pThis->szPrf, port, cb);
    5864     }
    5865     else
    5866     {
    5867         port -= pThis->addrIOPort;
    5868         switch (port)
     5852    E1kLog2(("%s e1kIOPortOut: uPort=%RTiop value=%08x\n", pThis->szPrf, uPort, u32));
     5853    if (RT_LIKELY(cb == 4))
     5854    {
     5855        uPort -= pThis->addrIOPort;
     5856        switch (uPort)
    58695857        {
    58705858            case 0x00: /* IOADDR */
    58715859                pThis->uSelectedReg = u32;
    58725860                E1kLog2(("%s e1kIOPortOut: IOADDR(0), selected register %08x\n", pThis->szPrf, pThis->uSelectedReg));
     5861                rc = VINF_SUCCESS;
    58735862                break;
     5863
    58745864            case 0x04: /* IODATA */
    58755865                E1kLog2(("%s e1kIOPortOut: IODATA(4), writing to selected register %#010x, value=%#010x\n", pThis->szPrf, pThis->uSelectedReg, u32));
    5876                 rc = e1kRegWrite(pThis, pThis->uSelectedReg, &u32, cb);
    5877                 /** @todo wrong return code triggers assertions in the debug build; fix please */
    5878                 if (rc == VINF_IOM_R3_MMIO_WRITE)
    5879                     rc = VINF_IOM_R3_IOPORT_WRITE;
     5866                if (RT_LIKELY(!(pThis->uSelectedReg & 3)))
     5867                {
     5868                    rc = e1kRegWriteAlignedU32(pThis, pThis->uSelectedReg, u32);
     5869                    if (rc == VINF_IOM_R3_MMIO_WRITE)
     5870                        rc = VINF_IOM_R3_IOPORT_WRITE;
     5871                }
     5872                else
     5873                    rc = PDMDevHlpDBGFStop(pThis->CTX_SUFF(pDevIns), RT_SRC_POS,
     5874                                           "Spec violation: misaligned offset: %#10x, ignored.\n", pThis->uSelectedReg);
    58805875                break;
     5876
    58815877            default:
    5882                 E1kLog(("%s e1kIOPortOut: invalid port %#010x\n", pThis->szPrf, port));
    5883                 /** @todo Do we need to return an error here?
    5884                  * bird: VINF_SUCCESS is fine for unhandled cases of an OUT handler. (If you're curious
    5885                  *       about the guest code and a bit adventuresome, try rc = PDMDeviceDBGFStop(...);) */
    5886                 rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "invalid port %#010x\n", port);
    5887         }
     5878                E1kLog(("%s e1kIOPortOut: invalid port %#010x\n", pThis->szPrf, uPort));
     5879                rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "invalid port %#010x\n", uPort);
     5880        }
     5881    }
     5882    else
     5883    {
     5884        E1kLog(("%s e1kIOPortOut: invalid op size: uPort=%RTiop cb=%08x\n", pThis->szPrf, uPort, cb));
     5885        rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "invalid op size: uPort=%RTiop cb=%#x\n", pThis->szPrf, uPort, cb);
    58885886    }
    58895887
     
    59545952static DECLCALLBACK(int) e1kMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
    59555953{
     5954    PE1KSTATE pThis = PDMINS_2_DATA(pPciDev->pDevIns, E1KSTATE*);
    59565955    int       rc;
    5957     PE1KSTATE pThis = PDMINS_2_DATA(pPciDev->pDevIns, E1KSTATE*);
    59585956
    59595957    switch (enmType)
     
    59615959        case PCI_ADDRESS_SPACE_IO:
    59625960            pThis->addrIOPort = (RTIOPORT)GCPhysAddress;
    5963             rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, pThis->addrIOPort, cb, 0,
     5961            rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns, pThis->addrIOPort, cb, NULL /*pvUser*/,
    59645962                                         e1kIOPortOut, e1kIOPortIn, NULL, NULL, "E1000");
    5965             if (RT_FAILURE(rc))
    5966                 break;
    5967             if (pThis->fR0Enabled)
    5968             {
    5969                 rc = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, pThis->addrIOPort, cb, 0,
     5963            if (pThis->fR0Enabled && RT_SUCCESS(rc))
     5964                rc = PDMDevHlpIOPortRegisterR0(pPciDev->pDevIns, pThis->addrIOPort, cb, NIL_RTR0PTR /*pvUser*/,
    59705965                                             "e1kIOPortOut", "e1kIOPortIn", NULL, NULL, "E1000");
    5971                 if (RT_FAILURE(rc))
    5972                     break;
    5973             }
    5974             if (pThis->fGCEnabled)
    5975             {
    5976                 rc = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, pThis->addrIOPort, cb, 0,
     5966            if (pThis->fGCEnabled && RT_SUCCESS(rc))
     5967                rc = PDMDevHlpIOPortRegisterRC(pPciDev->pDevIns, pThis->addrIOPort, cb, NIL_RTRCPTR /*pvUser*/,
    59775968                                               "e1kIOPortOut", "e1kIOPortIn", NULL, NULL, "E1000");
    5978             }
    59795969            break;
     5970
    59805971        case PCI_ADDRESS_SPACE_MEM:
    5981             pThis->addrMMReg = GCPhysAddress;
     5972            /*
     5973             * From the spec:
     5974             *    For registers that should be accessed as 32-bit double words,
     5975             *    partial writes (less than a 32-bit double word) is ignored.
     5976             *    Partial reads return all 32 bits of data regardless of the
     5977             *    byte enables.
     5978             */
     5979            pThis->addrMMReg = GCPhysAddress; Assert(!(GCPhysAddress & 7));
    59825980            rc = PDMDevHlpMMIORegister(pPciDev->pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    5983                                        IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
     5981                                       IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD,
    59845982                                       e1kMMIOWrite, e1kMMIORead, "E1000");
    5985             if (pThis->fR0Enabled)
    5986             {
     5983            if (pThis->fR0Enabled && RT_SUCCESS(rc))
    59875984                rc = PDMDevHlpMMIORegisterR0(pPciDev->pDevIns, GCPhysAddress, cb, NIL_RTR0PTR /*pvUser*/,
    59885985                                             "e1kMMIOWrite", "e1kMMIORead");
    5989                 if (RT_FAILURE(rc))
    5990                     break;
    5991             }
    5992             if (pThis->fGCEnabled)
    5993             {
     5986            if (pThis->fGCEnabled && RT_SUCCESS(rc))
    59945987                rc = PDMDevHlpMMIORegisterRC(pPciDev->pDevIns, GCPhysAddress, cb, NIL_RTRCPTR /*pvUser*/,
    59955988                                             "e1kMMIOWrite", "e1kMMIORead");
    5996             }
    59975989            break;
     5990
    59985991        default:
    59995992            /* We should never get here */
     
    74397432            pThis->fGSOEnabled ? "enabled" : "disabled"));
    74407433
    7441     /* Initialize the EEPROM */
     7434    /* Initialize the EEPROM. */
    74427435    pThis->eeprom.init(pThis->macConfigured);
    74437436
    7444     /* Initialize internal PHY */
     7437    /* Initialize internal PHY. */
    74457438    Phy::init(&pThis->phy, iInstance, pThis->eChip == E1K_CHIP_82543GC ? PHY_EPID_M881000 : PHY_EPID_M881011);
    74467439    Phy::setLinkStatus(&pThis->phy, pThis->fCableConnected);
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