summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--README56
-rw-r--r--SConscript9
-rw-r--r--arch/alpha/ev5.hh1
-rw-r--r--arch/alpha/vtophys.cc2
-rw-r--r--base/match.cc96
-rw-r--r--base/match.hh57
-rw-r--r--base/mysql.cc13
-rw-r--r--base/mysql.hh10
-rw-r--r--base/statistics.cc3
-rw-r--r--base/stats/events.cc39
-rw-r--r--base/stats/mysql.cc156
-rw-r--r--base/stats/mysql.hh7
-rw-r--r--base/stats/statdb.cc4
-rw-r--r--base/trace.cc50
-rw-r--r--base/trace.hh24
-rw-r--r--base/traceflags.py4
-rw-r--r--configs/boot/client.netperf.maerts33
-rw-r--r--configs/boot/client.netperf.rr33
-rw-r--r--configs/boot/client.netperf.stream33
-rw-r--r--configs/boot/server.netperf17
-rw-r--r--cpu/simple_cpu/simple_cpu.cc19
-rw-r--r--cpu/simple_cpu/simple_cpu.hh11
-rw-r--r--cpu/trace/reader/ibm_reader.cc2
-rw-r--r--cpu/trace/reader/ibm_reader.hh2
-rw-r--r--cpu/trace/reader/itx_reader.cc2
-rw-r--r--cpu/trace/reader/itx_reader.hh2
-rw-r--r--cpu/trace/reader/m5_reader.cc2
-rw-r--r--cpu/trace/reader/m5_reader.hh2
-rw-r--r--cpu/trace/reader/mem_trace_reader.cc2
-rw-r--r--cpu/trace/reader/mem_trace_reader.hh2
-rw-r--r--cpu/trace/trace_cpu.cc2
-rw-r--r--cpu/trace/trace_cpu.hh2
-rw-r--r--dev/baddev.cc5
-rw-r--r--dev/disk_image.cc2
-rw-r--r--dev/etherdump.cc15
-rw-r--r--dev/etherdump.hh3
-rw-r--r--dev/etherlink.hh2
-rw-r--r--dev/ide_ctrl.cc9
-rw-r--r--dev/ide_ctrl.hh2
-rw-r--r--dev/ide_disk.cc4
-rw-r--r--dev/io_device.cc2
-rw-r--r--dev/io_device.hh1
-rw-r--r--dev/ns_gige.cc526
-rw-r--r--dev/ns_gige.hh48
-rw-r--r--dev/pciconfigall.cc10
-rw-r--r--dev/pciconfigall.hh2
-rw-r--r--dev/tsunami_cchip.cc11
-rw-r--r--dev/tsunami_cchip.hh3
-rw-r--r--dev/tsunami_io.cc10
-rw-r--r--dev/tsunami_io.hh3
-rw-r--r--dev/tsunami_pchip.cc10
-rw-r--r--dev/tsunami_pchip.hh3
-rw-r--r--dev/uart.cc13
-rw-r--r--dev/uart.hh3
-rw-r--r--kern/kernel_stats.cc1
-rw-r--r--kern/linux/linux_system.cc18
-rw-r--r--kern/linux/linux_system.hh5
-rw-r--r--kern/linux/printk.cc265
-rw-r--r--kern/linux/printk.hh36
-rw-r--r--kern/tru64/dump_mbuf.cc4
-rw-r--r--sim/eventq.cc17
-rw-r--r--sim/sim_object.cc36
-rw-r--r--sim/sim_object.hh6
-rw-r--r--sim/stat_control.cc8
-rw-r--r--util/ccdrv/devtime.c44
66 files changed, 1321 insertions, 505 deletions
diff --git a/LICENSE b/LICENSE
index 8ecb95578..3c9fd6627 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2000-2003 The Regents of The University of Michigan
+Copyright (c) 2000-2004 The Regents of The University of Michigan
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README b/README
index f5651ec00..fe5b99f23 100644
--- a/README
+++ b/README
@@ -1,4 +1,3 @@
-
This is release m5_1.0_beta1 of the M5 simulator.
This file contains brief "getting started" information and release
@@ -13,13 +12,23 @@ distribution. The archive you've unpacked has three subdirectories:
- m5: the simulator itself
- m5-test: regression tests and scripts to run them
- ext: less-common external packages needed to build m5
- (currently just "ply")
+ (currently ply and libelf)
+
+M5 is a capable, full-system simulator that current supports both Linux
+2.4/2.6 and the proprietary Compaq/HP Tru64 version of Unix. We are able
+to distribute Linux bootdisks, but we are unable to distribute bootable
+disk images of Tru64 Unix. If you have a Tru64 license and are interested
+in obtaining disk images, contact us at m5-dev@eecs.umich.edu.
+
+WHAT'S NEEDED
+-------------
+-GCC(3.X)
+-Python(2.2.2+)
-Although M5 is capable of full-system simulation, the only OS it
-currently supports is the proprietary Compaq/HP Tru64 version of Unix.
-We are thus unable to distribute bootable disk images freely. If you
-have a Tru64 license and are interested in obtaining disk images,
-contact us at m5-dev@eecs.umich.edu.
+WHAT'S RECOMMENDED
+------------------
+-MySQL (for statistics complex statistics storage/retrieval)
+-Python-MysqlDB (for statistics analysis)
GETTING STARTED
---------------
@@ -28,24 +37,23 @@ The following steps will build and test the simulator. The variable
"$top" refers to the top directory where you've unpacked the files,
i.e., the one containing the m5, m5-test, and ext directories.
-cd $top/m5/setup
-./setup ALPHA # set up build/ALPHA directory
-cd $top/m5/build/ALPHA
-make m5.opt # use "-j N" if you've got an MP system
-# wait for build...
+There are three different build targets and three optimizations in each level:
+Target:
+-------
+ALPHA - Syscall emulation simulation
+KERNEL - Linux full system simulation
+KERNEL_TLASER - Tru64 Unix full system simulation
+
+Optimization:
+-------------
+m5.debug - debug version of the code with tracing and without optimization
+m5.opt - optimized version of code with tracing
+m5.fast - optimized version of the code without tracing and asserts
+
+cd $top/m5/build
+scons TARGET/OPTLEVL # e.g. KERNEL/m5.opt, use -j N if you have a MP system
cd $top/m5-test
./do-tests.pl -B ALPHA # test what you just built
+./do-tests.pl -B KERNEL # test what you just built
# wait for tests to run...
# should end with "finished do-tests successfully!"
-
-If you run into errors regarding m5/arch/alpha/decoder.cc, just
-"touch" that file to update its timestamp. This file is generated
-from a compact ISA description using a program written in Python. If
-you have Python 2.2.2 or later installed on your system, you should be
-able to generate it yourself, but if you don't have Python (or have an
-older version), you may run in to trouble. Since we've shipped a
-working copy of decoder.cc, it's not necessary to have Python to build
-M5 (unless you start modifying the ISA decription). Unfortunately,
-sometimes make gets confused and tries to do so anyway. The "touch"
-should convince make to stop trying.
-
diff --git a/SConscript b/SConscript
index 7d8d9f50e..60e703e9b 100644
--- a/SConscript
+++ b/SConscript
@@ -59,6 +59,7 @@ base_sources = Split('''
base/hybrid_pred.cc
base/inifile.cc
base/intmath.cc
+ base/match.cc
base/misc.cc
base/pollevent.cc
base/python.cc
@@ -162,6 +163,9 @@ base_sources = Split('''
mem/cache/tags/fa_lru.cc
mem/cache/tags/iic.cc
mem/cache/tags/lru.cc
+ mem/cache/tags/split.cc
+ mem/cache/tags/split_lifo.cc
+ mem/cache/tags/split_lru.cc
mem/cache/tags/repl/gen.cc
mem/cache/tags/repl/repl.cc
mem/functional_mem/functional_memory.cc
@@ -216,6 +220,7 @@ full_system_sources = Split('''
dev/simconsole.cc
dev/disk_image.cc
dev/dma.cc
+ dev/etherbus.cc
dev/etherdump.cc
dev/etherint.cc
dev/etherlink.cc
@@ -254,6 +259,7 @@ full_system_sources = Split('''
kern/linux/linux_events.cc
kern/linux/linux_syscalls.cc
kern/linux/linux_system.cc
+ kern/linux/printk.cc
kern/tru64/dump_mbuf.cc
kern/tru64/printf.cc
kern/tru64/tru64_events.cc
@@ -310,7 +316,8 @@ env.Command(Split('''arch/alpha/decoder.cc
arch/alpha/fast_cpu_exec.cc
arch/alpha/simple_cpu_exec.cc
arch/alpha/full_cpu_exec.cc'''),
- 'arch/alpha/isa_desc',
+ Split('''arch/alpha/isa_desc
+ arch/isa_parser.py'''),
'$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/alpha')
diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh
index 5b27dd3dc..f49eadeb0 100644
--- a/arch/alpha/ev5.hh
+++ b/arch/alpha/ev5.hh
@@ -123,5 +123,6 @@
#define PAL_BASE 0x4000
+#define PAL_MAX 0x10000
#endif //__EV5_H__
diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc
index 464ed41e6..5468d4b07 100644
--- a/arch/alpha/vtophys.cc
+++ b/arch/alpha/vtophys.cc
@@ -98,7 +98,7 @@ vtophys(ExecContext *xc, Addr vaddr)
Addr paddr = 0;
//@todo Andrew couldn't remember why he commented some of this code
//so I put it back in. Perhaps something to do with gdb debugging?
- if (PC_PAL(vaddr)) {
+ if (PC_PAL(vaddr) && (vaddr < PAL_MAX)) {
paddr = vaddr & ~ULL(1);
} else {
if (vaddr >= ALPHA_K0SEG_BASE && vaddr <= ALPHA_K0SEG_END) {
diff --git a/base/match.cc b/base/match.cc
new file mode 100644
index 000000000..ba5c2181c
--- /dev/null
+++ b/base/match.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2001-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * 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.
+ */
+
+#include "base/match.hh"
+#include "base/str.hh"
+
+using namespace std;
+
+ObjectMatch::ObjectMatch()
+{
+}
+
+ObjectMatch::ObjectMatch(const string &expr)
+{
+ setExpression(expr);
+}
+
+void
+ObjectMatch::setExpression(const string &expr)
+{
+ tokens.resize(1);
+ tokenize(tokens[0], expr, '.');
+}
+
+void
+ObjectMatch::setExpression(const vector<string> &expr)
+{
+ if (expr.empty()) {
+ tokens.resize(0);
+ } else {
+ tokens.resize(expr.size());
+ for (int i = 0; i < expr.size(); ++i)
+ tokenize(tokens[i], expr[i], '.');
+ }
+}
+
+/**
+ * @todo this should probably be changed to just use regular
+ * expression code
+ */
+bool
+ObjectMatch::domatch(const string &name) const
+{
+ vector<string> name_tokens;
+ tokenize(name_tokens, name, '.');
+ int ntsize = name_tokens.size();
+
+ int num_expr = tokens.size();
+ for (int i = 0; i < num_expr; ++i) {
+ const vector<string> &token = tokens[i];
+ int jstop = token.size();
+
+ bool match = true;
+ for (int j = 0; j < jstop; ++j) {
+ if (j >= ntsize)
+ break;
+
+ const string &var = token[j];
+ if (var != "*" && var != name_tokens[j]) {
+ match = false;
+ break;
+ }
+ }
+
+ if (match == true)
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/base/match.hh b/base/match.hh
new file mode 100644
index 000000000..8831ed424
--- /dev/null
+++ b/base/match.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2001-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * 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.
+ */
+
+/* @file
+ * User Console Definitions
+ */
+
+#ifndef __BASE_MATCH_HH__
+#define __BASE_MATCH_HH__
+
+#include <string>
+#include <vector>
+
+class ObjectMatch
+{
+ protected:
+ std::vector<std::vector<std::string> > tokens;
+ bool domatch(const std::string &name) const;
+
+ public:
+ ObjectMatch();
+ ObjectMatch(const std::string &expression);
+ void setExpression(const std::string &expression);
+ void setExpression(const std::vector<std::string> &expression);
+ bool match(const std::string &name) const
+ {
+ return tokens.empty() ? false : domatch(name);
+ }
+};
+
+#endif // __BASE_MATCH_HH__
+
diff --git a/base/mysql.cc b/base/mysql.cc
index 8481e74e2..15e12fdeb 100644
--- a/base/mysql.cc
+++ b/base/mysql.cc
@@ -29,6 +29,7 @@
#include <iostream>
#include "base/mysql.hh"
+#include "base/trace.hh"
using namespace std;
@@ -94,4 +95,16 @@ Connection::close()
mysql_close(&mysql);
}
+bool
+Connection::query(const string &sql)
+{
+ DPRINTF(SQL, "Sending SQL query to server:\n%s", sql);
+ error.clear();
+ if (mysql_real_query(&mysql, sql.c_str(), sql.size()))
+ error.set(mysql_error(&mysql));
+
+ return error;
+}
+
+
/* namespace MySQL */ }
diff --git a/base/mysql.hh b/base/mysql.hh
index 89bec73d0..58a1bf7c2 100644
--- a/base/mysql.hh
+++ b/base/mysql.hh
@@ -177,15 +177,7 @@ class Connection
operator MYSQL *() { return &mysql; }
public:
- bool
- query(const std::string &sql)
- {
- error.clear();
- if (mysql_real_query(&mysql, sql.c_str(), sql.size()))
- error.set(mysql_error(&mysql));
-
- return error;
- }
+ bool query(const std::string &sql);
bool
query(const std::stringstream &sql)
diff --git a/base/statistics.cc b/base/statistics.cc
index 78012bff7..6e3dae1ef 100644
--- a/base/statistics.cc
+++ b/base/statistics.cc
@@ -273,7 +273,8 @@ check()
for (i = Database::stats().begin(); i != end; ++i) {
StatData *data = *i;
assert(data);
- data->check();
+ if (!data->check() || !data->baseCheck())
+ panic("stat check failed for %s\n", data->name);
}
int j = 0;
diff --git a/base/stats/events.cc b/base/stats/events.cc
index ed25e2423..e5efceabe 100644
--- a/base/stats/events.cc
+++ b/base/stats/events.cc
@@ -35,50 +35,21 @@
#include "base/stats/events.hh"
#include "base/stats/mysql.hh"
#include "base/stats/mysql_run.hh"
+#include "base/str.hh"
#endif
-#include "base/str.hh"
+#include "base/match.hh"
#include "sim/host.hh"
+#include "sim/sim_object.hh"
#include "sim/universe.hh"
using namespace std;
namespace Stats {
-Tick EventStart = ULL(0xffffffffffffffff);
-
-vector<string> event_ignore;
-vector<vector<string> > ignore_tokens;
-vector<int> ignore_size;
-int event_ignore_size;
+Tick EventStart = ULL(0x7fffffffffffffff);
-bool
-ignoreEvent(const string &name)
-{
- vector<string> name_tokens;
- tokenize(name_tokens, name, '.');
- int ntsize = name_tokens.size();
-
- for (int i = 0; i < event_ignore_size; ++i) {
- bool match = true;
- int jstop = ignore_size[i];
- for (int j = 0; j < jstop; ++j) {
- if (j >= ntsize)
- break;
-
- const string &ignore = ignore_tokens[i][j];
- if (ignore != "*" && ignore != name_tokens[j]) {
- match = false;
- break;
- }
- }
-
- if (match == true)
- return true;
- }
-
- return false;
-}
+ObjectMatch event_ignore;
#ifdef USE_MYSQL
class InsertEvent
diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc
index 4c2a60127..523494743 100644
--- a/base/stats/mysql.cc
+++ b/base/stats/mysql.cc
@@ -67,9 +67,16 @@ MySqlRun::connect(const string &host, const string &user, const string &passwd,
if (mysql.error)
panic("could not connect to database server\n%s\n", mysql.error);
+ mysql.query("LOCK TABLES runs WRITE");
+ if (mysql.error)
+ panic("could not lock tables\n%s\n", mysql.error);
+
remove(name);
- cleanup();
+// cleanup();
setup(name, sample, user, project);
+ mysql.query("UNLOCK TABLES");
+ if (mysql.error)
+ panic("could not unlock tables\n%s\n", mysql.error);
}
void
@@ -100,6 +107,8 @@ MySqlRun::remove(const string &name)
stringstream sql;
ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name);
mysql.query(sql);
+ if (mysql.error)
+ panic("could not delete run\n%s\n", mysql.error);
}
void
@@ -195,13 +204,13 @@ SetupStat::setup()
mysql.query(select);
MySQL::Result result = mysql.store_result();
if (!result)
- panic("could not get a run\n%s\n", mysql.error);
+ panic("could not find stat\n%s\n", mysql.error);
assert(result.num_fields() == 16);
MySQL::Row row = result.fetch_row();
if (!row)
- panic("could not get a run\n%s\n", mysql.error);
+ panic("could not get stat row\n%s\n", mysql.error);
bool tb;
int8_t ti8;
@@ -274,33 +283,52 @@ SetupStat::setup()
unsigned
SetupBin(const string &bin)
{
- MySQL::Connection &mysql = MySqlDB.conn();
- assert(mysql.connected());
+ static map<string, int> binmap;
using namespace MySQL;
+ map<string,int>::const_iterator i = binmap.find(bin);
+ if (i != binmap.end())
+ return (*i).second;
+
+ Connection &mysql = MySqlDB.conn();
+ assert(mysql.connected());
+
+ mysql.query("LOCK TABLES bins WRITE");
+ if (mysql.error)
+ panic("could not lock bin table\n%s\n", mysql.error);
+
+ uint16_t bin_id;
+
stringstream select;
+ stringstream insert;
ccprintf(select, "SELECT bn_id FROM bins WHERE bn_name=\"%s\"", bin);
mysql.query(select);
MySQL::Result result = mysql.store_result();
if (result) {
assert(result.num_fields() == 1);
- Row row = result.fetch_row();
+ MySQL::Row row = result.fetch_row();
if (row) {
- uint16_t bin_id;
to_number(row[0], bin_id);
- return bin_id;
+ goto exit;
}
}
- stringstream insert;
ccprintf(insert, "INSERT INTO bins(bn_name) values(\"%s\")", bin);
mysql.query(insert);
if (mysql.error)
- panic("could not get a run\n%s\n", mysql.error);
+ panic("could not get a bin\n%s\n", mysql.error);
+
+ bin_id = mysql.insert_id();
+ binmap.insert(make_pair(bin, bin_id));
- return mysql.insert_id();
+ exit:
+ mysql.query("UNLOCK TABLES");
+ if (mysql.error)
+ panic("could not unlock tables\n%s\n", mysql.error);
+
+ return bin_id;
}
InsertData::InsertData()
@@ -322,13 +350,15 @@ InsertData::flush()
MySQL::Connection &mysql = MySqlDB.conn();
assert(mysql.connected());
mysql.query(query);
+ if (mysql.error)
+ panic("could not insert data\n%s\n", mysql.error);
}
query[0] = '\0';
size = 0;
first = true;
strcpy(query, "INSERT INTO "
- "data(dt_stat,dt_x,dt_y,dt_run,dt_sample,dt_bin,dt_data) "
+ "data(dt_stat,dt_x,dt_y,dt_run,dt_tick,dt_bin,dt_data) "
"values");
size = strlen(query);
}
@@ -347,7 +377,7 @@ InsertData::insert()
first = false;
size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")",
- stat, x, y, MySqlDB.run(), (unsigned long long)sample,
+ stat, x, y, MySqlDB.run(), (unsigned long long)tick,
bin, data);
}
@@ -374,6 +404,8 @@ InsertSubData::setup()
stat, x, y, name, descr);
mysql.query(insert);
+// if (mysql.error)
+// panic("could not insert subdata\n%s\n", mysql.error);
}
void
@@ -387,13 +419,17 @@ InsertFormula(uint16_t stat, const string &formula)
stat, formula);
mysql.query(insert_formula);
+// if (mysql.error)
+// panic("could not insert formula\n%s\n", mysql.error);
stringstream insert_ref;
ccprintf(insert_ref,
"INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)",
stat, MySqlDB.run());
- mysql.query(insert_ref);
+ mysql.query(insert_ref);
+// if (mysql.error)
+// panic("could not insert formula reference\n%s\n", mysql.error);
}
void
@@ -405,6 +441,8 @@ UpdatePrereq(uint16_t stat, uint16_t prereq)
ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d",
prereq, stat);
mysql.query(update);
+ if (mysql.error)
+ panic("could not update prereq\n%s\n", mysql.error);
}
void
@@ -414,6 +452,17 @@ MySql::configure()
* set up all stats!
*/
using namespace Database;
+
+ MySQL::Connection &mysql = MySqlDB.conn();
+ mysql.query("LOCK TABLES "
+ "stats WRITE, "
+ "bins WRITE, "
+ "subdata WRITE, "
+ "formulas WRITE, "
+ "formula_ref WRITE");
+ if (mysql.error)
+ panic("could not lock tables\n%s\n", mysql.error);
+
stat_list_t::const_iterator i, end = stats().end();
for (i = stats().begin(); i != end; ++i)
(*i)->visit(*this);
@@ -429,11 +478,15 @@ MySql::configure()
}
}
+ mysql.query("UNLOCK TABLES");
+ if (mysql.error)
+ panic("could not unlock tables\n%s\n", mysql.error);
+
configured = true;
}
-void
+bool
MySql::configure(const StatData &data, string type)
{
stat.init();
@@ -447,19 +500,25 @@ MySql::configure(const StatData &data, string type)
stat.total = data.flags & total;
stat.pdf = data.flags & pdf;
stat.cdf = data.flags & cdf;
+
+ return stat.print;
}
void
MySql::configure(const ScalarData &data)
{
- configure(data, "SCALAR");
+ if (!configure(data, "SCALAR"))
+ return;
+
insert(data.id, stat.setup());
}
void
MySql::configure(const VectorData &data)
{
- configure(data, "VECTOR");
+ if (!configure(data, "VECTOR"))
+ return;
+
uint16_t statid = stat.setup();
if (!data.subnames.empty()) {
@@ -482,7 +541,9 @@ MySql::configure(const VectorData &data)
void
MySql::configure(const DistData &data)
{
- configure(data, "DIST");
+ if (!configure(data, "DIST"))
+ return;
+
if (!data.data.fancy) {
stat.size = data.data.size;
stat.min = data.data.min;
@@ -495,7 +556,8 @@ MySql::configure(const DistData &data)
void
MySql::configure(const VectorDistData &data)
{
- configure(data, "VECTORDIST");
+ if (!configure(data, "VECTORDIST"))
+ return;
if (!data.data[0].fancy) {
stat.size = data.data[0].size;
@@ -525,13 +587,15 @@ MySql::configure(const VectorDistData &data)
void
MySql::configure(const Vector2dData &data)
{
- configure(data, "VECTOR2D");
+ if (!configure(data, "VECTOR2D"))
+ return;
+
uint16_t statid = stat.setup();
if (!data.subnames.empty()) {
InsertSubData subdata;
subdata.stat = statid;
- subdata.y = 0;
+ subdata.y = -1;
for (int i = 0; i < data.subnames.size(); ++i) {
subdata.x = i;
subdata.name = data.subnames[i];
@@ -544,7 +608,7 @@ MySql::configure(const Vector2dData &data)
if (!data.y_subnames.empty()) {
InsertSubData subdata;
subdata.stat = statid;
- subdata.x = 0;
+ subdata.x = -1;
subdata.descr = "";
for (int i = 0; i < data.y_subnames.size(); ++i) {
subdata.y = i;
@@ -562,17 +626,25 @@ MySql::configure(const FormulaData &data)
{
configure(data, "FORMULA");
insert(data.id, stat.setup());
+ InsertFormula(find(data.id), data.str());
}
void
-MySql::output(const string &bin)
+MySql::output(MainBin *bin)
{
- // set up new bin in database if there is a bin name
- newdata.bin = bin.empty() ? 0 : SetupBin(bin);
+ if (bin) {
+ bin->activate();
+ newdata.bin = SetupBin(bin->name());
+ } else {
+ newdata.bin = 0;
+ }
Database::stat_list_t::const_iterator i, end = Database::stats().end();
- for (i = Database::stats().begin(); i != end; ++i)
- (*i)->visit(*this);
+ for (i = Database::stats().begin(); i != end; ++i) {
+ StatData *stat = *i;
+ if (bin && stat->binned() || !bin && !stat->binned())
+ stat->visit(*this);
+ }
}
bool
@@ -591,17 +663,13 @@ MySql::output()
configure();
// store sample #
- newdata.sample = curTick;
+ newdata.tick = curTick;
- if (bins().empty()) {
- output(string(""));
- } else {
+ output(NULL);
+ if (!bins().empty()) {
bin_list_t::iterator i, end = bins().end();
- for (i = bins().begin(); i != end; ++i) {
- MainBin *bin = *i;
- bin->activate();
- output(bin->name());
- }
+ for (i = bins().begin(); i != end; ++i)
+ output(*i);
}
newdata.flush();
@@ -610,6 +678,9 @@ MySql::output()
void
MySql::output(const ScalarData &data)
{
+ if (!(data.flags & print))
+ return;
+
newdata.stat = find(data.id);
newdata.x = 0;
newdata.y = 0;
@@ -621,6 +692,9 @@ MySql::output(const ScalarData &data)
void
MySql::output(const VectorData &data)
{
+ if (!(data.flags & print))
+ return;
+
newdata.stat = find(data.id);
newdata.y = 0;
@@ -686,6 +760,9 @@ MySql::output(const DistDataData &data)
void
MySql::output(const DistData &data)
{
+ if (!(data.flags & print))
+ return;
+
newdata.stat = find(data.id);
newdata.y = 0;
output(data.data);
@@ -694,6 +771,9 @@ MySql::output(const DistData &data)
void
MySql::output(const VectorDistData &data)
{
+ if (!(data.flags & print))
+ return;
+
newdata.stat = find(data.id);
int size = data.data.size();
@@ -706,6 +786,9 @@ MySql::output(const VectorDistData &data)
void
MySql::output(const Vector2dData &data)
{
+ if (!(data.flags & print))
+ return;
+
newdata.stat = find(data.id);
int index = 0;
@@ -722,7 +805,6 @@ MySql::output(const Vector2dData &data)
void
MySql::output(const FormulaData &data)
{
- InsertFormula(find(data.id), data.str());
}
/*
diff --git a/base/stats/mysql.hh b/base/stats/mysql.hh
index 5780009d7..5b6d8a138 100644
--- a/base/stats/mysql.hh
+++ b/base/stats/mysql.hh
@@ -37,6 +37,7 @@
namespace MySQL { class Connection; }
namespace Stats {
+class MainBin;
class DistDataData;
class MySqlRun;
bool MySqlConnected();
@@ -76,7 +77,7 @@ class InsertData
MySqlRun *run;
public:
- uint64_t sample;
+ uint64_t tick;
double data;
uint16_t stat;
uint16_t bin;
@@ -130,7 +131,7 @@ class MySql : public Output
protected:
// Output helper
- void output(const std::string &bin);
+ void output(MainBin *bin);
void output(const DistDataData &data);
void output(const ScalarData &data);
void output(const VectorData &data);
@@ -140,7 +141,7 @@ class MySql : public Output
void output(const FormulaData &data);
void configure();
- void configure(const StatData &data, std::string type);
+ bool configure(const StatData &data, std::string type);
void configure(const ScalarData &data);
void configure(const VectorData &data);
void configure(const DistData &data);
diff --git a/base/stats/statdb.cc b/base/stats/statdb.cc
index eed3d6296..66871b9f7 100644
--- a/base/stats/statdb.cc
+++ b/base/stats/statdb.cc
@@ -51,6 +51,10 @@ find(void *stat)
void
regBin(MainBin *bin, const std::string &_name)
{
+ bin_list_t::iterator i, end = bins().end();
+ for (i = bins().begin(); i != end; ++i)
+ if ((*i)->name() == _name)
+ panic("re-registering bin %s", _name);
bins().push_back(bin);
DPRINTF(Stats, "registering %s\n", _name);
}
diff --git a/base/trace.cc b/base/trace.cc
index aa82ee403..bc6c9aa7a 100644
--- a/base/trace.cc
+++ b/base/trace.cc
@@ -51,39 +51,7 @@ FlagVec flags(NumFlags, false);
//
ostream *dprintf_stream = &cerr;
-int dprintf_ignore_size;
-vector<string> dprintf_ignore;
-vector<vector<string> > ignore_tokens;
-vector<int> ignore_size;
-
-bool
-dprintf_ignore_name(const string &name)
-{
- vector<string> name_tokens;
- tokenize(name_tokens, name, '.');
- int ntsize = name_tokens.size();
-
- for (int i = 0; i < dprintf_ignore_size; ++i) {
- bool match = true;
- int jstop = ignore_size[i];
- for (int j = 0; j < jstop; ++j) {
- if (j >= ntsize)
- break;
-
- const string &ignore = ignore_tokens[i][j];
- if (ignore != "*" && ignore != name_tokens[j]) {
- match = false;
- break;
- }
- }
-
- if (match == true)
- return true;
- }
-
- return false;
-}
-
+ObjectMatch ignore;
Log theLog;
@@ -184,7 +152,6 @@ PrintfRecord::~PrintfRecord()
delete &args;
}
-
void
PrintfRecord::dump(ostream &os)
{
@@ -206,29 +173,26 @@ PrintfRecord::dump(ostream &os)
os.flush();
}
-
-
-RawDataRecord::RawDataRecord(Tick _cycle, const void *_data, int _len)
- : Record(_cycle), len(_len)
+DataRecord::DataRecord(Tick _cycle, const string &_name,
+ const void *_data, int _len)
+ : Record(_cycle), name(_name), len(_len)
{
data = new uint8_t[len];
memcpy(data, _data, len);
}
-
-RawDataRecord::~RawDataRecord()
+DataRecord::~DataRecord()
{
delete [] data;
}
-
void
-RawDataRecord::dump(ostream &os)
+DataRecord::dump(ostream &os)
{
int c, i, j;
for (i = 0; i < len; i += 16) {
- ccprintf(os, "%08x ", i);
+ ccprintf(os, "%d: %s: %08x ", cycle, name, i);
c = len - i;
if (c > 16) c = 16;
diff --git a/base/trace.hh b/base/trace.hh
index 60ea015ea..1aadb36cf 100644
--- a/base/trace.hh
+++ b/base/trace.hh
@@ -32,6 +32,7 @@
#include <vector>
#include "base/cprintf.hh"
+#include "base/match.hh"
#include "sim/host.hh"
#include "sim/universe.hh"
@@ -69,7 +70,7 @@ namespace Trace {
class Record
{
protected:
- Tick cycle;
+ Tick cycle;
Record(Tick _cycle)
: cycle(_cycle)
@@ -101,15 +102,17 @@ namespace Trace {
virtual void dump(std::ostream &);
};
- class RawDataRecord : public Record
+ class DataRecord : public Record
{
private:
+ const std::string &name;
uint8_t *data;
int len;
public:
- RawDataRecord(Tick cycle, const void *_data, int _len);
- virtual ~RawDataRecord();
+ DataRecord(Tick cycle, const std::string &name,
+ const void *_data, int _len);
+ virtual ~DataRecord();
virtual void dump(std::ostream &);
};
@@ -135,23 +138,20 @@ namespace Trace {
extern Log theLog;
- extern int dprintf_ignore_size;
-
- bool
- dprintf_ignore_name(const std::string &name);
+ extern ObjectMatch ignore;
inline void
dprintf(const char *format, cp::ArgList &args, Tick cycle,
const std::string &name)
{
- if (!dprintf_ignore_size || name.empty() || !dprintf_ignore_name(name))
+ if (name.empty() || !ignore.match(name))
theLog.append(new Trace::PrintfRecord(format, args, cycle, name));
}
inline void
- rawDump(const void *data, int len)
+ dataDump(Tick cycle, const std::string &name, const void *data, int len)
{
- theLog.append(new Trace::RawDataRecord(curTick, data, len));
+ theLog.append(new Trace::DataRecord(cycle, name, data, len));
}
extern const std::string DefaultName;
@@ -180,7 +180,7 @@ std::ostream &DebugOut();
#define DDUMP(x, data, count) \
do { \
if (Trace::IsOn(Trace::x)) \
- Trace::rawDump(data, count); \
+ Trace::dataDump(curTick, name(), data, count); \
} while (0)
#define __dprintf(cycle, name, format, args...) \
diff --git a/base/traceflags.py b/base/traceflags.py
index 8e1594b24..4be61d7ee 100644
--- a/base/traceflags.py
+++ b/base/traceflags.py
@@ -120,7 +120,9 @@ baseFlags = [
'IdeCtrl',
'IdeDisk',
'Tsunami',
- 'Uart'
+ 'Uart',
+ 'Split',
+ 'SQL'
]
#
diff --git a/configs/boot/client.netperf.maerts b/configs/boot/client.netperf.maerts
new file mode 100644
index 000000000..f1335c020
--- /dev/null
+++ b/configs/boot/client.netperf.maerts
@@ -0,0 +1,33 @@
+#!/bin/sh
+SERVER=10.0.0.1
+CLIENT=10.0.0.2
+
+echo "setting up network..."
+ifconfig lo 127.0.0.1
+ifconfig eth0 $CLIENT
+
+echo -n "waiting for server..."
+/usr/bin/netcat -c -l -p 8000
+
+BINARY=/benchmarks/netperf/netperf
+TEST="TCP_MAERTS"
+SHORT_ARGS="-l -100k"
+LONG_ARGS="-k16384,0 -K16384,0 -- -m 65536 -M 65536 -s 262144 -S 262144"
+
+
+SHORT="$BINARY -H $SERVER -t $TEST $SHORT_ARGS"
+LONG="$BINARY -H $SERVER -t $TEST $LONG_ARGS"
+
+echo "starting test..."
+echo "netperf warmup"
+echo $SHORT
+eval $SHORT
+
+echo "netperf benchmark"
+echo $LONG
+/sbin/m5 ivlb 1
+/sbin/m5 resetstats
+/sbin/m5 dumpresetstats 2000000000 2000000000
+/sbin/m5 checkpoint 2000000000 2000000000
+eval $LONG
+/sbin/m5 exit
diff --git a/configs/boot/client.netperf.rr b/configs/boot/client.netperf.rr
new file mode 100644
index 000000000..aafc569e7
--- /dev/null
+++ b/configs/boot/client.netperf.rr
@@ -0,0 +1,33 @@
+#!/bin/sh
+SERVER=10.0.0.1
+CLIENT=10.0.0.2
+
+echo "setting up network..."
+ifconfig lo 127.0.0.1
+ifconfig eth0 $CLIENT
+
+echo -n "waiting for server..."
+/usr/bin/netcat -c -l -p 8000
+
+BINARY=/benchmarks/netperf/netperf
+TEST="TCP_RR"
+SHORT_ARGS="-l -1k"
+LONG_ARGS="-k10000,0 -K10000,0"
+
+
+SHORT="$BINARY -H $SERVER -t $TEST $SHORT_ARGS"
+LONG="$BINARY -H $SERVER -t $TEST $LONG_ARGS"
+
+echo "starting test..."
+echo "netperf warmup"
+echo $SHORT
+eval $SHORT
+
+echo "netperf benchmark"
+echo $LONG
+/sbin/m5 ivlb 1
+/sbin/m5 resetstats
+/sbin/m5 dumpresetstats 2000000000 2000000000
+/sbin/m5 checkpoint 2000000000 2000000000
+eval $LONG
+/sbin/m5 exit
diff --git a/configs/boot/client.netperf.stream b/configs/boot/client.netperf.stream
new file mode 100644
index 000000000..f04228cd4
--- /dev/null
+++ b/configs/boot/client.netperf.stream
@@ -0,0 +1,33 @@
+#!/bin/sh
+SERVER=10.0.0.1
+CLIENT=10.0.0.2
+
+echo "setting up network..."
+ifconfig lo 127.0.0.1
+ifconfig eth0 $CLIENT
+
+echo -n "waiting for server..."
+/usr/bin/netcat -c -l -p 8000
+
+BINARY=/benchmarks/netperf/netperf
+TEST="TCP_STREAM"
+SHORT_ARGS="-l -100k"
+LONG_ARGS="-k16384,0 -K16384,0 -- -m 65536 -M 65536 -s 262144 -S 262144"
+
+
+SHORT="$BINARY -H $SERVER -t $TEST $SHORT_ARGS"
+LONG="$BINARY -H $SERVER -t $TEST $LONG_ARGS"
+
+echo "starting test..."
+echo "netperf warmup"
+echo $SHORT
+eval $SHORT
+
+echo "netperf benchmark"
+echo $LONG
+/sbin/m5 ivlb 1
+/sbin/m5 resetstats
+/sbin/m5 dumpresetstats 2000000000 2000000000
+/sbin/m5 checkpoint 2000000000 2000000000
+eval $LONG
+/sbin/m5 exit
diff --git a/configs/boot/server.netperf b/configs/boot/server.netperf
new file mode 100644
index 000000000..a62bc171e
--- /dev/null
+++ b/configs/boot/server.netperf
@@ -0,0 +1,17 @@
+#!/bin/sh
+SERVER=10.0.0.1
+CLIENT=10.0.0.2
+
+echo "setting up network..."
+ifconfig lo 127.0.0.1
+ifconfig eth0 $SERVER
+
+echo "running netserver..."
+/benchmarks/netperf/netserver
+
+echo -n "signal client to begin..."
+echo "server ready" | /usr/bin/netcat -c $CLIENT 8000
+echo "done."
+
+echo "starting bash..."
+exec /bin/bash
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index d70f0ccfa..6c22d7c81 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -75,14 +75,17 @@
using namespace std;
SimpleCPU::TickEvent::TickEvent(SimpleCPU *c)
- : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
+ : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), multiplier(1)
{
}
void
SimpleCPU::TickEvent::process()
{
- cpu->tick();
+ int count = multiplier;
+ do {
+ cpu->tick();
+ } while (--count > 0 && cpu->status() == Running);
}
const char *
@@ -269,6 +272,11 @@ SimpleCPU::regStats()
.desc("Number of memory references")
;
+ notIdleFraction
+ .name(name() + ".not_idle_fraction")
+ .desc("Percentage of non-idle cycles")
+ ;
+
idleFraction
.name(name() + ".idle_fraction")
.desc("Percentage of idle cycles")
@@ -799,6 +807,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
SimObjectParam<BaseMem *> dcache;
Param<bool> defer_registration;
+ Param<int> multiplier;
END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
@@ -830,7 +839,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL),
INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL),
INIT_PARAM_DFLT(defer_registration, "defer registration with system "
- "(for sampling)", false)
+ "(for sampling)", false),
+
+ INIT_PARAM_DFLT(multiplier, "clock multiplier", 1)
END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
@@ -861,6 +872,8 @@ CREATE_SIM_OBJECT(SimpleCPU)
#endif // FULL_SYSTEM
+ cpu->setTickMultiplier(multiplier);
+
return cpu;
}
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 3692ab511..6ab231e7e 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -68,12 +68,11 @@ class SimpleCPU : public BaseCPU
void tick();
private:
- class TickEvent : public Event
+ struct TickEvent : public Event
{
- private:
SimpleCPU *cpu;
+ int multiplier;
- public:
TickEvent(SimpleCPU *c);
void process();
const char *description();
@@ -97,6 +96,12 @@ class SimpleCPU : public BaseCPU
tickEvent.squash();
}
+ public:
+ void setTickMultiplier(int multiplier)
+ {
+ tickEvent.multiplier = multiplier;
+ }
+
private:
Trace::InstRecord *traceData;
template<typename T>
diff --git a/cpu/trace/reader/ibm_reader.cc b/cpu/trace/reader/ibm_reader.cc
index 439931dba..7ca32fe21 100644
--- a/cpu/trace/reader/ibm_reader.cc
+++ b/cpu/trace/reader/ibm_reader.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/ibm_reader.hh b/cpu/trace/reader/ibm_reader.hh
index 0f14da24d..f7e3ae149 100644
--- a/cpu/trace/reader/ibm_reader.hh
+++ b/cpu/trace/reader/ibm_reader.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/itx_reader.cc b/cpu/trace/reader/itx_reader.cc
index 54bbbc4ea..593d383ec 100644
--- a/cpu/trace/reader/itx_reader.cc
+++ b/cpu/trace/reader/itx_reader.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/itx_reader.hh b/cpu/trace/reader/itx_reader.hh
index ff74062ea..0e08d5db5 100644
--- a/cpu/trace/reader/itx_reader.hh
+++ b/cpu/trace/reader/itx_reader.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/m5_reader.cc b/cpu/trace/reader/m5_reader.cc
index d081f0bc0..c5b807824 100644
--- a/cpu/trace/reader/m5_reader.cc
+++ b/cpu/trace/reader/m5_reader.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/m5_reader.hh b/cpu/trace/reader/m5_reader.hh
index d78787461..296c99ccf 100644
--- a/cpu/trace/reader/m5_reader.hh
+++ b/cpu/trace/reader/m5_reader.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/mem_trace_reader.cc b/cpu/trace/reader/mem_trace_reader.cc
index c6fc53f51..441e72b80 100644
--- a/cpu/trace/reader/mem_trace_reader.cc
+++ b/cpu/trace/reader/mem_trace_reader.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/reader/mem_trace_reader.hh b/cpu/trace/reader/mem_trace_reader.hh
index 5da99a498..6b6f804af 100644
--- a/cpu/trace/reader/mem_trace_reader.hh
+++ b/cpu/trace/reader/mem_trace_reader.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/trace_cpu.cc b/cpu/trace/trace_cpu.cc
index 6122fc786..94f311d4b 100644
--- a/cpu/trace/trace_cpu.cc
+++ b/cpu/trace/trace_cpu.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpu/trace/trace_cpu.hh b/cpu/trace/trace_cpu.hh
index 13a204f4e..6f3ef50a6 100644
--- a/cpu/trace/trace_cpu.hh
+++ b/cpu/trace/trace_cpu.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/dev/baddev.cc b/dev/baddev.cc
index 8b552e989..7c563e80a 100644
--- a/dev/baddev.cc
+++ b/dev/baddev.cc
@@ -78,7 +78,7 @@ BadDevice::write(MemReqPtr &req, const uint8_t *data)
Tick
BadDevice::cacheAccess(MemReqPtr &req)
{
- return curTick + 1000;
+ return curTick;
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
@@ -103,7 +103,8 @@ END_INIT_SIM_OBJECT_PARAMS(BadDevice)
CREATE_SIM_OBJECT(BadDevice)
{
- return new BadDevice(getInstanceName(), addr, mmu, hier, io_bus, devicename);
+ return new BadDevice(getInstanceName(), addr, mmu, hier, io_bus,
+ devicename);
}
REGISTER_SIM_OBJECT("BadDevice", BadDevice)
diff --git a/dev/disk_image.cc b/dev/disk_image.cc
index f9e1c2fe3..20e693d0d 100644
--- a/dev/disk_image.cc
+++ b/dev/disk_image.cc
@@ -427,7 +427,7 @@ CowDiskImage::serialize(ostream &os)
{
string cowFilename = name() + ".cow";
SERIALIZE_SCALAR(cowFilename);
- save(cowFilename);
+ save(Checkpoint::dir() + "/" + cowFilename);
}
void
diff --git a/dev/etherdump.cc b/dev/etherdump.cc
index 54e573be4..27817d456 100644
--- a/dev/etherdump.cc
+++ b/dev/etherdump.cc
@@ -32,6 +32,7 @@
#include <sys/time.h>
+#include <algorithm>
#include <string>
#include "base/misc.hh"
@@ -41,8 +42,8 @@
using std::string;
-EtherDump::EtherDump(const string &name, const string &file)
- : SimObject(name)
+EtherDump::EtherDump(const string &name, const string &file, int max)
+ : SimObject(name), maxlen(max)
{
if (!file.empty())
stream.open(file.c_str());
@@ -113,22 +114,24 @@ EtherDump::dumpPacket(PacketPtr &packet)
pcap_pkthdr pkthdr;
pkthdr.seconds = curtime + (curTick / s_freq);
pkthdr.microseconds = (curTick / us_freq) % ULL(1000000);
- pkthdr.caplen = packet->length;
+ pkthdr.caplen = std::min(packet->length, maxlen);
pkthdr.len = packet->length;
stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
- stream.write(reinterpret_cast<char *>(packet->data), packet->length);
+ stream.write(reinterpret_cast<char *>(packet->data), pkthdr.caplen);
stream.flush();
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
Param<string> file;
+ Param<int> maxlen;
END_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump)
- INIT_PARAM(file, "file to dump packets to")
+ INIT_PARAM(file, "file to dump packets to"),
+ INIT_PARAM_DFLT(maxlen, "max portion of packet data to dump", 96)
END_INIT_SIM_OBJECT_PARAMS(EtherDump)
@@ -148,7 +151,7 @@ CREATE_SIM_OBJECT(EtherDump)
}
}
- return new EtherDump(getInstanceName(), filename);
+ return new EtherDump(getInstanceName(), filename, maxlen);
}
REGISTER_SIM_OBJECT("EtherDump", EtherDump)
diff --git a/dev/etherdump.hh b/dev/etherdump.hh
index ef4399e1a..62364359e 100644
--- a/dev/etherdump.hh
+++ b/dev/etherdump.hh
@@ -44,6 +44,7 @@ class EtherDump : public SimObject
{
private:
std::ofstream stream;
+ const int maxlen;
void dumpPacket(PacketPtr &packet);
void init();
@@ -52,7 +53,7 @@ class EtherDump : public SimObject
Tick us_freq;
public:
- EtherDump(const std::string &name, const std::string &file);
+ EtherDump(const std::string &name, const std::string &file, int max);
inline void dump(PacketPtr &pkt) { if (stream.is_open()) dumpPacket(pkt); }
};
diff --git a/dev/etherlink.hh b/dev/etherlink.hh
index 4f227fac5..204348c6d 100644
--- a/dev/etherlink.hh
+++ b/dev/etherlink.hh
@@ -105,7 +105,7 @@ class EtherLink : public SimObject
public:
Interface(const std::string &name, Link *txlink, Link *rxlink);
bool recvPacket(PacketPtr &packet) { return txlink->transmit(packet); }
- void sendDone() { }
+ void sendDone() { peer->sendDone(); }
};
Link *link1;
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index 4805570d2..e40248461 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -60,7 +60,7 @@ IdeController::IdeController(const string &name, IntrControl *ic,
MemoryController *mmu, PciConfigAll *cf,
PciConfigData *cd, Tsunami *t, uint32_t bus_num,
uint32_t dev_num, uint32_t func_num,
- Bus *host_bus, HierParams *hier)
+ Bus *host_bus, Tick pio_latency, HierParams *hier)
: PciDev(name, mmu, cf, cd, bus_num, dev_num, func_num), tsunami(t)
{
// put back pointer into Tsunami
@@ -105,6 +105,7 @@ IdeController::IdeController(const string &name, IntrControl *ic,
dmaInterface = new DMAInterface<Bus>(name + ".dma", host_bus,
host_bus, 1);
+ pioLatency = pio_latency * host_bus->clockRatio;
}
// setup the disks attached to controller
@@ -261,7 +262,7 @@ Tick
IdeController::cacheAccess(MemReqPtr &req)
{
// @todo Add more accurate timing to cache access
- return curTick + 1000;
+ return curTick + pioLatency;
}
////
@@ -700,6 +701,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
SimObjectParam<Bus *> io_bus;
+ Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(IdeController)
@@ -716,6 +718,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
INIT_PARAM(pci_dev, "PCI device number"),
INIT_PARAM(pci_func, "PCI function code"),
INIT_PARAM_DFLT(io_bus, "Host bus to attach to", NULL),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
END_INIT_SIM_OBJECT_PARAMS(IdeController)
@@ -724,7 +727,7 @@ CREATE_SIM_OBJECT(IdeController)
{
return new IdeController(getInstanceName(), intr_ctrl, disks, mmu,
configspace, configdata, tsunami, pci_bus,
- pci_dev, pci_func, io_bus, hier);
+ pci_dev, pci_func, io_bus, pio_latency, hier);
}
REGISTER_SIM_OBJECT("IdeController", IdeController)
diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh
index 39c64eb30..b29e5ae9a 100644
--- a/dev/ide_ctrl.hh
+++ b/dev/ide_ctrl.hh
@@ -167,7 +167,7 @@ class IdeController : public PciDev
MemoryController *mmu, PciConfigAll *cf,
PciConfigData *cd, Tsunami *t,
uint32_t bus_num, uint32_t dev_num, uint32_t func_num,
- Bus *host_bus, HierParams *hier);
+ Bus *host_bus, Tick pio_latency, HierParams *hier);
/**
* Deletes the connected devices.
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index ee21feaea..99724f077 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -341,8 +341,8 @@ IdeDisk::dmaPrdReadDone()
curPrd.getByteCount(), (cmdBytesLeft/SectorSize),
curPrd.getEOT(), curSector);
- // make sure the new curPrdAddr is properly translated from PCI to system
- curPrdAddr = pciToDma(curPrdAddr + sizeof(PrdEntry_t));
+ // the prd pointer has already been translated, so just do an increment
+ curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
if (dmaRead)
doDmaRead();
diff --git a/dev/io_device.cc b/dev/io_device.cc
index b39efa1f5..7703ad5e3 100644
--- a/dev/io_device.cc
+++ b/dev/io_device.cc
@@ -32,7 +32,7 @@
#include "sim/builder.hh"
PioDevice::PioDevice(const std::string &name)
- : FunctionalMemory(name), pioInterface(NULL)
+ : FunctionalMemory(name), pioInterface(NULL), pioLatency(0)
{}
PioDevice::~PioDevice()
diff --git a/dev/io_device.hh b/dev/io_device.hh
index e6014e73d..f49afc0a6 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -40,6 +40,7 @@ class PioDevice : public FunctionalMemory
{
protected:
BaseInterface *pioInterface;
+ Tick pioLatency;
public:
PioDevice(const std::string &name);
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index f88fc507f..22c0ba35d 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -38,8 +38,10 @@
#include "cpu/exec_context.hh"
#include "cpu/intr_control.hh"
#include "dev/dma.hh"
-#include "dev/ns_gige.hh"
#include "dev/etherlink.hh"
+#include "dev/ns_gige.hh"
+#include "dev/pciconfigall.hh"
+#include "dev/tsunami_cchip.hh"
#include "mem/bus/bus.hh"
#include "mem/bus/dma_interface.hh"
#include "mem/bus/pio_interface.hh"
@@ -47,11 +49,10 @@
#include "mem/functional_mem/memory_control.hh"
#include "mem/functional_mem/physical_memory.hh"
#include "sim/builder.hh"
+#include "sim/debug.hh"
#include "sim/host.hh"
#include "sim/sim_stats.hh"
#include "targetarch/vtophys.hh"
-#include "dev/pciconfigall.hh"
-#include "dev/tsunami_cchip.hh"
const char *NsRxStateStrings[] =
{
@@ -86,8 +87,9 @@ const char *NsDmaState[] =
using namespace std;
-//helper function declarations
-//These functions reverse Endianness so we can evaluate network data correctly
+// helper function declarations
+// These functions reverse Endianness so we can evaluate network data
+// correctly
uint16_t reverseEnd16(uint16_t);
uint32_t reverseEnd32(uint32_t);
@@ -96,19 +98,21 @@ uint32_t reverseEnd32(uint32_t);
// NSGigE PCI Device
//
NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
- PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
- MemoryController *mmu, HierParams *hier, Bus *header_bus,
- Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
- bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
- Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
- PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
- uint32_t func, bool rx_filter, const int eaddr[6])
+ PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
+ MemoryController *mmu, HierParams *hier, Bus *header_bus,
+ Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
+ bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
+ Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
+ PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
+ uint32_t func, bool rx_filter, const int eaddr[6],
+ uint32_t tx_fifo_size, uint32_t rx_fifo_size)
: PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), ioEnable(false),
+ maxTxFifoSize(tx_fifo_size), maxRxFifoSize(rx_fifo_size),
txPacket(0), rxPacket(0), txPacketBufPtr(NULL), rxPacketBufPtr(NULL),
- txXferLen(0), rxXferLen(0), txState(txIdle), CTDD(false),
- txFifoAvail(MAX_TX_FIFO_SIZE), txHalt(false),
+ txXferLen(0), rxXferLen(0), txState(txIdle), txEnable(false),
+ CTDD(false), txFifoAvail(tx_fifo_size),
txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle),
- CRDD(false), rxPktBytes(0), rxFifoCnt(0), rxHalt(false),
+ rxEnable(false), CRDD(false), rxPktBytes(0), rxFifoCnt(0),
rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false),
rxDmaReadEvent(this), rxDmaWriteEvent(this),
txDmaReadEvent(this), txDmaWriteEvent(this),
@@ -118,7 +122,7 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
acceptMulticast(false), acceptUnicast(false),
acceptPerfect(false), acceptArp(false),
physmem(pmem), intctrl(i), intrTick(0), cpuPendingIntr(false),
- intrEvent(0), interface(0), pioLatency(pio_latency)
+ intrEvent(0), interface(0)
{
tsunami->ethernet = this;
@@ -126,6 +130,8 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
pioInterface = newPioInterface(name, hier, header_bus, this,
&NSGigE::cacheAccess);
+ pioLatency = pio_latency * header_bus->clockRatio;
+
if (payload_bus)
dmaInterface = new DMAInterface<Bus>(name + ".dma",
header_bus, payload_bus, 1);
@@ -136,9 +142,10 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
pioInterface = newPioInterface(name, hier, payload_bus, this,
&NSGigE::cacheAccess);
+ pioLatency = pio_latency * payload_bus->clockRatio;
+
dmaInterface = new DMAInterface<Bus>(name + ".dma", payload_bus,
payload_bus, 1);
-
}
@@ -299,9 +306,9 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data)
// Need to catch writes to BARs to update the PIO interface
switch (offset) {
- //seems to work fine without all these PCI settings, but i put in the IO
- //to double check, an assertion will fail if we need to properly
- // implement it
+ // seems to work fine without all these PCI settings, but i
+ // put in the IO to double check, an assertion will fail if we
+ // need to properly implement it
case PCI_COMMAND:
if (config.data[offset] & PCI_CMD_IOSE)
ioEnable = true;
@@ -327,22 +334,20 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data)
case PCI0_BASE_ADDR0:
if (BARAddrs[0] != 0) {
-
if (pioInterface)
- pioInterface->addAddrRange(BARAddrs[0], BARAddrs[0] + BARSize[0] - 1);
+ pioInterface->addAddrRange(BARAddrs[0],
+ BARAddrs[0] + BARSize[0] - 1);
BARAddrs[0] &= PA_UNCACHED_MASK;
-
}
break;
case PCI0_BASE_ADDR1:
if (BARAddrs[1] != 0) {
-
if (pioInterface)
- pioInterface->addAddrRange(BARAddrs[1], BARAddrs[1] + BARSize[1] - 1);
+ pioInterface->addAddrRange(BARAddrs[1],
+ BARAddrs[1] + BARSize[1] - 1);
BARAddrs[1] &= PA_UNCACHED_MASK;
-
}
break;
}
@@ -363,8 +368,8 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
daddr, req->paddr, req->vaddr, req->size);
- //there are some reserved registers, you can see ns_gige_reg.h and
- //the spec sheet for details
+ // there are some reserved registers, you can see ns_gige_reg.h and
+ // the spec sheet for details
if (daddr > LAST && daddr <= RESERVED) {
panic("Accessing reserved register");
} else if (daddr > RESERVED && daddr <= 0x3FC) {
@@ -461,10 +466,11 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
reg = regs.pcr;
break;
- //see the spec sheet for how RFCR and RFDR work
- //basically, you write to RFCR to tell the machine what you want to do next
- //then you act upon RFDR, and the device will be prepared b/c
- //of what you wrote to RFCR
+ // see the spec sheet for how RFCR and RFDR work
+ // basically, you write to RFCR to tell the machine
+ // what you want to do next, then you act upon RFDR,
+ // and the device will be prepared b/c of what you
+ // wrote to RFCR
case RFCR:
reg = regs.rfcr;
break;
@@ -485,8 +491,9 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
reg += rom.perfectMatch[4];
break;
default:
- panic("reading from RFDR for something for other than PMATCH!\n");
- //didn't implement other RFDR functionality b/c driver didn't use
+ panic("reading RFDR for something other than PMATCH!\n");
+ // didn't implement other RFDR functionality b/c
+ // driver didn't use it
}
break;
@@ -540,7 +547,7 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
break;
default:
- panic("reading unimplemented register: addr = %#x", daddr);
+ panic("reading unimplemented register: addr=%#x", daddr);
}
DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
@@ -580,24 +587,23 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
switch (daddr) {
case CR:
regs.command = reg;
- if ((reg & (CR_TXE | CR_TXD)) == (CR_TXE | CR_TXD)) {
- txHalt = true;
+ if (reg & CR_TXD) {
+ txEnable = false;
} else if (reg & CR_TXE) {
- //the kernel is enabling the transmit machine
+ txEnable = true;
+
+ // the kernel is enabling the transmit machine
if (txState == txIdle)
txKick();
- } else if (reg & CR_TXD) {
- txHalt = true;
}
- if ((reg & (CR_RXE | CR_RXD)) == (CR_RXE | CR_RXD)) {
- rxHalt = true;
+ if (reg & CR_RXD) {
+ rxEnable = false;
} else if (reg & CR_RXE) {
- if (rxState == rxIdle) {
+ rxEnable = true;
+
+ if (rxState == rxIdle)
rxKick();
- }
- } else if (reg & CR_RXD) {
- rxHalt = true;
}
if (reg & CR_TXR)
@@ -618,26 +624,34 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
break;
case CFG:
- if (reg & CFG_LNKSTS || reg & CFG_SPDSTS || reg & CFG_DUPSTS
- || reg & CFG_RESERVED || reg & CFG_T64ADDR
- || reg & CFG_PCI64_DET)
+ if (reg & CFG_LNKSTS ||
+ reg & CFG_SPDSTS ||
+ reg & CFG_DUPSTS ||
+ reg & CFG_RESERVED ||
+ reg & CFG_T64ADDR ||
+ reg & CFG_PCI64_DET)
panic("writing to read-only or reserved CFG bits!\n");
- regs.config |= reg & ~(CFG_LNKSTS | CFG_SPDSTS | CFG_DUPSTS | CFG_RESERVED |
- CFG_T64ADDR | CFG_PCI64_DET);
+ regs.config |= reg & ~(CFG_LNKSTS | CFG_SPDSTS | CFG_DUPSTS |
+ CFG_RESERVED | CFG_T64ADDR | CFG_PCI64_DET);
-// all these #if 0's are because i don't THINK the kernel needs to have these implemented
-// if there is a problem relating to one of these, you may need to add functionality in
+// all these #if 0's are because i don't THINK the kernel needs to
+// have these implemented. if there is a problem relating to one of
+// these, you may need to add functionality in.
#if 0
- if (reg & CFG_TBI_EN) ;
- if (reg & CFG_MODE_1000) ;
+ if (reg & CFG_TBI_EN) ;
+ if (reg & CFG_MODE_1000) ;
#endif
if (reg & CFG_AUTO_1000)
panic("CFG_AUTO_1000 not implemented!\n");
#if 0
- if (reg & CFG_PINT_DUPSTS || reg & CFG_PINT_LNKSTS || reg & CFG_PINT_SPDSTS) ;
+ if (reg & CFG_PINT_DUPSTS ||
+ reg & CFG_PINT_LNKSTS ||
+ reg & CFG_PINT_SPDSTS)
+ ;
+
if (reg & CFG_TMRTEST) ;
if (reg & CFG_MRM_DIS) ;
if (reg & CFG_MWI_DIS) ;
@@ -673,11 +687,12 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
case MEAR:
regs.mear = reg;
- /* since phy is completely faked, MEAR_MD* don't matter
- and since the driver never uses MEAR_EE*, they don't matter */
+ // since phy is completely faked, MEAR_MD* don't matter
+ // and since the driver never uses MEAR_EE*, they don't
+ // matter
#if 0
if (reg & MEAR_EEDI) ;
- if (reg & MEAR_EEDO) ; //this one is read only
+ if (reg & MEAR_EEDO) ; // this one is read only
if (reg & MEAR_EECLK) ;
if (reg & MEAR_EESEL) ;
if (reg & MEAR_MDIO) ;
@@ -688,8 +703,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
case PTSCR:
regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY);
- /* these control BISTs for various parts of chip - we don't care or do
- just fake that the BIST is done */
+ // these control BISTs for various parts of chip - we
+ // don't care or do just fake that the BIST is done
if (reg & PTSCR_RBIST_EN)
regs.ptscr |= PTSCR_RBIST_DONE;
if (reg & PTSCR_EEBIST_EN)
@@ -732,20 +747,26 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
if (reg & TXCFG_HBI) ;
if (reg & TXCFG_MLB) ;
if (reg & TXCFG_ATP) ;
- if (reg & TXCFG_ECRETRY) ; /* this could easily be implemented, but
- considering the network is just a fake
- pipe, wouldn't make sense to do this */
+ if (reg & TXCFG_ECRETRY) {
+ /*
+ * this could easily be implemented, but considering
+ * the network is just a fake pipe, wouldn't make
+ * sense to do this
+ */
+ }
if (reg & TXCFG_BRST_DIS) ;
#endif
-
+#if 0
/* we handle our own DMA, ignore the kernel's exhortations */
- //if (reg & TXCFG_MXDMA) ;
+ if (reg & TXCFG_MXDMA) ;
+#endif
- //also, we currently don't care about fill/drain thresholds
- //though this may change in the future with more realistic
- //networks or a driver which changes it according to feedback
+ // also, we currently don't care about fill/drain
+ // thresholds though this may change in the future with
+ // more realistic networks or a driver which changes it
+ // according to feedback
break;
@@ -756,6 +777,7 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
case RXDP:
regs.rxdp = reg;
+ CRDD = false;
break;
case RXDP_HI:
@@ -771,12 +793,10 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
if (reg & RXCFG_RX_RD) ;
if (reg & RXCFG_ALP) ;
if (reg & RXCFG_AIRL) ;
-#endif
/* we handle our own DMA, ignore what kernel says about it */
- //if (reg & RXCFG_MXDMA) ;
+ if (reg & RXCFG_MXDMA) ;
-#if 0
//also, we currently don't care about fill/drain thresholds
//though this may change in the future with more realistic
//networks or a driver which changes it according to feedback
@@ -809,8 +829,10 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
acceptPerfect = (reg & RFCR_APM) ? true : false;
acceptArp = (reg & RFCR_AARP) ? true : false;
- if (reg & RFCR_APAT) ;
-// panic("RFCR_APAT not implemented!\n");
+#if 0
+ if (reg & RFCR_APAT)
+ panic("RFCR_APAT not implemented!\n");
+#endif
if (reg & RFCR_MHEN || reg & RFCR_UHEN)
panic("hash filtering not implemented!\n");
@@ -891,11 +913,11 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
break;
default:
- panic("thought i covered all the register, what is this? addr=%#x",
- daddr);
+ panic("invalid register access daddr=%#x", daddr);
}
- } else
+ } else {
panic("Invalid Request Size");
+ }
return No_Fault;
}
@@ -968,7 +990,8 @@ NSGigE::devIntrPost(uint32_t interrupts)
cpuIntrPost(when);
}
- DPRINTF(EthernetIntr, "**interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
+ DPRINTF(EthernetIntr,
+ "interrupt written to ISR: intr=%#x isr=%#x imr=%#x\n",
interrupts, regs.isr, regs.imr);
}
@@ -1027,17 +1050,19 @@ NSGigE::devIntrClear(uint32_t interrupts)
if (interrupts & ISR_RXOK)
regs.isr &= ~ISR_RXOK;
+ DPRINTF(EthernetIntr,
+ "interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
+ interrupts, regs.isr, regs.imr);
+
if (!(regs.isr & regs.imr))
cpuIntrClear();
-
- DPRINTF(EthernetIntr, "**interrupt cleared from ISR: intr=%x isr=%x imr=%x\n",
- interrupts, regs.isr, regs.imr);
}
void
NSGigE::devIntrChangeMask()
{
- DPRINTF(EthernetIntr, "interrupt mask changed\n");
+ DPRINTF(EthernetIntr, "interrupt mask changed: isr=%x imr=%x masked=%x\n",
+ regs.isr, regs.imr, regs.isr & regs.imr);
if (regs.isr & regs.imr)
cpuIntrPost(curTick);
@@ -1048,11 +1073,20 @@ NSGigE::devIntrChangeMask()
void
NSGigE::cpuIntrPost(Tick when)
{
- //If the interrupt you want to post is later than an
- //interrupt already scheduled, just let it post in the coming one and
- //don't schedule another.
- //HOWEVER, must be sure that the scheduled intrTick is in the future
- //(this was formerly the source of a bug)
+ // If the interrupt you want to post is later than an interrupt
+ // already scheduled, just let it post in the coming one and don't
+ // schedule another.
+ // HOWEVER, must be sure that the scheduled intrTick is in the
+ // future (this was formerly the source of a bug)
+ /**
+ * @todo this warning should be removed and the intrTick code should
+ * be fixed.
+ */
+ if (intrTick < curTick && intrTick != 0) {
+ warn("intrTick < curTick !!! intrTick=%d curTick=%d\n",
+ intrTick, curTick);
+ intrTick = 0;
+ }
assert((intrTick >= curTick) || (intrTick == 0));
if (when > intrTick && intrTick != 0)
return;
@@ -1067,7 +1101,8 @@ NSGigE::cpuIntrPost(Tick when)
if (when < curTick) {
cpuInterrupt();
} else {
- DPRINTF(EthernetIntr, "going to schedule an interrupt for intrTick=%d\n",
+ DPRINTF(EthernetIntr,
+ "going to schedule an interrupt for intrTick=%d\n",
intrTick);
intrEvent = new IntrEvent(this, true);
intrEvent->schedule(intrTick);
@@ -1086,7 +1121,8 @@ NSGigE::cpuInterrupt()
}
// Don't send an interrupt if it's supposed to be delayed
if (intrTick > curTick) {
- DPRINTF(EthernetIntr, "an interrupt is scheduled for %d, wait til then\n",
+ DPRINTF(EthernetIntr,
+ "an interrupt is scheduled for %d, wait til then\n",
intrTick);
return;
}
@@ -1107,13 +1143,14 @@ NSGigE::cpuInterrupt()
void
NSGigE::cpuIntrClear()
{
- if (cpuPendingIntr) {
- cpuPendingIntr = false;
- /** @todo rework the intctrl to be tsunami ok */
- //intctrl->clear(TheISA::INTLEVEL_IRQ1, TheISA::INTINDEX_ETHERNET);
- DPRINTF(EthernetIntr, "clearing all interrupts from cchip\n");
- tsunami->cchip->clearDRIR(configData->config.hdr.pci0.interruptLine);
- }
+ if (!cpuPendingIntr)
+ return;
+
+ cpuPendingIntr = false;
+ /** @todo rework the intctrl to be tsunami ok */
+ //intctrl->clear(TheISA::INTLEVEL_IRQ1, TheISA::INTINDEX_ETHERNET);
+ DPRINTF(EthernetIntr, "clearing all interrupts from cchip\n");
+ tsunami->cchip->clearDRIR(configData->config.hdr.pci0.interruptLine);
}
bool
@@ -1127,12 +1164,11 @@ NSGigE::txReset()
DPRINTF(Ethernet, "transmit reset\n");
CTDD = false;
- txFifoAvail = MAX_TX_FIFO_SIZE;
- txHalt = false;
+ txFifoAvail = maxTxFifoSize;
+ txEnable = false;;
txFragPtr = 0;
assert(txDescCnt == 0);
txFifo.clear();
- regs.command &= ~CR_TXE;
txState = txIdle;
assert(txDmaState == dmaIdle);
}
@@ -1145,16 +1181,16 @@ NSGigE::rxReset()
CRDD = false;
assert(rxPktBytes == 0);
rxFifoCnt = 0;
- rxHalt = false;
+ rxEnable = false;
rxFragPtr = 0;
assert(rxDescCnt == 0);
assert(rxDmaState == dmaIdle);
rxFifo.clear();
- regs.command &= ~CR_RXE;
rxState = rxIdle;
}
-void NSGigE::regsReset()
+void
+NSGigE::regsReset()
{
memset(&regs, 0, sizeof(regs));
regs.config = 0x80000000;
@@ -1180,7 +1216,7 @@ NSGigE::rxDmaReadCopy()
{
assert(rxDmaState == dmaReading);
- memcpy(rxDmaData, physmem->dma_addr(rxDmaAddr, rxDmaLen), rxDmaLen);
+ physmem->dma_read((uint8_t *)rxDmaData, rxDmaAddr, rxDmaLen);
rxDmaState = dmaIdle;
DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n",
@@ -1232,7 +1268,7 @@ NSGigE::rxDmaWriteCopy()
{
assert(rxDmaState == dmaWriting);
- memcpy(physmem->dma_addr(rxDmaAddr, rxDmaLen), rxDmaData, rxDmaLen);
+ physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen);
rxDmaState = dmaIdle;
DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
@@ -1282,7 +1318,7 @@ NSGigE::rxDmaWriteDone()
void
NSGigE::rxKick()
{
- DPRINTF(EthernetSM, "receive kick state=%s (rxBuf.size=%d)\n",
+ DPRINTF(EthernetSM, "receive kick rxState=%s (rxBuf.size=%d)\n",
NsRxStateStrings[rxState], rxFifo.size());
if (rxKickTick > curTick) {
@@ -1306,14 +1342,15 @@ NSGigE::rxKick()
}
// see state machine from spec for details
- // the way this works is, if you finish work on one state and can go directly to
- // another, you do that through jumping to the label "next". however, if you have
- // intermediate work, like DMA so that you can't go to the next state yet, you go to
- // exit and exit the loop. however, when the DMA is done it will trigger an
- // event and come back to this loop.
+ // the way this works is, if you finish work on one state and can
+ // go directly to another, you do that through jumping to the
+ // label "next". however, if you have intermediate work, like DMA
+ // so that you can't go to the next state yet, you go to exit and
+ // exit the loop. however, when the DMA is done it will trigger
+ // an event and come back to this loop.
switch (rxState) {
case rxIdle:
- if (!regs.command & CR_RXE) {
+ if (!rxEnable) {
DPRINTF(EthernetSM, "Receive Disabled! Nothing to do.\n");
goto exit;
}
@@ -1359,12 +1396,17 @@ NSGigE::rxKick()
goto exit;
DPRINTF(EthernetDesc,
- "rxDescCache:\n\tlink=%08x\n\tbufptr=%08x\n\tcmdsts=%08x\n\textsts=%08x\n"
- ,rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts,
+ "rxDescCache: addr=%08x read descriptor\n",
+ regs.rxdp & 0x3fffffff);
+ DPRINTF(EthernetDesc,
+ "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
+ rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts,
rxDescCache.extsts);
if (rxDescCache.cmdsts & CMDSTS_OWN) {
+ devIntrPost(ISR_RXIDLE);
rxState = rxIdle;
+ goto exit;
} else {
rxState = rxFifoBlock;
rxFragPtr = rxDescCache.bufptr;
@@ -1382,25 +1424,27 @@ NSGigE::rxKick()
if (rxFifo.empty())
goto exit;
- DPRINTF(EthernetSM, "\n\n*****processing receive of new packet\n");
+ DPRINTF(EthernetSM, "****processing receive of new packet****\n");
// If we don't have a packet, grab a new one from the fifo.
rxPacket = rxFifo.front();
rxPktBytes = rxPacket->length;
rxPacketBufPtr = rxPacket->data;
+#if TRACING_ON
if (DTRACE(Ethernet)) {
if (rxPacket->isIpPkt()) {
ip_header *ip = rxPacket->getIpHdr();
DPRINTF(Ethernet, "ID is %d\n", reverseEnd16(ip->ID));
if (rxPacket->isTcpPkt()) {
tcp_header *tcp = rxPacket->getTcpHdr(ip);
- DPRINTF(Ethernet, "Src Port = %d, Dest Port = %d\n",
+ DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
reverseEnd16(tcp->src_port_num),
reverseEnd16(tcp->dest_port_num));
}
}
}
+#endif
// sanity check - i think the driver behaves like this
assert(rxDescCnt >= rxPktBytes);
@@ -1413,10 +1457,12 @@ NSGigE::rxKick()
}
- // dont' need the && rxDescCnt > 0 if driver sanity check above holds
+ // dont' need the && rxDescCnt > 0 if driver sanity check
+ // above holds
if (rxPktBytes > 0) {
rxState = rxFragWrite;
- // don't need min<>(rxPktBytes,rxDescCnt) if above sanity check holds
+ // don't need min<>(rxPktBytes,rxDescCnt) if above sanity
+ // check holds
rxXferLen = rxPktBytes;
rxDmaAddr = rxFragPtr & 0x3fffffff;
@@ -1441,11 +1487,13 @@ NSGigE::rxKick()
rxDescCache.cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE
#if 0
- /* all the driver uses these are for its own stats keeping
- which we don't care about, aren't necessary for functionality
- and doing this would just slow us down. if they end up using
- this in a later version for functional purposes, just undef
- */
+ /*
+ * all the driver uses these are for its own stats keeping
+ * which we don't care about, aren't necessary for
+ * functionality and doing this would just slow us down.
+ * if they end up using this in a later version for
+ * functional purposes, just undef
+ */
if (rxFilterEnable) {
rxDescCache.cmdsts &= ~CMDSTS_DEST_MASK;
if (rxFifo.front()->IsUnicast())
@@ -1482,14 +1530,20 @@ NSGigE::rxKick()
}
rxPacket = 0;
- /* the driver seems to always receive into desc buffers
- of size 1514, so you never have a pkt that is split
- into multiple descriptors on the receive side, so
- i don't implement that case, hence the assert above.
- */
+ /*
+ * the driver seems to always receive into desc buffers
+ * of size 1514, so you never have a pkt that is split
+ * into multiple descriptors on the receive side, so
+ * i don't implement that case, hence the assert above.
+ */
- DPRINTF(EthernetDesc, "rxDesc writeback:\n\tcmdsts=%08x\n\textsts=%08x\n",
- rxDescCache.cmdsts, rxDescCache.extsts);
+ DPRINTF(EthernetDesc,
+ "rxDescCache: addr=%08x writeback cmdsts extsts\n",
+ regs.rxdp & 0x3fffffff);
+ DPRINTF(EthernetDesc,
+ "rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
+ rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts,
+ rxDescCache.extsts);
rxDmaAddr = (regs.rxdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff;
rxDmaData = &(rxDescCache.cmdsts);
@@ -1527,18 +1581,20 @@ NSGigE::rxKick()
if (rxDescCache.cmdsts & CMDSTS_INTR)
devIntrPost(ISR_RXDESC);
- if (rxHalt) {
+ if (!rxEnable) {
DPRINTF(EthernetSM, "Halting the RX state machine\n");
rxState = rxIdle;
- rxHalt = false;
+ goto exit;
} else
rxState = rxAdvance;
break;
case rxAdvance:
if (rxDescCache.link == 0) {
+ devIntrPost(ISR_RXIDLE);
rxState = rxIdle;
- return;
+ CRDD = true;
+ goto exit;
} else {
rxState = rxDescRead;
regs.rxdp = rxDescCache.link;
@@ -1558,23 +1614,16 @@ NSGigE::rxKick()
panic("Invalid rxState!");
}
-
- DPRINTF(EthernetSM, "entering next rx state = %s\n",
+ DPRINTF(EthernetSM, "entering next rxState=%s\n",
NsRxStateStrings[rxState]);
- if (rxState == rxIdle) {
- regs.command &= ~CR_RXE;
- devIntrPost(ISR_RXIDLE);
- return;
- }
-
goto next;
exit:
/**
* @todo do we want to schedule a future kick?
*/
- DPRINTF(EthernetSM, "rx state machine exited state=%s\n",
+ DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n",
NsRxStateStrings[rxState]);
}
@@ -1586,21 +1635,23 @@ NSGigE::transmit()
return;
}
- DPRINTF(Ethernet, "\n\nAttempt Pkt Transmit: txFifo length = %d\n",
- MAX_TX_FIFO_SIZE - txFifoAvail);
+ DPRINTF(Ethernet, "Attempt Pkt Transmit: txFifo length=%d\n",
+ maxTxFifoSize - txFifoAvail);
if (interface->sendPacket(txFifo.front())) {
+#if TRACING_ON
if (DTRACE(Ethernet)) {
if (txFifo.front()->isIpPkt()) {
ip_header *ip = txFifo.front()->getIpHdr();
DPRINTF(Ethernet, "ID is %d\n", reverseEnd16(ip->ID));
if (txFifo.front()->isTcpPkt()) {
tcp_header *tcp = txFifo.front()->getTcpHdr(ip);
- DPRINTF(Ethernet, "Src Port = %d, Dest Port = %d\n",
+ DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
reverseEnd16(tcp->src_port_num),
reverseEnd16(tcp->dest_port_num));
}
}
}
+#endif
DDUMP(Ethernet, txFifo.front()->data, txFifo.front()->length);
txBytes += txFifo.front()->length;
@@ -1608,18 +1659,23 @@ NSGigE::transmit()
txFifoAvail += txFifo.front()->length;
- DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n", txFifoAvail);
+ DPRINTF(Ethernet, "Successful Xmit! now txFifoAvail is %d\n",
+ txFifoAvail);
txFifo.front() = NULL;
txFifo.pop_front();
- /* normally do a writeback of the descriptor here, and ONLY after that is
- done, send this interrupt. but since our stuff never actually fails,
- just do this interrupt here, otherwise the code has to stray from this
- nice format. besides, it's functionally the same.
- */
+ /*
+ * normally do a writeback of the descriptor here, and ONLY
+ * after that is done, send this interrupt. but since our
+ * stuff never actually fails, just do this interrupt here,
+ * otherwise the code has to stray from this nice format.
+ * besides, it's functionally the same.
+ */
devIntrPost(ISR_TXOK);
- } else
- DPRINTF(Ethernet, "May need to rethink always sending the descriptors back?\n");
+ } else {
+ DPRINTF(Ethernet,
+ "May need to rethink always sending the descriptors back?\n");
+ }
if (!txFifo.empty() && !txEvent.scheduled()) {
DPRINTF(Ethernet, "reschedule transmit\n");
@@ -1632,7 +1688,7 @@ NSGigE::txDmaReadCopy()
{
assert(txDmaState == dmaReading);
- memcpy(txDmaData, physmem->dma_addr(txDmaAddr, txDmaLen), txDmaLen);
+ physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen);
txDmaState = dmaIdle;
DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
@@ -1684,7 +1740,7 @@ NSGigE::txDmaWriteCopy()
{
assert(txDmaState == dmaWriting);
- memcpy(physmem->dma_addr(txDmaAddr, txDmaLen), txDmaData, txDmaLen);
+ physmem->dma_write(txDmaAddr, (uint8_t *)txDmaData, txDmaLen);
txDmaState = dmaIdle;
DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n",
@@ -1734,7 +1790,8 @@ NSGigE::txDmaWriteDone()
void
NSGigE::txKick()
{
- DPRINTF(EthernetSM, "transmit kick state=%s\n", NsTxStateStrings[txState]);
+ DPRINTF(EthernetSM, "transmit kick txState=%s\n",
+ NsTxStateStrings[txState]);
if (txKickTick > curTick) {
DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
@@ -1759,7 +1816,7 @@ NSGigE::txKick()
switch (txState) {
case txIdle:
- if (!regs.command & CR_TXE) {
+ if (!txEnable) {
DPRINTF(EthernetSM, "Transmit disabled. Nothing to do.\n");
goto exit;
}
@@ -1806,8 +1863,8 @@ NSGigE::txKick()
goto exit;
DPRINTF(EthernetDesc,
- "txDescCache data:\n\tlink=%08x\n\tbufptr=%08x\n\tcmdsts=%08x\n\textsts=%08x\n"
- ,txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts,
+ "txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
+ txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts,
txDescCache.extsts);
if (txDescCache.cmdsts & CMDSTS_OWN) {
@@ -1815,13 +1872,15 @@ NSGigE::txKick()
txFragPtr = txDescCache.bufptr;
txDescCnt = txDescCache.cmdsts & CMDSTS_LEN_MASK;
} else {
+ devIntrPost(ISR_TXIDLE);
txState = txIdle;
+ goto exit;
}
break;
case txFifoBlock:
if (!txPacket) {
- DPRINTF(EthernetSM, "\n\n*****starting the tx of a new packet\n");
+ DPRINTF(EthernetSM, "****starting the tx of a new packet****\n");
txPacket = new EtherPacket;
txPacket->data = new uint8_t[16384];
txPacketBufPtr = txPacket->data;
@@ -1835,7 +1894,8 @@ NSGigE::txKick()
txDescCache.cmdsts &= ~CMDSTS_OWN;
- txDmaAddr = (regs.txdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff;
+ txDmaAddr = regs.txdp + offsetof(ns_desc, cmdsts);
+ txDmaAddr &= 0x3fffffff;
txDmaData = &(txDescCache.cmdsts);
txDmaLen = sizeof(txDescCache.cmdsts);
txDmaFree = dmaDescFree;
@@ -1860,66 +1920,80 @@ NSGigE::txKick()
}
txPacket->length = txPacketBufPtr - txPacket->data;
- /* this is just because the receive can't handle a packet bigger
- want to make sure */
+ // this is just because the receive can't handle a
+ // packet bigger want to make sure
assert(txPacket->length <= 1514);
txFifo.push_back(txPacket);
- /* this following section is not to spec, but functionally shouldn't
- be any different. normally, the chip will wait til the transmit has
- occurred before writing back the descriptor because it has to wait
- to see that it was successfully transmitted to decide whether to set
- CMDSTS_OK or not. however, in the simulator since it is always
- successfully transmitted, and writing it exactly to spec would
- complicate the code, we just do it here
- */
+ /*
+ * this following section is not tqo spec, but
+ * functionally shouldn't be any different. normally,
+ * the chip will wait til the transmit has occurred
+ * before writing back the descriptor because it has
+ * to wait to see that it was successfully transmitted
+ * to decide whether to set CMDSTS_OK or not.
+ * however, in the simulator since it is always
+ * successfully transmitted, and writing it exactly to
+ * spec would complicate the code, we just do it here
+ */
txDescCache.cmdsts &= ~CMDSTS_OWN;
txDescCache.cmdsts |= CMDSTS_OK;
DPRINTF(EthernetDesc,
- "txDesc writeback:\n\tcmdsts=%08x\n\textsts=%08x\n",
+ "txDesc writeback: cmdsts=%08x extsts=%08x\n",
txDescCache.cmdsts, txDescCache.extsts);
- txDmaAddr = (regs.txdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff;
+ txDmaAddr = regs.txdp + offsetof(ns_desc, cmdsts);
+ txDmaAddr &= 0x3fffffff;
txDmaData = &(txDescCache.cmdsts);
- txDmaLen = sizeof(txDescCache.cmdsts) + sizeof(txDescCache.extsts);
+ txDmaLen = sizeof(txDescCache.cmdsts) +
+ sizeof(txDescCache.extsts);
txDmaFree = dmaDescFree;
descDmaWrites++;
descDmaWrBytes += txDmaLen;
- if (doTxDmaWrite())
- goto exit;
-
transmit();
-
txPacket = 0;
- if (txHalt) {
+ if (!txEnable) {
DPRINTF(EthernetSM, "halting TX state machine\n");
txState = txIdle;
- txHalt = false;
+ goto exit;
} else
txState = txAdvance;
+
+ if (doTxDmaWrite())
+ goto exit;
}
} else {
DPRINTF(EthernetSM, "this descriptor isn't done yet\n");
- txState = txFragRead;
-
- /* The number of bytes transferred is either whatever is left
- in the descriptor (txDescCnt), or if there is not enough
- room in the fifo, just whatever room is left in the fifo
- */
- txXferLen = min<uint32_t>(txDescCnt, txFifoAvail);
-
- txDmaAddr = txFragPtr & 0x3fffffff;
- txDmaData = txPacketBufPtr;
- txDmaLen = txXferLen;
- txDmaFree = dmaDataFree;
+ if (txFifoAvail) {
+ txState = txFragRead;
+
+ /*
+ * The number of bytes transferred is either whatever
+ * is left in the descriptor (txDescCnt), or if there
+ * is not enough room in the fifo, just whatever room
+ * is left in the fifo
+ */
+ txXferLen = min<uint32_t>(txDescCnt, txFifoAvail);
+
+ txDmaAddr = txFragPtr & 0x3fffffff;
+ txDmaData = txPacketBufPtr;
+ txDmaLen = txXferLen;
+ txDmaFree = dmaDataFree;
+
+ if (doTxDmaRead())
+ goto exit;
+ } else {
+ txState = txFifoBlock;
+ transmit();
- if (doTxDmaRead())
goto exit;
+ }
+
}
break;
@@ -1939,16 +2013,17 @@ NSGigE::txKick()
if (txDmaState != dmaIdle)
goto exit;
- if (txDescCache.cmdsts & CMDSTS_INTR) {
+ if (txDescCache.cmdsts & CMDSTS_INTR)
devIntrPost(ISR_TXDESC);
- }
txState = txAdvance;
break;
case txAdvance:
if (txDescCache.link == 0) {
+ devIntrPost(ISR_TXIDLE);
txState = txIdle;
+ goto exit;
} else {
txState = txDescRead;
regs.txdp = txDescCache.link;
@@ -1968,30 +2043,28 @@ NSGigE::txKick()
panic("invalid state");
}
- DPRINTF(EthernetSM, "entering next tx state=%s\n",
+ DPRINTF(EthernetSM, "entering next txState=%s\n",
NsTxStateStrings[txState]);
- if (txState == txIdle) {
- regs.command &= ~CR_TXE;
- devIntrPost(ISR_TXIDLE);
- return;
- }
-
goto next;
exit:
/**
* @todo do we want to schedule a future kick?
*/
- DPRINTF(EthernetSM, "tx state machine exited state=%s\n",
+ DPRINTF(EthernetSM, "tx state machine exited txState=%s\n",
NsTxStateStrings[txState]);
}
void
NSGigE::transferDone()
{
- if (txFifo.empty())
+ if (txFifo.empty()) {
+ DPRINTF(Ethernet, "transfer complete: txFifo empty...nothing to do\n");
return;
+ }
+
+ DPRINTF(Ethernet, "transfer complete: data in txFifo...schedule xmit\n");
if (txEvent.scheduled())
txEvent.reschedule(curTick + 1);
@@ -2013,8 +2086,8 @@ NSGigE::rxFilter(PacketPtr packet)
drop = false;
// If we make a perfect match
- if ((acceptPerfect)
- && (memcmp(rom.perfectMatch, packet->data, sizeof(rom.perfectMatch)) == 0))
+ if (acceptPerfect &&
+ memcmp(rom.perfectMatch, packet->data, EADDR_LEN) == 0)
drop = false;
eth_header *eth = (eth_header *) packet->data;
@@ -2055,10 +2128,12 @@ NSGigE::recvPacket(PacketPtr packet)
rxBytes += packet->length;
rxPackets++;
- DPRINTF(Ethernet, "\n\nReceiving packet from wire, rxFifoAvail = %d\n", MAX_RX_FIFO_SIZE - rxFifoCnt);
+ DPRINTF(Ethernet, "Receiving packet from wire, rxFifoAvail=%d\n",
+ maxRxFifoSize - rxFifoCnt);
- if (rxState == rxIdle) {
+ if (!rxEnable) {
DPRINTF(Ethernet, "receive disabled...packet dropped\n");
+ debug_break();
interface->recvDone();
return true;
}
@@ -2069,7 +2144,7 @@ NSGigE::recvPacket(PacketPtr packet)
return true;
}
- if ((rxFifoCnt + packet->length) >= MAX_RX_FIFO_SIZE) {
+ if ((rxFifoCnt + packet->length) >= maxRxFifoSize) {
DPRINTF(Ethernet,
"packet will not fit in receive buffer...packet dropped\n");
devIntrPost(ISR_RXORN);
@@ -2085,8 +2160,9 @@ NSGigE::recvPacket(PacketPtr packet)
}
/**
- * does a udp checksum. if gen is true, then it generates it and puts it in the right place
- * else, it just checks what it calculates against the value in the header in packet
+ * does a udp checksum. if gen is true, then it generates it and puts
+ * it in the right place else, it just checks what it calculates
+ * against the value in the header in packet
*/
bool
NSGigE::udpChecksum(PacketPtr packet, bool gen)
@@ -2126,10 +2202,11 @@ NSGigE::tcpChecksum(PacketPtr packet, bool gen)
pseudo->src_ip_addr = ip->src_ip_addr;
pseudo->dest_ip_addr = ip->dest_ip_addr;
pseudo->protocol = reverseEnd16(ip->protocol);
- pseudo->len = reverseEnd16(reverseEnd16(ip->dgram_len) - (ip->vers_len & 0xf)*4);
+ pseudo->len = reverseEnd16(reverseEnd16(ip->dgram_len) -
+ (ip->vers_len & 0xf)*4);
cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
- (uint32_t) reverseEnd16(pseudo->len));
+ (uint32_t) reverseEnd16(pseudo->len));
} else {
pseudo->src_ip_addr = 0;
pseudo->dest_ip_addr = 0;
@@ -2137,7 +2214,8 @@ NSGigE::tcpChecksum(PacketPtr packet, bool gen)
pseudo->len = 0;
hdr->chksum = 0;
cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
- (uint32_t) (reverseEnd16(ip->dgram_len) - (ip->vers_len & 0xf)*4));
+ (uint32_t) (reverseEnd16(ip->dgram_len) -
+ (ip->vers_len & 0xf)*4));
}
delete pseudo;
@@ -2155,7 +2233,8 @@ NSGigE::ipChecksum(PacketPtr packet, bool gen)
{
ip_header *hdr = packet->getIpHdr();
- uint16_t cksum = checksumCalc(NULL, (uint16_t *) hdr, (hdr->vers_len & 0xf)*4);
+ uint16_t cksum = checksumCalc(NULL, (uint16_t *) hdr,
+ (hdr->vers_len & 0xf)*4);
if (gen) {
DPRINTF(EthernetCksum, "generated checksum: %#x\n", cksum);
@@ -2318,9 +2397,9 @@ NSGigE::serialize(ostream &os)
*/
int txState = this->txState;
SERIALIZE_SCALAR(txState);
+ SERIALIZE_SCALAR(txEnable);
SERIALIZE_SCALAR(CTDD);
SERIALIZE_SCALAR(txFifoAvail);
- SERIALIZE_SCALAR(txHalt);
SERIALIZE_SCALAR(txFragPtr);
SERIALIZE_SCALAR(txDescCnt);
int txDmaState = this->txDmaState;
@@ -2331,10 +2410,10 @@ NSGigE::serialize(ostream &os)
*/
int rxState = this->rxState;
SERIALIZE_SCALAR(rxState);
+ SERIALIZE_SCALAR(rxEnable);
SERIALIZE_SCALAR(CRDD);
SERIALIZE_SCALAR(rxPktBytes);
SERIALIZE_SCALAR(rxFifoCnt);
- SERIALIZE_SCALAR(rxHalt);
SERIALIZE_SCALAR(rxDescCnt);
int rxDmaState = this->rxDmaState;
SERIALIZE_SCALAR(rxDmaState);
@@ -2480,9 +2559,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
int txState;
UNSERIALIZE_SCALAR(txState);
this->txState = (TxState) txState;
+ UNSERIALIZE_SCALAR(txEnable);
UNSERIALIZE_SCALAR(CTDD);
UNSERIALIZE_SCALAR(txFifoAvail);
- UNSERIALIZE_SCALAR(txHalt);
UNSERIALIZE_SCALAR(txFragPtr);
UNSERIALIZE_SCALAR(txDescCnt);
int txDmaState;
@@ -2495,10 +2574,10 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
int rxState;
UNSERIALIZE_SCALAR(rxState);
this->rxState = (RxState) rxState;
+ UNSERIALIZE_SCALAR(rxEnable);
UNSERIALIZE_SCALAR(CRDD);
UNSERIALIZE_SCALAR(rxPktBytes);
UNSERIALIZE_SCALAR(rxFifoCnt);
- UNSERIALIZE_SCALAR(rxHalt);
UNSERIALIZE_SCALAR(rxDescCnt);
int rxDmaState;
UNSERIALIZE_SCALAR(rxDmaState);
@@ -2631,6 +2710,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
+ Param<uint32_t> tx_fifo_size;
+ Param<uint32_t> rx_fifo_size;
END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
@@ -2648,7 +2729,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
INIT_PARAM_DFLT(header_bus, "The IO Bus to attach to for headers", NULL),
INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
- INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(dma_desc_free, "DMA of Descriptors is free", false),
INIT_PARAM_DFLT(dma_data_free, "DMA of Data is free", false),
INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0),
@@ -2660,7 +2741,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
INIT_PARAM(tsunami, "Tsunami"),
INIT_PARAM(pci_bus, "PCI bus"),
INIT_PARAM(pci_dev, "PCI device number"),
- INIT_PARAM(pci_func, "PCI function code")
+ INIT_PARAM(pci_func, "PCI function code"),
+ INIT_PARAM_DFLT(tx_fifo_size, "max size in bytes of txFifo", 131072),
+ INIT_PARAM_DFLT(rx_fifo_size, "max size in bytes of rxFifo", 131072)
END_INIT_SIM_OBJECT_PARAMS(NSGigE)
@@ -2676,7 +2759,8 @@ CREATE_SIM_OBJECT(NSGigE)
payload_bus, pio_latency, dma_desc_free, dma_data_free,
dma_read_delay, dma_write_delay, dma_read_factor,
dma_write_factor, configspace, configdata,
- tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr);
+ tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr,
+ tx_fifo_size, rx_fifo_size);
}
REGISTER_SIM_OBJECT("NSGigE", NSGigE)
diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh
index a8d8d1f18..82f640db1 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -34,20 +34,15 @@
#ifndef __NS_GIGE_HH__
#define __NS_GIGE_HH__
-//#include "base/range.hh"
+#include "base/statistics.hh"
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
-#include "sim/eventq.hh"
+#include "dev/io_device.hh"
#include "dev/ns_gige_reg.h"
-#include "base/statistics.hh"
#include "dev/pcidev.hh"
#include "dev/tsunami.hh"
-#include "dev/io_device.hh"
#include "mem/bus/bus.hh"
-
-/** defined by the NS83820 data sheet */
-#define MAX_TX_FIFO_SIZE 8192
-#define MAX_RX_FIFO_SIZE 32768
+#include "sim/eventq.hh"
/** length of ethernet address in bytes */
#define EADDR_LEN 6
@@ -91,7 +86,10 @@ struct dp_regs {
};
struct dp_rom {
- /** for perfect match memory. the linux driver doesn't use any other ROM */
+ /**
+ * for perfect match memory.
+ * the linux driver doesn't use any other ROM
+ */
uint8_t perfectMatch[EADDR_LEN];
};
@@ -168,7 +166,9 @@ class NSGigE : public PciDev
/*** BASIC STRUCTURES FOR TX/RX ***/
/* Data FIFOs */
pktbuf_t txFifo;
+ uint32_t maxTxFifoSize;
pktbuf_t rxFifo;
+ uint32_t maxRxFifoSize;
/** various helper vars */
PacketPtr txPacket;
@@ -186,6 +186,8 @@ class NSGigE : public PciDev
/* tx State Machine */
TxState txState;
+ bool txEnable;
+
/** Current Transmit Descriptor Done */
bool CTDD;
/** current amt of free space in txDataFifo in bytes */
@@ -200,6 +202,8 @@ class NSGigE : public PciDev
/** rx State Machine */
RxState rxState;
+ bool rxEnable;
+
/** Current Receive Descriptor Done */
bool CRDD;
/** num of bytes in the current packet being drained from rxDataFifo */
@@ -281,7 +285,13 @@ class NSGigE : public PciDev
* Retransmit event
*/
void transmit();
- typedef EventWrapper<NSGigE, &NSGigE::transmit> TxEvent;
+ void txEventTransmit()
+ {
+ transmit();
+ if (txState == txFifoBlock)
+ txKick();
+ }
+ typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
friend class TxEvent;
TxEvent txEvent;
@@ -332,13 +342,14 @@ class NSGigE : public PciDev
public:
NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
- PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
- MemoryController *mmu, HierParams *hier, Bus *header_bus,
- Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
- bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
- Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
- PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
- uint32_t func, bool rx_filter, const int eaddr[6]);
+ PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
+ MemoryController *mmu, HierParams *hier, Bus *header_bus,
+ Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
+ bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
+ Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
+ PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
+ uint32_t func, bool rx_filter, const int eaddr[6],
+ uint32_t tx_fifo_size, uint32_t rx_fifo_size);
~NSGigE();
virtual void WriteConfig(int offset, int size, uint32_t data);
@@ -379,9 +390,6 @@ class NSGigE : public PciDev
Stats::Formula txPacketRate;
Stats::Formula rxPacketRate;
- private:
- Tick pioLatency;
-
public:
Tick cacheAccess(MemReqPtr &req);
};
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index 8937b8e67..740a9b4ac 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -47,7 +47,7 @@
using namespace std;
PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu,
- HierParams *hier, Bus *bus)
+ HierParams *hier, Bus *bus, Tick pio_latency)
: PioDevice(name), addr(a)
{
mmu->add_child(this, Range<Addr>(addr, addr + size));
@@ -56,6 +56,7 @@ PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu,
pioInterface = newPioInterface(name, hier, bus, this,
&PciConfigAll::cacheAccess);
pioInterface->addAddrRange(addr, addr + size - 1);
+ pioLatency = pio_latency * bus->clockRatio;
}
// Make all the pointers to devices null
@@ -175,7 +176,7 @@ PciConfigAll::unserialize(Checkpoint *cp, const std::string &section)
Tick
PciConfigAll::cacheAccess(MemReqPtr &req)
{
- return curTick + 1000;
+ return curTick + pioLatency;
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -186,6 +187,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll)
Param<Addr> addr;
Param<Addr> mask;
SimObjectParam<Bus*> io_bus;
+ Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll)
@@ -196,13 +198,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigAll)
INIT_PARAM(addr, "Device Address"),
INIT_PARAM(mask, "Address Mask"),
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
END_INIT_SIM_OBJECT_PARAMS(PciConfigAll)
CREATE_SIM_OBJECT(PciConfigAll)
{
- return new PciConfigAll(getInstanceName(), addr, mmu, hier, io_bus);
+ return new PciConfigAll(getInstanceName(), addr, mmu, hier, io_bus,
+ pio_latency);
}
REGISTER_SIM_OBJECT("PciConfigAll", PciConfigAll)
diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh
index 356e62a3c..d6b37b9b1 100644
--- a/dev/pciconfigall.hh
+++ b/dev/pciconfigall.hh
@@ -73,7 +73,7 @@ class PciConfigAll : public PioDevice
* @param bus The bus that this device is attached to
*/
PciConfigAll(const std::string &name, Addr a, MemoryController *mmu,
- HierParams *hier, Bus *bus);
+ HierParams *hier, Bus *bus, Tick pio_latency);
/**
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 0fbfcb56f..870924a2f 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -49,7 +49,8 @@
using namespace std;
TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
- MemoryController *mmu, HierParams *hier, Bus* bus)
+ MemoryController *mmu, HierParams *hier, Bus* bus,
+ Tick pio_latency)
: PioDevice(name), addr(a), tsunami(t)
{
mmu->add_child(this, Range<Addr>(addr, addr + size));
@@ -66,6 +67,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
pioInterface = newPioInterface(name, hier, bus, this,
&TsunamiCChip::cacheAccess);
pioInterface->addAddrRange(addr, addr + size - 1);
+ pioLatency = pio_latency * bus->clockRatio;
}
drir = 0;
@@ -383,7 +385,7 @@ TsunamiCChip::clearDRIR(uint32_t interrupt)
Tick
TsunamiCChip::cacheAccess(MemReqPtr &req)
{
- return curTick + 1000;
+ return curTick + pioLatency;
}
@@ -417,6 +419,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
SimObjectParam<MemoryController *> mmu;
Param<Addr> addr;
SimObjectParam<Bus*> io_bus;
+ Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip)
@@ -427,13 +430,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
INIT_PARAM(mmu, "Memory Controller"),
INIT_PARAM(addr, "Device Address"),
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip)
CREATE_SIM_OBJECT(TsunamiCChip)
{
- return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, io_bus);
+ return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier,
+ io_bus, pio_latency);
}
REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip)
diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh
index a358c98ba..3269cf53a 100644
--- a/dev/tsunami_cchip.hh
+++ b/dev/tsunami_cchip.hh
@@ -100,7 +100,8 @@ class TsunamiCChip : public PioDevice
* @param bus The bus that this device is attached to
*/
TsunamiCChip(const std::string &name, Tsunami *t, Addr a,
- MemoryController *mmu, HierParams *hier, Bus *bus);
+ MemoryController *mmu, HierParams *hier, Bus *bus,
+ Tick pio_latency);
/**
* Process a read to the CChip.
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index 4c798a852..105e3b5b7 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -160,7 +160,8 @@ TsunamiIO::ClockEvent::unserialize(Checkpoint *cp, const std::string &section)
}
TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
- Addr a, MemoryController *mmu, HierParams *hier, Bus *bus)
+ Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
+ Tick pio_latency)
: PioDevice(name), addr(a), tsunami(t), rtc(t)
{
mmu->add_child(this, Range<Addr>(addr, addr + size));
@@ -169,6 +170,7 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
pioInterface = newPioInterface(name, hier, bus, this,
&TsunamiIO::cacheAccess);
pioInterface->addAddrRange(addr, addr + size - 1);
+ pioLatency = pio_latency * bus->clockRatio;
}
// set the back pointer from tsunami to myself
@@ -425,7 +427,7 @@ TsunamiIO::clearPIC(uint8_t bitvector)
Tick
TsunamiIO::cacheAccess(MemReqPtr &req)
{
- return curTick + 1000;
+ return curTick + pioLatency;
}
void
@@ -476,6 +478,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
SimObjectParam<MemoryController *> mmu;
Param<Addr> addr;
SimObjectParam<Bus*> io_bus;
+ Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
@@ -488,6 +491,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
INIT_PARAM(mmu, "Memory Controller"),
INIT_PARAM(addr, "Device Address"),
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
@@ -495,7 +499,7 @@ END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
CREATE_SIM_OBJECT(TsunamiIO)
{
return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier,
- io_bus);
+ io_bus, pio_latency);
}
REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)
diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh
index 75e5d764c..d507355c3 100644
--- a/dev/tsunami_io.hh
+++ b/dev/tsunami_io.hh
@@ -237,7 +237,8 @@ class TsunamiIO : public PioDevice
* @param mmu pointer to the memory controller that sends us events.
*/
TsunamiIO(const std::string &name, Tsunami *t, time_t init_time,
- Addr a, MemoryController *mmu, HierParams *hier, Bus *bus);
+ Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
+ Tick pio_latency);
/**
* Create the tm struct from seconds since 1970
diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc
index b1346bb1a..89940fb5a 100644
--- a/dev/tsunami_pchip.cc
+++ b/dev/tsunami_pchip.cc
@@ -50,7 +50,7 @@ using namespace std;
TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
MemoryController *mmu, HierParams *hier,
- Bus *bus)
+ Bus *bus, Tick pio_latency)
: PioDevice(name), addr(a), tsunami(t)
{
mmu->add_child(this, Range<Addr>(addr, addr + size));
@@ -65,6 +65,7 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
pioInterface = newPioInterface(name, hier, bus, this,
&TsunamiPChip::cacheAccess);
pioInterface->addAddrRange(addr, addr + size - 1);
+ pioLatency = pio_latency * bus->clockRatio;
}
@@ -351,7 +352,7 @@ TsunamiPChip::unserialize(Checkpoint *cp, const std::string &section)
Tick
TsunamiPChip::cacheAccess(MemReqPtr &req)
{
- return curTick + 1000;
+ return curTick + pioLatency;
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
@@ -360,6 +361,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
SimObjectParam<MemoryController *> mmu;
Param<Addr> addr;
SimObjectParam<Bus*> io_bus;
+ Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
@@ -370,13 +372,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
INIT_PARAM(mmu, "Memory Controller"),
INIT_PARAM(addr, "Device Address"),
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
CREATE_SIM_OBJECT(TsunamiPChip)
{
- return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier, io_bus);
+ return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier,
+ io_bus, pio_latency);
}
REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip)
diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh
index af50872a0..f88098d58 100644
--- a/dev/tsunami_pchip.hh
+++ b/dev/tsunami_pchip.hh
@@ -80,7 +80,8 @@ class TsunamiPChip : public PioDevice
* @param bus The bus that this device is attached to
*/
TsunamiPChip(const std::string &name, Tsunami *t, Addr a,
- MemoryController *mmu, HierParams *hier, Bus *bus);
+ MemoryController *mmu, HierParams *hier, Bus *bus,
+ Tick pio_latency);
/**
* Translate a PCI bus address to a memory address for DMA.
diff --git a/dev/uart.cc b/dev/uart.cc
index 4784ad640..fca856d5d 100644
--- a/dev/uart.cc
+++ b/dev/uart.cc
@@ -88,7 +88,7 @@ Uart::IntrEvent::scheduleIntr()
}
Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
- Addr s, HierParams *hier, Bus *bus, Platform *p)
+ Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p)
: PioDevice(name), addr(a), size(s), cons(c), txIntrEvent(this, TX_INT),
rxIntrEvent(this, RX_INT), platform(p)
{
@@ -98,7 +98,8 @@ Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
if (bus) {
pioInterface = newPioInterface(name, hier, bus, this,
&Uart::cacheAccess);
- pioInterface->addAddrRange(addr, addr + size - 1);
+ pioInterface->addAddrRange(addr, addr + size - 1);
+ pioLatency = pio_latency * bus->clockRatio;
}
readAddr = 0;
@@ -370,7 +371,7 @@ Uart::dataAvailable()
Tick
Uart::cacheAccess(MemReqPtr &req)
{
- return curTick + 1000;
+ return curTick + pioLatency;
}
void
@@ -394,7 +395,7 @@ Uart::serialize(ostream &os)
if (txIntrEvent.scheduled())
txintrwhen = txIntrEvent.when();
else
- rxintrwhen = 0;
+ txintrwhen = 0;
SERIALIZE_SCALAR(rxintrwhen);
SERIALIZE_SCALAR(txintrwhen);
#endif
@@ -432,6 +433,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Uart)
Param<Addr> addr;
Param<Addr> size;
SimObjectParam<Bus*> io_bus;
+ Param<Tick> pio_latency;
SimObjectParam<HierParams *> hier;
@@ -445,6 +447,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Uart)
INIT_PARAM(addr, "Device Address"),
INIT_PARAM_DFLT(size, "Device size", 0x8),
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
+ INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
END_INIT_SIM_OBJECT_PARAMS(Uart)
@@ -452,7 +455,7 @@ END_INIT_SIM_OBJECT_PARAMS(Uart)
CREATE_SIM_OBJECT(Uart)
{
return new Uart(getInstanceName(), console, mmu, addr, size, hier, io_bus,
- platform);
+ pio_latency, platform);
}
REGISTER_SIM_OBJECT("Uart", Uart)
diff --git a/dev/uart.hh b/dev/uart.hh
index 07ad4d0c8..ac8ed7d73 100644
--- a/dev/uart.hh
+++ b/dev/uart.hh
@@ -76,7 +76,8 @@ class Uart : public PioDevice
public:
Uart(const string &name, SimConsole *c, MemoryController *mmu,
- Addr a, Addr s, HierParams *hier, Bus *bus, Platform *p);
+ Addr a, Addr s, HierParams *hier, Bus *bus, Tick pio_latency,
+ Platform *p);
Fault read(MemReqPtr &req, uint8_t *data);
Fault write(MemReqPtr &req, const uint8_t *data);
diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc
index de944329a..e6bcb4d29 100644
--- a/kern/kernel_stats.cc
+++ b/kern/kernel_stats.cc
@@ -214,6 +214,7 @@ KSData::regStats(const string &name)
_modeGood
.init(2)
+ .name(name + ".mode_good")
;
_modeFraction
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index 70f5fb783..bc2753908 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -28,10 +28,11 @@
/**
* @file
- * linux_system.cc loads the linux kernel, console, pal and patches certain functions.
- * The symbol tables are loaded so that traces can show the executing function and we can
- * skip functions. Various delay loops are skipped and their final values manually computed to
- * speed up boot time.
+ * This code loads the linux kernel, console, pal and patches certain
+ * functions. The symbol tables are loaded so that traces can show
+ * the executing function and we can skip functions. Various delay
+ * loops are skipped and their final values manually computed to speed
+ * up boot time.
*/
#include "base/loader/aout_object.hh"
@@ -121,13 +122,15 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
#endif
skipIdeDelay50msEvent = new SkipFuncEvent(&pcEventQueue,
- "ide_delay_50ms");
+ "ide_delay_50ms");
skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
"calibrate_delay");
skipCacheProbeEvent = new SkipFuncEvent(&pcEventQueue,
- "determine_cpu_caches");
+ "determine_cpu_caches");
+
+ debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk");
Addr addr = 0;
@@ -236,6 +239,9 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
if (kernelSymtab->findAddress("determine_cpu_caches", addr))
skipCacheProbeEvent->schedule(addr+sizeof(MachInst));
+
+ if (kernelSymtab->findAddress("dprintk", addr))
+ debugPrintkEvent->schedule(addr+sizeof(MachInst)*2);
}
LinuxSystem::~LinuxSystem()
diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh
index 4f5a74259..e7cdf140d 100644
--- a/kern/linux/linux_system.hh
+++ b/kern/linux/linux_system.hh
@@ -46,7 +46,7 @@ const Addr PARAM_ADDR = ULL(0xfffffc000030a000);
class ExecContext;
class ElfObject;
class SymbolTable;
-
+class DebugPrintkEvent;
class BreakPCEvent;
class LinuxSkipDelayLoopEvent;
class SkipFuncEvent;
@@ -87,6 +87,9 @@ class LinuxSystem : public System
/** PC based event to skip the ide_delay_50ms() call */
SkipFuncEvent *skipIdeDelay50msEvent;
+ /** PC based event to skip the dprink() call and emulate its functionality */
+ DebugPrintkEvent *debugPrintkEvent;
+
/** Skip calculate_delay_loop() rather than waiting for this to be
* calculated
*/
diff --git a/kern/linux/printk.cc b/kern/linux/printk.cc
new file mode 100644
index 000000000..fc7c171bc
--- /dev/null
+++ b/kern/linux/printk.cc
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2003 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <algorithm>
+
+#include "base/cprintf.hh"
+#include "base/trace.hh"
+#include "sim/host.hh"
+#include "targetarch/arguments.hh"
+#include "targetarch/vtophys.hh"
+#include "kern/linux/printk.hh"
+
+using namespace std;
+
+
+void
+Printk(AlphaArguments args)
+{
+ char *p = (char *)args++;
+
+ ios::fmtflags saved_flags = DebugOut().flags();
+ char old_fill = DebugOut().fill();
+ int old_precision = DebugOut().precision();
+
+ while (*p) {
+ switch (*p) {
+ case '%': {
+ bool more = true;
+ bool islong = false;
+ bool leftjustify = false;
+ bool format = false;
+ bool zero = false;
+ int width = 0;
+ while (more && *++p) {
+ switch (*p) {
+ case 'l':
+ case 'L':
+ islong = true;
+ break;
+ case '-':
+ leftjustify = true;
+ break;
+ case '#':
+ format = true;
+ break;
+ case '0':
+ if (width)
+ width *= 10;
+ else
+ zero = true;
+ break;
+ default:
+ if (*p >= '1' && *p <= '9')
+ width = 10 * width + *p - '0';
+ else
+ more = false;
+ break;
+ }
+ }
+
+ bool hexnum = false;
+ bool octal = false;
+ bool sign = false;
+ switch (*p) {
+ case 'X':
+ case 'x':
+ hexnum = true;
+ break;
+ case 'O':
+ case 'o':
+ octal = true;
+ break;
+ case 'D':
+ case 'd':
+ sign = true;
+ break;
+ case 'P':
+ format = true;
+ case 'p':
+ hexnum = true;
+ break;
+ }
+
+ switch (*p) {
+ case 'D':
+ case 'd':
+ case 'U':
+ case 'u':
+ case 'X':
+ case 'x':
+ case 'O':
+ case 'o':
+ case 'P':
+ case 'p': {
+ if (hexnum)
+ DebugOut() << hex;
+
+ if (octal)
+ DebugOut() << oct;
+
+ if (format) {
+ if (!zero)
+ DebugOut().setf(ios::showbase);
+ else {
+ if (hexnum) {
+ DebugOut() << "0x";
+ width -= 2;
+ } else if (octal) {
+ DebugOut() << "0";
+ width -= 1;
+ }
+ }
+ }
+
+ if (zero)
+ DebugOut().fill('0');
+
+ if (width > 0)
+ DebugOut().width(width);
+
+ if (leftjustify && !zero)
+ DebugOut().setf(ios::left);
+
+ if (sign) {
+ if (islong)
+ DebugOut() << (int64_t)args;
+ else
+ DebugOut() << (int32_t)args;
+ } else {
+ if (islong)
+ DebugOut() << (uint64_t)args;
+ else
+ DebugOut() << (uint32_t)args;
+ }
+
+ if (zero)
+ DebugOut().fill(' ');
+
+ if (width > 0)
+ DebugOut().width(0);
+
+ DebugOut() << dec;
+
+ ++args;
+ }
+ break;
+
+ case 's': {
+ char *s = (char *)args;
+ if (!s)
+ s = "<NULL>";
+
+ if (width > 0)
+ DebugOut().width(width);
+ if (leftjustify)
+ DebugOut().setf(ios::left);
+
+ DebugOut() << s;
+ ++args;
+ }
+ break;
+ case 'C':
+ case 'c': {
+ uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
+ uint64_t num;
+ int width;
+
+ if (islong) {
+ num = (uint64_t)args;
+ width = sizeof(uint64_t);
+ } else {
+ num = (uint32_t)args;
+ width = sizeof(uint32_t);
+ }
+
+ while (width-- > 0) {
+ char c = (char)(num & mask);
+ if (c)
+ DebugOut() << c;
+ num >>= 8;
+ }
+
+ ++args;
+ }
+ break;
+ case 'b': {
+ uint64_t n = (uint64_t)args++;
+ char *s = (char *)args++;
+ DebugOut() << s << ": " << n;
+ }
+ break;
+ case 'n':
+ case 'N': {
+ args += 2;
+#if 0
+ uint64_t n = (uint64_t)args++;
+ struct reg_values *rv = (struct reg_values *)args++;
+#endif
+ }
+ break;
+ case 'r':
+ case 'R': {
+ args += 2;
+#if 0
+ uint64_t n = (uint64_t)args++;
+ struct reg_desc *rd = (struct reg_desc *)args++;
+#endif
+ }
+ break;
+ case '%':
+ DebugOut() << '%';
+ break;
+ }
+ ++p;
+ }
+ break;
+ case '\n':
+ DebugOut() << endl;
+ ++p;
+ break;
+ case '\r':
+ ++p;
+ if (*p != '\n')
+ DebugOut() << endl;
+ break;
+
+ default: {
+ size_t len = strcspn(p, "%\n\r\0");
+ DebugOut().write(p, len);
+ p += len;
+ }
+ }
+ }
+
+ DebugOut().flags(saved_flags);
+ DebugOut().fill(old_fill);
+ DebugOut().precision(old_precision);
+}
+
diff --git a/kern/linux/printk.hh b/kern/linux/printk.hh
new file mode 100644
index 000000000..98493b753
--- /dev/null
+++ b/kern/linux/printk.hh
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2003-2004 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * 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.
+ */
+
+#ifndef __PRINTK_HH__
+#define __PRINTK_HH__
+
+class AlphaArguments;
+
+void Printk(AlphaArguments args);
+
+#endif // __PRINTK_HH__
diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc
index 9121e823d..5dd8e64c3 100644
--- a/kern/tru64/dump_mbuf.cc
+++ b/kern/tru64/dump_mbuf.cc
@@ -31,6 +31,7 @@
#include "base/cprintf.hh"
#include "base/trace.hh"
+#include "cpu/exec_context.hh"
#include "kern/tru64/mbuf.hh"
#include "sim/host.hh"
#include "targetarch/arguments.hh"
@@ -58,7 +59,8 @@ DumpMbuf(AlphaArguments args)
addr, m.m_data, m.m_len);
char *buffer = new char[m.m_len];
CopyOut(xc, buffer, m.m_data, m.m_len);
- Trace::rawDump((uint8_t *)buffer, m.m_len);
+ Trace::dataDump(curTick, xc->system->name(), (uint8_t *)buffer,
+ m.m_len);
delete [] buffer;
count -= m.m_len;
diff --git a/sim/eventq.cc b/sim/eventq.cc
index 6b4ccc827..f975c5e97 100644
--- a/sim/eventq.cc
+++ b/sim/eventq.cc
@@ -208,6 +208,13 @@ EventQueue::dump()
cprintf("============================================================\n");
}
+extern "C"
+void
+dumpMainQueue()
+{
+ mainEventQueue.dump();
+}
+
const char *
Event::description()
@@ -235,16 +242,18 @@ Event::trace(const char *action)
void
Event::dump()
{
+ cprintf("Event (%s)\n", description());
+ cprintf("Flags: %#x\n", _flags);
#if TRACING_ON
- cprintf(" Created: %d\n", when_created);
+ cprintf("Created: %d\n", when_created);
#endif
if (scheduled()) {
#if TRACING_ON
- cprintf(" Scheduled at %d\n", when_scheduled);
+ cprintf("Scheduled at %d\n", when_scheduled);
#endif
- cprintf(" Scheduled for %d\n", when());
+ cprintf("Scheduled for %d, priority %d\n", when(), _priority);
}
else {
- cprintf(" Not Scheduled\n");
+ cprintf("Not Scheduled\n");
}
}
diff --git a/sim/sim_object.cc b/sim/sim_object.cc
index 39219b500..818648b98 100644
--- a/sim/sim_object.cc
+++ b/sim/sim_object.cc
@@ -30,6 +30,7 @@
#include "base/callback.hh"
#include "base/inifile.hh"
+#include "base/match.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "base/stats/events.hh"
@@ -53,13 +54,21 @@ using namespace std;
//
SimObject::SimObjectList SimObject::simObjectList;
+namespace Stats {
+ extern ObjectMatch event_ignore;
+}
+
//
// SimObject constructor: used to maintain static simObjectList
//
SimObject::SimObject(const string &_name)
: objName(_name)
{
- doRecordEvent = !Stats::ignoreEvent(_name);
+#ifdef DEBUG
+ doDebugBreak = false;
+#endif
+
+ doRecordEvent = !Stats::event_ignore.match(_name);
simObjectList.push_back(this);
}
@@ -172,6 +181,31 @@ SimObject::serializeAll(ostream &os)
}
}
+#ifdef DEBUG
+//
+// static function: flag which objects should have the debugger break
+//
+void
+SimObject::debugObjectBreak(const string &objs)
+{
+ SimObjectList::const_iterator i = simObjectList.begin();
+ SimObjectList::const_iterator end = simObjectList.end();
+
+ ObjectMatch match(objs);
+ for (; i != end; ++i) {
+ SimObject *obj = *i;
+ obj->doDebugBreak = match.match(obj->name());
+ }
+}
+
+extern "C"
+void
+debugObjectBreak(const char *objs)
+{
+ SimObject::debugObjectBreak(string(objs));
+}
+#endif
+
void
SimObject::recordEvent(const std::string &stat)
{
diff --git a/sim/sim_object.hh b/sim/sim_object.hh
index 770cd558e..dfd70f8ec 100644
--- a/sim/sim_object.hh
+++ b/sim/sim_object.hh
@@ -83,6 +83,12 @@ class SimObject : public Serializable
// static: call nameOut() & serialize() on all SimObjects
static void serializeAll(std::ostream &);
+#ifdef DEBUG
+ public:
+ bool doDebugBreak;
+ static void debugObjectBreak(const std::string &objs);
+#endif
+
public:
bool doRecordEvent;
void recordEvent(const std::string &stat);
diff --git a/sim/stat_control.cc b/sim/stat_control.cc
index 9a4313a61..8a8eaa790 100644
--- a/sim/stat_control.cc
+++ b/sim/stat_control.cc
@@ -80,6 +80,12 @@ statElapsedTime()
return elapsed();
}
+Tick
+statElapsedTicks()
+{
+ return curTick - startTick;
+}
+
SimTicksReset simTicksReset;
void
@@ -105,7 +111,7 @@ InitSimStats()
;
simTicks
- .scalar(curTick)
+ .functor(statElapsedTicks)
.name("sim_ticks")
.desc("Number of ticks simulated")
;
diff --git a/util/ccdrv/devtime.c b/util/ccdrv/devtime.c
index c3897e597..e487f2fe7 100644
--- a/util/ccdrv/devtime.c
+++ b/util/ccdrv/devtime.c
@@ -54,18 +54,16 @@ static inline uint32_t cycleCounter(uint32_t dep);
static int __init devtime_start(void)
{
uint64_t addr;
- uint32_t t1, t2;
+ uint32_t t1, t2;
uint32_t trash;
int x;
uint32_t *times;
uint32_t num = 0;
struct net_device *dev;
-
printk("Devtime Driver Version %s Loaded...\n", DRIVER_VER);
- if ((dataAddr != 0) && (count != 0))
- {
+ if (dataAddr != 0 && count != 0) {
addr = simple_strtoull(dataAddr, NULL, 0);
addr = ioremap(addr, PAGE_SIZE);
@@ -75,19 +73,16 @@ static int __init devtime_start(void)
* if physical memory is mapped to this address.
*/
times = kmalloc(sizeof(uint32_t) * count, GFP_USER);
- if (!times)
- {
+ if (!times) {
printk("Could not allocate memory... Try again later.\n");
return -1;
}
- if (addr)
- {
+ if (addr) {
printk("Preparing to read %#llx %d times.\n", addr, count);
t1 = cycleCounter(trash);
- for (x=0; x < count; x++)
- {
+ for (x = 0; x < count; x++) {
trash = readl(addr);
t2 = cycleCounter(trash);
times[num++] = t2 - t1;
@@ -100,36 +95,30 @@ static int __init devtime_start(void)
iounmap(addr);
printk("Measurements:\n");
- for (x = 0; x < count; x++)
- {
+ for (x = 0; x < count; x++) {
printk("%d ", times[x]);
- if (((x+1) % 10) == 0)
+ if (((x + 1) % 10) == 0)
printk("\n");
}
printk("\nDone.\n");
-
-
- }
- else
+ } else {
printk("Unable to remap address. Please try again later.\n");
+ }
} else {
dev = dev_get_by_name("eth0");
- if (dev)
- {
- printk("Eth0: MemStart: %#lx MemEnd: %#lx I/O Addr: %#lx\n", dev->mem_start,
- dev->mem_end, dev->base_addr);
+ if (dev) {
+ printk("Eth0: MemStart: %#lx MemEnd: %#lx I/O Addr: %#lx\n",
+ dev->mem_start, dev->mem_end, dev->base_addr);
dev_put(dev);
}
dev = 0;
dev = dev_get_by_name("eth1");
- if (dev)
- {
- printk("Eth1: MemStart: %#lx MemEnd: %#lx I/O Addr: %#lx\n", dev->mem_start,
- dev->mem_end, dev->base_addr);
+ if (dev) {
+ printk("Eth1: MemStart: %#lx MemEnd: %#lx I/O Addr: %#lx\n",
+ dev->mem_start, dev->mem_end, dev->base_addr);
dev_put(dev);
}
-
printk("Required information not supplied.\n");
}
@@ -159,7 +148,8 @@ inline uint32_t cycleCounter(uint32_t dep)
#error Architecture NOT SUPPORTE
#endif
-static void __exit devtime_end(void) {
+static void __exit devtime_end(void)
+{
printk("Devtime Driver Version %s Unloaded...\n", DRIVER_VER);
}