freg
=re
.compile('^f[0-9]$|^f[1-5][0-9]$|^f6[0-3]$')
greg
= re
.compile('^g[0-7]$')
wreg
= re
.compile('^[ilo][0-7]$')
class AsiStateError(Exception):
def __init__(self
,asi
,va
):
return "The strand has no mapping for: asi="+hex(self
.asi
)+" va="+hex(self
.va
)
def __init__(self
,asi
,va
):
data
= strand
.get_asi(self
.asi
,self
.va
)
if strand
.asi_error
!= 0:
raise AsiStateError(self
.asi
,self
.va
)
def set(self
,strand
,data
):
strand
.set_asi(self
.asi
,self
.va
,data
)
if strand
.asi_error
!= 0:
raise AsiStateError(self
.asi
,self
.va
)
return lambda strand
: strand
.get_reg(index
)
return lambda strand
,value
: strand
.set_reg(index
,value
)
def __getreg_tl__(index
):
return lambda strand
,tl
: strand
.get_reg_tl(tl
,index
)
def __setreg_tl__(index
):
return lambda strand
,tl
,value
: strand
.set_reg_tl(tl
,index
,value
)
def __getreg_gl__(index
):
return lambda strand
,gl
: strand
.get_reg_gl(gl
,index
)
def __setreg_gl__(index
):
return lambda strand
,gl
,value
: strand
.set_reg_gl(gl
,index
,value
)
def __getreg_wp__(index
):
return lambda strand
,wp
: strand
.get_reg_wp(wp
,index
)
def __setreg_wp__(index
):
return lambda strand
,wp
,value
: strand
.set_reg_wp(wp
,index
,value
)
# Good old Python is a little sick. The Py_BuildValue api routine
# does not treat uint64_t as unsigned and converts the unsigned value
# to an signed value. The abs64 function below fixes this problem.
# Currently the onlu code using By_BuildValue with K format is SS_PythonTracer
return 0x10000000000000000 + x
def __init__(self
,strand
,tracer
):
self
.__vonk
__ = strand
.__vonk
__
self
.opt_exe_instr
= False
self
.opt_reg_value
= False
self
.trc_connected
= False
# output in n2 sas.log format
def set_format(self
,format
=None):
elif type(format
) == bool:
if self
.opt_exe_instr
or self
.opt_reg_value
or self
.opt_trap
or self
.opt_mem_access
or self
.opt_tlb_update
:
if not self
.trc_connected
:
self
.strand
.__strand
__.add_tracer(self
.__tracer
__)
self
.trc_connected
= True
self
.strand
.__strand
__.del_tracer(self
.__tracer
__)
self
.trc_connected
= False
def exe_instr(self
,on
=None):
return self
.opt_exe_instr
self
.__tracer
__.set_exe_instr(self
.trc_exe_instr
)
self
.__tracer
__.set_exe_instr(self
.trc_exe_instr_n2
)
self
.__tracer
__.clr_exe_instr()
def trc_exe_instr(self
,pc
,tte
,i
):
opc
= self
.__vonk
__.ss_instr(i
).get_opc() & 0xffffffffL
pa
= self
.__vonk
__.ss_tte(tte
).trans(pc
)
str = self
.__vonk
__.dis(opc
,pc
)
print "%d:" % self
.strand
.strand_id
,pc
,':',pa
,"[0x%08x] %s" % (opc
,str)
def trc_exe_instr_n2(self
,pc
,tte
,i
):
# the function is embedded in SS_PliSocket.cc so that we have consistent
# content in sas.log and vcs.log
def reg_value(self
,on
=None):
return self
.opt_reg_value
self
.__tracer
__.set_reg_value(self
.trc_reg_value
)
self
.__tracer
__.set_reg_value(self
.trc_reg_value_n2
)
self
.__tracer
__.clr_reg_value()
def trc_reg_value(self
,index
,value
):
if index
>= self
.__vonk
__.SS_Registers
.ALIAS_END
:
reg
= self
.strand
.__vonk
__.SS_Registers
.get_alias_name(index
)
if self
.state
.has_key(index
):
print "%d:\t%s:" % (self
.strand
.strand_id
,reg
),self
.state
[index
],"->",value
print "%d:\t%s: None ->" % (self
.strand
.strand_id
,reg
),value
self
.state
[index
] = value
def trc_reg_value_n2(self
,index
,value
):
# the function is embedded in SS_PliSocket.cc so that we have consistent
# content in sas.log and vcs.log
self
.__tracer
__.set_trap(self
.trc_trap
)
self
.__tracer
__.clr_trap()
def trc_trap(self
,type,mode
,addr
):
if mode
== self
.__tracer
__.TRAP
:
print "%d: 0x%x trap: 0x%x" % (self
.strand
.strand_id
,self
.strand
.pc
,type)
elif mode
== self
.__tracer
__.INST_TRAP
:
print "%d: 0x%x trap: 0x%x inst mmu pc=0x%x" % (self
.strand
.strand_id
,self
.strand
.pc
,type,addr
)
elif mode
== self
.__tracer
__.DATA_TRAP
:
print "%d: 0x%x trap: 0x%x data mmu ea=0x%x" % (self
.strand
.strand_id
,self
.strand
.pc
,type,addr
)
def mem_access(self
,on
=None):
return self
.opt_mem_access
self
.opt_mem_access
= self
.MEM_CODE | self
.MEM_DATA
if (self
.opt_mem_access
& (self
.MEM_CODE | self
.MEM_DATA
)) != 0:
self
.__tracer
__.set_mem_access(self
.trc_mem_access
)
self
.__tracer
__.clr_mem_access()
def trc_mem_access(self
,type,va
,tte
,size
,data
):
pa
= self
.__vonk
__.ss_tte(tte
).trans(va
)
if type == self
.__tracer
__.LD_CODE
:
if (self
.opt_mem_access
& self
.MEM_CODE
) == 0:
elif (self
.opt_mem_access
& self
.MEM_DATA
) == 0:
elif type == self
.__tracer
__.LD_DATA
:
elif type == self
.__tracer
__.ST_DATA
:
elif type == self
.__tracer
__.ST_PART
:
elif type == self
.__tracer
__.ST_SWAP
:
elif type == self
.__tracer
__.LD_SWAP
:
elif type == self
.__tracer
__.ST_CAS
:
elif type == self
.__tracer
__.LD_CAS
:
elif type == self
.__tracer
__.ST_LDST
:
elif type == self
.__tracer
__.LD_LDST
:
# ToDo need unsigned python function
print '%d: 0x%016x : 0x%015x %s%d' % (self
.strand
.strand_id
,va
,pa
,op
,size
),data
def tlb_update(self
,on
=None):
0 - tlb update traceing disable
1 - tlb insert traceing enable
2 - tlb remove traceing enable
3 - tlb update traceing enable
return self
.opt_tlb_update
self
.opt_tlb_update
= self
.TLB_INSERT | self
.TLB_REMOVE
if (self
.opt_tlb_update
& (self
.TLB_INSERT | self
.TLB_REMOVE
)) != 0:
self
.__tracer
__.set_tlb_update(self
.trc_tlb_update
)
self
.__tracer
__.clr_tlb_update()
def trc_tlb__fun__(self
,tte
):
def trc_tlb_update(self
,insert
,tlb
,index
,tte
):
tte
= Pfe_Tlb
.TlbTte(None,self
.trc_tlb__fun__
,self
.__vonk
__.ss_tte(tte
))
ss_tlb
= self
.__vonk
__.ss_tlb(tlb
)
if not ss_tlb
.is_inst_tlb():
type = 'tlb.d%02x' % ss_tlb
.tlb_id()
elif not ss_tlb
.is_data_tlb():
type = 'tlb.i%02x' % ss_tlb
.tlb_id()
type = 'tlb.u%02x' % ss_tlb
.tlb_id()
if (self
.opt_tlb_update
& self
.TLB_INSERT
) != 0:
print "%s: insert %03x: %s" % (type,index
,str(tte
))
if (self
.opt_tlb_update
& self
.TLB_REMOVE
) != 0:
print "%s: remove %03x: %s" % (type,index
,str(tte
))
class Strand(Pfe_Strand
.Strand
):
def __init__(self
,strand
,ref
,vonk
):
Pfe_Strand
.Strand
.__init
__(self
,strand
,ref
)
self
.__dict
__['__asierr__'] = vonk
.SS_AsiSpace
self
.__dict
__['__vonk__'] = vonk
self
.brk
= BreakDict(strand
,vonk
)
self
.__dict
__['trc'] = Tracer(self
,vonk
.SS_PythonTracer())
if Strand
.__first
_strand
__:
Strand
.__first
_strand
__ = False
__getfun__
= Pfe_Strand
.Strand
.__getfun
__
__setfun__
= Pfe_Strand
.Strand
.__setfun
__
for index
in range(vonk
.SS_Registers
.INDEX_BEGIN
,vonk
.SS_Registers
.INDEX_END
):
name
= vonk
.SS_Registers
.get_name(index
)
__getfun__
[name
] = __getreg__(index
)
__setfun__
[name
] = __setreg__(index
)
alias
= strand
.get_state_name(index
)
__getfun__
[alias
] = __getreg__(index
)
__setfun__
[alias
] = __setreg__(index
)
for index
in range(vonk
.SS_Registers
.ALIAS_BEGIN
,vonk
.SS_Registers
.ALIAS_END
):
name
= vonk
.SS_Registers
.get_name(index
)
__getfun__
[name
] = __getreg__(index
)
__setfun__
[name
] = __setreg__(index
)
__getfun__
[name
] = __asi_va__
[name
].get
__setfun__
[name
] = __asi_va__
[name
].set
for i
,g
in enumerate(Pfe_Strand
.Strand
.__irf
__[:8]):
Pfe_Strand
.GlobalStack
.__getfun
__[g
] = __getreg_gl__(i
)
Pfe_Strand
.GlobalStack
.__getfun
__[i
] = __getreg_gl__(i
)
Pfe_Strand
.GlobalStack
.__setfun
__[g
] = __setreg_gl__(i
)
Pfe_Strand
.GlobalStack
.__setfun
__[i
] = __setreg_gl__(i
)
for i
,w
in enumerate(Pfe_Strand
.Strand
.__irf
__[8:]):
Pfe_Strand
.WindowStack
.__getfun
__[w
] = __getreg_wp__(i
+8)
Pfe_Strand
.WindowStack
.__getfun
__[i
+8] = __getreg_wp__(i
+8)
Pfe_Strand
.WindowStack
.__setfun
__[w
] = __setreg_wp__(i
+8)
Pfe_Strand
.WindowStack
.__setfun
__[i
+8] = __setreg_wp__(i
+8)
Pfe_Strand
.TrapStack
.__getfun
__['tt'] = __getreg_tl__(vonk
.SS_Registers
.PR_TT
)
Pfe_Strand
.TrapStack
.__setfun
__['tt'] = __setreg_tl__(vonk
.SS_Registers
.PR_TT
)
Pfe_Strand
.TrapStack
.__getfun
__['tpc'] = __getreg_tl__(vonk
.SS_Registers
.PR_TPC
)
Pfe_Strand
.TrapStack
.__setfun
__['tpc'] = __setreg_tl__(vonk
.SS_Registers
.PR_TPC
)
Pfe_Strand
.TrapStack
.__getfun
__['tnpc'] = __getreg_tl__(vonk
.SS_Registers
.PR_TNPC
)
Pfe_Strand
.TrapStack
.__setfun
__['tnpc'] = __setreg_tl__(vonk
.SS_Registers
.PR_TNPC
)
Pfe_Strand
.TrapStack
.__getfun
__['tstate'] = __getreg_tl__(vonk
.SS_Registers
.PR_TSTATE
)
Pfe_Strand
.TrapStack
.__setfun
__['tstate'] = __setreg_tl__(vonk
.SS_Registers
.PR_TSTATE
)
Pfe_Strand
.TrapStack
.__getfun
__['htstate'] = __getreg_tl__(vonk
.SS_Registers
.HPR_HTSTATE
)
Pfe_Strand
.TrapStack
.__setfun
__['htstate'] = __setreg_tl__(vonk
.SS_Registers
.HPR_HTSTATE
)
self
.step
= self
.__runstep
__
self
.trc
.exe_instr(False)
self
.trc
.reg_value(False)
data
= self
.__strand
__.get_asi(asi
,va
)
if self
.__strand
__.asi_error
!= self
.__asierr
__.OK
:
raise AsiStateError(asi
,va
)
def wrasi(self
,asi
,va
,data
):
self
.__strand
__.set_asi(asi
,va
,data
)
if self
.__strand
__.asi_error
!= self
.__asierr
__.OK
:
raise AsiStateError(asi
,va
)
def set_format(self
,format
=None):
return self
.trc
.set_format(format
)
self
.trc
.set_format(format
)
def lstmode(self
,on
=None):
return Pfe_Strand
.Strand
.lstmode(self
,on
)
Pfe_Strand
.Strand
.lstmode(self
,on
)
self
.trc
.exe_instr(False)
self
.trc
.reg_value(False)
self
.trc
.reg_value(False)
elif on
in [91,92,93,94]:
# on = -sas_run_args=-DPLI_DEBUG + 90
# set by cosim -sas_run_args=-DPLI_DEBUG option, in this case the
# instr & delta are handled in backend, not at pfe layer.
self
.trc
.exe_instr(False)
self
.trc
.reg_value(False)
self
.trc
.exe_instr(False)
self
.trc
.reg_value(False)
def __runstep__(self
,n
=None):
n
= self
.__strand
__.run_step(n
)
pass # flush break loop for flush broadcast sync
elif self
.brk
.callback
[id] == None:
print self
.ref
+': Stopped at pc='+hex(self
.pc
)+': '+str(self
.brk
.hit_bp())
self
.brk
.callback
[id](self
)
def __lststep__(self
,n
=None):
n
= self
.__strand
__.trc_step(n
)
pass # flush break loop for flush broadcast sync
elif self
.brk
.callback
[id] == None:
print self
.ref
+': Stopped at pc='+hex(self
.pc
)+': '+str(self
.brk
.hit_bp())
self
.brk
.callback
[id](self
)
def va2pa(self
,va
,ctx
=None,pid
=None):
return self
.__strand
__.va2pa(va
)
return self
.__strand
__.va2pa(va
,ctx
)
return self
.__strand
__.va2pa(va
,ctx
,pid
)
def ra2pa(self
,ra
,pid
=None):
return self
.__strand
__.ra2pa(ra
)
return self
.__strand
__.ra2pa(ra
,pid
)
def icache_info(self
,pa
):
print self
.__strand
__.icache_info(pa
)
def icache_set(self
,set):
print self
.__strand
__.icache_set(set)
def dcache_set(self
,set):
print self
.__strand
__.dcache_set(set)
def l2cache_set(self
,set):
print self
.__strand
__.l2cache_set(set)