Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: trconv.H | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | // ========== Copyright Header Begin ========================================== | |
24 | // | |
25 | // OpenSPARC T2 Processor File: trconv.H | |
26 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
27 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
28 | // | |
29 | // The above named program is free software; you can redistribute it and/or | |
30 | // modify it under the terms of the GNU General Public | |
31 | // License version 2 as published by the Free Software Foundation. | |
32 | // | |
33 | // The above named program is distributed in the hope that it will be | |
34 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36 | // General Public License for more details. | |
37 | // | |
38 | // You should have received a copy of the GNU General Public | |
39 | // License along with this work; if not, write to the Free Software | |
40 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
41 | // | |
42 | // ========== Copyright Header End ============================================ | |
43 | // File: trconv.H | |
44 | // | |
45 | // Description: Part of trconv library file, trconv.o, for printing and | |
46 | // converting execution traces | |
47 | // | |
48 | // How to add another RST record type to trconv: | |
49 | // | |
50 | // This file, trconv.H, is the main file supporting the class | |
51 | // definitions of each trace record type. It includes a global struct | |
52 | // "gbl" containing variables used throughout trconv, including the | |
53 | // counts of each record type. Also here is the base class "Trace" | |
54 | // containing the pure virtual functions you will need to define in | |
55 | // your new derived class. | |
56 | // | |
57 | // To create a new derived class, copy one of the existing classes, | |
58 | // and modify it accordingly. RSTF_Traceinfo is a simple example; | |
59 | // RSTF_Instr is a more elaborate example. | |
60 | // | |
61 | // All RST traces are first processed by RSTF_Union. In | |
62 | // RSTF_Union the rtype of each RST record is examined, and the | |
63 | // corresponding class member function is called. The protected member | |
64 | // function RSTF_Union::get_rst_type() determines to RST rtype and | |
65 | // returns a pointer to the corresponding RST class. | |
66 | // | |
67 | // Finally in init_globals(char *argv[]) in trconv.C, initialize | |
68 | // the new counter variable to 0. And in print_counts(FILE* outfp) in | |
69 | // trconv.C add an fprintf(stdout, ...) statement to print the count | |
70 | // of the new record type. | |
71 | // | |
72 | // Cross you fingers, recompile (ignore the warnings about "master is | |
73 | // defined but not used" and various member functions being "too large | |
74 | // and will not be expanded inline", they're normal), and run... | |
75 | ||
76 | #pragma ident "@(#) trconv.H 1.19: 11/06/07 11:35:08 @(#)" | |
77 | ||
78 | #include <assert.h> | |
79 | #include <stdio.h> | |
80 | #include <sys/types.h> | |
81 | #include <unistd.h> | |
82 | #include <time.h> | |
83 | ||
84 | #include <string> | |
85 | #include <map> | |
86 | ||
87 | #define RSTF_NOADDR -1 | |
88 | ||
89 | #include "rstf/rstf.h" | |
90 | #include "rstf/rstf_deprecated.h" | |
91 | #if defined(ARCH_AMD64) | |
92 | #include "rstf/rstf_convert.h" | |
93 | #endif | |
94 | ||
95 | #include "MISC.h" | |
96 | #include "ITYPES.h" | |
97 | ||
98 | #define MAX_CPUID (1024) | |
99 | #define NUM_VERIFY (8) | |
100 | ||
101 | #define PSTATE_AM (0x8) | |
102 | ||
103 | extern char switch_error_string[]; | |
104 | ||
105 | enum { | |
106 | NONE = 0, | |
107 | RTF99, | |
108 | SHADE5, | |
109 | SHADE6x32, | |
110 | SHADE6x64, | |
111 | MASTER64, | |
112 | RST | |
113 | }; | |
114 | ||
115 | typedef struct { | |
116 | // format options | |
117 | int fromtype; // -from FX | |
118 | int totype; // -to FX | |
119 | ||
120 | // selection options | |
121 | uint64_t maxRecs; // -n N | |
122 | uint64_t maxInstrs; // -n Ni | |
123 | uint64_t skipRecs; // -s N | |
124 | uint64_t skipInstrs; // -s Ni | |
125 | uint64_t frompc; // -pc=pc1[,pc2] // -frompc ? | |
126 | uint64_t topc; // // -topc ? | |
127 | uint64_t fromea; // -ea=ea1[,ea2] // -fromea ? | |
128 | uint64_t toea; // // -toea ? | |
129 | char cpu[MAX_CPUID + 1]; // -cpu= | |
130 | uint16_t pstate[MAX_CPUID + 1]; // monitor pstate.am per cpu | |
131 | ||
132 | // printing options | |
133 | bool record; // -a | |
134 | bool disassembly; // -d | |
135 | bool verbose; // -x | |
136 | bool showIdx; // -nid | |
137 | bool countOnly; // -c | |
138 | #ifdef _PRINT_PA | |
139 | bool printPA; // -pa | |
140 | #endif // _PRINT_PA | |
141 | #ifdef _VALUE_TRACE | |
142 | bool valueTrace; // -vt | |
143 | #endif // _VALUE_TRACE | |
144 | FILE* msgfp; // -msg ? | |
145 | bool show_syms; | |
146 | symbol_table_t symbol_table; | |
147 | ||
148 | // verification options | |
149 | bool verify; // -nv | |
150 | bool checkError; // -e | |
151 | bool fast; // -fast | |
152 | ||
153 | // rst options | |
154 | bool onlyIns; // -i | |
155 | bool reorderIns; // -ic | |
156 | bool noIns; // -ni | |
157 | bool reorderNoIns; // -nic | |
158 | bool branch; // -branch (-nobranch?) | |
159 | bool pc_pavadiff; // -pc_pavadiff (-nopc_pavadiff?) | |
160 | bool ea_pavadiff; // -ea_pavadiff (-noea_pavadiff?) | |
161 | ||
162 | // patching options | |
163 | bool clean; // -patchcleanrst | |
164 | bool genIHash; // -patchihash | |
165 | ||
166 | // output options | |
167 | FILE* infp; // [input-file] | |
168 | FILE* outfp; // -stdout || -o | |
169 | ||
170 | // convenient variables | |
171 | char* progname; | |
172 | char* infile; | |
173 | int fromsize; | |
174 | int tosize; | |
175 | ||
176 | bool checkIHash; | |
177 | ||
178 | uint64_t icount, rcount; // instr count & total record count. | |
179 | uint64_t skipInstrsRecs; | |
180 | ||
181 | // rst-related | |
182 | ||
183 | bool rstf_pre212; | |
184 | ||
185 | // rst types | |
186 | uint64_t headercount, | |
187 | // instrcount, ---> use icount | |
188 | //asicount, | |
189 | traceinfocount, // ASI_T == TRACEINFO_T, TRACEINFO_T is to replace ASI_T | |
190 | tlbcount, | |
191 | threadcount, | |
192 | pregcount, | |
193 | trapcount, | |
194 | trapexitcount, | |
195 | trappinginstrcount, | |
196 | cpucount, | |
197 | dmacount, | |
198 | snoopcount, | |
199 | tsb_access_count, | |
200 | rfs_section_header_count, | |
201 | bpwarming_count, | |
202 | cachewarming_count, | |
203 | delimcount, // combination of leftdelim & rightdelim | |
204 | physaddrcount, | |
205 | pavadiffcount, | |
206 | //nullrec??? // null record, can be ignored | |
207 | filemarkercount, | |
208 | //hwinfocount, | |
209 | recnumcount, | |
210 | stringcount, // combination of strdesc & strcont | |
211 | statuscount, | |
212 | patchcount, | |
213 | regvalcount, | |
214 | memval64count, | |
215 | memval128count, | |
216 | bustracecount, | |
217 | processcount, | |
218 | timesynccount, | |
219 | devidstrcount, | |
220 | zerocount, | |
221 | unknowncount; | |
222 | ||
223 | #ifdef _PRINT_PA | |
224 | bool ea_pavadiff_valid[MAX_INSTR_CPUID]; | |
225 | uint64_t ea_pavadiff_value[MAX_INSTR_CPUID]; | |
226 | bool pc_pavadiff_valid[MAX_INSTR_CPUID]; | |
227 | uint64_t pc_pavadiff_value[MAX_INSTR_CPUID]; | |
228 | #endif // _PRINT_PA | |
229 | ||
230 | std::map<int, std::string> devid2string; | |
231 | } Globals_T; | |
232 | ||
233 | extern Globals_T gbl; | |
234 | ||
235 | extern char usage_string[]; | |
236 | ||
237 | void usage(char progName[]); | |
238 | ||
239 | void parse_args(int argc, char *argv[], bool debug = false); | |
240 | ||
241 | void init_globals(char *argv[]); | |
242 | ||
243 | int format2int(const char str[]); | |
244 | ||
245 | int format2size(int format); | |
246 | ||
247 | bool streqprefix(const char* a, const char* b); | |
248 | ||
249 | bool streq(const char* a, const char* b); | |
250 | ||
251 | void get_pc_range(char* pc_str); | |
252 | ||
253 | void get_range(char* str, uint64_t *from, uint64_t* to); | |
254 | ||
255 | void get_cpu_range(char* pc_str); | |
256 | ||
257 | bool in_range(const uint64_t x, const uint64_t a, const uint64_t b); | |
258 | ||
259 | void print_counts(FILE* outfp); | |
260 | ||
261 | // base class for all trace structs | |
262 | class Trace { | |
263 | public: | |
264 | // increments global record and instruction counts | |
265 | virtual void count() { | |
266 | gbl.rcount++; | |
267 | gbl.icount++; | |
268 | } | |
269 | ||
270 | // prints record fields without disassembly of instruction records | |
271 | virtual void print_rec(uint64_t idx) = 0; | |
272 | ||
273 | // prints record disassenbly | |
274 | virtual void print_dasm(uint64_t idx) { | |
275 | print_rec(idx); | |
276 | } // Trace::print_dasm() | |
277 | ||
278 | // prints verbose record disassembly | |
279 | virtual void print_verb(uint64_t idx) { | |
280 | print_rec(idx); | |
281 | } // Trace::print_verb() | |
282 | ||
283 | // converts record type to Tmaster64 | |
284 | virtual void convert_to_master() { | |
285 | // not converted | |
286 | } // Trace::convert_to_master() | |
287 | ||
288 | // converts master to record type | |
289 | virtual void convert_from_master(Tmaster64* master) { | |
290 | Tmaster64* useless = master; | |
291 | // not converted | |
292 | } // Trace::convert_from_master() | |
293 | ||
294 | // sets ihash field to correct value for instruction records | |
295 | virtual void gen_ihash() { | |
296 | // not generated | |
297 | } // Trace::gen_ihash() | |
298 | ||
299 | // verifies ihash value of instruction records; | |
300 | // returns 1 on error, 0 otherwise | |
301 | virtual int check_ihash_error() { | |
302 | return 0; | |
303 | } // Trace::check_ihash_error() | |
304 | ||
305 | // verifies pc values of instruction records; prints message on error | |
306 | virtual void verify() { | |
307 | // not verified | |
308 | } // Trace::verify() | |
309 | ||
310 | // returns RSTF_NOADDR for non-instruction, non-trap types | |
311 | virtual uint64_t get_pc() { | |
312 | return RSTF_NOADDR; | |
313 | } // Trace::get_pc() | |
314 | ||
315 | // returns RSTF_NOADDR for non-instruction types | |
316 | virtual uint64_t get_ea() { | |
317 | return RSTF_NOADDR; | |
318 | } // Trace::get_ea() | |
319 | ||
320 | // returns ihash value in trace record | |
321 | virtual int get_ihash() { | |
322 | return 0; | |
323 | } // Trace::get_ihash() | |
324 | ||
325 | // increments trace pointer to next trace record in trace buffer | |
326 | virtual void inc_tr() = 0; | |
327 | ||
328 | // sets trace pointer to ptr; optionally sets tr_orig to ptr also | |
329 | virtual void set_tr(void* ptr, bool set_orig = true) = 0; | |
330 | ||
331 | // resets trace pointer to tr_orig | |
332 | virtual void reset_tr() = 0; | |
333 | ||
334 | // returns pointer to static protected data member this_master | |
335 | virtual Tmaster64* get_master() { | |
336 | return &this_master; | |
337 | } // Trace::get_master() | |
338 | ||
339 | // used for piping to and from rst trace types | |
340 | virtual rstf_unionT* copy_from_rst() { | |
341 | // do nothing (except for RSTF_Union::copy_from_rst() ) | |
342 | return NULL; | |
343 | } | |
344 | ||
345 | // used for piping to and from rst trace types | |
346 | virtual void copy_to_rst(rstf_unionT* from) { | |
347 | rstf_unionT* useless = from; | |
348 | // do nothing (except for RSTF_Union::copy_to_rst() ) | |
349 | } | |
350 | ||
351 | // used to verify branch targets in RSTF disassembly printouts | |
352 | int check_branch_ea(uint64_t dis_ea, uint64_t tr_ea) { | |
353 | if (dis_ea != tr_ea) { | |
354 | if ((dis_ea ^ tr_ea) != (0xffffffff00000000ull)) { | |
355 | fprintf(stderr, "trconv: warning: branch target != effective address " | |
356 | "(Rec #%llu: 0x%llx != 0x%llx)\n", | |
357 | gbl.rcount - 1, dis_ea, tr_ea); | |
358 | return 1; | |
359 | } | |
360 | } | |
361 | ||
362 | return 0; | |
363 | } | |
364 | ||
365 | virtual int getCpuID() { | |
366 | return -1; | |
367 | } | |
368 | ||
369 | protected: | |
370 | // static data member, shared by all derived classes | |
371 | static Tmaster64 this_master; | |
372 | ||
373 | }; // Trace | |
374 | ||
375 | //====================================================================== | |
376 | //====================================================================== | |
377 | class RSTF_Header : public Trace { | |
378 | public: | |
379 | virtual void count() { | |
380 | gbl.rcount++; | |
381 | gbl.headercount++; | |
382 | if (tr->majorVer*1000 + tr->minorVer <= 2011) { | |
383 | gbl.rstf_pre212 = true; | |
384 | } | |
385 | } | |
386 | ||
387 | virtual void print_rec(uint64_t idx) { | |
388 | if (gbl.showIdx) { | |
389 | fprintf(gbl.outfp , "%6lld ", idx); | |
390 | } | |
391 | ||
392 | fprintf(gbl.outfp, "header : majorVer=%d minorVer=%d %s", | |
393 | tr->majorVer, tr->minorVer, tr->header_str); | |
394 | fprintf(gbl.outfp, "\n"); | |
395 | } // RSTF_Header::print_rec() | |
396 | ||
397 | virtual void inc_tr() { | |
398 | tr++; | |
399 | } // RSTF_Header::inc_tr() | |
400 | ||
401 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
402 | tr = (rstf_headerT*) ptr; | |
403 | ||
404 | if (set_orig) { | |
405 | tr_orig = tr; | |
406 | } | |
407 | } // RSTF_Header::set_tr() | |
408 | ||
409 | virtual void reset_tr() { | |
410 | tr = tr_orig; | |
411 | } // RSTF_Header::reset_tr() | |
412 | ||
413 | protected: | |
414 | rstf_headerT* tr; | |
415 | rstf_headerT* tr_orig; | |
416 | }; // RSTF_Header | |
417 | ||
418 | //====================================================================== | |
419 | //====================================================================== | |
420 | class RSTF_Instr : public Trace { | |
421 | public: | |
422 | virtual void count() { | |
423 | gbl.rcount++; | |
424 | gbl.icount++; | |
425 | ||
426 | if (gbl.clean == true) { | |
427 | if (!tr->ea_valid){ | |
428 | tr->ea_va = RSTF_NOADDR; | |
429 | } | |
430 | } | |
431 | } // RSTF_Instr::count() | |
432 | ||
433 | virtual void print_dasm(uint64_t idx) { | |
434 | char dis_string[80]; | |
435 | uint64_t ea_va = -1; | |
436 | ||
437 | int cpuid = getCpuID(); | |
438 | ||
439 | sprintDiss(dis_string, tr->instr, tr->pc_va); | |
440 | ||
441 | int ihash = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); | |
442 | // if (ih_isbranch(tr->ihash) || tr->ihash == SPIX_SPARC_IOP_CALL) { | |
443 | if (ih_isbranch(ihash) || ihash == SPIX_SPARC_IOP_CALL) { | |
444 | if (gbl.branch && tr->bt) { | |
445 | ea_va = getCtiEa(tr->instr, ihash, tr->pc_va); | |
446 | ||
447 | if (gbl.pstate[cpuid] & PSTATE_AM) { | |
448 | ea_va &= 0xffffffff; | |
449 | } | |
450 | ||
451 | if (!tr->an) { | |
452 | check_branch_ea(ea_va, tr->ea_va); | |
453 | } | |
454 | } | |
455 | } | |
456 | ||
457 | if (gbl.showIdx) { | |
458 | fprintf(gbl.outfp , "%6lld ", idx); | |
459 | } | |
460 | ||
461 | fprintf(gbl.outfp, "instr : cpuid=%d ", cpuid); | |
462 | ||
463 | if (tr->hpriv) { | |
464 | fprintf(gbl.outfp, "h "); | |
465 | } else if (tr->pr) { | |
466 | fprintf(gbl.outfp, "p "); | |
467 | } else { | |
468 | fprintf(gbl.outfp, "u "); | |
469 | } | |
470 | ||
471 | fprintf(gbl.outfp, "[0x%016llx] ", tr->pc_va); | |
472 | if (gbl.show_syms) { | |
473 | char *symbol; | |
474 | uint64_t offset; | |
475 | if (gbl.symbol_table.search_symbol_table(tr->pc_va, symbol, offset)) { | |
476 | fprintf(gbl.outfp, "(%s+0x%llx) ", symbol, offset); | |
477 | } | |
478 | else { | |
479 | fprintf(gbl.outfp, "(???+???) ", symbol, offset); | |
480 | } | |
481 | } | |
482 | fprintf(gbl.outfp, "%-32s", dis_string); | |
483 | ||
484 | if (ih_iscti(ihash)) { | |
485 | if (tr->bt) { | |
486 | fprintf(gbl.outfp, "T "); | |
487 | } else { | |
488 | fprintf(gbl.outfp, "N "); | |
489 | } | |
490 | } else { | |
491 | fprintf(gbl.outfp, " "); | |
492 | } | |
493 | ||
494 | #ifdef _PRINT_PA | |
495 | if (gbl.printPA) { | |
496 | if (!tr->an) { | |
497 | if (tr->ea_valid) { | |
498 | fprintf(gbl.outfp, "v[0x%016llx] ", tr->ea_va); | |
499 | ||
500 | if ((ih_isload(ihash) || ih_isstore(ihash)) && | |
501 | tr->tr == 0) { | |
502 | if (gbl.ea_pavadiff_valid[cpuid]) { | |
503 | fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.ea_pavadiff_value[cpuid]); | |
504 | } | |
505 | } else { | |
506 | if (gbl.pc_pavadiff_valid[cpuid]) { | |
507 | fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.pc_pavadiff_value[cpuid]); | |
508 | } | |
509 | } | |
510 | } else if (tr->bt) { // so it must be a branch...(?) | |
511 | fprintf(gbl.outfp, "<0x%016llx> ", tr->ea_va); | |
512 | } | |
513 | } | |
514 | } else | |
515 | #endif //_PRINT_PA | |
516 | { | |
517 | if (!tr->an) { | |
518 | if (tr->ea_valid) { | |
519 | fprintf(gbl.outfp, "[0x%016llx] ", tr->ea_va); | |
520 | } else if (tr->bt) { // so it must be a branch...(?) | |
521 | fprintf(gbl.outfp, "<0x%016llx> ", tr->ea_va); | |
522 | } | |
523 | } | |
524 | } | |
525 | ||
526 | if (tr->an) { | |
527 | fprintf(gbl.outfp, "an "); | |
528 | } | |
529 | ||
530 | if (tr->tr) { | |
531 | fprintf(gbl.outfp, "tr "); | |
532 | } | |
533 | ||
534 | fprintf(gbl.outfp, "\n"); | |
535 | } // RSTF_Instr::print_dasm() | |
536 | ||
537 | virtual void print_rec(uint64_t idx) { | |
538 | if (gbl.showIdx) { | |
539 | fprintf(gbl.outfp, "%6lld ", idx); | |
540 | } | |
541 | ||
542 | // int ihash = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); | |
543 | fprintf(gbl.outfp, "instr : cpuid=%d ", gbl.rstf_pre212? tr->cpuid: rstf_instrT_get_cpuid(tr)); | |
544 | fprintf(gbl.outfp, "pc=0x%016llx ", tr->pc_va); | |
545 | fprintf(gbl.outfp, "instr=0x%08x ", tr->instr); | |
546 | // fprintf(gbl.outfp, "ihash=%-3d ", ihash); | |
547 | fprintf(gbl.outfp, "hpriv=%d ", tr->hpriv); | |
548 | fprintf(gbl.outfp, "pr=%d ", tr->pr); | |
549 | fprintf(gbl.outfp, "bt=%d ", tr->bt); | |
550 | fprintf(gbl.outfp, "ea=0x%016llx ", tr->ea_va); | |
551 | fprintf(gbl.outfp, "ev=%d ", tr->ea_valid); | |
552 | fprintf(gbl.outfp, "an=%d ", tr->an); | |
553 | fprintf(gbl.outfp, "tr=%d ", tr->tr); | |
554 | fprintf(gbl.outfp, "\n"); | |
555 | } // RSTF_Instr::print_rec() | |
556 | ||
557 | virtual void print_verb(uint64_t idx) { | |
558 | char dis_string[80]; | |
559 | uint64_t ea_va = -1; | |
560 | int cpuid = gbl.rstf_pre212? tr->cpuid: rstf_instrT_get_cpuid(tr); | |
561 | ||
562 | sprintDiss(dis_string, tr->instr, tr->pc_va); | |
563 | int ihash = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); | |
564 | if (ih_isbranch(ihash) || ihash == SPIX_SPARC_IOP_CALL) { | |
565 | if (gbl.branch && tr->bt) { | |
566 | ea_va = getCtiEa(tr->instr, ihash, tr->pc_va); | |
567 | ||
568 | if (gbl.pstate[cpuid] & PSTATE_AM) { | |
569 | ea_va &= 0xffffffff; | |
570 | } | |
571 | ||
572 | if (!tr->an) { | |
573 | check_branch_ea(ea_va, tr->ea_va); | |
574 | } | |
575 | } | |
576 | } | |
577 | ||
578 | if (gbl.showIdx) { | |
579 | fprintf(gbl.outfp , "%6lld ", idx); | |
580 | } | |
581 | ||
582 | fprintf(gbl.outfp, "instr : cpuid=%d ", cpuid); | |
583 | ||
584 | if (tr->hpriv) { | |
585 | fprintf(gbl.outfp, "h "); | |
586 | } else if (tr->pr) { | |
587 | fprintf(gbl.outfp, "p "); | |
588 | } else { | |
589 | fprintf(gbl.outfp, "u "); | |
590 | } | |
591 | ||
592 | fprintf(gbl.outfp, "[0x%016llx] ", tr->pc_va); | |
593 | fprintf(gbl.outfp, "%-32s", dis_string); | |
594 | fprintf(gbl.outfp, "(0x%08x) ", tr->instr); | |
595 | fprintf(gbl.outfp, "%3d ", ihash); | |
596 | ||
597 | if (ih_iscti(ihash)) { | |
598 | if (tr->bt) { | |
599 | fprintf(gbl.outfp, "T "); | |
600 | } else { | |
601 | fprintf(gbl.outfp, "N "); | |
602 | } | |
603 | } else { | |
604 | fprintf(gbl.outfp, " "); | |
605 | } | |
606 | ||
607 | #ifdef _PRINT_PA | |
608 | if (gbl.printPA) { | |
609 | fprintf(gbl.outfp, "v[0x%016llx]", tr->ea_va); | |
610 | if (!tr->ea_valid) { | |
611 | fprintf(gbl.outfp, "x "); | |
612 | } else { | |
613 | fprintf(gbl.outfp, " "); | |
614 | } | |
615 | ||
616 | if ((ih_isload(ihash) || ih_isstore(ihash)) && | |
617 | tr->tr == 0) { | |
618 | if (gbl.ea_pavadiff_valid[cpuid]) { | |
619 | fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.ea_pavadiff_value[cpuid]); | |
620 | } | |
621 | } else { | |
622 | if (gbl.pc_pavadiff_valid[cpuid]) { | |
623 | fprintf(gbl.outfp, "p[0x%016llx] ", tr->ea_va + gbl.pc_pavadiff_value[cpuid]); | |
624 | } | |
625 | } | |
626 | } else | |
627 | #endif // _PRINT_PA | |
628 | { | |
629 | fprintf(gbl.outfp, "[0x%016llx]", tr->ea_va); | |
630 | if (!tr->ea_valid) { | |
631 | fprintf(gbl.outfp, "x "); | |
632 | } else { | |
633 | fprintf(gbl.outfp, " "); | |
634 | } | |
635 | } | |
636 | ||
637 | if (tr->an) { | |
638 | fprintf(gbl.outfp, "an "); | |
639 | } | |
640 | ||
641 | if (tr->tr) { | |
642 | fprintf(gbl.outfp, "tr "); | |
643 | } | |
644 | ||
645 | fprintf(gbl.outfp, "\n"); | |
646 | } // RSTF_Instr::print_verb() | |
647 | ||
648 | virtual void convert_to_master() { | |
649 | this_master.tr_pc_va = tr->pc_va; | |
650 | this_master.tr_ea_va = tr->ea_va ; | |
651 | this_master.tr_tid = 0; | |
652 | this_master.tr_ih = spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); | |
653 | this_master.tr_reserved0 = 0; | |
654 | this_master.tr_taken = tr->bt; | |
655 | this_master.tr_annulled = tr->an; | |
656 | this_master.tr_i = tr->instr; | |
657 | this_master.tr_reserved1 = 0; | |
658 | this_master.tr_pc_pa = 0; | |
659 | this_master.tr_ea_pa = 0; | |
660 | this_master.tr_context = 0; | |
661 | //this_master.tr_traceinfo = 0; | |
662 | this_master.tr_got_trap = tr->tr; | |
663 | this_master.tr_privmode = tr->pr; | |
664 | this_master.tr_va_valid = tr->ea_valid; | |
665 | } // RSTF_Instr::convert_to_master() | |
666 | ||
667 | virtual void convert_from_master(Tmaster64* master) { | |
668 | tr->rtype = INSTR_T; | |
669 | tr->notused = 0; | |
670 | tr->ea_valid = master->tr_va_valid; | |
671 | tr->tr = master->tr_got_trap; | |
672 | tr->pr = master->tr_privmode; | |
673 | tr->bt = master->tr_taken; | |
674 | tr->an = master->tr_annulled; | |
675 | // tr->ihash = master->tr_ih; | |
676 | tr->instr = master->tr_i; | |
677 | tr->pc_va = master->tr_pc_va; | |
678 | tr->ea_va = master->tr_ea_va; | |
679 | } // RSTF_Instr::convert_from_master() | |
680 | ||
681 | virtual void gen_ihash() { | |
682 | // tr->ihash = getIHash(tr->instr); | |
683 | } // RSTF_Instr::gen_ihash() | |
684 | ||
685 | virtual int check_ihash_error() { | |
686 | #if 0 | |
687 | if (tr->ihash != getIHash(tr->instr)) { | |
688 | return 1; | |
689 | } | |
690 | #endif | |
691 | return 0; | |
692 | } // RSTF_Instr::check_ihash_error() | |
693 | ||
694 | virtual void verify() { | |
695 | rstf_instrT* vtr = tr - NUM_VERIFY; | |
696 | int i; | |
697 | ||
698 | for (i = 0; i < NUM_VERIFY - 1; i++) { | |
699 | if (vtr[i].rtype == INSTR_T) { | |
700 | if (vtr[i].pc_va % 4 != 0 && RSTF_IS_BADADDR(vtr[i].pc_va) == 0) { | |
701 | fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); | |
702 | set_tr(&vtr[i], false); | |
703 | print_verb(gbl.rcount - NUM_VERIFY + i); | |
704 | //exit(2); | |
705 | } | |
706 | } | |
707 | } | |
708 | } // RSTF_Instr::verify() | |
709 | ||
710 | virtual uint64_t get_pc() { | |
711 | return tr->pc_va; | |
712 | } // RSTF_Instr::get_pc() | |
713 | ||
714 | virtual uint64_t get_ea() { | |
715 | if (tr->ea_valid) { | |
716 | return tr->ea_va; | |
717 | } | |
718 | ||
719 | return RSTF_NOADDR; | |
720 | } // RSTF_Instr::get_ea() | |
721 | ||
722 | virtual int get_ihash() { | |
723 | return spix_sparc_iop(SPIX_SPARC_V9, &tr->instr); | |
724 | } // RSTF_Instr::get_ihash() | |
725 | ||
726 | virtual void inc_tr() { | |
727 | tr++; | |
728 | } // RSTF_Instr::inc_tr() | |
729 | ||
730 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
731 | tr = (rstf_instrT*) ptr; | |
732 | ||
733 | if (set_orig) { | |
734 | tr_orig = tr; | |
735 | } | |
736 | } // RSTF_Instr::set_tr() | |
737 | ||
738 | virtual void reset_tr() { | |
739 | tr = tr_orig; | |
740 | } // RSTF_Instr::reset_tr() | |
741 | ||
742 | virtual int getCpuID() { | |
743 | return gbl.rstf_pre212? tr->cpuid: rstf_instrT_get_cpuid(tr); | |
744 | } | |
745 | ||
746 | protected: | |
747 | rstf_instrT* tr; | |
748 | rstf_instrT* tr_orig; | |
749 | }; // RSTF_Instr | |
750 | ||
751 | #if 0 // deprecated | |
752 | //====================================================================== | |
753 | //====================================================================== | |
754 | // ASI_T is deprecated, is replaced by TRACEINFO_T with the same enum value. | |
755 | class RSTF_Asi : public Trace { | |
756 | public: | |
757 | virtual void count() { | |
758 | gbl.rcount++; | |
759 | gbl.asicount++; | |
760 | } | |
761 | ||
762 | virtual void print_rec(uint64_t idx) { | |
763 | if (gbl.showIdx) { | |
764 | fprintf(gbl.outfp , "%6lld ", idx); | |
765 | } | |
766 | ||
767 | //FIXME should use rstf_traceinfoT, but it is not done yet, stay tune. | |
768 | ||
769 | fprintf(gbl.outfp, "asi : rtype=%d asi=%d", tr->rtype, tr->asi); | |
770 | fprintf(gbl.outfp, "\n"); | |
771 | } // RSTF_Asi::print_rec() | |
772 | ||
773 | virtual void inc_tr() { | |
774 | tr++; | |
775 | } // RSTF_Asi::inc_tr() | |
776 | ||
777 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
778 | tr = (rstf_asiT*) ptr; | |
779 | ||
780 | if (set_orig) { | |
781 | tr_orig = tr; | |
782 | } | |
783 | } // RSTF_Asi::set_tr() | |
784 | ||
785 | virtual void reset_tr() { | |
786 | tr = tr_orig; | |
787 | } // RSTF_Asi::reset_tr() | |
788 | ||
789 | protected: | |
790 | rstf_asiT* tr; | |
791 | rstf_asiT* tr_orig; | |
792 | }; // RSTF_Asi | |
793 | #endif | |
794 | ||
795 | //====================================================================== | |
796 | //====================================================================== | |
797 | class RSTF_Traceinfo : public Trace { | |
798 | public: | |
799 | virtual void count() { | |
800 | gbl.rcount++; | |
801 | gbl.traceinfocount++; | |
802 | } | |
803 | ||
804 | virtual void print_rec(uint64_t idx) { | |
805 | if (gbl.showIdx) { | |
806 | fprintf(gbl.outfp , "%6lld ", idx); | |
807 | } | |
808 | ||
809 | switch(ti_level->rtype2) { | |
810 | case RSTT2_NLEVEL_T: | |
811 | { time_t t = ti_level->time64; | |
812 | fprintf(gbl.outfp, "trinfo : LEVEL=%d time=%s", ti_level->level, ctime(&t)); | |
813 | } | |
814 | break; | |
815 | case RSTT2_CPUINFO_T: | |
816 | fprintf(gbl.outfp, "trinfo : NCPUS=%d mincpuid=%d maxcpuid=%d\n", ti_cpuinfo->numcpus, | |
817 | ti_cpuinfo->min_cpu_id, ti_cpuinfo->max_cpu_id); | |
818 | break; | |
819 | case RSTT2_CPUIDINFO_T: | |
820 | fprintf(gbl.outfp, "trinfo : CPUIDS={ "); | |
821 | int i; | |
822 | for (i=0; i<10; i++) { | |
823 | fprintf(gbl.outfp, "%d,", ti_cpuid->cpuids[i]); | |
824 | } | |
825 | fprintf(gbl.outfp, "}\n"); | |
826 | break; | |
827 | ||
828 | default: | |
829 | fprintf(gbl.outfp, "Unknown TRACEINFO record\n"); | |
830 | } | |
831 | } // RSTF_Traceinfo::print_rec() | |
832 | ||
833 | virtual void inc_tr() { | |
834 | ti_level++; | |
835 | } // RSTF_Traceinfo::inc_tr() | |
836 | ||
837 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
838 | ti_level = (rstf_traceinfo_levelT*) ptr; | |
839 | ti_cpuinfo = (rstf_cpuinfoT*) ptr; | |
840 | ti_cpuid = (rstf_cpuidinfoT*) ptr; | |
841 | ||
842 | if (set_orig) { | |
843 | tr_orig = ti_level; | |
844 | } | |
845 | } // RSTF_Traceinfo::set_tr() | |
846 | ||
847 | virtual void reset_tr() { | |
848 | ti_level = (rstf_traceinfo_levelT*) tr_orig; | |
849 | ti_cpuinfo = (rstf_cpuinfoT*) tr_orig; | |
850 | ti_cpuid = (rstf_cpuidinfoT*) tr_orig; | |
851 | } // RSTF_Traceinfo::reset_tr() | |
852 | ||
853 | protected: | |
854 | rstf_traceinfo_levelT* ti_level; | |
855 | rstf_cpuinfoT * ti_cpuinfo; | |
856 | rstf_cpuidinfoT * ti_cpuid; | |
857 | rstf_traceinfo_levelT* tr_orig; | |
858 | }; // RSTF_Traceinfo | |
859 | ||
860 | //====================================================================== | |
861 | //====================================================================== | |
862 | class RSTF_Tlb : public Trace { | |
863 | public: | |
864 | virtual void count() { | |
865 | gbl.rcount++; | |
866 | gbl.tlbcount++; | |
867 | } | |
868 | ||
869 | virtual void print_rec(uint64_t idx) { | |
870 | uint64_t pa; | |
871 | ||
872 | pa = tr->tte_data; | |
873 | pa &= (~ 0x1fffULL); | |
874 | pa &= 0x7ffffffffffULL; | |
875 | ||
876 | if (gbl.showIdx) { | |
877 | fprintf(gbl.outfp , "%6lld ", idx); | |
878 | } | |
879 | ||
880 | fprintf(gbl.outfp, "tlb : cpuid=%d demap=%d ", getCpuID(), tr->demap); | |
881 | fprintf(gbl.outfp, "type=%d ", tr->tlb_type); | |
882 | //fprintf(gbl.outfp, "valid=%d ", tr->valid); | |
883 | fprintf(gbl.outfp, "index=%-4d ", tr->tlb_index); | |
884 | fprintf(gbl.outfp, "no=%d ", tr->tlb_no); | |
885 | //fprintf(gbl.outfp, "state=0x%04x ", tr->state); | |
886 | //fprintf(gbl.outfp, "context=0x%04x ", tr->context); | |
887 | fprintf(gbl.outfp, "tag=0x%016llx ", tr->tte_tag); | |
888 | fprintf(gbl.outfp, "data=0x%016llx ", tr->tte_data); | |
889 | fprintf(gbl.outfp, "pa=0x%llx", pa); | |
890 | fprintf(gbl.outfp, "\n"); | |
891 | } // RSTF_Tlb::print_rec() | |
892 | ||
893 | virtual void inc_tr() { | |
894 | tr++; | |
895 | } // RSTF_Tlb::inc_tr() | |
896 | ||
897 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
898 | tr = (rstf_tlbT*) ptr; | |
899 | ||
900 | if (set_orig) { | |
901 | tr_orig = tr; | |
902 | } | |
903 | } // RSTF_Tlb::set_tr() | |
904 | ||
905 | virtual void reset_tr() { | |
906 | tr = tr_orig; | |
907 | } // RSTF_Tlb::reset_tr() | |
908 | ||
909 | virtual int getCpuID() { | |
910 | return gbl.rstf_pre212? tr->cpuid: rstf_tlbT_get_cpuid(tr); | |
911 | } | |
912 | ||
913 | protected: | |
914 | rstf_tlbT* tr; | |
915 | rstf_tlbT* tr_orig; | |
916 | }; // RSTF_Tlb | |
917 | ||
918 | //====================================================================== | |
919 | //====================================================================== | |
920 | class RSTF_Thread : public Trace { | |
921 | public: | |
922 | virtual void count() { | |
923 | gbl.rcount++; | |
924 | gbl.threadcount++; | |
925 | } | |
926 | ||
927 | virtual void print_rec(uint64_t idx) { | |
928 | if (gbl.showIdx) { | |
929 | fprintf(gbl.outfp , "%6lld ", idx); | |
930 | } | |
931 | ||
932 | fprintf(gbl.outfp, "thread : rtype=%d", tr->rtype); | |
933 | //fprintf(gbl.outfp, "thread : rtype=%d newtid=%d newpid=%d", | |
934 | // tr->rtype, tr->newtid, tr->newpid); | |
935 | fprintf(gbl.outfp, "\n"); | |
936 | } // RSTF_Thread::print_rec() | |
937 | ||
938 | virtual void inc_tr() { | |
939 | tr++; | |
940 | } // RSTF_Thread::inc_tr() | |
941 | ||
942 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
943 | tr = (rstf_threadT*) ptr; | |
944 | ||
945 | if (set_orig) { | |
946 | tr_orig = tr; | |
947 | } | |
948 | } // RSTF_Thread::set_tr() | |
949 | ||
950 | virtual void reset_tr() { | |
951 | tr = tr_orig; | |
952 | } // RSTF_Thread::reset_tr() | |
953 | ||
954 | protected: | |
955 | rstf_threadT* tr; | |
956 | rstf_threadT* tr_orig; | |
957 | }; // RSTF_Thread | |
958 | ||
959 | inline void | |
960 | decode_pstate_bits (FILE* const out, uint16_t pstate) | |
961 | { | |
962 | fprintf (out, "("); | |
963 | if ((pstate & 0x800) != 0) { // Cheetah specific | |
964 | fprintf(out, " IG"); | |
965 | } | |
966 | if ((pstate & 0x400) != 0) { // Cheetah specific | |
967 | fprintf(out, " MG"); | |
968 | } | |
969 | if ((pstate & 0x4) != 0) { | |
970 | fprintf(out, " PRIV"); | |
971 | } | |
972 | if ((pstate & 0x2) != 0) { | |
973 | fprintf(out, " IE"); | |
974 | } | |
975 | if ((pstate & 0x1) != 0) { | |
976 | fprintf(out, " AG"); | |
977 | } | |
978 | fprintf (out, ") "); | |
979 | } | |
980 | //====================================================================== | |
981 | //====================================================================== | |
982 | class RSTF_Trap : public Trace { | |
983 | public: | |
984 | virtual void count() { | |
985 | gbl.rcount++; | |
986 | gbl.trapcount++; | |
987 | } | |
988 | ||
989 | virtual void print_rec(uint64_t idx) { | |
990 | if (gbl.showIdx) { | |
991 | fprintf(gbl.outfp , "%6lld ", idx); | |
992 | } | |
993 | ||
994 | fprintf(gbl.outfp, "trap : cpuid=%d ", getCpuID()); | |
995 | fprintf(gbl.outfp, "async==%d ", tr->is_async); | |
996 | fprintf(gbl.outfp, "tl=%d ", tr->tl); | |
997 | fprintf(gbl.outfp, "ttype=0x%03x ", tr->ttype); | |
998 | switch (tr->ttype) { | |
999 | ||
1000 | case 0x12: | |
1001 | fprintf(gbl.outfp, "(unimplemented LDD instr) "); | |
1002 | break; | |
1003 | ||
1004 | case 0x24: case 0x25: case 0x26: case 0x27: | |
1005 | fprintf(gbl.outfp, "(clean window) "); | |
1006 | break; | |
1007 | ||
1008 | case 0x40: case 0x41: case 0x42: case 0x43: | |
1009 | case 0x44: case 0x45: case 0x46: case 0x47: | |
1010 | case 0x48: case 0x49: case 0x4A: case 0x4B: | |
1011 | case 0x4C: case 0x4D: case 0x4E: case 0x4F: | |
1012 | fprintf(gbl.outfp, "(interrupt request lvl n) "); | |
1013 | break; | |
1014 | ||
1015 | case 0x60: | |
1016 | fprintf(gbl.outfp, "(interrupt request) "); | |
1017 | break; | |
1018 | ||
1019 | case 0x64: case 0x65: case 0x66: case 0x67: | |
1020 | fprintf(gbl.outfp, "(ITLB miss) "); | |
1021 | break; | |
1022 | ||
1023 | case 0x68: case 0x69: case 0x6A: case 0x6B: | |
1024 | fprintf(gbl.outfp, "(DTLB miss) "); | |
1025 | break; | |
1026 | ||
1027 | case 0x80: case 0x81: case 0x82: case 0x83: | |
1028 | case 0x84: case 0x85: case 0x86: case 0x87: | |
1029 | case 0x88: case 0x89: case 0x8A: case 0x8B: | |
1030 | case 0x8C: case 0x8D: case 0x8E: case 0x8F: | |
1031 | case 0x90: case 0x91: case 0x92: case 0x93: | |
1032 | case 0x94: case 0x95: case 0x96: case 0x97: | |
1033 | case 0x98: case 0x99: case 0x9A: case 0x9B: | |
1034 | case 0x9C: case 0x9D: case 0x9E: case 0x9F: | |
1035 | fprintf(gbl.outfp, "(spill normal) "); | |
1036 | break; | |
1037 | ||
1038 | case 0xA0: case 0xA1: case 0xA2: case 0xA3: | |
1039 | case 0xA4: case 0xA5: case 0xA6: case 0xA7: | |
1040 | case 0xA8: case 0xA9: case 0xAA: case 0xAB: | |
1041 | case 0xAC: case 0xAD: case 0xAE: case 0xAF: | |
1042 | case 0xB0: case 0xB1: case 0xB2: case 0xB3: | |
1043 | case 0xB4: case 0xB5: case 0xB6: case 0xB7: | |
1044 | case 0xB8: case 0xB9: case 0xBA: case 0xBB: | |
1045 | case 0xBC: case 0xBD: case 0xBE: case 0xBF: | |
1046 | fprintf(gbl.outfp, "(spill other) "); | |
1047 | break; | |
1048 | ||
1049 | case 0xC0: case 0xC1: case 0xC2: case 0xC3: | |
1050 | case 0xC4: case 0xC5: case 0xC6: case 0xC7: | |
1051 | case 0xC8: case 0xC9: case 0xCA: case 0xCB: | |
1052 | case 0xCC: case 0xCD: case 0xCE: case 0xCF: | |
1053 | case 0xD0: case 0xD1: case 0xD2: case 0xD3: | |
1054 | case 0xD4: case 0xD5: case 0xD6: case 0xD7: | |
1055 | case 0xD8: case 0xD9: case 0xDA: case 0xDB: | |
1056 | case 0xDC: case 0xDD: case 0xDE: case 0xDF: | |
1057 | fprintf(gbl.outfp, "(fill normal) "); | |
1058 | break; | |
1059 | ||
1060 | // 0x100 - 0x176 - Tcc instruction executed | |
1061 | case 0x100: case 0x101: case 0x102: case 0x103: | |
1062 | case 0x108: case 0x109: case 0x10a: case 0x10b: | |
1063 | case 0x120: case 0x121: case 0x122: case 0x123: | |
1064 | case 0x124: case 0x125: case 0x126: case 0x127: | |
1065 | case 0x140: | |
1066 | fprintf(gbl.outfp, "(tcc instr.) "); | |
1067 | break; | |
1068 | ||
1069 | default: | |
1070 | /* do nothing */ | |
1071 | break; | |
1072 | } | |
1073 | fprintf(gbl.outfp, "pstate=0x%03x ", tr->pstate); | |
1074 | decode_pstate_bits (gbl.outfp, tr->pstate); | |
1075 | fprintf(gbl.outfp, "syscall=0x%04x ", tr->syscall); | |
1076 | fprintf(gbl.outfp, "pc=0x%016llx ", tr->pc); | |
1077 | fprintf(gbl.outfp, "npc=0x%016llx", tr->npc); | |
1078 | fprintf(gbl.outfp, "\n"); | |
1079 | } // RSTF_Trap::print_rec() | |
1080 | ||
1081 | virtual uint64_t get_pc() { | |
1082 | return tr->pc; | |
1083 | } // RSTF_Trap::get_pc() | |
1084 | ||
1085 | virtual void inc_tr() { | |
1086 | tr++; | |
1087 | } // RSTF_Trap::inc_tr() | |
1088 | ||
1089 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1090 | tr = (rstf_trapT*) ptr; | |
1091 | ||
1092 | if (set_orig) { | |
1093 | tr_orig = tr; | |
1094 | } | |
1095 | } // RSTF_Trap::set_tr() | |
1096 | ||
1097 | virtual void reset_tr() { | |
1098 | tr = tr_orig; | |
1099 | } // RSTF_Trap::reset_tr() | |
1100 | ||
1101 | virtual int getCpuID() { | |
1102 | return gbl.rstf_pre212? tr->cpuid: rstf_trapT_get_cpuid(tr); | |
1103 | } | |
1104 | ||
1105 | protected: | |
1106 | rstf_trapT* tr; | |
1107 | rstf_trapT* tr_orig; | |
1108 | }; // RSTF_Trap | |
1109 | ||
1110 | //====================================================================== | |
1111 | //====================================================================== | |
1112 | class RSTF_Trapexit : public Trace { | |
1113 | public: | |
1114 | virtual void count() { | |
1115 | gbl.rcount++; | |
1116 | gbl.trapexitcount++; | |
1117 | } | |
1118 | ||
1119 | virtual void print_rec(uint64_t idx) { | |
1120 | if (gbl.showIdx) { | |
1121 | fprintf(gbl.outfp , "%6lld ", idx); | |
1122 | } | |
1123 | ||
1124 | fprintf(gbl.outfp, "trapexit: cpuid=%d tl=%d ", getCpuID(), tr->tl); | |
1125 | fprintf(gbl.outfp, "tstate=%d ", tr->tstate); | |
1126 | //fprintf(gbl.outfp, "pc=0x%016llx ", tr->pc); | |
1127 | //fprintf(gbl.outfp, "npc=0x%016llx ", tr->npc); | |
1128 | fprintf(gbl.outfp, "\n"); | |
1129 | } // RSTF_Trapexit::print_rec() | |
1130 | ||
1131 | #if 0 | |
1132 | virtual uint64_t get_pc() { | |
1133 | return tr->pc; | |
1134 | } // RSTF_Trapexit::get_pc() | |
1135 | #endif | |
1136 | ||
1137 | virtual void inc_tr() { | |
1138 | tr++; | |
1139 | } // RSTF_Trapexit::inc_tr() | |
1140 | ||
1141 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1142 | tr = (rstf_trapexitT*) ptr; | |
1143 | ||
1144 | if (set_orig) { | |
1145 | tr_orig = tr; | |
1146 | } | |
1147 | } // RSTF_Trapexit::set_tr() | |
1148 | ||
1149 | virtual void reset_tr() { | |
1150 | tr = tr_orig; | |
1151 | } // RSTF_Trapexit::reset_tr() | |
1152 | ||
1153 | virtual int getCpuID() { | |
1154 | return gbl.rstf_pre212? tr->cpuid: rstf_trapexitT_get_cpuid(tr); | |
1155 | } | |
1156 | ||
1157 | protected: | |
1158 | rstf_trapexitT* tr; | |
1159 | rstf_trapexitT* tr_orig; | |
1160 | }; // RSTF_Trapexit | |
1161 | ||
1162 | ||
1163 | ||
1164 | //====================================================================== | |
1165 | //====================================================================== | |
1166 | class RSTF_Regval : public Trace { | |
1167 | public: | |
1168 | virtual void count() { | |
1169 | gbl.rcount++; | |
1170 | gbl.regvalcount++; | |
1171 | } | |
1172 | ||
1173 | #ifdef _VALUE_TRACE | |
1174 | virtual void print_rec_valueTrace(uint64_t idx) { | |
1175 | if (gbl.showIdx) { | |
1176 | fprintf(gbl.outfp , "%6lld ", idx); | |
1177 | } | |
1178 | ||
1179 | fprintf(gbl.outfp, "regval : "); | |
1180 | fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); | |
1181 | // fprintf(gbl.outfp, "postInstr=%d ", tr->postInstr); | |
1182 | for(long i=0; i<2; i++) { | |
1183 | vtPrintReg(gbl.outfp, tr->regtype[i], tr->regid[i], tr->reg64[i], i); | |
1184 | } | |
1185 | fprintf(gbl.outfp, "\n"); | |
1186 | } // RSTF_Regval::print_rec() | |
1187 | #endif // _VALUE_TRACE | |
1188 | virtual void print_rec_normal(uint64_t idx) { | |
1189 | if (gbl.showIdx) { | |
1190 | fprintf(gbl.outfp , "%6lld ", idx); | |
1191 | } | |
1192 | ||
1193 | fprintf(gbl.outfp, "regval : "); | |
1194 | fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); | |
1195 | fprintf(gbl.outfp, "postInstr=%d ", tr->postInstr); | |
1196 | fprintf(gbl.outfp, "regtype[0]=%d ", tr->regtype[0]); | |
1197 | fprintf(gbl.outfp, "regid[0]=%d ", tr->regid[0]); | |
1198 | fprintf(gbl.outfp, "reg64[0]=0x%llx ", tr->reg64[0]); | |
1199 | fprintf(gbl.outfp, "regtype[1]=%d ", tr->regtype[1]); | |
1200 | fprintf(gbl.outfp, "regid[1]=%d ", tr->regid[1]); | |
1201 | fprintf(gbl.outfp, "reg64[1]=0x%llx", tr->reg64[1]); | |
1202 | fprintf(gbl.outfp, "\n"); | |
1203 | //fprintf(gbl.outfp, "regnum=%d ", tr->regnum); | |
1204 | //fprintf(gbl.outfp, "reg32=%d ", tr->reg32); | |
1205 | } // RSTF_Regval::print_rec() | |
1206 | ||
1207 | virtual void print_rec(uint64_t idx) { | |
1208 | #ifdef _VALUE_TRACE | |
1209 | if (gbl.valueTrace) { | |
1210 | print_rec_valueTrace(idx); | |
1211 | } else | |
1212 | #endif // _VALUE_TRACE | |
1213 | { | |
1214 | print_rec_normal(idx); | |
1215 | } | |
1216 | } | |
1217 | ||
1218 | virtual void inc_tr() { | |
1219 | tr++; | |
1220 | } // RSTF_Regval::inc_tr() | |
1221 | ||
1222 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1223 | tr = (rstf_regvalT*) ptr; | |
1224 | ||
1225 | if (set_orig) { | |
1226 | tr_orig = tr; | |
1227 | } | |
1228 | } // RSTF_Regval::set_tr() | |
1229 | ||
1230 | virtual void reset_tr() { | |
1231 | tr = tr_orig; | |
1232 | } // RSTF_Regval::reset_tr() | |
1233 | ||
1234 | virtual int getCpuID() { | |
1235 | return gbl.rstf_pre212? tr->cpuid: rstf_regvalT_get_cpuid(tr); | |
1236 | } | |
1237 | ||
1238 | protected: | |
1239 | rstf_regvalT* tr; | |
1240 | rstf_regvalT* tr_orig; | |
1241 | #ifdef _VALUE_TRACE | |
1242 | virtual void | |
1243 | vtPrintIntRegName(FILE *outfp, long regid) | |
1244 | { | |
1245 | if (regid < 0 || regid >= 32) { | |
1246 | fprintf(stderr, "trconv: warning: Register number %d should be <32 (Rec #%llu)\n", regid, gbl.rcount); | |
1247 | } | |
1248 | static char prefix[5] = "goli"; | |
1249 | char toprint[3] = "g0"; | |
1250 | toprint[0] = prefix[(regid/8)]; | |
1251 | toprint[1] = '0' + (regid%8); | |
1252 | fprintf(outfp, "%%%s ", toprint); | |
1253 | } | |
1254 | ||
1255 | virtual void | |
1256 | vtPrintFloatReg(FILE *outfp, long regid, uint64_t reg64, | |
1257 | long i, char &isQuad, uint64_t &quadWord) | |
1258 | { | |
1259 | if (regid >= 0 && regid < 32) { | |
1260 | // Single | |
1261 | if(isQuad) { | |
1262 | fprintf(stderr, | |
1263 | "trconv: warning: quad register encountered (#%llu)\n", | |
1264 | gbl.rcount); | |
1265 | } | |
1266 | float f = (float) reg64; | |
1267 | fprintf(outfp, "(Reg %d: %%f%d = %f(0x%llx)) ", i, regid, f, reg64); | |
1268 | } | |
1269 | else if (regid < 64) { | |
1270 | // Double | |
1271 | if(isQuad) { | |
1272 | fprintf(stderr, | |
1273 | "trconv: warning: quad register encountered (#%llu)\n", | |
1274 | gbl.rcount); | |
1275 | } | |
1276 | double d = (double) reg64; | |
1277 | fprintf(outfp, "(Reg %d: %%d%d = %f(0x%llx)) ", i, ((regid - 32) * 2), d, reg64); | |
1278 | } | |
1279 | else { | |
1280 | if (regid >= 80) { | |
1281 | fprintf(stderr, "trconv: warning: regid = %d should have been <80 (Rec #%llu\n", regid, gbl.rcount); | |
1282 | } | |
1283 | if (i == 0) { | |
1284 | isQuad = 1; | |
1285 | quadWord = reg64; | |
1286 | } | |
1287 | else { | |
1288 | if(isQuad) { | |
1289 | fprintf(stderr, | |
1290 | "trconv: warning: quad register encountered (#%llu)\n", | |
1291 | gbl.rcount); | |
1292 | } | |
1293 | fprintf(outfp, "(Reg 0+1: %%q%d = 0x%016llx%016llx) ", | |
1294 | i, ((regid - 64) * 4), quadWord, reg64); | |
1295 | } | |
1296 | } | |
1297 | } | |
1298 | ||
1299 | virtual void | |
1300 | vtPrintPrivReg(FILE *outfp, long regid) | |
1301 | { | |
1302 | switch (regid) { | |
1303 | case RSTREG_TPC_R: fprintf(outfp, "%%tpc "); break; | |
1304 | case RSTREG_TNPC_R: fprintf(outfp, "%%tnpc "); break; | |
1305 | case RSTREG_TSTATE_R: fprintf(outfp, "%%tstate "); break; | |
1306 | case RSTREG_TT_R: fprintf(outfp, "%%tt "); break; | |
1307 | case RSTREG_TICK_R: fprintf(outfp, "%%tick "); break; | |
1308 | case RSTREG_TBA_R: fprintf(outfp, "%%tba "); break; | |
1309 | case RSTREG_PSTATE_R: fprintf(outfp, "%%pstate "); break; | |
1310 | case RSTREG_TL_R: fprintf(outfp, "%%tl "); break; | |
1311 | case RSTREG_PIL_R: fprintf(outfp, "%%pil "); break; | |
1312 | case RSTREG_CWP_R: fprintf(outfp, "%%cwp "); break; | |
1313 | case RSTREG_CANSAVE_R: fprintf(outfp, "%%cansave "); break; | |
1314 | case RSTREG_CANRESTORE_R: fprintf(outfp, "%%canrestore "); break; | |
1315 | case RSTREG_CLEANWIN_R: fprintf(outfp, "%%cleanwin "); break; | |
1316 | case RSTREG_OTHERWIN_R: fprintf(outfp, "%%otherwin "); break; | |
1317 | case RSTREG_WSTATE_R: fprintf(outfp, "%%wstate "); break; | |
1318 | case RSTREG_FQ_R: fprintf(outfp, "%%fq "); break; | |
1319 | case RSTREG_VERSION_R: fprintf(outfp, "%%ver "); break; | |
1320 | case RSTREG_TPC_RBASE + 0: | |
1321 | case RSTREG_TPC_RBASE + 1: | |
1322 | case RSTREG_TPC_RBASE + 2: | |
1323 | case RSTREG_TPC_RBASE + 3: | |
1324 | case RSTREG_TPC_RBASE + 4: | |
1325 | if (regid == RSTREG_TPC_RBASE){ // does not make sense to have trap level 0 | |
1326 | fprintf(stderr, "trconv: warning: TPC should not be present for trap level 0 (#%llu) \n", gbl.rcount); | |
1327 | } | |
1328 | fprintf(outfp, "%%tpc[%d]", regid-RSTREG_TPC_RBASE); break; | |
1329 | case RSTREG_TNPC_RBASE + 0: | |
1330 | case RSTREG_TNPC_RBASE + 1: | |
1331 | case RSTREG_TNPC_RBASE + 2: | |
1332 | case RSTREG_TNPC_RBASE + 3: | |
1333 | case RSTREG_TNPC_RBASE + 4: | |
1334 | if (regid == RSTREG_TNPC_RBASE){ // does not make sense to have trap level 0 | |
1335 | fprintf(stderr, "trconv: warning: TNPC should not be present for trap level 0 (#%llu) \n", gbl.rcount); | |
1336 | } | |
1337 | fprintf(outfp, "%%tnpc[%d]", regid-RSTREG_TNPC_RBASE); break; | |
1338 | case RSTREG_TSTATE_RBASE + 0: | |
1339 | case RSTREG_TSTATE_RBASE + 1: | |
1340 | case RSTREG_TSTATE_RBASE + 2: | |
1341 | case RSTREG_TSTATE_RBASE + 3: | |
1342 | case RSTREG_TSTATE_RBASE + 4: | |
1343 | if (regid == RSTREG_TSTATE_RBASE){ // does not make sense to have trap level 0 | |
1344 | fprintf(stderr, "trconv: warning: TSTATE should not be present for trap level 0 (#%llu) \n", gbl.rcount); | |
1345 | } | |
1346 | fprintf(outfp, "%%tstate[%d]", regid-RSTREG_TSTATE_RBASE); break; | |
1347 | case RSTREG_TT_RBASE + 0: case RSTREG_TT_RBASE + 1: case RSTREG_TT_RBASE + 2: case RSTREG_TT_RBASE + 3: case RSTREG_TT_RBASE + 4: | |
1348 | if (regid == RSTREG_TT_RBASE){ // does not make sense to have trap level 0 | |
1349 | fprintf(stderr, "trconv: warning: TT should not be present for trap level 0 (#%llu) \n", gbl.rcount); | |
1350 | } | |
1351 | fprintf(outfp, "%%tt[%d]", regid-RSTREG_TT_RBASE); break; | |
1352 | default: | |
1353 | fprintf(outfp, "%%unknownpr%d ", regid); | |
1354 | // fprintf(stderr, "trconv: warning: Unknown priv regid %d (#%llu)", regid, gbl.rcount); | |
1355 | break; | |
1356 | } | |
1357 | } | |
1358 | ||
1359 | virtual void | |
1360 | vtPrintOtherReg(FILE *outfp, long regid) | |
1361 | { | |
1362 | switch (regid) { | |
1363 | case RSTREG_Y_R: fprintf(outfp, "%%y "); break; | |
1364 | case RSTREG_CC_R: fprintf(outfp, "%%cc "); break; | |
1365 | case RSTREG_ASI_R: fprintf(outfp, "%%asi "); break; | |
1366 | case RSTREG_TICK_R: fprintf(outfp, "%%tick "); break; | |
1367 | case RSTREG_PC_R: fprintf(outfp, "%%pc "); break; | |
1368 | case RSTREG_FPRS_R: fprintf(outfp, "%%fprs "); break; | |
1369 | // case RSTREG_ASR_R: fprintf(outfp, "%%asr "); break; | |
1370 | case RSTREG_ASR_PCR_R: fprintf(outfp, "%%pcr "); break; | |
1371 | case RSTREG_ASR_PIC_R: fprintf(outfp, "%%pic "); break; | |
1372 | case RSTREG_ASR_IEU_CTRL_R: fprintf(outfp, "%%ieu_ctrl "); break; | |
1373 | case RSTREG_ASR_GSR_R: fprintf(outfp, "%%gsr "); break; | |
1374 | case RSTREG_ASR_INTR_SET_R: fprintf(outfp, "%%intr_set "); break; | |
1375 | case RSTREG_ASR_INTR_CLR_R: fprintf(outfp, "%%intr_clr "); break; | |
1376 | case RSTREG_ASR_INTR_WRITE_R: fprintf(outfp, "%%intr_write "); break; | |
1377 | case RSTREG_ASR_TICK_CMPR_R: fprintf(outfp, "%%tick_cmpr "); break; | |
1378 | case RSTREG_ASR_STICK_REG_R: fprintf(outfp, "%%stick "); break; | |
1379 | case RSTREG_ASR_STICK_CMPR_R: fprintf(outfp, "%%stick_cmpr "); break; | |
1380 | case RSTREG_ASR_STICK_THR_STR_R: fprintf(outfp, "%%stick_thr_str "); break; | |
1381 | case RSTREG_ASR_NPC_R: fprintf(outfp, "%%npc "); break; | |
1382 | case RSTREG_ASR_FSR_R: fprintf(outfp, "%%fsr "); break; | |
1383 | ||
1384 | default: | |
1385 | fprintf(outfp, "%%UnknownASR "); | |
1386 | break; | |
1387 | } | |
1388 | } | |
1389 | ||
1390 | virtual void | |
1391 | vtPrintReg(FILE *outfp, long regtype, long regid, uint64_t reg64, int i) | |
1392 | { | |
1393 | static char isQuad = 0; | |
1394 | static uint64_t quadWord = 0x0; | |
1395 | switch (regtype) { | |
1396 | case RSTREG_INT_RT: | |
1397 | if(isQuad) { | |
1398 | fprintf(stderr, | |
1399 | "trconv: warning: quad register encountered (#%llu)\n", | |
1400 | gbl.rcount); | |
1401 | } | |
1402 | fprintf(outfp, "(Reg %d: ", i); | |
1403 | vtPrintIntRegName(outfp, regid); | |
1404 | fprintf(outfp, "= 0x%llx) ", reg64); | |
1405 | break; | |
1406 | case RSTREG_FLOAT_RT: | |
1407 | vtPrintFloatReg(outfp, regid, reg64, i, isQuad, quadWord); | |
1408 | break; | |
1409 | case RSTREG_PRIV_RT: | |
1410 | if(isQuad) { | |
1411 | fprintf(stderr, | |
1412 | "trconv: warning: quad register encountered (#%llu)\n", | |
1413 | gbl.rcount); | |
1414 | } | |
1415 | fprintf(outfp, "(Reg %d: ", i); | |
1416 | vtPrintPrivReg(outfp, regid); | |
1417 | fprintf(outfp, "= 0x%llx) ", reg64); | |
1418 | if (regid == RSTREG_PSTATE_R) | |
1419 | decode_pstate_bits (outfp, reg64); | |
1420 | break; | |
1421 | case RSTREG_OTHER_RT: | |
1422 | if(isQuad) { | |
1423 | fprintf(stderr, | |
1424 | "trconv: warning: quad register encountered (#%llu)\n", | |
1425 | gbl.rcount); | |
1426 | } | |
1427 | fprintf(outfp, "(Reg %d: ", i); | |
1428 | vtPrintOtherReg(outfp, regid); | |
1429 | fprintf(outfp, "= 0x%llx) ", reg64); | |
1430 | break; | |
1431 | case RSTREG_UNUSED_RT: | |
1432 | if(isQuad) { | |
1433 | fprintf(stderr, | |
1434 | "trconv: warning: quad register encountered (#%llu)\n", | |
1435 | gbl.rcount); | |
1436 | } | |
1437 | // fprintf(outfp, "(Reg %d unused)", i); | |
1438 | break; | |
1439 | case RSTREG_CC_RT: | |
1440 | fprintf(outfp, "(Reg %d: %%ccr=0x%02x) ", i, regid); | |
1441 | break; | |
1442 | case RSTREG_FCC_RT: | |
1443 | fprintf(outfp, "(Reg %d: %%fcc=0x%02x) ", i, regid); | |
1444 | break; | |
1445 | case RSTREG_MMU_RT: | |
1446 | if (regid == RSTREG_MMU_PCONTEXT) { | |
1447 | fprintf(outfp, "(Reg %d: PContext=0x%02llx) ", i, reg64); | |
1448 | } else if (regid == RSTREG_MMU_SCONTEXT) { | |
1449 | fprintf(outfp, "(Reg %d: SContext=0x%02llx) ", i, reg64); | |
1450 | } else { | |
1451 | fprintf(stderr, "trconv: warning: (#%llu) (Reg %d: Unknown MMU RegID %d = 0x%02x)\n", | |
1452 | gbl.rcount, i, regid, reg64); | |
1453 | } | |
1454 | break; | |
1455 | ||
1456 | case RSTREG_HPRIV_RT: | |
1457 | switch(regid) { | |
1458 | case RSTREG_HPR_HPSTATE: | |
1459 | fprintf(outfp, "(Reg %d: %%hpstate=0x%llx) ", i, reg64); | |
1460 | break; | |
1461 | case RSTREG_HPR_HTSTATE: | |
1462 | fprintf(outfp, "(Reg %d: %%htstate=0x%llx) ", i, reg64); | |
1463 | break; | |
1464 | case RSTREG_HPR_HINTP: | |
1465 | fprintf(outfp, "(Reg %d: %%hintp=0x%llx) ", i, reg64); | |
1466 | break; | |
1467 | case RSTREG_HPR_HTBA: | |
1468 | fprintf(outfp, "(Reg %d: %%htba=0x%llx) ", i, reg64); | |
1469 | break; | |
1470 | case RSTREG_HPR_HVER: | |
1471 | fprintf(outfp, "(Reg %d: %%hver=0x%llx) ", i, reg64); | |
1472 | break; | |
1473 | case RSTREG_HPR_HSTICK_CMPR: | |
1474 | fprintf(outfp, "(Reg %d: %%hstick_cmpr=0x%llx) ", i, reg64); | |
1475 | break; | |
1476 | default: | |
1477 | fprintf(outfp, "(Reg %d: UnknownHPR%d = 0x%llx) ", i, regid, reg64); | |
1478 | } | |
1479 | break; | |
1480 | ||
1481 | default: | |
1482 | fprintf(stderr, "trconv: warning: Unknown regtype %d for reg[%d] (#%llu)", regtype, i, gbl.rcount); | |
1483 | break; | |
1484 | } | |
1485 | } | |
1486 | #endif // _VALUE_TRACE | |
1487 | }; // RSTF_Regval | |
1488 | ||
1489 | //====================================================================== | |
1490 | //====================================================================== | |
1491 | class RSTF_Cpu : public Trace { | |
1492 | public: | |
1493 | virtual void count() { | |
1494 | gbl.rcount++; | |
1495 | gbl.cpucount++; | |
1496 | } | |
1497 | ||
1498 | virtual void print_rec(uint64_t idx) { | |
1499 | if (gbl.showIdx) { | |
1500 | fprintf(gbl.outfp , "%6lld ", idx); | |
1501 | } | |
1502 | ||
1503 | fprintf(gbl.outfp, "cpu : cpuid=%d ", getCpuID()); | |
1504 | fprintf(gbl.outfp, "timestamp=%llu", tr->timestamp); | |
1505 | fprintf(gbl.outfp, "\n"); | |
1506 | } // RSTF_Cpu::print_rec() | |
1507 | ||
1508 | virtual void inc_tr() { | |
1509 | tr++; | |
1510 | } // RSTF_Cpu::inc_tr() | |
1511 | ||
1512 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1513 | tr = (rstf_cpuT*) ptr; | |
1514 | ||
1515 | if (set_orig) { | |
1516 | tr_orig = tr; | |
1517 | } | |
1518 | } // RSTF_Cpu::set_tr() | |
1519 | ||
1520 | virtual void reset_tr() { | |
1521 | tr = tr_orig; | |
1522 | } // RSTF_Cpu::reset_tr() | |
1523 | ||
1524 | virtual int getCpuID() { | |
1525 | return tr->cpu; | |
1526 | } | |
1527 | ||
1528 | protected: | |
1529 | rstf_cpuT* tr; | |
1530 | rstf_cpuT* tr_orig; | |
1531 | }; // RSTF_Cpu | |
1532 | ||
1533 | //====================================================================== | |
1534 | //====================================================================== | |
1535 | class RSTF_Process : public Trace { | |
1536 | public: | |
1537 | virtual void count() { | |
1538 | gbl.rcount++; | |
1539 | gbl.processcount++; | |
1540 | } | |
1541 | ||
1542 | virtual void print_rec(uint64_t idx) { | |
1543 | if (gbl.showIdx) { | |
1544 | fprintf(gbl.outfp , "%6lld ", idx); | |
1545 | } | |
1546 | ||
1547 | fprintf(gbl.outfp, "process : "); | |
1548 | fprintf(gbl.outfp, "%d ", tr->oldpid); | |
1549 | fprintf(gbl.outfp, "%d ", tr->newpid); | |
1550 | fprintf(gbl.outfp, "%d ", tr->oldcontext); | |
1551 | fprintf(gbl.outfp, "%d", tr->newcontext); | |
1552 | fprintf(gbl.outfp, "\n"); | |
1553 | } // RSTF_Process::print_rec() | |
1554 | ||
1555 | virtual void inc_tr() { | |
1556 | tr++; | |
1557 | } // RSTF_Process::inc_tr() | |
1558 | ||
1559 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1560 | tr = (rstf_processT*) ptr; | |
1561 | ||
1562 | if (set_orig) { | |
1563 | tr_orig = tr; | |
1564 | } | |
1565 | } // RSTF_Process::set_tr() | |
1566 | ||
1567 | virtual void reset_tr() { | |
1568 | tr = tr_orig; | |
1569 | } // RSTF_Process::reset_tr() | |
1570 | ||
1571 | protected: | |
1572 | rstf_processT* tr; | |
1573 | rstf_processT* tr_orig; | |
1574 | }; // RSTF_Process | |
1575 | ||
1576 | //====================================================================== | |
1577 | //====================================================================== | |
1578 | class RSTF_Dma : public Trace { | |
1579 | public: | |
1580 | virtual void count() { | |
1581 | gbl.rcount++; | |
1582 | gbl.dmacount++; | |
1583 | } | |
1584 | ||
1585 | virtual void print_rec(uint64_t idx) { | |
1586 | if (gbl.showIdx) { | |
1587 | fprintf(gbl.outfp , "%6lld ", idx); | |
1588 | } | |
1589 | ||
1590 | fprintf(gbl.outfp, "dma : "); | |
1591 | //fprintf(gbl.outfp, "rtype=%d ", tr->rtype); | |
1592 | fprintf(gbl.outfp, "iswrite=%d ", tr->iswrite); | |
1593 | fprintf(gbl.outfp, "start_pa=0x%016llx ", tr->start_pa); | |
1594 | fprintf(gbl.outfp, "nbytes=%d ", tr->nbytes); | |
1595 | if (tr->devid) { | |
1596 | fprintf(gbl.outfp, "dev_id=%d ", tr->devid); | |
1597 | std::string idstring = gbl.devid2string[tr->devid]; | |
1598 | if (idstring.length() == 0) { | |
1599 | idstring = "unknown"; | |
1600 | } | |
1601 | fprintf(gbl.outfp, "(%s)", idstring.c_str()); | |
1602 | } | |
1603 | fprintf(gbl.outfp, "\n"); | |
1604 | } // RSTF_Dma::print_rec() | |
1605 | ||
1606 | virtual void inc_tr() { | |
1607 | tr++; | |
1608 | } // RSTF_Dma::inc_tr() | |
1609 | ||
1610 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1611 | tr = (rstf_dmaT*) ptr; | |
1612 | ||
1613 | if (set_orig) { | |
1614 | tr_orig = tr; | |
1615 | } | |
1616 | } // RSTF_Dma::set_tr() | |
1617 | ||
1618 | virtual void reset_tr() { | |
1619 | tr = tr_orig; | |
1620 | } // RSTF_Dma::reset_tr() | |
1621 | ||
1622 | protected: | |
1623 | rstf_dmaT* tr; | |
1624 | rstf_dmaT* tr_orig; | |
1625 | }; // RSTF_Dma | |
1626 | ||
1627 | //====================================================================== | |
1628 | //====================================================================== | |
1629 | class RSTF_String : public Trace { | |
1630 | public: | |
1631 | virtual void count() { | |
1632 | gbl.rcount++; | |
1633 | gbl.stringcount++; | |
1634 | } | |
1635 | ||
1636 | virtual void print_rec(uint64_t idx) { | |
1637 | static char desc_string[800]; | |
1638 | static char* desc_str = desc_string; | |
1639 | char cont_string[32]; | |
1640 | int i; | |
1641 | ||
1642 | if (tr->rtype == STRDESC_T) { | |
1643 | if (gbl.showIdx) { | |
1644 | fprintf(gbl.outfp , "%6lld ", idx); | |
1645 | } | |
1646 | ||
1647 | for (i = 0; i < 23; i++) { | |
1648 | if (tr->string[i] == 0) { | |
1649 | break; | |
1650 | } | |
1651 | } | |
1652 | ||
1653 | if (i == 23) { | |
1654 | fprintf(stderr, | |
1655 | "trconv: warning: strdesc string not null terminated (#%llu)\n", | |
1656 | gbl.rcount); | |
1657 | } | |
1658 | ||
1659 | strncpy(desc_str, tr->string, 23); | |
1660 | desc_str += 23; | |
1661 | desc_str[0] = 0; | |
1662 | ||
1663 | fprintf(gbl.outfp, "strdesc : \"%s\"\n", desc_string); | |
1664 | desc_str = desc_string; | |
1665 | } else { | |
1666 | strncpy(desc_str, tr->string, 23); | |
1667 | desc_str += 23; | |
1668 | desc_str[0] = 0; | |
1669 | ||
1670 | strncpy(cont_string, tr->string, 23); | |
1671 | cont_string[23] = 0; | |
1672 | ||
1673 | if (gbl.fast) { | |
1674 | if (gbl.showIdx) { | |
1675 | fprintf(gbl.outfp , "%6lld ", idx); | |
1676 | } | |
1677 | ||
1678 | fprintf(gbl.outfp, "strcont : \"%s\"\n", cont_string); | |
1679 | } | |
1680 | } | |
1681 | } // RSTF_String::print_rec() | |
1682 | ||
1683 | virtual void inc_tr() { | |
1684 | tr++; | |
1685 | } // RSTF_String::inc_tr() | |
1686 | ||
1687 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1688 | tr = (rstf_stringT*) ptr; | |
1689 | ||
1690 | if (set_orig) { | |
1691 | tr_orig = tr; | |
1692 | } | |
1693 | } // RSTF_String::set_tr() | |
1694 | ||
1695 | virtual void reset_tr() { | |
1696 | tr = tr_orig; | |
1697 | } // RSTF_String::reset_tr() | |
1698 | ||
1699 | protected: | |
1700 | rstf_stringT* tr; | |
1701 | rstf_stringT* tr_orig; | |
1702 | }; // RSTF_String | |
1703 | ||
1704 | //====================================================================== | |
1705 | //====================================================================== | |
1706 | class RSTF_Delim : public Trace { | |
1707 | public: | |
1708 | virtual void count() { | |
1709 | gbl.rcount++; | |
1710 | gbl.delimcount++; | |
1711 | } | |
1712 | ||
1713 | virtual void print_rec(uint64_t idx) { | |
1714 | if (gbl.showIdx) { | |
1715 | fprintf(gbl.outfp , "%6lld ", idx); | |
1716 | } | |
1717 | ||
1718 | if (tr->rtype == LEFTDELIM_T) { | |
1719 | fprintf(gbl.outfp, "delimTl : "); | |
1720 | } else { | |
1721 | fprintf(gbl.outfp, "delimTr : "); | |
1722 | } | |
1723 | fprintf(gbl.outfp, "id=%d ", tr->id); | |
1724 | fprintf(gbl.outfp, "what=%d ", tr->what); | |
1725 | fprintf(gbl.outfp, "length=%d", tr->length); | |
1726 | fprintf(gbl.outfp, "\n"); | |
1727 | } // RSTF_Delim::print_rec() | |
1728 | ||
1729 | virtual void inc_tr() { | |
1730 | tr++; | |
1731 | } // RSTF_Delim::inc_tr() | |
1732 | ||
1733 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1734 | tr = (rstf_delimT*) ptr; | |
1735 | ||
1736 | if (set_orig) { | |
1737 | tr_orig = tr; | |
1738 | } | |
1739 | } // RSTF_Delim::set_tr() | |
1740 | ||
1741 | virtual void reset_tr() { | |
1742 | tr = tr_orig; | |
1743 | } // RSTF_Delim::reset_tr() | |
1744 | ||
1745 | protected: | |
1746 | rstf_delimT* tr; | |
1747 | rstf_delimT* tr_orig; | |
1748 | }; // RSTF_Delim | |
1749 | ||
1750 | //====================================================================== | |
1751 | //====================================================================== | |
1752 | class RSTF_Preg : public Trace { | |
1753 | public: | |
1754 | virtual void count() { | |
1755 | gbl.rcount++; | |
1756 | gbl.pregcount++; | |
1757 | } | |
1758 | ||
1759 | virtual void print_rec(uint64_t idx) { | |
1760 | if (gbl.showIdx) { | |
1761 | fprintf(gbl.outfp , "%6lld ", idx); | |
1762 | } | |
1763 | ||
1764 | fprintf(gbl.outfp, "preg : cpuid=%d ", getCpuID()); | |
1765 | fprintf(gbl.outfp, "asiReg=%d ", tr->asiReg); | |
1766 | //fprintf(gbl.outfp, "last_context=%d ", tr->lastcontext); | |
1767 | fprintf(gbl.outfp, "trap_lvl=0x%02x ", tr->traplevel); | |
1768 | fprintf(gbl.outfp, "trap_type=0x%02x ", tr->traptype); | |
1769 | fprintf(gbl.outfp, "pstate=0x%04x ", tr->pstate); | |
1770 | decode_pstate_bits(gbl.outfp, tr->pstate); | |
1771 | fprintf(gbl.outfp, "primA=%d ", tr->primA); | |
1772 | fprintf(gbl.outfp, "secA=%d ", tr->secA); | |
1773 | fprintf(gbl.outfp, "primD=%d ", tr->primD); | |
1774 | fprintf(gbl.outfp, "secD=%d", tr->secD); | |
1775 | fprintf(gbl.outfp, "\n"); | |
1776 | } // RSTF_Preg::print_rec() | |
1777 | ||
1778 | virtual void inc_tr() { | |
1779 | tr++; | |
1780 | } // RSTF_Preg::inc_tr() | |
1781 | ||
1782 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1783 | tr = (rstf_pregT*) ptr; | |
1784 | ||
1785 | if (set_orig) { | |
1786 | tr_orig = tr; | |
1787 | } | |
1788 | } // RSTF_Preg::set_tr() | |
1789 | ||
1790 | virtual void reset_tr() { | |
1791 | tr = tr_orig; | |
1792 | } // RSTF_Preg::reset_tr() | |
1793 | ||
1794 | virtual int getCpuID() { | |
1795 | return gbl.rstf_pre212? tr->cpuid: rstf_pregT_get_cpuid(tr); | |
1796 | } | |
1797 | ||
1798 | protected: | |
1799 | rstf_pregT* tr; | |
1800 | rstf_pregT* tr_orig; | |
1801 | }; // RSTF_Preg | |
1802 | ||
1803 | //====================================================================== | |
1804 | //====================================================================== | |
1805 | class RSTF_Physaddr : public Trace { | |
1806 | public: | |
1807 | virtual void count() { | |
1808 | gbl.rcount++; | |
1809 | gbl.physaddrcount++; | |
1810 | } | |
1811 | ||
1812 | virtual void print_rec(uint64_t idx) { | |
1813 | if (gbl.showIdx) { | |
1814 | fprintf(gbl.outfp , "%6lld ", idx); | |
1815 | } | |
1816 | ||
1817 | fprintf(gbl.outfp, "physadd : "); | |
1818 | fprintf(gbl.outfp, "pc_pa=0x%08llx ", tr->pc_pa); | |
1819 | if (tr->ea_valid) { | |
1820 | fprintf(gbl.outfp, "ea_pa=0x%08llx ", tr->ea_pa); | |
1821 | } else { | |
1822 | fprintf(gbl.outfp, "((ea_pa=0x%08llx)) ", tr->ea_pa); | |
1823 | } | |
1824 | fprintf(gbl.outfp, "ea_valid=%d", tr->ea_valid); | |
1825 | fprintf(gbl.outfp, "\n"); | |
1826 | } // RSTF_Physaddr::print_rec() | |
1827 | ||
1828 | virtual void inc_tr() { | |
1829 | tr++; | |
1830 | } // RSTF_Physaddr::inc_tr() | |
1831 | ||
1832 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1833 | tr = (rstf_physaddrT*) ptr; | |
1834 | ||
1835 | if (set_orig) { | |
1836 | tr_orig = tr; | |
1837 | } | |
1838 | } // RSTF_Physaddr::set_tr() | |
1839 | ||
1840 | virtual void reset_tr() { | |
1841 | tr = tr_orig; | |
1842 | } // RSTF_Physaddr::reset_tr() | |
1843 | ||
1844 | protected: | |
1845 | rstf_physaddrT* tr; | |
1846 | rstf_physaddrT* tr_orig; | |
1847 | }; // RSTF_Physaddr | |
1848 | ||
1849 | #define PAVADIFF_MASK (0x1fff) // lower 13 bits | |
1850 | ||
1851 | //====================================================================== | |
1852 | //====================================================================== | |
1853 | class RSTF_Pavadiff : public Trace { | |
1854 | public: | |
1855 | virtual void count() { | |
1856 | static uint64_t prev_pc_pa_va = 0; | |
1857 | ||
1858 | gbl.rcount++; | |
1859 | gbl.pavadiffcount++; | |
1860 | ||
1861 | if (gbl.pc_pavadiff) { | |
1862 | if (tr->pc_pa_va != prev_pc_pa_va) { | |
1863 | prev_pc_pa_va = tr->pc_pa_va; | |
1864 | ||
1865 | if (tr->pc_pa_va & PAVADIFF_MASK) { | |
1866 | fprintf(gbl.msgfp, "trconv: warning: pc pa-va error " | |
1867 | "(#%llu pc_pa_va=0x%llx not multiple of pagesize)\n", | |
1868 | gbl.rcount - 1, tr->pc_pa_va); | |
1869 | } | |
1870 | } | |
1871 | ||
1872 | if (tr->ea_valid) { | |
1873 | if (tr->ea_pa_va & PAVADIFF_MASK) { | |
1874 | fprintf(gbl.msgfp, "trconv: warning: ea pa-va error " | |
1875 | "(#%llu ea_pa_va=0x%llx not multiple of pagesize)\n", | |
1876 | gbl.rcount - 1, tr->ea_pa_va); | |
1877 | } | |
1878 | } | |
1879 | } | |
1880 | } | |
1881 | ||
1882 | virtual void print_rec(uint64_t idx) { | |
1883 | if (gbl.showIdx) { | |
1884 | fprintf(gbl.outfp , "%6lld ", idx); | |
1885 | } | |
1886 | ||
1887 | fprintf(gbl.outfp, "pavadiff: cpuid=%d ", getCpuID()); | |
1888 | fprintf(gbl.outfp, "icontext=%d ", tr->icontext); | |
1889 | fprintf(gbl.outfp, "dcontext=%d ", tr->dcontext); | |
1890 | fprintf(gbl.outfp, "pc_pa_va=0x%016llx ", tr->pc_pa_va); | |
1891 | if (tr->ea_valid) { | |
1892 | fprintf(gbl.outfp, "ea_pa_va=0x%016llx ", tr->ea_pa_va); | |
1893 | } else { | |
1894 | fprintf(gbl.outfp, "((ea_pa_va=0x%016llx)) ", tr->ea_pa_va); | |
1895 | } | |
1896 | fprintf(gbl.outfp, "ea_valid=%d", tr->ea_valid); | |
1897 | fprintf(gbl.outfp, "\n"); | |
1898 | } // RSTF_Pavadiff::print_rec() | |
1899 | ||
1900 | virtual void inc_tr() { | |
1901 | tr++; | |
1902 | } // RSTF_Pavadiff::inc_tr() | |
1903 | ||
1904 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1905 | tr = (rstf_pavadiffT*) ptr; | |
1906 | ||
1907 | if (set_orig) { | |
1908 | tr_orig = tr; | |
1909 | } | |
1910 | } // RSTF_Pavadiff::set_tr() | |
1911 | ||
1912 | virtual void reset_tr() { | |
1913 | tr = tr_orig; | |
1914 | } // RSTF_Pavadiff::reset_tr() | |
1915 | ||
1916 | virtual int getCpuID() { | |
1917 | return gbl.rstf_pre212? tr->cpuid: rstf_pavadiffT_get_cpuid(tr); | |
1918 | } | |
1919 | ||
1920 | protected: | |
1921 | rstf_pavadiffT* tr; | |
1922 | rstf_pavadiffT* tr_orig; | |
1923 | }; // RSTF_Pavadiff | |
1924 | ||
1925 | //====================================================================== | |
1926 | //====================================================================== | |
1927 | class RSTF_Filemarker : public Trace { | |
1928 | public: | |
1929 | virtual void count() { | |
1930 | gbl.rcount++; | |
1931 | gbl.filemarkercount++; | |
1932 | } | |
1933 | ||
1934 | virtual void print_rec(uint64_t idx) { | |
1935 | if (gbl.showIdx) { | |
1936 | fprintf(gbl.outfp , "%6lld ", idx); | |
1937 | } | |
1938 | ||
1939 | if (tr->recNum == 0) { | |
1940 | // FILEMARKER_T | |
1941 | fprintf(gbl.outfp, "filemark: "); | |
1942 | fprintf(gbl.outfp, "recNum=%u ", tr->recNum); | |
1943 | fprintf(gbl.outfp, "level=%u ", tr->level); | |
1944 | fprintf(gbl.outfp, "incount=%llu ", tr->incount); | |
1945 | fprintf(gbl.outfp, "outcount=%llu", tr->outcount); | |
1946 | fprintf(gbl.outfp, "\n"); | |
1947 | } | |
1948 | else { | |
1949 | // RECNUM_T | |
1950 | rstf_recnumT *ttr = (rstf_recnumT *)tr; | |
1951 | fprintf(gbl.outfp, "recnum : cpuid=%d ", gbl.rstf_pre212? tr->cpuID: rstf_filemarkerT_get_cpuid(tr)); | |
1952 | fprintf(gbl.outfp, "recNum=%u ", ttr->recNum); | |
1953 | fprintf(gbl.outfp, "level=%u ", ttr->level); | |
1954 | fprintf(gbl.outfp, "level=%d ", ttr->recType); | |
1955 | fprintf(gbl.outfp, "incount=%llu", ttr->incount); | |
1956 | fprintf(gbl.outfp, "\n"); | |
1957 | } | |
1958 | } // RSTF_Filemarker::print_rec() | |
1959 | ||
1960 | virtual void inc_tr() { | |
1961 | tr++; | |
1962 | } // RSTF_Filemarker::inc_tr() | |
1963 | ||
1964 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
1965 | tr = (rstf_filemarkerT*) ptr; | |
1966 | ||
1967 | if (set_orig) { | |
1968 | tr_orig = tr; | |
1969 | } | |
1970 | } // RSTF_Filemarker::set_tr() | |
1971 | ||
1972 | virtual void reset_tr() { | |
1973 | tr = tr_orig; | |
1974 | } // RSTF_Filemarker::reset_tr() | |
1975 | ||
1976 | protected: | |
1977 | rstf_filemarkerT* tr; | |
1978 | rstf_filemarkerT* tr_orig; | |
1979 | }; // RSTF_Filemarker | |
1980 | ||
1981 | //====================================================================== | |
1982 | //====================================================================== | |
1983 | class RSTF_Status : public Trace { | |
1984 | public: | |
1985 | virtual void count() { | |
1986 | gbl.rcount++; | |
1987 | gbl.statuscount++; | |
1988 | } | |
1989 | ||
1990 | virtual void print_rec(uint64_t idx) { | |
1991 | if (gbl.showIdx) { | |
1992 | fprintf(gbl.outfp , "%6lld ", idx); | |
1993 | } | |
1994 | ||
1995 | fprintf(gbl.outfp, "status : "); | |
1996 | fprintf(gbl.outfp, "status="); | |
1997 | ||
1998 | switch (tr->status) { | |
1999 | case RST_EOF: | |
2000 | fprintf(gbl.outfp, "RST_EOF\n"); | |
2001 | break; | |
2002 | case RST_ERROR: | |
2003 | fprintf(gbl.outfp, "RST_ERROR\n"); | |
2004 | break; | |
2005 | case RST_STATUS_END: | |
2006 | fprintf(gbl.outfp, "RST_STATUS_END\n"); | |
2007 | break; | |
2008 | default: | |
2009 | fprintf(gbl.outfp, "Unknown status id: %d\n", tr->status); | |
2010 | } | |
2011 | } // RSTF_Status::print_rec() | |
2012 | ||
2013 | virtual void inc_tr() { | |
2014 | tr++; | |
2015 | } // RSTF_Status::inc_tr() | |
2016 | ||
2017 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2018 | tr = (rstf_statusT*) ptr; | |
2019 | ||
2020 | if (set_orig) { | |
2021 | tr_orig = tr; | |
2022 | } | |
2023 | } // RSTF_Status::set_tr() | |
2024 | ||
2025 | virtual void reset_tr() { | |
2026 | tr = tr_orig; | |
2027 | } // RSTF_Status::reset_tr() | |
2028 | ||
2029 | protected: | |
2030 | rstf_statusT* tr; | |
2031 | rstf_statusT* tr_orig; | |
2032 | }; // RSTF_Status | |
2033 | ||
2034 | //====================================================================== | |
2035 | //====================================================================== | |
2036 | class RSTF_Patch : public Trace { | |
2037 | public: | |
2038 | virtual void count() { | |
2039 | gbl.rcount++; | |
2040 | gbl.patchcount++; | |
2041 | } | |
2042 | ||
2043 | virtual void print_rec(uint64_t idx) { | |
2044 | char text[16] = {0}; | |
2045 | ||
2046 | if (gbl.showIdx) { | |
2047 | fprintf(gbl.outfp , "%6lld ", idx); | |
2048 | } | |
2049 | ||
2050 | fprintf(gbl.outfp, "patch : "); | |
2051 | fprintf(gbl.outfp, "isbegin=%d ", tr->isBegin); | |
2052 | fprintf(gbl.outfp, "rewindrecs=%d ", tr->rewindrecs); | |
2053 | fprintf(gbl.outfp, "id=%d ", tr->id); | |
2054 | fprintf(gbl.outfp, "length=%d ", tr->length); | |
2055 | fprintf(gbl.outfp, "descr=%s", memcpy(text, tr->descr, 8)); | |
2056 | fprintf(gbl.outfp, "\n"); | |
2057 | } // RSTF_Patch::print_rec() | |
2058 | ||
2059 | virtual void inc_tr() { | |
2060 | tr++; | |
2061 | } // RSTF_Patch::inc_tr() | |
2062 | ||
2063 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2064 | tr = (rstf_patchT*) ptr; | |
2065 | ||
2066 | if (set_orig) { | |
2067 | tr_orig = tr; | |
2068 | } | |
2069 | } // RSTF_Patch::set_tr() | |
2070 | ||
2071 | virtual void reset_tr() { | |
2072 | tr = tr_orig; | |
2073 | } // RSTF_Patch::reset_tr() | |
2074 | ||
2075 | protected: | |
2076 | rstf_patchT* tr; | |
2077 | rstf_patchT* tr_orig; | |
2078 | }; // RSTF_Patch | |
2079 | ||
2080 | //====================================================================== | |
2081 | //====================================================================== | |
2082 | class RSTF_Hwinfo : public Trace { | |
2083 | ||
2084 | //FIXME nothing is defined yet, stay tune. | |
2085 | ||
2086 | }; // RSTF_Hwinfo | |
2087 | ||
2088 | ||
2089 | ||
2090 | //====================================================================== | |
2091 | //====================================================================== | |
2092 | class RSTF_Memval64 : public Trace { | |
2093 | public: | |
2094 | virtual void count() { | |
2095 | gbl.rcount++; | |
2096 | gbl.memval64count++; | |
2097 | } | |
2098 | ||
2099 | virtual void print_rec(uint64_t idx) { | |
2100 | if (gbl.showIdx) { | |
2101 | fprintf(gbl.outfp , "%6lld ", idx); | |
2102 | } | |
2103 | ||
2104 | fprintf(gbl.outfp, "mem64 : "); | |
2105 | //fprintf(gbl.outfp, "128=%1d ", tr->ismemval128); | |
2106 | fprintf(gbl.outfp, "isVA=%1d ", tr->addrisVA); | |
2107 | //fprintf(gbl.outfp, "cont=%1d ", tr->isContRec); | |
2108 | //fprintf(gbl.outfp, "zero5=%1d ", tr->zero5); | |
2109 | fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); | |
2110 | fprintf(gbl.outfp, "sz=%d ", tr->size); | |
2111 | fprintf(gbl.outfp, "addr=0x%016llx ", tr->addr); | |
2112 | fprintf(gbl.outfp, "val=0x%llx ", tr->val); | |
2113 | fprintf(gbl.outfp, "\n"); | |
2114 | } // RSTF_Memval64::print_rec() | |
2115 | ||
2116 | virtual void inc_tr() { | |
2117 | tr++; | |
2118 | } // RSTF_Memval64::inc_tr() | |
2119 | ||
2120 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2121 | tr = (rstf_memval64T*) ptr; | |
2122 | ||
2123 | if (set_orig) { | |
2124 | tr_orig = tr; | |
2125 | } | |
2126 | } // RSTF_Memval64::set_tr() | |
2127 | ||
2128 | virtual void reset_tr() { | |
2129 | tr = tr_orig; | |
2130 | } // RSTF_Memval64::reset_tr() | |
2131 | ||
2132 | virtual int getCpuID() { | |
2133 | return gbl.rstf_pre212? tr->cpuid: rstf_memval64T_get_cpuid(tr); | |
2134 | } | |
2135 | ||
2136 | protected: | |
2137 | rstf_memval64T* tr; | |
2138 | rstf_memval64T* tr_orig; | |
2139 | }; // RSTF_Memval64 | |
2140 | ||
2141 | //====================================================================== | |
2142 | //====================================================================== | |
2143 | class RSTF_Memval128 : public Trace { | |
2144 | public: | |
2145 | virtual void count() { | |
2146 | gbl.rcount++; | |
2147 | gbl.memval128count++; | |
2148 | } | |
2149 | ||
2150 | virtual void print_rec(uint64_t idx) { | |
2151 | if (gbl.showIdx) { | |
2152 | fprintf(gbl.outfp , "%6lld ", idx); | |
2153 | } | |
2154 | ||
2155 | fprintf(gbl.outfp, "mem128 : "); | |
2156 | //fprintf(gbl.outfp, "128=%1d ", tr->ismemval128); | |
2157 | fprintf(gbl.outfp, "isVA=%1d ", tr->addrisVA); | |
2158 | fprintf(gbl.outfp, "cont=%1d ", tr->isContRec); | |
2159 | //fprintf(gbl.outfp, "zero5=%1d ", tr->zero5); | |
2160 | fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); | |
2161 | if (tr->isContRec == 0) { | |
2162 | fprintf(gbl.outfp, "addr=0x%016llx ", makeAddr()); | |
2163 | } | |
2164 | fprintf(gbl.outfp, "val[0]=0x%llx ", tr->val[0]); | |
2165 | fprintf(gbl.outfp, "val[1]=0x%llx ", tr->val[1]); | |
2166 | fprintf(gbl.outfp, "\n"); | |
2167 | } // RSTF_Memval128::print_rec() | |
2168 | ||
2169 | virtual void inc_tr() { | |
2170 | tr++; | |
2171 | } // RSTF_Memval128::inc_tr() | |
2172 | ||
2173 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2174 | tr = (rstf_memval128T*) ptr; | |
2175 | ||
2176 | if (set_orig) { | |
2177 | tr_orig = tr; | |
2178 | } | |
2179 | } // RSTF_Memval128::set_tr() | |
2180 | ||
2181 | virtual void reset_tr() { | |
2182 | tr = tr_orig; | |
2183 | } // RSTF_Memval128::reset_tr() | |
2184 | ||
2185 | virtual int getCpuID() { | |
2186 | return gbl.rstf_pre212? tr->cpuid: rstf_memval128T_get_cpuid(tr); | |
2187 | } | |
2188 | ||
2189 | protected: | |
2190 | rstf_memval128T* tr; | |
2191 | rstf_memval128T* tr_orig; | |
2192 | ||
2193 | uint64_t makeAddr() { | |
2194 | int64_t addr = 0; | |
2195 | int8_t* paddr = (int8_t*) &addr; | |
2196 | ||
2197 | if (tr->isContRec == 0) { | |
2198 | paddr[0] = tr->addr36_43; | |
2199 | addr >>= 20; | |
2200 | addr |= (tr->addr04_35 << 4); | |
2201 | } | |
2202 | ||
2203 | return (uint64_t) addr; | |
2204 | } | |
2205 | }; // RSTF_Memval128 | |
2206 | ||
2207 | ||
2208 | ||
2209 | //====================================================================== | |
2210 | //====================================================================== | |
2211 | class RSTF_Bustrace : public Trace { | |
2212 | public: | |
2213 | virtual void count() { | |
2214 | gbl.rcount++; | |
2215 | gbl.bustracecount++; | |
2216 | } | |
2217 | ||
2218 | virtual void print_rec(uint64_t idx) { | |
2219 | if (gbl.showIdx) { | |
2220 | fprintf(gbl.outfp , "%6lld ", idx); | |
2221 | } | |
2222 | ||
2223 | fprintf(gbl.outfp, "bustrace: "); | |
2224 | fprintf(gbl.outfp, "dv=%1d ", tr->dirtyvictim); | |
2225 | fprintf(gbl.outfp, "sh=%1d ", tr->shared); | |
2226 | fprintf(gbl.outfp, "own=%1d ", tr->owned); | |
2227 | fprintf(gbl.outfp, "mc=%1d ", tr->memcancel); | |
2228 | //fprintf(gbl.outfp, "bt_type=%2d ", tr->bt_type); | |
2229 | fprintf(gbl.outfp, "txType=%2d ", tr->txType); | |
2230 | fprintf(gbl.outfp, "aid=%2d ", tr->agentid); | |
2231 | fprintf(gbl.outfp, "tscale=%1d ", tr->nsScale); | |
2232 | fprintf(gbl.outfp, "ts=%7d ", tr->timestamp); | |
2233 | fprintf(gbl.outfp, "addr=0x%016llx ", tr->addr_pa); | |
2234 | fprintf(gbl.outfp, "\n"); | |
2235 | } // RSTF_Bustrace::print_rec() | |
2236 | ||
2237 | virtual void inc_tr() { | |
2238 | tr++; | |
2239 | } // RSTF_Bustrace::inc_tr() | |
2240 | ||
2241 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2242 | tr = (rstf_bustraceT*) ptr; | |
2243 | ||
2244 | if (set_orig) { | |
2245 | tr_orig = tr; | |
2246 | } | |
2247 | } // RSTF_Bustrace::set_tr() | |
2248 | ||
2249 | virtual void reset_tr() { | |
2250 | tr = tr_orig; | |
2251 | } // RSTF_Bustrace::reset_tr() | |
2252 | ||
2253 | protected: | |
2254 | rstf_bustraceT* tr; | |
2255 | rstf_bustraceT* tr_orig; | |
2256 | }; // RSTF_Bustrace | |
2257 | ||
2258 | ||
2259 | //====================================================================== | |
2260 | //====================================================================== | |
2261 | class RSTF_Snoop : public Trace { | |
2262 | public: | |
2263 | virtual void count() { | |
2264 | gbl.rcount++; | |
2265 | gbl.snoopcount++; | |
2266 | } | |
2267 | ||
2268 | virtual void print_rec(uint64_t idx) { | |
2269 | if (gbl.showIdx) { | |
2270 | fprintf(gbl.outfp , "%6lld ", idx); | |
2271 | } | |
2272 | ||
2273 | if (tr->device_type == DEVICE_CPU) { | |
2274 | fprintf(gbl.outfp, "snoop : cpuid=%d ", tr->device_id); | |
2275 | } | |
2276 | else { | |
2277 | fprintf(gbl.outfp, "snoop : unknown device=%d ", tr->device_id); | |
2278 | } | |
2279 | ||
2280 | switch(tr->snoopreq) { | |
2281 | case SNOOP_RTO: | |
2282 | fprintf(gbl.outfp, "RTO "); | |
2283 | break; | |
2284 | ||
2285 | case SNOOP_RTS: | |
2286 | fprintf(gbl.outfp, "RTS "); | |
2287 | break; | |
2288 | ||
2289 | default: | |
2290 | fprintf(gbl.outfp, "Unknown snoop type "); | |
2291 | break; | |
2292 | } | |
2293 | fprintf(gbl.outfp, "[0x%016llx]\n", tr->addr_pa); | |
2294 | } // RSTF_Snoop::print_rec() | |
2295 | ||
2296 | virtual void inc_tr() { | |
2297 | tr++; | |
2298 | } // RSTF_Snoop::inc_tr() | |
2299 | ||
2300 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2301 | tr = (rstf_snoopT*) ptr; | |
2302 | ||
2303 | if (set_orig) { | |
2304 | tr_orig = tr; | |
2305 | } | |
2306 | } // RSTF_Snoop::set_tr() | |
2307 | ||
2308 | virtual void reset_tr() { | |
2309 | tr = tr_orig; | |
2310 | } // RSTF_Snoop::reset_tr() | |
2311 | ||
2312 | protected: | |
2313 | rstf_snoopT* tr; | |
2314 | rstf_snoopT* tr_orig; | |
2315 | }; // RSTF_Snoop | |
2316 | ||
2317 | ||
2318 | ||
2319 | class RSTF_tsb_access : public Trace { | |
2320 | public: | |
2321 | virtual void count() { | |
2322 | gbl.rcount++; | |
2323 | gbl.tsb_access_count++; | |
2324 | } | |
2325 | ||
2326 | virtual void print_rec(uint64_t idx) { | |
2327 | if (gbl.showIdx) { | |
2328 | fprintf(gbl.outfp, "%6lld ", idx); | |
2329 | } | |
2330 | fprintf(gbl.outfp, "tsbaccess: cpuid=%d ", getCpuID()); | |
2331 | fprintf(gbl.outfp, "%s ", (tr->isdata? "DTSB": "ITSB")); | |
2332 | fprintf(gbl.outfp, "pa=0x%016llx\n", tr->pa); | |
2333 | } // RSTF_tsb_access::print_rec() | |
2334 | ||
2335 | virtual void inc_tr() { | |
2336 | tr++; | |
2337 | } | |
2338 | ||
2339 | virtual void set_tr(void * ptr, bool set_orig = true) { | |
2340 | tr = (rstf_tsb_accessT*) ptr; | |
2341 | if (set_orig) { | |
2342 | tr_orig = tr; | |
2343 | } | |
2344 | } // RSTF_tsb_access::set_tr() | |
2345 | ||
2346 | virtual void reset_tr() { | |
2347 | tr = tr_orig; | |
2348 | } | |
2349 | ||
2350 | virtual int getCpuID() { | |
2351 | return gbl.rstf_pre212? tr->cpuid: rstf_tsb_accessT_get_cpuid(tr); | |
2352 | } | |
2353 | protected: | |
2354 | rstf_tsb_accessT * tr; | |
2355 | rstf_tsb_accessT * tr_orig; | |
2356 | }; // class RSTF_tsb_access : public Trace | |
2357 | ||
2358 | ||
2359 | class RSTF_rfs_section_header : public Trace { | |
2360 | public: | |
2361 | virtual void count() { | |
2362 | gbl.rcount++; | |
2363 | gbl.rfs_section_header_count++; | |
2364 | } | |
2365 | ||
2366 | virtual void print_rec(uint64_t idx) { | |
2367 | if (gbl.showIdx) { | |
2368 | fprintf(gbl.outfp, "%6lld ", idx); | |
2369 | } | |
2370 | ||
2371 | fprintf(gbl.outfp, "rfs_section_header: "); | |
2372 | ||
2373 | switch(tr->section_type) { | |
2374 | case RFS_CW_T: | |
2375 | fprintf(gbl.outfp, "CacheWarming: "); | |
2376 | break; | |
2377 | case RFS_BT_T: | |
2378 | fprintf(gbl.outfp, "BranchTrace: "); | |
2379 | break; | |
2380 | case RFS_RST_T: | |
2381 | fprintf(gbl.outfp, "RST Trace: "); | |
2382 | break; | |
2383 | default: | |
2384 | fprintf(gbl.outfp, "Unknown Type: "); | |
2385 | break; | |
2386 | } | |
2387 | ||
2388 | if (tr->n_records == rfs_unknown_nrecords) { | |
2389 | fprintf(gbl.outfp, "All remaining records\n"); | |
2390 | } else { | |
2391 | fprintf(gbl.outfp, "%lld records\n", tr->n_records); | |
2392 | } | |
2393 | ||
2394 | } | |
2395 | ||
2396 | virtual void inc_tr() { | |
2397 | tr++; | |
2398 | } // RSTF_Snoop::inc_tr() | |
2399 | ||
2400 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2401 | tr = (rstf_rfs_section_headerT *) ptr; | |
2402 | ||
2403 | if (set_orig) { | |
2404 | tr_orig = tr; | |
2405 | } | |
2406 | } | |
2407 | ||
2408 | virtual void reset_tr() { | |
2409 | tr = tr_orig; | |
2410 | } | |
2411 | ||
2412 | protected: | |
2413 | rstf_rfs_section_headerT * tr; | |
2414 | rstf_rfs_section_headerT * tr_orig; | |
2415 | }; // class RSTF_rfs_section_header : public Trace | |
2416 | ||
2417 | ||
2418 | class RSTF_bpwarming : public Trace { | |
2419 | public: | |
2420 | virtual void count() { | |
2421 | gbl.rcount++; | |
2422 | gbl.bpwarming_count++; | |
2423 | } | |
2424 | ||
2425 | virtual void print_rec(uint64_t idx) { | |
2426 | if (gbl.showIdx) { | |
2427 | fprintf(gbl.outfp, "%6lld ", idx); | |
2428 | } | |
2429 | ||
2430 | fprintf(gbl.outfp, "bpwarm : "); | |
2431 | ||
2432 | char dis_string[80]; | |
2433 | sprintDiss(dis_string, tr->instr, tr->pc_va); | |
2434 | ||
2435 | fprintf(gbl.outfp, "cpuid=%d [0x%016llx] %08x %-32s %c [0x%016llx]", getCpuID(), tr->pc_va, tr->instr, dis_string, (tr->taken? 'T' : 'N'), tr->npc_va); | |
2436 | ||
2437 | } | |
2438 | ||
2439 | virtual void inc_tr() { | |
2440 | tr++; | |
2441 | } // RSTF_Snoop::inc_tr() | |
2442 | ||
2443 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2444 | tr = (rstf_bpwarmingT *) ptr; | |
2445 | ||
2446 | if (set_orig) { | |
2447 | tr_orig = tr; | |
2448 | } | |
2449 | } | |
2450 | ||
2451 | virtual void reset_tr() { | |
2452 | tr = tr_orig; | |
2453 | } | |
2454 | ||
2455 | virtual int getCpuID() { | |
2456 | return gbl.rstf_pre212? tr->cpuid: rstf_bpwarmingT_get_cpuid(tr); | |
2457 | } | |
2458 | ||
2459 | protected: | |
2460 | rstf_bpwarmingT * tr; | |
2461 | rstf_bpwarmingT * tr_orig; | |
2462 | }; // class Rstf_bpwarming: public Trace | |
2463 | ||
2464 | ||
2465 | ||
2466 | ||
2467 | class RSTF_cachewarming : public Trace { | |
2468 | public: | |
2469 | virtual void count() { | |
2470 | gbl.rcount++; | |
2471 | gbl.cachewarming_count++; | |
2472 | } | |
2473 | ||
2474 | virtual void print_rec(uint64_t idx) { | |
2475 | if (gbl.showIdx) { | |
2476 | fprintf(gbl.outfp, "%6lld ", idx); | |
2477 | } | |
2478 | ||
2479 | fprintf(gbl.outfp, "cachewarm: "); | |
2480 | ||
2481 | fprintf(gbl.outfp, "cpuid=%d ", getCpuID()); | |
2482 | switch(tr->reftype) { | |
2483 | case cw_reftype_I: | |
2484 | fprintf(gbl.outfp, "ifetch "); | |
2485 | break; | |
2486 | case cw_reftype_R: | |
2487 | fprintf(gbl.outfp, "load "); | |
2488 | break; | |
2489 | case cw_reftype_W: | |
2490 | fprintf(gbl.outfp, "store "); | |
2491 | break; | |
2492 | case cw_reftype_PF_I: | |
2493 | fprintf(gbl.outfp, "i-prefetch "); | |
2494 | break; | |
2495 | case cw_reftype_PF_D: | |
2496 | fprintf(gbl.outfp, "d-prefetch "); | |
2497 | break; | |
2498 | case cw_reftype_DMA_R: | |
2499 | fprintf(gbl.outfp, "dma-read "); | |
2500 | break; | |
2501 | case cw_reftype_DMA_W: | |
2502 | fprintf(gbl.outfp, "dma-write "); | |
2503 | break; | |
2504 | default: | |
2505 | fprintf(gbl.outfp, "unknown reftype "); | |
2506 | break; | |
2507 | } | |
2508 | ||
2509 | if (tr->reftype == cw_reftype_DMA_R || tr->reftype == cw_reftype_DMA_W) { | |
2510 | fprintf(gbl.outfp, "pa=0x%016llx size=%08x\n", tr->pa, tr->refinfo.dma_size); | |
2511 | } else { | |
2512 | fprintf(gbl.outfp, "asi=%02x ", tr->refinfo.s.asi); | |
2513 | fprintf(gbl.outfp, "va=0x%016llx pa=0x%016llx ", tr->va, tr->pa); | |
2514 | if (tr->reftype == cw_reftype_PF_D) { | |
2515 | fprintf(gbl.outfp, "fcn=%d\n", tr->refinfo.s.fcn); | |
2516 | } else { | |
2517 | fprintf(gbl.outfp, "\n"); | |
2518 | } | |
2519 | } | |
2520 | } | |
2521 | ||
2522 | virtual void inc_tr() { | |
2523 | tr++; | |
2524 | } // RSTF_Snoop::inc_tr() | |
2525 | ||
2526 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2527 | tr = (rstf_cachewarmingT *) ptr; | |
2528 | ||
2529 | if (set_orig) { | |
2530 | tr_orig = tr; | |
2531 | } | |
2532 | } | |
2533 | ||
2534 | virtual void reset_tr() { | |
2535 | tr = tr_orig; | |
2536 | } | |
2537 | ||
2538 | virtual int getCpuID() { | |
2539 | return gbl.rstf_pre212 ? tr->cpuid : rstf_cachewarmingT_get_cpuid(tr); | |
2540 | } | |
2541 | ||
2542 | protected: | |
2543 | rstf_cachewarmingT * tr; | |
2544 | rstf_cachewarmingT * tr_orig; | |
2545 | }; // class Rstf_cachewarming: public Trace | |
2546 | ||
2547 | ||
2548 | class RSTF_Trapping_Instr : public Trace { | |
2549 | public: | |
2550 | virtual void count() { | |
2551 | gbl.rcount++; | |
2552 | gbl.trappinginstrcount++; | |
2553 | } | |
2554 | ||
2555 | virtual void print_rec(uint64_t idx) { | |
2556 | if (gbl.showIdx) { | |
2557 | fprintf(gbl.outfp , "%6lld ", idx); | |
2558 | } | |
2559 | ||
2560 | fprintf(gbl.outfp, "tr_instr : cpuid=%d", rstf_trapping_instrT_get_cpuid(tr)); | |
2561 | ||
2562 | if (tr->hpriv) fprintf(gbl.outfp, " h"); else if (tr->priv) fprintf(gbl.outfp, " p"); else fprintf(gbl.outfp, " u"); | |
2563 | ||
2564 | fprintf(gbl.outfp, " [0x%016llx] ", tr->pc_va); | |
2565 | ||
2566 | if (tr->iftrap) { | |
2567 | fprintf(gbl.outfp, "ifetch_trap"); | |
2568 | } else { | |
2569 | fprintf(gbl.outfp, "%08x", tr->instr); | |
2570 | // output decoded instr | |
2571 | if (tr->ea_va_valid) { | |
2572 | fprintf(gbl.outfp, " [%llx]", tr->ea_va); | |
2573 | if (tr->ea_pa_valid) { | |
2574 | fprintf(gbl.outfp, " ea_pa valid"); | |
2575 | } else { | |
2576 | fprintf(gbl.outfp, " ea_pa INVALID"); | |
2577 | } | |
2578 | } // if ea_va_valid | |
2579 | } // tr->iftrap? | |
2580 | ||
2581 | fprintf(gbl.outfp, "\n"); | |
2582 | } // RSTF_Trapexit::print_rec() | |
2583 | ||
2584 | #if 0 | |
2585 | virtual uint64_t get_pc() { | |
2586 | return tr->pc; | |
2587 | } // RSTF_Trapexit::get_pc() | |
2588 | #endif | |
2589 | ||
2590 | virtual void inc_tr() { | |
2591 | tr++; | |
2592 | } // RSTF_Trapexit::inc_tr() | |
2593 | ||
2594 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2595 | tr = (rstf_trapping_instrT*) ptr; | |
2596 | ||
2597 | if (set_orig) { | |
2598 | tr_orig = tr; | |
2599 | } | |
2600 | } // RSTF_Trapexit::set_tr() | |
2601 | ||
2602 | virtual void reset_tr() { | |
2603 | tr = tr_orig; | |
2604 | } // RSTF_Trapexit::reset_tr() | |
2605 | ||
2606 | virtual int getCpuID() { | |
2607 | return gbl.rstf_pre212? tr->cpuid: rstf_trapping_instrT_get_cpuid(tr); | |
2608 | } | |
2609 | ||
2610 | protected: | |
2611 | rstf_trapping_instrT* tr; | |
2612 | rstf_trapping_instrT* tr_orig; | |
2613 | }; // RSTF_TRAPPING_INSTR_T | |
2614 | ||
2615 | ||
2616 | //====================================================================== | |
2617 | //====================================================================== | |
2618 | class RSTF_Timesync : public Trace { | |
2619 | public: | |
2620 | virtual void count() { | |
2621 | gbl.rcount++; | |
2622 | gbl.timesynccount++; | |
2623 | } | |
2624 | ||
2625 | virtual void print_rec(uint64_t idx) { | |
2626 | if (gbl.showIdx) { | |
2627 | fprintf(gbl.outfp , "%6lld ", idx); | |
2628 | } | |
2629 | ||
2630 | fprintf(gbl.outfp, "timesync: cpuid=%d ", getCpuID()); | |
2631 | fprintf(gbl.outfp, "seqnum=%llu ", tr->sequence_number); | |
2632 | switch(tr->subtype) { | |
2633 | case rstf_timesyncT_local: | |
2634 | fprintf(gbl.outfp, "local"); | |
2635 | break; | |
2636 | case rstf_timesyncT_global: | |
2637 | fprintf(gbl.outfp, "global"); | |
2638 | break; | |
2639 | default: | |
2640 | fprintf(gbl.outfp, "unknown-sync-type"); | |
2641 | break; | |
2642 | } | |
2643 | fprintf(gbl.outfp, "\n"); | |
2644 | } // RSTF_Timesync::print_rec() | |
2645 | ||
2646 | virtual void inc_tr() { | |
2647 | tr++; | |
2648 | } // RSTF_TimeSync::inc_tr() | |
2649 | ||
2650 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2651 | tr = (rstf_timesyncT*) ptr; | |
2652 | ||
2653 | if (set_orig) { | |
2654 | tr_orig = tr; | |
2655 | } | |
2656 | } // RSTF_Timesync::set_tr() | |
2657 | ||
2658 | virtual void reset_tr() { | |
2659 | tr = tr_orig; | |
2660 | } // RSTF_Timesync::reset_tr() | |
2661 | ||
2662 | virtual int getCpuID() { | |
2663 | return rstf_timesyncT_get_cpuid(tr); | |
2664 | } | |
2665 | ||
2666 | protected: | |
2667 | rstf_timesyncT* tr; | |
2668 | rstf_timesyncT* tr_orig; | |
2669 | }; // RSTF_Timesync | |
2670 | ||
2671 | ||
2672 | ||
2673 | //====================================================================== | |
2674 | //====================================================================== | |
2675 | class RSTF_Devidstr : public Trace { | |
2676 | public: | |
2677 | virtual void count() { | |
2678 | gbl.rcount++; | |
2679 | gbl.devidstrcount++; | |
2680 | } | |
2681 | ||
2682 | virtual void print_rec(uint64_t idx) { | |
2683 | static uint32_t id; | |
2684 | static std::string idstring; | |
2685 | char cstr[20]; | |
2686 | ||
2687 | if (gbl.showIdx) { | |
2688 | fprintf(gbl.outfp , "%6lld ", idx); | |
2689 | } | |
2690 | ||
2691 | if (tr->id != rstf_devidstr_continuation_id) { | |
2692 | id = tr->id; | |
2693 | } | |
2694 | ||
2695 | int i; | |
2696 | for (i=0; i<19; i++) { | |
2697 | if (tr->str[i] != '\0') { | |
2698 | idstring += tr->str[i]; | |
2699 | cstr[i] = tr->str[i]; | |
2700 | } else { | |
2701 | break; | |
2702 | } | |
2703 | } | |
2704 | cstr[i] = 0; | |
2705 | ||
2706 | fprintf(gbl.outfp, "devidstr: id=%d \"%s\"\n", id, cstr); | |
2707 | ||
2708 | if (i < 19) { | |
2709 | gbl.devid2string[tr->id] = idstring; | |
2710 | idstring.clear(); | |
2711 | } | |
2712 | } // RSTF_Devidstr::print_rec() | |
2713 | ||
2714 | virtual void inc_tr() { | |
2715 | tr++; | |
2716 | } // RSTF_Devidstr::inc_tr() | |
2717 | ||
2718 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2719 | tr = (rstf_devidstrT*) ptr; | |
2720 | ||
2721 | if (set_orig) { | |
2722 | tr_orig = tr; | |
2723 | } | |
2724 | } // RSTF_Devidstr::set_tr() | |
2725 | ||
2726 | virtual void reset_tr() { | |
2727 | tr = tr_orig; | |
2728 | } // RSTF_Devidstr::reset_tr() | |
2729 | ||
2730 | protected: | |
2731 | rstf_devidstrT* tr; | |
2732 | rstf_devidstrT* tr_orig; | |
2733 | }; // RSTF_Devidstr | |
2734 | ||
2735 | //====================================================================== | |
2736 | //====================================================================== | |
2737 | class RSTF_Zero : public Trace { | |
2738 | public: | |
2739 | virtual void count() { | |
2740 | gbl.rcount++; | |
2741 | gbl.zerocount++; | |
2742 | } | |
2743 | ||
2744 | virtual void print_rec(uint64_t idx) { | |
2745 | if (gbl.showIdx) { | |
2746 | fprintf(gbl.outfp , "%6lld\t\tZero Record", idx); | |
2747 | } | |
2748 | ||
2749 | } // RSTF_Zero::print_rec() | |
2750 | ||
2751 | virtual void inc_tr() { | |
2752 | tr++; | |
2753 | } // RSTF_Zero::inc_tr() | |
2754 | ||
2755 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2756 | tr = (rstf_xxxT*) ptr; | |
2757 | ||
2758 | if (set_orig) { | |
2759 | tr_orig = tr; | |
2760 | } | |
2761 | } // RSTF_Zero::set_tr() | |
2762 | ||
2763 | virtual void reset_tr() { | |
2764 | tr = tr_orig; | |
2765 | } // RSTF_Zero::reset_tr() | |
2766 | ||
2767 | protected: | |
2768 | rstf_xxxT* tr; | |
2769 | rstf_xxxT* tr_orig; | |
2770 | }; // RSTF_Zero | |
2771 | ||
2772 | //====================================================================== | |
2773 | //====================================================================== | |
2774 | class RSTF_Unknown : public Trace { | |
2775 | public: | |
2776 | virtual void count() { | |
2777 | gbl.rcount++; | |
2778 | gbl.unknowncount++; | |
2779 | } | |
2780 | ||
2781 | virtual void print_rec(uint64_t idx) { | |
2782 | if (gbl.showIdx) { | |
2783 | fprintf(gbl.outfp , "%6lld ", idx); | |
2784 | } | |
2785 | ||
2786 | fprintf(gbl.outfp, "unknown : [Unsupported record type; rtype=%d]\n", | |
2787 | tr->rtype); | |
2788 | } // RSTF_Unknown::print_rec() | |
2789 | ||
2790 | virtual void inc_tr() { | |
2791 | tr++; | |
2792 | } // RSTF_Unknown::inc_tr() | |
2793 | ||
2794 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2795 | tr = (rstf_protoT*) ptr; | |
2796 | ||
2797 | if (set_orig) { | |
2798 | tr_orig = tr; | |
2799 | } | |
2800 | } // RSTF_Unknown::set_tr() | |
2801 | ||
2802 | virtual void reset_tr() { | |
2803 | tr = tr_orig; | |
2804 | } // RSTF_Unknown::reset_tr() | |
2805 | ||
2806 | protected: | |
2807 | rstf_protoT* tr; | |
2808 | rstf_protoT* tr_orig; | |
2809 | }; // RSTF_Unknown | |
2810 | ||
2811 | //====================================================================== | |
2812 | //====================================================================== | |
2813 | class RSTF_Union : public Trace { | |
2814 | public: | |
2815 | virtual void count() { | |
2816 | Trace* tr_trace; | |
2817 | ||
2818 | #if defined(ARCH_AMD64) | |
2819 | rstf_convertT::b2l((rstf_uint8T *)tr); | |
2820 | #endif | |
2821 | tr_trace = get_rst_type(); | |
2822 | ||
2823 | if (tr_trace != NULL) { | |
2824 | tr_trace->set_tr(tr, false); | |
2825 | tr_trace->count(); | |
2826 | } | |
2827 | } // RSTF_Union::count() | |
2828 | ||
2829 | virtual void print_dasm(uint64_t idx) { | |
2830 | Trace* tr_trace; | |
2831 | ||
2832 | print_header(); | |
2833 | ||
2834 | if (gbl.onlyIns) { | |
2835 | if (tr->proto.rtype == INSTR_T) { | |
2836 | tr_instr.set_tr(tr, false); | |
2837 | tr_instr.print_dasm(idx); | |
2838 | } | |
2839 | } else { | |
2840 | tr_trace = get_rst_type(); | |
2841 | ||
2842 | if (gbl.noIns && tr->proto.rtype == INSTR_T) { | |
2843 | tr_trace = NULL; | |
2844 | } | |
2845 | ||
2846 | if (tr_trace) { | |
2847 | tr_trace->set_tr(tr, false); | |
2848 | tr_trace->print_dasm(idx); | |
2849 | } | |
2850 | } | |
2851 | } // RSTF_Union::print_dasm() | |
2852 | ||
2853 | virtual void print_rec(uint64_t idx) { | |
2854 | Trace* tr_trace; | |
2855 | ||
2856 | print_header(); | |
2857 | ||
2858 | if (gbl.onlyIns) { | |
2859 | if (tr->proto.rtype == INSTR_T) { | |
2860 | tr_instr.set_tr(tr, false); | |
2861 | tr_instr.print_rec(idx); | |
2862 | } | |
2863 | } else { | |
2864 | tr_trace = get_rst_type(); | |
2865 | ||
2866 | if (gbl.noIns && tr->proto.rtype == INSTR_T) { | |
2867 | tr_trace = NULL; | |
2868 | } | |
2869 | ||
2870 | if (tr_trace) { | |
2871 | tr_trace->set_tr(tr, false); | |
2872 | tr_trace->print_rec(idx); | |
2873 | } | |
2874 | } | |
2875 | } // RSTF_Union::print_rec() | |
2876 | ||
2877 | virtual void print_verb(uint64_t idx) { | |
2878 | Trace* tr_trace; | |
2879 | ||
2880 | print_header(); | |
2881 | ||
2882 | if (gbl.onlyIns) { | |
2883 | if (tr->proto.rtype == INSTR_T) { | |
2884 | tr_instr.set_tr(tr, false); | |
2885 | tr_instr.print_verb(idx); | |
2886 | } | |
2887 | } else { | |
2888 | tr_trace = get_rst_type(); | |
2889 | ||
2890 | if (gbl.noIns && tr->proto.rtype == INSTR_T) { | |
2891 | tr_trace = NULL; | |
2892 | } | |
2893 | ||
2894 | if (tr_trace) { | |
2895 | tr_trace->set_tr(tr, false); | |
2896 | tr_trace->print_verb(idx); | |
2897 | } | |
2898 | } | |
2899 | } // RSTF_Union::print_verb() | |
2900 | ||
2901 | virtual void convert_to_master() { | |
2902 | if (tr->proto.rtype == INSTR_T) { | |
2903 | tr_instr.set_tr(tr, false); | |
2904 | tr_instr.convert_to_master(); | |
2905 | } | |
2906 | } // RSTF_Union::convert_to_master() | |
2907 | ||
2908 | virtual void convert_from_master(Tmaster64* master) { | |
2909 | tr_instr.set_tr(tr, false); | |
2910 | tr_instr.convert_from_master(master); | |
2911 | } // RSTF_Union::convert_from_master() | |
2912 | ||
2913 | virtual void gen_ihash() { | |
2914 | if (tr->proto.rtype == INSTR_T) { | |
2915 | tr_instr.set_tr(tr, false); | |
2916 | tr_instr.gen_ihash(); | |
2917 | } | |
2918 | } // RSTF_Union::gen_ihash() | |
2919 | ||
2920 | virtual int check_ihash_error() { | |
2921 | if (tr->proto.rtype == INSTR_T) { | |
2922 | tr_instr.set_tr(tr, false); | |
2923 | return tr_instr.check_ihash_error(); | |
2924 | } | |
2925 | ||
2926 | return 0; | |
2927 | } // RSTF_Union::check_ihash_error() | |
2928 | ||
2929 | // check pc value of last NUM_VERIFY records in buffer | |
2930 | virtual void verify() { | |
2931 | tr_instr.set_tr(tr_orig, true); | |
2932 | tr_instr.set_tr(tr, false); | |
2933 | tr_instr.verify(); | |
2934 | } // RSTF_Union::verify() | |
2935 | ||
2936 | virtual uint64_t get_pc() { | |
2937 | switch (tr->proto.rtype) { | |
2938 | case INSTR_T: | |
2939 | return tr->instr.pc_va; | |
2940 | case TRAP_T: | |
2941 | return tr->trap.pc; | |
2942 | #if 0 | |
2943 | case TRAPEXIT_T: | |
2944 | return tr->trapexit.pc; | |
2945 | #endif | |
2946 | } | |
2947 | ||
2948 | return RSTF_NOADDR; | |
2949 | } // RSTF_Union::get_pc() | |
2950 | ||
2951 | virtual uint64_t get_ea() { | |
2952 | if (tr->proto.rtype == INSTR_T) { | |
2953 | if (tr->instr.ea_valid) { | |
2954 | return tr->instr.ea_va; | |
2955 | } | |
2956 | } | |
2957 | ||
2958 | return RSTF_NOADDR; | |
2959 | } // RSTF_Union::get_ea() | |
2960 | ||
2961 | virtual int get_ihash() { | |
2962 | if (tr->proto.rtype == INSTR_T) { | |
2963 | return spix_sparc_iop(SPIX_SPARC_V9, &tr->instr.instr); | |
2964 | // return tr->instr.ihash; | |
2965 | } | |
2966 | ||
2967 | return 0; | |
2968 | } // RSTF_Union::get_ihash() | |
2969 | ||
2970 | virtual void inc_tr() { | |
2971 | tr++; | |
2972 | } // RSTF_Union::inc_tr() | |
2973 | ||
2974 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
2975 | tr = (rstf_unionT*) ptr; | |
2976 | ||
2977 | if (set_orig) { | |
2978 | tr_orig = tr; | |
2979 | } | |
2980 | } // RSTF_Union::set_tr() | |
2981 | ||
2982 | virtual void reset_tr() { | |
2983 | tr = tr_orig; | |
2984 | } // RSTF_Union::reset_tr() | |
2985 | ||
2986 | virtual rstf_unionT* copy_from_rst() { | |
2987 | return tr; | |
2988 | } // RSTF_Union::copy_from_rst() | |
2989 | ||
2990 | virtual void copy_to_rst(rstf_unionT* from) { | |
2991 | *tr = *from; | |
2992 | } // RSTF_Union::copy_to_rst() | |
2993 | ||
2994 | virtual int getCpuID() { | |
2995 | return get_rst_type()->getCpuID(); | |
2996 | } | |
2997 | ||
2998 | protected: | |
2999 | rstf_unionT* tr; | |
3000 | rstf_unionT* tr_orig; | |
3001 | ||
3002 | RSTF_Header tr_header; | |
3003 | RSTF_Instr tr_instr; | |
3004 | //RSTF_Asi tr_asi; | |
3005 | RSTF_Traceinfo tr_traceinfo; | |
3006 | RSTF_Tlb tr_tlb; | |
3007 | RSTF_Thread tr_thread; | |
3008 | RSTF_Trap tr_trap; | |
3009 | RSTF_Trapexit tr_trapexit; | |
3010 | RSTF_Trapping_Instr tr_trapping_instr; | |
3011 | RSTF_Bustrace tr_bustrace; | |
3012 | RSTF_Regval tr_regval; | |
3013 | RSTF_Memval64 tr_memval64; | |
3014 | RSTF_Memval128 tr_memval128; | |
3015 | RSTF_Cpu tr_cpu; | |
3016 | RSTF_Process tr_process; | |
3017 | RSTF_Dma tr_dma; | |
3018 | RSTF_String tr_string; | |
3019 | RSTF_Delim tr_delim; | |
3020 | RSTF_Preg tr_preg; | |
3021 | RSTF_Physaddr tr_physaddr; | |
3022 | RSTF_Pavadiff tr_pavadiff; | |
3023 | RSTF_Filemarker tr_filemarker; | |
3024 | RSTF_Status tr_status; | |
3025 | RSTF_Patch tr_patch; | |
3026 | //RSTF_Hwinfo tr_hwinfo; | |
3027 | //RSTF_Memval tr_memval; | |
3028 | RSTF_Snoop tr_snoop; | |
3029 | RSTF_tsb_access tr_tsb_access; | |
3030 | RSTF_rfs_section_header tr_rfs_shdr; | |
3031 | RSTF_bpwarming tr_bpwarming; | |
3032 | RSTF_cachewarming tr_cachewarming; | |
3033 | ||
3034 | RSTF_Timesync tr_timesync; | |
3035 | RSTF_Devidstr tr_devidstr; | |
3036 | ||
3037 | RSTF_Zero tr_zero; | |
3038 | RSTF_Unknown tr_unknown; | |
3039 | ||
3040 | Trace* get_rst_type() { | |
3041 | int cpuid = -1; | |
3042 | switch (tr->proto.rtype) { | |
3043 | case RSTHEADER_T: | |
3044 | return &tr_header; | |
3045 | case INSTR_T: | |
3046 | return &tr_instr; | |
3047 | //case ASI_T: // ASI is deprecated. ASI_T == TRACEINFO_T | |
3048 | //return &tr_asi; | |
3049 | case TRACEINFO_T: | |
3050 | return &tr_traceinfo; | |
3051 | case TLB_T: | |
3052 | return &tr_tlb; | |
3053 | case THREAD_T: | |
3054 | return &tr_thread; | |
3055 | case TRAP_T: | |
3056 | return &tr_trap; | |
3057 | case TRAPEXIT_T: | |
3058 | return &tr_trapexit; | |
3059 | case TRAPPING_INSTR_T: | |
3060 | return & tr_trapping_instr; | |
3061 | case BUSTRACE_T: | |
3062 | return &tr_bustrace; | |
3063 | case REGVAL_T: | |
3064 | return &tr_regval; | |
3065 | case MEMVAL_T: | |
3066 | if (tr->memval64.ismemval128) { | |
3067 | return &tr_memval128; | |
3068 | } | |
3069 | return &tr_memval64; | |
3070 | case CPU_T: // CPU_T == TIMESTAMP_T | |
3071 | return &tr_cpu; | |
3072 | case PROCESS_T: | |
3073 | return &tr_process; | |
3074 | case DMA_T: | |
3075 | return &tr_dma; | |
3076 | case STRDESC_T: | |
3077 | case STRCONT_T: | |
3078 | return &tr_string; | |
3079 | case LEFTDELIM_T: | |
3080 | case RIGHTDELIM_T: | |
3081 | return &tr_delim; | |
3082 | case PREG_T: | |
3083 | gbl.pstate[gbl.rstf_pre212? tr->preg.cpuid: rstf_pregT_get_cpuid(&tr->preg)] = tr->preg.pstate; | |
3084 | return &tr_preg; | |
3085 | case PHYSADDR_T: | |
3086 | return &tr_physaddr; | |
3087 | case PAVADIFF_T: | |
3088 | #ifdef _PRINT_PA | |
3089 | cpuid = gbl.rstf_pre212? tr->pavadiff.cpuid: rstf_pavadiffT_get_cpuid(&tr->pavadiff); | |
3090 | if (tr->pavadiff.ea_valid) { | |
3091 | gbl.ea_pavadiff_valid[cpuid] = true; | |
3092 | gbl.ea_pavadiff_value[cpuid] = tr->pavadiff.ea_pa_va; | |
3093 | } | |
3094 | gbl.pc_pavadiff_value[cpuid] = tr->pavadiff.pc_pa_va; | |
3095 | gbl.pc_pavadiff_valid[cpuid] = true; | |
3096 | #endif | |
3097 | return &tr_pavadiff; | |
3098 | case FILEMARKER_T: // FILEMARKER_T == RECNUM_T | |
3099 | return &tr_filemarker; | |
3100 | case STATUS_T: | |
3101 | return &tr_status; | |
3102 | case PATCH_T: | |
3103 | return &tr_patch; | |
3104 | case HWINFO_T: | |
3105 | //return &tr_hwinfo; | |
3106 | return &tr_unknown; | |
3107 | case SNOOP_T: | |
3108 | return &tr_snoop; | |
3109 | case TSB_ACCESS_T: | |
3110 | return &tr_tsb_access; | |
3111 | case RFS_SECTION_HEADER_T: | |
3112 | return &tr_rfs_shdr; | |
3113 | case RFS_BT_T: | |
3114 | return & tr_bpwarming; | |
3115 | case RFS_CW_T: | |
3116 | return & tr_cachewarming; | |
3117 | case TIMESYNC_T: | |
3118 | return & tr_timesync; | |
3119 | case DEVIDSTR_T: | |
3120 | return & tr_devidstr; | |
3121 | case RST_ZERO_T: | |
3122 | return &tr_zero; | |
3123 | default: | |
3124 | return &tr_unknown; | |
3125 | } | |
3126 | } // RSTF_Union::get_rst_type() | |
3127 | ||
3128 | void print_header() { | |
3129 | static bool prheader = true; | |
3130 | ||
3131 | if (prheader) { | |
3132 | fprintf(gbl.outfp, "RST trace format (%s)\n", gbl.infile); | |
3133 | fprintf(gbl.outfp, "================\n"); | |
3134 | ||
3135 | if (!gbl.noIns) { | |
3136 | if (gbl.disassembly) { | |
3137 | if (gbl.showIdx) { | |
3138 | fprintf(gbl.outfp, | |
3139 | " User/ Branch\n" | |
3140 | " Rec # Type Priv PC Disassembly Taken EA \n"); | |
3141 | } else { | |
3142 | fprintf(gbl.outfp, | |
3143 | " User/ Branch\n" | |
3144 | "Type Priv PC Disassembly Taken EA \n"); | |
3145 | } | |
3146 | } else if (gbl.verbose) { | |
3147 | if (gbl.showIdx) { | |
3148 | fprintf(gbl.outfp, | |
3149 | " User/ Br\n" | |
3150 | " Rec # Type Priv PC Disassembly Instr Word IH Tk EA (x = invalid ea)\n"); | |
3151 | } else { | |
3152 | fprintf(gbl.outfp, | |
3153 | " User/ Br\n" | |
3154 | "Type Priv PC Disassembly Instr Word IH Tk EA (x = invalid ea)\n"); | |
3155 | } | |
3156 | } | |
3157 | } | |
3158 | ||
3159 | prheader = false; | |
3160 | } | |
3161 | } // RSTF_Union::print_header() | |
3162 | }; // RSTF_Union | |
3163 | ||
3164 | //====================================================================== | |
3165 | //====================================================================== | |
3166 | ||
3167 | // Trtf99 and Tshade5 use Shade5 ihash values; | |
3168 | // all other formats use the Shade6 ihash values. | |
3169 | // | |
3170 | class rtf99 : public Trace { | |
3171 | public: | |
3172 | virtual void print_dasm(uint64_t idx) { | |
3173 | char dis_string[80]; | |
3174 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3175 | ||
3176 | print_header(); | |
3177 | ||
3178 | if (gbl.showIdx) { | |
3179 | fprintf(gbl.outfp , "%6lld ", idx); | |
3180 | } | |
3181 | ||
3182 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3183 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3184 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3185 | fprintf(gbl.outfp, "0x%x", tr->tr_misc); | |
3186 | ||
3187 | fprintf(gbl.outfp, "\n"); | |
3188 | } // rtf99::print_dasm() | |
3189 | ||
3190 | virtual void print_rec(uint64_t idx) { | |
3191 | print_header(); | |
3192 | ||
3193 | if (gbl.showIdx) { | |
3194 | fprintf(gbl.outfp , "%6lld ", idx); | |
3195 | } | |
3196 | ||
3197 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3198 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3199 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3200 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3201 | fprintf(gbl.outfp, "0x%x ", tr->tr_misc); | |
3202 | fprintf(gbl.outfp, "\n"); | |
3203 | } // rtf99::print_rec() | |
3204 | ||
3205 | virtual void print_verb(uint64_t idx) { | |
3206 | char dis_string[80]; | |
3207 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3208 | ||
3209 | print_header(); | |
3210 | ||
3211 | if (gbl.showIdx) { | |
3212 | fprintf(gbl.outfp , "%6lld ", idx); | |
3213 | } | |
3214 | ||
3215 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3216 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3217 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3218 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3219 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3220 | fprintf(gbl.outfp, "0x%x", tr->tr_misc); | |
3221 | ||
3222 | fprintf(gbl.outfp, "\n"); | |
3223 | } // rtf99::print_verb() | |
3224 | ||
3225 | virtual void convert_to_master() { | |
3226 | this_master.tr_pc_va = tr->tr_pc; | |
3227 | this_master.tr_ea_va = tr->tr_ea ; | |
3228 | this_master.tr_tid = 0; | |
3229 | this_master.tr_ih = tr->tr_ih; | |
3230 | this_master.tr_reserved0 = 0; | |
3231 | this_master.tr_taken = tr->tr_misc & 1; | |
3232 | this_master.tr_annulled = (tr->tr_misc << 1) & 1; | |
3233 | this_master.tr_iwstart = 0; | |
3234 | this_master.tr_i = tr->tr_i; | |
3235 | this_master.tr_reserved1 = 0; | |
3236 | this_master.tr_pc_pa = 0; | |
3237 | this_master.tr_ea_pa = 0; | |
3238 | this_master.tr_context = 0; | |
3239 | this_master.tr_asi = 0; | |
3240 | this_master.tr_got_trap = 0; | |
3241 | this_master.tr_asi_change = 0; | |
3242 | this_master.tr_privmode = 0; | |
3243 | } // rtf99::convert_to_master() | |
3244 | ||
3245 | virtual void convert_from_master(Tmaster64* master) { | |
3246 | tr->tr_pc = (uint32_t)master->tr_pc_va; | |
3247 | tr->tr_ea = (uint32_t)master->tr_ea_va; | |
3248 | tr->tr_ih = master->tr_ih; | |
3249 | tr->tr_misc = master->tr_taken + (master->tr_annulled >> 1); | |
3250 | tr->tr_i = master->tr_i; | |
3251 | } // rtf99::convert_from_master() | |
3252 | ||
3253 | virtual void gen_ihash() { | |
3254 | tr->tr_ih = getIHash(tr->tr_i); | |
3255 | } // tfr99::gen_ihash() | |
3256 | ||
3257 | virtual int check_ihash_error() { | |
3258 | if (tr->tr_ih != getIHash(tr->tr_i)) { | |
3259 | return 1; | |
3260 | } | |
3261 | ||
3262 | return 0; | |
3263 | } // rtf99::check_ihash_error() | |
3264 | ||
3265 | virtual void verify() { | |
3266 | Trtf99 * vtr = tr - NUM_VERIFY; | |
3267 | int i; | |
3268 | ||
3269 | for (i = 0; i < NUM_VERIFY - 1; i++) { | |
3270 | if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { | |
3271 | fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); | |
3272 | set_tr(&vtr[i], false); | |
3273 | print_verb(gbl.rcount - NUM_VERIFY + i); | |
3274 | //exit(2); | |
3275 | } | |
3276 | } | |
3277 | } // rtf99::verify() | |
3278 | ||
3279 | virtual uint64_t get_pc() { | |
3280 | return tr->tr_pc; | |
3281 | } // rtf99::get_pc() | |
3282 | ||
3283 | virtual uint64_t get_ea() { | |
3284 | return tr->tr_ea; | |
3285 | } // rtf99::get_ea() | |
3286 | ||
3287 | virtual int get_ihash() { | |
3288 | return tr->tr_ih; | |
3289 | } // rtf99::get_ihash() | |
3290 | ||
3291 | virtual void inc_tr() { | |
3292 | tr++; | |
3293 | } // rtf99::inc_tr() | |
3294 | ||
3295 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
3296 | tr = (Trtf99 *) ptr; | |
3297 | ||
3298 | if (set_orig) { | |
3299 | tr_orig = tr; | |
3300 | } | |
3301 | } // rtf99::set_tr() | |
3302 | ||
3303 | virtual void reset_tr() { | |
3304 | tr = tr_orig; | |
3305 | } // rtf99::reset_tr() | |
3306 | ||
3307 | protected: | |
3308 | Trtf99 * tr; | |
3309 | Trtf99 * tr_orig; | |
3310 | ||
3311 | void print_header() { | |
3312 | static bool prheader = false; | |
3313 | ||
3314 | if (!prheader) { | |
3315 | fprintf(gbl.outfp, "rtf99 trace format (%s)\n", gbl.infile); | |
3316 | fprintf(gbl.outfp, "====================\n"); | |
3317 | ||
3318 | if (gbl.record) { | |
3319 | if (gbl.showIdx) { | |
3320 | fprintf(gbl.outfp, " Rec # tr_pc tr_i " | |
3321 | "tr_ih tr_ea misc\n"); | |
3322 | } else { | |
3323 | fprintf(gbl.outfp, " tr_pc tr_i " | |
3324 | "tr_ih tr_ea misc\n"); | |
3325 | } | |
3326 | } else if (gbl.disassembly) { | |
3327 | if (gbl.showIdx) { | |
3328 | fprintf(gbl.outfp, " Rec # PC Disassembly" | |
3329 | " EA Misc\n"); | |
3330 | } else { | |
3331 | fprintf(gbl.outfp, " PC Disassembly" | |
3332 | " EA Misc\n"); | |
3333 | } | |
3334 | } else { | |
3335 | if (gbl.showIdx) { | |
3336 | fprintf(gbl.outfp, " Rec # PC Disassembly" | |
3337 | " Instr Word IH EA\n"); | |
3338 | } else { | |
3339 | fprintf(gbl.outfp, " PC Disassembly" | |
3340 | " Instr Word IH EA\n"); | |
3341 | } | |
3342 | } | |
3343 | ||
3344 | prheader = true; | |
3345 | } | |
3346 | } // rtf99::print_header() | |
3347 | }; // rtf99 | |
3348 | ||
3349 | // Trtf99 and Tshade5 use Shade5 ihash values; | |
3350 | // all other formats use the Shade6 ihash values. | |
3351 | ||
3352 | class Shade5 : public Trace { | |
3353 | public: | |
3354 | virtual void print_dasm(uint64_t idx) { | |
3355 | char dis_string[80]; | |
3356 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3357 | ||
3358 | print_header(); | |
3359 | ||
3360 | if (gbl.showIdx) { | |
3361 | fprintf(gbl.outfp , "%6lld ", idx); | |
3362 | } | |
3363 | ||
3364 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3365 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3366 | ||
3367 | if (ih_iscti(tr->tr_ih)) { | |
3368 | if (tr->tr_taken) { | |
3369 | fprintf(gbl.outfp, "T "); | |
3370 | } else { | |
3371 | fprintf(gbl.outfp, "N "); | |
3372 | } | |
3373 | } else { | |
3374 | fprintf(gbl.outfp, " "); | |
3375 | } | |
3376 | ||
3377 | if (tr->tr_annulled) { | |
3378 | fprintf(gbl.outfp, "an "); | |
3379 | } else { | |
3380 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3381 | } | |
3382 | ||
3383 | fprintf(gbl.outfp, "\n"); | |
3384 | } // Shade5::print_dasm() | |
3385 | ||
3386 | virtual void print_rec(uint64_t idx) { | |
3387 | print_header(); | |
3388 | ||
3389 | if (gbl.showIdx) { | |
3390 | fprintf(gbl.outfp , "%6lld ", idx); | |
3391 | } | |
3392 | ||
3393 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3394 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3395 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3396 | ||
3397 | if (ih_iscti(tr->tr_ih)) { | |
3398 | if (tr->tr_taken) { | |
3399 | fprintf(gbl.outfp, "T "); | |
3400 | } else { | |
3401 | fprintf(gbl.outfp, "N "); | |
3402 | } | |
3403 | } else { | |
3404 | fprintf(gbl.outfp, " "); | |
3405 | } | |
3406 | ||
3407 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3408 | fprintf(gbl.outfp, "%d ", tr->tr_annulled); | |
3409 | fprintf(gbl.outfp, "\n"); | |
3410 | } // Shade5::print_rec() | |
3411 | ||
3412 | virtual void print_verb(uint64_t idx) { | |
3413 | char dis_string[80]; | |
3414 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3415 | ||
3416 | print_header(); | |
3417 | ||
3418 | if (gbl.showIdx) { | |
3419 | fprintf(gbl.outfp , "%6lld ", idx); | |
3420 | } | |
3421 | ||
3422 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3423 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3424 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3425 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3426 | ||
3427 | if (ih_iscti(tr->tr_ih)) { | |
3428 | if (tr->tr_taken) { | |
3429 | fprintf(gbl.outfp, "T "); | |
3430 | } else { | |
3431 | fprintf(gbl.outfp, "N "); | |
3432 | } | |
3433 | } else { | |
3434 | fprintf(gbl.outfp, " "); | |
3435 | } | |
3436 | ||
3437 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3438 | ||
3439 | if (tr->tr_annulled) { | |
3440 | fprintf(gbl.outfp, "an "); | |
3441 | } | |
3442 | ||
3443 | fprintf(gbl.outfp, "\n"); | |
3444 | } // Shade5::print_verb() | |
3445 | ||
3446 | virtual void convert_to_master() { | |
3447 | this_master.tr_pc_va = tr->tr_pc; | |
3448 | this_master.tr_ea_va = tr->tr_ea ; | |
3449 | this_master.tr_tid = 0; | |
3450 | this_master.tr_ih = tr->tr_ih; | |
3451 | this_master.tr_reserved0 = 0; | |
3452 | this_master.tr_taken = tr->tr_taken; | |
3453 | this_master.tr_annulled = tr->tr_annulled; | |
3454 | this_master.tr_iwstart = 0; | |
3455 | this_master.tr_i = tr->tr_i; | |
3456 | this_master.tr_reserved1 = 0; | |
3457 | this_master.tr_pc_pa = 0; | |
3458 | this_master.tr_ea_pa = 0; | |
3459 | this_master.tr_context = 0; | |
3460 | this_master.tr_asi = 0; | |
3461 | this_master.tr_got_trap = 0; | |
3462 | this_master.tr_asi_change = 0; | |
3463 | this_master.tr_privmode = 0; | |
3464 | } // Shade5::convert_to_master() | |
3465 | ||
3466 | virtual void convert_from_master(Tmaster64* master) { | |
3467 | tr->tr_pc = (uint32_t) master->tr_pc_va; | |
3468 | tr->tr_ea = (uint32_t) master->tr_ea_va; | |
3469 | tr->tr_ih = master->tr_ih; | |
3470 | tr->tr_taken = master->tr_taken; | |
3471 | tr->tr_annulled = master->tr_annulled; | |
3472 | tr->tr_i = master->tr_i; | |
3473 | } // Shade5::convert_from_master() | |
3474 | ||
3475 | virtual void gen_ihash() { | |
3476 | tr->tr_ih = getIHash(tr->tr_i); | |
3477 | } // Shade5::gen_ihash() | |
3478 | ||
3479 | virtual int check_ihash_error() { | |
3480 | if (tr->tr_ih != getIHash(tr->tr_i)) { | |
3481 | return 1; | |
3482 | } | |
3483 | ||
3484 | return 0; | |
3485 | } // Shade5::check_ihash_error() | |
3486 | ||
3487 | virtual void verify() { | |
3488 | Tshade5* vtr = tr - NUM_VERIFY; | |
3489 | int i; | |
3490 | ||
3491 | for (i = 0; i < NUM_VERIFY - 1; i++) { | |
3492 | if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { | |
3493 | fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); | |
3494 | set_tr(&vtr[i], false); | |
3495 | print_verb(gbl.rcount - NUM_VERIFY + i); | |
3496 | //exit(2); | |
3497 | } | |
3498 | } | |
3499 | } // Shade5::verify() | |
3500 | ||
3501 | virtual uint64_t get_pc() { | |
3502 | return tr->tr_pc; | |
3503 | } // Shade5::get_pc() | |
3504 | ||
3505 | virtual uint64_t get_ea() { | |
3506 | return tr->tr_ea; | |
3507 | } // Shade5::get_ea() | |
3508 | ||
3509 | virtual int get_ihash() { | |
3510 | return tr->tr_ih; | |
3511 | } // Shade5::get_ihash() | |
3512 | ||
3513 | virtual void inc_tr() { | |
3514 | tr++; | |
3515 | } // Shade5::inc_tr() | |
3516 | ||
3517 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
3518 | tr = (Tshade5*) ptr; | |
3519 | ||
3520 | if (set_orig) { | |
3521 | tr_orig = tr; | |
3522 | } | |
3523 | } // Shade5::set_tr() | |
3524 | ||
3525 | virtual void reset_tr() { | |
3526 | tr = tr_orig; | |
3527 | } // Shade5::reset_tr() | |
3528 | ||
3529 | protected: | |
3530 | Tshade5* tr; | |
3531 | Tshade5* tr_orig; | |
3532 | ||
3533 | void print_header() { | |
3534 | static bool prheader = true; | |
3535 | ||
3536 | if (prheader) { | |
3537 | fprintf(gbl.outfp, "Shade5 trace format (%s)\n", gbl.infile); | |
3538 | fprintf(gbl.outfp, "=====================\n"); | |
3539 | ||
3540 | if (gbl.record) { | |
3541 | if (gbl.showIdx) { | |
3542 | fprintf(gbl.outfp, " Rec # tr_pc tr_i " | |
3543 | "tr_ih tr_ea an\n"); | |
3544 | } else { | |
3545 | fprintf(gbl.outfp, " tr_pc tr_i " | |
3546 | "tr_ih tr_ea an\n"); | |
3547 | } | |
3548 | } else if (gbl.disassembly) { | |
3549 | if (gbl.showIdx) { | |
3550 | fprintf(gbl.outfp, " " | |
3551 | " Br\n" | |
3552 | " Rec # PC Disassembly" | |
3553 | " Tk EA\n"); | |
3554 | } else { | |
3555 | fprintf(gbl.outfp, " " | |
3556 | " Br\n" | |
3557 | " PC Disassembly" | |
3558 | " Tk EA\n"); | |
3559 | } | |
3560 | } else { | |
3561 | if (gbl.showIdx) { | |
3562 | fprintf(gbl.outfp, " " | |
3563 | " Br\n" | |
3564 | " Rec # PC Disassembly" | |
3565 | " Instr Word IH Tk EA\n"); | |
3566 | } else { | |
3567 | fprintf(gbl.outfp, " " | |
3568 | " Br\n" | |
3569 | " PC Disassembly" | |
3570 | " Instr Word IH Tk EA\n"); | |
3571 | } | |
3572 | } | |
3573 | ||
3574 | prheader = false; | |
3575 | } | |
3576 | } | |
3577 | }; // Shade5 | |
3578 | ||
3579 | class Shade6x32 : public Trace { | |
3580 | public: | |
3581 | virtual void print_dasm(uint64_t idx) { | |
3582 | char dis_string[80]; | |
3583 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3584 | ||
3585 | print_header(); | |
3586 | ||
3587 | if (gbl.showIdx) { | |
3588 | fprintf(gbl.outfp , "%6lld ", idx); | |
3589 | } | |
3590 | ||
3591 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3592 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3593 | ||
3594 | if (ih_iscti(tr->tr_ih)) { | |
3595 | if (tr->tr_taken) { | |
3596 | fprintf(gbl.outfp, "T "); | |
3597 | } else { | |
3598 | fprintf(gbl.outfp, "N "); | |
3599 | } | |
3600 | } else { | |
3601 | fprintf(gbl.outfp, " "); | |
3602 | } | |
3603 | ||
3604 | if (tr->tr_annulled) { | |
3605 | fprintf(gbl.outfp, "an "); | |
3606 | } else { | |
3607 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3608 | } | |
3609 | ||
3610 | if (tr->tr_tid) { | |
3611 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); | |
3612 | } | |
3613 | ||
3614 | if (tr->tr_iwstart) { | |
3615 | fprintf(gbl.outfp, "wi "); | |
3616 | } | |
3617 | ||
3618 | fprintf(gbl.outfp, "\n"); | |
3619 | } // Shade6x32::print_dasm() | |
3620 | ||
3621 | virtual void print_rec(uint64_t idx) { | |
3622 | print_header(); | |
3623 | ||
3624 | if (gbl.showIdx) { | |
3625 | fprintf(gbl.outfp , "%6lld ", idx); | |
3626 | } | |
3627 | ||
3628 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3629 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3630 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3631 | ||
3632 | if (ih_iscti(tr->tr_ih)) { | |
3633 | if (tr->tr_taken) { | |
3634 | fprintf(gbl.outfp, "T "); | |
3635 | } else { | |
3636 | fprintf(gbl.outfp, "N "); | |
3637 | } | |
3638 | } else { | |
3639 | fprintf(gbl.outfp, " "); | |
3640 | } | |
3641 | ||
3642 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3643 | fprintf(gbl.outfp, "%d ", tr->tr_annulled); | |
3644 | fprintf(gbl.outfp, "%d ", tr->tr_iwstart); | |
3645 | fprintf(gbl.outfp, "0x%08x ", tr->tr_tid); | |
3646 | fprintf(gbl.outfp, "\n"); | |
3647 | } // Shade6x32::print_rec() | |
3648 | ||
3649 | virtual void print_verb(uint64_t idx) { | |
3650 | char dis_string[80]; | |
3651 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3652 | ||
3653 | print_header(); | |
3654 | ||
3655 | if (gbl.showIdx) { | |
3656 | fprintf(gbl.outfp , "%6lld ", idx); | |
3657 | } | |
3658 | ||
3659 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_pc); | |
3660 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3661 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3662 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3663 | ||
3664 | if (ih_iscti(tr->tr_ih)) { | |
3665 | if (tr->tr_taken) { | |
3666 | fprintf(gbl.outfp, "T "); | |
3667 | } else { | |
3668 | fprintf(gbl.outfp, "N "); | |
3669 | } | |
3670 | } else { | |
3671 | fprintf(gbl.outfp, " "); | |
3672 | } | |
3673 | ||
3674 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_ea); | |
3675 | ||
3676 | if (tr->tr_annulled) { | |
3677 | fprintf(gbl.outfp, "an "); | |
3678 | } | |
3679 | ||
3680 | if (tr->tr_tid) { | |
3681 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); | |
3682 | } | |
3683 | ||
3684 | if (tr->tr_iwstart) { | |
3685 | fprintf(gbl.outfp, "wi "); | |
3686 | } | |
3687 | ||
3688 | fprintf(gbl.outfp, "\n"); | |
3689 | } // Shade6x32::print_verb() | |
3690 | ||
3691 | virtual void convert_to_master() { | |
3692 | this_master.tr_pc_va = tr->tr_pc; | |
3693 | this_master.tr_ea_va = tr->tr_ea ; | |
3694 | this_master.tr_tid = tr->tr_tid; | |
3695 | this_master.tr_ih = tr->tr_ih; | |
3696 | this_master.tr_reserved0 = tr->tr_shade_reserved0; | |
3697 | this_master.tr_taken = tr->tr_taken; | |
3698 | this_master.tr_annulled = tr->tr_annulled; | |
3699 | this_master.tr_iwstart = tr->tr_iwstart; | |
3700 | this_master.tr_i = tr->tr_i; | |
3701 | this_master.tr_reserved1 = tr->tr_shade_reserved1; | |
3702 | this_master.tr_pc_pa = 0; | |
3703 | this_master.tr_ea_pa = 0; | |
3704 | this_master.tr_context = 0; | |
3705 | this_master.tr_asi = 0; | |
3706 | this_master.tr_got_trap = 0; | |
3707 | this_master.tr_asi_change = 0; | |
3708 | this_master.tr_privmode = 0; | |
3709 | } // Shade6x32::convert_to_master() | |
3710 | ||
3711 | virtual void convert_from_master(Tmaster64* master) { | |
3712 | tr->tr_pc = (uint32_t)master->tr_pc_va; | |
3713 | tr->tr_ea = (uint32_t)master->tr_ea_va ; | |
3714 | tr->tr_tid = master->tr_tid; | |
3715 | tr->tr_ih = master->tr_ih; | |
3716 | tr->tr_ih = tr->tr_ih; | |
3717 | tr->tr_shade_reserved0 = master->tr_reserved0; | |
3718 | tr->tr_taken = master->tr_taken; | |
3719 | tr->tr_annulled = master->tr_annulled; | |
3720 | tr->tr_iwstart = master->tr_iwstart; | |
3721 | tr->tr_i = master->tr_i; | |
3722 | tr->tr_shade_reserved1 = master->tr_reserved1; | |
3723 | } // Shade6x32::convert_from_master() | |
3724 | ||
3725 | virtual void gen_ihash() { | |
3726 | tr->tr_ih = getIHash(tr->tr_i); | |
3727 | } // Shade6x32::gen_ihash() | |
3728 | ||
3729 | virtual int check_ihash_error() { | |
3730 | if (tr->tr_ih != getIHash(tr->tr_i)) { | |
3731 | return 1; | |
3732 | } | |
3733 | ||
3734 | return 0; | |
3735 | } // Shade6x32::check_ihash_error() | |
3736 | ||
3737 | virtual void verify() { | |
3738 | Tshade6x32* vtr = tr - NUM_VERIFY; | |
3739 | int i; | |
3740 | ||
3741 | for (i = 0; i < NUM_VERIFY - 1; i++) { | |
3742 | if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { | |
3743 | fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); | |
3744 | set_tr(&vtr[i], false); | |
3745 | print_verb(gbl.rcount - NUM_VERIFY + i); | |
3746 | //exit(2); | |
3747 | } | |
3748 | } | |
3749 | } // Shade6x32::verify() | |
3750 | ||
3751 | virtual uint64_t get_pc() { | |
3752 | return tr->tr_pc; | |
3753 | } // Shade6x32::get_pc() | |
3754 | ||
3755 | virtual uint64_t get_ea() { | |
3756 | return tr->tr_ea; | |
3757 | } // Shade6x32::get_ea() | |
3758 | ||
3759 | virtual int get_ihash() { | |
3760 | return tr->tr_ih; | |
3761 | } // Shade6x32::get_ihash() | |
3762 | ||
3763 | virtual void inc_tr() { | |
3764 | tr++; | |
3765 | } // Shade6x32::inc_tr() | |
3766 | ||
3767 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
3768 | tr = (Tshade6x32*) ptr; | |
3769 | ||
3770 | if (set_orig) { | |
3771 | tr_orig = tr; | |
3772 | } | |
3773 | } // Shade6x32::set_tr() | |
3774 | ||
3775 | virtual void reset_tr() { | |
3776 | tr = tr_orig; | |
3777 | } // Shade6x32::reset_tr() | |
3778 | ||
3779 | protected: | |
3780 | Tshade6x32* tr; | |
3781 | Tshade6x32* tr_orig; | |
3782 | ||
3783 | void print_header() { | |
3784 | static bool prheader = true; | |
3785 | ||
3786 | if (prheader) { | |
3787 | fprintf(gbl.outfp, "Shade6 (32bit) trace format (%s)\n", gbl.infile); | |
3788 | fprintf(gbl.outfp, "=============================\n"); | |
3789 | ||
3790 | if (gbl.record) { | |
3791 | if (gbl.showIdx) { | |
3792 | fprintf(gbl.outfp, " Rec # tr_pc tr_i " | |
3793 | "tr_ih tr_ea a w tr_tid\n"); | |
3794 | } else { | |
3795 | fprintf(gbl.outfp, " tr_pc tr_i " | |
3796 | "tr_ih tr_ea a w tr_tid\n"); | |
3797 | } | |
3798 | } else if (gbl.disassembly) { | |
3799 | if (gbl.showIdx) { | |
3800 | fprintf(gbl.outfp, " " | |
3801 | " Br\n" | |
3802 | " Rec # PC Disassembly" | |
3803 | " Tk EA\n"); | |
3804 | } else { | |
3805 | fprintf(gbl.outfp, " " | |
3806 | " Br\n" | |
3807 | " PC Disassembly" | |
3808 | " Tk EA\n"); | |
3809 | } | |
3810 | } else { | |
3811 | if (gbl.showIdx) { | |
3812 | fprintf(gbl.outfp, " " | |
3813 | " Br\n" | |
3814 | " Rec # PC Disassembly" | |
3815 | " Instr Word IH Tk EA\n"); | |
3816 | } else { | |
3817 | fprintf(gbl.outfp, " " | |
3818 | " Br\n" | |
3819 | " PC Disassembly" | |
3820 | " Instr Word IH Tk EA\n"); | |
3821 | } | |
3822 | } | |
3823 | ||
3824 | prheader = false; | |
3825 | } | |
3826 | } | |
3827 | }; // Shade6x32 | |
3828 | ||
3829 | ||
3830 | class Shade6x64 : public Trace { | |
3831 | public: | |
3832 | virtual void print_dasm(uint64_t idx) { | |
3833 | char dis_string[80]; | |
3834 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3835 | ||
3836 | print_header(); | |
3837 | ||
3838 | if (gbl.showIdx) { | |
3839 | fprintf(gbl.outfp , "%6lld ", idx); | |
3840 | } | |
3841 | ||
3842 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc); | |
3843 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3844 | ||
3845 | if (ih_iscti(tr->tr_ih)) { | |
3846 | if (tr->tr_taken) { | |
3847 | fprintf(gbl.outfp, "T "); | |
3848 | } else { | |
3849 | fprintf(gbl.outfp, "N "); | |
3850 | } | |
3851 | } else { | |
3852 | fprintf(gbl.outfp, " "); | |
3853 | } | |
3854 | ||
3855 | if (tr->tr_annulled) { | |
3856 | fprintf(gbl.outfp, "an "); | |
3857 | } else { | |
3858 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea); | |
3859 | } | |
3860 | ||
3861 | if (tr->tr_tid) { | |
3862 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); | |
3863 | } | |
3864 | ||
3865 | if (tr->tr_iwstart) { | |
3866 | fprintf(gbl.outfp, "wi "); | |
3867 | } | |
3868 | ||
3869 | fprintf(gbl.outfp, "\n"); | |
3870 | } // Shade6x64::print_dasm() | |
3871 | ||
3872 | virtual void print_rec(uint64_t idx) { | |
3873 | print_header(); | |
3874 | ||
3875 | if (gbl.showIdx) { | |
3876 | fprintf(gbl.outfp , "%6lld ", idx); | |
3877 | } | |
3878 | ||
3879 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc); | |
3880 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3881 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3882 | ||
3883 | if (ih_iscti(tr->tr_ih)) { | |
3884 | if (tr->tr_taken) { | |
3885 | fprintf(gbl.outfp, "T "); | |
3886 | } else { | |
3887 | fprintf(gbl.outfp, "N "); | |
3888 | } | |
3889 | } else { | |
3890 | fprintf(gbl.outfp, " "); | |
3891 | } | |
3892 | ||
3893 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea); | |
3894 | fprintf(gbl.outfp, "%d ", tr->tr_annulled); | |
3895 | fprintf(gbl.outfp, "%d ", tr->tr_iwstart); | |
3896 | fprintf(gbl.outfp, "0x%08x ", tr->tr_tid); | |
3897 | fprintf(gbl.outfp, "\n"); | |
3898 | } // Shade6x64::print_rec() | |
3899 | ||
3900 | virtual void print_verb(uint64_t idx) { | |
3901 | char dis_string[80]; | |
3902 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc); | |
3903 | ||
3904 | print_header(); | |
3905 | ||
3906 | if (gbl.showIdx) { | |
3907 | fprintf(gbl.outfp , "%6lld ", idx); | |
3908 | } | |
3909 | ||
3910 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc); | |
3911 | fprintf(gbl.outfp, "%-32s", dis_string); | |
3912 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
3913 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
3914 | ||
3915 | if (ih_iscti(tr->tr_ih)) { | |
3916 | if (tr->tr_taken) { | |
3917 | fprintf(gbl.outfp, "T "); | |
3918 | } else { | |
3919 | fprintf(gbl.outfp, "N "); | |
3920 | } | |
3921 | } else { | |
3922 | fprintf(gbl.outfp, " "); | |
3923 | } | |
3924 | ||
3925 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea); | |
3926 | ||
3927 | if (tr->tr_annulled) { | |
3928 | fprintf(gbl.outfp, "an "); | |
3929 | } | |
3930 | ||
3931 | if (tr->tr_tid) { | |
3932 | fprintf(gbl.outfp, "[0x%08x] ", tr->tr_tid); | |
3933 | } | |
3934 | ||
3935 | if (tr->tr_iwstart) { | |
3936 | fprintf(gbl.outfp, "wi "); | |
3937 | } | |
3938 | ||
3939 | fprintf(gbl.outfp, "\n"); | |
3940 | } // Shade6x64::print_verb() | |
3941 | ||
3942 | virtual void convert_to_master() { | |
3943 | this_master.tr_pc_va = tr->tr_pc; | |
3944 | this_master.tr_ea_va = tr->tr_ea ; | |
3945 | this_master.tr_tid = tr->tr_tid; | |
3946 | this_master.tr_ih = tr->tr_ih; | |
3947 | this_master.tr_reserved0 = tr->tr_shade_reserved0; | |
3948 | this_master.tr_taken = tr->tr_taken; | |
3949 | this_master.tr_annulled = tr->tr_annulled; | |
3950 | this_master.tr_iwstart = tr->tr_iwstart; | |
3951 | this_master.tr_i = tr->tr_i; | |
3952 | this_master.tr_reserved1 = tr->tr_shade_reserved1; | |
3953 | this_master.tr_pc_pa = 0; | |
3954 | this_master.tr_ea_pa = 0; | |
3955 | this_master.tr_context = 0; | |
3956 | this_master.tr_asi = 0; | |
3957 | this_master.tr_got_trap = 0; | |
3958 | this_master.tr_asi_change = 0; | |
3959 | this_master.tr_privmode = 0; | |
3960 | } // Shade6x64::convert_to_master() | |
3961 | ||
3962 | virtual void convert_from_master(Tmaster64* master) { | |
3963 | tr->tr_pc = master->tr_pc_va; | |
3964 | tr->tr_ea = master->tr_ea_va ; | |
3965 | tr->tr_tid = master->tr_tid; | |
3966 | tr->tr_ih = master->tr_ih; | |
3967 | tr->tr_shade_reserved0 = master->tr_reserved0; | |
3968 | tr->tr_taken = master->tr_taken; | |
3969 | tr->tr_annulled = master->tr_annulled; | |
3970 | tr->tr_iwstart = master->tr_iwstart; | |
3971 | tr->tr_i = master->tr_i; | |
3972 | tr->tr_shade_reserved1 = master->tr_reserved1; | |
3973 | } // Shade6x64::convert_from_master() | |
3974 | ||
3975 | virtual void gen_ihash() { | |
3976 | tr->tr_ih = getIHash(tr->tr_i); | |
3977 | } // Shade6x64::gen_ihash() | |
3978 | ||
3979 | virtual int check_ihash_error() { | |
3980 | if (tr->tr_ih != getIHash(tr->tr_i)) { | |
3981 | return 1; | |
3982 | } | |
3983 | ||
3984 | return 0; | |
3985 | } // Shade6x64::check_ihash_error() | |
3986 | ||
3987 | virtual void verify() { | |
3988 | Tshade6x64* vtr = tr - NUM_VERIFY; | |
3989 | int i; | |
3990 | ||
3991 | for (i = 0; i < NUM_VERIFY - 1; i++) { | |
3992 | if (vtr[i].tr_pc % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc) == 0) { | |
3993 | fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); | |
3994 | set_tr(&vtr[i], false); | |
3995 | print_verb(gbl.rcount - NUM_VERIFY + i); | |
3996 | //exit(2); | |
3997 | } | |
3998 | } | |
3999 | } // Shade6x64::verify() | |
4000 | ||
4001 | virtual uint64_t get_pc() { | |
4002 | return tr->tr_pc; | |
4003 | } // Shade6x64::get_pc() | |
4004 | ||
4005 | virtual uint64_t get_ea() { | |
4006 | return tr->tr_ea; | |
4007 | } // Shade6x64::get_ea() | |
4008 | ||
4009 | virtual int get_ihash() { | |
4010 | return tr->tr_ih; | |
4011 | } // Shade6x64::get_ihash() | |
4012 | ||
4013 | virtual void inc_tr() { | |
4014 | tr++; | |
4015 | } // Shade6x64::inc_tr() | |
4016 | ||
4017 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
4018 | tr = (Tshade6x64*) ptr; | |
4019 | ||
4020 | if (set_orig) { | |
4021 | tr_orig = tr; | |
4022 | } | |
4023 | } // Shade6x64::set_tr() | |
4024 | ||
4025 | virtual void reset_tr() { | |
4026 | tr = tr_orig; | |
4027 | } // Shade6x64::reset_tr() | |
4028 | ||
4029 | protected: | |
4030 | Tshade6x64* tr; | |
4031 | Tshade6x64* tr_orig; | |
4032 | ||
4033 | void print_header() { | |
4034 | static bool prheader = true; | |
4035 | ||
4036 | if (prheader) { | |
4037 | fprintf(gbl.outfp, "Shade6 (64bit) trace format (%s)\n", gbl.infile); | |
4038 | fprintf(gbl.outfp, "=============================\n"); | |
4039 | ||
4040 | if (gbl.record) { | |
4041 | if (gbl.showIdx) { | |
4042 | fprintf(gbl.outfp, " Rec # tr_pc tr_i " | |
4043 | "tr_ih tr_ea a w tr_tid\n"); | |
4044 | } else { | |
4045 | fprintf(gbl.outfp, " tr_pc tr_i " | |
4046 | "tr_ih tr_ea a w tr_tid\n"); | |
4047 | } | |
4048 | } else if (gbl.disassembly) { | |
4049 | if (gbl.showIdx) { | |
4050 | fprintf(gbl.outfp, " " | |
4051 | " Br\n" | |
4052 | " Rec # PC Disassembly" | |
4053 | " Tk EA\n"); | |
4054 | } else { | |
4055 | fprintf(gbl.outfp, " " | |
4056 | " Br\n" | |
4057 | " PC Disassembly" | |
4058 | " Tk EA\n"); | |
4059 | } | |
4060 | } else { | |
4061 | if (gbl.showIdx) { | |
4062 | fprintf(gbl.outfp, " " | |
4063 | " Br\n" | |
4064 | " Rec # PC Disassembly" | |
4065 | " Instr Word IH Tk EA\n"); | |
4066 | } else { | |
4067 | fprintf(gbl.outfp, " " | |
4068 | " Br\n" | |
4069 | " PC Disassembly" | |
4070 | " Instr Word IH Tk EA\n"); | |
4071 | } | |
4072 | } | |
4073 | ||
4074 | prheader = false; | |
4075 | } | |
4076 | } // Shade6x64::print_header() | |
4077 | }; // Shade6x64 | |
4078 | ||
4079 | class Master : public Trace { | |
4080 | public: | |
4081 | virtual void print_dasm(uint64_t idx) { | |
4082 | char dis_string[80]; | |
4083 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc_va); | |
4084 | ||
4085 | print_header(); | |
4086 | ||
4087 | if (gbl.showIdx) { | |
4088 | fprintf(gbl.outfp , "%6lld ", idx); | |
4089 | } | |
4090 | ||
4091 | if (tr->tr_privmode) { | |
4092 | fprintf(gbl.outfp, "p "); | |
4093 | } else { | |
4094 | fprintf(gbl.outfp, "u "); | |
4095 | } | |
4096 | ||
4097 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc_va); | |
4098 | fprintf(gbl.outfp, "%-32s", dis_string); | |
4099 | ||
4100 | if (ih_iscti(tr->tr_ih)) { | |
4101 | if (tr->tr_taken) { | |
4102 | fprintf(gbl.outfp, "T "); | |
4103 | } else { | |
4104 | fprintf(gbl.outfp, "N "); | |
4105 | } | |
4106 | } else { | |
4107 | fprintf(gbl.outfp, " "); | |
4108 | } | |
4109 | ||
4110 | if (tr->tr_va_valid && !tr->tr_annulled) { | |
4111 | fprintf(gbl.outfp, "[0x%016llx]", tr->tr_ea_va); | |
4112 | } | |
4113 | ||
4114 | if (tr->tr_annulled) { | |
4115 | fprintf(gbl.outfp, "an "); | |
4116 | } | |
4117 | ||
4118 | if (tr->tr_got_trap) { | |
4119 | fprintf(gbl.outfp, "tr "); | |
4120 | } | |
4121 | ||
4122 | if (tr->tr_asi_change) { | |
4123 | fprintf(gbl.outfp, "asi "); | |
4124 | } | |
4125 | ||
4126 | if (tr->tr_iwstart) { | |
4127 | fprintf(gbl.outfp, "wi "); | |
4128 | } | |
4129 | ||
4130 | fprintf(gbl.outfp, "\n"); | |
4131 | } // Master::print_dasm() | |
4132 | ||
4133 | virtual void print_rec(uint64_t idx) { | |
4134 | print_header(); | |
4135 | ||
4136 | if (gbl.showIdx) { | |
4137 | fprintf(gbl.outfp , "%6lld ", idx); | |
4138 | } | |
4139 | ||
4140 | fprintf(gbl.outfp, " [0x%016llx] ", tr->tr_pc_va); | |
4141 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc_pa); | |
4142 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
4143 | ||
4144 | if (tr->tr_privmode) { | |
4145 | fprintf(gbl.outfp, " p "); | |
4146 | } else { | |
4147 | fprintf(gbl.outfp, " u "); | |
4148 | } | |
4149 | ||
4150 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
4151 | ||
4152 | if (ih_iscti(tr->tr_ih)) { | |
4153 | if (tr->tr_taken) { | |
4154 | fprintf(gbl.outfp, "T "); | |
4155 | } else { | |
4156 | fprintf(gbl.outfp, "N "); | |
4157 | } | |
4158 | } else { | |
4159 | fprintf(gbl.outfp, " "); | |
4160 | } | |
4161 | ||
4162 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_ea_va); | |
4163 | fprintf(gbl.outfp, "<0x%016llx> ", tr->tr_ea_pa); | |
4164 | fprintf(gbl.outfp, "%d ", tr->tr_va_valid); | |
4165 | fprintf(gbl.outfp, " %d ", tr->tr_annulled); | |
4166 | fprintf(gbl.outfp, " %d ", tr->tr_got_trap); | |
4167 | fprintf(gbl.outfp, " %d ", tr->tr_asi_change); | |
4168 | fprintf(gbl.outfp, "0x%04x", tr->tr_tid); | |
4169 | fprintf(gbl.outfp, " %d ", tr->tr_context); | |
4170 | fprintf(gbl.outfp, " %d ", tr->tr_asi); | |
4171 | fprintf(gbl.outfp, " %d ", tr->tr_iwstart); | |
4172 | fprintf(gbl.outfp, "\n"); | |
4173 | } // Master::print_rec | |
4174 | ||
4175 | virtual void print_verb(uint64_t idx) { | |
4176 | char dis_string[80]; | |
4177 | sprintDiss(dis_string, tr->tr_i, tr->tr_pc_va); | |
4178 | ||
4179 | print_header(); | |
4180 | ||
4181 | if (gbl.showIdx) { | |
4182 | fprintf(gbl.outfp , "%6lld ", idx); | |
4183 | } | |
4184 | ||
4185 | if (tr->tr_privmode) { | |
4186 | fprintf(gbl.outfp, "p "); | |
4187 | } else { | |
4188 | fprintf(gbl.outfp, "u "); | |
4189 | } | |
4190 | ||
4191 | fprintf(gbl.outfp, "[0x%016llx] ", tr->tr_pc_va); | |
4192 | fprintf(gbl.outfp, "<0x%016llx> ", tr->tr_pc_pa); | |
4193 | fprintf(gbl.outfp, "%-32s", dis_string); | |
4194 | fprintf(gbl.outfp, "(0x%08x) ", tr->tr_i); | |
4195 | fprintf(gbl.outfp, "%3d ", tr->tr_ih); | |
4196 | ||
4197 | if (ih_iscti(tr->tr_ih)) { | |
4198 | if (tr->tr_taken) { | |
4199 | fprintf(gbl.outfp, "T "); | |
4200 | } else { | |
4201 | fprintf(gbl.outfp, "N "); | |
4202 | } | |
4203 | } else { | |
4204 | fprintf(gbl.outfp, " "); | |
4205 | } | |
4206 | ||
4207 | fprintf(gbl.outfp, "[0x%016llx]", tr->tr_ea_va); | |
4208 | ||
4209 | if (!tr->tr_va_valid) { | |
4210 | fprintf(gbl.outfp, "x "); | |
4211 | } else { | |
4212 | fprintf(gbl.outfp, " "); | |
4213 | } | |
4214 | ||
4215 | fprintf(gbl.outfp, "<0x%016llx> ", tr->tr_ea_pa); | |
4216 | ||
4217 | if (tr->tr_annulled) { | |
4218 | fprintf(gbl.outfp, "an "); | |
4219 | } | |
4220 | ||
4221 | if (tr->tr_got_trap) { | |
4222 | fprintf(gbl.outfp, "tr "); | |
4223 | } | |
4224 | ||
4225 | if (tr->tr_asi_change) { | |
4226 | fprintf(gbl.outfp, "asi "); | |
4227 | } | |
4228 | ||
4229 | if (tr->tr_iwstart) { | |
4230 | fprintf(gbl.outfp, "wi "); | |
4231 | } | |
4232 | ||
4233 | fprintf(gbl.outfp, "\n"); | |
4234 | } // Master::print_verb() | |
4235 | ||
4236 | virtual void convert_to_master() { | |
4237 | this_master = *tr; | |
4238 | } // Master::convert_to_master | |
4239 | ||
4240 | virtual void convert_from_master(Tmaster64* master) { | |
4241 | *tr = *master; | |
4242 | } // Master::convert_from_master() | |
4243 | ||
4244 | virtual void gen_ihash() { | |
4245 | tr->tr_ih = getIHash(tr->tr_i); | |
4246 | } // Master::gen_ihash() | |
4247 | ||
4248 | virtual int check_ihash_error() { | |
4249 | if (tr->tr_ih != getIHash(tr->tr_i)) { | |
4250 | return 1; | |
4251 | } | |
4252 | ||
4253 | return 0; | |
4254 | } // Master::check_ihash_error() | |
4255 | ||
4256 | virtual void verify() { | |
4257 | Tmaster64* vtr = tr - NUM_VERIFY; | |
4258 | int i; | |
4259 | ||
4260 | for (i = 0; i < NUM_VERIFY - 1; i++) { | |
4261 | if (vtr[i].tr_pc_va % 4 != 0 && RSTF_IS_BADADDR(vtr[i].tr_pc_va) == 0) { | |
4262 | fprintf(stderr, "trconv: Error: Incorrect pc value in input file.\n"); | |
4263 | set_tr(&vtr[i], false); | |
4264 | print_verb(gbl.rcount - NUM_VERIFY + i); | |
4265 | //exit(2); | |
4266 | } | |
4267 | } | |
4268 | } // Master::verify() | |
4269 | ||
4270 | virtual uint64_t get_pc() { | |
4271 | return tr->tr_pc_va; | |
4272 | } // Master::get_pc() | |
4273 | ||
4274 | virtual uint64_t get_ea() { | |
4275 | return tr->tr_ea_va; | |
4276 | } // Master::get_ea() | |
4277 | ||
4278 | virtual int get_ihash() { | |
4279 | return tr->tr_ih; | |
4280 | } // Master::get_ihash() | |
4281 | ||
4282 | virtual void inc_tr() { | |
4283 | tr++; | |
4284 | } // Master::inc_tr() | |
4285 | ||
4286 | virtual void set_tr(void* ptr, bool set_orig = true) { | |
4287 | tr = (Tmaster64*) ptr; | |
4288 | ||
4289 | if (set_orig) { | |
4290 | tr_orig = tr; | |
4291 | } | |
4292 | } // Master::set_tr() | |
4293 | ||
4294 | virtual void reset_tr() { | |
4295 | tr = tr_orig; | |
4296 | } // Master::reset_tr() | |
4297 | ||
4298 | protected: | |
4299 | Tmaster64* tr; | |
4300 | Tmaster64* tr_orig; | |
4301 | ||
4302 | void print_header() { | |
4303 | static bool prheader = true; | |
4304 | ||
4305 | if (prheader) { | |
4306 | fprintf(gbl.outfp, "Master trace format (%s)\n", gbl.infile); | |
4307 | fprintf(gbl.outfp, "===================\n"); | |
4308 | ||
4309 | if (gbl.record) { | |
4310 | if (gbl.showIdx) { | |
4311 | fprintf(gbl.outfp, " Rec # tr_pc_va tr_pc_pa " | |
4312 | "tr_i tr_ih tr_ea_va tr_ea_pa " | |
4313 | " va an gt ac tid cx a iw\n"); | |
4314 | } else { | |
4315 | fprintf(gbl.outfp, " tr_pc_va tr_pc_pa " | |
4316 | "tr_i tr_ih tr_ea_va tr_ea_pa " | |
4317 | " va an gt ac tid cx a iw\n"); | |
4318 | } | |
4319 | } else if (gbl.disassembly) { | |
4320 | if (gbl.showIdx) { | |
4321 | fprintf(gbl.outfp, " Usr/ " | |
4322 | " Br\n" | |
4323 | " Rec # Pr PC Disassembly" | |
4324 | " Tk EA\n"); | |
4325 | } else { | |
4326 | fprintf(gbl.outfp, "Usr/ " | |
4327 | " Br\n" | |
4328 | "Pr PC Disassembly" | |
4329 | " Tk EA\n"); | |
4330 | } | |
4331 | } else { | |
4332 | if (gbl.showIdx) { | |
4333 | fprintf(gbl.outfp, " Usr/ " | |
4334 | " " | |
4335 | " Br\n" | |
4336 | " Rec # Pr PC (virtual) PC (physical)" | |
4337 | " Disassembly " | |
4338 | "Instr Word IH" | |
4339 | " Tk EA (virtual, x=inv) EA (physical)\n"); | |
4340 | } else { | |
4341 | fprintf(gbl.outfp, "Usr/ " | |
4342 | " " | |
4343 | " Br\n" | |
4344 | "Pr PC (virtual) PC (physical)" | |
4345 | " Disassembly " | |
4346 | "Instr Word IH" | |
4347 | " Tk EA (virtual, x=inv) EA (physical)\n"); | |
4348 | } | |
4349 | } | |
4350 | ||
4351 | prheader = false; | |
4352 | } // Master::print_header() | |
4353 | } | |
4354 | }; // Master | |
4355 |