Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / pfe / samfe / RunScript.py
CommitLineData
86530b38
AT
1#
2# A collection of functions that help display executed instructions and
3# collect informaiton leading to a specified breakpoint.
4# Use execfile('RunScript.py') to load this module into samfe python
5# environment. This script is valid only when the samfe is in python mode,
6# it cannot be used in line-oriented command mode. When in line-oriented
7# command mode, use 'pym' command to enter python mode. Use 'pym_off()' in
8# python mode to switch back to line-oriented command mode.
9#
10
11# available functions:
12# showi()
13# runshow()
14# runbreak()
15# runbreak2()
16# runforever()
17# allpc()
18
19print 'loading RunScript...'
20
21import os, sys
22import sam
23
24# change this as needed
25try:
26 import Rk_Python as pyobj
27except:
28 print 'need to import proper XX_Python module'
29 sys.exit(1)
30
31symFile = 'symbol.tbl'
32symTable = None
33if os.path.exists(symFile):
34 try:
35 import SymbolTableNi
36 symTable = SymbolTableNi.SymbolTableNi()
37 symTable.load(symFile)
38 except:
39 symTable = None
40
41# global instruction count
42icount = 0L
43
44#
45# show the latest executed instruction. If the execution is continuing at
46# the background, we may not get the pc & instrWord of the same execution,
47# because we access pc and instrWord in two function calls, so there is a
48# possibility that the values are not matched. In other case, if a va is
49# provided, we will need to translate that into pa, which can be tricky, as
50# the execution may be at a different state, which may affect the va->pa
51# translation.
52#
53def showi(sid=0,va=0):
54 """
55 sid: strand id, default is 0
56 """
57 global pyobj
58 # if va=0, use the instruction to be executed next, otherwise use the
59 # provided va to access the instruction word and disassemble it.
60 if va == 0:
61 (len,instr,type) = RS_disassemblePC(sid, pyobj)
62 print 'sid=%d, pc=%#x, %s' % (sid, sim.s[sid].pc, instr)
63 else:
64 (len,instr,type) = RS_disassemble(sid, va, 2, pyobj)
65 print 'sid=%d, pc=%#x, %s' % (sid, va, instr)
66
67#
68# if there are breakpoints set up by "break" command, hitting one of those
69# breakpoints will terminate runshow(), runbreak(), or runbreak2() function
70# and return control to UI prompt. The breakpoints list specified in runbreak()
71# or runbreak2() function will have the same effect on execution.
72#
73
74# execute instructions and display executed instructions along the way
75# e.g., "runshow(100,1)" will run 100 instructions on strand1 and display
76# every instruction executed.
77#
78def runshow(step=1,sid=0,fd=sys.stdout,sym=1):
79 """
80 step: number of instruction to be executed, default is 1
81 sid: strand id, default is 0
82 fd: write the output to a file descriptor, default to stdout
83 sym: show (PC) symbol if available
84
85 example:
86 sam>>> fd1=open('0-tmp','w')
87 sam>>> runshow(10,fd=fd1)
88 sam>>> runshow(100,fd=fd1)
89 sam>>> fd1.close()
90 """
91 global pyobj
92 global icount
93 global symTable
94 prevPC = 0x0L
95 newPC = 0x0L
96 prevTL = 0
97 newTL = 0
98 i = 0
99 done = 0
100 while (done == 0) and (i < step):
101 i += 1
102 icount += 1
103 newPC = sim.s[sid].pc
104 (len,instr,type) = RS_disassemblePC(sid, pyobj)
105 sam.ui_exec('stepi')
106 newTL = sim.s[sid].tl
107 # check for hitting breakpoint
108 for s in sim.s:
109 if s.brk.hit():
110 done = 1
111 break
112 if done == 0:
113 if (newPC != prevPC+4) or (newTL != prevTL):
114 # display PC or related symbol when PC moves to a different
115 # path
116 if (sym == 1) and (symTable != None):
117 fd.write('%s, TL=%d:\n' % (symTable.va2symbol(newPC), newTL))
118 else:
119 fd.write('PC=%#x, TL=%d:\n' % (newPC, newTL))
120 fd.write('sid=%d, ic=%d, pc=%#x, %s\n' % (sid, icount, newPC, instr))
121 prevPC = newPC
122 prevTL = newTL
123
124#
125# execute instructions and check for breakpoints along the way
126# e.g., runbreak(100,bpoints=[0x40070,0x40078,0x83400]) will run 100
127# instructions on strand0 and display every instruction executed, if PC has a
128# hit with any value in bpoints, then the execution will stop.
129#
130def runbreak(step=1,sid=0,bpoints=[0x83400,0xfffffffff0000080L,0x00122000],fd=sys.stdout,sym=1):
131 """
132 step: number of instruction to be executed, default is 1
133 sid: strand id, default is 0
134 bpoints: a list of PC breakpoints, default is empty list
135 fd: output file descriptor, default to stdout
136 sym: show (PC) symbol if available
137 """
138 global pyobj
139 global symTable
140 global icount
141 prevPC = 0x0L
142 newPC = 0x0L
143 prevTL = 0
144 newTL = 0
145 i = 0
146 done = 0
147 while (done == 0) and (i < step):
148 i += 1
149 icount += 1
150 newPC = sim.s[sid].pc
151 (len,instr,type) = RS_disassemblePC(sid, pyobj)
152 # check breakpoints
153 if newPC in bpoints:
154 if symTable != None:
155 fd.write('BREAKPOINT: sid=%d, pc=%#x [%s]\n' % (sid, newPC, symTable.va2symbol(newPC)))
156 else:
157 fd.write('BREAKPOINT: sid=%d, pc=%#x\n' % (sid, newPC))
158 done = 1
159 else:
160 # execute the next instr if no breakpoint is hit
161 sam.ui_exec('stepi')
162 newTL = sim.s[sid].tl
163 for s in sim.s:
164 if s.brk.hit():
165 done = 1
166 break
167 if done == 0:
168 if (newPC != prevPC+4) or (newTL != prevTL):
169 # display PC or related symbol when PC moves to a
170 # different path
171 if (sym == 1) and (symTable != None):
172 fd.write('%s, TL=%d:\n' % (symTable.va2symbol(newPC), newTL))
173 else:
174 fd.write('PC=%#x, TL=%d:\n' % (newPC, newTL))
175 fd.write('sid=%d, ic=%d, pc=%#x, %s\n' % (sid, icount, newPC, instr))
176 prevPC = newPC
177 prevTL = newTL
178
179#
180# execute instructions and check for breakpoints along the way
181# e.g., runbreak2(100,bpoints=[0x40070,0x40078,0x83400],size=50) will run
182# 100 instructions on strand0 and display every instruction executed, if PC
183# has a hit with any value in bpoints, then the execution will stop. The last
184# 'size' instructions will be kept in specified file.
185#
186def runbreak2(step=1,sid=0,bpoints=[0x83400,0xfffffffff0000080L,0x00122000],fd=sys.stdout,size=10000):
187 """
188 step: number of instruction to be executed, default is 1
189 sid: strand id, default is 0
190 bpoints: a list of PC breakpoints, default is empty list
191 fd: output file descriptor, default to stdout
192 size: instr buffer size, the last 'size' instructions before the breakpoint
193 will be written to fd
194
195 example:
196 sam>>> fd1=open('0-tmp','w')
197 sam>>> runbreak2(10,bpoints=[0x83400],fd=fd1,size=100)
198 sam>>> fd1.close()
199 """
200 global pyobj
201 global symTable
202 global icount
203 buffer = { }
204 index = 0
205 prevPC = 0x0L
206 newPC = 0x0L
207 prevTL = 0
208 newTL = 0
209 i = 0
210 done = 0
211 while (done == 0) and (i < step):
212 i += 1
213 icount += 1
214 newPC = sim.s[sid].pc
215 (len,instr,type) = RS_disassemblePC(sid, pyobj)
216 # check breakpoints
217 if newPC in bpoints:
218 bs = sim.s[sid]
219 done = 1
220 else:
221 # execute the next instr if no breakpoint is hit
222 sam.ui_exec('stepi')
223 for s in sim.s:
224 if s.brk.hit():
225 done = 1
226 bs = s
227 break
228 if done == 0:
229 index = (i-1) % size
230 buffer[index] = 'PC=%#x, %s' % (newPC, instr)
231 # dump out buffer if hit a breakpoint
232 if done == 1:
233 jj = 1
234 for ii in range(index+1, size):
235 if buffer.has_key(ii):
236 fd.write('sid=%d, ic=%d, %s\n' % (sid, jj, buffer[ii]))
237 jj += 1
238 for ii in range(0,index+1):
239 if buffer.has_key(ii):
240 fd.write('sid=%d, ic=%d, %s\n' % (sid, jj, buffer[ii]))
241 jj += 1
242 if symTable != None:
243 fd.write('BREAKPOINT: sid=%d, pc=%#x [%s]\n' % (bs.strand_id, bs.pc, symTable.va2symbol(bs.pc)))
244 else:
245 fd.write('BREAKPOINT: sid=%d, pc=%#x\n' % (bs.strand_id, bs.pc))
246
247#
248# check PASS/FAIL at the end of an execution, and return exit code
249# accordingly.
250#
251def runforever(insts=0x7fffffffffffffff,ss=None,bout=1,va_pass=[0x122000],va_fail=[0x122020]):
252 """
253 insts: number of instructions to run per strand, default is MAXINT
254 ss: array of strand-ids, e.g., [0,1,2]. default is None, means all strands
255 bout: upon hitting pass/fail, 1 means exit, 0 means returns to caller
256 va_pass: array of 'pass' VAs, default is 0x122000
257 va_fail: array of 'fail' VAs, default is 0x122020
258 """
259 strands = []
260 if ss == None:
261 # special case, step through all strands
262 for s in sim.s:
263 strands.append(s)
264 else:
265 # otherwise only step through specified strands
266 for sid in ss:
267 strands.append(sim.s[sid])
268 # set 'pass' breakpoints
269 bp_pass = {}
270 for s in strands:
271 bp_pass[s.strand_id] = []
272 for va in va_pass:
273 bp_pass[s.strand_id].append(s.brk.on_inst_va(va))
274 # set 'fail' breakpoints
275 bp_fail = {}
276 for s in strands:
277 bp_fail[s.strand_id] = []
278 for va in va_fail:
279 bp_fail[s.strand_id].append(s.brk.on_inst_va(va))
280 # step through strands
281 sam.ui_exec('stepi %d' % insts)
282 # check for pass/fail breakpoint
283 for s in strands:
284 bp = s.brk.hit()
285 if bp:
286 if bp[0] in bp_pass[s.strand_id]:
287 if bout:
288 sys.exit(0)
289 else:
290 return 0
291 elif bp[0] in bp_fail[s.strand_id]:
292 if bout:
293 sys.exit(1)
294 else:
295 return 1
296 # if nothing hit, consider it is good
297 if bout:
298 sys.exit(0)
299 else:
300 return 0
301
302#
303# display the PC of all strands
304#
305def allpc():
306 for s in sim.s:
307 print 'T%d: PC=%#x' % (s.strand_id, s.pc)
308
309
310###############################################################################
311### python memory debugging, for developers' internal use.
312###############################################################################
313
314import gc
315
316def gc_dbx_on():
317 """
318 """
319 gc.enable()
320 gc.set_debug(gc.DEBUG_LEAK|gc.DEBUG_STATS)
321
322def gc_dbx_off():
323 """
324 """
325 gc.set_debug(0x0)
326
327def gc_dump():
328 """
329 """
330 gc.collect()
331 print '\nGARBAGE OBJECTS:'
332 for x in gc.garbage:
333 xx = str(x)
334 if len(xx) > 80:
335 xx = xx[:77]+'...'
336 print '%s ---> %s' % (type(x), xx)