arch: nuke arch/isa_specific.hh and move stuff to generated config/the_isa.hh
[gem5.git] / src / dev / ns_gige.cc
index 719747b26615583d5e24808f215d9b8aebf77acd..86f081ec5855c8992b2ae75f47e8833f3d7ab7f6 100644 (file)
@@ -24,6 +24,9 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ *          Lisa Hsu
  */
 
 /** @file
 #include <deque>
 #include <string>
 
-#include "arch/alpha/ev5.hh"
+#include "base/debug.hh"
 #include "base/inet.hh"
-#include "cpu/exec_context.hh"
+#include "base/types.hh"
+#include "config/the_isa.hh"
+#include "cpu/thread_context.hh"
 #include "dev/etherlink.hh"
 #include "dev/ns_gige.hh"
 #include "dev/pciconfigall.hh"
 #include "mem/packet.hh"
-#include "sim/builder.hh"
-#include "sim/debug.hh"
-#include "sim/host.hh"
-#include "sim/stats.hh"
+#include "mem/packet_access.hh"
+#include "params/NSGigE.hh"
 #include "sim/system.hh"
 
 const char *NsRxStateStrings[] =
@@ -86,34 +89,38 @@ using namespace TheISA;
 // NSGigE PCI Device
 //
 NSGigE::NSGigE(Params *p)
-    : PciDev(p), ioEnable(false),
+    : EtherDevice(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), clock(p->clock),
-      txState(txIdle), txEnable(false), CTDD(false),
+      txXferLen(0), rxXferLen(0), rxDmaFree(false), txDmaFree(false),
+      clock(p->clock),
+      txState(txIdle), txEnable(false), CTDD(false), txHalt(false),
       txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
-      rxEnable(false), CRDD(false), rxPktBytes(0),
+      rxEnable(false), CRDD(false), rxPktBytes(0), rxHalt(false),
       rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
-      eepromState(eepromStart), rxDmaReadEvent(this), rxDmaWriteEvent(this),
+      eepromState(eepromStart), eepromClk(false), eepromBitsToRx(0),
+      eepromOpcode(0), eepromAddress(0), eepromData(0),
+      dmaReadDelay(p->dma_read_delay), dmaWriteDelay(p->dma_write_delay),
+      dmaReadFactor(p->dma_read_factor), dmaWriteFactor(p->dma_write_factor),
+      rxDmaData(NULL), rxDmaAddr(0), rxDmaLen(0),
+      txDmaData(NULL), txDmaAddr(0), txDmaLen(0),
+      rxDmaReadEvent(this), rxDmaWriteEvent(this),
       txDmaReadEvent(this), txDmaWriteEvent(this),
       dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free),
       txDelay(p->tx_delay), rxDelay(p->rx_delay),
       rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
-      txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false),
-      acceptMulticast(false), acceptUnicast(false),
+      txEvent(this), rxFilterEnable(p->rx_filter),
+      acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false),
       acceptPerfect(false), acceptArp(false), multicastHashEnable(false),
-      intrTick(0), cpuPendingIntr(false),
+      intrDelay(p->intr_delay), intrTick(0), cpuPendingIntr(false),
       intrEvent(0), interface(0)
 {
 
-    intrDelay = p->intr_delay;
-    dmaReadDelay = p->dma_read_delay;
-    dmaWriteDelay = p->dma_write_delay;
-    dmaReadFactor = p->dma_read_factor;
-    dmaWriteFactor = p->dma_write_factor;
+
+    interface = new NSGigEInt(name() + ".int0", this);
 
     regsReset();
-    memcpy(&rom.perfectMatch, p->eaddr.bytes(), ETH_ADDR_LEN);
+    memcpy(&rom.perfectMatch, p->hardware_address.bytes(), ETH_ADDR_LEN);
 
     memset(&rxDesc32, 0, sizeof(rxDesc32));
     memset(&txDesc32, 0, sizeof(txDesc32));
@@ -124,349 +131,15 @@ NSGigE::NSGigE(Params *p)
 NSGigE::~NSGigE()
 {}
 
-void
-NSGigE::regStats()
-{
-    txBytes
-        .name(name() + ".txBytes")
-        .desc("Bytes Transmitted")
-        .prereq(txBytes)
-        ;
-
-    rxBytes
-        .name(name() + ".rxBytes")
-        .desc("Bytes Received")
-        .prereq(rxBytes)
-        ;
-
-    txPackets
-        .name(name() + ".txPackets")
-        .desc("Number of Packets Transmitted")
-        .prereq(txBytes)
-        ;
-
-    rxPackets
-        .name(name() + ".rxPackets")
-        .desc("Number of Packets Received")
-        .prereq(rxBytes)
-        ;
-
-    txIpChecksums
-        .name(name() + ".txIpChecksums")
-        .desc("Number of tx IP Checksums done by device")
-        .precision(0)
-        .prereq(txBytes)
-        ;
-
-    rxIpChecksums
-        .name(name() + ".rxIpChecksums")
-        .desc("Number of rx IP Checksums done by device")
-        .precision(0)
-        .prereq(rxBytes)
-        ;
-
-    txTcpChecksums
-        .name(name() + ".txTcpChecksums")
-        .desc("Number of tx TCP Checksums done by device")
-        .precision(0)
-        .prereq(txBytes)
-        ;
-
-    rxTcpChecksums
-        .name(name() + ".rxTcpChecksums")
-        .desc("Number of rx TCP Checksums done by device")
-        .precision(0)
-        .prereq(rxBytes)
-        ;
-
-    txUdpChecksums
-        .name(name() + ".txUdpChecksums")
-        .desc("Number of tx UDP Checksums done by device")
-        .precision(0)
-        .prereq(txBytes)
-        ;
-
-    rxUdpChecksums
-        .name(name() + ".rxUdpChecksums")
-        .desc("Number of rx UDP Checksums done by device")
-        .precision(0)
-        .prereq(rxBytes)
-        ;
-
-    descDmaReads
-        .name(name() + ".descDMAReads")
-        .desc("Number of descriptors the device read w/ DMA")
-        .precision(0)
-        ;
-
-    descDmaWrites
-        .name(name() + ".descDMAWrites")
-        .desc("Number of descriptors the device wrote w/ DMA")
-        .precision(0)
-        ;
-
-    descDmaRdBytes
-        .name(name() + ".descDmaReadBytes")
-        .desc("number of descriptor bytes read w/ DMA")
-        .precision(0)
-        ;
-
-   descDmaWrBytes
-        .name(name() + ".descDmaWriteBytes")
-        .desc("number of descriptor bytes write w/ DMA")
-        .precision(0)
-        ;
-
-    txBandwidth
-        .name(name() + ".txBandwidth")
-        .desc("Transmit Bandwidth (bits/s)")
-        .precision(0)
-        .prereq(txBytes)
-        ;
-
-    rxBandwidth
-        .name(name() + ".rxBandwidth")
-        .desc("Receive Bandwidth (bits/s)")
-        .precision(0)
-        .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)")
-        .precision(0)
-        .prereq(txBytes)
-        ;
-
-    rxPacketRate
-        .name(name() + ".rxPPS")
-        .desc("Packet Reception Rate (packets/s)")
-        .precision(0)
-        .prereq(rxBytes)
-        ;
-
-    postedSwi
-        .name(name() + ".postedSwi")
-        .desc("number of software interrupts posted to CPU")
-        .precision(0)
-        ;
-
-    totalSwi
-        .name(name() + ".totalSwi")
-        .desc("total number of 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("total number of 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("total number of 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("total number of 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("total number of 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("total number of 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("total number of 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("total number of 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;
-}
-
-
 /**
  * This is to write to the PCI general configuration registers
  */
-void
-NSGigE::writeConfig(int offset, const uint16_t data)
+Tick
+NSGigE::writeConfig(PacketPtr pkt)
 {
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
     if (offset < PCI_DEVICE_SPECIFIC)
-        PciDev::writeConfig(offset,  data);
+        PciDev::writeConfig(pkt);
     else
         panic("Device specific PCI config space not implemented!\n");
 
@@ -481,6 +154,19 @@ NSGigE::writeConfig(int offset, const uint16_t data)
             ioEnable = false;
         break;
     }
+
+    return configDelay;
+}
+
+EtherInt*
+NSGigE::getEthPort(const std::string &if_name, int idx)
+{
+    if (if_name == "interface") {
+       if (interface->getPeer())
+           panic("interface already connected to\n");
+       return interface;
+    }
+    return NULL;
 }
 
 /**
@@ -488,7 +174,7 @@ NSGigE::writeConfig(int offset, const uint16_t data)
  * spec sheet
  */
 Tick
-NSGigE::read(Packet *pkt)
+NSGigE::read(PacketPtr pkt)
 {
     assert(ioEnable);
 
@@ -505,20 +191,13 @@ NSGigE::read(Packet *pkt)
     if (daddr > LAST && daddr <=  RESERVED) {
         panic("Accessing reserved register");
     } else if (daddr > RESERVED && daddr <= 0x3FC) {
-        if (pkt->getSize() == sizeof(uint8_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint8_t>());
-        if (pkt->getSize() == sizeof(uint16_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint16_t>());
-        if (pkt->getSize() == sizeof(uint32_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint32_t>());
-        pkt->result = Packet::Success;
-        return pioDelay;
+        return readConfig(pkt);
     } else if (daddr >= MIB_START && daddr <= MIB_END) {
         // don't implement all the MIB's.  hopefully the kernel
         // doesn't actually DEPEND upon their values
         // MIB are just hardware stats keepers
         pkt->set<uint32_t>(0);
-        pkt->result = Packet::Success;
+        pkt->makeAtomicResponse();
         return pioDelay;
     } else if (daddr > 0x3FC)
         panic("Something is messed up!\n");
@@ -714,12 +393,12 @@ NSGigE::read(Packet *pkt)
         DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
                 daddr, reg, reg);
 
-    pkt->result = Packet::Success;
+    pkt->makeAtomicResponse();
     return pioDelay;
 }
 
 Tick
-NSGigE::write(Packet *pkt)
+NSGigE::write(PacketPtr pkt)
 {
     assert(ioEnable);
 
@@ -730,14 +409,7 @@ NSGigE::write(Packet *pkt)
     if (daddr > LAST && daddr <=  RESERVED) {
         panic("Accessing reserved register");
     } else if (daddr > RESERVED && daddr <= 0x3FC) {
-        if (pkt->getSize() == sizeof(uint8_t))
-            writeConfig(daddr & 0xff, pkt->get<uint8_t>());
-        if (pkt->getSize() == sizeof(uint16_t))
-            writeConfig(daddr & 0xff, pkt->get<uint16_t>());
-        if (pkt->getSize() == sizeof(uint32_t))
-            writeConfig(daddr & 0xff, pkt->get<uint32_t>());
-        pkt->result = Packet::Success;
-        return pioDelay;
+        return writeConfig(pkt);
     } else if (daddr > 0x3FC)
         panic("Something is messed up!\n");
 
@@ -1128,7 +800,7 @@ NSGigE::write(Packet *pkt)
     } else {
         panic("Invalid Request Size");
     }
-    pkt->result = Packet::Success;
+    pkt->makeAtomicResponse();
     return pioDelay;
 }
 
@@ -1179,6 +851,7 @@ NSGigE::devIntrPost(uint32_t interrupts)
         Tick when = curTick;
         if ((regs.isr & regs.imr & ISR_NODELAY) == 0)
             when += intrDelay;
+        postedInterrupts++;
         cpuIntrPost(when);
     }
 }
@@ -1219,9 +892,6 @@ NSGigE::devIntrClear(uint32_t interrupts)
         postedRxOrn++;
     }
 
-    if (regs.isr & regs.imr & ISR_IMPL)
-        postedInterrupts++;
-
     interrupts &= ~ISR_NOIMPL;
     regs.isr &= ~interrupts;
 
@@ -1277,7 +947,7 @@ NSGigE::cpuIntrPost(Tick when)
     if (intrEvent)
         intrEvent->squash();
     intrEvent = new IntrEvent(this, true);
-    intrEvent->schedule(intrTick);
+    schedule(intrEvent, intrTick);
 }
 
 void
@@ -1385,7 +1055,7 @@ NSGigE::doRxDmaRead()
     assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting);
     rxDmaState = dmaReading;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         rxDmaState = dmaReadWaiting;
     else
         dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData);
@@ -1416,7 +1086,7 @@ NSGigE::doRxDmaWrite()
     assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting);
     rxDmaState = dmaWriting;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         rxDmaState = dmaWriteWaiting;
     else
         dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData);
@@ -1463,7 +1133,7 @@ NSGigE::rxKick()
         }
 
         // Go to the next state machine clock tick.
-        rxKickTick = curTick + cycles(1);
+        rxKickTick = curTick + ticks(1);
     }
 
     switch(rxDmaState) {
@@ -1774,7 +1444,7 @@ NSGigE::rxKick()
             NsRxStateStrings[rxState]);
 
     if (clock && !rxKickEvent.scheduled())
-        rxKickEvent.schedule(rxKickTick);
+        schedule(rxKickEvent, rxKickTick);
 }
 
 void
@@ -1824,7 +1494,7 @@ NSGigE::transmit()
 
    if (!txFifo.empty() && !txEvent.scheduled()) {
        DPRINTF(Ethernet, "reschedule transmit\n");
-       txEvent.schedule(curTick + retryTime);
+       schedule(txEvent, curTick + retryTime);
    }
 }
 
@@ -1834,7 +1504,7 @@ NSGigE::doTxDmaRead()
     assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting);
     txDmaState = dmaReading;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         txDmaState = dmaReadWaiting;
     else
         dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData);
@@ -1865,7 +1535,7 @@ NSGigE::doTxDmaWrite()
     assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting);
     txDmaState = dmaWriting;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         txDmaState = dmaWriteWaiting;
     else
         dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData);
@@ -1910,7 +1580,7 @@ NSGigE::txKick()
         }
 
         // Go to the next state machine clock tick.
-        txKickTick = curTick + cycles(1);
+        txKickTick = curTick + ticks(1);
     }
 
     switch(txDmaState) {
@@ -2030,19 +1700,34 @@ NSGigE::txKick()
                     IpPtr ip(txPacket);
                     if (extsts & EXTSTS_UDPPKT) {
                         UdpPtr udp(ip);
-                        udp->sum(0);
-                        udp->sum(cksum(udp));
-                        txUdpChecksums++;
+                        if (udp) {
+                            udp->sum(0);
+                            udp->sum(cksum(udp));
+                            txUdpChecksums++;
+                        } else {
+                            debug_break();
+                            warn_once("UDPPKT set, but not UDP!\n");
+                        }
                     } else if (extsts & EXTSTS_TCPPKT) {
                         TcpPtr tcp(ip);
-                        tcp->sum(0);
-                        tcp->sum(cksum(tcp));
-                        txTcpChecksums++;
+                        if (tcp) {
+                            tcp->sum(0);
+                            tcp->sum(cksum(tcp));
+                            txTcpChecksums++;
+                        } else {
+                            debug_break();
+                            warn_once("TCPPKT set, but not UDP!\n");
+                        }
                     }
                     if (extsts & EXTSTS_IPPKT) {
-                        ip->sum(0);
-                        ip->sum(cksum(ip));
-                        txIpChecksums++;
+                        if (ip) {
+                            ip->sum(0);
+                            ip->sum(cksum(ip));
+                            txIpChecksums++;
+                        } else {
+                            debug_break();
+                            warn_once("IPPKT set, but not UDP!\n");
+                        }
                     }
                 }
 
@@ -2202,7 +1887,7 @@ NSGigE::txKick()
             NsTxStateStrings[txState]);
 
     if (clock && !txKickEvent.scheduled())
-        txKickEvent.schedule(txKickTick);
+        schedule(txKickEvent, txKickTick);
 }
 
 /**
@@ -2316,10 +2001,7 @@ NSGigE::transferDone()
 
     DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
 
-    if (txEvent.scheduled())
-        txEvent.reschedule(curTick + cycles(1));
-    else
-        txEvent.schedule(curTick + cycles(1));
+    reschedule(txEvent, curTick + ticks(1), true);
 }
 
 bool
@@ -2414,6 +2096,20 @@ NSGigE::recvPacket(EthPacketPtr packet)
     return true;
 }
 
+
+void
+NSGigE::resume()
+{
+    SimObject::resume();
+
+    // During drain we could have left the state machines in a waiting state and
+    // they wouldn't get out until some other event occured to kick them.
+    // This way they'll get out immediately
+    txKick();
+    rxKick();
+}
+
+
 //=====================================================================
 //
 //
@@ -2706,7 +2402,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     this->txDmaState = (DmaState) txDmaState;
     UNSERIALIZE_SCALAR(txKickTick);
     if (txKickTick)
-        txKickEvent.schedule(txKickTick);
+        schedule(txKickEvent, txKickTick);
 
     /*
      * unserialize rx state machine
@@ -2724,7 +2420,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     this->rxDmaState = (DmaState) rxDmaState;
     UNSERIALIZE_SCALAR(rxKickTick);
     if (rxKickTick)
-        rxKickEvent.schedule(rxKickTick);
+        schedule(rxKickEvent, rxKickTick);
 
     /*
      * Unserialize EEPROM state machine
@@ -2744,7 +2440,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     Tick transmitTick;
     UNSERIALIZE_SCALAR(transmitTick);
     if (transmitTick)
-        txEvent.schedule(curTick + transmitTick);
+        schedule(txEvent, curTick + transmitTick);
 
     /*
      * unserialize receive address filter settings
@@ -2766,146 +2462,12 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(intrEventTick);
     if (intrEventTick) {
         intrEvent = new IntrEvent(this, true);
-        intrEvent->schedule(intrEventTick);
+        schedule(intrEvent, intrEventTick);
     }
 }
 
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt)
-
-    SimObjectParam<EtherInt *> peer;
-    SimObjectParam<NSGigE *> device;
-
-END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt)
-
-    INIT_PARAM_DFLT(peer, "peer interface", NULL),
-    INIT_PARAM(device, "Ethernet device of this interface")
-
-END_INIT_SIM_OBJECT_PARAMS(NSGigEInt)
-
-CREATE_SIM_OBJECT(NSGigEInt)
-{
-    NSGigEInt *dev_int = new NSGigEInt(getInstanceName(), device);
-
-    EtherInt *p = (EtherInt *)peer;
-    if (p) {
-        dev_int->setPeer(p);
-        p->setPeer(dev_int);
-    }
-
-    return dev_int;
-}
-
-REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt)
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
-
-    SimObjectParam<System *> system;
-    SimObjectParam<Platform *> platform;
-    SimObjectParam<PciConfigAll *> configspace;
-    SimObjectParam<PciConfigData *> configdata;
-    Param<uint32_t> pci_bus;
-    Param<uint32_t> pci_dev;
-    Param<uint32_t> pci_func;
-    Param<Tick> pio_latency;
-
-    Param<Tick> clock;
-    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;
-    Param<bool> dma_no_allocate;
-    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;
-    Param<bool> rss;
-
-END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
-
-    INIT_PARAM(system, "System pointer"),
-    INIT_PARAM(platform, "Platform pointer"),
-    INIT_PARAM(configspace, "PCI Configspace"),
-    INIT_PARAM(configdata, "PCI Config data"),
-    INIT_PARAM(pci_bus, "PCI bus ID"),
-    INIT_PARAM(pci_dev, "PCI device number"),
-    INIT_PARAM(pci_func, "PCI function code"),
-    INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
-    INIT_PARAM(clock, "State machine cycle time"),
-
-    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(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, ""),
-    INIT_PARAM(rss, "")
-
-END_INIT_SIM_OBJECT_PARAMS(NSGigE)
-
-
-CREATE_SIM_OBJECT(NSGigE)
+NSGigE *
+NSGigEParams::create()
 {
-    NSGigE::Params *params = new NSGigE::Params;
-
-    params->name = getInstanceName();
-    params->platform = platform;
-    params->system = system;
-    params->configSpace = configspace;
-    params->configData = configdata;
-    params->busNum = pci_bus;
-    params->deviceNum = pci_dev;
-    params->functionNum = pci_func;
-    params->pio_delay = pio_latency;
-
-    params->clock = clock;
-    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_delay = pio_latency;
-    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->rx_thread = rx_thread;
-    params->tx_thread = tx_thread;
-    params->rss = rss;
-
-    return new NSGigE(params);
+    return new NSGigE(this);
 }
-
-REGISTER_SIM_OBJECT("NSGigE", NSGigE)