// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: cpu_interface.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
////////////////////////////////////////////////////////////
// File: cpu_interface.cc
// Copyright (C) 2005 Sun Microsystems, Inc.
#include "blaze_globals.h"
#include "cpu_interface.h"
#include "command_opts.h"
// This file implements C++ interface for the
void *cpu_lib_handle
= NULL
;
char cpu_lib_name
[160] = "lib.unknown.cpu.type";
int g_nvcpu
= 0; // total number of vcpu's
int g_vcpu_id_max
= 0; // max id of the vcpu
VCPU_ExInterface g_cpu_ex_intf
;
extern int pselect_cpu_id
;
#define CPU_TYPE "cpu-type"
#define MMU_TYPE "mmu-type"
#define DTLB_SIZE "dtlb-entries"
#define ITLB_SIZE "itlb-entries"
#define CLOCK "clock-frequency"
#define SCLOCK "system-frequency"
#define LOOPTICKS "cpu-loopticks"
#define STICKINCR "cpu-stickincr"
#define NWINS "cpu-nwins"
#define TLMAX "cpu-tlmax"
static int pregs_ui_cmd (void *, int argc
, char **argv
);
static int fpregs_ui_cmd (void *, int argc
, char **argv
);
static int cmpregs_ui_cmd (void *, int argc
, char **argv
);
static int read_reg_ui_cmd (void *, int argc
, char **argv
);
static int set_pc_ui_cmd (void *, int argc
, char **argv
);
static int write_reg_ui_cmd (void *, int argc
, char **argv
);
static int regs_ui_cmd (void *, int argc
, char **argv
);
static int pc_ui_cmd (void *, int argc
, char **argv
);
static int cpuregs_ui_cmd (void *, int argc
, char **argv
);
static int pregs_cmd_usage ();
static int fpregs_cmd_usage ();
static int cmpregs_cmd_usage ();
static int read_reg_cmd_usage ();
static int set_pc_cmd_usage ();
static int write_reg_cmd_usage();
static int print_reg_cmd_usage();
static int cpuregs_cmd_usage ();
//////////////////////////////////////////////////////////////
// set configuration parameter
// Configuration informaion is encoded in
char * name_value
, // parameter name=value string
VCPU_Config
*config
// set value in this sructure
char *name
= strtok ( name_value
, " =" );
ui
->error("cannot read cpu param name %s\n", name_value
);
char *param
= strtok ( NULL
, "\0" );
ui
->error("cannot read cpu param value %s\n", name_value
);
if (strcmp ( name
, CPU_TYPE
) == 0 )
config
->type
= strdup ( param
) ;
else if (strcmp ( name
, INST_NAME
) == 0 )
config
->name
= strdup ( param
) ;
else if (strcmp ( name
, MMU_TYPE
) == 0 )
config
->mmu_type
= strdup ( param
) ;
else if (strcmp ( name
, NWINS
) == 0 )
config
->reg_wins
= (int)strtol(param
, NULL
, 0);
else if (strcmp ( name
, TLMAX
) == 0 )
config
->tl_max
= (int)strtol(param
, NULL
, 0);
else if (strcmp ( name
, DTLB_SIZE
) == 0 )
config
->dtlb_size
= (int)strtol(param
, NULL
, 0);
else if (strcmp ( name
, ITLB_SIZE
) == 0 )
config
->itlb_size
= (int)strtol(param
, NULL
, 0);
else if (strcmp ( name
, CLOCK
) == 0 )
config
->cpufreq
= (unsigned long long)strtoull(param
, NULL
, 0);
else if (strcmp ( name
, SCLOCK
) == 0 )
ui
->warning("param %s %s is not supported \n", name
, param
);
else if (strcmp ( name
, STICKINCR
) == 0 )
config
->stickincr
= (int)strtol(param
, NULL
, 0);
else if (strcmp ( name
, LOOPTICKS
) == 0 )
config
->loopticks
= (int)strtol(param
, NULL
, 0);
else if(strcmp(name
,CPU_ID
) == 0)
config
->id
= (int)strtol(param
,NULL
,0);
if (config
->id
>= NCPU_MAX
)
ui
->error("cpu id %d cannot exceed %d\n", config
->id
, NCPU_MAX
);
ui
->error("unknown cpu param: %s\n", name
);
///////////////////////////////////////////////////////////
// get cpu config parameter string based on param name
static char *get_param ( char *name
, VCPU_Config
*config
)
static char param_value
[40];
sprintf ( param_value
, "unknown parameter" );
if (strcmp ( name
, CPU_TYPE
) == 0 )
sprintf ( param_value
, "%s", config
->type
);
else if (strcmp ( name
, INST_NAME
) == 0 )
sprintf ( param_value
, "%s", config
->name
);
else if (strcmp ( name
, MMU_TYPE
) == 0 )
sprintf ( param_value
, "%s", config
->mmu_type
);
else if (strcmp ( name
, NWINS
) == 0 )
sprintf ( param_value
, "%i", config
->reg_wins
);
else if (strcmp ( name
, TLMAX
) == 0 )
sprintf ( param_value
, "%i", config
->tl_max
);
else if (strcmp ( name
, DTLB_SIZE
) == 0 )
sprintf ( param_value
, "%i", config
->dtlb_size
);
else if (strcmp ( name
, ITLB_SIZE
) == 0 )
sprintf ( param_value
, "%i", config
->itlb_size
);
else if (strcmp ( name
, SCLOCK
) == 0 )
sprintf ( param_value
, "%i", config
->stickfreq
);
else if (strcmp ( name
, CLOCK
) == 0 )
sprintf ( param_value
, "%llu", config
->cpufreq
);
else if (strcmp ( name
, STICKINCR
) == 0 )
sprintf ( param_value
, "%i", config
->stickincr
);
else if (strcmp ( name
, LOOPTICKS
) == 0 )
sprintf ( param_value
, "%i", config
->loopticks
);
else if(strcmp(name
,CPU_ID
) == 0)
sprintf ( param_value
, "%i", config
->id
);
void set_default ( VCPU_Config
&config
)
config
.type
= NULL
; //strdup("SUNW,UltraSPARC-II");
config
.cpu_type
= VCPU_IMPL_VER_NONE
; // encoded cpu impl version
config
.reg_wins
= 8; // number of reg windows
config
.tl_max
= 7; // trap level max
config
.itlb_size
= 64; // number of tlb entries
config
.stickincr
= 1; // the amount stick has to be incremented
// a person doing simulation ought to know these values
// have to be initialized in the rc file ... Sreenivas
///* not to break the regression without changes available in rc file
config
.loopticks
= 25; // number of instruction per one update of stick
config
.cpufreq
= 1000000; // cpu clock
config
.stickfreq
= 10000; // system clock
config
.cpi
= 1; // cycles per instruction
config
.delay
= 0; // delay this number of instructions
config
.mode
= 1; // all cpu's on separate threads
config
.trace_on
= 0; // tracing is off
config
.execution_driven
= 0;
//////////////////////////////////////////////////////////////
static int process_config_cmd
char *config_cmd
, // config string: name=value pairs
VCPU_Config
*config
// return config structure
char param_delimiter
[] = " \0";
// make a copy because strtok() will write the termination chars
char *cmd
= strdup ( config_cmd
);
int n_param
= 0; // param counter
char *name_value
= strtok ( cmd
, param_delimiter
);
name_value
= strtok ( NULL
, param_delimiter
)
if ( set_param ( name_value
, config
) != 0 )
ui
->error("cannot set cpu param %s\n", name_value
);
ui
->error("there are no cpu config params\n");
int deprecated_read_cmd (void *, int argc
, char **argv
)
ui
->error("This command is deprecated, use read-reg command instead.\n");
int deprecated_write_cmd (void *, int argc
, char **argv
)
ui
->error("This command is deprecated, use write-reg command instead.\n");
//////////////////////////////////////////////////////////////
// Create a new cpu instance
char *path
, // library path
char *pconfig
, // config line with name=value pairs
VCPU_ImpIntf
*intf
, // cpu imported interface
int version
// cpu lib version number
// process cpu config command
// fill out config_info structure
if ( process_config_cmd (pconfig
, &config_info
) != 0 )
ui
->error("Invalid Cpu config information \n");
return create_cpu ( path
, config_info
, intf
, version
);
char *path
, // library path
VCPU_Config
&config_info
, // cpu config params
VCPU_ImpIntf
*intf
, // cpu imported interface
int version
// cpu lib version number
static bool id_from_sysconf
= true; // expect id from sysconf
if ( config_info
.type
== NULL
)
ui
->error("missing cpu type information \n");
// either id is present on all lines, or its not present on any
// sysconf line. no intermixing is allowed
if(config_info
.id
== -1){
// sid is not provided on sysconf line. assign sid = vid
config_info
.id
= g_nvcpu
;
if(g_nvcpu
== 0) // first vcpu
ui
->error("cpu id is being assigned implicitly. sysconf file error\n");
ui
->error("cpu id missing. sysconf file error\n");
if (!cpu_lib_handle
) // first cpu
// register cpu related ui commands
UI_register_cmd_2 ("cpuregs", "print cpu register names", cpuregs_ui_cmd
, cpuregs_cmd_usage
);
UI_register_cmd_2 ("pregs", "print cpu architecture registers", pregs_ui_cmd
, pregs_cmd_usage
);
UI_register_cmd_2 ("fpregs", "print floating-point registers", fpregs_ui_cmd
, fpregs_cmd_usage
);
UI_register_cmd_2 ("cmpregs", "print cmp registers", cmpregs_ui_cmd
, cmpregs_cmd_usage
);
UI_register_cmd_2 ("read-reg", "read a register by name", read_reg_ui_cmd
, read_reg_cmd_usage
);
UI_register_cmd_2 ("write-reg","write value to a register", write_reg_ui_cmd
, write_reg_cmd_usage
);
UI_register_cmd_2 ("set-pc", "set pc for current cpu", set_pc_ui_cmd
, set_pc_cmd_usage
);
UI_register_cmd_2 ("pc", "print current pc for all cpus", pc_ui_cmd
, NULL
);
UI_register_cmd_2 ("r", "print cpu regs", regs_ui_cmd
, print_reg_cmd_usage
);
UI_register_cmd_2 ("read-fp-reg-i", "print floating point single register as integer", deprecated_read_cmd
, NULL
);
UI_register_cmd_2 ("read-fp-reg-x", "print floating point double register as integer", deprecated_read_cmd
, NULL
);
UI_register_cmd_2 ("read-th-ctl-reg", "print a control register value of a strand" , deprecated_read_cmd
, NULL
);
UI_register_cmd_2 ("read-th-fp-reg-i", "print a single fp register value of a strand" , deprecated_read_cmd
, NULL
);
UI_register_cmd_2 ("read-th-fp-reg-x", "print a double fp register value of a strand" , deprecated_read_cmd
, NULL
);
UI_register_cmd_2 ("read-th-reg", "print an integer register value of a strand" , deprecated_read_cmd
, NULL
);
UI_register_cmd_2 ("write-fp-reg-i", "write floating point single register as integer", deprecated_write_cmd
, NULL
);
UI_register_cmd_2 ("write-fp-reg-x", "write floating point double register as integer", deprecated_write_cmd
, NULL
);
UI_register_cmd_2 ("write-th-ctl-reg", "write a control register value of a strand" , deprecated_write_cmd
, NULL
);
UI_register_cmd_2 ("write-th-fp-reg-i","write floating point single register as integer", deprecated_write_cmd
, NULL
);
UI_register_cmd_2 ("write-th-fp-reg-x","write double fp register value of a strand" , deprecated_write_cmd
, NULL
);
UI_register_cmd_2 ("write-th-reg", "write integer register value of a strand" , deprecated_write_cmd
, NULL
);
// generate cpu library name from the config info
sprintf(lib_name
,"lib%s.so", config_info
.type
);
if (strcmp(lib_name
, cpu_lib_name
)!=0) // library was not loaded yet
extern void * mod_dlopen (char * pathp
, char * name
, int flags
);
cpu_lib_handle
= mod_dlopen (path
, lib_name
, RTLD_LAZY
|RTLD_GLOBAL
|RTLD_PARENT
);
// remember last opened cpu library
strlcpy ( cpu_lib_name
, lib_name
, 160 );
if ( cpu_lib_handle
== NULL
)
ui
->error("Cannot find cpu library %s \n", lib_name
);
// extract lib exported interface
VCPU_GetIntfFn get_interface
= (VCPU_GetIntfFn
)dlsym ( cpu_lib_handle
, "get_ex_interface" );
if (get_interface
== NULL
)
ui
->error("Cannot find cpu exported interface \n");
get_interface ( &g_cpu_ex_intf
);
Vcpu
* vcpu
= (Vcpu
*)g_cpu_ex_intf
.create( &config_info
, intf
);
ui
->error("Cannot create Cpu %s \n", config_info
.name
);
int sid
= vcpu
->config
.id
;
// total number of vcpu's
// cofiguration parameters
int set_param ( int cpu_id
, char *param_name
)
Vcpu
*vcpu
= get_vcpu(cpu_id
);
return set_param (param_name
, &(vcpu
->config
));
char *get_param ( int cpu_id
, char *param_name
)
Vcpu
*vcpu
= get_vcpu(cpu_id
);
return get_param (param_name
, &(vcpu
->config
));
// set a breakpoint from a remote debugger
int cpu_set_breakpoint ( int cpu_id
, VCPU_BpType type
, uint64_t addr
)
extern int bp_action ( int bp_id
, int vcpu_id
);
Vcpu
* vcpu
= get_vcpu(cpu_id
);
return vcpu
->set_breakpoint( &bp_id
,type
, addr
, bp_action
);
int cpu_remove_breakpoint ( int cpu_id
, VCPU_BpType type
, uint64_t addr
)
Vcpu
* vcpu
= get_vcpu(cpu_id
);
return vcpu
->delete_breakpoint();
/////////////////////////////////////////////////////////
// Disassemble instruction
int disassemble (uint32_t iw
, uint64_t pc
, char *buf
, int size
)
! spix_sparc_dis( buf
, size
,
spix_sparc_iop(SPIX_SPARC_V9
, &iw
),
sprintf ( buf
, "unknown" );
///////////////////////////////////////////////////////
// Read vcpu regs from the ui
int print_reg_cmd_usage()
ui
->output("usage: r [-cpu <id>] [-w [<wp>]|-g [<gwp>]|-f|df|-pr|-asr|-hpr|-tr <tr_level>|-asi <asi> <va>]\n");
int regs_ui_cmd (void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
for(int i
=1; i
<argc
; i
++)
if (strcmp(argv
[i
], "-w")==0)
if (((i
+1)<argc
) && isdigit(argv
[i
+1][0]))
wp
= int(strtol(argv
[++i
], NULL
, 0));
else if (strcmp(argv
[i
], "-g")==0)
if ( ((i
+1)<argc
) && isdigit(argv
[i
+1][0]) )
gl
= int(strtol(argv
[++i
], NULL
, 0));
else if (strcmp(argv
[i
], "-f")==0) freg
= 1;
else if (strcmp(argv
[i
], "-df")==0) dfreg
= 1;
else if (strcmp(argv
[i
], "-pr")==0) pr
= 1;
else if (strcmp(argv
[i
], "-asr")==0) asr
= 1;
else if (strcmp(argv
[i
], "-hpr")==0) hpr
= 1;
else if ((strcmp(argv
[i
], "-asi")==0) && ((i
+2)<argc
))
asi_i
= uint8_t(strtol(argv
[++i
], NULL
, 0));
asi_va
= strtoll(argv
[++i
], NULL
, 0);
else if ((strcmp(argv
[i
], "-tr")==0) && ((i
+1)<argc
))
tl
= int(strtol(argv
[++i
], NULL
, 0));
else if ((strcmp(argv
[i
], "-cpu")==0) && ((i
+1)<argc
))
cpuid
= int(strtol(argv
[++i
], NULL
, 0));
ui
->error("cpu[%d] is not available\n",cpuid
);
else if (strcmp(argv
[i
], "?")==0)
if (!( greg
||wreg
||freg
||dfreg
||pr
||asr
||hpr
||tr
|asi
) )
return print_reg_cmd_usage();
if(!cpu
) // no cpu id was selected
cpu
= get_vcpu(pselect_cpu_id
);
ui
->error("cpu[%d] is not available\n",cpuid
);
ui
->output ( "cpu[%i]:",cpuid
);
ui
->output ("asi 0x%x, va=0x%llx, ", asi_i
, asi_va
);
if (cpu
->get_asi(asi_i
, asi_va
, value
) == 0)
ui
->output ("value = 0x%llx \n", value
);
ui
->error ("unknown \n");
cpu
->get_reg(VCPU_SIM_MAX_WP
,&max_wp
);
cpu
->get_reg(VCPU_PR_CWP
,&cur_wp
);
ui
->output ( "\nwindowed R registers,");
ui
->output (" wp=%d (current)\n",wp
);
ui
->output (" wp=%d\n", wp
);
cpu
->set_reg(VCPU_PR_CWP
,wp
);
cpu
->get_reg(VCPU_IRF_0
+ i
+ 8, &value
); // o regs
ui
->output ("%s=0x%016llx ", cpu
->get_reg_name(VCPU_IRF_0
+ i
+ 8), value
);
cpu
->get_reg(VCPU_IRF_0
+ i
+ 16, &value
); // l regs
ui
->output ("%s=0x%016llx ", cpu
->get_reg_name(VCPU_IRF_0
+ i
+ 16), value
);
cpu
->get_reg(VCPU_IRF_0
+ i
+ 24, &value
); // i regs
ui
->output ("%s=0x%016llx\n", cpu
->get_reg_name(VCPU_IRF_0
+ i
+ 24), value
);
cpu
->set_reg(VCPU_PR_CWP
,cur_wp
);
cpu
->get_reg(VCPU_SIM_MAX_GL
,&max_gl
);
cpu
->get_reg(VCPU_PR_GL
,&cur_gl
);
ui
->output ( "\nglobal R registers,");
ui
->output (" gl=%d (current)\n",gl
);
ui
->output (" gl=%d\n", gl
);
cpu
->set_reg(VCPU_PR_GL
,gl
);
cpu
->get_reg(VCPU_IRF_0
+ i
, &value
);
ui
->output ("%s=0x%016llx\n", cpu
->get_reg_name(VCPU_IRF_0
+ i
), value
);
cpu
->set_reg(VCPU_PR_GL
,cur_gl
);
ui
->output ( "\nfloating point registers\n");
cpu
->get_reg(VCPU_FRF_0
+ i
, &value
);
uint32_t val32
= uint32(value
);
ui
->output ( "f%-2i = %e\n", i
, val32
);
ui
->output ( "\ndouble floating point registers\n");
for (int i
=0; i
<63; i
+=2)
if (cpu
->get_reg(VCPU_DRF_0
+ i
/2, &value
) == 0)
ui
->output ( "d%-2i = %e\n", i
, value
);
ui
->output ( "\nPR registers\n");
if (cpu
->get_reg(VCPU_PR_0
+ i
, &value
) == Vcpu::REG_OK
)
ui
->output ( "pr%-2d %16s = 0x%llx\n", i
, cpu
->get_reg_name(VCPU_PR_0
+ i
), value
);
ui
->output ( "\nASR registers\n");
if (cpu
->get_reg(VCPU_ASR_0
+ i
, &value
) == Vcpu::REG_OK
)
ui
->output ( "asr%-2d %16s = 0x%llx\n", i
, cpu
->get_reg_name(VCPU_ASR_0
+ i
), value
);
ui
->output ( "\nHPR registers\n");
if (cpu
->get_reg(VCPU_HPR_0
+ i
, &value
) == Vcpu::REG_OK
)
ui
->output ( "hpr%-2d %16s = 0x%llx\n", i
, cpu
->get_reg_name(VCPU_HPR_0
+ i
), value
);
cpu
->get_reg(VCPU_SIM_MAX_TL
,&max_tl
);
cpu
->get_reg(VCPU_PR_TL
,&cur_tl
);
ui
->output ( "\ntrap registers, tl=%i\n", tl
);
ui
->output (" tl=%d (current)\n",tl
);
ui
->output (" tl=%d\n", tl
);
cpu
->set_reg(VCPU_PR_TL
,tl
);
cpu
->get_reg(VCPU_PR_TPC
,&value
);
ui
->output ( "tpc = 0x%llx\n", value
);
cpu
->get_reg(VCPU_PR_TNPC
,&value
);
ui
->output ( "tnpc = 0x%llx\n", value
);
cpu
->get_reg(VCPU_PR_TSTATE
,&value
);
ui
->output ( "tstate = 0x%llx\n", value
);
cpu
->get_reg(VCPU_PR_TT
,&value
);
ui
->output ( "tt = 0x%llx\n", value
);
if (cpu
->get_reg(VCPU_HPR_HTSTATE
,&value
) == Vcpu::REG_OK
)
ui
->output ( "htstate = 0x%llx\n", value
);
cpu
->set_reg(VCPU_PR_TL
,cur_tl
);
///////////////////////////////////////////////////////
// single step one vcpu only
int sstep_cmd (int cpu_id
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
Vcpu
*vcpu
= get_vcpu(cpu_id
);
/////////////////////////////////////////////////////////////////////
int pc_ui_cmd (void *, int argc
, char **argv
)
for (int i
=0; i
<=g_vcpu_id_max
; i
++)
Vcpu
*vcpu
= get_vcpu(i
);
vcpu
->get_reg(VCPU_ASR_PC
, &pc
);
ui
->output ("cpu[%i]: pc=0x%llx \n", i
, pc
);
////////////////////////////////////////////////////////////////////////
int cpu_read_register_name ( char *cmd
)
if (!IN_STOP_STATE(blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
Vcpu
* vcpu
= g_vcpu
[pselect_cpu_id
];
ui
->error("cpu[%d] is not available\n", pselect_cpu_id
);
const int max_reg_name
= 128;
char reg_name
[max_reg_name
];
strlcpy(reg_name
, cmd
, max_reg_name
);
char *name
= strtok ( reg_name
, " \n\0" );
char *parm
= strtok ( NULL
, " \n\0" );
ui
->error("\nusage: %%reg_name , to list register names use 'cpuregs' command\n");
if ( (vcpu
->get_reg_index( reg_name
, &index
)==Vcpu::REG_OK
) &&
(vcpu
->get_reg( index
, &value
)==Vcpu::REG_OK
))
ui
->output("0x%llx\n", value
);
ui
->error("cpu[%d] register %s is not available\n", pselect_cpu_id
, reg_name
);
////////////////////////////////////////////////////////////
ui
->output("\nusage : pregs [-cpu cpu_set]]\n");
int pregs_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
CpuOption
cpu_option(pselect_cpu_id
,CpuOption::MULTITUDE
);
std::vector
<std::string
> args
;
if (!option
.parse(argc
-1,(const char**)&argv
[1],args
))
ui
->error("%s command parsing failed: %s\n",cmd
,option
.get_error_msg().c_str());
return pregs_cmd_usage();
CpuSet
& cpu_set
= cpu_option
.get_value();
for (CpuSet::iterator i
=cpu_set
.begin(); i
!= cpu_set
.end(); ++i
)
ui
->output("cpu[%d]: \n",cpu_id
);
Vcpu
* vcpu
= g_vcpu
[cpu_id
];
ui
->error("cpu[%d] is not available\n", cpu_id
);
if (vcpu
->get_reg(VCPU_PR_0
+ i
, &value
) == Vcpu::REG_OK
)
ui
->output ( "pr%3d %16s = 0x%llx\n", i
, vcpu
->get_reg_name(VCPU_PR_0
+ i
), value
);
if (vcpu
->get_reg(VCPU_ASR_0
+ i
, &value
) == Vcpu::REG_OK
)
ui
->output ( "asr%2d %16s = 0x%llx\n", i
, vcpu
->get_reg_name(VCPU_ASR_0
+ i
), value
);
if (vcpu
->get_reg(VCPU_HPR_0
+ i
, &value
) == Vcpu::REG_OK
)
ui
->output ( "hpr%2d %16s = 0x%llx\n", i
, vcpu
->get_reg_name(VCPU_HPR_0
+ i
), value
);
/////////////////////////////////////////////////////////////
ui
->error("\nusage : fpregs [-cpu cpu_set]]\n");
int fpregs_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
CpuOption
cpu_option(pselect_cpu_id
,CpuOption::MULTITUDE
);
std::vector
<std::string
> args
;
if (!option
.parse(argc
-1,(const char**)&argv
[1],args
))
ui
->error("%s command parsing failed: %s\n",cmd
,option
.get_error_msg().c_str());
return fpregs_cmd_usage();
CpuSet
& cpu_set
= cpu_option
.get_value();
for (CpuSet::iterator i
=cpu_set
.begin(); i
!= cpu_set
.end(); ++i
)
Vcpu
* vcpu
= g_vcpu
[cpu_id
];
ui
->error("cpu[%d] is not available\n", cpu_id
);
ui
->output("cpu[%d]: ",cpu_id
);
if ( (vcpu
->get_reg_index( fsr
, &index
)==Vcpu::REG_OK
) &&
(vcpu
->get_reg( index
, &value
)==Vcpu::REG_OK
))
ui
->output("%s=0x%llx\n",fsr
, value
);
for (int i
=0; i
<63; i
+=2)
if (vcpu
->get_reg(VCPU_DRF_0
+ i
/2, &value
) == 0)
ui
->output ( "d%-2i=0x%016llx ", i
, value
);
ui
->output ( "f%-2i=0x%08llx f%-2i=0x%08llx\n", i
, uint32(value
), i
+1, uint32(value
>>32));
/////////////////////////////////////////////////////////////
ui
->error("\nusage : cmpregs [-cpu cpu_set]]\n");
int cmpregs_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE(blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
CpuOption
cpu_option(pselect_cpu_id
,CpuOption::MULTITUDE
);
std::vector
<std::string
> args
;
if (!option
.parse(argc
-1,(const char**)&argv
[1],args
))
ui
->error("%s command: %s\n",cmd
,option
.get_error_msg().c_str());
return cmpregs_cmd_usage();
CpuSet
& cpu_set
= cpu_option
.get_value();
for (CpuSet::iterator i
=cpu_set
.begin(); i
!= cpu_set
.end(); ++i
)
ui
->output("cpu[%d]: \n",cpu_id
);
Vcpu
* vcpu
= g_vcpu
[cpu_id
];
ui
->error("cpu %d is not available\n", cpu_id
);
if (vcpu
->get_asi(0x41, 0x0 , value
) == 0) ui
->output ("STRAND_AVAILABLE 0x%016llx \n", value
);
if (vcpu
->get_asi(0x41, 0x10, value
) == 0) ui
->output ("STRAND_ENABLE_STATUS 0x%016llx \n", value
);
if (vcpu
->get_asi(0x41, 0x20, value
) == 0) ui
->output ("STRAND_ENABLE 0x%016llx \n", value
);
if (vcpu
->get_asi(0x41, 0x30, value
) == 0) ui
->output ("XIR_STEERING 0x%016llx \n", value
);
if (vcpu
->get_asi(0x41, 0x38, value
) == 0) ui
->output ("CMT_TICK_ENABLE 0x%016llx \n", value
);
if (vcpu
->get_asi(0x41, 0x50, value
) == 0) ui
->output ("STRAND_RUNNING 0x%016llx \n", value
);
if (vcpu
->get_asi(0x41, 0x58, value
) == 0) ui
->output ("STRAND_RUNNING_STATUS 0x%016llx \n", value
);
//////////////////////////////////////////////////
ui
->error("\nusage : cpuregs \n");
int cpuregs_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
Vcpu
* vcpu
= g_vcpu
[pselect_cpu_id
];
ui
->error("cpu %d is not available\n", pselect_cpu_id
);
for (int i
=0; i
<=VCPU_MAX_INDEX
;i
++)
const char *reg_name
= vcpu
->get_reg_name(i
);
ui
->output("%3d) %s\n", i
, reg_name
);
//////////////////////////////////////////////////
ui
->error("\nusage : read-reg [-cpu cpu_set] reg-name\n");
int read_reg_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
CpuOption
cpu_option(pselect_cpu_id
,CpuOption::MULTITUDE
);
std::vector
<std::string
> args
;
if (!option
.parse(argc
-1,(const char**)&argv
[1],args
))
ui
->error("%s command parsing failed: %s\n",cmd
,option
.get_error_msg().c_str());
ui
->error("%s requires 1 positional argument - register name.\n",cmd
);
CpuSet
& cpu_set
= cpu_option
.get_value();
for (CpuSet::iterator i
=cpu_set
.begin(); i
!= cpu_set
.end(); ++i
)
Vcpu
* vcpu
= g_vcpu
[cpu_id
];
ui
->error("cpu[%d] is not available\n", cpu_id
);
const char *reg_name
= args
[0].c_str();
if ( (vcpu
->get_reg_index( reg_name
, &index
)==Vcpu::REG_OK
) &&
(vcpu
->get_reg( index
, &value
)==Vcpu::REG_OK
))
ui
->output("cpu[%d]: %s=0x%llx\n",cpu_id
, reg_name
, value
);
ui
->error("cpu[%d] - register %s is not available\n", cpu_id
, reg_name
);
//////////////////////////////////////////////////
ui
->error("\nusage : set-pc address\n");
int set_pc_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
CpuOption
cpu_option(pselect_cpu_id
);
std::vector
<std::string
> args
;
if (!option
.parse(argc
-1,(const char**)&argv
[1],args
))
ui
->error("%s command parsing failed: %s\n",cmd
,option
.get_error_msg().c_str());
ui
->error("%s requires 1 positional argument - pc value.\n",cmd
);
uint32_t cpu_id
= *(cpu_option
.get_value().begin());
Vcpu
* vcpu
= g_vcpu
[cpu_id
];
ui
->error("cpu[%d] is not available\n", cpu_id
);
uint64_t value
= strtoull(args
[0].c_str(), NULL
, 0);
if ( vcpu
->set_reg( VCPU_ASR_PC
, value
)!=Vcpu::REG_OK
)
ui
->error(" cannot set pc value 0x%llx for cpu[%d]\n",value
,cpu_id
);
//////////////////////////////////////////////////
int write_reg_cmd_usage()
ui
->output("\nusage : write-reg [-cpu cpu_set] reg-name value\n");
int write_reg_ui_cmd(void *, int argc
, char **argv
)
if (!IN_STOP_STATE (blaze_run_state
))
ui
->error("not in stop state, use stop command first\n");
CpuOption
cpu_option(pselect_cpu_id
);
std::vector
<std::string
> args
;
if (!option
.parse(argc
-1,(const char**)&argv
[1],args
))
ui
->error("%s command parsing failed: %s\n",cmd
,option
.get_error_msg().c_str());
ui
->error("%s requires 2 positional argument - reg name and value.\n",cmd
);
uint32_t cpu_id
= *(cpu_option
.get_value().begin());
Vcpu
* vcpu
= g_vcpu
[cpu_id
];
ui
->error("cpu[%d] is not available\n", cpu_id
);
uint64_t value
= strtoull(args
[1].c_str(), NULL
, 0);
const char *reg_name
= args
[0].c_str();
if ( (vcpu
->get_reg_index( reg_name
, &index
)!=Vcpu::REG_OK
) ||
(vcpu
->set_reg( index
, value
) !=Vcpu::REG_OK
) )
ui
->error("cannot set reg %s=0x%llx for cpu[%d]\n",reg_name
,value
,cpu_id
);