<commit_before>// Copyright ***********************************************************
//                                                                      
// File ecmdIstepUser.C                                   
//                                                                      
// IBM Confidential                                                     
// OCO Source Materials                                                 
// 9400 Licensed Internal Code                                          
// (C) COPYRIGHT IBM CORP. 1996                                         
//                                                                      
// The source code for this program is not published or otherwise       
// divested of its trade secrets, irrespective of what has been         
// deposited with the U.S. Copyright Office.                            
//                                                                      
// End Copyright *******************************************************

// Module Description **************************************************
//
// Description: 
//
// End Module Description **********************************************
/* $Header$ */
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------

#include <stdio.h>
#include <list>
#include <string>
#include <algorithm>
#include <ctype.h>

#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdUtils.H>
#include <ecmdDataBuffer.H>
#include <ecmdInterpreter.H>
#include <ecmdSharedUtils.H>


//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------

uint32_t ecmdIstepUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;
  ecmdDataBuffer steps(200);                    ///< Buffer to hold numbered steps (max of 200 steps)
  std::string userArgs;                         ///< Buffer for manipulating user args
  std::vector<std::string> tokens;              ///< Tokens from user args
  std::list< std::string > iSteps;              ///< Steps to pass into Multiple function
  bool foundRange;                              ///< Did the user specify a range of step names

  char * stepPtr = ecmdParseOptionWithArgs(&argc, &argv, "-s");
  char * skipStepPtr = ecmdParseOptionWithArgs(&argc, &argv, "-i");


  /* Now pull off the common args */
  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  if ((stepPtr != NULL) || (skipStepPtr != NULL) || (argc == 0)) {

    if ((stepPtr == NULL) && (skipStepPtr == NULL)) {
      /* They didn't specify a step, so we will run all */
      steps.flushTo1();

    } else {

      if ((stepPtr != NULL) && (skipStepPtr != NULL)) {
        ecmdOutputError("istep - You cannot specify -s and -i on the same command\n");
        return ECMD_INVALID_ARGS;
      } else if (argc != 0) {
        ecmdOutputError("istep - Too many arguments passed to istep\n");
        return ECMD_INVALID_ARGS;
      }

      std::string curSubstr;
      if (stepPtr != NULL)
        userArgs = stepPtr;
      else {
        userArgs = skipStepPtr;
        steps.flushTo1();
      }

      size_t curOffset = 0;
      size_t nextOffset = 0;
      size_t tmpOffset = 0;

      while (curOffset < userArgs.length()) {

        nextOffset = userArgs.find(',',curOffset);
        if (nextOffset == std::string::npos) {
          nextOffset = userArgs.length();
        }

        curSubstr = userArgs.substr(curOffset, nextOffset - curOffset);
        
        if ((tmpOffset = curSubstr.find("..",0)) < curSubstr.length()) {

          if (!isdigit(curSubstr[0]) || !isdigit(curSubstr[tmpOffset+2])) {
            ecmdOutputError("istep - Non-Numeric character found in istep range (x..y)\n");
            return ECMD_INVALID_ARGS;
          }
            
          uint32_t lowerBound = (uint32_t)atoi(curSubstr.substr(0,tmpOffset).c_str());
          uint32_t upperBound = (uint32_t)atoi(curSubstr.substr(tmpOffset+2, curSubstr.length()).c_str());
          
          if (stepPtr != NULL)
            steps.setBit(lowerBound, upperBound - lowerBound + 1);
          else
            steps.clearBit(lowerBound, upperBound - lowerBound + 1);

        }
        else {
          if (!isdigit(curSubstr[0])) {
            ecmdOutputError("istep - Non-Numeric character found in istep steps (x,y)\n");
            return ECMD_INVALID_ARGS;
          }

          if (stepPtr != NULL)
            steps.setBit((uint32_t)atoi(curSubstr.c_str()));
          else
            steps.clearBit((uint32_t)atoi(curSubstr.c_str()));

        }
        
        curOffset = nextOffset+1;
        
      }
    }



    rc = iStepsByNumber(steps);

  } else {

    /* Let's just push all the args into one string */
    userArgs = "";
    for (int arg = 0; arg < argc; arg ++) {
      userArgs += argv[arg];
    }

    /* Let's see if the user specified a range */
    foundRange = false;
    if (userArgs.find("..",0) != std::string::npos) foundRange = true;

    /* Now let's break up into our tokens */
    ecmdParseTokens(userArgs, ", .", tokens);

    if (foundRange) {
      if (tokens.size() != 2) {
        ecmdOutputError("istep - Too many arguments found when specifying a step name range '..'\n");
        rc = ECMD_INVALID_ARGS;
      } else {
        rc = iStepsByNameRange(tokens[0], tokens[1]);
      }

    } else {
      /* Let's move the steps from the vector to a list (kindof annoying) */
      for (uint32_t x = 0; x < tokens.size(); x ++) {
        iSteps.push_back(tokens[x]);
      }

      rc = iStepsByNameMultiple(iSteps);
    }   
  }
  if (rc) {
    ecmdOutputError("istep - Problems running iSteps\n");
  }

  return rc;

}

#ifndef ECMD_REMOVE_CLOCK_FUNCTIONS
uint32_t ecmdStartClocksUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;

  char clockDomain[100]; 			///< Store the clock domain user specified
  ecmdLooperData looperdata;            ///< Store internal Looper data
  ecmdChipTarget target;                ///< Current target being operated on
  bool validPosFound = false;           ///< Did the looper find something to run on?

   /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
 
  //Check force option
  bool force = ecmdParseOption(&argc, &argv, "-force");

  strcpy(clockDomain, "ALL");
  
  //Convenience Clock Domains
  char * cDomain = ecmdParseOptionWithArgs(&argc, &argv, "-domain");
  if (cDomain != NULL) {
    strcpy(clockDomain, cDomain);
  }
  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  //Setup the target that will be used to query the system config
  if(argc >= 1) {
   target.chipType = argv[0];
   target.chipTypeState = ECMD_TARGET_FIELD_VALID;
   target.posState      = ECMD_TARGET_FIELD_WILDCARD;
  }
  else {
   target.chipTypeState = target.posState = ECMD_TARGET_FIELD_UNUSED;
  }

  target.cageState = target.nodeState = target.slotState = ECMD_TARGET_FIELD_WILDCARD;
  target.threadState = target.coreState = ECMD_TARGET_FIELD_UNUSED;

  std::string printed;

  //Should be the case only if -domain wasn't specified
  if(argc == 2) {
    if(strcmp(clockDomain,"ALL")!=0) {
       printed = "startclocks - Convenience Domain '"+ (std::string)clockDomain + "' and Physical Domain '" + (std::string)argv[1] +"' both specified. Choosing Physical Domain.\n";
       ecmdOutputWarning( printed.c_str() );
    }
    strcpy(clockDomain, argv[1]);
  }
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP_DEFALL, looperdata);
  if (rc) return rc;

  ecmdOutput("Starting Clocks on Targets ...\n");

  while ( ecmdConfigLooperNext(target, looperdata) ) {

    rc = startClocks(target, clockDomain, force);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc == ECMD_INVALID_CLOCK_DOMAIN) {
        printed = "startclocks - An invalid clock domain " + (std::string)clockDomain+ " was specified for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_CLOCKS_ALREADY_ON) {
        printed = "startclocks - Clocks in the specified domain are already on for target ";
        printed += ecmdWriteTarget(target) + "\n";
        if(force) {
         ecmdOutput( printed.c_str() );
	 continue;
	} 
	else {
	 ecmdOutputError( printed.c_str() );
         return rc;
	}
    }
    else if (rc == ECMD_CLOCKS_IN_INVALID_STATE) {
        printed = "startclocks - The clock in the specified domain are in an unknown state (not all on/off) for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_RING_CACHE_ENABLED) {
        printed = "startclocks - Ring Cache enabled - must be disabled to use this function. Target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }


    printed = ecmdWriteTarget(target) + "\n";
    ecmdOutput( printed.c_str() ); 
  }

  if (!validPosFound) {
    ecmdOutputError("Unable to find a valid target to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}

uint32_t ecmdStopClocksUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;

  char clockDomain[100]; 			///< Store the clock domain user specified
  ecmdLooperData looperdata;            ///< Store internal Looper data
  ecmdChipTarget target;                ///< Current target being operated on
  bool validPosFound = false;           ///< Did the looper find something to run on?

   /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
 
  //Check force option
  bool force = ecmdParseOption(&argc, &argv, "-force");

  strcpy(clockDomain, "ALL");
  
  //Convenience Clock Domains
  char * cDomain = ecmdParseOptionWithArgs(&argc, &argv, "-domain");
  if (cDomain != NULL) {
    strcpy(clockDomain, cDomain);
  }
  
  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  //Setup the target that will be used to query the system config
  if(argc >= 1) {
   target.chipType = argv[0];
   target.chipTypeState = ECMD_TARGET_FIELD_VALID;
   target.posState      = ECMD_TARGET_FIELD_WILDCARD;
  }
  else {
   target.chipTypeState = target.posState = ECMD_TARGET_FIELD_UNUSED;
  }

  target.cageState = target.nodeState = target.slotState = ECMD_TARGET_FIELD_WILDCARD;
  target.threadState = target.coreState = ECMD_TARGET_FIELD_UNUSED;

  std::string printed;

  if(argc == 2) {
     if(strcmp(clockDomain,"ALL")!=0) {
       printed = "stopclocks - Convenience Domain '"+ (std::string)clockDomain + "' and Physical Domain '" + (std::string)argv[1] +"' both specified. Choosing Physical Domain.\n";
       ecmdOutputWarning( printed.c_str() );
     }
     strcpy(clockDomain, argv[1]);
  }
  
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP_DEFALL, looperdata);
  if (rc) return rc;
  ecmdOutput("Stopping Clocks on Targets ...\n");

  while ( ecmdConfigLooperNext(target, looperdata) ) {

    rc = stopClocks(target, clockDomain, force);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc == ECMD_INVALID_CLOCK_DOMAIN) {
        printed = "stopclocks - An invalid clock domain " + (std::string)clockDomain+ " was specified for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_CLOCKS_ALREADY_OFF) {
        printed = "stopclocks - Clocks in the specified domain are already off for target ";
        printed += ecmdWriteTarget(target) + "\n";
	if(force) {
         ecmdOutput( printed.c_str() );
	 continue;
	} 
	else {
	 ecmdOutputError( printed.c_str() );
         return rc;
	}
    }
    else if (rc == ECMD_CLOCKS_IN_INVALID_STATE) {
        printed = "stopclocks - The clock in the specified domain are in an unknown state (not all on/off) for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_RING_CACHE_ENABLED) {
        printed = "stopclocks - Ring Cache enabled - must be disabled to use this function. Target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }


    printed = ecmdWriteTarget(target) + "\n";
    ecmdOutput( printed.c_str() ); 
  }

  if (!validPosFound) {
    ecmdOutputError("Unable to find a valid target to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}  
#endif // ECMD_REMOVE_CLOCK_FUNCTIONS

#ifndef ECMD_REMOVE_REFCLOCK_FUNCTIONS
uint32_t ecmdSetClockSpeedUser(int argc, char* argv[]) {
  uint32_t rc = ECMD_SUCCESS;
  
  ecmdChipTarget target;                        ///< Current target being operated on
  bool validPosFound = false;                   ///< Did the looper find anything?
  ecmdLooperData looperdata;                    ///< Store internal Looper data
  std::string printed;                          ///< Output data
  std::string chipType;                         ///< The chiptype the user specified (optional)
  std::string clocktype;                        ///< the clock type to change the speed on
  std::string clockspeed;                       ///< Speed - frequency or cycle time
  ecmdClockSpeedType_t speedType = ECMD_CLOCK_FREQUENCY_SPEC; ///< Clock speed type - frequency or cycle time
  ecmdClockType_t clockType = ECMD_CLOCKTYPE_UNKNOWN;  ///< the clock type to change the speed on
  ecmdClockSetMode_t clockSetMode = ECMD_CLOCK_ONE_STEP; ///< do adjustment in one operation or to steer to new value
  ecmdClockRange_t clockRange = ECMD_CLOCK_RANGE_DEFAULT; ///< range to adjust clock steering procedure
  uint32_t iv_mult=0;                              ///< Multiplier value, if present 
  uint32_t iv_div=0;                           ///< Divider value, if present
  int32_t endOffet = 0;                         ///< The location where the required args in the arg list end

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
  if (ecmdParseOption(&argc, &argv, "-steer")) {
    clockSetMode = ECMD_CLOCK_STEER;
  }
  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  if (argc < 2) {  //clocktype + speed
    ecmdOutputError("setclockspeed - Too few arguments specified; you need at least a clocktype and speed.\n");
    ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  /* We need to figure out if the user gave us a proc chip or not */
  std::string temp = argv[0];
  transform(temp.begin(), temp.end(), temp.begin(), (int(*)(int)) tolower);
  if (temp.find_last_of("clock") == std::string::npos) {
    /* No clock in the very first arg, assume it is a chip */
    chipType = argv[0];
    clocktype = argv[1];
    clockspeed = argv[2];
    endOffet = 2;
  } else {
    /* We had a clock in the very first arg, assume no chip was given */
    clocktype = argv[0];
    clockspeed = argv[1];
    endOffet = 1;
  }

  //Setup the target that will be used to query the system config
  if (chipType != "") {
    target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
    target.chipType = chipType;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.coreState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else {
    target.cageState =  ECMD_TARGET_FIELD_WILDCARD;
    target.nodeState = target.slotState = target.posState = target.chipTypeState = target.coreState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  }

  //Check the clock type
  transform(clocktype.begin(), clocktype.end(), clocktype.begin(), (int(*)(int)) tolower);
  if (clocktype == "pu_refclock") {
    clockType = ECMD_PROC_REFCLOCK;
  } else if (clocktype == "memctrl_refclock") {
    clockType = ECMD_MEMCTRL_REFCLOCK;
  } else if (clocktype == "pu_coreclock") {
    clockType = ECMD_PROC_CORE_CLOCK;
  } else if (clocktype == "pu_nestclock") {
    clockType = ECMD_PROC_NEST_CLOCK;
  } else if (clocktype == "memctrl_clock") {
    clockType = ECMD_MEMCTRL_CLOCK;
  } else if (clocktype == "io_refclock") {
    clockType = ECMD_IO_REFCLOCK;
  } else if (clocktype == "io_clock") {
    clockType = ECMD_IO_CLOCK;
  } else {
    ecmdOutputError("setclockspeed - Unrecognized clocktype! 'setclockspeed -h' for recognized types.\n");
    return ECMD_INVALID_ARGS;
  }
  
  //get clockspeed
  size_t strpos;
  transform(clockspeed.begin(), clockspeed.end(), clockspeed.begin(), (int(*)(int)) tolower);
  
  if ((strpos = clockspeed.find("mhz")) != std::string::npos)  {
    speedType = ECMD_CLOCK_FREQUENCY_SPEC;
  } else if ((strpos = clockspeed.find("us")) != std::string::npos) {
    speedType = ECMD_CLOCK_CYCLETIME_SPEC;
  } else if ((strpos = clockspeed.find("npu")) != std::string::npos) {
    speedType = ECMD_CLOCK_NOMINAL_PERCENT_UP;
  } else if ((strpos = clockspeed.find("npd")) != std::string::npos) {
    speedType = ECMD_CLOCK_NOMINAL_PERCENT_DOWN;
  } else if ((strpos = clockspeed.find("cpu")) != std::string::npos) {
    speedType = ECMD_CLOCK_CURRENT_PERCENT_UP;
  } else if ((strpos = clockspeed.find("cpd")) != std::string::npos) {
    speedType = ECMD_CLOCK_CURRENT_PERCENT_DOWN;
  } else if ((strpos = clockspeed.find("pspu")) != std::string::npos) {
    speedType = ECMD_CLOCK_POWERSAVE_PERCENT_UP;
  } else if ((strpos = clockspeed.find("pspd")) != std::string::npos) {
    speedType = ECMD_CLOCK_POWERSAVE_PERCENT_DOWN;
  } else if ((strpos = clockspeed.find("mult")) != std::string::npos) {

    // get mult and divider value from cmdline
    clockspeed.erase(strpos, clockspeed.length()-strpos);

    if (!ecmdIsAllDecimal(clockspeed.c_str())) {
      ecmdOutputError("setclockspeed - Non-Decimal characters detected in speed field with 'mult' parm\n");
      return ECMD_INVALID_ARGS;
    }
    iv_mult = (uint32_t)atoi(clockspeed.c_str());
    if (iv_mult==0) {
      ecmdOutputError("setclockspeed - 'mult' value cannot equal 0\n");
      return ECMD_INVALID_ARGS;
    }
    
    // divider is the next parm
    clockspeed = argv[endOffet + 1];
    transform(clockspeed.begin(), clockspeed.end(), clockspeed.begin(), (int(*)(int)) tolower);

    if ((strpos = clockspeed.find("div")) != std::string::npos) {
      clockspeed.erase(strpos, clockspeed.length()-strpos);

      if (!ecmdIsAllDecimal(clockspeed.c_str())) {
        ecmdOutputError("setclockspeed - Non-Decimal characters detected in speed field with 'div' parm\n");
        return ECMD_INVALID_ARGS;
      }
      iv_div = (uint32_t)atoi(clockspeed.c_str());
      if (iv_div==0) {
        ecmdOutputError("setclockspeed - 'div' value cannot equal 0\n");
        return ECMD_INVALID_ARGS;
      }
      // set 'clockspeed' variable back to argv[1], as if another parm was used rather than mult and div
      //  therefore, code after this check will work
      clockspeed = argv[1];

    } else {
      // this is supposed to be 'div'
      ecmdOutputError("setclockspeed - 'div' parm needs to come after 'mult' parm\n");
      ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
      return ECMD_INVALID_ARGS;
    }


  } else {
    ecmdOutputError("setclockspeed - Speed Keyword not found in clock speed field\n");
    ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }
  
  clockspeed.erase(strpos, clockspeed.length()-strpos);
  
  if (!ecmdIsAllDecimal(clockspeed.c_str())) {
    ecmdOutputError("setclockspeed - Non-Decimal characters detected in speed field\n");
    return ECMD_INVALID_ARGS;
  } 
  
  uint32_t speed = (uint32_t)atoi(clockspeed.c_str());

  if (((argc > (endOffet+1)) && (iv_mult==0)) || ((argc > (endOffet+1)) && (iv_mult!=0)))  {
    ecmdOutputError("setclockspeed - Too many arguments specified; you probably added an option that wasn't recognized.\n");
    ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }
  
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;


  while ( ecmdConfigLooperNext(target, looperdata) ) {
    if (iv_mult==0)
      rc = ecmdSetClockSpeed(target, clockType, speed, speedType, clockSetMode, clockRange);
    else 
      rc = ecmdSetClockMultDiv(target, clockType, iv_mult, iv_div);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc) {
        printed = "setclockspeed - Error occured performing setclockspeed on ";
        printed += ecmdWriteTarget(target);
        printed += "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }

    
    printed = ecmdWriteTarget(target);
    printed += "\n";
    ecmdOutput( printed.c_str() );
  }


  if (!validPosFound) {
    //this is an error common across all UI functions
    ecmdOutputError("setclockspeed - Unable to find a valid chip to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  

  return rc;
}

uint32_t ecmdGetClockSpeedUser(int argc, char* argv[]) {
  uint32_t rc = ECMD_SUCCESS;
  
  ecmdChipTarget target;                        ///< Current target being operated on
  bool validPosFound = false;                   ///< Did the looper find anything?
  ecmdLooperData looperdata;                    ///< Store internal Looper data
  std::string printed;                          ///< Output data
  ecmdClockSpeedType_t speedType;               ///< Clock speed type - frequency or cycle time
  ecmdClockType_t clockType;                    ///< the clock type to change the speed on
  std::string outputformat = "d";               ///< Output Format to display
  uint32_t speed;                               ///< The speed return value
  ecmdDataBuffer buffer(32);

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  if (argc < 2) {  //clocktype + speed
    ecmdOutputError("getclockspeed - Too few arguments specified; you need at least a clocktype and speed.\n");
    ecmdOutputError("getclockspeed - Type 'getclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }
  if (argc > 2) {
    ecmdOutputError("getclockspeed - Too many arguments specified; you need only a clocktype and speed.\n");
    ecmdOutputError("getclockspeed - Type 'getclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  //Setup the target that will be used to query the system config 
  target.chipType = ECMD_CHIPT_PROCESSOR;
  target.chipTypeState = ECMD_TARGET_FIELD_VALID;
  target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
  target.coreState = target.threadState = ECMD_TARGET_FIELD_UNUSED;

  //Get the clock type
  std::string clocktype = argv[0];
  transform(clocktype.begin(), clocktype.end(), clocktype.begin(), (int(*)(int)) tolower);
  if (clocktype == "pu_refclock") {
    clockType = ECMD_PROC_REFCLOCK;
  } else if (clocktype == "memctrl_refclock") {
    clockType = ECMD_MEMCTRL_REFCLOCK;
  } else if (clocktype == "pu_coreclock") {
    clockType = ECMD_PROC_CORE_CLOCK;
  } else if (clocktype == "pu_nestclock") {
    clockType = ECMD_PROC_NEST_CLOCK;
  } else if (clocktype == "memctrl_clock") {
    clockType = ECMD_MEMCTRL_CLOCK;
  } else if (clocktype == "io_refclock") {
    clockType = ECMD_IO_REFCLOCK;
  } else if (clocktype == "io_clock") {
    clockType = ECMD_IO_CLOCK;
  } else {
    ecmdOutputError("getclockspeed - Unrecognized clocktype! 'getclockspeed -h' for recognized types.\n");
    return ECMD_INVALID_ARGS;
  }
  
  //get clockspeed
  std::string clockspeed = argv[1];
  transform(clockspeed.begin(), clockspeed.end(), clockspeed.begin(), (int(*)(int)) tolower);
  
  if (clockspeed == "mhz")  {
    speedType = ECMD_CLOCK_FREQUENCY_SPEC;
  } else if (clockspeed == "us") {
    speedType = ECMD_CLOCK_CYCLETIME_SPEC;
  } else {
    ecmdOutputError("getclockspeed - keyword \"mhz\" or \"us\" not found in clock speed field\n");
    return ECMD_INVALID_ARGS;
  }
  
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;


  while ( ecmdConfigLooperNext(target, looperdata) ) {
    rc = ecmdGetClockSpeed(target, clockType, speedType, speed);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc) {
        printed = "getclockspeed - Error occured performing getclockspeed on ";
        printed += ecmdWriteTarget(target);
        printed += "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }

    buffer.setWord(0, speed);
    printed = ecmdWriteTarget(target);
    printed += ecmdWriteDataFormatted(buffer, outputformat);
    ecmdOutput( printed.c_str() );
  }


  if (!validPosFound) {
    //this is an error common across all UI functions
    ecmdOutputError("getclockspeed - Unable to find a valid chip to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  

  return rc;
}
#endif // ECMD_REMOVE_REFCLOCK_FUNCTIONS

// Change Log *********************************************************
//                                                                      
//  Flag Reason   Vers Date     Coder    Description                       
//  ---- -------- ---- -------- -------- ------------------------------   
//                              CENGEL   Initial Creation
//  @00  D546069       11/03/06 honi     setclockspeed cpu/cpd change
//
// End Change Log *****************************************************
<commit_msg>Add lowerBound <= upperBound check for istep by numbers<commit_after>// Copyright ***********************************************************
//                                                                      
// File ecmdIstepUser.C                                   
//                                                                      
// IBM Confidential                                                     
// OCO Source Materials                                                 
// 9400 Licensed Internal Code                                          
// (C) COPYRIGHT IBM CORP. 1996                                         
//                                                                      
// The source code for this program is not published or otherwise       
// divested of its trade secrets, irrespective of what has been         
// deposited with the U.S. Copyright Office.                            
//                                                                      
// End Copyright *******************************************************

// Module Description **************************************************
//
// Description: 
//
// End Module Description **********************************************
/* $Header$ */
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------

#include <stdio.h>
#include <list>
#include <string>
#include <algorithm>
#include <ctype.h>

#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdUtils.H>
#include <ecmdDataBuffer.H>
#include <ecmdInterpreter.H>
#include <ecmdSharedUtils.H>


//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------

uint32_t ecmdIstepUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;
  ecmdDataBuffer steps(200);                    ///< Buffer to hold numbered steps (max of 200 steps)
  std::string userArgs;                         ///< Buffer for manipulating user args
  std::vector<std::string> tokens;              ///< Tokens from user args
  std::list< std::string > iSteps;              ///< Steps to pass into Multiple function
  bool foundRange;                              ///< Did the user specify a range of step names

  char * stepPtr = ecmdParseOptionWithArgs(&argc, &argv, "-s");
  char * skipStepPtr = ecmdParseOptionWithArgs(&argc, &argv, "-i");


  /* Now pull off the common args */
  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  if ((stepPtr != NULL) || (skipStepPtr != NULL) || (argc == 0)) {

    if ((stepPtr == NULL) && (skipStepPtr == NULL)) {
      /* They didn't specify a step, so we will run all */
      steps.flushTo1();

    } else {

      if ((stepPtr != NULL) && (skipStepPtr != NULL)) {
        ecmdOutputError("istep - You cannot specify -s and -i on the same command\n");
        return ECMD_INVALID_ARGS;
      } else if (argc != 0) {
        ecmdOutputError("istep - Too many arguments passed to istep\n");
        return ECMD_INVALID_ARGS;
      }

      std::string curSubstr;
      if (stepPtr != NULL)
        userArgs = stepPtr;
      else {
        userArgs = skipStepPtr;
        steps.flushTo1();
      }

      size_t curOffset = 0;
      size_t nextOffset = 0;
      size_t tmpOffset = 0;

      while (curOffset < userArgs.length()) {

        nextOffset = userArgs.find(',',curOffset);
        if (nextOffset == std::string::npos) {
          nextOffset = userArgs.length();
        }

        curSubstr = userArgs.substr(curOffset, nextOffset - curOffset);
        
        if ((tmpOffset = curSubstr.find("..",0)) < curSubstr.length()) {

          if (!isdigit(curSubstr[0]) || !isdigit(curSubstr[tmpOffset+2])) {
            ecmdOutputError("istep - Non-Numeric character found in istep range (x..y)\n");
            return ECMD_INVALID_ARGS;
          }
            
          uint32_t lowerBound = (uint32_t)atoi(curSubstr.substr(0,tmpOffset).c_str());
          uint32_t upperBound = (uint32_t)atoi(curSubstr.substr(tmpOffset+2, curSubstr.length()).c_str());
          
          if (lowerBound > upperBound) {
            ecmdOutputError("istep - Lower Bound istep # > Upper Bound istep #\n");
            return ECMD_INVALID_ARGS;
          }

          if (stepPtr != NULL)
            steps.setBit(lowerBound, upperBound - lowerBound + 1);
          else
            steps.clearBit(lowerBound, upperBound - lowerBound + 1);

        }
        else {
          if (!isdigit(curSubstr[0])) {
            ecmdOutputError("istep - Non-Numeric character found in istep steps (x,y)\n");
            return ECMD_INVALID_ARGS;
          }

          if (stepPtr != NULL)
            steps.setBit((uint32_t)atoi(curSubstr.c_str()));
          else
            steps.clearBit((uint32_t)atoi(curSubstr.c_str()));

        }
        
        curOffset = nextOffset+1;
        
      }
    }



    rc = iStepsByNumber(steps);

  } else {

    /* Let's just push all the args into one string */
    userArgs = "";
    for (int arg = 0; arg < argc; arg ++) {
      userArgs += argv[arg];
    }

    /* Let's see if the user specified a range */
    foundRange = false;
    if (userArgs.find("..",0) != std::string::npos) foundRange = true;

    /* Now let's break up into our tokens */
    ecmdParseTokens(userArgs, ", .", tokens);

    if (foundRange) {
      if (tokens.size() != 2) {
        ecmdOutputError("istep - Too many arguments found when specifying a step name range '..'\n");
        rc = ECMD_INVALID_ARGS;
      } else {
        rc = iStepsByNameRange(tokens[0], tokens[1]);
      }

    } else {
      /* Let's move the steps from the vector to a list (kindof annoying) */
      for (uint32_t x = 0; x < tokens.size(); x ++) {
        iSteps.push_back(tokens[x]);
      }

      rc = iStepsByNameMultiple(iSteps);
    }   
  }
  if (rc) {
    ecmdOutputError("istep - Problems running iSteps\n");
  }

  return rc;

}

#ifndef ECMD_REMOVE_CLOCK_FUNCTIONS
uint32_t ecmdStartClocksUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;

  char clockDomain[100]; 			///< Store the clock domain user specified
  ecmdLooperData looperdata;            ///< Store internal Looper data
  ecmdChipTarget target;                ///< Current target being operated on
  bool validPosFound = false;           ///< Did the looper find something to run on?

   /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
 
  //Check force option
  bool force = ecmdParseOption(&argc, &argv, "-force");

  strcpy(clockDomain, "ALL");
  
  //Convenience Clock Domains
  char * cDomain = ecmdParseOptionWithArgs(&argc, &argv, "-domain");
  if (cDomain != NULL) {
    strcpy(clockDomain, cDomain);
  }
  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  //Setup the target that will be used to query the system config
  if(argc >= 1) {
   target.chipType = argv[0];
   target.chipTypeState = ECMD_TARGET_FIELD_VALID;
   target.posState      = ECMD_TARGET_FIELD_WILDCARD;
  }
  else {
   target.chipTypeState = target.posState = ECMD_TARGET_FIELD_UNUSED;
  }

  target.cageState = target.nodeState = target.slotState = ECMD_TARGET_FIELD_WILDCARD;
  target.threadState = target.coreState = ECMD_TARGET_FIELD_UNUSED;

  std::string printed;

  //Should be the case only if -domain wasn't specified
  if(argc == 2) {
    if(strcmp(clockDomain,"ALL")!=0) {
       printed = "startclocks - Convenience Domain '"+ (std::string)clockDomain + "' and Physical Domain '" + (std::string)argv[1] +"' both specified. Choosing Physical Domain.\n";
       ecmdOutputWarning( printed.c_str() );
    }
    strcpy(clockDomain, argv[1]);
  }
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP_DEFALL, looperdata);
  if (rc) return rc;

  ecmdOutput("Starting Clocks on Targets ...\n");

  while ( ecmdConfigLooperNext(target, looperdata) ) {

    rc = startClocks(target, clockDomain, force);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc == ECMD_INVALID_CLOCK_DOMAIN) {
        printed = "startclocks - An invalid clock domain " + (std::string)clockDomain+ " was specified for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_CLOCKS_ALREADY_ON) {
        printed = "startclocks - Clocks in the specified domain are already on for target ";
        printed += ecmdWriteTarget(target) + "\n";
        if(force) {
         ecmdOutput( printed.c_str() );
	 continue;
	} 
	else {
	 ecmdOutputError( printed.c_str() );
         return rc;
	}
    }
    else if (rc == ECMD_CLOCKS_IN_INVALID_STATE) {
        printed = "startclocks - The clock in the specified domain are in an unknown state (not all on/off) for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_RING_CACHE_ENABLED) {
        printed = "startclocks - Ring Cache enabled - must be disabled to use this function. Target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }


    printed = ecmdWriteTarget(target) + "\n";
    ecmdOutput( printed.c_str() ); 
  }

  if (!validPosFound) {
    ecmdOutputError("Unable to find a valid target to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}

uint32_t ecmdStopClocksUser(int argc, char * argv[]) {
  uint32_t rc = ECMD_SUCCESS;

  char clockDomain[100]; 			///< Store the clock domain user specified
  ecmdLooperData looperdata;            ///< Store internal Looper data
  ecmdChipTarget target;                ///< Current target being operated on
  bool validPosFound = false;           ///< Did the looper find something to run on?

   /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
 
  //Check force option
  bool force = ecmdParseOption(&argc, &argv, "-force");

  strcpy(clockDomain, "ALL");
  
  //Convenience Clock Domains
  char * cDomain = ecmdParseOptionWithArgs(&argc, &argv, "-domain");
  if (cDomain != NULL) {
    strcpy(clockDomain, cDomain);
  }
  
  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  //Setup the target that will be used to query the system config
  if(argc >= 1) {
   target.chipType = argv[0];
   target.chipTypeState = ECMD_TARGET_FIELD_VALID;
   target.posState      = ECMD_TARGET_FIELD_WILDCARD;
  }
  else {
   target.chipTypeState = target.posState = ECMD_TARGET_FIELD_UNUSED;
  }

  target.cageState = target.nodeState = target.slotState = ECMD_TARGET_FIELD_WILDCARD;
  target.threadState = target.coreState = ECMD_TARGET_FIELD_UNUSED;

  std::string printed;

  if(argc == 2) {
     if(strcmp(clockDomain,"ALL")!=0) {
       printed = "stopclocks - Convenience Domain '"+ (std::string)clockDomain + "' and Physical Domain '" + (std::string)argv[1] +"' both specified. Choosing Physical Domain.\n";
       ecmdOutputWarning( printed.c_str() );
     }
     strcpy(clockDomain, argv[1]);
  }
  
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP_DEFALL, looperdata);
  if (rc) return rc;
  ecmdOutput("Stopping Clocks on Targets ...\n");

  while ( ecmdConfigLooperNext(target, looperdata) ) {

    rc = stopClocks(target, clockDomain, force);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc == ECMD_INVALID_CLOCK_DOMAIN) {
        printed = "stopclocks - An invalid clock domain " + (std::string)clockDomain+ " was specified for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_CLOCKS_ALREADY_OFF) {
        printed = "stopclocks - Clocks in the specified domain are already off for target ";
        printed += ecmdWriteTarget(target) + "\n";
	if(force) {
         ecmdOutput( printed.c_str() );
	 continue;
	} 
	else {
	 ecmdOutputError( printed.c_str() );
         return rc;
	}
    }
    else if (rc == ECMD_CLOCKS_IN_INVALID_STATE) {
        printed = "stopclocks - The clock in the specified domain are in an unknown state (not all on/off) for target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else if (rc == ECMD_RING_CACHE_ENABLED) {
        printed = "stopclocks - Ring Cache enabled - must be disabled to use this function. Target ";
        printed += ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }


    printed = ecmdWriteTarget(target) + "\n";
    ecmdOutput( printed.c_str() ); 
  }

  if (!validPosFound) {
    ecmdOutputError("Unable to find a valid target to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}  
#endif // ECMD_REMOVE_CLOCK_FUNCTIONS

#ifndef ECMD_REMOVE_REFCLOCK_FUNCTIONS
uint32_t ecmdSetClockSpeedUser(int argc, char* argv[]) {
  uint32_t rc = ECMD_SUCCESS;
  
  ecmdChipTarget target;                        ///< Current target being operated on
  bool validPosFound = false;                   ///< Did the looper find anything?
  ecmdLooperData looperdata;                    ///< Store internal Looper data
  std::string printed;                          ///< Output data
  std::string chipType;                         ///< The chiptype the user specified (optional)
  std::string clocktype;                        ///< the clock type to change the speed on
  std::string clockspeed;                       ///< Speed - frequency or cycle time
  ecmdClockSpeedType_t speedType = ECMD_CLOCK_FREQUENCY_SPEC; ///< Clock speed type - frequency or cycle time
  ecmdClockType_t clockType = ECMD_CLOCKTYPE_UNKNOWN;  ///< the clock type to change the speed on
  ecmdClockSetMode_t clockSetMode = ECMD_CLOCK_ONE_STEP; ///< do adjustment in one operation or to steer to new value
  ecmdClockRange_t clockRange = ECMD_CLOCK_RANGE_DEFAULT; ///< range to adjust clock steering procedure
  uint32_t iv_mult=0;                              ///< Multiplier value, if present 
  uint32_t iv_div=0;                           ///< Divider value, if present
  int32_t endOffet = 0;                         ///< The location where the required args in the arg list end

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
  if (ecmdParseOption(&argc, &argv, "-steer")) {
    clockSetMode = ECMD_CLOCK_STEER;
  }
  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  if (argc < 2) {  //clocktype + speed
    ecmdOutputError("setclockspeed - Too few arguments specified; you need at least a clocktype and speed.\n");
    ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  /* We need to figure out if the user gave us a proc chip or not */
  std::string temp = argv[0];
  transform(temp.begin(), temp.end(), temp.begin(), (int(*)(int)) tolower);
  if (temp.find_last_of("clock") == std::string::npos) {
    /* No clock in the very first arg, assume it is a chip */
    chipType = argv[0];
    clocktype = argv[1];
    clockspeed = argv[2];
    endOffet = 2;
  } else {
    /* We had a clock in the very first arg, assume no chip was given */
    clocktype = argv[0];
    clockspeed = argv[1];
    endOffet = 1;
  }

  //Setup the target that will be used to query the system config
  if (chipType != "") {
    target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
    target.chipType = chipType;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.coreState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else {
    target.cageState =  ECMD_TARGET_FIELD_WILDCARD;
    target.nodeState = target.slotState = target.posState = target.chipTypeState = target.coreState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  }

  //Check the clock type
  transform(clocktype.begin(), clocktype.end(), clocktype.begin(), (int(*)(int)) tolower);
  if (clocktype == "pu_refclock") {
    clockType = ECMD_PROC_REFCLOCK;
  } else if (clocktype == "memctrl_refclock") {
    clockType = ECMD_MEMCTRL_REFCLOCK;
  } else if (clocktype == "pu_coreclock") {
    clockType = ECMD_PROC_CORE_CLOCK;
  } else if (clocktype == "pu_nestclock") {
    clockType = ECMD_PROC_NEST_CLOCK;
  } else if (clocktype == "memctrl_clock") {
    clockType = ECMD_MEMCTRL_CLOCK;
  } else if (clocktype == "io_refclock") {
    clockType = ECMD_IO_REFCLOCK;
  } else if (clocktype == "io_clock") {
    clockType = ECMD_IO_CLOCK;
  } else {
    ecmdOutputError("setclockspeed - Unrecognized clocktype! 'setclockspeed -h' for recognized types.\n");
    return ECMD_INVALID_ARGS;
  }
  
  //get clockspeed
  size_t strpos;
  transform(clockspeed.begin(), clockspeed.end(), clockspeed.begin(), (int(*)(int)) tolower);
  
  if ((strpos = clockspeed.find("mhz")) != std::string::npos)  {
    speedType = ECMD_CLOCK_FREQUENCY_SPEC;
  } else if ((strpos = clockspeed.find("us")) != std::string::npos) {
    speedType = ECMD_CLOCK_CYCLETIME_SPEC;
  } else if ((strpos = clockspeed.find("npu")) != std::string::npos) {
    speedType = ECMD_CLOCK_NOMINAL_PERCENT_UP;
  } else if ((strpos = clockspeed.find("npd")) != std::string::npos) {
    speedType = ECMD_CLOCK_NOMINAL_PERCENT_DOWN;
  } else if ((strpos = clockspeed.find("cpu")) != std::string::npos) {
    speedType = ECMD_CLOCK_CURRENT_PERCENT_UP;
  } else if ((strpos = clockspeed.find("cpd")) != std::string::npos) {
    speedType = ECMD_CLOCK_CURRENT_PERCENT_DOWN;
  } else if ((strpos = clockspeed.find("pspu")) != std::string::npos) {
    speedType = ECMD_CLOCK_POWERSAVE_PERCENT_UP;
  } else if ((strpos = clockspeed.find("pspd")) != std::string::npos) {
    speedType = ECMD_CLOCK_POWERSAVE_PERCENT_DOWN;
  } else if ((strpos = clockspeed.find("mult")) != std::string::npos) {

    // get mult and divider value from cmdline
    clockspeed.erase(strpos, clockspeed.length()-strpos);

    if (!ecmdIsAllDecimal(clockspeed.c_str())) {
      ecmdOutputError("setclockspeed - Non-Decimal characters detected in speed field with 'mult' parm\n");
      return ECMD_INVALID_ARGS;
    }
    iv_mult = (uint32_t)atoi(clockspeed.c_str());
    if (iv_mult==0) {
      ecmdOutputError("setclockspeed - 'mult' value cannot equal 0\n");
      return ECMD_INVALID_ARGS;
    }
    
    // divider is the next parm
    clockspeed = argv[endOffet + 1];
    transform(clockspeed.begin(), clockspeed.end(), clockspeed.begin(), (int(*)(int)) tolower);

    if ((strpos = clockspeed.find("div")) != std::string::npos) {
      clockspeed.erase(strpos, clockspeed.length()-strpos);

      if (!ecmdIsAllDecimal(clockspeed.c_str())) {
        ecmdOutputError("setclockspeed - Non-Decimal characters detected in speed field with 'div' parm\n");
        return ECMD_INVALID_ARGS;
      }
      iv_div = (uint32_t)atoi(clockspeed.c_str());
      if (iv_div==0) {
        ecmdOutputError("setclockspeed - 'div' value cannot equal 0\n");
        return ECMD_INVALID_ARGS;
      }
      // set 'clockspeed' variable back to argv[1], as if another parm was used rather than mult and div
      //  therefore, code after this check will work
      clockspeed = argv[1];

    } else {
      // this is supposed to be 'div'
      ecmdOutputError("setclockspeed - 'div' parm needs to come after 'mult' parm\n");
      ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
      return ECMD_INVALID_ARGS;
    }


  } else {
    ecmdOutputError("setclockspeed - Speed Keyword not found in clock speed field\n");
    ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }
  
  clockspeed.erase(strpos, clockspeed.length()-strpos);
  
  if (!ecmdIsAllDecimal(clockspeed.c_str())) {
    ecmdOutputError("setclockspeed - Non-Decimal characters detected in speed field\n");
    return ECMD_INVALID_ARGS;
  } 
  
  uint32_t speed = (uint32_t)atoi(clockspeed.c_str());

  if (((argc > (endOffet+1)) && (iv_mult==0)) || ((argc > (endOffet+1)) && (iv_mult!=0)))  {
    ecmdOutputError("setclockspeed - Too many arguments specified; you probably added an option that wasn't recognized.\n");
    ecmdOutputError("setclockspeed - Type 'setclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }
  
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;


  while ( ecmdConfigLooperNext(target, looperdata) ) {
    if (iv_mult==0)
      rc = ecmdSetClockSpeed(target, clockType, speed, speedType, clockSetMode, clockRange);
    else 
      rc = ecmdSetClockMultDiv(target, clockType, iv_mult, iv_div);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc) {
        printed = "setclockspeed - Error occured performing setclockspeed on ";
        printed += ecmdWriteTarget(target);
        printed += "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }

    
    printed = ecmdWriteTarget(target);
    printed += "\n";
    ecmdOutput( printed.c_str() );
  }


  if (!validPosFound) {
    //this is an error common across all UI functions
    ecmdOutputError("setclockspeed - Unable to find a valid chip to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  

  return rc;
}

uint32_t ecmdGetClockSpeedUser(int argc, char* argv[]) {
  uint32_t rc = ECMD_SUCCESS;
  
  ecmdChipTarget target;                        ///< Current target being operated on
  bool validPosFound = false;                   ///< Did the looper find anything?
  ecmdLooperData looperdata;                    ///< Store internal Looper data
  std::string printed;                          ///< Output data
  ecmdClockSpeedType_t speedType;               ///< Clock speed type - frequency or cycle time
  ecmdClockType_t clockType;                    ///< the clock type to change the speed on
  std::string outputformat = "d";               ///< Output Format to display
  uint32_t speed;                               ///< The speed return value
  ecmdDataBuffer buffer(32);

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/

  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;


  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  if (argc < 2) {  //clocktype + speed
    ecmdOutputError("getclockspeed - Too few arguments specified; you need at least a clocktype and speed.\n");
    ecmdOutputError("getclockspeed - Type 'getclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }
  if (argc > 2) {
    ecmdOutputError("getclockspeed - Too many arguments specified; you need only a clocktype and speed.\n");
    ecmdOutputError("getclockspeed - Type 'getclockspeed -h' for usage.\n");
    return ECMD_INVALID_ARGS;
  }

  //Setup the target that will be used to query the system config 
  target.chipType = ECMD_CHIPT_PROCESSOR;
  target.chipTypeState = ECMD_TARGET_FIELD_VALID;
  target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
  target.coreState = target.threadState = ECMD_TARGET_FIELD_UNUSED;

  //Get the clock type
  std::string clocktype = argv[0];
  transform(clocktype.begin(), clocktype.end(), clocktype.begin(), (int(*)(int)) tolower);
  if (clocktype == "pu_refclock") {
    clockType = ECMD_PROC_REFCLOCK;
  } else if (clocktype == "memctrl_refclock") {
    clockType = ECMD_MEMCTRL_REFCLOCK;
  } else if (clocktype == "pu_coreclock") {
    clockType = ECMD_PROC_CORE_CLOCK;
  } else if (clocktype == "pu_nestclock") {
    clockType = ECMD_PROC_NEST_CLOCK;
  } else if (clocktype == "memctrl_clock") {
    clockType = ECMD_MEMCTRL_CLOCK;
  } else if (clocktype == "io_refclock") {
    clockType = ECMD_IO_REFCLOCK;
  } else if (clocktype == "io_clock") {
    clockType = ECMD_IO_CLOCK;
  } else {
    ecmdOutputError("getclockspeed - Unrecognized clocktype! 'getclockspeed -h' for recognized types.\n");
    return ECMD_INVALID_ARGS;
  }
  
  //get clockspeed
  std::string clockspeed = argv[1];
  transform(clockspeed.begin(), clockspeed.end(), clockspeed.begin(), (int(*)(int)) tolower);
  
  if (clockspeed == "mhz")  {
    speedType = ECMD_CLOCK_FREQUENCY_SPEC;
  } else if (clockspeed == "us") {
    speedType = ECMD_CLOCK_CYCLETIME_SPEC;
  } else {
    ecmdOutputError("getclockspeed - keyword \"mhz\" or \"us\" not found in clock speed field\n");
    return ECMD_INVALID_ARGS;
  }
  
  
  /************************************************************************/
  /* Kickoff Looping Stuff                                                */
  /************************************************************************/

  rc = ecmdConfigLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;


  while ( ecmdConfigLooperNext(target, looperdata) ) {
    rc = ecmdGetClockSpeed(target, clockType, speedType, speed);
    if (rc == ECMD_TARGET_NOT_CONFIGURED) {
      continue;
    }
    else if (rc) {
        printed = "getclockspeed - Error occured performing getclockspeed on ";
        printed += ecmdWriteTarget(target);
        printed += "\n";
        ecmdOutputError( printed.c_str() );
        return rc;
    }
    else {
      validPosFound = true;     
    }

    buffer.setWord(0, speed);
    printed = ecmdWriteTarget(target);
    printed += ecmdWriteDataFormatted(buffer, outputformat);
    ecmdOutput( printed.c_str() );
  }


  if (!validPosFound) {
    //this is an error common across all UI functions
    ecmdOutputError("getclockspeed - Unable to find a valid chip to execute command on\n");
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  

  return rc;
}
#endif // ECMD_REMOVE_REFCLOCK_FUNCTIONS

// Change Log *********************************************************
//                                                                      
//  Flag Reason   Vers Date     Coder    Description                       
//  ---- -------- ---- -------- -------- ------------------------------   
//                              CENGEL   Initial Creation
//  @00  D546069       11/03/06 honi     setclockspeed cpu/cpd change
//
// End Change Log *****************************************************

{'fraction_non_alphanumeric': 0.21267824559032236, 'fraction_numerical': 0.005034804352233561, 'mean_word_length': 2.3075719474713607, 'pattern_counts': {'":': 0, '<': 114, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 88, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2716602', 'n_tokens_mistral': 17278, 'n_tokens_neox': 16604, 'n_words': 4116}