}
Device::Device(Params *p)
- : Base(p), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
+ : Base(p), plat(p->plat), physmem(p->physmem), rxUnique(0), txUnique(0),
+ virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
- rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
rxKickTick(0), txKickTick(0),
txEvent(this), rxDmaEvent(this), txDmaEvent(this),
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
+ pkt.time += pioDelay;
+ pkt.allocate();
+
if (!regValid(raddr))
- panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
- cpu, daddr, pkt.addr, pkt.size);
- panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d",
- cpu, index, daddr, req->paddr, req->vaddr, req->size);
++ panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d",
++ cpu, index, daddr, pkt.addr, pkt.size);
const Regs::Info &info = regInfo(raddr);
if (!info.read)
- panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("read %s (write only): "
- "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size);
++ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
++ info.name, cpu, index, daddr, pkt.addr, pkt.size);
- if (pkt.size != info.size)
- panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
- if (req->size != info.size)
+ panic("read %s (invalid size): "
- "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size);
++ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
++ info.name, cpu, index, daddr, pkt.addr, pkt.size);
prepareRead(cpu, index);
}
DPRINTF(EthernetPIO,
- "read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n",
- info.name, cpu, daddr, pkt.addr, pkt.size, value);
- "read %s: cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d val=%#x\n",
- info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size,
- value);
++ "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n",
++ info.name, cpu, index, daddr, pkt.addr, pkt.size, value);
// reading the interrupt status register has the side effect of
// clearing it
const Regs::Info &info = regInfo(raddr);
if (!info.write)
- panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("write %s (read only): "
- "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size);
++ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
++ info.name, cpu, index, daddr, pkt.addr, pkt.size);
- if (req->size != info.size)
+ if (pkt.size != info.size)
- panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("write %s (invalid size): "
- "cpu=%d vnic=%d da=%#x pa=%#x va=%#x size=%d",
- info.name, cpu, index, daddr, req->paddr, req->vaddr, req->size);
++ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
++ info.name, cpu, index, daddr, pkt.addr, pkt.size);
- uint32_t reg32 = *(uint32_t *)data;
- uint64_t reg64 = *(uint64_t *)data;
VirtualReg &vnic = virtualRegs[index];
DPRINTF(EthernetPIO,
- "write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
- info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() :
- "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n",
- info.name, index, cpu, info.size == 4 ? reg32 : reg64, daddr,
- req->paddr, req->vaddr, req->size);
++ "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
++ info.name, index, cpu, info.size == 4 ? pkt.get<uint32_t>() :
+ pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size);
prepareWrite(cpu, index);
panic("receive machine busy with another request! rxState=%s",
RxStateStrings[rxState]);
+ vnic.rxUnique = rxUnique++;
vnic.RxDone = Regs::RxDone_Busy;
- vnic.RxData = reg64;
+ vnic.RxData = pkt.get<uint64_t>();
- rxList.push_back(index);
- if (rxEnable && rxState == rxIdle) {
+
+ if (Regs::get_RxData_Vaddr(reg64)) {
+ Addr vaddr = Regs::get_RxData_Addr(reg64);
+ Addr paddr = vtophys(req->xc, vaddr);
+ DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d): "
+ "vaddr=%#x, paddr=%#x\n",
+ index, vnic.rxUnique, vaddr, paddr);
+
+ vnic.RxData = Regs::set_RxData_Addr(vnic.RxData, paddr);
+ } else {
+ DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d)\n",
+ index, vnic.rxUnique);
+ }
+
+ if (vnic.rxPacket == rxFifo.end()) {
+ DPRINTF(EthernetPIO, "request new packet...appending to rxList\n");
+ rxList.push_back(index);
+ } else {
+ DPRINTF(EthernetPIO, "packet exists...appending to rxBusy\n");
+ rxBusy.push_back(index);
+ }
+
+ if (rxEnable && (rxState == rxIdle || rxState == rxFifoBlock)) {
rxState = rxFifoBlock;
rxKick();
}
panic("transmit machine busy with another request! txState=%s",
TxStateStrings[txState]);
+ vnic.txUnique = txUnique++;
vnic.TxDone = Regs::TxDone_Busy;
- vnic.TxData = pkt.get<uint64_t>();
- vnic.TxData = reg64;
+
- if (Regs::get_TxData_Vaddr(reg64)) {
- Addr vaddr = Regs::get_TxData_Addr(reg64);
++ if (Regs::get_TxData_Vaddr(pkt.get<uint64_t>())) {
++ panic("vtophys won't work here in newmem.\n");
++ /*Addr vaddr = Regs::get_TxData_Addr(reg64);
+ Addr paddr = vtophys(req->xc, vaddr);
+ DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d): "
+ "vaddr=%#x, paddr=%#x\n",
+ index, vnic.txUnique, vaddr, paddr);
+
- vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);
++ vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);*/
+ } else {
+ DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d)\n",
+ index, vnic.txUnique);
+ }
+
if (txList.empty() || txList.front() != index)
txList.push_back(index);
if (txEnable && txState == txIdle && txList.front() == index) {
{
assert(rxState == rxCopy);
rxState = rxCopyDone;
- DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
- DPRINTF(EthernetDMA, "begin rx dma write paddr=%#x len=%d\n",
- rxDmaAddr, rxDmaLen);
- physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen);
+ DPRINTF(EthernetDMA, "end rx dma write paddr=%#x len=%d\n",
rxDmaAddr, rxDmaLen);
DDUMP(EthernetData, rxDmaData, rxDmaLen);
-}
-
-void
-Device::rxDmaDone()
-{
- rxDmaCopy();
// If the transmit state machine has a pending DMA, let it go first
if (txState == txBeginCopy)
vnic->rxPacketBytes);
rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
rxState = rxCopy;
-
+ if (rxDmaAddr == 1LL) {
+ rxState = rxCopyDone;
+ break;
+ }
+
- if (dmaInterface) {
- dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen,
- curTick, &rxDmaEvent, true);
- goto exit;
- }
-
- if (dmaWriteDelay != 0 || dmaWriteFactor != 0) {
- Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor;
- Tick start = curTick + dmaWriteDelay + factor;
- rxDmaEvent.schedule(start);
- goto exit;
- }
- rxDmaCopy();
+ dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData);
break;
case rxCopy:
switch (txState) {
case txFifoBlock:
- assert(Regs::get_TxDone_Busy(vnic->TxData));
+ assert(Regs::get_TxDone_Busy(vnic->TxDone));
if (!txPacket) {
// Grab a new packet from the fifo.
- txPacket = new PacketData(16384);
+ txPacket = new EthPacketData(16384);
txPacketOffset = 0;
}
}
void
-Device::serialize(ostream &os)
+Device::serialize(std::ostream &os)
{
+ int count;
+
// Serialize the PciDev base class
Base::serialize(os);