summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/sparc/miscregfile.cc6
-rw-r--r--src/cpu/o3/commit_impl.hh16
-rw-r--r--src/cpu/o3/decode_impl.hh6
-rw-r--r--src/cpu/o3/fetch_impl.hh5
-rw-r--r--src/cpu/o3/iew_impl.hh7
-rw-r--r--src/cpu/o3/inst_queue_impl.hh11
-rw-r--r--src/cpu/o3/lsq_impl.hh13
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh2
-rw-r--r--src/cpu/o3/rename_impl.hh10
-rw-r--r--src/cpu/o3/rob_impl.hh4
-rw-r--r--src/cpu/o3/sparc/cpu_builder.cc7
-rw-r--r--src/dev/i8254xGBe.cc317
-rw-r--r--src/dev/i8254xGBe.hh135
-rw-r--r--src/dev/i8254xGBe_defs.hh87
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 &section)
+{
+ 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 &section)
+{
+ 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 &section)
{
- 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 &section)
+ {
+ 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 &section);
};
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 &section);
+
};
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 &section);
-
+ 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 &section)
+ {
+ 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 &section)
+ {
+ 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