(record_data_memory_write_latency): New virtual method.
* Contribute the following changes:n_memory_read_latency.
(write_insn_memory): Call record_insn_memory_write_latency.
2005-07-13 Dave Brolley <brolley@redhat.com>ad_latency.
(write_data_memory): Call record_data_memory_write_latency.
* mepCfg.cxx (set_dynamic_config): New method of MepMemCfg.::check_level
(MepCacheCfg::set_dynamic_config): Don't use the new-config pin
or the dynamic-configurator attribute. Instead, relate the cache
to the dynamic configurator using its client relation.
(MepBoardCfg::write_config): Likewise for the insn_buffer, dmac,result
hw_engines and peripherals. Call set_dynamic_config for shared_main_mem.
* mainDynamic.cxx (BoardConfig): New struct type.
(main): Keep a vector of the boards in board_configs. Call:ok.
set_start_config for each board after all the --wrap options have
been seen. Call add_wrapped_component to identify each wrapped
component to the session.y@redhat.com>
* commonCfg.h (wrapped_components): New member of SessionCfg.
(add_wrapped_component): New method of SessionCfg.New class.
(wrap_config): Likewise.ule): Reschedule after the given number of
* commonCfg.cxx (wrap_config): New method of SessionCfg.
(profile_config): Use possible_wrap_name to obtain the component
being wrapped so we can get its name.
(GdbCfg::write_config): Don't connect the new-config pin or use the
dynamic-configurator relation. Instead, use the dynamic configurator's
client relation.
(BoardCfg::write_config): Likewise. Relate the dynamic configurator
to gloss.
* baseCfg.cxx (wrap_component): Now returns AtomicCfg *.
(possible_wrap_name): Likewise.
(dynamic_config_for_wrapped_children): Don't connect the dynamic
configurator's new-config pin to the components or relate the
dynamic configurator to them. Rather, relate the components to the
dynamic configurator using its 'client' relation.
* baseCfg.h (wrap_component): Now returns AtomicCfg *.
(possible_wrap_name): Likewise.
2005-07-05 Dave Brolley <brolley@redhat.com>
* commonCfg.cxx (BoardCfg::write_load): Connect dynamic configurator's
"reset" pin to output 2 of reset_net.
(write_config): Set the "start-config" attribute of the dynamic
configurator not gloss. Relate "main" to the dynamic configurator
unconditionally. Connect the "config-error" pins of the dynamic
configurator and gloss.
2005-06-30 Dave Brolley <brolley@redhat.com>
* mainDynamic.cxx (try_add_gprof): Make sure an argument is specified
after the comma.
2005-06-06 Dave Brolley <brolley@redhat.com>
* mainDynamic.cxx (need_sess): Now takes 'verbose' argument. Use it
to initialize sess->verbose. Update all callers.
(main): Add " --model-busses" to board_start_config instead of
" --model_busses" (typo).
* commonCfg.h (need_core_probe): New member of SessionCfg.
(BoardCfg::dynamic_configurator): Now public.
* commonCfg.cxx (SessionCfg): Initialize need_core_probe.
(profile_config): Set need_core_probe for --trace-core. Call
use_tcl_bridge and possible_wrap_name for --wrap.
(LoaderCfg): Don't set verbose? attribute here.
(GlossCfg): Likewise.
(GdbCfg::write_config): Connect the stub and the socket to the
dynamic_configurator.
(BoardCfg): Initialize core_probe and warmup_funcs. Connect the cpu's
print-insn-summary pin to the shutdown sequence here.
(BoardCfg::write_load): Connect the dynamic configurator's step! pin
to the init-sequence's output 6. Set the core_probe's trace?
attribute. Set the gloss and loader's verbose? attributes.
(BoardCfg::write_config): Give the dynamic configurator its own
subscription to sim-sched. Set the cpu's 'main' and core-probe
relations. Connect gloss, core_probe, loader and all of the board's
wrapped childred to the dynamic configurator. Check whether components
are wrapped before connecting them to the dynamic configurator. Don't co
nnect
the cpu's print-insn-summary pin to the shutdown sequence here.
* baseCfg.cxx (AtomicCfg): Initialize my_possibly_wrapped.
(wrap_component): Set my_possibly_wrapped.
(possible_wrap_name): New static method of AtomicCfg.
(AtomicCfg::write_construct): Check my_possibly_wrapped. Set
victim-trace? to false if only possibly wrapped.
(dynamic_config_for_wrapped_children): New method of AggregateCfg.
* baseCfg.h (possible_wrap_name): New static method of AtomicCfg.
(possibly_wrapped): New method of AtomicCfg.
(my_possibly_wrapped): New member of AtomicCfg.
(dynamic_config_for_wrapped_children): New method of AggregateCfg.
2005-05-29 Dave Brolley <brolley@redhat.com>
* mainDynamic.cxx (usage): Document --profile-config,--profile-func,
--warmup-func and --warmup.
(Defs): Initialize warmup, profile_func and start_config.
(warmup,profile_func,warmup_func,start_config): New members of Defs.
(need_sess): Call profile_config with "sid-internal-warmup:".
(opt_warmup,opt_warmup_func,opt_profile_func,opt_profile_config): New
enumerators.
(long_options): Add --profile-config,--profile-func,
--warmup-func and --warmup.
(main): Accumulate start_config with reconfigurable options which occur
before the first --board. For each board call set_start_config with
the value of start_config concatenated with the additional reconfigurabl
e
options specified for that --board. Call set_warmup, add_warmup_func and
add_profile_func for each board. Handle new option enums.
* commonCfg.h (add_profile_config): New method of SessionCfg.
(profile_config_error, profile_opt_value, profile_opt_int_value)
(profile_opt_gprof_value, match_profile_opt, profile_config): New
methods of SessionCfg.
(GprofCfg): New constructor.
(write_load): New virtual override in BoardCfg.
(add_profile_func, add_warmup_func, set_warmup, set_start_config): New
methods of BoardCfg.
(need_gprof): New member of BoardCfg.
(start_config,warmup_funcs,profile_funcs): New members of BoardCfg.
* commonCfg.cxx (SessionCfg): Initialize need_gprof.
(add_profile_config): New method of SessionCfg.
(profile_config_error, profile_opt_value, profile_opt_int_value)
(profile_opt_gprof_value, match_profile_opt, profile_config): New
methods of SessionCfg.
(GprofCfg): Always add a sunscription to sim_sched. Set the
sim-sched-event attribute.
(GprofCfg): New constructor.
(BoardCfg): Initialize dynamic_configurator and start_config.
(write_load): New virtual override in BoardCfg.
(BoardCfg::write_config): Make connections and set attributes to allow
for dynamic configuration.
(add_profile_func, add_warmup_func, set_warmup, set_start_config): New
methods of BoardCfg.
+2005-08-19 Dave Brolley <brolley@redhat.com>
+
+ * Contribute the following changes:
+
+ 2005-07-13 Dave Brolley <brolley@redhat.com>
+
+ * mepCfg.cxx (set_dynamic_config): New method of MepMemCfg.
+ (MepCacheCfg::set_dynamic_config): Don't use the new-config pin
+ or the dynamic-configurator attribute. Instead, relate the cache
+ to the dynamic configurator using its client relation.
+ (MepBoardCfg::write_config): Likewise for the insn_buffer, dmac,
+ hw_engines and peripherals. Call set_dynamic_config for shared_main_mem.
+ * mainDynamic.cxx (BoardConfig): New struct type.
+ (main): Keep a vector of the boards in board_configs. Call
+ set_start_config for each board after all the --wrap options have
+ been seen. Call add_wrapped_component to identify each wrapped
+ component to the session.
+ * commonCfg.h (wrapped_components): New member of SessionCfg.
+ (add_wrapped_component): New method of SessionCfg.
+ (wrap_config): Likewise.
+ * commonCfg.cxx (wrap_config): New method of SessionCfg.
+ (profile_config): Use possible_wrap_name to obtain the component
+ being wrapped so we can get its name.
+ (GdbCfg::write_config): Don't connect the new-config pin or use the
+ dynamic-configurator relation. Instead, use the dynamic configurator's
+ client relation.
+ (BoardCfg::write_config): Likewise. Relate the dynamic configurator
+ to gloss.
+ * baseCfg.cxx (wrap_component): Now returns AtomicCfg *.
+ (possible_wrap_name): Likewise.
+ (dynamic_config_for_wrapped_children): Don't connect the dynamic
+ configurator's new-config pin to the components or relate the
+ dynamic configurator to them. Rather, relate the components to the
+ dynamic configurator using its 'client' relation.
+ * baseCfg.h (wrap_component): Now returns AtomicCfg *.
+ (possible_wrap_name): Likewise.
+
+ 2005-07-05 Dave Brolley <brolley@redhat.com>
+
+ * commonCfg.cxx (BoardCfg::write_load): Connect dynamic configurator's
+ "reset" pin to output 2 of reset_net.
+ (write_config): Set the "start-config" attribute of the dynamic
+ configurator not gloss. Relate "main" to the dynamic configurator
+ unconditionally. Connect the "config-error" pins of the dynamic
+ configurator and gloss.
+
+ 2005-06-30 Dave Brolley <brolley@redhat.com>
+
+ * mainDynamic.cxx (try_add_gprof): Make sure an argument is specified
+ after the comma.
+
+ 2005-06-06 Dave Brolley <brolley@redhat.com>
+
+ * mainDynamic.cxx (need_sess): Now takes 'verbose' argument. Use it
+ to initialize sess->verbose. Update all callers.
+ (main): Add " --model-busses" to board_start_config instead of
+ " --model_busses" (typo).
+ * commonCfg.h (need_core_probe): New member of SessionCfg.
+ (BoardCfg::dynamic_configurator): Now public.
+ * commonCfg.cxx (SessionCfg): Initialize need_core_probe.
+ (profile_config): Set need_core_probe for --trace-core. Call
+ use_tcl_bridge and possible_wrap_name for --wrap.
+ (LoaderCfg): Don't set verbose? attribute here.
+ (GlossCfg): Likewise.
+ (GdbCfg::write_config): Connect the stub and the socket to the
+ dynamic_configurator.
+ (BoardCfg): Initialize core_probe and warmup_funcs. Connect the cpu's
+ print-insn-summary pin to the shutdown sequence here.
+ (BoardCfg::write_load): Connect the dynamic configurator's step! pin
+ to the init-sequence's output 6. Set the core_probe's trace?
+ attribute. Set the gloss and loader's verbose? attributes.
+ (BoardCfg::write_config): Give the dynamic configurator its own
+ subscription to sim-sched. Set the cpu's 'main' and core-probe
+ relations. Connect gloss, core_probe, loader and all of the board's
+ wrapped childred to the dynamic configurator. Check whether components
+ are wrapped before connecting them to the dynamic configurator. Don't connect
+ the cpu's print-insn-summary pin to the shutdown sequence here.
+ * baseCfg.cxx (AtomicCfg): Initialize my_possibly_wrapped.
+ (wrap_component): Set my_possibly_wrapped.
+ (possible_wrap_name): New static method of AtomicCfg.
+ (AtomicCfg::write_construct): Check my_possibly_wrapped. Set
+ victim-trace? to false if only possibly wrapped.
+ (dynamic_config_for_wrapped_children): New method of AggregateCfg.
+ * baseCfg.h (possible_wrap_name): New static method of AtomicCfg.
+ (possibly_wrapped): New method of AtomicCfg.
+ (my_possibly_wrapped): New member of AtomicCfg.
+ (dynamic_config_for_wrapped_children): New method of AggregateCfg.
+
+ 2005-05-29 Dave Brolley <brolley@redhat.com>
+
+ * mainDynamic.cxx (usage): Document --profile-config,--profile-func,
+ --warmup-func and --warmup.
+ (Defs): Initialize warmup, profile_func and start_config.
+ (warmup,profile_func,warmup_func,start_config): New members of Defs.
+ (need_sess): Call profile_config with "sid-internal-warmup:".
+ (opt_warmup,opt_warmup_func,opt_profile_func,opt_profile_config): New
+ enumerators.
+ (long_options): Add --profile-config,--profile-func,
+ --warmup-func and --warmup.
+ (main): Accumulate start_config with reconfigurable options which occur
+ before the first --board. For each board call set_start_config with
+ the value of start_config concatenated with the additional reconfigurable
+ options specified for that --board. Call set_warmup, add_warmup_func and
+ add_profile_func for each board. Handle new option enums.
+ * commonCfg.h (add_profile_config): New method of SessionCfg.
+ (profile_config_error, profile_opt_value, profile_opt_int_value)
+ (profile_opt_gprof_value, match_profile_opt, profile_config): New
+ methods of SessionCfg.
+ (GprofCfg): New constructor.
+ (write_load): New virtual override in BoardCfg.
+ (add_profile_func, add_warmup_func, set_warmup, set_start_config): New
+ methods of BoardCfg.
+ (need_gprof): New member of BoardCfg.
+ (start_config,warmup_funcs,profile_funcs): New members of BoardCfg.
+ * commonCfg.cxx (SessionCfg): Initialize need_gprof.
+ (add_profile_config): New method of SessionCfg.
+ (profile_config_error, profile_opt_value, profile_opt_int_value)
+ (profile_opt_gprof_value, match_profile_opt, profile_config): New
+ methods of SessionCfg.
+ (GprofCfg): Always add a sunscription to sim_sched. Set the
+ sim-sched-event attribute.
+ (GprofCfg): New constructor.
+ (BoardCfg): Initialize dynamic_configurator and start_config.
+ (write_load): New virtual override in BoardCfg.
+ (BoardCfg::write_config): Make connections and set attributes to allow
+ for dynamic configuration.
+ (add_profile_func, add_warmup_func, set_warmup, set_start_config): New
+ methods of BoardCfg.
+
2005-06-03 Jim Blandy <jimb@redhat.com>
* Makefile.am (LIBIBERTY): Link against the libiberty.a from
AtomicCfg::AtomicCfg (const string name, const string complib,
const string compsym, const string comptype) :
ComponentCfg (name),
- wrapped (false),
+ my_wrapped (false),
+ my_possibly_wrapped (false),
my_complib (complib),
my_compsym (compsym),
my_comptype (comptype)
AtomicCfg::~AtomicCfg() {}
-bool AtomicCfg::wrap_component (const string name)
+AtomicCfg *AtomicCfg::wrap_component (const string name)
{
if (AtomicCfg_impl::atomic_names.find (name) ==
AtomicCfg_impl::atomic_names.end ())
- return false;
- AtomicCfg_impl::atomic_names[name]->wrapped = true;
- return true;
+ return 0;
+ AtomicCfg *comp = AtomicCfg_impl::atomic_names[name];
+ comp->my_wrapped = true;
+ comp->my_possibly_wrapped = false;
+ return comp;
+}
+
+AtomicCfg *
+AtomicCfg::possible_wrap_name (const string &name)
+{
+ if (AtomicCfg_impl::atomic_names.find (name) ==
+ AtomicCfg_impl::atomic_names.end ())
+ return 0;
+ AtomicCfg *comp = AtomicCfg_impl::atomic_names[name];
+ if (! comp->my_wrapped)
+ comp->my_possibly_wrapped = true;
+ return comp;
}
void AtomicCfg::reset_load_map ()
{
if (my_comptype == "")
return;
- if (wrapped)
+ if (my_wrapped || my_possibly_wrapped)
{
w.write_line ("new sid-api-trace " + my_name);
w.write_line ("new " + my_comptype + " " + my_name + "-traced");
w.write_line ("relate " + my_name + " victim " + my_name + "-traced");
+ w.write_line ("set " + my_name + " victim-name " + my_name + "-traced");
+ if (my_possibly_wrapped)
+ w.write_line ("set " + my_name + " victim-trace? 0");
}
else
w.write_line ("new " + my_comptype + " " + my_name);
}
+void AggregateCfg::dynamic_config_for_wrapped_children (AtomicCfg *dynamic_configurator, Writer &w)
+{
+ assert (dynamic_configurator);
+ for (vector<ComponentCfg *>::const_iterator i = a_impl->my_children.begin();
+ i != a_impl->my_children.end(); ++i)
+ {
+ if (*i == dynamic_configurator)
+ continue;
+ AtomicCfg *a = dynamic_cast<AtomicCfg *>(*i);
+ if (a)
+ {
+ if (a->possibly_wrapped ())
+ {
+ Relation (dynamic_configurator, "client", a).write_to (w);
+ }
+ continue;
+ }
+ AggregateCfg *ag = dynamic_cast<AggregateCfg *>(*i);
+ if (ag)
+ {
+ ag->dynamic_config_for_wrapped_children (dynamic_configurator, w);
+ continue;
+ }
+ assert (false);
+ }
+}
+
Connection::Connection (ComponentCfg *src, const string srcport,
ComponentCfg *dst, const string dstport,
virtual void write_load (Writer &w);
virtual void write_construct (Writer &w);
static void reset_load_map ();
- static bool wrap_component (const string name);
+ static AtomicCfg *wrap_component (const string name);
+ static AtomicCfg *possible_wrap_name (const string &comp_name);
string comp_type () const { return my_comptype; }
+ bool wrapped () const { return my_wrapped; }
+ bool possibly_wrapped () const { return my_wrapped || my_possibly_wrapped; }
protected:
- bool wrapped;
+ bool my_wrapped;
+ bool my_possibly_wrapped;
string my_complib;
string my_compsym;
string my_comptype;
virtual void write_config (Writer &w);
void add_child (ComponentCfg *c);
virtual const ResolvedName resolve(const role r, const string name);
+ void dynamic_config_for_wrapped_children (AtomicCfg *dynamic_configurator, Writer &w);
protected:
AggregateCfg_impl *a_impl;
};
loader (NULL),
verbose (false),
use_stdio (true),
+ need_gprof (false),
+ need_core_probe (false),
board_count (0),
gdb_count (0)
{
add_child (ulog);
}
+void
+SessionCfg::add_profile_config (const string &name, const string &options)
+{
+ set (main_obj, "dynamic-config!", name + "|" + options);
+}
+
void SessionCfg::set_loader (LoaderCfg *l)
{
if (loader)
init_seq->add_output (7, tcl_bridge, "!event");
}
+string
+SessionCfg::wrap_config ()
+{
+ string spec;
+ for (vector<AtomicCfg *>::const_iterator it = wrapped_components.begin ();
+ it != wrapped_components.end ();
+ ++it)
+ spec += " --wrap=" + (*it)->get_name ();
+ return spec;
+}
+
+// Process the argument to --profile-config which will
+// be a subset of the allowable SID command line options
+// which can be dynamically changed.
+//
+void
+SessionCfg::profile_config_error (const string &spec)
+{
+ cerr << "error: invalid argument to --profile-config: " << spec << endl;
+ exit (8);
+}
+
+string
+SessionCfg::profile_opt_value (const string& opt, const vector<string>& opt_parts, unsigned max_parts)
+{
+ unsigned size = opt_parts.size ();
+ if (size > max_parts)
+ profile_config_error (opt); // doesn't return
+
+ if (max_parts == 1)
+ return "true";
+
+ return opt_parts[1];
+}
+
+string
+SessionCfg::profile_opt_int_value (const string& opt, const vector<string>& opt_parts)
+{
+ unsigned size = opt_parts.size ();
+ if (size != 2)
+ profile_config_error (opt); // doesn't return
+
+ unsigned n;
+ sid::component::status s = sidutil::parse_attribute (opt_parts[1], n);
+ if (s != sid::component::ok)
+ profile_config_error (opt); // doesn't return
+
+ return opt_parts[1];
+}
+
+string
+SessionCfg::profile_opt_gprof_value (const string& opt, const vector<string>& opt_parts)
+{
+ unsigned size = opt_parts.size ();
+ if (size < 2 || size > 3)
+ profile_config_error (opt); // doesn't return
+
+ vector<string> sub_parts = sidutil::tokenize (opt_parts[1], ",");
+ string value = sub_parts[0];
+ if (size == 3)
+ {
+ if (sub_parts.size () != 2 || sub_parts[1] != "cycles")
+ profile_config_error (opt); // doesn't return
+
+ unsigned n;
+ sid::component::status s = sidutil::parse_attribute (opt_parts[2], n);
+ if (s != sid::component::ok)
+ profile_config_error (opt); // doesn't return
+
+ value += "," + opt_parts[2];
+ }
+
+ need_gprof = true;
+ return value;
+}
+
+bool
+SessionCfg::match_profile_opt (const string &opt, const string& want, unsigned min_size)
+{
+ unsigned opt_size = opt.size ();
+ unsigned want_size = want.size ();
+ if (opt_size < min_size || opt_size > want_size)
+ return false;
+ return opt == want.substr (0, opt_size);
+}
+
+void
+SessionCfg::profile_config (const string &spec)
+{
+ // Extract the name of the config profile
+ vector<string> parts = sidutil::tokenize (spec, ":");
+ if (parts.size () != 2)
+ profile_config_error (spec);
+ string name = parts[0];
+
+ // Initialize the candidate options to their default values.
+ string trace_extract = "false";
+ string trace_semantics = "false";
+ string trace_disassemble = "false";
+ string trace_core = "false";
+ string trace_counter = "false";
+ string ulog_level = "0";
+ string ulog_mode = "less";
+ string wrap = "";
+ string verbose = "false";
+ string final_insn_count = "false";
+ string gprof = "";
+ string insn_count = "10000";
+
+ // Now examine the spec and reset those which are specified.
+ vector<string>opts = sidutil::tokenize (parts[1], " ");
+ int size = opts.size ();
+ for (int i = 0; i < size; ++i)
+ {
+ const string opt = opts[i];
+ vector<string> opt_parts = sidutil::tokenize (opt, "=");
+ const string opt_name = opt_parts[0];
+
+ if (match_profile_opt (opt_name, "--trace-extract", 9))
+ trace_extract = profile_opt_value (opt, opt_parts, 1);
+ else if (match_profile_opt (opt_name, "--trace-semantics", 9))
+ trace_semantics = profile_opt_value (opt, opt_parts, 1);
+ else if (match_profile_opt (opt_name, "--trace-disassemble", 9))
+ trace_disassemble = profile_opt_value (opt, opt_parts, 1);
+ else if (match_profile_opt (opt_name, "--trace-core", 11))
+ {
+ trace_core = profile_opt_value (opt, opt_parts, 1);
+ need_core_probe = true;
+ }
+ else if (match_profile_opt (opt_name, "--trace-counter", 11))
+ trace_counter = profile_opt_value (opt, opt_parts, 1);
+ else if (match_profile_opt (opt_name, "--ulog-level=", 8))
+ ulog_level = profile_opt_int_value (opt, opt_parts);
+ else if (match_profile_opt (opt_name, "--ulog-mode=", 8))
+ ulog_mode = profile_opt_value (opt, opt_parts, 2);
+ else if (match_profile_opt (opt_name, "--verbose", 3))
+ verbose = profile_opt_value (opt, opt_parts, 1);
+ else if (match_profile_opt (opt_name, "--wrap=", 3))
+ {
+ string comp_name = profile_opt_value (opt, opt_parts, 2);
+ use_tcl_bridge ();
+ AtomicCfg *comp = AtomicCfg::possible_wrap_name (comp_name);
+ if (! wrap.empty ()) wrap += ",";
+ if (comp)
+ wrap += comp->get_name ();
+ else
+ wrap += comp_name;
+ }
+ else if (match_profile_opt (opt_name, "--final-insn-count", 3))
+ final_insn_count = profile_opt_value (opt, opt_parts, 1);
+ else if (match_profile_opt (opt_name, "--gprof=", 3))
+ gprof = profile_opt_gprof_value (opt, opt_parts);
+ else if (match_profile_opt (opt_name, "--insn-count=", 3))
+ insn_count = profile_opt_int_value (opt, opt_parts);
+ }
+
+ // Now contruct a string representing the complete configuration
+ add_profile_config (name,
+ "trace-extract=" + trace_extract + ":" +
+ "trace-semantics=" + trace_semantics + ":" +
+ "trace-disassemble=" + trace_disassemble + ":" +
+ "trace-core=" + trace_core + ":" +
+ "trace-counter=" + trace_counter + ":" +
+ "ulog-level=" + ulog_level + ":" +
+ "ulog-mode=" + ulog_mode + ":" +
+ "wrap=" + wrap + ":" +
+ "verbose=" + verbose + ":" +
+ "final-insn-count=" + final_insn_count + ":" +
+ "gprof=" + gprof + ":" +
+ "insn-count=" + insn_count);
+}
+
void SessionCfg::write_config (Writer &w)
{
AggregateCfg::write_config (w);
{
assert (sess);
set (this, "file", "a.out");
- set (this, "verbose?", sess->verbose ? "true" : "false");
conn_pin (this, "error", sess->main_obj, "stop!");
sess->init_seq->add_output (1, this, "load!");
}
conn_pin (this, "trap", cpu, "trap", both);
conn_pin (this, "trap-code", cpu, "trap-code", dst_to_src);
conn_bus (this, "target-memory", mem, mem_bus_name);
- set (this, "verbose?", sess->verbose ? "true" : "false");
assert (sess->init_seq);
sess->init_seq->add_output (2, this, "reset");
}
relate (this, "cpu", cpu);
conn_pin (this, "trap", cpu, "trap", both);
conn_pin (this, "trap-code", cpu, "trap-code", dst_to_src);
- set (this, "verbose?", sess->verbose ? "true" : "false");
assert (sess->init_seq);
sess->init_seq->add_output (2, this, "reset");
}
-
// GprofCfg
GprofCfg::~GprofCfg() {}
GprofCfg::GprofCfg (const string name,
{
assert (cpu);
assert (sess);
+ // Add a subscription to the target scheduler. Even if it's not
+ // used now, it could be used due to dynamic configuration.
+ assert (sess->sim_sched);
+ int slot = sess->sim_sched->add_subscription (this, "sample");
+
if (type == simulated_cycles)
{
- assert (sess->sim_sched);
- int slot = sess->sim_sched->add_subscription (this, "sample");
sess->sim_sched->set_regular (slot, true);
sess->sim_sched->set_time (slot, interval);
}
set (this, "value-attribute", "pc");
set (this, "bucket-size", "4"); // bytes-per-bucket
set (this, "output-file", filename);
+ set (this, "sim-sched-event", sidutil::make_attribute (slot));
+}
+
+// Create a gprof component but don't activate it
+GprofCfg::GprofCfg (const string name,
+ CpuCfg *cpu,
+ SessionCfg *sess) :
+ ComponentCfg (name),
+ AtomicCfg ( name, "libprof.la",
+ "prof_component_library",
+ "sw-profile-gprof")
+{
+ assert (cpu);
+ assert (sess);
+ // Add a subscription to the target scheduler. Even if it's not
+ // used now, it could be used due to dynamic configuration.
+ assert (sess->sim_sched);
+ int slot = sess->sim_sched->add_subscription (this, "sample");
+
+ sess->shutdown_seq->add_output (7, this, "store");
+ relate (this, "target-component", cpu);
+ set (this, "value-attribute", "pc");
+ set (this, "bucket-size", "4"); // bytes-per-bucket
+ set (this, "sim-sched-event", sidutil::make_attribute (slot));
}
Setting (stub, "trace-gdbserv?", "true").write_to (w);
Setting (sock, "verbose?", "true").write_to (w);
}
+
+ // the stub and socket need to be connected to the dynamic_configurator.
+ if (board->dynamic_configurator)
+ {
+ if (! stub->possibly_wrapped ())
+ {
+ Relation (board->dynamic_configurator, "client", stub).write_to (w);
+ }
+ if (! sock->possibly_wrapped ())
+ {
+ Relation (board->dynamic_configurator, "client", sock).write_to (w);
+ }
+ }
}
main_mapper (NULL),
icache (NULL),
dcache (NULL),
- loader (NULL)
+ loader (NULL),
+ core_probe (0),
+ dynamic_configurator (NULL),
+ start_config (""),
+ warmup_funcs ("_Sid_config")
{
assert (sess);
cpu = new CpuCfg ("cpu", default_cpu_variant, sess);
cpu->set_imem (main_mapper, "access-port");
cpu->set_dmem (main_mapper, "access-port");
}
+
+ sess->shutdown_seq->add_output (0, cpu, "print-insn-summary!");
+
add_child (cpu);
add_child (main_mapper);
add_child (cache_flush_net);
add_child (l);
}
+void BoardCfg::write_load (Writer &w)
+{
+ if (gloss)
+ {
+ // Create a dynamic reconfigurator to be used by this gloss
+ dynamic_configurator = new AtomicCfg ("dynamic-config", "libconfig.la",
+ "config_component_library",
+ "sid-control-dynamic-configurator");
+ sess->init_seq->add_output (6, dynamic_configurator, "step!");
+ sess->reset_net->add_output (2, dynamic_configurator, "reset");
+ sess->sim_sched->add_subscription (dynamic_configurator, "step!", "step-control");
+ add_child (dynamic_configurator);
+
+ // If we may need a gprof for dynamic configuration but don't have
+ // one yet, then create a disabled one.
+ if (! gprof && sess->need_gprof)
+ {
+ gprof = new GprofCfg ("gprof", cpu, sess);
+ add_child (gprof);
+ }
+
+ // If we may need a core_probe for dynamic configuration but don't have
+ // one yet, then create a disabled one.
+ if (! core_probe && sess->need_core_probe)
+ {
+ trace_core ();
+ core_probe->set (core_probe, "trace?", "false");
+ }
+
+ if (sess->verbose)
+ set (gloss, "verbose?", "true");
+ }
+ if (loader)
+ if (sess->verbose)
+ set (loader, "verbose?", "true");
+
+ AggregateCfg::write_load (w);
+}
+
void BoardCfg::write_config (Writer &w)
{
AggregateCfg::write_config (w);
+
if (gloss)
{
if (gdb)
PinConnection (gloss, "process-signal", sess->main_obj, "stop!").write_to(w);
PinConnection (gloss, "process-signal", sess->yield_net, "input").write_to(w);
}
+
+ // Set up for dynamic configuration
+ assert (dynamic_configurator);
+ Relation (dynamic_configurator, "main", sess->main_obj).write_to (w);
+ PinConnection (dynamic_configurator, "step-control", cpu, "yield").write_to (w);
+ Relation (gloss, "main", sess->main_obj).write_to (w);
+ Relation (gloss, "dynamic-configurator", dynamic_configurator).write_to (w);
+ PinConnection (gloss, "configure", dynamic_configurator, "configure!").write_to (w);
+ PinConnection (dynamic_configurator, "config-result", gloss, "config-result").write_to (w);
+ PinConnection (dynamic_configurator, "config-error", gloss, "config-error").write_to (w);
+
+ // Set the starting configuration
+ if (start_config.empty ())
+ start_config = "sid-internal-warmup";
+ Setting (dynamic_configurator, "start-config", start_config).write_to (w);
+
+ // Connect the new-config pin of the dynamic configurator to
+ // the components of this board which need to know when the
+ // configuration changes.
+ assert (cpu);
+ Relation (cpu, "main", sess->main_obj).write_to (w);
+ if (! cpu->possibly_wrapped ())
+ {
+ Relation (dynamic_configurator, "client", cpu).write_to (w);
+ }
+ if (gprof)
+ {
+ // gprof's configure! attribute will be set by the cpu.
+ Relation (gprof, "sim-sched", sess->sim_sched).write_to (w);
+ Relation (cpu, "gprof", gprof).write_to (w);
+ }
+ if (! gloss->possibly_wrapped ())
+ {
+ Relation (dynamic_configurator, "client", gloss).write_to (w);
+ }
+ if (core_probe)
+ Relation (cpu, "core-probe", core_probe).write_to (w);
+
+ // Connect the new-config pin of the dynamic configurator to any wrapped child components
+ dynamic_config_for_wrapped_children (dynamic_configurator, w);
+
+ // Make the connections which enable the dynamic configurator to change configs on function
+ // call and return.
+ if (loader)
+ {
+ if (! loader->possibly_wrapped ())
+ {
+ Relation (dynamic_configurator, "client", loader).write_to (w);
+ }
+ PinConnection (cpu, "cg-caller", dynamic_configurator, "function-caller!").write_to (w);
+ PinConnection (cpu, "cg-callee", dynamic_configurator, "function-callee!").write_to (w);
+ PinConnection (cpu, "cg-jump", dynamic_configurator, "function-jump!").write_to (w);
+ PinConnection (cpu, "cg-return", dynamic_configurator, "function-return!").write_to (w);
+ Relation (dynamic_configurator, "loader", loader).write_to (w);
+ PinConnection (dynamic_configurator, "function-address", loader, "function?").write_to (w);
+ }
+
+ // Initialize the warmup functions and profile functions.
+ assert (! warmup_funcs.empty ());
+ Setting (dynamic_configurator, "warmup-functions!", warmup_funcs).write_to (w);
+ if (! profile_funcs.empty ())
+ Setting (dynamic_configurator, "profile-functions!", profile_funcs.substr (1)).write_to (w); // Skip the initial delimeter.
}
else
{
{
assert (cpu);
assert (sess->shutdown_seq);
- sess->shutdown_seq->add_output (0, cpu, "print-insn-summary!");
cpu->set (cpu, "final-insn-count?", "true");
}
core_probe->conn_bus (core_probe, "downstream", main_mapper, "access-port", false);
core_probe->set (core_probe, "trace?", "true");
}
+
+void BoardCfg::add_profile_func (const string &spec)
+{
+ if (! spec.empty ())
+ profile_funcs += "|" + spec;
+}
+
+void BoardCfg::add_warmup_func (const string &funcs)
+{
+ if (! funcs.empty ())
+ warmup_funcs += "," + funcs;
+}
+
+void BoardCfg::set_warmup (bool w)
+{
+ if (w)
+ start_config = "sid-internal-warmup";
+}
+
+void BoardCfg::set_start_config (const string &config)
+{
+ if (! start_config.empty ())
+ return;
+
+ if (! config.empty ())
+ {
+ start_config = "sid-internal-start-" + get_name ();
+ sess->profile_config (start_config + ":" + config.substr (1)); // get past leading comma
+ }
+}
AtomicCfg *tcl_bridge;
bool verbose;
bool use_stdio;
+ bool need_gprof;
+ bool need_core_probe;
void add_ulog_file (const string filename);
+
map<const string, AtomicCfg *> ulog_map;
void add_gdb () { ++gdb_count; }
void add_board (ComponentCfg *b) { ++board_count; add_child (b); }
virtual void write_config (Writer &w);
+ // Support for dynamic configuration profiles
+ vector<AtomicCfg *> wrapped_components;
+ void add_wrapped_component (AtomicCfg *comp) { wrapped_components.push_back (comp); }
+ string wrap_config ();
+ void profile_config (const string &spec);
+protected:
+ void add_profile_config (const string &name, const string &options);
+ void profile_config_error (const string &spec);
+ string profile_opt_value (const string& opt, const vector<string>& opt_parts, unsigned max_parts);
+ string profile_opt_int_value (const string& opt, const vector<string>& opt_parts);
+ string profile_opt_gprof_value (const string& opt, const vector<string>& opt_parts);
+ bool match_profile_opt (const string &opt, const string& want, unsigned min_size);
private:
sid::host_int_4 board_count;
sid::host_int_4 gdb_count;
SessionCfg *sess,
gprof_type type,
int interval);
+ GprofCfg (const string name,
+ CpuCfg *cpu,
+ SessionCfg *sess);
virtual ~GprofCfg ();
};
virtual void trace_semantics ();
virtual void trace_disassemble ();
virtual void trace_core ();
+ virtual void set_warmup (bool w = true);
+ virtual void add_profile_func (const string &spec);
+ virtual void add_warmup_func (const string &funcs);
+ virtual void set_start_config (const string &config);
+ virtual void write_load (Writer &w);
virtual void write_config (Writer &w);
virtual ~BoardCfg ();
CpuCfg *cpu;
SessionCfg *sess;
MapperCfg *main_mapper;
+ AtomicCfg *dynamic_configurator;
protected:
GdbCfg *gdb;
AtomicCfg *icache;
AtomicCfg *dcache;
LoaderCfg *loader;
+
+ string start_config;
+ string warmup_funcs;
+ string profile_funcs;
};
#endif // __commonCfg_h__
// mainDynamic.cxx - high-tech mainline. -*- C++ -*-
-// Copyright (C) 1999-2004 Red Hat.
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat.
// This file is part of SID and is licensed under the GPL.
// See the file COPYING.SID for conditions for redistribution.
#include <getopt.h>
+#include <string>
+
// Stub functions to set breakpoints on
static void sid_pre_configure () {}
static void sid_post_configure () {}
cout << "FILE names supplied without -f are done last, in sequence." << endl;
cout << endl;
cout << "--persistent Run top-level loop indefinitely" << endl;
+ cout << "--profile-config=NAME,OPTIONS" << endl;
+ cout << " Specify options for a named profiling configuration" << endl;
cout << "--rc Pass stop code as simulator exit rc" << endl;
cout << "--save-temps=FILE Write config to FILE, '-' for stdout." << endl;
cout << "--wrap=COMPONENT Turn on SID API tracing for COMPONENT" << endl;
<< " mmap Memory map given file" << endl
<< " latency=r:w Set read, write latencies [0:0]" << endl
<< " latency=rw Set both latencies [0]" << endl;
+ cout << "--profile-func=FUNCTIONS:NAME" << endl;
+ cout << " Specify functions which use a given profiling configuration" << endl;
cout << "--ulog-level=LEVEL Set the logging level for the current board" << endl;
cout << "--ulog-mode=less|match|equal" << endl
<< " Set the logging mode for the current board" << endl;
cout << "--ulog-file=-|FILE Set the log file name" << endl;
+ cout << "--warmup Start the simulation in 'warm-up' mode" << endl;
+ cout << "--warmup-func=FUNCTIONS" << endl;
+ cout << " Specify functions to be simulated in 'warm-up' mode" << endl;
cout << endl
<< " note: most board-specific options can be used in board-neutral position " << endl
<< " where they are interpreted as session-specific or default settings. " << endl;
type = instruction_count; // default type value
if (toks.size() > 1) // if we have a type argument
{
+ if (toks[1].empty ())
+ {
+ cerr << "error: unknown sub-option to --gprof: " << optstring << endl;
+ exit (21);
+ }
vector<string> subtoks = sidutil::tokenize (toks[1], "=");
-
if (subtoks[0] == "cycles") // If it is cycles
{
type = simulated_cycles;
ulog_level (0),
ulog_mode ("less"),
ulog_file ("-"),
+ warmup (false),
+ profile_func (""),
+ warmup_func (""),
+ start_config (""),
step_insn_count ("10000")
{}
string cpu;
sid::host_int_4 ulog_level;
string ulog_mode;
string ulog_file;
+ bool warmup;
+ string profile_func;
+ string warmup_func;
+ string start_config;
string step_insn_count;
};
+struct BoardConfig
+{
+ BoardCfg *board;
+ string config;
+};
-void need_sess (SessionCfg *&sess)
+static void need_sess (SessionCfg *&sess, bool verbose)
{
if (! sess)
- sess = new SessionCfg ("");
+ {
+ sess = new SessionCfg ("");
+ sess->profile_config ("sid-internal-warmup:");
+ sess->verbose = verbose;
+ }
}
-
// main line
int
main(int argc, char* argv[])
string output_file ("");
SessionCfg *sess = NULL;
BoardCfg *curr_board = NULL;
+ vector<BoardConfig> board_configs;
int nboards = 0;
if (argc == 1)
enum option_num { opt_help, opt_version, opt_save_temps, opt_wrap,
opt_verbose, opt_tksched, opt_enable_warnings,
- opt_persistent, opt_rc, opt_no_run, opt_sidrtc, opt_sidcodec,
+ opt_persistent, opt_profile_config,
+ opt_rc, opt_no_run, opt_sidrtc, opt_sidcodec,
opt_tksm, opt_board, opt_cpu, opt_gdb, opt_gloss, opt_engine,
opt_insn_count, opt_load, opt_icache, opt_dcache,
- opt_memory_region, opt_trace_extract, opt_trace_semantics,
+ opt_memory_region, opt_profile_func,
+ opt_trace_extract, opt_trace_semantics,
opt_trace_disassemble, opt_trace_counter, opt_trace_core,
opt_final_insn_count, opt_eb, opt_el, opt_gprof,
- opt_ulog_level, opt_ulog_mode, opt_ulog_file };
+ opt_ulog_level, opt_ulog_mode, opt_ulog_file,
+ opt_warmup, opt_warmup_func };
int curr_opt;
{"tksched", no_argument, & curr_opt, opt_tksched },
{"enable-warnings", no_argument, & curr_opt, opt_enable_warnings },
{"persistent", no_argument, & curr_opt, opt_persistent },
+ {"profile-config", required_argument, &curr_opt, opt_profile_config },
{"rc", no_argument, & curr_opt, opt_rc },
{"tksm", no_argument, & curr_opt, opt_tksm },
{"dcache", required_argument, & curr_opt, opt_dcache },
{"memory-region", required_argument, & curr_opt, opt_memory_region },
{"gloss", no_argument, & curr_opt, opt_gloss },
+ {"profile-func", required_argument, &curr_opt, opt_profile_func },
{"trace-extract", no_argument, & curr_opt, opt_trace_extract },
{"trace-semantics", no_argument, & curr_opt, opt_trace_semantics },
{"trace-disassemble", no_argument, & curr_opt, opt_trace_disassemble },
{"ulog-level", required_argument, &curr_opt, opt_ulog_level },
{"ulog-mode", required_argument, &curr_opt, opt_ulog_mode },
{"ulog-file", required_argument, &curr_opt, opt_ulog_file },
+ {"warmup", no_argument, &curr_opt, opt_warmup },
+ {"warmup-func", required_argument, &curr_opt, opt_warmup_func },
{ 0, 0, NULL, 0 }
};
-
+
+ string board_start_config = "";
+ string wrap_config = "";
while (true)
{
int c = getopt_long (argc, argv, "+hvne:f:",
case opt_board:
{
- need_sess (sess);
+ need_sess (sess, verbose_p);
if (curr_board)
- sess->add_board (curr_board);
+ {
+ sess->add_board (curr_board);
+ if (! defaults.warmup)
+ {
+ BoardConfig bc = { curr_board, defaults.start_config + board_start_config };
+ board_configs.push_back (bc);
+ }
+ board_start_config = "";
+ }
curr_board = NULL;
string new_board_type = optstring();
string new_board_name (new_board_type + "-" +
curr_board->set_ulog_level (defaults.ulog_level);
curr_board->set_ulog_mode (defaults.ulog_mode);
curr_board->set_ulog_file (defaults.ulog_file);
+ curr_board->set_warmup (defaults.warmup);
+ curr_board->add_warmup_func (defaults.warmup_func);
+ curr_board->add_profile_func (defaults.profile_func);
if (defaults.step_insn_count != "10000")
curr_board->set_step_insn_count(defaults.step_insn_count);
break;
verbose_p = true;
if (sess)
sess->verbose = true;
+ defaults.start_config += " --verbose";
break;
case opt_gprof:
option_requires_board (curr_board, "gprof");
try_add_gprof(optstring(), curr_board);
+ board_start_config += " --gprof=" + optstring();
break;
case opt_gdb:
break;
case opt_load:
- need_sess (sess);
+ need_sess (sess, verbose_p);
try_load_file (optstring(), curr_board, sess);
break;
case opt_trace_extract:
if (curr_board)
- curr_board->trace_extract();
+ {
+ board_start_config += " --trace-extract";
+ curr_board->trace_extract();
+ }
else
- defaults.trace_extract = true;
+ {
+ defaults.trace_extract = true;
+ defaults.start_config += " --trace-extract";
+ }
break;
case opt_trace_semantics:
if (curr_board)
- curr_board->trace_semantics();
+ {
+ board_start_config += " --trace-semantics";
+ curr_board->trace_semantics();
+ }
else
- defaults.trace_semantics = true;
+ {
+ defaults.trace_semantics = true;
+ defaults.start_config += " --trace-semantics";
+ }
break;
case opt_trace_disassemble:
if (curr_board)
- curr_board->trace_disassemble();
+ {
+ curr_board->trace_disassemble();
+ board_start_config += " --trace-disassemble";
+ }
else
- defaults.trace_disassemble = true;
+ {
+ defaults.trace_disassemble = true;
+ defaults.start_config += " --trace-disassemble";
+ }
break;
case opt_trace_counter:
if (curr_board)
- curr_board->trace_counter();
+ {
+ curr_board->trace_counter();
+ board_start_config += " --trace-counter";
+ }
else
- defaults.trace_counter = true;
+ {
+ defaults.trace_counter = true;
+ defaults.start_config += " --trace-counter";
+ }
break;
case opt_final_insn_count:
if (curr_board)
- curr_board->final_insn_count();
+ {
+ curr_board->final_insn_count();
+ board_start_config += " --final-insn-count";
+ }
else
- defaults.final_insn_count = true;
+ {
+ defaults.final_insn_count = true;
+ defaults.start_config += " --final-insn-count";
+ }
break;
case opt_trace_core:
if (curr_board)
- curr_board->trace_core();
+ {
+ curr_board->trace_core();
+ board_start_config += " --trace-core";
+ }
else
- defaults.trace_core = true;
+ {
+ defaults.trace_core = true;
+ defaults.start_config += " --trace-core";
+ }
break;
case opt_enable_warnings:
string c (optstring());
if (sess)
sess->use_tcl_bridge ();
- if (! AtomicCfg::wrap_component (c))
+ AtomicCfg *comp = AtomicCfg::wrap_component (c);
+ if (! comp)
{
cerr << "error: no component named '" << c << "' to wrap" << endl;
exit (9);
}
+ sess->add_wrapped_component (comp);
}
break;
case opt_insn_count:
if (curr_board)
- curr_board->set_step_insn_count(optstring());
+ {
+ curr_board->set_step_insn_count(optstring());
+ board_start_config += " --insn-count=" + optstring();
+ }
else
- defaults.step_insn_count = optstring();
+ {
+ defaults.step_insn_count = optstring();
+ defaults.start_config += " --insn-count=" + optstring();
+ }
break;
case opt_persistent:
break;
case opt_memory_region:
- need_sess (sess);
+ need_sess (sess, verbose_p);
try_add_memory (optstring(), curr_board, sess);
break;
case opt_ulog_level:
if (curr_board)
- curr_board->set_ulog_level (optaddr ("ulog-level"));
+ {
+ curr_board->set_ulog_level (optaddr ("ulog-level"));
+ board_start_config += " --ulog-level=" + optstring();
+ }
else
{
defaults.ulog_level = optaddr ("ulog-level");
- need_sess (sess);
+ defaults.start_config += " --ulog-level=" + optstring();
+ need_sess (sess, verbose_p);
sess->set_ulog_level (optaddr ("ulog-level"));
}
break;
case opt_ulog_mode:
if (curr_board)
- curr_board->set_ulog_mode (optstring ());
+ {
+ curr_board->set_ulog_mode (optstring ());
+ board_start_config += " --ulog-mode=" + optstring();
+ }
else
{
defaults.ulog_mode = optstring ();
- need_sess (sess);
+ defaults.start_config += " --ulog-mode=" + optstring();
+ need_sess (sess, verbose_p);
sess->set_ulog_mode (optstring ());
}
break;
case opt_ulog_file:
- need_sess (sess);
+ need_sess (sess, verbose_p);
sess->add_ulog_file (optstring ());
if (curr_board)
curr_board->set_ulog_file (optstring ());
sess->set_ulog_file (optstring ());
}
break;
+
+ case opt_warmup:
+ if (curr_board)
+ curr_board->set_warmup (true);
+ else
+ defaults.warmup = true;
+ break;
+
+ case opt_warmup_func:
+ if (curr_board)
+ curr_board->add_warmup_func (optstring ());
+ else
+ {
+ if (! defaults.warmup_func.empty ())
+ defaults.warmup_func += ",";
+ defaults.warmup_func += optstring ();
+ }
+ break;
+
+ case opt_profile_func:
+ if (curr_board)
+ curr_board->add_profile_func (optstring ());
+ else
+ {
+ if (! defaults.profile_func.empty ())
+ defaults.profile_func += "|";
+ defaults.profile_func += optstring ();
+ }
+ break;
+
+ case opt_profile_config:
+ need_sess (sess, verbose_p);
+ sess->profile_config (optstring ());
+ break;
}
break;
-
+
case '?':
default:
}
if (sess && curr_board)
- sess->add_board (curr_board);
+ {
+ sess->add_board (curr_board);
+ if (! defaults.warmup)
+ {
+ BoardConfig bc = { curr_board, defaults.start_config + board_start_config };
+ board_configs.push_back (bc);
+
+ string wrap_config = sess->wrap_config ();
+ for (vector<BoardConfig>::const_iterator it = board_configs.begin ();
+ it != board_configs.end ();
+ ++it)
+ it->board->set_start_config (it->config + wrap_config);
+ }
+ }
if (persistent_p)
config_items.push_back (make_pair (false, string("set main persistent? true")));