diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/sparc/miscregfile.cc | 6 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 16 | ||||
-rw-r--r-- | src/cpu/o3/decode_impl.hh | 6 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 7 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 11 | ||||
-rw-r--r-- | src/cpu/o3/lsq_impl.hh | 13 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 10 | ||||
-rw-r--r-- | src/cpu/o3/rob_impl.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/sparc/cpu_builder.cc | 7 | ||||
-rw-r--r-- | src/dev/i8254xGBe.cc | 317 | ||||
-rw-r--r-- | src/dev/i8254xGBe.hh | 135 | ||||
-rw-r--r-- | src/dev/i8254xGBe_defs.hh | 87 |
14 files changed, 496 insertions, 130 deletions
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 5bd572d38..f511ef454 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -647,11 +647,9 @@ void MiscRegFile::setReg(int miscReg, return; case MISCREG_CWP: new_val = val >= NWindows ? NWindows - 1 : val; - if (val >= NWindows) { + if (val >= NWindows) new_val = NWindows - 1; - warn("Attempted to set the CWP to %d with NWindows = %d\n", - val, NWindows); - } + tc->changeRegFileContext(CONTEXT_CWP, new_val); break; case MISCREG_GL: diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 3fd85595f..65e36d99a 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -96,7 +96,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params) if (policy == "aggressive"){ commitPolicy = Aggressive; - DPRINTF(Commit,"Commit Policy set to Aggressive."); +// DPRINTF(Commit,"Commit Policy set to Aggressive."); } else if (policy == "roundrobin"){ commitPolicy = RoundRobin; @@ -105,11 +105,11 @@ DefaultCommit<Impl>::DefaultCommit(Params *params) priority_list.push_back(tid); } - DPRINTF(Commit,"Commit Policy set to Round Robin."); +// DPRINTF(Commit,"Commit Policy set to Round Robin."); } else if (policy == "oldestready"){ commitPolicy = OldestReady; - DPRINTF(Commit,"Commit Policy set to Oldest Ready."); +// DPRINTF(Commit,"Commit Policy set to Oldest Ready."); } else { assert(0 && "Invalid SMT Commit Policy. Options Are: {Aggressive," "RoundRobin,OldestReady}"); @@ -229,8 +229,8 @@ template <class Impl> void DefaultCommit<Impl>::setCPU(O3CPU *cpu_ptr) { - DPRINTF(Commit, "Commit: Setting CPU pointer.\n"); cpu = cpu_ptr; + DPRINTF(Commit, "Commit: Setting CPU pointer.\n"); // Commit must broadcast the number of free entries it has at the start of // the simulation, so it starts as active. @@ -250,7 +250,6 @@ template <class Impl> void DefaultCommit<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) { - DPRINTF(Commit, "Commit: Setting time buffer pointer.\n"); timeBuffer = tb_ptr; // Setup wire to send information back to IEW. @@ -264,7 +263,6 @@ template <class Impl> void DefaultCommit<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr) { - DPRINTF(Commit, "Commit: Setting fetch queue pointer.\n"); fetchQueue = fq_ptr; // Setup wire to get instructions from rename (for the ROB). @@ -275,7 +273,6 @@ template <class Impl> void DefaultCommit<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) { - DPRINTF(Commit, "Commit: Setting rename queue pointer.\n"); renameQueue = rq_ptr; // Setup wire to get instructions from rename (for the ROB). @@ -286,7 +283,6 @@ template <class Impl> void DefaultCommit<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) { - DPRINTF(Commit, "Commit: Setting IEW queue pointer.\n"); iewQueue = iq_ptr; // Setup wire to get instructions from IEW. @@ -304,7 +300,6 @@ template<class Impl> void DefaultCommit<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) { - DPRINTF(Commit, "Commit: Setting active threads list pointer.\n"); activeThreads = at_ptr; } @@ -312,8 +307,6 @@ template <class Impl> void DefaultCommit<Impl>::setRenameMap(RenameMap rm_ptr[]) { - DPRINTF(Commit, "Setting rename map pointers.\n"); - for (int i=0; i < numThreads; i++) { renameMap[i] = &rm_ptr[i]; } @@ -323,7 +316,6 @@ template <class Impl> void DefaultCommit<Impl>::setROB(ROB *rob_ptr) { - DPRINTF(Commit, "Commit: Setting ROB pointer.\n"); rob = rob_ptr; } diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index 79a0bfdbf..93d02bfcd 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -114,15 +114,14 @@ template<class Impl> void DefaultDecode<Impl>::setCPU(O3CPU *cpu_ptr) { - DPRINTF(Decode, "Setting CPU pointer.\n"); cpu = cpu_ptr; + DPRINTF(Decode, "Setting CPU pointer.\n"); } template<class Impl> void DefaultDecode<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) { - DPRINTF(Decode, "Setting time buffer pointer.\n"); timeBuffer = tb_ptr; // Setup wire to write information back to fetch. @@ -138,7 +137,6 @@ template<class Impl> void DefaultDecode<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) { - DPRINTF(Decode, "Setting decode queue pointer.\n"); decodeQueue = dq_ptr; // Setup wire to write information to proper place in decode queue. @@ -149,7 +147,6 @@ template<class Impl> void DefaultDecode<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr) { - DPRINTF(Decode, "Setting fetch queue pointer.\n"); fetchQueue = fq_ptr; // Setup wire to read information from fetch queue. @@ -160,7 +157,6 @@ template<class Impl> void DefaultDecode<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) { - DPRINTF(Decode, "Setting active threads list pointer.\n"); activeThreads = at_ptr; } diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 34b06420d..85885906d 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -266,8 +266,8 @@ template<class Impl> void DefaultFetch<Impl>::setCPU(O3CPU *cpu_ptr) { - DPRINTF(Fetch, "Setting the CPU pointer.\n"); cpu = cpu_ptr; + DPRINTF(Fetch, "Setting the CPU pointer.\n"); // Name is finally available, so create the port. icachePort = new IcachePort(this); @@ -292,7 +292,6 @@ template<class Impl> void DefaultFetch<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer) { - DPRINTF(Fetch, "Setting the time buffer pointer.\n"); timeBuffer = time_buffer; // Create wires to get information from proper places in time buffer. @@ -306,7 +305,6 @@ template<class Impl> void DefaultFetch<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) { - DPRINTF(Fetch, "Setting active threads list pointer.\n"); activeThreads = at_ptr; } @@ -314,7 +312,6 @@ template<class Impl> void DefaultFetch<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr) { - DPRINTF(Fetch, "Setting the fetch queue pointer.\n"); fetchQueue = fq_ptr; // Create wire to write information to proper place in fetch queue. diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 4883e5a5c..d2948a525 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -282,8 +282,8 @@ template<class Impl> void DefaultIEW<Impl>::setCPU(O3CPU *cpu_ptr) { - DPRINTF(IEW, "Setting CPU pointer.\n"); cpu = cpu_ptr; + DPRINTF(IEW, "Setting CPU pointer.\n"); instQueue.setCPU(cpu_ptr); ldstQueue.setCPU(cpu_ptr); @@ -295,7 +295,6 @@ template<class Impl> void DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) { - DPRINTF(IEW, "Setting time buffer pointer.\n"); timeBuffer = tb_ptr; // Setup wire to read information from time buffer, from commit. @@ -314,7 +313,6 @@ template<class Impl> void DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) { - DPRINTF(IEW, "Setting rename queue pointer.\n"); renameQueue = rq_ptr; // Setup wire to read information from rename queue. @@ -325,7 +323,6 @@ template<class Impl> void DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) { - DPRINTF(IEW, "Setting IEW queue pointer.\n"); iewQueue = iq_ptr; // Setup wire to write instructions to commit. @@ -336,7 +333,6 @@ template<class Impl> void DefaultIEW<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) { - DPRINTF(IEW, "Setting active threads list pointer.\n"); activeThreads = at_ptr; ldstQueue.setActiveThreads(at_ptr); @@ -347,7 +343,6 @@ template<class Impl> void DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr) { - DPRINTF(IEW, "Setting scoreboard pointer.\n"); scoreboard = sb_ptr; } diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index 79e03d4bf..4d99fb520 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -81,8 +81,6 @@ InstructionQueue<Impl>::InstructionQueue(Params *params) // Set the number of physical registers as the number of int + float numPhysRegs = numPhysIntRegs + numPhysFloatRegs; - DPRINTF(IQ, "There are %i physical registers.\n", numPhysRegs); - //Create an entry for each physical register within the //dependency graph. dependGraph.resize(numPhysRegs); @@ -124,8 +122,10 @@ InstructionQueue<Impl>::InstructionQueue(Params *params) maxEntries[i] = part_amt; } +/* DPRINTF(IQ, "IQ sharing policy set to Partitioned:" "%i entries per thread.\n",part_amt); +*/ } else if (policy == "threshold") { iqPolicy = Threshold; @@ -139,8 +139,10 @@ InstructionQueue<Impl>::InstructionQueue(Params *params) maxEntries[i] = thresholdIQ; } +/* DPRINTF(IQ, "IQ sharing policy set to Threshold:" "%i entries per thread.\n",thresholdIQ); +*/ } else { assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic," "Partitioned, Threshold}"); @@ -360,7 +362,6 @@ template <class Impl> void InstructionQueue<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) { - DPRINTF(IQ, "Setting active threads list pointer.\n"); activeThreads = at_ptr; } @@ -368,15 +369,13 @@ template <class Impl> void InstructionQueue<Impl>::setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2e_ptr) { - DPRINTF(IQ, "Set the issue to execute queue.\n"); - issueToExecuteQueue = i2e_ptr; + issueToExecuteQueue = i2e_ptr; } template <class Impl> void InstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) { - DPRINTF(IQ, "Set the time buffer.\n"); timeBuffer = tb_ptr; fromCommit = timeBuffer->getWire(-commitToIEWDelay); diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index d4994fcb7..02cc5784c 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -112,8 +112,6 @@ LSQ<Impl>::LSQ(Params *params) SQEntries(params->SQEntries), numThreads(params->numberOfThreads), retryTid(-1) { - DPRINTF(LSQ, "Creating LSQ object.\n"); - dcachePort.snoopRangeSent = false; //**********************************************/ @@ -131,20 +129,20 @@ LSQ<Impl>::LSQ(Params *params) maxLQEntries = LQEntries; maxSQEntries = SQEntries; - +/* DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); - +*/ } else if (policy == "partitioned") { lsqPolicy = Partitioned; //@todo:make work if part_amt doesnt divide evenly. maxLQEntries = LQEntries / numThreads; maxSQEntries = SQEntries / numThreads; - +/* DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " "%i entries per LQ | %i entries per SQ", maxLQEntries,maxSQEntries); - +*/ } else if (policy == "threshold") { lsqPolicy = Threshold; @@ -156,10 +154,11 @@ LSQ<Impl>::LSQ(Params *params) //amount of the LSQ maxLQEntries = params->smtLSQThreshold; maxSQEntries = params->smtLSQThreshold; - +/* DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " "%i entries per LQ | %i entries per SQ", maxLQEntries,maxSQEntries); +*/ } else { assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index e70c960b3..0a3021046 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -112,7 +112,7 @@ void LSQUnit<Impl>::init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries, unsigned maxSQEntries, unsigned id) { - DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",id); +// DPRINTF(LSQUnit, "Creating LSQUnit%i object.\n",id); switchedOut = false; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index e303f1cee..eb04ca733 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -168,15 +168,14 @@ template <class Impl> void DefaultRename<Impl>::setCPU(O3CPU *cpu_ptr) { - DPRINTF(Rename, "Setting CPU pointer.\n"); cpu = cpu_ptr; + DPRINTF(Rename, "Setting CPU pointer.\n"); } template <class Impl> void DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) { - DPRINTF(Rename, "Setting time buffer pointer.\n"); timeBuffer = tb_ptr; // Setup wire to read information from time buffer, from IEW stage. @@ -193,7 +192,6 @@ template <class Impl> void DefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) { - DPRINTF(Rename, "Setting rename queue pointer.\n"); renameQueue = rq_ptr; // Setup wire to write information to future stages. @@ -204,7 +202,6 @@ template <class Impl> void DefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) { - DPRINTF(Rename, "Setting decode queue pointer.\n"); decodeQueue = dq_ptr; // Setup wire to get information from decode. @@ -228,7 +225,6 @@ template<class Impl> void DefaultRename<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) { - DPRINTF(Rename, "Setting active threads list pointer.\n"); activeThreads = at_ptr; } @@ -237,8 +233,6 @@ template <class Impl> void DefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[]) { - DPRINTF(Rename, "Setting rename map pointers.\n"); - for (int i=0; i<numThreads; i++) { renameMap[i] = &rm_ptr[i]; } @@ -248,7 +242,6 @@ template <class Impl> void DefaultRename<Impl>::setFreeList(FreeList *fl_ptr) { - DPRINTF(Rename, "Setting free list pointer.\n"); freeList = fl_ptr; } @@ -256,7 +249,6 @@ template<class Impl> void DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard) { - DPRINTF(Rename, "Setting scoreboard pointer.\n"); scoreboard = _scoreboard; } diff --git a/src/cpu/o3/rob_impl.hh b/src/cpu/o3/rob_impl.hh index fde636754..975aba379 100644 --- a/src/cpu/o3/rob_impl.hh +++ b/src/cpu/o3/rob_impl.hh @@ -66,7 +66,7 @@ ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth, } else if (policy == "partitioned") { robPolicy = Partitioned; - DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); +// DPRINTF(Fetch, "ROB sharing policy set to Partitioned\n"); //@todo:make work if part_amt doesnt divide evenly. int part_amt = numEntries / numThreads; @@ -78,7 +78,7 @@ ROB<Impl>::ROB(unsigned _numEntries, unsigned _squashWidth, } else if (policy == "threshold") { robPolicy = Threshold; - DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); +// DPRINTF(Fetch, "ROB sharing policy set to Threshold\n"); int threshold = _smtROBThreshold;; diff --git a/src/cpu/o3/sparc/cpu_builder.cc b/src/cpu/o3/sparc/cpu_builder.cc index 3cac89bad..35badce2c 100644 --- a/src/cpu/o3/sparc/cpu_builder.cc +++ b/src/cpu/o3/sparc/cpu_builder.cc @@ -50,11 +50,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU) Param<int> clock; Param<int> phase; Param<int> numThreads; + Param<int> cpu_id; Param<int> activity; #if FULL_SYSTEM SimObjectParam<System *> system; - Param<int> cpu_id; SimObjectParam<SparcISA::ITB *> itb; SimObjectParam<SparcISA::DTB *> dtb; Param<Tick> profile; @@ -161,11 +161,11 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU) INIT_PARAM(clock, "clock speed"), INIT_PARAM_DFLT(phase, "clock phase", 0), INIT_PARAM(numThreads, "number of HW thread contexts"), + INIT_PARAM(cpu_id, "processor ID"), INIT_PARAM_DFLT(activity, "Initial activity count", 0), #if FULL_SYSTEM INIT_PARAM(system, "System object"), - INIT_PARAM(cpu_id, "processor ID"), INIT_PARAM(itb, "Instruction translation buffer"), INIT_PARAM(dtb, "Data translation buffer"), INIT_PARAM(profile, ""), @@ -305,14 +305,15 @@ CREATE_SIM_OBJECT(DerivO3CPU) SparcSimpleParams *params = new SparcSimpleParams; params->clock = clock; + params->phase = phase; params->name = getInstanceName(); params->numberOfThreads = actual_num_threads; + params->cpu_id = cpu_id; params->activity = activity; #if FULL_SYSTEM params->system = system; - params->cpu_id = cpu_id; params->itb = itb; params->dtb = dtb; params->profile = profile; diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index c38a9e873..3d08bca1e 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -55,10 +55,10 @@ using namespace iGbReg; using namespace Net; IGbE::IGbE(Params *p) - : PciDev(p), etherInt(NULL), useFlowControl(p->use_flow_control), + : PciDev(p), etherInt(NULL), drainEvent(NULL), useFlowControl(p->use_flow_control), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false), - txTick(false), rdtrEvent(this), radvEvent(this), tadvEvent(this), - tidvEvent(this), tickEvent(this), interEvent(this), + txTick(false), txFifoTick(false), rdtrEvent(this), radvEvent(this), + tadvEvent(this), tidvEvent(this), tickEvent(this), interEvent(this), rxDescCache(this, name()+".RxDesc", p->rx_desc_cache_size), txDescCache(this, name()+".TxDesc", p->tx_desc_cache_size), clock(p->clock) { @@ -223,6 +223,7 @@ IGbE::read(PacketPtr pkt) pkt->set<uint32_t>(regs.rdtr()); if (regs.rdtr.fpd()) { rxDescCache.writeback(0); + DPRINTF(EthernetIntr, "Posting interrupt because of RDTR.FPD write\n"); postInterrupt(IT_RXT); regs.rdtr.fpd(0); } @@ -411,6 +412,7 @@ IGbE::write(PacketPtr pkt) regs.itr = val; break; case REG_ICS: + DPRINTF(EthernetIntr, "Posting interrupt because of ICS write\n"); postInterrupt((IntTypes)val); break; case REG_IMS: @@ -429,6 +431,7 @@ IGbE::write(PacketPtr pkt) regs.rctl = val; if (regs.rctl.rst()) { rxDescCache.reset(); + DPRINTF(EthernetSM, "RXS: Got RESET!\n"); rxFifo.clear(); regs.rctl.rst(0); } @@ -568,8 +571,8 @@ IGbE::postInterrupt(IntTypes t, bool now) } else { DPRINTF(EthernetIntr, "EINT: Scheduling timer interrupt for %d ticks\n", Clock::Int::ns * 256 * regs.itr.interval()); - assert(!interEvent.scheduled()); - interEvent.schedule(curTick + Clock::Int::ns * 256 * regs.itr.interval()); + if (!interEvent.scheduled()) + interEvent.schedule(curTick + Clock::Int::ns * 256 * regs.itr.interval()); } } } @@ -676,39 +679,39 @@ IGbE::RxDescCache::pktComplete() // no support for anything but starting at 0 assert(igbe->regs.rxcsum.pcss() == 0); - DPRINTF(EthernetDesc, "RxDesc: Packet written to memory updating Descriptor\n"); + DPRINTF(EthernetDesc, "Packet written to memory updating Descriptor\n"); uint8_t status = RXDS_DD | RXDS_EOP; uint8_t err = 0; IpPtr ip(pktPtr); if (ip) { if (igbe->regs.rxcsum.ipofld()) { - DPRINTF(EthernetDesc, "RxDesc: Checking IP checksum\n"); + DPRINTF(EthernetDesc, "Checking IP checksum\n"); status |= RXDS_IPCS; desc->csum = htole(cksum(ip)); if (cksum(ip) != 0) { err |= RXDE_IPE; - DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n"); + DPRINTF(EthernetDesc, "Checksum is bad!!\n"); } } TcpPtr tcp(ip); if (tcp && igbe->regs.rxcsum.tuofld()) { - DPRINTF(EthernetDesc, "RxDesc: Checking TCP checksum\n"); + DPRINTF(EthernetDesc, "Checking TCP checksum\n"); status |= RXDS_TCPCS; desc->csum = htole(cksum(tcp)); if (cksum(tcp) != 0) { - DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n"); + DPRINTF(EthernetDesc, "Checksum is bad!!\n"); err |= RXDE_TCPE; } } UdpPtr udp(ip); if (udp && igbe->regs.rxcsum.tuofld()) { - DPRINTF(EthernetDesc, "RxDesc: Checking UDP checksum\n"); + DPRINTF(EthernetDesc, "Checking UDP checksum\n"); status |= RXDS_UDPCS; desc->csum = htole(cksum(udp)); if (cksum(tcp) != 0) { - DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n"); + DPRINTF(EthernetDesc, "Checksum is bad!!\n"); err |= RXDE_TCPE; } } @@ -748,15 +751,18 @@ IGbE::RxDescCache::pktComplete() // If the packet is small enough, interrupt appropriately // I wonder if this is delayed or not?! - if (pktPtr->length <= igbe->regs.rsrpd.idv()) + if (pktPtr->length <= igbe->regs.rsrpd.idv()) { + DPRINTF(EthernetSM, "RXS: Posting IT_SRPD beacuse small packet received\n"); igbe->postInterrupt(IT_SRPD); + } - DPRINTF(EthernetDesc, "RxDesc: Processing of this descriptor complete\n"); + DPRINTF(EthernetDesc, "Processing of this descriptor complete\n"); unusedCache.pop_front(); usedCache.push_back(desc); pktPtr = NULL; enableSm(); pktDone = true; + igbe->checkDrain(); } void @@ -776,11 +782,33 @@ IGbE::RxDescCache::packetDone() return false; } +bool +IGbE::RxDescCache::hasOutstandingEvents() +{ + return pktEvent.scheduled() || wbEvent.scheduled() || + fetchEvent.scheduled(); +} + +void +IGbE::RxDescCache::serialize(std::ostream &os) +{ + DescCache<RxDesc>::serialize(os); + SERIALIZE_SCALAR(pktDone); +} + +void +IGbE::RxDescCache::unserialize(Checkpoint *cp, const std::string §ion) +{ + DescCache<RxDesc>::unserialize(cp, section); + UNSERIALIZE_SCALAR(pktDone); +} + + ///////////////////////////////////// IGbE::TxDesc ///////////////////////////////// IGbE::TxDescCache::TxDescCache(IGbE *i, const std::string n, int s) : DescCache<TxDesc>(i,n, s), pktDone(false), isTcp(false), pktWaiting(false), - hLen(0), pktEvent(this) + pktEvent(this) { } @@ -792,10 +820,10 @@ IGbE::TxDescCache::getPacketSize() TxDesc *desc; - DPRINTF(EthernetDesc, "TxDesc: Starting processing of descriptor\n"); + DPRINTF(EthernetDesc, "Starting processing of descriptor\n"); while (unusedCache.size() && TxdOp::isContext(unusedCache.front())) { - DPRINTF(EthernetDesc, "TxDesc: Got context descriptor type... skipping\n"); + DPRINTF(EthernetDesc, "Got context descriptor type... skipping\n"); // I think we can just ignore these for now? desc = unusedCache.front(); @@ -813,7 +841,7 @@ IGbE::TxDescCache::getPacketSize() if (!unusedCache.size()) return -1; - DPRINTF(EthernetDesc, "TxDesc: Next TX packet is %d bytes\n", + DPRINTF(EthernetDesc, "Next TX packet is %d bytes\n", TxdOp::getLen(unusedCache.front())); return TxdOp::getLen(unusedCache.front()); @@ -833,9 +861,9 @@ IGbE::TxDescCache::getPacketData(EthPacketPtr p) pktWaiting = true; - DPRINTF(EthernetDesc, "TxDesc: Starting DMA of packet\n"); + DPRINTF(EthernetDesc, "Starting DMA of packet\n"); igbe->dmaRead(igbe->platform->pciToDma(TxdOp::getBuf(desc)), - TxdOp::getLen(desc), &pktEvent, p->data + hLen); + TxdOp::getLen(desc), &pktEvent, p->data + p->length); } @@ -848,7 +876,7 @@ IGbE::TxDescCache::pktComplete() assert(unusedCache.size()); assert(pktPtr); - DPRINTF(EthernetDesc, "TxDesc: DMA of packet complete\n"); + DPRINTF(EthernetDesc, "DMA of packet complete\n"); desc = unusedCache.front(); @@ -857,20 +885,21 @@ IGbE::TxDescCache::pktComplete() DPRINTF(EthernetDesc, "TxDescriptor data d1: %#llx d2: %#llx\n", desc->d1, desc->d2); if (!TxdOp::eop(desc)) { - assert(hLen == 0); - hLen = TxdOp::getLen(desc); + // This only supports two descriptors per tx packet + assert(pktPtr->length == 0); + pktPtr->length = TxdOp::getLen(desc); unusedCache.pop_front(); usedCache.push_back(desc); pktDone = true; pktWaiting = false; pktPtr = NULL; - DPRINTF(EthernetDesc, "TxDesc: Partial Packet Descriptor Done\n"); + DPRINTF(EthernetDesc, "Partial Packet Descriptor Done\n"); return; } // Set the length of the data in the EtherPacket - pktPtr->length = TxdOp::getLen(desc) + hLen; + pktPtr->length += TxdOp::getLen(desc); // no support for vlans assert(!TxdOp::vle(desc)); @@ -888,33 +917,33 @@ IGbE::TxDescCache::pktComplete() // Checksums are only ofloaded for new descriptor types if (TxdOp::isData(desc) && ( TxdOp::ixsm(desc) || TxdOp::txsm(desc)) ) { - DPRINTF(EthernetDesc, "TxDesc: Calculating checksums for packet\n"); + DPRINTF(EthernetDesc, "Calculating checksums for packet\n"); IpPtr ip(pktPtr); if (TxdOp::ixsm(desc)) { ip->sum(0); ip->sum(cksum(ip)); - DPRINTF(EthernetDesc, "TxDesc: Calculated IP checksum\n"); + DPRINTF(EthernetDesc, "Calculated IP checksum\n"); } if (TxdOp::txsm(desc)) { if (isTcp) { TcpPtr tcp(ip); tcp->sum(0); tcp->sum(cksum(tcp)); - DPRINTF(EthernetDesc, "TxDesc: Calculated TCP checksum\n"); + DPRINTF(EthernetDesc, "Calculated TCP checksum\n"); } else { UdpPtr udp(ip); udp->sum(0); udp->sum(cksum(udp)); - DPRINTF(EthernetDesc, "TxDesc: Calculated UDP checksum\n"); + DPRINTF(EthernetDesc, "Calculated UDP checksum\n"); } } } if (TxdOp::ide(desc)) { // Deal with the rx timer interrupts - DPRINTF(EthernetDesc, "TxDesc: Descriptor had IDE set\n"); + DPRINTF(EthernetDesc, "Descriptor had IDE set\n"); if (igbe->regs.tidv.idv()) { - DPRINTF(EthernetDesc, "TxDesc: setting tidv\n"); + DPRINTF(EthernetDesc, "setting tidv\n"); if (igbe->tidvEvent.scheduled()) igbe->tidvEvent.reschedule(curTick + igbe->regs.tidv.idv() * igbe->intClock()); @@ -924,7 +953,7 @@ IGbE::TxDescCache::pktComplete() } if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) { - DPRINTF(EthernetDesc, "TxDesc: setting tadv\n"); + DPRINTF(EthernetDesc, "setting tadv\n"); if (!igbe->tadvEvent.scheduled()) igbe->tadvEvent.schedule(curTick + igbe->regs.tadv.idv() * igbe->intClock()); @@ -939,17 +968,34 @@ IGbE::TxDescCache::pktComplete() pktWaiting = false; pktPtr = NULL; - hLen = 0; - DPRINTF(EthernetDesc, "TxDesc: Descriptor Done\n"); + DPRINTF(EthernetDesc, "Descriptor Done\n"); if (igbe->regs.txdctl.wthresh() == 0) { - DPRINTF(EthernetDesc, "TxDesc: WTHRESH == 0, writing back descriptor\n"); + DPRINTF(EthernetDesc, "WTHRESH == 0, writing back descriptor\n"); writeback(0); } else if (igbe->regs.txdctl.wthresh() >= usedCache.size()) { - DPRINTF(EthernetDesc, "TxDesc: used > WTHRESH, writing back descriptor\n"); + DPRINTF(EthernetDesc, "used > WTHRESH, writing back descriptor\n"); writeback((igbe->cacheBlockSize()-1)>>4); } + igbe->checkDrain(); +} +void +IGbE::TxDescCache::serialize(std::ostream &os) +{ + DescCache<TxDesc>::serialize(os); + SERIALIZE_SCALAR(pktDone); + SERIALIZE_SCALAR(isTcp); + SERIALIZE_SCALAR(pktWaiting); +} + +void +IGbE::TxDescCache::unserialize(Checkpoint *cp, const std::string §ion) +{ + DescCache<TxDesc>::unserialize(cp, section); + UNSERIALIZE_SCALAR(pktDone); + UNSERIALIZE_SCALAR(isTcp); + UNSERIALIZE_SCALAR(pktWaiting); } bool @@ -969,7 +1015,12 @@ IGbE::TxDescCache::enableSm() igbe->restartClock(); } - +bool +IGbE::TxDescCache::hasOutstandingEvents() +{ + return pktEvent.scheduled() || wbEvent.scheduled() || + fetchEvent.scheduled(); +} ///////////////////////////////////// IGbE ///////////////////////////////// @@ -977,10 +1028,61 @@ IGbE::TxDescCache::enableSm() void IGbE::restartClock() { - if (!tickEvent.scheduled() && (rxTick || txTick)) + if (!tickEvent.scheduled() && (rxTick || txTick) && getState() == + SimObject::Running) tickEvent.schedule((curTick/cycles(1)) * cycles(1) + cycles(1)); } +unsigned int +IGbE::drain(Event *de) +{ + unsigned int count; + count = pioPort->drain(de) + dmaPort->drain(de); + if (rxDescCache.hasOutstandingEvents() || + txDescCache.hasOutstandingEvents()) { + count++; + drainEvent = de; + } + + txFifoTick = false; + txTick = false; + rxTick = false; + + if (tickEvent.scheduled()) + tickEvent.deschedule(); + + if (count) + changeState(Draining); + else + changeState(Drained); + + return count; +} + +void +IGbE::resume() +{ + SimObject::resume(); + + txFifoTick = true; + txTick = true; + rxTick = true; + + restartClock(); +} + +void +IGbE::checkDrain() +{ + if (!drainEvent) + return; + + if (rxDescCache.hasOutstandingEvents() || + txDescCache.hasOutstandingEvents()) { + drainEvent->process(); + drainEvent = NULL; + } +} void IGbE::txStateMachine() @@ -998,8 +1100,10 @@ IGbE::txStateMachine() bool success; DPRINTF(EthernetSM, "TXS: packet placed in TX FIFO\n"); success = txFifo.push(txPacket); + txFifoTick = true; assert(success); txPacket = NULL; + txDescCache.writeback((cacheBlockSize()-1)>>4); return; } @@ -1021,6 +1125,7 @@ IGbE::txStateMachine() txDescCache.writeback(0); txTick = false; postInterrupt(IT_TXQE, true); + return; } @@ -1038,11 +1143,17 @@ IGbE::txStateMachine() "DMA of next packet\n", size); txFifo.reserve(size); txDescCache.getPacketData(txPacket); - } else { + } else if (size <= 0) { DPRINTF(EthernetSM, "TXS: No packets to get, writing back used descriptors\n"); txDescCache.writeback(0); + } else { + DPRINTF(EthernetSM, "TXS: FIFO full, stopping ticking until space " + "available in FIFO\n"); + txDescCache.writeback((cacheBlockSize()-1)>>4); + txTick = false; } + return; } } @@ -1095,9 +1206,9 @@ IGbE::rxStateMachine() } if (descLeft == 0) { - DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing writeback\n"); + DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing" + " writeback and stopping ticking\n"); rxDescCache.writeback(0); - DPRINTF(EthernetSM, "RXS: No descriptors left, stopping ticking\n"); rxTick = false; } @@ -1119,9 +1230,9 @@ IGbE::rxStateMachine() } if (rxDescCache.descUnused() == 0) { - DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n"); + DPRINTF(EthernetSM, "RXS: No descriptors available in cache, " + "fetching descriptors and stopping ticking\n"); rxTick = false; - DPRINTF(EthernetSM, "RXS: Fetching descriptors because none available\n"); rxDescCache.fetchDescriptors(); } return; @@ -1159,15 +1270,18 @@ void IGbE::txWire() { if (txFifo.empty()) { + txFifoTick = false; return; } - txTick = true; if (etherInt->sendPacket(txFifo.front())) { - DPRINTF(Ethernet, "TxFIFO: Successful transmit, bytes in fifo: %d\n", + DPRINTF(EthernetSM, "TxFIFO: Successful transmit, bytes available in fifo: %d\n", txFifo.avail()); txFifo.pop(); + } else { + // We'll get woken up when the packet ethTxDone() gets called + txFifoTick = false; } } @@ -1180,34 +1294,133 @@ IGbE::tick() if (rxTick) rxStateMachine(); - if (txTick) { + if (txTick) txStateMachine(); + + if (txFifoTick) txWire(); - } - if (rxTick || txTick) + + if (rxTick || txTick || txFifoTick) tickEvent.schedule(curTick + cycles(1)); } void IGbE::ethTxDone() { - // restart the state machines if they are stopped + // restart the tx state machines if they are stopped + // fifo to send another packet + // tx sm to put more data into the fifo + txFifoTick = true; txTick = true; + restartClock(); - DPRINTF(Ethernet, "TxFIFO: Transmission complete\n"); + DPRINTF(EthernetSM, "TxFIFO: Transmission complete\n"); } void IGbE::serialize(std::ostream &os) { - panic("Need to implemenet\n"); + PciDev::serialize(os); + + regs.serialize(os); + SERIALIZE_SCALAR(eeOpBits); + SERIALIZE_SCALAR(eeAddrBits); + SERIALIZE_SCALAR(eeDataBits); + SERIALIZE_SCALAR(eeOpcode); + SERIALIZE_SCALAR(eeAddr); + SERIALIZE_ARRAY(flash,iGbReg::EEPROM_SIZE); + + rxFifo.serialize("rxfifo", os); + txFifo.serialize("txfifo", os); + + bool txPktExists = txPacket; + SERIALIZE_SCALAR(txPktExists); + if (txPktExists) + txPacket->serialize("txpacket", os); + + Tick rdtr_time = 0, radv_time = 0, tidv_time = 0, tadv_time = 0, + inter_time = 0; + + if (rdtrEvent.scheduled()) + rdtr_time = rdtrEvent.when(); + SERIALIZE_SCALAR(rdtr_time); + + if (radvEvent.scheduled()) + radv_time = radvEvent.when(); + SERIALIZE_SCALAR(radv_time); + + if (tidvEvent.scheduled()) + rdtr_time = tidvEvent.when(); + SERIALIZE_SCALAR(tidv_time); + + if (tadvEvent.scheduled()) + rdtr_time = tadvEvent.when(); + SERIALIZE_SCALAR(tadv_time); + + if (interEvent.scheduled()) + rdtr_time = interEvent.when(); + SERIALIZE_SCALAR(inter_time); + + nameOut(os, csprintf("%s.TxDescCache", name())); + txDescCache.serialize(os); + + nameOut(os, csprintf("%s.RxDescCache", name())); + rxDescCache.serialize(os); } void IGbE::unserialize(Checkpoint *cp, const std::string §ion) { - panic("Need to implemenet\n"); + PciDev::unserialize(cp, section); + + regs.unserialize(cp, section); + UNSERIALIZE_SCALAR(eeOpBits); + UNSERIALIZE_SCALAR(eeAddrBits); + UNSERIALIZE_SCALAR(eeDataBits); + UNSERIALIZE_SCALAR(eeOpcode); + UNSERIALIZE_SCALAR(eeAddr); + UNSERIALIZE_ARRAY(flash,iGbReg::EEPROM_SIZE); + + rxFifo.unserialize("rxfifo", cp, section); + txFifo.unserialize("txfifo", cp, section); + + bool txPktExists; + UNSERIALIZE_SCALAR(txPktExists); + if (txPktExists) { + txPacket = new EthPacketData(16384); + txPacket->unserialize("txpacket", cp, section); + } + + rxTick = true; + txTick = true; + txFifoTick = true; + + Tick rdtr_time, radv_time, tidv_time, tadv_time, inter_time; + UNSERIALIZE_SCALAR(rdtr_time); + UNSERIALIZE_SCALAR(radv_time); + UNSERIALIZE_SCALAR(tidv_time); + UNSERIALIZE_SCALAR(tadv_time); + UNSERIALIZE_SCALAR(inter_time); + + if (rdtr_time) + rdtrEvent.schedule(rdtr_time); + + if (radv_time) + radvEvent.schedule(radv_time); + + if (tidv_time) + tidvEvent.schedule(tidv_time); + + if (tadv_time) + tadvEvent.schedule(tadv_time); + + if (inter_time) + interEvent.schedule(inter_time); + + txDescCache.unserialize(cp, csprintf("%s.TxDescCache", section)); + + rxDescCache.unserialize(cp, csprintf("%s.RxDescCache", section)); } diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh index a2b9f38d5..2dec3b08c 100644 --- a/src/dev/i8254xGBe.hh +++ b/src/dev/i8254xGBe.hh @@ -62,8 +62,10 @@ class IGbE : public PciDev uint8_t eeOpcode, eeAddr; uint16_t flash[iGbReg::EEPROM_SIZE]; + // The drain event if we have one + Event *drainEvent; + // cached parameters from params struct - Tick tickRate; bool useFlowControl; // packet fifos @@ -76,24 +78,44 @@ class IGbE : public PciDev // Should to Rx/Tx State machine tick? bool rxTick; bool txTick; + bool txFifoTick; // Event and function to deal with RDTR timer expiring - void rdtrProcess() { rxDescCache.writeback(0); postInterrupt(iGbReg::IT_RXT, true); } + void rdtrProcess() { + rxDescCache.writeback(0); + DPRINTF(EthernetIntr, "Posting RXT interrupt because RDTR timer expired\n"); + postInterrupt(iGbReg::IT_RXT, true); + } + //friend class EventWrapper<IGbE, &IGbE::rdtrProcess>; EventWrapper<IGbE, &IGbE::rdtrProcess> rdtrEvent; // Event and function to deal with RADV timer expiring - void radvProcess() { rxDescCache.writeback(0); postInterrupt(iGbReg::IT_RXT, true); } + void radvProcess() { + rxDescCache.writeback(0); + DPRINTF(EthernetIntr, "Posting RXT interrupt because RADV timer expired\n"); + postInterrupt(iGbReg::IT_RXT, true); + } + //friend class EventWrapper<IGbE, &IGbE::radvProcess>; EventWrapper<IGbE, &IGbE::radvProcess> radvEvent; // Event and function to deal with TADV timer expiring - void tadvProcess() { postInterrupt(iGbReg::IT_TXDW, true); } + void tadvProcess() { + txDescCache.writeback(0); + DPRINTF(EthernetIntr, "Posting TXDW interrupt because TADV timer expired\n"); + postInterrupt(iGbReg::IT_TXDW, true); + } + //friend class EventWrapper<IGbE, &IGbE::tadvProcess>; EventWrapper<IGbE, &IGbE::tadvProcess> tadvEvent; // Event and function to deal with TIDV timer expiring - void tidvProcess() { postInterrupt(iGbReg::IT_TXDW, true); }; + void tidvProcess() { + txDescCache.writeback(0); + DPRINTF(EthernetIntr, "Posting TXDW interrupt because TIDV timer expired\n"); + postInterrupt(iGbReg::IT_TXDW, true); + } //friend class EventWrapper<IGbE, &IGbE::tidvProcess>; EventWrapper<IGbE, &IGbE::tidvProcess> tidvEvent; @@ -131,8 +153,15 @@ class IGbE : public PciDev Tick intClock() { return Clock::Int::ns * 1024; } + /** This function is used to restart the clock so it can handle things like + * draining and resume in one place. */ void restartClock(); + /** Check if all the draining things that need to occur have occured and + * handle the drain event if so. + */ + void checkDrain(); + template<class T> class DescCache { @@ -202,8 +231,10 @@ class IGbE : public PciDev */ void areaChanged() { - if (usedCache.size() > 0 || unusedCache.size() > 0) + if (usedCache.size() > 0 || curFetching || wbOut) panic("Descriptor Address, Length or Head changed. Bad\n"); + reset(); + } void writeback(Addr aMask) @@ -229,7 +260,7 @@ class IGbE : public PciDev moreToWb = false; wbAlignment = aMask; - if (max_to_wb + curHead > descLen()) { + if (max_to_wb + curHead >= descLen()) { max_to_wb = descLen() - curHead; moreToWb = true; // this is by definition aligned correctly @@ -265,10 +296,14 @@ class IGbE : public PciDev */ void fetchDescriptors() { - size_t max_to_fetch = descTail() - cachePnt; - if (max_to_fetch < 0) + size_t max_to_fetch; + + if (descTail() >= cachePnt) + max_to_fetch = descTail() - cachePnt; + else max_to_fetch = descLen() - cachePnt; + max_to_fetch = std::min(max_to_fetch, (size - usedCache.size() - unusedCache.size())); @@ -311,8 +346,9 @@ class IGbE : public PciDev #endif cachePnt += curFetching; - if (cachePnt > descLen()) - cachePnt -= descLen(); + assert(cachePnt <= descLen()); + if (cachePnt == descLen()) + cachePnt = 0; curFetching = 0; @@ -320,7 +356,7 @@ class IGbE : public PciDev oldCp, cachePnt); enableSm(); - + igbe->checkDrain(); } EventWrapper<DescCache, &DescCache::fetchComplete> fetchEvent; @@ -337,8 +373,8 @@ class IGbE : public PciDev curHead += wbOut; wbOut = 0; - if (curHead > descLen()) - curHead = 0; + if (curHead >= descLen()) + curHead -= descLen(); // Update the head updateHead(curHead); @@ -352,6 +388,7 @@ class IGbE : public PciDev writeback(wbAlignment); } intAfterWb(); + igbe->checkDrain(); } @@ -390,6 +427,63 @@ class IGbE : public PciDev usedCache.clear(); unusedCache.clear(); + + cachePnt = 0; + + } + + virtual void serialize(std::ostream &os) + { + SERIALIZE_SCALAR(cachePnt); + SERIALIZE_SCALAR(curFetching); + SERIALIZE_SCALAR(wbOut); + SERIALIZE_SCALAR(moreToWb); + SERIALIZE_SCALAR(wbAlignment); + + int usedCacheSize = usedCache.size(); + SERIALIZE_SCALAR(usedCacheSize); + for(int x = 0; x < usedCacheSize; x++) { + arrayParamOut(os, csprintf("usedCache_%d", x), + (uint8_t*)usedCache[x],sizeof(T)); + } + + int unusedCacheSize = unusedCache.size(); + SERIALIZE_SCALAR(unusedCacheSize); + for(int x = 0; x < unusedCacheSize; x++) { + arrayParamOut(os, csprintf("unusedCache_%d", x), + (uint8_t*)unusedCache[x],sizeof(T)); + } + } + + virtual void unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(cachePnt); + UNSERIALIZE_SCALAR(curFetching); + UNSERIALIZE_SCALAR(wbOut); + UNSERIALIZE_SCALAR(moreToWb); + UNSERIALIZE_SCALAR(wbAlignment); + + int usedCacheSize; + UNSERIALIZE_SCALAR(usedCacheSize); + T *temp; + for(int x = 0; x < usedCacheSize; x++) { + temp = new T; + arrayParamIn(cp, section, csprintf("usedCache_%d", x), + (uint8_t*)temp,sizeof(T)); + usedCache.push_back(temp); + } + + int unusedCacheSize; + UNSERIALIZE_SCALAR(unusedCacheSize); + for(int x = 0; x < unusedCacheSize; x++) { + temp = new T; + arrayParamIn(cp, section, csprintf("unusedCache_%d", x), + (uint8_t*)temp,sizeof(T)); + unusedCache.push_back(temp); + } + } + virtual bool hasOutstandingEvents() { + return wbEvent.scheduled() || fetchEvent.scheduled(); } }; @@ -428,6 +522,10 @@ class IGbE : public PciDev EventWrapper<RxDescCache, &RxDescCache::pktComplete> pktEvent; + virtual bool hasOutstandingEvents(); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; friend class RxDescCache; @@ -447,7 +545,6 @@ class IGbE : public PciDev bool pktDone; bool isTcp; bool pktWaiting; - int hLen; public: TxDescCache(IGbE *i, std::string n, int s); @@ -475,6 +572,11 @@ class IGbE : public PciDev void pktComplete(); EventWrapper<TxDescCache, &TxDescCache::pktComplete> pktEvent; + virtual bool hasOutstandingEvents(); + + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; friend class TxDescCache; @@ -513,7 +615,8 @@ class IGbE : public PciDev virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - + virtual unsigned int drain(Event *de); + virtual void resume(); }; diff --git a/src/dev/i8254xGBe_defs.hh b/src/dev/i8254xGBe_defs.hh index 8538c155b..91b3eacc9 100644 --- a/src/dev/i8254xGBe_defs.hh +++ b/src/dev/i8254xGBe_defs.hh @@ -162,7 +162,7 @@ struct TxDesc { namespace TxdOp { const uint8_t TXD_CNXT = 0x0; -const uint8_t TXD_DATA = 0x0; +const uint8_t TXD_DATA = 0x1; bool isLegacy(TxDesc *d) { return !bits(d->d2,29,29); } uint8_t getType(TxDesc *d) { return bits(d->d2, 23,20); } @@ -220,6 +220,14 @@ struct Regs { bool operator==(T d) { return d == _data; } void operator()(T d) { _data = d; } Reg() { _data = 0; } + void serialize(std::ostream &os) + { + SERIALIZE_SCALAR(_data); + } + void unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(_data); + } }; struct CTRL : public Reg<uint32_t> { // 0x0000 CTRL Register @@ -595,6 +603,79 @@ struct Regs { ADD_FIELD32(smbclkout,30,1); // smb clock out }; MANC manc; -}; -}; // iGbReg namespace + void serialize(std::ostream &os) + { + paramOut(os, "ctrl", ctrl._data); + paramOut(os, "sts", sts._data); + paramOut(os, "eecd", eecd._data); + paramOut(os, "eerd", eerd._data); + paramOut(os, "ctrl_ext", ctrl_ext._data); + paramOut(os, "mdic", mdic._data); + paramOut(os, "icr", icr._data); + SERIALIZE_SCALAR(imr); + paramOut(os, "itr", itr._data); + SERIALIZE_SCALAR(iam); + paramOut(os, "rctl", rctl._data); + paramOut(os, "fcttv", fcttv._data); + paramOut(os, "tctl", tctl._data); + paramOut(os, "pba", pba._data); + paramOut(os, "fcrtl", fcrtl._data); + paramOut(os, "fcrth", fcrth._data); + paramOut(os, "rdba", rdba._data); + paramOut(os, "rdlen", rdlen._data); + paramOut(os, "rdh", rdh._data); + paramOut(os, "rdt", rdt._data); + paramOut(os, "rdtr", rdtr._data); + paramOut(os, "rxdctl", rxdctl._data); + paramOut(os, "radv", radv._data); + paramOut(os, "rsrpd", rsrpd._data); + paramOut(os, "tdba", tdba._data); + paramOut(os, "tdlen", tdlen._data); + paramOut(os, "tdh", tdh._data); + paramOut(os, "tdt", tdt._data); + paramOut(os, "tidv", tidv._data); + paramOut(os, "txdctl", txdctl._data); + paramOut(os, "tadv", tadv._data); + paramOut(os, "rxcsum", rxcsum._data); + paramOut(os, "manc", manc._data); + } + + void unserialize(Checkpoint *cp, const std::string §ion) + { + paramIn(cp, section, "ctrl", ctrl._data); + paramIn(cp, section, "sts", sts._data); + paramIn(cp, section, "eecd", eecd._data); + paramIn(cp, section, "eerd", eerd._data); + paramIn(cp, section, "ctrl_ext", ctrl_ext._data); + paramIn(cp, section, "mdic", mdic._data); + paramIn(cp, section, "icr", icr._data); + UNSERIALIZE_SCALAR(imr); + paramIn(cp, section, "itr", itr._data); + UNSERIALIZE_SCALAR(iam); + paramIn(cp, section, "rctl", rctl._data); + paramIn(cp, section, "fcttv", fcttv._data); + paramIn(cp, section, "tctl", tctl._data); + paramIn(cp, section, "pba", pba._data); + paramIn(cp, section, "fcrtl", fcrtl._data); + paramIn(cp, section, "fcrth", fcrth._data); + paramIn(cp, section, "rdba", rdba._data); + paramIn(cp, section, "rdlen", rdlen._data); + paramIn(cp, section, "rdh", rdh._data); + paramIn(cp, section, "rdt", rdt._data); + paramIn(cp, section, "rdtr", rdtr._data); + paramIn(cp, section, "rxdctl", rxdctl._data); + paramIn(cp, section, "radv", radv._data); + paramIn(cp, section, "rsrpd", rsrpd._data); + paramIn(cp, section, "tdba", tdba._data); + paramIn(cp, section, "tdlen", tdlen._data); + paramIn(cp, section, "tdh", tdh._data); + paramIn(cp, section, "tdt", tdt._data); + paramIn(cp, section, "tidv", tidv._data); + paramIn(cp, section, "txdctl", txdctl._data); + paramIn(cp, section, "tadv", tadv._data); + paramIn(cp, section, "rxcsum", rxcsum._data); + paramIn(cp, section, "manc", manc._data); + } +}; +} // iGbReg namespace |