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<Bus>(name() + ".dma",
p->header_bus,
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<Bus>(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;
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:
} 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;
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)
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;
}
}
rxFifo.push(packet);
- interface->recvDone();
rxKick();
return true;
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<RegWriteData> &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;
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
- Param<Addr> addr;
Param<Tick> clock;
- Param<Tick> tx_delay;
- Param<Tick> rx_delay;
- Param<Tick> intr_delay;
+
+ Param<Addr> addr;
SimObjectParam<MemoryController *> mmu;
SimObjectParam<PhysicalMemory *> physmem;
- Param<bool> rx_filter;
- Param<string> hardware_address;
- SimObjectParam<Bus*> io_bus;
- SimObjectParam<Bus*> payload_bus;
+ SimObjectParam<PciConfigAll *> configspace;
+ SimObjectParam<PciConfigData *> configdata;
+ SimObjectParam<Platform *> platform;
+ Param<uint32_t> pci_bus;
+ Param<uint32_t> pci_dev;
+ Param<uint32_t> pci_func;
+
SimObjectParam<HierParams *> hier;
- Param<Tick> pio_latency;
+ SimObjectParam<Bus*> pio_bus;
+ SimObjectParam<Bus*> dma_bus;
+ SimObjectParam<Bus*> payload_bus;
Param<bool> dma_desc_free;
Param<bool> dma_data_free;
Param<Tick> dma_read_delay;
Param<Tick> dma_write_delay;
Param<Tick> dma_read_factor;
Param<Tick> dma_write_factor;
- SimObjectParam<PciConfigAll *> configspace;
- SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Platform *> platform;
- Param<uint32_t> pci_bus;
- Param<uint32_t> pci_dev;
- 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;
+ Param<Tick> pio_latency;
+ Param<bool> pio_delay_write;
+ Param<Tick> intr_delay;
+
+ Param<Tick> rx_delay;
+ Param<Tick> tx_delay;
+ Param<uint32_t> rx_fifo_size;
+ Param<uint32_t> tx_fifo_size;
+
+ Param<bool> rx_filter;
+ Param<string> hardware_address;
+ Param<bool> rx_thread;
+ Param<bool> 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)
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;
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);
}