[patch][rfa] Dynamic Configuration of SID

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[patch][rfa] Dynamic Configuration of SID

Dave Brolley-2
Hi,

A customer of our showed some interest in dynamic configuration of SID
simulations from the point of view of "warming up" the simulator in
various situations. This generally means limiting high overhead
functionality (tracing, performance analysis, etc.) to areas of the
target application which are of greatest interest.

Attached are overviews of external and internal specs of how this could
be applied to SID along with a patch which implements the spec.

Comments are appreciated and, as always, I'm looking for approval to
commit this work.

Thanks,
Dave

Applying Simulator "Warmup" Techniques in SID
External Specification
==============================================
Simulating program execution using SID can be a useful way to collect
information about the behaviour and performance of an application. For most
existing ports, SID provides cycle counting, an interface for collecting data
for analysis using gprof as well as a variety of options for generating trace
output.

While simulation using these features is useful, it also requires the
simulator to perform extra overhead which can significantly slow down the
simulation. In addition, it is probable that only a portion of the application
being simulated is of interest for analysis. For example, when executing
applications written in C, the C runtime startup code is probably not of
interest.

It would be useful to enable detailed modelling for only the portions of the
application which are of interest. Thus the extra overhead of detailed
modelling would only be applied for a smaller portion of the simulation. The
remaining portion of the simulation would be run without this overhead, so
the simulation as a whole would finish more quickly.

In SID, the following options result in extra overhead for the simulator:

--trace-extract
--trace-semantics
--trace-disassemble
--trace-core
--ulog-level
--ulog-mode
--wrap
--verbose
--trace-counter
--final-insn-count
--gprof
--insn-count=N where N is a small integer

All of these options could be enabled/disabled on demand during the simulation
to provide information only about the parts of the application which are of
interest.

Proposed Interfaces For Controlled Modelling in SID
===================================================
In order for this technique to be useful for analyzing real applications and
algorithms, precise control is necessary. We propose a combination of a SID
command line options and a syscall instruction.

SID Command Line Options
------------------------
We propose the addition of new SID command line options:

--warmup

This option starts SID in "warmup" mode regardless of the specification of the
other options listed above. warmup mode means that all these options are set
to the values which provide maximum simulation speed.

As with most other SID options, if specified before the first --board, then
--warmup applies to all --boards, otherwise, it applies only to the previous
--board.

--profile-config=<profile-name>:<options>
  where <profile-name> is the name being assigned to this group of options
        <options> is one or more options from the list above

This option associates the given set of options with the given profile name.
This profile name may be referenced on a --profile-func option (see below) in
order to activate that set of options for a given function or functions. This
profile name may also be specified using a syscall instruction (see below)
to activate a set of options within a function.

This option may be specified more than once in order to define several
configuration profiles. The position of the option on the command line is
irrelevent. The named profile is available for use by any --board.

--profile-func=<functions>:<profile-name>
  where <functions> is a comma-separated list of function names
        <profile-name> is the name of a profile configuration specified
        on a --profile-config option.
        (see above)

This option automatically reconfigures SID with the specified options whenever
one of the listed functions is entered and restores the previous configuration
when the function exits. This can be used for gathering information about
the execution of specific functions within an application.

--profile-func may be specified more than once to provide different
configurations for different functions. As with most other SID options, if
specified before the first --board, then it applies to all --boards,
otherwise, it applies only to the previous --board.

***NOTE: This option will only work for ports in which the cpu component drives
cg-caller, cg-callee, cg-jump and cg-return pins on calls and branches.
Currently, no port does this.

--warmup-func=<functions>
  where <functions> is a comma-separated list of function names

  This option automatically returns SID to warmup mode whenever one of the
  listed functions is entered and restores the previous configuration when
  the function exits.

--warmup-func may be specified more than once. As with most other SID options,
if specified before the first --board, then it applies to all --boards,
otherwise, it applies only to the previous --board.

***NOTE: This option will only work for ports in which the cpu component drives
cg-caller, cg-callee, cg-jump and cg-return pins on calls and branches.
Currently, no port does this.

Syscall Instruction
-------------------
For finer control at the instruction level, we propose a system call.

A system call number which is curently not
in use would be selected. We propose the use of syscall number 0 since it is
likely that it can be specified on the system call instruction of all existing
ports.

The API for this system call would be:

On Entry:
  Argument 1: Configuration mode
      0 -- warmup: The above options are automatically set to the
           values which result in maximum simulation speed for the cpu
           making the call.
      1 -- set: Used to set specific configuration options.
           Argument 2 is a pointer to a nul terminated string containing the
           name of a profile configuration specified by --profile-config.
           The syscall dynamically reconfigures SID
           to reflect the options specified by the given profile configuration
           for the cpu which executes the syscall.
      2 -- reset: Used to restore a previous configuration setting.
           Argument 2 is a configuration handle returned from a previous call
           to this syscall insn by the cpu making the call. The configuration
           is restored to the state represented by that handle.
On Exit:
  Return Value: The configuration handle of the previous configuration. This
      value may be used in a subsequent call to restore a previous
      configuration for the cpu making the call. If there is an error, the
      handle of the current configuration will be returned.

  Error code:
      0 of no error
      If mode was 1 (set) a non zero value indicates that the profile
        configuration name was not valid.
      If mode was 2 (reset) a non zero value indicates that the configuration
        handle was not valid.

This system call may be made in a function specified on a --profile-func option
(see above). If so, the configuration which existed prior to calling the
function will automatically be restored when the function exits.

System call access from C/C++
-----------------------------
The libgloss implementation for a given port may provide access to the system
call from C/C++ by implementing the following function:

  #define _SID_CONFIG_WARMUP 0
  #define _SID_CONFIG_SET 1
  #define _SID_CONFIG_RESET 2
  unsigned _Sid_config (unsigned mode, ...);

The arguments to _Sid_config correspond directly to the interface of the
system call instruction above:

  If 'mode' is _SID_CONFIG_WARMUP, then no further arguments are expected.

  If 'mode' is _SID_CONFIG_SET, then a second  argument of type
  'const char *' is expected to contain the name of a configuration profile
  specified on --profile-config and a third argument of type 'unsigned *' is
  expected for returning the error code.

  If mode is _SID_CONFIG_RESET, a second argument of type 'unsigned'
  is expected to contain the configuration handle and a third argument of type
  'unsigned *' is expected for returning the error code.

  The return value will be a handle for the previous configuration. If there
  are errors, then the handle of the current configuration will be returned.

If provided, the implementation of _Sid_config should simply make the
appropriate system call for the target.

Examples:
=========
NOTES:
------
o The examples below are for the xstormy16. Other ports will use different
  --board and --cpu flags and may use a different system call interface.

o The examples using --profile-func and --warmup-func depend upon the cpu
component of the port driving the cg-caller, cg-callee, cg-jump and cg-return
pins on calls and branches. Currently, no port does this.

o The examples using _Sid_config depend on the existence of the function
  Sid_config in the libgloss implementation for the port. Currently no ports
  implement this function. Similar examples could be constructed using 'asm'
  statements to make the system calls directly.

Example 1: Profile the entire simulation
----------------------------------------
  sid --gprof=gprof.out,cycles=1 --trace-disassemble --trace-counter \
      --board=basic --cpu=xstormy16 --memory-region=0x0,0x100000 --load=a.out

This example behaves as SID does today. It collects gprof data and dumps a
trace of the disassembly and cycle count for the entire simulation.

Example 2: Trace and Profile part of one function as specified on the command line
----------------------------------------------------------------------------------
  sid --warmup \
      --profile-config=myprofile:"--gprof=gprof.out,cycles=1 --trace-disassemble --trace-counter" \
      --board=basic --cpu=xstormy16 --memory-region=0x0,0x100000 --load=a.out

If function f in a.out looks as follows:

        .data
pname: .ascii "myprofile"
        .text
        .p2align 1
        .globl f
        .type f, @function
f:
        # enable profiling as specified by myprofile
        mov r1,#1
        mov.w r2,#pname
        .byte 0x01
        .byte 0x00

        ....
        # code to be tested goes here
        ....

        # Restore the simulation to warmup mode
        mov     r1,#0
        .byte 0x01
        .byte 0x00
       
        #return 0
        mov r2, #0
        ret
   
This example will collect gprof data and dump a trace of the disassembly
and cycle count during the execution of the function f and then restore the
simulator to the previous state (warmup mode) before returning.

Example 2a: Trace and Profile part of one function as specified on the command line
-----------------------------------------------------------------------------------
This example is the same as example 2, except that it uses the 'reset' mode of the syscall
to restore the previous configuration after profiling.

  sid --warmup \
      --profile-config=myprofile:"--gprof=gprof.out,cycles=1 --trace-disassemble --trace-counter" \
      --board=basic --cpu=xstormy16 --memory-region=0x0,0x100000 --load=a.out

If function f in a.out looks as follows:

        .data
pname: .ascii "myprofile"
        .text
        .p2align 1
        .globl f
        .type f, @function
f:
        # enable profiling as specified by myprofile
        mov r1,#1
        mov.w r2,#pname
        .byte 0x01
        .byte 0x00
        # handle for previous configuration is in r2

        ....
        # code to be tested goes here
        # must preserve r2
        ....

        # Restore the simulation to the previous mode
        # r2 contains the handle of the previous configuration
        mov     r1,#2
        .byte 0x01
        .byte 0x00
       
        #return 0
        mov r2, #0
        ret
   
Example 3: Collect gprof=<file>,cycles=1 data for one function and then
restore the previous configuration
-----------------------------------------------------------------------
  sid --warmup \
      --board=basic --cpu=xstormy16 --memory-region=0x0,0x100000 \
      --profile-func=test_function,myprofile \
      --profile-config=myprofile:"--gprof=gprof.out,cycles=1 --final-insn-count" \
      --load=a.out

  test.c:
  -------
        main ()
        {
          non_profiled_function ();
          test_function ();
          another_non_profiled_function ();
        }
   
This example will collect gprof data during the execution of test_function and
then restore the simulator to warmup mode before returning. Note that no
source code changes are necessary in this example.

Example 4: Cache Priming
------------------------
It may be useful in some situations to run a function once without profiling
in order to prime the instruction cache and/or data cache before turning on
profiling:

  sid --warmup \
      --profile-config=myprofile:"--gprof=gprof.out,cycles=1 --final-insn-count" \
      --board=basic --cpu=xstormy16 --memory-region=0x0,0x100000 --load=a.out

  test.c:
  -------
        main ()
        {
          unsigned ix;
          const char *set_error;
          unsigned reset_error;

          /* warm up the test function */
          test_function ();

          /* Reconfigure for profiling */
          ix = _Sid_config (_SID_CONFIG_SET, "myprofile", & set_error);
          test_function ();

          /* Restore the previous configuration */
          _Sid_config (_SID_CONFIG_RESET, ix, & reset_error);
        }

Example 5: Excluding a function from profiling
----------------------------------------------
It may be useful to exclude one or more functions from profiling.
For example, one might like to exclude functions which set up the
state of the application being profiled. The example below profiles
'main' and all functions which it calls except for 'setup_function':

  sid --warmup \
      --profile-config=myprofile:"--gprof=gprof.out,cycles=1 --final-insn-count" \
      --profile-func=main:myprofile \
      --warmup-func=setup_function \
      --board=basic --cpu=xstormy16 --memory-region=0x0,0x100000 --load=a.out

  test.c:
  -------
        main ()
        {
          int i;
          for (i = 0; i < 100; ++i)
          {
            setup_function (i);
            test_function ();
          }
        }

Applying Simulator "Warmup" Techniques in SID
Internal Specification
=============================================
The behavior described in the document sid-warmup-external-spec.txt can be
realized in SID by implementing the following:

cfgroot_component
-----------------
o Add a mapping from configuration name to configuration spec.

o Add an attribute "dynamic-config". When set with a value of the form

    <name>:<spec>

  it adds the name/spec pair to the mapping. This corresponds to the
  command line option --profile-config.

o Add an attribute "lookup-dynamic-config". When set, assume the value is the
  name of a config in the mapping and look it up. If found make the spec
  available via the "found-dynamic-config" attribute.

dynamic_config component (new)
------------------------------
o One of these is allocated for each --board. It manages the configuration of
  that --board including:
  - configuration on demand via the configuration syscall
  - configuration on function entry/exit

o This component maintains a table of configurations which have been used by
  its --board. The index of each configuration in the table is its handle.

o This component maintains a mapping of function names to config spec names.
  This mapping is established by setting the profile-functions! attribute with
  strings of the form

    <function-name>[,<function-name]*:<config-name>

  The attribute may be set more than once and will accumulate pairs in the
  mapping. This corresponds to the command line option --profile-func.

o This component maintains a list of functions which should be run in
  warmup mode. This list is established by setting the warmup-functions!
  attribute with strings of the form

    <function-name>[,<function-name]*

  The attribute may be set more than once and will accumulate pairs in the
  mapping. This corresponds to the command line option --warmup-func.

o This component maintains a function call stack containing the handle of the
  configuration to be used for each function. The correct maintenance of this
  stack depends upon the port driving the cg-caller, cg-callee, cg-jump and
  cg-return pins on function calls, branches and returns. Without this,
  the stack will not be maintained and the --profile-func and --warmup-func
  options will have no effect.

o The configuration is changed by either:
  - setting the configure! attribute with the name of a configuration spec
    known to the cfgroot component.
  - driving the configure! pin with the handle of a configuration in the table.
  - Entering or returning to a function on the function call stack.

o This component maintains a list of configurable client components. When the
  step! pin is driven and the configuration has changed, the dynamic
  configurator sets the "configure!" attribute of each client with the spec of
  the new configuration. Each client is responsible for interpreting the spec
  and reconfiguring itself accordingly.

Individual Components
---------------------
Each component which may be reconfigured inherits from the
configurable_component mix-in base class. This provides each component with
the "configure!" attribute and a virtual method

    void configure (const string &spec);

The spec will be one of

        trace-extract=true|false
        trace-semantics=true|false
        trace-disassemble=true|false
        trace-core=true|false
        trace-counter=true|false
        ulog-level=N
        ulog-mode=greater|less|equal
        wrap=<component-name>[,<component-name>]*
        verbose=true|false
        final-insn-count=true|false
        gprof=<filename>[,N]
        insn-count=N

The implementation of 'configure' for each component should:

1) Call <base_class>::configure (spec)
2) Handle the given spec, if relevent for that component and ignore it
   otherwise.

Implementation Notes
--------------------
The current implementation provides support for the SID command line options
listed above. Below are some notes regarding the implementation

o No cpu currently drives the cg-caller, cg-callee, cg-jump and cg-return pins
  on function calls, branches and returns. This functionaility has been tested
  using an internal Red Hat port.

o In order to support detection of calls and returns to individual functions,
  the elf loader component now reads the symbol table of the executable and
  supports an interface for determining which function a given address is in.

  When the loader's "function?" pin is driven, the address is checked and the
  name of the function containing that address is made available via the
  loader's "current-function" attribute.

o Since the output filename for the --gprof option may be changed dynamically,
  the gprof component has been enhanced to maintain an array of statistics, one
  entry for each output file. Using dynamic configuration, statistics for
  different parts of the application may now be output to separate files.

o In order to solve timing issues, part of the gprof dynamic configuration
  is achieved by connecting/disconnecting pin connections between the cpu
  component and the gprof component. For this reason, the gprof component is
  not registered as a client of the dynamic configurator component. The
  gprof component's dynamic configuration is triggered from the cpu
  component's 'configure' method. The cpu component sets the gprof component's
  "configure!" attribute.

sid/main/dynamic/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * 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  <[hidden email]>

        * 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  <[hidden email]>

        * mainDynamic.cxx (try_add_gprof): Make sure an argument is specified
        after the comma.

        2005-06-06  Dave Brolley  <[hidden email]>

        * 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  <[hidden email]>

        * 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.

sid/include/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * 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  <[hidden email]>

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

        2005-06-21  Dave Brolley  <[hidden email]>

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

        2005-06-06  Dave Brolley  <[hidden email]>

        * 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  <[hidden email]>

        * 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.

sid/component/tcl/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * compTcl.cxx (set_attribute_value): Handle the configure! attribute.
        (find_pin): Don't handle the configure! pin.
        (relate): Don't handle the dynamic-configurator relation.
        (unrelate): Likewise.
        (configure_pin_handler): Removed.

        2005-06-06  Dave Brolley  <[hidden email]>

        * sid-api-trace.tcl (attribute_value): Handle component-type and victim
        attributes.
        * compTcl.cxx (tcl_component): component and configurable_component
        inherited virtually.
        (victim_name): New member of tcl_component.
        (set_attrinute_value): Handle victim-name attribute.
        (find_pin): Handle the "configure" pin specially.
        (relate): Handle the dynamic-configurator relation specially.
        (unrelate): Likewise.
        (configure_pin_handler,configure): New virtual overrides in
        tcl_component.

sid/component/profiling/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * gprof.cxx (gprof_component): Inherit virtually from
        fixed_attribute_map_component.

        2005-05-29  Dave Brolley  <[hidden email]>

        * gprof.cxx: Keep a vector of statistics to allow switching from
        one output file to another dynamically.
        (sid::pin,sidutil::configurable_component)
        (sidutil::output_pin,sidutil::tokenize): Add using clauses.
        (profiling_components): Inherit virtually from fixed_pin_map_component
        and fixed_relation_map_component. Inherit from configurable_component.
        (statistics): New struct type.
        (stats,current_stats): New members of gprof_component.
        (set_nothing,value_min_get,value_max_get,value_count_get,limit_min_get)
        (limit_min_set,limit_max_get,limit_max_set,output_file_get)
        (output_file_set): New methods of gprof_component.
        (reset): Initialize stats vector.
        (store): Call store stats for each element of the stats vector.
        (configure): New virtual override in gprof_component.
        (gprof_component): Call reset. Add sim-sched-event attribute. Add
        sim-sched relation.

sid/component/loader/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * compLoader.cxx (generic_loader): Inherit virtually from
        fixed_attribute_map_component. Inherit from no_relation_component.

        2005-06-06  Dave Brolley  <[hidden email]>

        * elfload.c (readElfFile): Return and empty symbol table if none found.

        * compLoader.cxx: Add using cleause for
        sidutil::configurable_component.
        (generic_loader): fixed_pin_map_component and configurable_component
        inherited virtually.
        (configure): New virtual override in generic_loader.
        (check_function_pin_handler): Return the empty string if no function
        is associated with the given address.
        * sw-load-elf.xml: Add description of new interfaces.
        * sw-load-elf.txt: Regenerated.

        2005-05-29  Dave Brolley  <[hidden email]>

        * elfload.h (StringTable, Symbol): New struct types.
        (readElfFile): New takes symbol_table argument.
        (SHT_SYMTAB, SHT_STRTAB, ELF32_ST_TYPE, STT_FUNC): New macros.
        * elfload.c (stringTables,stringTableCount,stringTableNum): New
        static variables.
        (newStringTable): New static function.
        (symbolTable,symbolCount,symbolNum): New static variables.
        (newSymbol): New static function.
        (readElfFile): New takes symbol_table argument. Build string tables and
        symbol table while reading the input file.
        * compLoader.cxx (elf_loader): New constructor.
        (load_it): Obtain symmol_table from readElfFile.
        (check_function_pin,symbol_table,current_function): New members
        of elf_loader.
        (check_function_pin_handler): New method of elf_loader.

sid/component/gloss/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * gloss.cxx (gloss32): Initialize dynamic_configurator. Add
        dynamic-configurator relation.
        * gloss.h (gloss32): Inherit virtually from
        fixed_attribute_map_component.
        (dynamic_configurator): New member of gloss32.

        2005-07-05  Dave Brolley  <[hidden email]>

        * gloss.cxx (start_config): Removed from gloss32.
        (gloss32): Remove "start-config" attribute. Add "config-error"
        pin.
        (reset): Don't call sys_config_set.
        (sys_reconfig_set): Call set_error_result based on the value driven on
        config_error_pin.
        (sys_reconfig_reset): Likewise.
        * gloss.h (start_config): Removed from gloss32.
        (config_error_pin): New member of gloss32.

        2005-06-06  Dave Brolley  <[hidden email]>

        * gloss.cxx (gloss32): Don't initialize dynamic_configurator.
        Don't add dynamic-configurator relation.
        (configure_pin): Renamed to sys_configure_pin.
        (configure): New virtual override in gloss32.
        (do_sys_reconfig): Print log messages to cerr and only when
        verbose_p.
        * gloss.h (gloss32): fixed_pin_map_component and configurable_component
        inherited virtually.
        (dynamic_configurator): Removed.
        (configure_pin): Renamed to sys_configure_pin.
        (configure): New virtual override in gloss32.

        2005-05-29  Dave Brolley  <[hidden email]>

        * libgloss.h (SYS_reconfig): New enumerator.
        * gloss.h (main, dynamic_configurator): New members of gloss32.
        (configure_pin, config_result_pin, start_config): Likewise.
        (sys_reconfig_set): New method of gloss32.
        (sys_reconfig_reset, do_sys_reconfig): Likewise.
        * gloss.cxx (gloss32): Initialize main, dynamic_configurator and
        start_config. Add relations main, dynamic-configurator. Add
        configure pin. Add start-config addtribute. Add config-result
        pin.
        (reset): Call sys_reconfig_set with start_config if it's not
        empty.
        (syscall_trap): Handle SYS_reconfig.
        (sys_reconfig_set): New method of gloss32.
        (sys_reconfig_reset, do_sys_reconfig): Likewise.

sid/component/gdb/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * gdb.h (configurable_component): Inherit virtually from
        fixed_attribute_map_component.

        2005-06-06  Dave Brolley  <[hidden email]>

        * gdb.cxx (configure): New virtual override in gdb.
        * gdb.h (configure): Likewise.
        (gdb): fixed_pin_map_component, fixed_relation_map_component and
        configurable_component inherited virtually.
        * sw-debug-gdb.xml: Add description of new interfaces.
        * sw-debug-gdb.txt: Regenerated.

sid/component/consoles/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * components.h (socketio): Inherit virtually from
        fixed_attribute_map_component. Inherit from no_relation_component.

        2005-06-06  Dave Brolley  <[hidden email]>

        * components.h: Add using clause for sidutil::configurable_component.
        (socketio): fixed_pin_map_component and configurable_component inherited
        virtually. no_relation_component no longer inherited.
        (configure): New virtual override in socketio.
        * socketio.cxx (configure): Likewise.
        * sid-io-socket.xml: Add description of new interfaces.
        * sid-io-socket.txt: Regenerated.

sid/component/cgen-cpu/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute the following changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * cgen-cpu.h (notify_ret): Set last_caller and last_callee.

        2005-05-29  Dave Brolley  <[hidden email]>

        * cgen-cpu.h (branch, done_insn, done_cti_insn, notify_ret):
        New virtual overrides.
        (was_return): New member of cgen_bi_endian_cpu.

sid/component/cfgroot/ChangeLog:
2005-08-04  Dave Brolley  <[hidden email]>

        * Contribute these changes:

        2005-07-13  Dave Brolley  <[hidden email]>

        * compConfig.cxx (new_config_pin): Removed from
        dynamic_configurator_component.
        (clients): Added to dynamic_configurator_component.
        (dynamic_configurator_component): Remove new-config pin. Add
        clients as a multi relation.
        (step_pin_handler): Set the configure! attribute of each component
        related via the client relationship.
        (do_configure): Set config_names[0] and config_specs[0] if the
        handle is zero.
        * sid-control-dynamic-configurator.xml: Document the removal of the
        new-config pin and the addition of the clients relationship.
        * sid-control-dynamic-configurator.txt: Regenerated.

        2005-07-05  Dave Brolley  <[hidden email]>

        * compConfig.cxx (reset_pin_handler): New method of
        dynamic_configurator_component.
        (set_start_config): Likewise.
        (reset): Likewise.
        (reset_pin): New member of dynamic_configurator_component.
        (config_error_pin): Likewise.
        (dynamic_configurator_component): Initialize current_config, prev_config
        and prev_user_config in the reset method. Add "start-config" attribute.
        Add "reset" and "config-error" pins.
        (configure): Check result of do_configure. Drive config_error_pin if not
        ok.
        (configure_pin_handler): Drive config_error_pin if the handle is not
        valid.
        * sid-control-dynamic-configurator.xml: Document the "config-error" and "reset"
        pins
        * sid-control-dynamic-configurator.txt: Regenerated.

        2005-06-21  Dave Brolley  <[hidden email]>

        * compConfig.cxx (step_pin_handler): Always drive new_config_pin.

        2005-06-06  Dave Brolley  <[hidden email]>

        * Makefile.am (pkgdata_DATA): Add sid-control-dynamic-configurator.txt.
        * Makefile.in: Regenerated.
        * compConfig.cxx (cfgroot_component::configure): Renamed to
        configure_file.
        (restore_config,set_syscall_config,check_config_change): New methods of
        dynamic_configurator_component.
        (in_function): Likewise.
        (prev_user_config): New member of dynamic_configurator_component.
        (dynamic_configurator_component): Prime the config_stack with a dummy
        entry.
        (add_warmup_functions): Tokenize based on ",".
        (add_profile_functions): Move on to the next spec on parse error.
        (dynamic_configurator_component::configure): Drive config_result_pin with
        prev_user_config. Call set_syscall_config and check_config_change.
        (do_configure): Don't drive the config_result_pin here. Don't drive the
        step_control_pin here. Duplicate the first stack entry for the first
        config in the dummy entry of the stack. Now takes a reference to a
        config handle.
        (configure_pin_handler): Drive the config_result_pin with prev_user_config.
        Call restore_config, sys_syscall_config and check_config_change.
        (function_callee_pin_handler): Always use sid-internal-warmup for _Sid_config.
        (function_return_pin_handler): Return if the loader can't identify the current
        function. Call restore_config and check_config_change.
        * sid-control-dynamic-configurator.txt: New file.
        * sid-control-dynamic-configurator.xml: New file.

        2005-05-29  Dave Brolley  <[hidden email]>

        * compConfig.cxx (std::pair,sidutil::tokenize): Add using clause for these.
        (dynamic_config,lookup_dynamic_config): New methods of cfgroot_component.
        (dynamic_configs,found_dynamic_config): New members of cfgroot_component.
        (configure_line): Initialize num_invalid_chars.
        (cfgroot_component): Initialize dynamic_configs and found_dynamic_config.
        Add virtual attributes dynamic-config! and lookup-dynamic-config!. Add
        attribute found-dynamic-config.
        (dynamic_configurator_component): New class.
        (compConfigListTypes): Push back sid-control-dynamic-configurator.
        (compConfigCreate): Handle sid-control-dynamic-configurator.
        (compConfigDelete): Delete dynamic_configurator_component.


? sid/component/cfgroot/sid-control-dynamic-configurator.txt
? sid/component/cfgroot/sid-control-dynamic-configurator.xml
Index: sid/component/cfgroot/Makefile.am
===================================================================
RCS file: /cvs/src/src/sid/component/cfgroot/Makefile.am,v
retrieving revision 1.6
diff -c -p -r1.6 Makefile.am
*** sid/component/cfgroot/Makefile.am 29 Apr 2004 20:26:58 -0000 1.6
--- sid/component/cfgroot/Makefile.am 4 Aug 2005 18:32:38 -0000
*************** libconfig_la_LDFLAGS = -module -no-undef
*** 14,20 ****
  libconfig_la_LIBADD = @LIBLTDL@
  libconfig_la_DEPENDENCIES = @LIBLTDL@
 
! pkgdata_DATA = sid-control-cfgroot.txt
 
  DEJAGNUTESTS=badconf.exp
  check-local: all
--- 14,20 ----
  libconfig_la_LIBADD = @LIBLTDL@
  libconfig_la_DEPENDENCIES = @LIBLTDL@
 
! pkgdata_DATA = sid-control-cfgroot.txt sid-control-dynamic-configurator.txt
 
  DEJAGNUTESTS=badconf.exp
  check-local: all
Index: sid/component/cfgroot/compConfig.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cfgroot/compConfig.cxx,v
retrieving revision 1.9
diff -c -p -r1.9 compConfig.cxx
*** sid/component/cfgroot/compConfig.cxx 29 Apr 2004 20:26:58 -0000 1.9
--- sid/component/cfgroot/compConfig.cxx 4 Aug 2005 18:32:38 -0000
***************
*** 1,7 ****
  // compConfig.cxx - The cfgroot component: configuration parsing, root
  // of component creation and management.  -*- C++ -*-
 
! // Copyright (C) 1999, 2000, 2001, 2002 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
 
--- 1,7 ----
  // compConfig.cxx - The cfgroot component: configuration parsing, root
  // of component creation and management.  -*- C++ -*-
 
! // Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
 
***************
*** 38,43 ****
--- 38,44 ----
  #endif
 
  using std::map;
+ using std::pair;
  using std::vector;
  using std::string;
  using std::ostream;
*************** using sidutil::std_error_string;
*** 75,80 ****
--- 76,82 ----
  using sidutil::recursion_limited;
  using sidutil::recursion_record;
  using sidutil::find_sid_data_file;
+ using sidutil::tokenize;
 
 
  // This component reads a flat config file, and acts as a root
*************** protected:
*** 99,106 ****
    void stop (host_int_4); // stop top-level simulation loop
 
    // config-file! and config-line! virtual attribute handlers
!   component::status configure(const std::string&);
    component::status configure_line(const std::string&);
    string nothing ();
 
    // parser
--- 101,110 ----
    void stop (host_int_4); // stop top-level simulation loop
 
    // config-file! and config-line! virtual attribute handlers
!   component::status configure_file(const std::string&);
    component::status configure_line(const std::string&);
+   component::status dynamic_config(const std::string&);
+   component::status lookup_dynamic_config(const std::string&);
    string nothing ();
 
    // parser
*************** private:
*** 179,184 ****
--- 183,191 ----
    typedef map<string,component_library*> component_creator_map_t;
    component_creator_map_t component_creator_map;
 
+   // Dynamic configurations
+   map<string,string> dynamic_configs;
+   string found_dynamic_config;
  #ifndef NDEBUG
    void crash() { abort(); }
  #endif
*************** cfgroot_component::nothing()
*** 491,497 ****
 
 
  component::status
! cfgroot_component::configure(const std::string& name)
  {
    string last_config_file = this->config_file;
    this->config_file = name;
--- 498,504 ----
 
 
  component::status
! cfgroot_component::configure_file(const std::string& name)
  {
    string last_config_file = this->config_file;
    this->config_file = name;
*************** cfgroot_component::configure_line(const
*** 529,534 ****
--- 536,542 ----
    this->config_file_history += this->config_file;
    unsigned last_line_num = this->line_num;
    this->line_num = 1;
+   num_invalid_chars = 0;
 
    string line_with_eol = line + "\n";
 
*************** cfgroot_component::configure_line(const
*** 554,559 ****
--- 562,590 ----
  }
 
 
+ component::status
+ cfgroot_component::dynamic_config(const std::string& spec)
+ {
+   vector<string> parts = tokenize (spec, "|");
+   if (parts.size () != 2)
+     return component::bad_value;
+
+   dynamic_configs[parts[0]] = parts[1];
+   return component::ok;
+ }
+
+
+ component::status
+ cfgroot_component::lookup_dynamic_config(const std::string& name)
+ {
+   if (dynamic_configs.find (name) == dynamic_configs.end())
+     return component::not_found;
+
+   found_dynamic_config = name + "|" + dynamic_configs [name];
+   return component::ok;
+ }
+
+
  cfgroot_component::cfgroot_component():
    recursion_limited ("running", 1),
    running (false),
*************** cfgroot_component::cfgroot_component():
*** 564,570 ****
    stop_pin(this, & cfgroot_component::stop),
    verbose_p (false),
    autoprint_p (true),
!   persistent_p (false)
  {
    // suck in libtool preloaded symbols; must be called before lt_dlinit()
    LTDL_SET_PRELOADED_SYMBOLS ();
--- 595,603 ----
    stop_pin(this, & cfgroot_component::stop),
    verbose_p (false),
    autoprint_p (true),
!   persistent_p (false),
!   dynamic_configs (),
!   found_dynamic_config ("")
  {
    // suck in libtool preloaded symbols; must be called before lt_dlinit()
    LTDL_SET_PRELOADED_SYMBOLS ();
*************** cfgroot_component::cfgroot_component():
*** 609,619 ****
    add_attribute("stopping", & this->stopping_pin, "pin");
 
    add_attribute_virtual ("config-file!", this,
! & cfgroot_component::configure,
  & cfgroot_component::nothing);
    add_attribute_virtual ("config-line!", this,
  & cfgroot_component::configure_line,
  & cfgroot_component::nothing);
    add_attribute_ro ("config-file-history", & this->config_file_history,
                      "register");
    add_attribute("verbose?", & this->verbose_p, "setting");
--- 642,659 ----
    add_attribute("stopping", & this->stopping_pin, "pin");
 
    add_attribute_virtual ("config-file!", this,
! & cfgroot_component::configure_file,
  & cfgroot_component::nothing);
    add_attribute_virtual ("config-line!", this,
  & cfgroot_component::configure_line,
  & cfgroot_component::nothing);
+   add_attribute_virtual ("dynamic-config!", this,
+ & cfgroot_component::dynamic_config,
+ & cfgroot_component::nothing);
+   add_attribute_virtual ("lookup-dynamic-config!", this,
+ & cfgroot_component::lookup_dynamic_config,
+ & cfgroot_component::nothing);
+   add_attribute("found-dynamic-config", & this->found_dynamic_config, "result");
    add_attribute_ro ("config-file-history", & this->config_file_history,
                      "register");
    add_attribute("verbose?", & this->verbose_p, "setting");
*************** cfgroot_component::register_dso(const st
*** 739,745 ****
 
    // At last, try again looking within the executable
    if (dl_handle == 0)
!     dl_handle = lt_dlopen(NULL); // component library linked into executable
 
    if (dl_handle == 0)
      {
--- 779,787 ----
 
    // At last, try again looking within the executable
    if (dl_handle == 0)
!     {
!       dl_handle = lt_dlopen(NULL); // component library linked into executable
!     }
 
    if (dl_handle == 0)
      {
*************** cfgroot_component::inform_component_cata
*** 1172,1178 ****
      }
  }
 
-
  ostream&
  operator << (ostream& out, const cfgroot_component& it)
  {
--- 1214,1219 ----
*************** operator >> (istream& in, cfgroot_compon
*** 1202,1209 ****
--- 1243,1748 ----
 
    return in;
  }
+
  // -----------------------------------------------------------------------
+ // This component is used to dynamically configure the system.
+ //
+ class dynamic_configurator_component: public virtual component,
+ protected fixed_pin_map_component,
+ protected fixed_attribute_map_component,
+ protected no_bus_component,
+ protected no_accessor_component,
+ protected fixed_relation_map_component
+ {
+ public:
+   dynamic_configurator_component();
+   virtual ~dynamic_configurator_component() throw() {}
+ protected:
+   void reset_pin_handler(host_int_4 ignore);
+
+   component::status add_warmup_functions (const std::string&);
+   component::status add_profile_functions (const std::string&);
+   component::status set_start_config (const std::string&);
+
+   component::status configure (const std::string&);
+   component::status do_configure (const std::string &name, const std::string& config, unsigned &handle);
+   unsigned restore_config (unsigned handle);
+   unsigned set_syscall_config (unsigned);
+   void check_config_change (unsigned);
+
+   callback_pin<dynamic_configurator_component> reset_pin;
+   callback_pin<dynamic_configurator_component> step_pin;
+   output_pin step_control_pin;
+   callback_pin<dynamic_configurator_component> configure_pin;
+   callback_pin<dynamic_configurator_component> function_caller_pin;
+   callback_pin<dynamic_configurator_component> function_callee_pin;
+   callback_pin<dynamic_configurator_component> function_jump_pin;
+   callback_pin<dynamic_configurator_component> function_return_pin;
+   void step_pin_handler (host_int_4);
+   void configure_pin_handler (host_int_4 handle);
+   void function_caller_pin_handler (host_int_4 addr);
+   void function_callee_pin_handler (host_int_4 addr);
+   void function_jump_pin_handler (host_int_4 addr);
+   void function_return_pin_handler (host_int_4 addr);
+
+   output_pin config_result_pin;
+   output_pin config_error_pin;
+   output_pin function_address_pin;
+
+   unsigned current_config;
+   unsigned prev_config;
+   unsigned prev_user_config;
+   string get_current_config();
+   bool in_function (const string &name);
+
+   vector<string> config_names;
+   vector<string> config_specs;
+   map<string,string> function_configs;
+   vector< pair<string,unsigned> > config_stack;
+
+   component *loader;
+   component *main;
+   component_relation_t clients;
+
+ private:
+   string get_nothing () { return ""; }
+   component::status set_nothing (const string&) { return component::not_found; }
+   void reset ();
+ };
+
+
+ dynamic_configurator_component::dynamic_configurator_component ()
+   :
+   reset_pin(this, &dynamic_configurator_component::reset_pin_handler),
+   step_pin (this, &dynamic_configurator_component::step_pin_handler),
+   configure_pin (this, &dynamic_configurator_component::configure_pin_handler),
+   function_caller_pin (this, &dynamic_configurator_component::function_caller_pin_handler),
+   function_callee_pin (this, &dynamic_configurator_component::function_callee_pin_handler),
+   function_jump_pin (this, &dynamic_configurator_component::function_jump_pin_handler),
+   function_return_pin (this, &dynamic_configurator_component::function_return_pin_handler),
+   loader (0),
+   main (0)
+ {
+   add_attribute_virtual ("warmup-functions!", this,
+ & dynamic_configurator_component::add_warmup_functions,
+ & dynamic_configurator_component::get_nothing);
+   add_attribute_virtual ("profile-functions!", this,
+ & dynamic_configurator_component::add_profile_functions,
+ & dynamic_configurator_component::get_nothing);
+   add_attribute_virtual ("start-config", this,
+ & dynamic_configurator_component::set_start_config,
+ & dynamic_configurator_component::get_nothing);
+   add_attribute_virtual ("configure!", this,
+ & dynamic_configurator_component::configure,
+ & dynamic_configurator_component::get_nothing);
+   add_attribute_virtual ("current-config", this,
+ & dynamic_configurator_component::get_current_config,
+ & dynamic_configurator_component::set_nothing);
+   add_pin("reset", &this->reset_pin);
+   add_pin ("step!", &step_pin);
+   add_pin ("step-control", &step_control_pin);
+   add_pin ("configure!", &configure_pin);
+   add_pin ("config-result", &config_result_pin);
+   add_pin ("config-error", &config_error_pin);
+   add_pin ("function-caller!", &function_caller_pin);
+   add_pin ("function-callee!", &function_callee_pin);
+   add_pin ("function-jump!", &function_jump_pin);
+   add_pin ("function-return!", &function_return_pin);
+   add_pin ("function-address", &function_address_pin);
+
+   add_uni_relation("loader", &this->loader);
+   add_uni_relation("main", &this->main);
+   add_multi_relation ("client", &this->clients);
+
+   config_stack.push_back (pair<string,unsigned> ("<start>", 0));
+   config_names.push_back ("<start>");
+   config_specs.push_back ("");
+
+   reset ();
+ }
+
+ void
+ dynamic_configurator_component::reset_pin_handler(host_int_4)
+ {
+   reset();
+ }
+
+ void
+ dynamic_configurator_component::reset ()
+ {
+   current_config = 0;
+   prev_config = 0;
+   prev_user_config = 0;
+
+   while (config_stack.size () > 1)
+     config_stack.pop_back ();
+
+   assert (config_names.size () == config_specs.size ());
+   while (config_names.size () > 1)
+     {
+       config_names.pop_back ();
+       config_specs.pop_back ();
+     }
+
+   if (config_names[0] != "<start>")
+     {
+       component::status s = main->set_attribute_value ("lookup-dynamic-config!", config_names[0]);
+       if (s == component::ok)
+ {
+  string spec = main->attribute_value ("found-dynamic-config");
+  configure (spec);
+ }
+     }
+ }
+
+ // Set the starting configuration
+ component::status
+ dynamic_configurator_component::set_start_config (const std::string& name)
+ {
+   config_names[0] = name;
+   return component::ok;
+ }
+
+ // Add the given list of function names as functions to be simulated in warmup
+ // mode. FUNCS will be a comma-separated list of function names.
+ //
+ component::status
+ dynamic_configurator_component::add_warmup_functions (const std::string& funcs)
+ {
+   vector<string> parts = tokenize (funcs, ",");
+   unsigned size = parts.size ();
+   for (unsigned i = 0; i < size; ++i)
+     function_configs[parts[i]] = "sid-internal-warmup";
+
+   return component::ok;
+ }
+
+ // Process the given spec and assign the given profile name to
+ // the associated list of functions.
+ // SPEC will be a list of specs separatyed by '|'. Each spec
+ // will be a list of function names separated by commas followed
+ // by a colon and then the name of the profile to associated with
+ // thos functions.
+ //
+ component::status
+ dynamic_configurator_component::add_profile_functions (const std::string& specs)
+ {
+   component::status s = component::ok;
+   vector<string> parts = tokenize (specs, "|");
+   unsigned size = parts.size ();
+   for (unsigned i = 0; i < size; ++i)
+     {
+       vector<string> spec = tokenize (parts[i], ":");
+       if (spec.size () != 2)
+ {
+  s = component::bad_value;
+  continue;
+ }
+
+       const string &profile = spec[1];
+       vector<string> funcs = tokenize (spec[0], ",");
+       unsigned num_funcs = funcs.size ();
+       for (unsigned f = 0; f < num_funcs; ++f)
+ function_configs[funcs[f]] = profile;
+     }
+   return s;
+ }
+
+ // Drive the config-result pin if the configuration has changed
+ void
+ dynamic_configurator_component::step_pin_handler (host_int_4)
+ {
+   prev_config = current_config;
+
+   for (component_relation_t::const_iterator it = clients.begin ();
+        it != clients.end();
+        ++it)
+     (*it)->set_attribute_value ("configure!", config_specs[current_config]);
+
+   //  cout << "configured for " << config_names[current_config] + "|" + config_specs[current_config] << endl;
+ }
+
+ // Search for the named configuration in the list of previously used ones.
+ // If found, drive the config-result pin with the index of that config.
+ // Otherwise add the new config and drive the pin with the new index.
+ component::status
+ dynamic_configurator_component::configure (const std::string& spec)
+ {
+   vector<string> parts = tokenize (spec, "|");
+   if (parts.size () != 2)
+     return component::bad_value;
+
+   // Drive config-result pin with old config regardless of whether it changes.
+   config_result_pin.drive (prev_user_config);
+
+   unsigned new_handle;
+   component::status s = do_configure (parts[0], parts[1], new_handle);
+   if (s == component::ok)
+     {
+       new_handle = set_syscall_config (new_handle);
+       check_config_change (new_handle);
+       config_error_pin.drive (0);
+     }
+   else
+     config_error_pin.drive (1);
+
+   return s;
+ }
+
+ component::status
+ dynamic_configurator_component::do_configure (const std::string &name, const std::string& config, unsigned &new_handle)
+ {
+   // Identify and/or save the new configuration
+   unsigned size = config_names.size ();
+   unsigned handle;
+   for (handle = 0; handle < size; handle++)
+     {
+       if (config_names[handle] == name)
+ break;
+     }
+   if (handle >= size)
+     {
+       config_names.push_back (name);
+       config_specs.push_back (config);
+     }
+
+   // If this is the first configuration, then also set the
+   // default "<start>" config to this value.
+   if (handle == 0
+       || size == 1 && config_names[0] == "<start>")
+     {
+       config_names[0] = name;
+       config_specs[0] = config;
+     }
+
+   new_handle = handle;
+   return component::ok;
+ }
 
+ void
+ dynamic_configurator_component::configure_pin_handler (host_int_4 handle)
+ {
+   // Drive config-result pin with old config regardless of whether it changes.
+   config_result_pin.drive (prev_user_config);
+
+   host_int_4 orig_handle = handle;
+   handle = restore_config (handle);
+   config_error_pin.drive (handle != orig_handle);
+   handle = set_syscall_config (handle);
+   check_config_change (handle);
+ }
+
+ unsigned
+ dynamic_configurator_component::restore_config (host_int_4 handle)
+ {
+   if (handle >= config_specs.size ())
+     return current_config;
+
+   return handle;
+ }
+
+ unsigned
+ dynamic_configurator_component::set_syscall_config (unsigned handle)
+ {
+   // For a real syscall, there will be at least 2 entries on the stack.
+   unsigned size = config_stack.size ();
+   if (size <= 1)
+     return handle;
+
+   // If the current function is _Sid_config, then change the config
+   // of the function which called _Sid_config, otherwise change the
+   // config of the function on the top of the stack.
+   string top_func = config_stack.back ().first;
+   unsigned top_handle = config_stack.back ().second;
+   config_stack.pop_back ();
+
+   if (top_func == "_Sid_config")
+     {
+       assert (size > 2);
+       string next_func = config_stack.back ().first;
+       config_stack.pop_back ();
+       config_stack.push_back (pair<string,unsigned> (next_func, handle));
+       config_stack.push_back (pair<string,unsigned> (top_func, top_handle));
+       return top_handle;
+     }
+
+   config_stack.push_back (pair<string,unsigned> (top_func, handle));
+   return handle;
+ }
+
+ void
+ dynamic_configurator_component::check_config_change (unsigned handle)
+ {
+   if (handle != prev_user_config)
+     {
+       if (! in_function ("_Sid_config"))
+ prev_user_config = handle;
+     }
+
+   if (current_config != handle
+       && config_specs[current_config] != config_specs[handle])
+     {
+       current_config = handle;
+       step_control_pin.drive (1); // reconfigure during next cycle
+     }
+ }
+
+ void
+ dynamic_configurator_component::function_caller_pin_handler (host_int_4 addr)
+ {
+   if (! loader)
+     return;
+
+   // Drive the address on the function-address pin and read the
+   // resulting attribute value from the loader.
+   function_address_pin.drive (addr);
+   string function = loader->attribute_value("current-function");
+
+   // If there is no config on the stack, or it is for a different function,
+   // we must have jumped into this function. Treat it as if it was called.
+   if (config_stack.size() == 0 || config_stack.back ().first != function)
+     function_callee_pin_handler (addr);
+ }
+
+ void
+ dynamic_configurator_component::function_jump_pin_handler (host_int_4 addr)
+ {
+   if (! loader)
+     return;
+
+   // Drive the address on the function-address pin and read the
+   // resulting attribute value from the loader.
+   function_address_pin.drive (addr);
+   string function = loader->attribute_value("current-function");
+
+   // If the current function is on the stack, then assume we're
+   // returning to it, otherwise assume we're calling it.
+   for (vector < pair<string,unsigned> >::const_iterator it = config_stack.begin ();
+        it != config_stack.end ();
+        ++it)
+     {
+       if (it->first == function)
+ {
+  function_return_pin_handler (addr);
+  return;
+ }
+     }
+   function_callee_pin_handler (addr);
+ }
+
+ void
+ dynamic_configurator_component::function_callee_pin_handler (host_int_4 addr)
+ {
+   if (! loader)
+     return;
+
+   // Drive the address on the function-address pin and read the
+   // resulting attr
Reply | Threaded
Open this post in threaded view
|

Re: [patch][rfa] Dynamic Configuration of SID

Dave Brolley-2
I've committed this.

Dave

Dave Brolley wrote:

> Hi,
>
> A customer of our showed some interest in dynamic configuration of SID
> simulations from the point of view of "warming up" the simulator in
> various situations. This generally means limiting high overhead
> functionality (tracing, performance analysis, etc.) to areas of the
> target application which are of greatest interest.
>
> Attached are overviews of external and internal specs of how this
> could be applied to SID along with a patch which implements the spec.
>
> Comments are appreciated and, as always, I'm looking for approval to
> commit this work.
>
> Thanks,
> Dave
>