#include "base/inet.hh"
#include "cpu/exec_context.hh"
-#include "cpu/intr_control.hh"
#include "dev/dma.hh"
#include "dev/etherlink.hh"
#include "dev/ns_gige.hh"
: PciDev(p), ioEnable(false),
txFifo(p->tx_fifo_size), rxFifo(p->rx_fifo_size),
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
- txXferLen(0), rxXferLen(0), txState(txIdle), txEnable(false),
- CTDD(false),
+ txXferLen(0), rxXferLen(0), clock(p->clock),
+ txState(txIdle), txEnable(false), CTDD(false),
txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
rxEnable(false), CRDD(false), rxPktBytes(0),
rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
p->header_bus, this,
&NSGigE::cacheAccess);
- pioLatency = p->pio_latency * p->header_bus->clockRatio;
+ pioLatency = p->pio_latency * p->header_bus->clockRate;
if (p->payload_bus)
dmaInterface = new DMAInterface<Bus>(name() + ".dma",
p->header_bus,
- p->payload_bus, 1);
+ p->payload_bus, 1,
+ p->dma_no_allocate);
else
dmaInterface = new DMAInterface<Bus>(name() + ".dma",
p->header_bus,
- p->header_bus, 1);
+ p->header_bus, 1,
+ p->dma_no_allocate);
} else if (p->payload_bus) {
pioInterface = newPioInterface(name(), p->hier,
p->payload_bus, this,
&NSGigE::cacheAccess);
- pioLatency = p->pio_latency * p->payload_bus->clockRatio;
+ pioLatency = p->pio_latency * p->payload_bus->clockRate;
dmaInterface = new DMAInterface<Bus>(name() + ".dma",
p->payload_bus,
- p->payload_bus, 1);
+ p->payload_bus, 1,
+ p->dma_no_allocate);
}
- intrDelay = US2Ticks(p->intr_delay);
+ intrDelay = p->intr_delay;
dmaReadDelay = p->dma_read_delay;
dmaWriteDelay = p->dma_write_delay;
dmaReadFactor = p->dma_read_factor;
.precision(0)
;
-
txBandwidth
.name(name() + ".txBandwidth")
.desc("Transmit Bandwidth (bits/s)")
.prereq(rxBytes)
;
+ totBandwidth
+ .name(name() + ".totBandwidth")
+ .desc("Total Bandwidth (bits/s)")
+ .precision(0)
+ .prereq(totBytes)
+ ;
+
+ totPackets
+ .name(name() + ".totPackets")
+ .desc("Total Packets")
+ .precision(0)
+ .prereq(totBytes)
+ ;
+
+ totBytes
+ .name(name() + ".totBytes")
+ .desc("Total Bytes")
+ .precision(0)
+ .prereq(totBytes)
+ ;
+
+ totPacketRate
+ .name(name() + ".totPPS")
+ .desc("Total Tranmission Rate (packets/s)")
+ .precision(0)
+ .prereq(totBytes)
+ ;
+
txPacketRate
.name(name() + ".txPPS")
.desc("Packet Tranmission Rate (packets/s)")
.prereq(rxBytes)
;
+ postedSwi
+ .name(name() + ".postedSwi")
+ .desc("number of software interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalSwi
+ .name(name() + ".totalSwi")
+ .desc("number of total Swi written to ISR")
+ .precision(0)
+ ;
+
+ coalescedSwi
+ .name(name() + ".coalescedSwi")
+ .desc("average number of Swi's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedRxIdle
+ .name(name() + ".postedRxIdle")
+ .desc("number of rxIdle interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalRxIdle
+ .name(name() + ".totalRxIdle")
+ .desc("number of total RxIdle written to ISR")
+ .precision(0)
+ ;
+
+ coalescedRxIdle
+ .name(name() + ".coalescedRxIdle")
+ .desc("average number of RxIdle's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedRxOk
+ .name(name() + ".postedRxOk")
+ .desc("number of RxOk interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalRxOk
+ .name(name() + ".totalRxOk")
+ .desc("number of total RxOk written to ISR")
+ .precision(0)
+ ;
+
+ coalescedRxOk
+ .name(name() + ".coalescedRxOk")
+ .desc("average number of RxOk's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedRxDesc
+ .name(name() + ".postedRxDesc")
+ .desc("number of RxDesc interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalRxDesc
+ .name(name() + ".totalRxDesc")
+ .desc("number of total RxDesc written to ISR")
+ .precision(0)
+ ;
+
+ coalescedRxDesc
+ .name(name() + ".coalescedRxDesc")
+ .desc("average number of RxDesc's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedTxOk
+ .name(name() + ".postedTxOk")
+ .desc("number of TxOk interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalTxOk
+ .name(name() + ".totalTxOk")
+ .desc("number of total TxOk written to ISR")
+ .precision(0)
+ ;
+
+ coalescedTxOk
+ .name(name() + ".coalescedTxOk")
+ .desc("average number of TxOk's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedTxIdle
+ .name(name() + ".postedTxIdle")
+ .desc("number of TxIdle interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalTxIdle
+ .name(name() + ".totalTxIdle")
+ .desc("number of total TxIdle written to ISR")
+ .precision(0)
+ ;
+
+ coalescedTxIdle
+ .name(name() + ".coalescedTxIdle")
+ .desc("average number of TxIdle's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedTxDesc
+ .name(name() + ".postedTxDesc")
+ .desc("number of TxDesc interrupts posted to CPU")
+ .precision(0)
+ ;
+
+ totalTxDesc
+ .name(name() + ".totalTxDesc")
+ .desc("number of total TxDesc written to ISR")
+ .precision(0)
+ ;
+
+ coalescedTxDesc
+ .name(name() + ".coalescedTxDesc")
+ .desc("average number of TxDesc's coalesced into each post")
+ .precision(0)
+ ;
+
+ postedRxOrn
+ .name(name() + ".postedRxOrn")
+ .desc("number of RxOrn posted to CPU")
+ .precision(0)
+ ;
+
+ totalRxOrn
+ .name(name() + ".totalRxOrn")
+ .desc("number of total RxOrn written to ISR")
+ .precision(0)
+ ;
+
+ coalescedRxOrn
+ .name(name() + ".coalescedRxOrn")
+ .desc("average number of RxOrn's coalesced into each post")
+ .precision(0)
+ ;
+
+ coalescedTotal
+ .name(name() + ".coalescedTotal")
+ .desc("average number of interrupts coalesced into each post")
+ .precision(0)
+ ;
+
+ postedInterrupts
+ .name(name() + ".postedInterrupts")
+ .desc("number of posts to CPU")
+ .precision(0)
+ ;
+
+ droppedPackets
+ .name(name() + ".droppedPackets")
+ .desc("number of packets dropped")
+ .precision(0)
+ ;
+
+ coalescedSwi = totalSwi / postedInterrupts;
+ coalescedRxIdle = totalRxIdle / postedInterrupts;
+ coalescedRxOk = totalRxOk / postedInterrupts;
+ coalescedRxDesc = totalRxDesc / postedInterrupts;
+ coalescedTxOk = totalTxOk / postedInterrupts;
+ coalescedTxIdle = totalTxIdle / postedInterrupts;
+ coalescedTxDesc = totalTxDesc / postedInterrupts;
+ coalescedRxOrn = totalRxOrn / postedInterrupts;
+
+ coalescedTotal = (totalSwi + totalRxIdle + totalRxOk + totalRxDesc + totalTxOk
+ + totalTxIdle + totalTxDesc + totalRxOrn) / postedInterrupts;
+
txBandwidth = txBytes * Stats::constant(8) / simSeconds;
rxBandwidth = rxBytes * Stats::constant(8) / simSeconds;
+ totBandwidth = txBandwidth + rxBandwidth;
+ totBytes = txBytes + rxBytes;
+ totPackets = txPackets + rxPackets;
+
txPacketRate = txPackets / simSeconds;
rxPacketRate = rxPackets / simSeconds;
}
reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR);
break;
- case CFG:
+ case CFGR:
reg = regs.config;
break;
reg = regs.txdp_hi;
break;
- case TXCFG:
+ case TX_CFG:
reg = regs.txcfg;
break;
reg = regs.rxdp_hi;
break;
- case RXCFG:
+ case RX_CFG:
reg = regs.rxcfg;
break;
reg = regs.tesr;
break;
+ case M5REG:
+ reg = params()->m5reg;
+ break;
+
default:
panic("reading unimplemented register: addr=%#x", daddr);
}
}
break;
- case CFG:
- if (reg & CFG_LNKSTS ||
- reg & CFG_SPDSTS ||
- reg & CFG_DUPSTS ||
- reg & CFG_RESERVED ||
- reg & CFG_T64ADDR ||
- reg & CFG_PCI64_DET)
- panic("writing to read-only or reserved CFG bits!\n");
+ case CFGR:
+ if (reg & CFGR_LNKSTS ||
+ reg & CFGR_SPDSTS ||
+ reg & CFGR_DUPSTS ||
+ reg & CFGR_RESERVED ||
+ reg & CFGR_T64ADDR ||
+ reg & CFGR_PCI64_DET)
+ panic("writing to read-only or reserved CFGR bits!\n");
- regs.config |= reg & ~(CFG_LNKSTS | CFG_SPDSTS | CFG_DUPSTS |
- CFG_RESERVED | CFG_T64ADDR | CFG_PCI64_DET);
+ regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
+ CFGR_RESERVED | CFGR_T64ADDR | CFGR_PCI64_DET);
// 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 & CFG_TBI_EN) ;
- if (reg & CFG_MODE_1000) ;
+ if (reg & CFGR_TBI_EN) ;
+ if (reg & CFGR_MODE_1000) ;
#endif
- if (reg & CFG_AUTO_1000)
- panic("CFG_AUTO_1000 not implemented!\n");
+ if (reg & CFGR_AUTO_1000)
+ panic("CFGR_AUTO_1000 not implemented!\n");
#if 0
- if (reg & CFG_PINT_DUPSTS ||
- reg & CFG_PINT_LNKSTS ||
- reg & CFG_PINT_SPDSTS)
+ if (reg & CFGR_PINT_DUPSTS ||
+ reg & CFGR_PINT_LNKSTS ||
+ reg & CFGR_PINT_SPDSTS)
;
- if (reg & CFG_TMRTEST) ;
- if (reg & CFG_MRM_DIS) ;
- if (reg & CFG_MWI_DIS) ;
+ if (reg & CFGR_TMRTEST) ;
+ if (reg & CFGR_MRM_DIS) ;
+ if (reg & CFGR_MWI_DIS) ;
- if (reg & CFG_T64ADDR)
- panic("CFG_T64ADDR is read only register!\n");
+ if (reg & CFGR_T64ADDR)
+ panic("CFGR_T64ADDR is read only register!\n");
- if (reg & CFG_PCI64_DET)
- panic("CFG_PCI64_DET is read only register!\n");
+ if (reg & CFGR_PCI64_DET)
+ panic("CFGR_PCI64_DET is read only register!\n");
- if (reg & CFG_DATA64_EN) ;
- if (reg & CFG_M64ADDR) ;
- if (reg & CFG_PHY_RST) ;
- if (reg & CFG_PHY_DIS) ;
+ if (reg & CFGR_DATA64_EN) ;
+ if (reg & CFGR_M64ADDR) ;
+ if (reg & CFGR_PHY_RST) ;
+ if (reg & CFGR_PHY_DIS) ;
#endif
- if (reg & CFG_EXTSTS_EN)
+ if (reg & CFGR_EXTSTS_EN)
extstsEnable = true;
else
extstsEnable = false;
#if 0
- if (reg & CFG_REQALG) ;
- if (reg & CFG_SB) ;
- if (reg & CFG_POW) ;
- if (reg & CFG_EXD) ;
- if (reg & CFG_PESEL) ;
- if (reg & CFG_BROM_DIS) ;
- if (reg & CFG_EXT_125) ;
- if (reg & CFG_BEM) ;
+ 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
break;
regs.txdp_hi = reg;
break;
- case TXCFG:
+ case TX_CFG:
regs.txcfg = reg;
#if 0
- if (reg & TXCFG_CSI) ;
- if (reg & TXCFG_HBI) ;
- if (reg & TXCFG_MLB) ;
- if (reg & TXCFG_ATP) ;
- if (reg & TXCFG_ECRETRY) {
+ if (reg & TX_CFG_CSI) ;
+ if (reg & TX_CFG_HBI) ;
+ if (reg & TX_CFG_MLB) ;
+ if (reg & TX_CFG_ATP) ;
+ if (reg & TX_CFG_ECRETRY) {
/*
* this could easily be implemented, but considering
* the network is just a fake pipe, wouldn't make
*/
}
- if (reg & TXCFG_BRST_DIS) ;
+ if (reg & TX_CFG_BRST_DIS) ;
#endif
#if 0
/* we handle our own DMA, ignore the kernel's exhortations */
- if (reg & TXCFG_MXDMA) ;
+ if (reg & TX_CFG_MXDMA) ;
#endif
// also, we currently don't care about fill/drain
regs.rxdp_hi = reg;
break;
- case RXCFG:
+ case RX_CFG:
regs.rxcfg = reg;
#if 0
- if (reg & RXCFG_AEP) ;
- if (reg & RXCFG_ARP) ;
- if (reg & RXCFG_STRIPCRC) ;
- if (reg & RXCFG_RX_RD) ;
- if (reg & RXCFG_ALP) ;
- if (reg & RXCFG_AIRL) ;
+ if (reg & RX_CFG_AEP) ;
+ if (reg & RX_CFG_ARP) ;
+ if (reg & RX_CFG_STRIPCRC) ;
+ if (reg & RX_CFG_RX_RD) ;
+ if (reg & RX_CFG_ALP) ;
+ if (reg & RX_CFG_AIRL) ;
/* we handle our own DMA, ignore what kernel says about it */
- if (reg & RXCFG_MXDMA) ;
+ if (reg & RX_CFG_MXDMA) ;
//also, we currently don't care about fill/drain thresholds
//though this may change in the future with more realistic
//networks or a driver which changes it according to feedback
- if (reg & (RXCFG_DRTH | RXCFG_DRTH0)) ;
+ if (reg & (RX_CFG_DRTH | RX_CFG_DRTH0)) ;
#endif
break;
interrupts &= ~ISR_NOIMPL;
regs.isr |= interrupts;
+ if (interrupts & regs.imr) {
+ if (interrupts & ISR_SWI) {
+ totalSwi++;
+ }
+ if (interrupts & ISR_RXIDLE) {
+ totalRxIdle++;
+ }
+ if (interrupts & ISR_RXOK) {
+ totalRxOk++;
+ }
+ if (interrupts & ISR_RXDESC) {
+ totalRxDesc++;
+ }
+ if (interrupts & ISR_TXOK) {
+ totalTxOk++;
+ }
+ if (interrupts & ISR_TXIDLE) {
+ totalTxIdle++;
+ }
+ if (interrupts & ISR_TXDESC) {
+ totalTxDesc++;
+ }
+ if (interrupts & ISR_RXORN) {
+ totalRxOrn++;
+ }
+ }
+
DPRINTF(EthernetIntr,
"interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
interrupts, regs.isr, regs.imr);
}
}
+/* writing this interrupt counting stats inside this means that this function
+ is now limited to being used to clear all interrupts upon the kernel
+ reading isr and servicing. just telling you in case you were thinking
+ of expanding use.
+*/
void
NSGigE::devIntrClear(uint32_t interrupts)
{
if (interrupts & ISR_RESERVE)
panic("Cannot clear a reserved interrupt");
+ if (regs.isr & regs.imr & ISR_SWI) {
+ postedSwi++;
+ }
+ if (regs.isr & regs.imr & ISR_RXIDLE) {
+ postedRxIdle++;
+ }
+ if (regs.isr & regs.imr & ISR_RXOK) {
+ postedRxOk++;
+ }
+ if (regs.isr & regs.imr & ISR_RXDESC) {
+ postedRxDesc++;
+ }
+ if (regs.isr & regs.imr & ISR_TXOK) {
+ postedTxOk++;
+ }
+ if (regs.isr & regs.imr & ISR_TXIDLE) {
+ postedTxIdle++;
+ }
+ if (regs.isr & regs.imr & ISR_TXDESC) {
+ postedTxDesc++;
+ }
+ if (regs.isr & regs.imr & ISR_RXORN) {
+ postedRxOrn++;
+ }
+
+ if (regs.isr & regs.imr & (ISR_SWI | ISR_RXIDLE | ISR_RXOK | ISR_RXDESC |
+ ISR_TXOK | ISR_TXIDLE | ISR_TXDESC | ISR_RXORN) )
+ postedInterrupts++;
+
interrupts &= ~ISR_NOIMPL;
regs.isr &= ~interrupts;
NSGigE::regsReset()
{
memset(®s, 0, sizeof(regs));
- regs.config = CFG_LNKSTS;
- regs.mear = MEAR_MDDIR | MEAR_EEDO;
+ regs.config = CFGR_LNKSTS;
+ regs.mear = 0x22;
regs.txcfg = 0x120; // set drain threshold to 1024 bytes and
// fill threshold to 32 bytes
regs.rxcfg = 0x4; // set drain threshold to 16 bytes
DPRINTF(Ethernet, "ID is %d\n", ip->id());
TcpPtr tcp(ip);
if (tcp) {
- DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
- tcp->sport(), tcp->dport());
+ DPRINTF(Ethernet,
+ "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
+ tcp->sport(), tcp->dport(), tcp->seq(),
+ tcp->ack());
}
}
}
DPRINTF(Ethernet, "ID is %d\n", ip->id());
TcpPtr tcp(ip);
if (tcp) {
- DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
- tcp->sport(), tcp->dport());
+ DPRINTF(Ethernet,
+ "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
+ tcp->sport(), tcp->dport(), tcp->seq(), tcp->ack());
}
}
}
#endif
- DDUMP(Ethernet, txFifo.front()->data, txFifo.front()->length);
+ DDUMP(EthernetData, txFifo.front()->data, txFifo.front()->length);
txBytes += txFifo.front()->length;
txPackets++;
if (!txFifo.empty() && !txEvent.scheduled()) {
DPRINTF(Ethernet, "reschedule transmit\n");
- txEvent.schedule(curTick + 1000);
+ txEvent.schedule(curTick + retryTime);
}
}
case txFifoBlock:
if (!txPacket) {
DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
- txPacket = new PacketData;
- txPacket->data = new uint8_t[16384];
+ txPacket = new PacketData(16384);
txPacketBufPtr = txPacket->data;
}
DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
if (txEvent.scheduled())
- txEvent.reschedule(curTick + 1);
+ txEvent.reschedule(curTick + cycles(1));
else
- txEvent.schedule(curTick + 1);
+ txEvent.schedule(curTick + cycles(1));
}
bool
}
if (rxFifo.avail() < packet->length) {
- DPRINTF(Ethernet,
- "packet will not fit in receive buffer...packet dropped\n");
+#if TRACING_ON
+ IpPtr ip(packet);
+ TcpPtr tcp(ip);
+ if (ip) {
+ DPRINTF(Ethernet,
+ "packet won't fit in receive buffer...pkt ID %d dropped\n",
+ ip->id());
+ if (tcp) {
+ DPRINTF(Ethernet, "Seq=%d\n", tcp->seq());
+ }
+ }
+#endif
+ droppedPackets++;
devIntrPost(ISR_RXORN);
return false;
}
bool txPacketExists = txPacket;
SERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) {
+ txPacket->length = txPacketBufPtr - txPacket->data;
txPacket->serialize("txPacket", os);
uint32_t txPktBufPtr = (uint32_t) (txPacketBufPtr - txPacket->data);
SERIALIZE_SCALAR(txPktBufPtr);
bool txPacketExists;
UNSERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) {
- txPacket = new PacketData;
+ txPacket = new PacketData(16384);
txPacket->unserialize("txPacket", cp, section);
uint32_t txPktBufPtr;
UNSERIALIZE_SCALAR(txPktBufPtr);
UNSERIALIZE_SCALAR(rxPacketExists);
rxPacket = 0;
if (rxPacketExists) {
- rxPacket = new PacketData;
+ rxPacket = new PacketData(16384);
rxPacket->unserialize("rxPacket", cp, section);
uint32_t rxPktBufPtr;
UNSERIALIZE_SCALAR(rxPktBufPtr);
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
+ Param<Addr> addr;
+ Param<Tick> clock;
Param<Tick> tx_delay;
Param<Tick> rx_delay;
Param<Tick> intr_delay;
SimObjectParam<PhysicalMemory *> physmem;
Param<bool> rx_filter;
Param<string> hardware_address;
- SimObjectParam<Bus*> header_bus;
+ SimObjectParam<Bus*> io_bus;
SimObjectParam<Bus*> payload_bus;
SimObjectParam<HierParams *> hier;
Param<Tick> pio_latency;
Param<uint32_t> pci_func;
Param<uint32_t> tx_fifo_size;
Param<uint32_t> rx_fifo_size;
+ Param<uint32_t> m5reg;
+ Param<bool> dma_no_allocate;
END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
- INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000),
- INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000),
- INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0),
+ 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(mmu, "Memory Controller"),
INIT_PARAM(physmem, "Physical Memory"),
INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true),
INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address",
"00:99:00:00:00:01"),
- INIT_PARAM_DFLT(header_bus, "The IO Bus to attach to for headers", NULL),
+ 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(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_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)
END_INIT_SIM_OBJECT_PARAMS(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 = header_bus;
+ params->header_bus = io_bus;
params->payload_bus = payload_bus;
params->pio_latency = pio_latency;
params->dma_desc_free = dma_desc_free;
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;
return new NSGigE(params);
}