OSDN Git Service

2005-08-19 Dave Brolley <brolley@redhat.com>
authorbrolley <brolley>
Fri, 19 Aug 2005 19:48:45 +0000 (19:48 +0000)
committerbrolley <brolley>
Fri, 19 Aug 2005 19:48:45 +0000 (19:48 +0000)
        (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.

sid/main/dynamic/ChangeLog
sid/main/dynamic/baseCfg.cxx
sid/main/dynamic/baseCfg.h
sid/main/dynamic/commonCfg.cxx
sid/main/dynamic/commonCfg.h
sid/main/dynamic/mainDynamic.cxx

index 177aebb..04b5c7e 100644 (file)
@@ -1,3 +1,132 @@
+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
index 4151908..65695f6 100644 (file)
@@ -229,7 +229,8 @@ map<string, AtomicCfg *> AtomicCfg_impl::atomic_names;
 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)
@@ -245,13 +246,27 @@ void AtomicCfg::add_prefix (const string prefix)
 
 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 () 
@@ -276,11 +291,14 @@ void AtomicCfg::write_construct (Writer &w)
 {
   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);
@@ -375,6 +393,33 @@ const ResolvedName AggregateCfg::resolve(const role r, const string 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,
index 57b4d4e..58910cc 100644 (file)
@@ -99,10 +99,14 @@ virtual public ComponentCfg
   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;
@@ -120,6 +124,7 @@ virtual public ComponentCfg
   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;
 };
index 4089805..44c81a7 100644 (file)
@@ -573,6 +573,8 @@ SessionCfg::SessionCfg (const string name)
     loader (NULL),
     verbose (false),
     use_stdio (true),
+    need_gprof (false),
+    need_core_probe (false),
     board_count (0),
     gdb_count (0)
 {
@@ -615,6 +617,12 @@ SessionCfg::add_ulog_file (const string name)
   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)
@@ -701,6 +709,178 @@ void SessionCfg::use_tcl_bridge ()
   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);
@@ -733,7 +913,6 @@ LoaderCfg::LoaderCfg (const string name,
 {
   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!");
 }
@@ -778,7 +957,6 @@ GlossCfg::GlossCfg (const string name,
   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");
 }
@@ -796,12 +974,10 @@ GlossCfg::GlossCfg (const string name,
   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, 
@@ -817,10 +993,13 @@ 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);
     }
@@ -837,6 +1016,30 @@ GprofCfg::GprofCfg (const string name,
   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));
 }
 
 
@@ -914,6 +1117,19 @@ void GdbCfg::write_config (Writer &w)
       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);
+       }
+    }
 }
 
 
@@ -938,7 +1154,11 @@ BoardCfg::BoardCfg (const string name,
   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);
@@ -958,6 +1178,9 @@ BoardCfg::BoardCfg (const string name,
       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);
@@ -997,9 +1220,49 @@ void BoardCfg::set_loader (LoaderCfg *l)
   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)
@@ -1024,6 +1287,68 @@ void BoardCfg::write_config (Writer &w)
          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
     {
@@ -1113,7 +1438,6 @@ void BoardCfg::final_insn_count ()
 {
   assert (cpu);
   assert (sess->shutdown_seq);
-  sess->shutdown_seq->add_output (0, cpu, "print-insn-summary!");
   cpu->set (cpu, "final-insn-count?", "true");
 }
 
@@ -1208,3 +1532,33 @@ void BoardCfg::trace_core ()
   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
+    }
+}
index a95bcf4..b2114db 100644 (file)
@@ -235,11 +235,26 @@ struct SessionCfg :
   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;
@@ -303,6 +318,9 @@ public:
            SessionCfg *sess,
            gprof_type type,
             int interval);
+  GprofCfg (const string name, 
+           CpuCfg *cpu, 
+           SessionCfg *sess);
   virtual ~GprofCfg ();
 };
 
@@ -356,6 +374,11 @@ public:
   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 ();
@@ -365,6 +388,7 @@ public:
   CpuCfg *cpu;
   SessionCfg *sess;
   MapperCfg *main_mapper;
+  AtomicCfg *dynamic_configurator;
 
  protected:
   GdbCfg *gdb;
@@ -374,6 +398,10 @@ public:
   AtomicCfg *icache;
   AtomicCfg *dcache;  
   LoaderCfg *loader;
+
+  string start_config;
+  string warmup_funcs;
+  string profile_funcs;
 };
 
 #endif // __commonCfg_h__
index bd1fc95..31b896b 100644 (file)
@@ -1,6 +1,6 @@
 // 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.
 
@@ -14,6 +14,8 @@
 #include <getopt.h>
 
 
+#include <string>
+
 // Stub functions to set breakpoints on
 static void sid_pre_configure () {}
 static void sid_post_configure () {}
@@ -68,6 +70,8 @@ usage ()
   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;
@@ -120,10 +124,15 @@ usage ()
        << "                         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;
@@ -416,8 +425,12 @@ void try_add_gprof(const string optstring, BoardCfg *board)
   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;
@@ -468,6 +481,10 @@ struct Defs {
            ulog_level (0),
            ulog_mode ("less"),
            ulog_file ("-"),
+           warmup (false),
+           profile_func (""),
+           warmup_func (""),
+           start_config (""),
            step_insn_count ("10000")
   {}
   string cpu;
@@ -481,17 +498,29 @@ struct Defs {
   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[])
@@ -504,6 +533,7 @@ 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)
@@ -518,13 +548,16 @@ main(int argc, char* argv[])
 
   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;
 
@@ -543,6 +576,7 @@ main(int argc, char* argv[])
     {"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 },
 
@@ -561,6 +595,7 @@ main(int argc, char* argv[])
     {"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 },
@@ -572,9 +607,13 @@ main(int argc, char* argv[])
     {"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:",
@@ -615,9 +654,17 @@ main(int argc, char* argv[])
 
            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 + "-" + 
@@ -648,6 +695,9 @@ main(int argc, char* argv[])
                        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;
@@ -676,11 +726,13 @@ main(int argc, char* argv[])
              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:
@@ -695,7 +747,7 @@ main(int argc, char* argv[])
              break;
 
            case opt_load:
-             need_sess (sess);
+             need_sess (sess, verbose_p);
              try_load_file (optstring(), curr_board, sess);
              break;
              
@@ -708,44 +760,80 @@ main(int argc, char* argv[])
              
            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:
@@ -760,20 +848,28 @@ main(int argc, char* argv[])
                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:
@@ -805,7 +901,7 @@ main(int argc, char* argv[])
              break;
 
            case opt_memory_region:
-             need_sess (sess);
+             need_sess (sess, verbose_p);
              try_add_memory (optstring(), curr_board, sess);
              break;
 
@@ -835,28 +931,36 @@ main(int argc, char* argv[])
 
            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 ());
@@ -866,9 +970,43 @@ main(int argc, char* argv[])
                  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:
@@ -878,7 +1016,20 @@ main(int argc, char* argv[])
     }
 
   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")));