OSDN Git Service

2005-08-19 Dave Brolley <brolley@redhat.com>
authorbrolley <brolley>
Fri, 19 Aug 2005 19:47:43 +0000 (19:47 +0000)
committerbrolley <brolley>
Fri, 19 Aug 2005 19:47:43 +0000 (19:47 +0000)
        * Contribute the following changes:

        2005-07-13  Dave Brolley  <brolley@redhat.com>

        * sidcpuutil.h (num_cycles): New member of basic_cpu.
        (step_pin_handler): Call configure_gprof.
        (cg_profile): Call last_caller and last_callee.
        (cg_profile_jump): Call last_caller and last_callee.
        (configure_gprof): New method of basic_cpu.
        (unconfigure_gprof): New method of basic_cpu.
        (gprof_configured_p,configure_gprof_p,last_caller,last_callee)
        (pprof_spec): New members of basic_cpu.
        (configure): Call configure_gprof.
        (basic_cpu): Initialize gprof_configured_p, configure_gprof_p,
        last_caller and last_callee.
        * sidattrutil.h (configurable_component): Moved here ...
        * sidcomputil.h (configurable_component): ... from here.
        * sidbusutil.h (bus_arbitrator): Inherit from no_relation_component.

        2005-06-24  Dave Brolley  <brolley@redhat.com>

        * sidattrutil.h (fixed_attribute_map_with_logging_component):
        Initialize buffer_output to false.

        2005-06-21  Dave Brolley  <brolley@redhat.com>

        * sidcpuutil.h (basic_cpu::configure): Call update_final_insn_count_p
        after processing "final-insn-count".

        2005-06-06  Dave Brolley  <brolley@redhat.com>

        * sidcpuutil.h (print_final_insn_count_p): New member of basic_cpu.
        (print_insn_summary): Check print_final_insn_count_p.
        (update_final_insn_count_p): New method of basic_cpu.
        (core_probe,main); New members of basic_cpu.
        (basic_cpu::configure): Handle insn-count, verbose, trace-core,
        trace-counter, trace-extract, trace-semantics and final-insn-count.
        (stream_state): Stream print_final_insn_count_p.
        (destream_state): Destream print_final_insn_count_p.
        (basic_cpu): Initialize core_probe and main. Initialize
        print_final_insn_count_p. Add final-insn-count? using
        add_attribute_notify. Add relations core-probe and main.
        * sidcomputil.h (configurable_component::configure_pin_handler): Now
        virtual.

        2005-05-29  Dave Brolley  <brolley@redhat.com>

        * sidcpuutil.h (basic_cpu): New inherits from configurable_component.
        (cg_jump_pin,cg_return_pin): New members of basic_cpu.
        (cg_profile_jump): New method of basic_cpu.
        (configure): New virtual override on basic_cpu.
        (basic_cpu): Initialize gprof. Add cg-return and cg-jump pins. Add
        gprof relation.
        * sidcomputil.h (configurable_component): New mix-in class for component
s.
        * sidattrutil.h (sidcomputil.h): #include it.
        (fixed_attribute_map_with_logging_component): Inherit from
        configurable_component.
        (configure): New virtual override in
        fixed_attribute_map_with_logging_component.

sid/include/ChangeLog
sid/include/sidattrutil.h
sid/include/sidcpuutil.h

index 5c340ef..8a9ef0f 100644 (file)
@@ -1,3 +1,65 @@
+2005-08-19  Dave Brolley  <brolley@redhat.com>
+
+       * Contribute the following changes:
+
+       2005-07-13  Dave Brolley  <brolley@redhat.com>
+
+       * sidcpuutil.h (num_cycles): New member of basic_cpu.
+       (step_pin_handler): Call configure_gprof.
+       (cg_profile): Call last_caller and last_callee.
+       (cg_profile_jump): Call last_caller and last_callee.
+       (configure_gprof): New method of basic_cpu.
+       (unconfigure_gprof): New method of basic_cpu.
+       (gprof_configured_p,configure_gprof_p,last_caller,last_callee)
+       (pprof_spec): New members of basic_cpu.
+       (configure): Call configure_gprof.
+       (basic_cpu): Initialize gprof_configured_p, configure_gprof_p,
+       last_caller and last_callee.
+       * sidattrutil.h (configurable_component): Moved here ...
+       * sidcomputil.h (configurable_component): ... from here.
+       * sidbusutil.h (bus_arbitrator): Inherit from no_relation_component.
+
+       2005-06-24  Dave Brolley  <brolley@redhat.com>
+
+       * sidattrutil.h (fixed_attribute_map_with_logging_component): 
+       Initialize buffer_output to false.
+
+       2005-06-21  Dave Brolley  <brolley@redhat.com>
+
+       * sidcpuutil.h (basic_cpu::configure): Call update_final_insn_count_p
+       after processing "final-insn-count".
+
+       2005-06-06  Dave Brolley  <brolley@redhat.com>
+
+       * sidcpuutil.h (print_final_insn_count_p): New member of basic_cpu.
+       (print_insn_summary): Check print_final_insn_count_p.
+       (update_final_insn_count_p): New method of basic_cpu.
+       (core_probe,main); New members of basic_cpu.
+       (basic_cpu::configure): Handle insn-count, verbose, trace-core,
+       trace-counter, trace-extract, trace-semantics and final-insn-count.
+       (stream_state): Stream print_final_insn_count_p.
+       (destream_state): Destream print_final_insn_count_p.
+       (basic_cpu): Initialize core_probe and main. Initialize
+       print_final_insn_count_p. Add final-insn-count? using
+       add_attribute_notify. Add relations core-probe and main.
+       * sidcomputil.h (configurable_component::configure_pin_handler): Now
+       virtual.
+
+       2005-05-29  Dave Brolley  <brolley@redhat.com>
+
+       * sidcpuutil.h (basic_cpu): New inherits from configurable_component.
+       (cg_jump_pin,cg_return_pin): New members of basic_cpu.
+       (cg_profile_jump): New method of basic_cpu.
+       (configure): New virtual override on basic_cpu.
+       (basic_cpu): Initialize gprof. Add cg-return and cg-jump pins. Add
+       gprof relation.
+       * sidcomputil.h (configurable_component): New mix-in class for components.
+       * sidattrutil.h (sidcomputil.h): #include it.
+       (fixed_attribute_map_with_logging_component): Inherit from
+       configurable_component.
+       (configure): New virtual override in
+       fixed_attribute_map_with_logging_component.
+
 2005-08-02  Dave Brolley  <brolley@redhat.com>
 
        * sidbusutil.h (bus_arbitrator): Remove passthrough_pin.
index e0c418e..266f81e 100644 (file)
@@ -2,7 +2,7 @@
 // mappings between application objects and their string
 // representations.  -*- C++ -*-
 
-// Copyright (C) 1999, 2000, 2003 Red Hat.
+// Copyright (C) 1999, 2000, 2003, 2005 Red Hat.
 // This file is part of SID and is licensed under the GPL.
 // See the file COPYING.SID for conditions for redistribution.
 
@@ -10,6 +10,7 @@
 #define SIDATTRUTIL_H
 
 #include <sidconfig.h>
+#include <sidcomputil.h>
 #include <sidpinutil.h>
 #include "sidtypes.h"
 
@@ -1017,17 +1018,51 @@ make_attribute (const sid::any_int<IntType,IsBig>& value)
       }
   };
 
+  // A configurable_component maintains a relationship with a
+  // sid-control-dynamic-configurator component and reconfigures itself
+  // when its configure! attribute is set.
+  class configurable_component:
+    public virtual fixed_attribute_map_component
+  {
+  public:
+    configurable_component ()
+      {
+       add_attribute_virtual ("configure!", this,
+                              & configurable_component::dynamic_config,
+                              & configurable_component::nothing);
+      }
+    ~configurable_component() throw() {}
+
+    // Dynamic reconfiguration support
+  private:
+    std::string configurable_component::nothing() { return ""; }
+  protected:
+    virtual component::status
+    dynamic_config(const std::string& spec)
+      {
+       // Call the configure method to handle each configuration item.
+       std::vector<std::string> parts = sidutil::tokenize (spec, ":");
+       unsigned size = parts.size ();
+       for (unsigned i = 0; i < size; ++i)
+         configure (parts[i]);
+       return component::ok;
+      }
+
+    virtual void configure (const std::string &config) {}
+  };
+
   // A mix-in for classes with user logging.
   class fixed_attribute_map_with_logging_component
   : public virtual fixed_attribute_map_component,
-    public virtual fixed_pin_map_component
+    public virtual fixed_pin_map_component,
+    public virtual configurable_component
   {
   protected:
     fixed_attribute_map_with_logging_component () :
       ulog_level (0),
       ulog_mode ("less"),
       ulog_out_pin (),
-      buffer_output (true)
+      buffer_output (false)
       {
        add_attribute ("buffer-output", &buffer_output, "setting");
        add_attribute ("ulog-level", &ulog_level, "setting");
@@ -1038,7 +1073,6 @@ make_attribute (const sid::any_int<IntType,IsBig>& value)
     ~fixed_attribute_map_with_logging_component () throw()
       {
        // Output any saved messages.
-       // output_saved_messages ();
        ulog_logger->output_saved_messages ();
       }
 
@@ -1062,7 +1096,37 @@ make_attribute (const sid::any_int<IntType,IsBig>& value)
     sidutil::output_pin ulog_out_pin;
     bool buffer_output;
     sidutil::logger *ulog_logger;
+
+protected:
+    // Dynamic configuration support
+    virtual void configure (const string &config)
+      {
+       // Call up to the base class
+       configurable_component::configure (config);
+
+       // Handle items specific to this component
+       if (config.size () < 11)
+         return;
+       if (config.substr (0, 10) == "ulog-mode=")
+         {
+           ulog_mode = config.substr (10);
+           ulog_logger->set_attributes (buffer_output, ulog_level, ulog_mode);
+           return;
+         }
+       if (config.size () < 12)
+         return;
+       if (config.substr (0, 11) == "ulog-level=")
+         {
+           sid::host_int_4 level;
+           sid::component::status s = sidutil::parse_attribute (config.substr (11), level);
+           if (s == sid::component::ok)
+             ulog_level = level;
+           ulog_logger->set_attributes (buffer_output, ulog_level, ulog_mode);
+           return;
+         }
+      }
   };
+
 }
 
 #endif // SIDATTRUTIL_H
index bf4f456..3c7043d 100644 (file)
@@ -1,6 +1,6 @@
 // sidcpuutil.h - Elements common to CPU models.  -*- 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.
 
@@ -105,7 +105,8 @@ namespace sidutil
                   protected virtual fixed_accessor_map_component,
                   protected virtual fixed_attribute_map_component,
                   protected virtual fixed_relation_map_component,
-                  protected virtual fixed_bus_map_component
+                  protected virtual fixed_bus_map_component,
+                  protected virtual configurable_component
   {
     // custom memory allocators for poisioning freshly-allocated memory
   public:
@@ -206,9 +207,12 @@ namespace sidutil
     sid::host_int_8 total_insn_count;
     mutable sid::host_int_8 total_latency;
     sid::host_int_4 current_step_insn_count;
+    sid::host_int_4 num_cycles;
     output_pin step_cycles_pin;
     output_pin cg_caller_pin;
     output_pin cg_callee_pin;
+    output_pin cg_jump_pin;
+    output_pin cg_return_pin;
    
     // tracing
   private:
@@ -257,6 +261,7 @@ namespace sidutil
     bool trace_semantics_p;
     bool trace_counter_p;
     bool final_insn_count_p;
+    bool print_final_insn_count_p;
     bool enable_step_trap_p;
     cpu_trace_stream trace_stream;
 
@@ -265,6 +270,9 @@ namespace sidutil
        recursion_record limit (& this->step_limit);
        if (UNLIKELY(! limit.ok())) return;
 
+       if (UNLIKELY (! gprof_configured_p && configure_gprof_p))
+         configure_gprof ();
+
        this->current_step_insn_count = 0;
        this->yield_p = false;
 
@@ -283,10 +291,11 @@ namespace sidutil
        const sid::host_int_4 min_num_cycles = 1;
        const sid::host_int_4 max_num_cycles = 0x7FFFFFFF;
        sid::host_int_8 insn_cycles = num_insns + latency_to_cycles (latency);
-       sid::host_int_4 num_cycles =
+       num_cycles =
          insn_cycles <= min_num_cycles ? min_num_cycles :
          insn_cycles >= max_num_cycles ? max_num_cycles :
          insn_cycles;
+
        this->stepped (num_cycles);
       }
     void yield ()
@@ -300,8 +309,9 @@ namespace sidutil
       }
     virtual void print_insn_summary (sid::host_int_4)
       {
-       std::cerr << "instruction count: " << this->total_insn_count << "  "
-                 << "simulated cycles: " << this->total_latency + this->total_insn_count << std::endl;
+       if (print_final_insn_count_p)
+         std::cerr << "instruction count: " << this->total_insn_count << "  "
+                   << "simulated cycles: " << this->total_latency + this->total_insn_count << std::endl;
       }
     virtual void stepped (sid::host_int_4 n)
       {
@@ -309,6 +319,8 @@ namespace sidutil
       }
     void cg_profile (sid::host_int_4 caller, sid::host_int_4 callee)
     {
+      last_caller = caller;
+      last_callee = callee;
       // The drive sequence is important: see sw-profile-gprof
       this->cg_caller_pin.drive (caller);
       this->cg_callee_pin.drive (callee);
@@ -324,6 +336,12 @@ namespace sidutil
                             << "  ";
        }
     }
+    void cg_profile_jump (sid::host_int_4 caller, sid::host_int_4 callee)
+    {
+      last_caller = caller;
+      last_callee = callee;
+      this->cg_jump_pin.drive (callee);
+    }
 
   public:
     void set_total_latency (sid::host_int_8 latency) { this->total_latency = latency; }
@@ -381,6 +399,12 @@ namespace sidutil
       this->trace_result_p = (this->trace_semantics_p || this->trace_disass_p);
     }
 
+    void
+    update_final_insn_count_p ()
+    {
+      if (this->final_insn_count_p)
+       this->print_final_insn_count_p = true;
+    }
 
     // Reset the processor model to power-up state.
   private:
@@ -426,7 +450,166 @@ namespace sidutil
        return static_cast<cpu_trap_disposition>(trap_disposition_pin.sense ());
       }
 
-    
+    void unconfigure_gprof (sid::host_int_4 num_cycles)
+      {
+       assert (gprof);
+       // First sample the address of the branch which caused
+       // the reconfig for the given number of cycles.
+       sid::pin *p;
+       if (num_cycles && last_caller)
+         {
+           p = gprof->find_pin ("sample");
+           if (p)
+             {
+               std::string save_pc = this->attribute_value ("pc");
+               if (! save_pc.empty ())
+                 {
+                   sid::component::status s = this->set_attribute_value ("pc", make_numeric_attribute (last_caller));
+                   if (s == sid::component::ok)
+                     do
+                       {
+                         p->driven (1);
+                         --num_cycles;
+                       } while (num_cycles);
+                   this->set_attribute_value ("pc", save_pc);
+                 }
+             }
+         }
+
+       // Then get gprof to reconfigure itself.
+       gprof->set_attribute_value ("configure!", gprof_spec);
+
+       // Then disconnect the call graph notification pins.
+       assert (! configure_gprof_p);
+       assert (gprof_configured_p);
+       p = gprof->find_pin ("cg-caller");
+       if (p) cg_caller_pin.disconnect (p); 
+       p = gprof->find_pin ("cg-callee");
+       if (p) cg_callee_pin.disconnect (p); 
+       gprof_configured_p = false;
+      }
+
+    void configure_gprof ()
+      {
+       // First get gprof to reconfigure itself.
+       assert (gprof);
+       gprof->set_attribute_value ("configure!", gprof_spec);
+
+       // Then connect the call graph notification pins.
+       assert (configure_gprof_p);
+       assert (! gprof_configured_p);
+       sid::pin *p = gprof->find_pin ("cg-caller");
+       if (p)
+         {
+           cg_caller_pin.connect (p); 
+           if (last_caller && last_callee)
+             p->driven (last_caller);
+         }
+       p = gprof->find_pin ("cg-callee");
+       if (p) {
+         cg_callee_pin.connect (p); 
+         if (last_caller && last_callee)
+           p->driven (last_callee); 
+       }
+       gprof_configured_p = true;
+      }
+
+    // ------------------------------------------------------------------------
+    // dynamic configuration
+  protected:
+    component *gprof;
+    component *core_probe;
+    component *main;
+    bool gprof_configured_p;
+    bool configure_gprof_p;
+    sid::host_int_4 last_caller;
+    sid::host_int_4 last_callee;
+    string gprof_spec;
+
+    virtual void configure (const string &config)
+      {
+       // Call up to the base class
+       configurable_component::configure (config);
+
+       // Handle configuration specific to this component
+       if (config.size () < 6)
+         return;
+       if (config.substr (0, 6) == "gprof=")
+         {
+           if (! gprof)
+             return; // nothing to configure
+           gprof_spec = config;
+           // Set a flag to configure the gprof component the next time
+           // our step! pin is driven....
+           configure_gprof_p = (config.size () > 6);
+           // ... unless we are unconfiguring the gprof, in which
+           // case do it now.
+           if (gprof_configured_p && ! configure_gprof_p)
+             unconfigure_gprof (num_cycles);
+           return;
+         }
+       if (config.size () <= 11)
+         return;
+       if (config.substr (0, 11) == "insn-count=")
+         {
+           sid::host_int_4 n;
+           sid::component::status s = parse_attribute (config.substr (11), n);
+           if (s == sid::component::ok)
+             step_insn_count = n;
+           return;
+         }
+       if (config.substr (0, 8) == "verbose=")
+         {
+           if (main)
+             main->set_attribute_value ("verbose?", config.substr (8));
+           return;
+         }
+       if (config.size () < 15)
+         return;
+       if (config.substr (0, 11) == "trace-core=")
+         {
+           if (core_probe)
+             core_probe->set_attribute_value ("trace?", config.substr (11));
+           return;
+         }
+       if (config.size () < 18)
+         return;
+       if (config.substr (0, 14) == "trace-counter=")
+         {
+           trace_counter_p = (config.substr (14) == "true");
+           return;
+         }
+       if (config.substr (0, 14) == "trace-extract=")
+         {
+           trace_extract_p = (config.substr (14) == "true");
+           return;
+         }
+       if (config.size () < 20)
+         return;
+       if (config.substr (0, 16) == "trace-semantics=")
+         {
+           trace_semantics_p = (config.substr (16) == "true");
+           update_trace_result_p ();
+           return;
+         }
+       if (config.size () < 21)
+         return;
+       if (config.substr (0, 17) == "final-insn-count=")
+         {
+           final_insn_count_p = (config.substr (17) == "true");
+           update_final_insn_count_p ();
+           return;
+         }
+       if (config.size () < 22)
+         return;
+       if (config.substr (0, 18) == "trace-disassemble=")
+         {
+           trace_disass_p = (config.substr (18) == "true");
+           update_trace_result_p ();
+           return;
+         }
+      }
+
     // state save/restore: Override these in derived classes, but
     // include a call up to this base implementation.
   protected:
@@ -444,6 +627,7 @@ namespace sidutil
          << " " << this->trace_semantics_p
          << " " << this->trace_counter_p
          << " " << this->final_insn_count_p
+         << " " << this->print_final_insn_count_p
          // pins
          << " " << this->step_cycles_pin
          << " " << this->trap_type_pin
@@ -469,6 +653,7 @@ namespace sidutil
          >> this->trace_semantics_p
          >> this->trace_counter_p
          >> this->final_insn_count_p
+         >> this->print_final_insn_count_p
          // pins
          >> this->step_cycles_pin
          >> this->trap_type_pin
@@ -567,7 +752,14 @@ public:
       debugger_bus (& this->data_bus),
       trace_stream (),
       trace_filename ("-"), // standard output
-      trace_pin (this, & basic_cpu::trace_pin_handler)
+      trace_pin (this, & basic_cpu::trace_pin_handler),
+      gprof (0),
+      gprof_configured_p (false),
+      configure_gprof_p (false),
+      last_caller (0),
+      last_callee (0),
+      core_probe (0),
+      main (0)
       {
        // buses
        this->data_bus = 0;
@@ -587,6 +779,8 @@ public:
        add_pin ("start-pc-set!", & this->pc_set_pin);
        add_pin ("cg-caller", & this->cg_caller_pin);
        add_pin ("cg-callee", & this->cg_callee_pin);
+       add_pin ("cg-return", & this->cg_return_pin);
+       add_pin ("cg-jump", & this->cg_jump_pin);
        add_pin ("print-insn-summary!", & this->print_insn_summary_pin);
        add_pin ("endian-set!", & this->endian_set_pin);
        add_pin ("eflags-set!", & this->eflags_set_pin);
@@ -625,7 +819,15 @@ public:
        this->trace_counter_p = false;
        add_attribute ("trace-counter?", & this->trace_counter_p, "setting");
        this->final_insn_count_p = false;
-       add_attribute ("final-insn-count?", & this->final_insn_count_p, "setting");
+       this->print_final_insn_count_p = false;
+       add_attribute_notify ("final-insn-count?", & this->final_insn_count_p, this,
+                             & basic_cpu::update_final_insn_count_p,
+                             "setting");
+
+       // For dynamic configuration
+       add_uni_relation("gprof", &this->gprof);
+       add_uni_relation("core-probe", &this->core_probe);
+       add_uni_relation("main", &this->main);
       }
 
     virtual ~basic_cpu() throw() {}