X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=dev%2Fns_gige.cc;h=9010850ab8a67cc1e09c497d768cbf1540cc0022;hb=1166d4f0bfe67a9dc178be3454b4f0eac38663ad;hp=47cd4d7da15cf2c2817918d16cc1311de9669e02;hpb=6e17280ce4a7491a82ff7c0911902a67c14732fb;p=gem5.git diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 47cd4d7da..9010850ab 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -109,13 +109,14 @@ NSGigE::NSGigE(Params *p) physmem(p->pmem), intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0) { - if (p->header_bus) { + if (p->pio_bus) { pioInterface = newPioInterface(name() + ".pio", p->hier, - p->header_bus, this, + p->pio_bus, this, &NSGigE::cacheAccess); + pioLatency = p->pio_latency * p->pio_bus->clockRate; + } - pioLatency = p->pio_latency * p->header_bus->clockRate; - + if (p->header_bus) { if (p->payload_bus) dmaInterface = new DMAInterface(name() + ".dma", p->header_bus, @@ -126,19 +127,10 @@ NSGigE::NSGigE(Params *p) p->header_bus, p->header_bus, 1, p->dma_no_allocate); - } else if (p->payload_bus) { - pioInterface = newPioInterface(name() + ".pio2", p->hier, - p->payload_bus, this, - &NSGigE::cacheAccess); - - pioLatency = p->pio_latency * p->payload_bus->clockRate; - - dmaInterface = new DMAInterface(name() + ".dma", - p->payload_bus, - p->payload_bus, 1, - p->dma_no_allocate); - } + } else if (p->payload_bus) + panic("Must define a header bus if defining a payload bus"); + pioDelayWrite = p->pio_delay_write && pioInterface; intrDelay = p->intr_delay; dmaReadDelay = p->dma_read_delay; @@ -148,6 +140,11 @@ NSGigE::NSGigE(Params *p) regsReset(); memcpy(&rom.perfectMatch, p->eaddr.bytes(), ETH_ADDR_LEN); + + memset(&rxDesc32, 0, sizeof(rxDesc32)); + memset(&txDesc32, 0, sizeof(txDesc32)); + memset(&rxDesc64, 0, sizeof(rxDesc64)); + memset(&txDesc64, 0, sizeof(txDesc64)); } NSGigE::~NSGigE() @@ -310,7 +307,7 @@ NSGigE::regStats() totalSwi .name(name() + ".totalSwi") - .desc("number of total Swi written to ISR") + .desc("total number of Swi written to ISR") .precision(0) ; @@ -328,7 +325,7 @@ NSGigE::regStats() totalRxIdle .name(name() + ".totalRxIdle") - .desc("number of total RxIdle written to ISR") + .desc("total number of RxIdle written to ISR") .precision(0) ; @@ -346,7 +343,7 @@ NSGigE::regStats() totalRxOk .name(name() + ".totalRxOk") - .desc("number of total RxOk written to ISR") + .desc("total number of RxOk written to ISR") .precision(0) ; @@ -364,7 +361,7 @@ NSGigE::regStats() totalRxDesc .name(name() + ".totalRxDesc") - .desc("number of total RxDesc written to ISR") + .desc("total number of RxDesc written to ISR") .precision(0) ; @@ -382,7 +379,7 @@ NSGigE::regStats() totalTxOk .name(name() + ".totalTxOk") - .desc("number of total TxOk written to ISR") + .desc("total number of TxOk written to ISR") .precision(0) ; @@ -400,7 +397,7 @@ NSGigE::regStats() totalTxIdle .name(name() + ".totalTxIdle") - .desc("number of total TxIdle written to ISR") + .desc("total number of TxIdle written to ISR") .precision(0) ; @@ -418,7 +415,7 @@ NSGigE::regStats() totalTxDesc .name(name() + ".totalTxDesc") - .desc("number of total TxDesc written to ISR") + .desc("total number of TxDesc written to ISR") .precision(0) ; @@ -436,7 +433,7 @@ NSGigE::regStats() totalRxOrn .name(name() + ".totalRxOrn") - .desc("number of total RxOrn written to ISR") + .desc("total number of RxOrn written to ISR") .precision(0) ; @@ -766,7 +763,11 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) break; case M5REG: - reg = params()->m5reg; + reg = 0; + if (params()->rx_thread) + reg |= M5REG_RX_THREAD; + if (params()->tx_thread) + reg |= M5REG_TX_THREAD; break; default: @@ -803,6 +804,13 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) } else if (daddr > 0x3FC) panic("Something is messed up!\n"); + if (pioDelayWrite) { + int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; + if (cpu >= writeQueue.size()) + writeQueue.resize(cpu + 1); + writeQueue[cpu].push_back(RegWriteData(daddr, *(uint32_t *)data)); + } + if (req->size == sizeof(uint32_t)) { uint32_t reg = *(uint32_t *)data; uint16_t rfaddr; @@ -815,20 +823,24 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) if (reg & CR_TXD) { txEnable = false; } else if (reg & CR_TXE) { - txEnable = true; + if (!pioDelayWrite) { + txEnable = true; - // the kernel is enabling the transmit machine - if (txState == txIdle) - txKick(); + // the kernel is enabling the transmit machine + if (txState == txIdle) + txKick(); + } } if (reg & CR_RXD) { rxEnable = false; } else if (reg & CR_RXE) { - rxEnable = true; + if (!pioDelayWrite) { + rxEnable = true; - if (rxState == rxIdle) - rxKick(); + if (rxState == rxIdle) + rxKick(); + } } if (reg & CR_TXR) @@ -868,15 +880,12 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) // all these #if 0's are because i don't THINK the kernel needs to // have these implemented. if there is a problem relating to one of // these, you may need to add functionality in. -#if 0 if (reg & CFGR_TBI_EN) ; if (reg & CFGR_MODE_1000) ; -#endif if (reg & CFGR_AUTO_1000) panic("CFGR_AUTO_1000 not implemented!\n"); -#if 0 if (reg & CFGR_PINT_DUPSTS || reg & CFGR_PINT_LNKSTS || reg & CFGR_PINT_SPDSTS) @@ -886,8 +895,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) if (reg & CFGR_MRM_DIS) ; if (reg & CFGR_MWI_DIS) ; - if (reg & CFGR_T64ADDR) - panic("CFGR_T64ADDR is read only register!\n"); + if (reg & CFGR_T64ADDR) ; + // panic("CFGR_T64ADDR is read only register!\n"); if (reg & CFGR_PCI64_DET) panic("CFGR_PCI64_DET is read only register!\n"); @@ -896,23 +905,20 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) if (reg & CFGR_M64ADDR) ; if (reg & CFGR_PHY_RST) ; if (reg & CFGR_PHY_DIS) ; -#endif if (reg & CFGR_EXTSTS_EN) extstsEnable = true; else extstsEnable = false; -#if 0 - if (reg & CFGR_REQALG) ; - if (reg & CFGR_SB) ; - if (reg & CFGR_POW) ; - if (reg & CFGR_EXD) ; - if (reg & CFGR_PESEL) ; - if (reg & CFGR_BROM_DIS) ; - if (reg & CFGR_EXT_125) ; - if (reg & CFGR_BEM) ; -#endif + if (reg & CFGR_REQALG) ; + if (reg & CFGR_SB) ; + if (reg & CFGR_POW) ; + if (reg & CFGR_EXD) ; + if (reg & CFGR_PESEL) ; + if (reg & CFGR_BROM_DIS) ; + if (reg & CFGR_EXT_125) ; + if (reg & CFGR_BEM) ; break; case MEAR: @@ -936,11 +942,9 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) eepromClk = reg & MEAR_EECLK; // since phy is completely faked, MEAR_MD* don't matter -#if 0 if (reg & MEAR_MDIO) ; if (reg & MEAR_MDDIR) ; if (reg & MEAR_MDC) ; -#endif break; case PTSCR: @@ -1556,8 +1560,15 @@ NSGigE::rxDmaWriteDone() void NSGigE::rxKick() { - DPRINTF(EthernetSM, "receive kick rxState=%s (rxBuf.size=%d)\n", - NsRxStateStrings[rxState], rxFifo.size()); + bool is64bit = (bool)(regs.config & CFGR_M64ADDR); + + DPRINTF(EthernetSM, + "receive kick rxState=%s (rxBuf.size=%d) %d-bit\n", + NsRxStateStrings[rxState], rxFifo.size(), is64bit ? 64 : 32); + + Addr link, bufptr; + uint32_t &cmdsts = is64bit ? rxDesc64.cmdsts : rxDesc32.cmdsts; + uint32_t &extsts = is64bit ? rxDesc64.extsts : rxDesc32.extsts; next: if (clock) { @@ -1585,6 +1596,9 @@ NSGigE::rxKick() break; } + link = is64bit ? (Addr)rxDesc64.link : (Addr)rxDesc32.link; + bufptr = is64bit ? (Addr)rxDesc64.bufptr : (Addr)rxDesc32.bufptr; + // see state machine from spec for details // the way this works is, if you finish work on one state and can // go directly to another, you do that through jumping to the @@ -1603,8 +1617,9 @@ NSGigE::rxKick() rxState = rxDescRefr; rxDmaAddr = regs.rxdp & 0x3fffffff; - rxDmaData = &rxDescCache + offsetof(ns_desc, link); - rxDmaLen = sizeof(rxDescCache.link); + rxDmaData = + is64bit ? (void *)&rxDesc64.link : (void *)&rxDesc32.link; + rxDmaLen = is64bit ? sizeof(rxDesc64.link) : sizeof(rxDesc32.link); rxDmaFree = dmaDescFree; descDmaReads++; @@ -1616,8 +1631,8 @@ NSGigE::rxKick() rxState = rxDescRead; rxDmaAddr = regs.rxdp & 0x3fffffff; - rxDmaData = &rxDescCache; - rxDmaLen = sizeof(ns_desc); + rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32; + rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32); rxDmaFree = dmaDescFree; descDmaReads++; @@ -1639,21 +1654,20 @@ NSGigE::rxKick() if (rxDmaState != dmaIdle) goto exit; - DPRINTF(EthernetDesc, "rxDescCache: addr=%08x read descriptor\n", + DPRINTF(EthernetDesc, "rxDesc: addr=%08x read descriptor\n", regs.rxdp & 0x3fffffff); DPRINTF(EthernetDesc, - "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n", - rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts, - rxDescCache.extsts); + "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n", + link, bufptr, cmdsts, extsts); - if (rxDescCache.cmdsts & CMDSTS_OWN) { + if (cmdsts & CMDSTS_OWN) { devIntrPost(ISR_RXIDLE); rxState = rxIdle; goto exit; } else { rxState = rxFifoBlock; - rxFragPtr = rxDescCache.bufptr; - rxDescCnt = rxDescCache.cmdsts & CMDSTS_LEN_MASK; + rxFragPtr = bufptr; + rxDescCnt = cmdsts & CMDSTS_LEN_MASK; } break; @@ -1719,11 +1733,11 @@ NSGigE::rxKick() assert(rxPktBytes == 0); DPRINTF(EthernetSM, "done with receiving packet\n"); - rxDescCache.cmdsts |= CMDSTS_OWN; - rxDescCache.cmdsts &= ~CMDSTS_MORE; - rxDescCache.cmdsts |= CMDSTS_OK; - rxDescCache.cmdsts &= 0xffff0000; - rxDescCache.cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE + cmdsts |= CMDSTS_OWN; + cmdsts &= ~CMDSTS_MORE; + cmdsts |= CMDSTS_OK; + cmdsts &= 0xffff0000; + cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE #if 0 /* @@ -1734,41 +1748,41 @@ NSGigE::rxKick() * functional purposes, just undef */ if (rxFilterEnable) { - rxDescCache.cmdsts &= ~CMDSTS_DEST_MASK; + cmdsts &= ~CMDSTS_DEST_MASK; const EthAddr &dst = rxFifoFront()->dst(); if (dst->unicast()) - rxDescCache.cmdsts |= CMDSTS_DEST_SELF; + cmdsts |= CMDSTS_DEST_SELF; if (dst->multicast()) - rxDescCache.cmdsts |= CMDSTS_DEST_MULTI; + cmdsts |= CMDSTS_DEST_MULTI; if (dst->broadcast()) - rxDescCache.cmdsts |= CMDSTS_DEST_MASK; + cmdsts |= CMDSTS_DEST_MASK; } #endif IpPtr ip(rxPacket); if (extstsEnable && ip) { - rxDescCache.extsts |= EXTSTS_IPPKT; + extsts |= EXTSTS_IPPKT; rxIpChecksums++; if (cksum(ip) != 0) { DPRINTF(EthernetCksum, "Rx IP Checksum Error\n"); - rxDescCache.extsts |= EXTSTS_IPERR; + extsts |= EXTSTS_IPERR; } TcpPtr tcp(ip); UdpPtr udp(ip); if (tcp) { - rxDescCache.extsts |= EXTSTS_TCPPKT; + extsts |= EXTSTS_TCPPKT; rxTcpChecksums++; if (cksum(tcp) != 0) { DPRINTF(EthernetCksum, "Rx TCP Checksum Error\n"); - rxDescCache.extsts |= EXTSTS_TCPERR; + extsts |= EXTSTS_TCPERR; } } else if (udp) { - rxDescCache.extsts |= EXTSTS_UDPPKT; + extsts |= EXTSTS_UDPPKT; rxUdpChecksums++; if (cksum(udp) != 0) { DPRINTF(EthernetCksum, "Rx UDP Checksum Error\n"); - rxDescCache.extsts |= EXTSTS_UDPERR; + extsts |= EXTSTS_UDPERR; } } } @@ -1782,16 +1796,21 @@ NSGigE::rxKick() */ DPRINTF(EthernetDesc, - "rxDescCache: addr=%08x writeback cmdsts extsts\n", + "rxDesc: addr=%08x writeback cmdsts extsts\n", regs.rxdp & 0x3fffffff); DPRINTF(EthernetDesc, - "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n", - rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts, - rxDescCache.extsts); + "rxDesc: link=%#x bufptr=%#x cmdsts=%08x extsts=%08x\n", + link, bufptr, cmdsts, extsts); - rxDmaAddr = (regs.rxdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; - rxDmaData = &(rxDescCache.cmdsts); - rxDmaLen = sizeof(rxDescCache.cmdsts) + sizeof(rxDescCache.extsts); + rxDmaAddr = regs.rxdp & 0x3fffffff; + rxDmaData = &cmdsts; + if (is64bit) { + rxDmaAddr += offsetof(ns_desc64, cmdsts); + rxDmaLen = sizeof(rxDesc64.cmdsts) + sizeof(rxDesc64.extsts); + } else { + rxDmaAddr += offsetof(ns_desc32, cmdsts); + rxDmaLen = sizeof(rxDesc32.cmdsts) + sizeof(rxDesc32.extsts); + } rxDmaFree = dmaDescFree; descDmaWrites++; @@ -1817,12 +1836,12 @@ NSGigE::rxKick() if (rxDmaState != dmaIdle) goto exit; - assert(rxDescCache.cmdsts & CMDSTS_OWN); + assert(cmdsts & CMDSTS_OWN); assert(rxPacket == 0); devIntrPost(ISR_RXOK); - if (rxDescCache.cmdsts & CMDSTS_INTR) + if (cmdsts & CMDSTS_INTR) devIntrPost(ISR_RXDESC); if (!rxEnable) { @@ -1834,7 +1853,7 @@ NSGigE::rxKick() break; case rxAdvance: - if (rxDescCache.link == 0) { + if (link == 0) { devIntrPost(ISR_RXIDLE); rxState = rxIdle; CRDD = true; @@ -1843,12 +1862,12 @@ NSGigE::rxKick() if (rxDmaState != dmaIdle) goto exit; rxState = rxDescRead; - regs.rxdp = rxDescCache.link; + regs.rxdp = link; CRDD = false; rxDmaAddr = regs.rxdp & 0x3fffffff; - rxDmaData = &rxDescCache; - rxDmaLen = sizeof(ns_desc); + rxDmaData = is64bit ? (void *)&rxDesc64 : (void *)&rxDesc32; + rxDmaLen = is64bit ? sizeof(rxDesc64) : sizeof(rxDesc32); rxDmaFree = dmaDescFree; if (doRxDmaRead()) @@ -1895,7 +1914,8 @@ NSGigE::transmit() if (tcp) { DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n", - tcp->sport(), tcp->dport(), tcp->seq(), tcp->ack()); + tcp->sport(), tcp->dport(), tcp->seq(), + tcp->ack()); } } } @@ -2032,8 +2052,14 @@ NSGigE::txDmaWriteDone() void NSGigE::txKick() { - DPRINTF(EthernetSM, "transmit kick txState=%s\n", - NsTxStateStrings[txState]); + bool is64bit = (bool)(regs.config & CFGR_M64ADDR); + + DPRINTF(EthernetSM, "transmit kick txState=%s %d-bit\n", + NsTxStateStrings[txState], is64bit ? 64 : 32); + + Addr link, bufptr; + uint32_t &cmdsts = is64bit ? txDesc64.cmdsts : txDesc32.cmdsts; + uint32_t &extsts = is64bit ? txDesc64.extsts : txDesc32.extsts; next: if (clock) { @@ -2060,6 +2086,8 @@ NSGigE::txKick() break; } + link = is64bit ? (Addr)txDesc64.link : (Addr)txDesc32.link; + bufptr = is64bit ? (Addr)txDesc64.bufptr : (Addr)txDesc32.bufptr; switch (txState) { case txIdle: if (!txEnable) { @@ -2071,8 +2099,9 @@ NSGigE::txKick() txState = txDescRefr; txDmaAddr = regs.txdp & 0x3fffffff; - txDmaData = &txDescCache + offsetof(ns_desc, link); - txDmaLen = sizeof(txDescCache.link); + txDmaData = + is64bit ? (void *)&txDesc64.link : (void *)&txDesc32.link; + txDmaLen = is64bit ? sizeof(txDesc64.link) : sizeof(txDesc32.link); txDmaFree = dmaDescFree; descDmaReads++; @@ -2085,8 +2114,8 @@ NSGigE::txKick() txState = txDescRead; txDmaAddr = regs.txdp & 0x3fffffff; - txDmaData = &txDescCache; - txDmaLen = sizeof(ns_desc); + txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32; + txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32); txDmaFree = dmaDescFree; descDmaReads++; @@ -2108,17 +2137,16 @@ NSGigE::txKick() if (txDmaState != dmaIdle) goto exit; - DPRINTF(EthernetDesc, "txDescCache: addr=%08x read descriptor\n", + DPRINTF(EthernetDesc, "txDesc: addr=%08x read descriptor\n", regs.txdp & 0x3fffffff); DPRINTF(EthernetDesc, - "txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n", - txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts, - txDescCache.extsts); + "txDesc: link=%#x bufptr=%#x cmdsts=%#08x extsts=%#08x\n", + link, bufptr, cmdsts, extsts); - if (txDescCache.cmdsts & CMDSTS_OWN) { + if (cmdsts & CMDSTS_OWN) { txState = txFifoBlock; - txFragPtr = txDescCache.bufptr; - txDescCnt = txDescCache.cmdsts & CMDSTS_LEN_MASK; + txFragPtr = bufptr; + txDescCnt = cmdsts & CMDSTS_LEN_MASK; } else { devIntrPost(ISR_TXIDLE); txState = txIdle; @@ -2135,16 +2163,21 @@ NSGigE::txKick() if (txDescCnt == 0) { DPRINTF(EthernetSM, "the txDescCnt == 0, done with descriptor\n"); - if (txDescCache.cmdsts & CMDSTS_MORE) { + if (cmdsts & CMDSTS_MORE) { DPRINTF(EthernetSM, "there are more descriptors to come\n"); txState = txDescWrite; - txDescCache.cmdsts &= ~CMDSTS_OWN; + cmdsts &= ~CMDSTS_OWN; - txDmaAddr = regs.txdp + offsetof(ns_desc, cmdsts); - txDmaAddr &= 0x3fffffff; - txDmaData = &(txDescCache.cmdsts); - txDmaLen = sizeof(txDescCache.cmdsts); + txDmaAddr = regs.txdp & 0x3fffffff; + txDmaData = &cmdsts; + if (is64bit) { + txDmaAddr += offsetof(ns_desc64, cmdsts); + txDmaLen = sizeof(txDesc64.cmdsts); + } else { + txDmaAddr += offsetof(ns_desc32, cmdsts); + txDmaLen = sizeof(txDesc32.cmdsts); + } txDmaFree = dmaDescFree; if (doTxDmaWrite()) @@ -2155,18 +2188,18 @@ NSGigE::txKick() /* deal with the the packet that just finished */ if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) { IpPtr ip(txPacket); - if (txDescCache.extsts & EXTSTS_UDPPKT) { + if (extsts & EXTSTS_UDPPKT) { UdpPtr udp(ip); udp->sum(0); udp->sum(cksum(udp)); txUdpChecksums++; - } else if (txDescCache.extsts & EXTSTS_TCPPKT) { + } else if (extsts & EXTSTS_TCPPKT) { TcpPtr tcp(ip); tcp->sum(0); tcp->sum(cksum(tcp)); txTcpChecksums++; } - if (txDescCache.extsts & EXTSTS_IPPKT) { + if (extsts & EXTSTS_IPPKT) { ip->sum(0); ip->sum(cksum(ip)); txIpChecksums++; @@ -2176,7 +2209,10 @@ NSGigE::txKick() txPacket->length = txPacketBufPtr - txPacket->data; // this is just because the receive can't handle a // packet bigger want to make sure - assert(txPacket->length <= 1514); + if (txPacket->length > 1514) + panic("transmit packet too large, %s > 1514\n", + txPacket->length); + #ifndef NDEBUG bool success = #endif @@ -2195,19 +2231,25 @@ NSGigE::txKick() * spec would complicate the code, we just do it here */ - txDescCache.cmdsts &= ~CMDSTS_OWN; - txDescCache.cmdsts |= CMDSTS_OK; + cmdsts &= ~CMDSTS_OWN; + cmdsts |= CMDSTS_OK; DPRINTF(EthernetDesc, "txDesc writeback: cmdsts=%08x extsts=%08x\n", - txDescCache.cmdsts, txDescCache.extsts); + cmdsts, extsts); - txDmaAddr = regs.txdp + offsetof(ns_desc, cmdsts); - txDmaAddr &= 0x3fffffff; - txDmaData = &(txDescCache.cmdsts); - txDmaLen = sizeof(txDescCache.cmdsts) + - sizeof(txDescCache.extsts); txDmaFree = dmaDescFree; + txDmaAddr = regs.txdp & 0x3fffffff; + txDmaData = &cmdsts; + if (is64bit) { + txDmaAddr += offsetof(ns_desc64, cmdsts); + txDmaLen = + sizeof(txDesc64.cmdsts) + sizeof(txDesc64.extsts); + } else { + txDmaAddr += offsetof(ns_desc32, cmdsts); + txDmaLen = + sizeof(txDesc32.cmdsts) + sizeof(txDesc32.extsts); + } descDmaWrites++; descDmaWrBytes += txDmaLen; @@ -2271,7 +2313,7 @@ NSGigE::txKick() if (txDmaState != dmaIdle) goto exit; - if (txDescCache.cmdsts & CMDSTS_INTR) + if (cmdsts & CMDSTS_INTR) devIntrPost(ISR_TXDESC); if (!txEnable) { @@ -2283,7 +2325,7 @@ NSGigE::txKick() break; case txAdvance: - if (txDescCache.link == 0) { + if (link == 0) { devIntrPost(ISR_TXIDLE); txState = txIdle; goto exit; @@ -2291,12 +2333,12 @@ NSGigE::txKick() if (txDmaState != dmaIdle) goto exit; txState = txDescRead; - regs.txdp = txDescCache.link; + regs.txdp = link; CTDD = false; - txDmaAddr = txDescCache.link & 0x3fffffff; - txDmaData = &txDescCache; - txDmaLen = sizeof(ns_desc); + txDmaAddr = link & 0x3fffffff; + txDmaData = is64bit ? (void *)&txDesc64 : (void *)&txDesc32; + txDmaLen = is64bit ? sizeof(txDesc64) : sizeof(txDesc32); txDmaFree = dmaDescFree; if (doTxDmaRead()) @@ -2494,20 +2536,17 @@ NSGigE::recvPacket(PacketPtr packet) if (!rxEnable) { DPRINTF(Ethernet, "receive disabled...packet dropped\n"); - interface->recvDone(); return true; } if (!rxFilterEnable) { DPRINTF(Ethernet, "receive packet filtering disabled . . . packet dropped\n"); - interface->recvDone(); return true; } if (rxFilter(packet)) { DPRINTF(Ethernet, "packet filtered...dropped\n"); - interface->recvDone(); return true; } @@ -2530,7 +2569,6 @@ NSGigE::recvPacket(PacketPtr packet) } rxFifo.push(packet); - interface->recvDone(); rxKick(); return true; @@ -2630,16 +2668,24 @@ NSGigE::serialize(ostream &os) SERIALIZE_SCALAR(rxXferLen); /* - * Serialize DescCaches + * Serialize Cached Descriptors */ - SERIALIZE_SCALAR(txDescCache.link); - SERIALIZE_SCALAR(txDescCache.bufptr); - SERIALIZE_SCALAR(txDescCache.cmdsts); - SERIALIZE_SCALAR(txDescCache.extsts); - SERIALIZE_SCALAR(rxDescCache.link); - SERIALIZE_SCALAR(rxDescCache.bufptr); - SERIALIZE_SCALAR(rxDescCache.cmdsts); - SERIALIZE_SCALAR(rxDescCache.extsts); + SERIALIZE_SCALAR(rxDesc64.link); + SERIALIZE_SCALAR(rxDesc64.bufptr); + SERIALIZE_SCALAR(rxDesc64.cmdsts); + SERIALIZE_SCALAR(rxDesc64.extsts); + SERIALIZE_SCALAR(txDesc64.link); + SERIALIZE_SCALAR(txDesc64.bufptr); + SERIALIZE_SCALAR(txDesc64.cmdsts); + SERIALIZE_SCALAR(txDesc64.extsts); + SERIALIZE_SCALAR(rxDesc32.link); + SERIALIZE_SCALAR(rxDesc32.bufptr); + SERIALIZE_SCALAR(rxDesc32.cmdsts); + SERIALIZE_SCALAR(rxDesc32.extsts); + SERIALIZE_SCALAR(txDesc32.link); + SERIALIZE_SCALAR(txDesc32.bufptr); + SERIALIZE_SCALAR(txDesc32.cmdsts); + SERIALIZE_SCALAR(txDesc32.extsts); SERIALIZE_SCALAR(extstsEnable); /* @@ -2792,16 +2838,24 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxXferLen); /* - * Unserialize DescCaches + * Unserialize Cached Descriptors */ - UNSERIALIZE_SCALAR(txDescCache.link); - UNSERIALIZE_SCALAR(txDescCache.bufptr); - UNSERIALIZE_SCALAR(txDescCache.cmdsts); - UNSERIALIZE_SCALAR(txDescCache.extsts); - UNSERIALIZE_SCALAR(rxDescCache.link); - UNSERIALIZE_SCALAR(rxDescCache.bufptr); - UNSERIALIZE_SCALAR(rxDescCache.cmdsts); - UNSERIALIZE_SCALAR(rxDescCache.extsts); + UNSERIALIZE_SCALAR(rxDesc64.link); + UNSERIALIZE_SCALAR(rxDesc64.bufptr); + UNSERIALIZE_SCALAR(rxDesc64.cmdsts); + UNSERIALIZE_SCALAR(rxDesc64.extsts); + UNSERIALIZE_SCALAR(txDesc64.link); + UNSERIALIZE_SCALAR(txDesc64.bufptr); + UNSERIALIZE_SCALAR(txDesc64.cmdsts); + UNSERIALIZE_SCALAR(txDesc64.extsts); + UNSERIALIZE_SCALAR(rxDesc32.link); + UNSERIALIZE_SCALAR(rxDesc32.bufptr); + UNSERIALIZE_SCALAR(rxDesc32.cmdsts); + UNSERIALIZE_SCALAR(rxDesc32.extsts); + UNSERIALIZE_SCALAR(txDesc32.link); + UNSERIALIZE_SCALAR(txDesc32.bufptr); + UNSERIALIZE_SCALAR(txDesc32.cmdsts); + UNSERIALIZE_SCALAR(txDesc32.extsts); UNSERIALIZE_SCALAR(extstsEnable); /* @@ -2894,8 +2948,38 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) Tick NSGigE::cacheAccess(MemReqPtr &req) { + Addr daddr = req->paddr & 0xfff; DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", - req->paddr, req->paddr - addr); + req->paddr, daddr); + + if (!pioDelayWrite || !req->cmd.isWrite()) + return curTick + pioLatency; + + int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; + std::list &wq = writeQueue[cpu]; + if (wq.empty()) + panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr); + + const RegWriteData &data = wq.front(); + if (data.daddr != daddr) + panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x", + cpu, data.daddr, daddr); + + if (daddr == CR) { + if ((data.value & (CR_TXD | CR_TXE)) == CR_TXE) { + txEnable = true; + if (txState == txIdle) + txKick(); + } + + if ((data.value & (CR_RXD | CR_RXE)) == CR_RXE) { + rxEnable = true; + if (rxState == rxIdle) + rxKick(); + } + } + + wq.pop_front(); return curTick + pioLatency; } @@ -2931,69 +3015,83 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) - Param addr; Param clock; - Param tx_delay; - Param rx_delay; - Param intr_delay; + + Param addr; SimObjectParam mmu; SimObjectParam physmem; - Param rx_filter; - Param hardware_address; - SimObjectParam io_bus; - SimObjectParam payload_bus; + SimObjectParam configspace; + SimObjectParam configdata; + SimObjectParam platform; + Param pci_bus; + Param pci_dev; + Param pci_func; + SimObjectParam hier; - Param pio_latency; + SimObjectParam pio_bus; + SimObjectParam dma_bus; + SimObjectParam payload_bus; Param dma_desc_free; Param dma_data_free; Param dma_read_delay; Param dma_write_delay; Param dma_read_factor; Param dma_write_factor; - SimObjectParam configspace; - SimObjectParam configdata; - SimObjectParam platform; - Param pci_bus; - Param pci_dev; - Param pci_func; - Param tx_fifo_size; - Param rx_fifo_size; - Param m5reg; Param dma_no_allocate; + Param pio_latency; + Param pio_delay_write; + Param intr_delay; + + Param rx_delay; + Param tx_delay; + Param rx_fifo_size; + Param tx_fifo_size; + + Param rx_filter; + Param hardware_address; + Param rx_thread; + Param tx_thread; END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) - INIT_PARAM(addr, "Device Address"), INIT_PARAM(clock, "State machine processor frequency"), - INIT_PARAM(tx_delay, "Transmit Delay"), - INIT_PARAM(rx_delay, "Receive Delay"), - INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), + + INIT_PARAM(addr, "Device Address"), INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), - INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), - INIT_PARAM(hardware_address, "Ethernet Hardware Address"), - INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL), - INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(dma_desc_free, "DMA of Descriptors is free", false), - INIT_PARAM_DFLT(dma_data_free, "DMA of Data is free", false), - INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0), - INIT_PARAM_DFLT(dma_write_delay, "fixed delay for dma writes", 0), - INIT_PARAM_DFLT(dma_read_factor, "multiplier for dma reads", 0), - INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), INIT_PARAM(platform, "Platform"), INIT_PARAM(pci_bus, "PCI bus"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), - INIT_PARAM_DFLT(tx_fifo_size, "max size in bytes of txFifo", 131072), - INIT_PARAM_DFLT(rx_fifo_size, "max size in bytes of rxFifo", 131072), - INIT_PARAM(m5reg, "m5 register"), - INIT_PARAM_DFLT(dma_no_allocate, "Should DMA reads allocate cache lines", true) + + INIT_PARAM(hier, "Hierarchy global variables"), + INIT_PARAM(pio_bus, ""), + INIT_PARAM(dma_bus, ""), + INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"), + INIT_PARAM(dma_desc_free, "DMA of Descriptors is free"), + INIT_PARAM(dma_data_free, "DMA of Data is free"), + INIT_PARAM(dma_read_delay, "fixed delay for dma reads"), + INIT_PARAM(dma_write_delay, "fixed delay for dma writes"), + INIT_PARAM(dma_read_factor, "multiplier for dma reads"), + INIT_PARAM(dma_write_factor, "multiplier for dma writes"), + INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"), + INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), + INIT_PARAM(pio_delay_write, ""), + INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), + + INIT_PARAM(rx_delay, "Receive Delay"), + INIT_PARAM(tx_delay, "Transmit Delay"), + INIT_PARAM(rx_fifo_size, "max size in bytes of rxFifo"), + INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"), + + INIT_PARAM(rx_filter, "Enable Receive Filter"), + INIT_PARAM(hardware_address, "Ethernet Hardware Address"), + INIT_PARAM(rx_thread, ""), + INIT_PARAM(tx_thread, "") END_INIT_SIM_OBJECT_PARAMS(NSGigE) @@ -3003,7 +3101,11 @@ CREATE_SIM_OBJECT(NSGigE) NSGigE::Params *params = new NSGigE::Params; params->name = getInstanceName(); + + params->clock = clock; + params->mmu = mmu; + params->pmem = physmem; params->configSpace = configspace; params->configData = configdata; params->plat = platform; @@ -3011,27 +3113,31 @@ CREATE_SIM_OBJECT(NSGigE) params->deviceNum = pci_dev; params->functionNum = pci_func; - params->clock = clock; - params->intr_delay = intr_delay; - params->pmem = physmem; - params->tx_delay = tx_delay; - params->rx_delay = rx_delay; params->hier = hier; - params->header_bus = io_bus; + params->pio_bus = pio_bus; + params->header_bus = dma_bus; params->payload_bus = payload_bus; - params->pio_latency = pio_latency; params->dma_desc_free = dma_desc_free; params->dma_data_free = dma_data_free; params->dma_read_delay = dma_read_delay; params->dma_write_delay = dma_write_delay; params->dma_read_factor = dma_read_factor; params->dma_write_factor = dma_write_factor; + params->dma_no_allocate = dma_no_allocate; + params->pio_latency = pio_latency; + params->pio_delay_write = pio_delay_write; + params->intr_delay = intr_delay; + + params->rx_delay = rx_delay; + params->tx_delay = tx_delay; + params->rx_fifo_size = rx_fifo_size; + params->tx_fifo_size = tx_fifo_size; + params->rx_filter = rx_filter; params->eaddr = hardware_address; - params->tx_fifo_size = tx_fifo_size; - params->rx_fifo_size = rx_fifo_size; - params->m5reg = m5reg; - params->dma_no_allocate = dma_no_allocate; + params->rx_thread = rx_thread; + params->tx_thread = tx_thread; + return new NSGigE(params); }