Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / include / rstf / rstf.h
CommitLineData
86530b38
AT
1#ifndef _rstf_h
2#define _rstf_h
3
4#ident "@(#) rstf.h 1.41: 12/08/03 13:03:59 @(#)"
5
6/*
7 * WARNING: The Java RST jrst package relies upon the existing comment style
8 * to pick off the rtype value in each record. The Perl script
9 * that "parses" this .h file is jrst/c2java.pl
10 * I apologize in advance for this hackery. -R Quong 5/2002
11 *
12 * File contents (you can search this file using on the terms below)
13 * 0) Associated header files and #defines
14 * 1) Overview of RST format
15 * History
16 * 2) Version info and checking
17 * If you use the RST version check code, you must link with rstf/rstf.o
18 * 3) struct definitions
19 * 4) Useful functions
20 * If you use any functions in (3), you must link with rstf/rstf.o
21 */
22
23/*
24 * ================ 0) Associated header file and #defines ===========
25 * Choose *ONE* of the following to include:
26 *
27 * rstf.h // most people should just include this file
28 * rstf_bustrace.h // bustrace implementation specifics + rstf.h
29 *
30 * To use deprecated RSTF values, include rstf_deprecated.h *FIRST* Ex:
31 *
32 * #include "rstf/rstf_deprecated.h"
33 * #include "rstf/rstf.h"
34 *
35 */
36
37/*
38 * ================ 1) Overview of RST format ================
39 * RST (trace) format or just RST for short.
40 * Russell's Simplified Trace format
41 * Really Simple Trace format
42 *
43 * RST format handles "unified architectural" trace data.
44 * There are different kinds of records corresponding to
45 * - instructions
46 * - events (traps, interrupts)
47 * - MMU state (TLB entry changes)
48 * - internal processor state (register dumps)
49 * - high-level evnts (process/context switch, thread switch)
50 * - markers (timestamp, current CPU)
51 * - state (cache/memory state)
52 *
53 * For simplicity of reading data, all records are the same size (24 bytes)
54 * making it easy if you want to skip certain records.
55 * The first byte in each record, the rtype, denotes the record type.
56 *
57 * +==============+
58 * | byte: header | The first record must be of type rstf_headerT
59 * | maj,minor,% | Use init_rstf_header(rstf_headerT * hp)
60 * | header |
61 * | marker |
62 * +==============+
63 * | byte: rtype |
64 * | |
65 * | 23 bytes of |
66 * | data |
67 * +==============+
68 * | byte: rtype |
69 * | |
70 * | 23 bytes of |
71 * | data |
72 * +==============+
73 * | byte: rtype |
74 * | |
75 * | 23 bytes of |
76 * | data |
77 * +==============+
78 *
79 * We have different records type, so that future record types
80 * can be added in the future.
81 *
82 * One easy way to read or write an RST trace is to define a
83 * buffer of type rstf_unionT, which is a union of all known rec types.
84 * You can access the record type of your choice directly w/o typecasts.
85 *
86 * rstf_unionT rstbuff [1024];
87 * ... read or write into rstbuff ...
88 * rstf_instrT * instrPtr = & rstbuff[3].instr; // good = NO TYPE CASTING
89 * rstf_instrT * instrPtr = (rstf_instrT*) &rstbuff[3]; // avoid, bad, ugly
90 * int pc = instrPtr->pc_va;
91 * int iContext = rstbuff[89].pavadiff.icontext;
92 * rstf_tlbT * tlb = & rstbuff[234].tlb; // no type casting (!!)
93 *
94 * HISTORY:
95 * This was format was originally known as unatrace (Version 1) in 1999.
96 *
97 * In 10/99, I (R Quong) developed a new definition for
98 * the unatrace version 2 (now known as unawrap) format,
99 * to be a general trace wrapper.
100 * Rather than call the original format unatrace version 1, which
101 * became way rather confusing, I renamed it as RST.
102 * As of 4/2001, nothing is called unatrace.
103 */
104
105#include <stdio.h> // FILE*
106#include <sys/types.h> // uid_t
107
108#ifdef __cplusplus
109extern "C" {
110#endif
111#if 0
112}
113#endif
114
115#if defined(RSTF_USE_DEPRECATED)
116#include "rstf/rstf_deprecated.h"
117#endif
118
119// if compiling with cc, use '-xCC' to handle C++ comments.
120
121// emacs commands for me (RQ)
122// (query-replace-regexp "int\\([0-9]+\\)" "int\\1_t" nil)
123
124#ifndef MIN
125 #define MIN(a,b) (((a)>(b))?(b):(a))
126#endif
127
128/*
129 * 2) Version info and checking
130 */
131
132#define RSTF_MAGIC "RST Header"
133#define RSTF_MAJOR_VERSION 2
134#define RSTF_MINOR_VERSION 13
135
136#define RSTF_VERSION_STR "2.13"
137
138 // Mandatory version checking info:
139 // See vercheck.h for return codes:
140 // 0 = version match
141 // 2 = semi compatible versions
142 // 4 = version mismatch
143int rstf_version_check_fn (const char* compile_time_version);
144
145 // Convenience macro for version checking
146#define RSTF_CHECK_VERSION() rstf_version_check_fn(RSTF_VERSION_STR)
147
148 // Do a compile-time vs run-time check on a record from a trace
149#define RSTF_CHECK_TRACEVER(rstheader_ptr) \
150 rstf_checkheader(RSTF_VERSION_STR, rstheader_ptr)
151
152static const char* rstf_version_str = "\n\
153 2.13 07/25/2005 [VP] Added TRAPPED_INSTR_T record type\n\
154 2.12 09/29/2004 [VP] extended cpuid fields to 10 bits; added accessor funcs\n\
155 2.10 09/17/2003 Merged in rfs.h file, which defines record for RFS traces\n\
156 2.09 08/28/2003 defined is_data one bit field in tsb_access record\n\
157 2.08 06/16/2003 define tsb_access record\n\
158 2.07 10/18/2002 define snoopT record\n\
159 2.06 03/XX/2002 regvalT:tpc is array; clean up comments for MM (trap::pstate, trapexit::tpc, tlb::line_idx)\n\
160 2.05 02/07/2002 augment STATUS_T w/ more analyzer-commands\n\
161 2.05 10/19/2001 augment STATUS_T w/ analyzer-commands, e.g. for MPCachesim\n\
162 2.05 10/04/2001 add bustrace::tdiff, renamed CONTEXT_T to PREG_T, add rstf_deprecated.h, expand hwinfo\n\
163 2.04 8/16/2001 revisions to bus trace spec\n\
164 2.03 8/06/2001 compile-vs-runtime version checking, openRST() supports rstzip\n\
165 2.02 7/20/2001 revise memval64/128 recs, add bus trace record type\n\
166 2.01 6/20/2001 add recs memval64 and memval128 records \n\
167 2.00 6/19/2001 rev 1.10 to 2.00 (no other changes)\n\
168 1.10 5/23/2001 cleanup openRST(), closeRST\n\
169 1.10 4/26/2001 add cpuid to INSTR_T +TRAP_T, add TRACEINFO_T,\n\
170 deprecate ASI_T, modified REGVAL_T \n\
171 1.9 4/20/2001 In CONTEXT_T: add cpuid, rename 'asi' to 'asiReg'\n\
172 1.8 3/27/2001 unixcommand(), rstf_snprintf(), stdized rstf_headerT,magic\n\
173 1.7 3/26/2001 Add RECNUM_T for rst-snapper\n\
174 1.6 3/15/2001 Add support for MP (cpuid to PAVADIFF, cpuid/tlbnum TLB)\n\
175 1.5 9/18/2000 Fixed Shade V6 record types (thanks Kelvin)\n\
176 1.4 9/9/2000 Added icontext and dcontext to PAVADIFF_T rec\n\
177 1.4 9/?/2000 Added major, minor numbers to HEADER_T rec\n\
178 1.3 8/25/2000 Added PATCH_T type.\n\
179 1.2 8/22/2000 Added STATUS_T type.\n\
180";
181
182/* The rtypes in RST */
183enum {
184 // values for the rtype field in the following traces.
185 // we start at 3 not 0, to catch the common uninitialized case.
186
187 // enum::rtypes Do not remove THIS comment, c2java.pl needs this
188 RST_ZERO_T = 0, // should not see this
189 RST_ONE_T = 1, // reserved, not used 5/2000.
190 RSTHEADER_T = 2, // [REQUIRED] header type (mostly for marking)
191 INSTR_T = 3, // instruction
192
193 TRACEINFO_T = 4, // [REQUIRED] additional header info
194
195 TLB_T = 5, // change in a TLB line
196 THREAD_T = 6, // thread info
197 TRAP_T = 7, // trap event
198 TRAPEXIT_T = 8, // exit a trap
199 REGVAL_T = 9, // short register dump (1 or 2 regs)
200 TIMESTAMP_T = 11, // current cycle
201 CPU_T = 11, // current CPU
202 PROCESS_T = 12, // change in process, uses Unix PID ... rarely used.
203 DMA_T = 13, // DMA event
204 STRDESC_T = 14, // record is a N-char null-terminated (!) string (N<22)
205 LEFTDELIM_T = 15, // multi-record data must be delimited by
206 RIGHTDELIM_T = 16, // matching LEFTDELIM, RIGHTDELIM records
207 PREG_T = 17, // priv regs (traplev, pstate, asiReg)
208 PHYSADDR_T = 18, // physical addr of PC and EA; prefer PAVADIFF instead
209 PAVADIFF_T = 19, // (PA-VA) values of PC and EA
210 NULLREC_T = 20, // null record, which should be ignored
211 // E.g. change the rtype to NULLREC_T to ignore it
212 STRCONT_T = 21, // string that is *NOT* null-terminated
213 // Multi-record str=>[STRCONT_T...STRCONT_T STRDESC_T]
214 FILEMARKER_T = 22, // indicate where we are in a file
215 RECNUM_T = 22, // set rec num counters (indicates a skip in the trace)
216 STATUS_T = 23, // some sort of status (error, EOF, etc).
217 PATCH_T = 24, // patch instructions (application specific)
218 HWINFO_T = 25, // # cpu's, speed, memory, etc
219 MEMVAL_T = 26, // value from ld/st from/to memory
220 BUSTRACE_T = 27, // data from a bus trace
221 SNOOP_T = 28, // a snoop event
222 TSB_ACCESS_T = 29, // TSB access address during tlb fill
223 RFS_SECTION_HEADER_T = 30, // The section header for RFS trace sub-type.
224 RFS_CW_T = 31, // cache-warming data
225 RFS_BT_T = 32, // branch-predict hardware warming
226 // RFS_RST_T is only used to identify the section type in the
227 // section header no actual rst records of that rtype are actually created
228 RFS_RST_T = 33,
229
230 TRAPPING_INSTR_T = 34,
231
232 LAST_T = 35
233
234};
235
236/*
237 * Multi-record types.
238 * These types values are used in a LEFTDELIM_T record in the WHAT field.
239 */
240enum {
241 STRING_MRT = 257,
242 REGDUMP_MRT = 258,
243 LAST_MRT = 300
244};
245
246 // These are all 32 bit values representing invalid or bad addresses
247 // I'll choose odd values of the form 0x3141592y where y=odd
248#define RSTF_BADADDR_BASE 0x31415900 // fictitious data EA, unknown reason
249#define RSTF_NO_EA 0x31415921 // fictitious data EA, unknown reason
250#define RSTF_NO_PC 0x31415923 // fictitious PC , unknown reason
251#define RSTF_ATRACE_NO_PC 0x31415927 // fictitious PC when no atrace I-rec
252#define RSTF_ATRACE_NO_EA 0x3141592f // fictitious data EA when no atrace D-rec
253
254 // D-addr address is invalid, officially removed in 2.05
255// #define RSTF_NOADDR 0x00314159 // (!!) Deprecated as of v 1.5 (!!)
256
257#define RSTF_IS_BADADDR(addr) \
258 ((((addr) & 01) != 0) && (((addr >> 8) == (RSTF_BADADDR_BASE >> 8))))
259
260//
261// Here are definitions of the individual RST record types.
262// There are some convenience types at the end, to let you view
263// an RST record as an array of 8, 16, 32, or 64 bit values
264// and
265// a union type
266
267typedef struct { /* not done yet */
268 uint8_t rtype; /* value = ZERO_T */
269 uint8_t notused8;
270 uint16_t notused16;
271 uint32_t notused32;
272 uint64_t notused64;
273 uint64_t notused64a;
274} rstf_protoT;
275typedef rstf_protoT rstf_xxxT;
276
277/*
278 * 3) struct definitions
279 */
280
281 // view rsttrace record as an array of bytes, shorts, ints and long longs
282typedef struct {
283 uint8_t arr8[ sizeof(rstf_protoT)/sizeof(uint8_t) ];
284} rstf_uint8T;
285
286typedef struct {
287 uint16_t arr16[ sizeof(rstf_protoT)/sizeof(uint16_t) ];
288} rstf_uint16T;
289
290typedef struct {
291 uint32_t arr32[ sizeof(rstf_protoT)/sizeof(uint32_t) ];
292} rstf_uint32T;
293
294typedef struct {
295 uint64_t arr64[ sizeof(rstf_protoT)/sizeof(uint64_t) ];
296} rstf_uint64T;
297
298 // All RST traces must begin with an rstf_headerT record.
299 //
300 // Initialize via init_rstf_header (rstf_headerT * headerp);
301typedef struct {
302 uint8_t rtype; /* value = RSTHEADER_T */
303 uint8_t majorVer; /* major version Ex: 2 (binary value) */
304 uint8_t minorVer; /* minor version Ex: 23 (binary value) */
305 uint8_t percent; /* must be '%' to be compliant */
306
307 // header_str MUST start with RSTF_MAGIC
308 // Expect it to look like: "RST Header v1.9"
309 char header_str[ sizeof(rstf_uint8T) - sizeof( uint32_t ) ];
310} rstf_headerT;
311
312#define MAX_INSTR_CPUID 48
313typedef struct {
314 uint8_t rtype; /* value = INSTR_T */
315 unsigned notused : 1; /* not used */
316 unsigned ea_valid : 1; /* ea_va field is valid, for ld/st only */
317 unsigned tr : 1; /* trap occured 1=yes */
318 unsigned hpriv : 1; /* hpriv: hpstate.hpriv==1. It is recommended */
319 /* that pr be set to 0 when hpriv==1 */
320 unsigned pr : 1; /* priviledged or user 1=priv */
321 unsigned bt : 1; /* br/trap taken, cond-move/st done */
322 unsigned an : 1; /* 1=annulled (instr was not executed) */
323 unsigned reservedCompress : 1; /* was used by rstzipv2 compressor */
324
325 unsigned cpuid : 6; /* do not access the cpuid field directly. Instead, use the
326 set/get_cpuid functions defined below */
327 unsigned cpuid9_6 : 4;
328
329 unsigned notused3 : 6; /* must be zero in this version of RST */
330
331 uint32_t instr; /* instruction word (opcode, src, dest) */
332 uint64_t pc_va; /* VA */
333 uint64_t ea_va; /* VA: Eff addr of ld/st; Eff targ of CTI */
334} rstf_instrT;
335static void rstf_instrT_set_cpuid(rstf_instrT * tr, int cpuid) { tr->cpuid = cpuid & 0x3f; tr->cpuid9_6 = ((cpuid>>6) & 0xf); }
336static int rstf_instrT_get_cpuid(const rstf_instrT * tr) { return (tr->cpuid9_6<<6)|tr->cpuid; }
337
338typedef struct {
339 uint8_t rtype; /* value = PAVADIFF_T */
340 unsigned ea_valid : 1; /* does ea_pa contain a valid address */
341 unsigned cpuid : 7;
342 unsigned cpuid9_7 : 3;
343 unsigned notused13: 13; /* must be zero */
344 uint16_t icontext; /* I-context used for these diffs */
345 uint16_t dcontext; /* only valid if ea_valid is true (!) */
346 uint64_t pc_pa_va; /* (PA-VA) of PC */
347 uint64_t ea_pa_va; /* (PA-VA) of EA for ld/st (not branches), if ea_valid is true */
348} rstf_pavadiffT;
349static void rstf_pavadiffT_set_cpuid(rstf_pavadiffT * tr, int cpuid) { tr->cpuid = cpuid & 0x7f; tr->cpuid9_7 = (cpuid>>7)&0x7; }
350static int rstf_pavadiffT_get_cpuid(const rstf_pavadiffT * tr) { return (tr->cpuid9_7 << 7)|tr->cpuid; }
351
352 // subtypes for records with a rtype2 field
353enum {
354 RSTT2_ZERO_T = 0, RSTT2_ONE = 1, // reserved
355 RSTT2_NLEVEL_T = 2, //
356 RSTT2_CPUINFO_T = 3,
357 RSTT2_CPUIDINFO_T = 4,
358 RSTT2_LAST_T = 5 //
359};
360
361// Trace information:
362
363// Each RST trace starts with a header record, followed by a series of tracinfo records
364
365// The first traceinfo record should indicate the trace level (incremented with each update)
366
367// The next traceinfo record specifies the number of cpus and the min/max cpuid in the trace
368
369// The following traceinfo records list the cpuids specified in the trace, up to 10 per record
370
371// This is followed by a series of string records containing more detail about the trace
372
373
374
375 // Initialize these records with init_rstf_traceinfo_level().
376 //
377 // Each program that generates/processes/modifies the trace is a level.
378 // Level 0 = program that generated the trace
379 // Level 1 = first "filter" run on the trace that modifies the trace.
380 // To be compliant w/ RST v2.06, the second record in the trace
381 // must be a traceinfo_levelT.
382 // Thus a filter can read the second record, bump the level
383 // and rewrite the modified record
384typedef struct { /* not done yet */
385 uint8_t rtype; /* value = TRACEINFO_T */
386 uint8_t rtype2; /* RSTT2_NLEVEL_T */
387 uint16_t level; /* number of levels, must be >= 1 */
388 uint32_t val32;
389 uint64_t time64; /* value returned by time(2) */
390 uint64_t notused64a;
391} rstf_traceinfo_levelT;
392
393typedef struct {
394 uint8_t rtype; /* value=TRACEINFO_T */
395 uint8_t rtype2; /* value = RSTT2_CPUINFO_T */
396 int16_t numcpus; /* number of cpus in trace */
397 int16_t min_cpu_id;
398 int16_t max_cpu_id;
399 int64_t reserved1; /* must be zero in this version */
400 int64_t reserved2; /* must be zero in this version */
401} rstf_cpuinfoT;
402
403/* The cpuidinfo records list the cpuids that occur in the trace.
404 * It is needed because cpuids are not necessarily 0..ncpus-1.
405 * More than one cpuidinfo record can appear following a cpuinfo record,
406 * each contains up to 10 cpuids that appear in the trace.
407 * For example, there will be 3 cpuidinfo records for ncpus=24.
408 * Unused cpuid's must be set to 0
409 */
410
411typedef struct {
412 uint8_t rtype; /* value=TRACEINFO_T */
413 uint8_t rtype2; /* value=RSTT2_CPUIDINFO_T */
414 uint16_t reserved1; /* must be zero in this version */
415 uint16_t cpuids[10]; /* unused fields must be zero */
416} rstf_cpuidinfoT;
417
418 // placemarker, as will split off more variants of
419typedef struct { /* not done yet */
420 uint8_t rtype; /* value = TRACEINFO_T */
421 uint8_t rtype2; /* subtype: RSTT2_NLEVEL_T */
422 uint16_t val16;
423 uint32_t val32;
424 uint64_t val64;
425 uint64_t val64a;
426} rstf_traceinfoT;
427
428
429
430typedef struct {
431 uint8_t rtype; /* value = TLB_T */
432 unsigned demap : 1; /* 0 = add/replace entry ; 1=invalidate */
433 unsigned tlb_type : 1; /* 0 = INSTR, 1 = DATA */
434 unsigned notused : 6; /* not used */
435
436 // Each TLB implementor can number the lines in the TLB arbitrarily
437 // For direct-mapped TLBs, the line index is obvious
438 // For a K-way TLB, we recommend having idx={0,1,..,K-1}=first set
439 uint16_t tlb_index; /* TLB line index, specific to each TLB impl */
440
441 unsigned tlb_no : 2 ; /* which I or D TLB ? (eg. Ch+ has 3 D TLBS) */
442 unsigned cpuid : 6 ; /* changed in v1.6 */
443 unsigned cpuid9_6 : 4;
444 unsigned unused : 4 ; /* */
445
446 uint16_t unused16; /* */
447
448 // The blaze RSTracer collects the following information
449 // tte_tag[63:13] = VA[63:13] tte_tag[12:0] = context
450 // (!) This format is different from that used in the US-I hardware
451 uint64_t tte_tag; /* tag for a TTE */
452
453 // See the struct rstf_tte_dataT at the end of this file
454 // for an example of how the tte_data might be organized.
455 // rstf_tte_dataT * xp = (rst_tte_data_T *) & tlbp->tte_data;
456 uint64_t tte_data; /* data for a TTE */
457} rstf_tlbT;
458static void rstf_tlbT_set_cpuid(rstf_tlbT * tr, int cpuid) { tr->cpuid = cpuid & 0x3f; tr->cpuid9_6 = (cpuid>>6)&0xf; }
459static int rstf_tlbT_get_cpuid(const rstf_tlbT * tr) { return (tr->cpuid9_6<<6)|tr->cpuid; }
460
461typedef struct { /* not done yet */
462 uint8_t rtype; /* value = THREAD_T */
463 uint8_t notused8;
464 uint16_t icontext; /* I-context */
465 uint32_t notused32;
466 uint64_t tid; /* Thread ID or %g7=ptr to OS thread */
467 uint64_t notused64;
468} rstf_threadT;
469
470typedef struct {
471 uint8_t rtype; /* value = PROCESS_T */
472 uint8_t notused8;
473 uint16_t notused16;
474 uint32_t notused32;
475
476 uint32_t oldpid; /* previous process id 0=no info */
477 uint32_t newpid; /* current process id 0=no info */
478
479 uint32_t oldcontext;
480 uint32_t newcontext;
481} rstf_processT;
482
483typedef struct {
484 uint8_t rtype; /* value = PREG_T */
485 uint8_t asiReg; /* ASI register */
486 uint16_t unused_lastcontext; /* DEPRECATED */
487
488 uint8_t traplevel;
489 uint8_t traptype; /* traptype[traplevel] register */
490 uint16_t pstate; /* pstate */
491
492 uint8_t cpuid; /* cpu 0, 1, 2, ... */
493 uint8_t cpuid9_8 : 2;
494 uint8_t notused4 : 6; /* */
495 uint16_t notused16; /* */
496 uint32_t notused32; /* */
497
498 // DO NOT USE THESE FOR GETTING THE CURRENT CONTEXT
499 // Use the PAVADIFF_T icontext and dcontext, instead
500 // These are MMU reg values, which may or may not be used by the instr
501 uint16_t primA; /* primary IMMU context, must be equal to primD */
502 uint16_t secA; /* secondary IMMU context, not used */
503 uint16_t primD; /* primary DMMU context register */
504 uint16_t secD; /* secondary DMMU context register */
505} rstf_pregT;
506static void rstf_pregT_set_cpuid(rstf_pregT * tr, int cpuid) { tr->cpuid = cpuid & 0xff; tr->cpuid9_8 = (cpuid>>8) & 3; }
507static int rstf_pregT_get_cpuid(const rstf_pregT * tr) { return (tr->cpuid9_8<<8)|tr->cpuid; }
508
509typedef struct {
510 uint8_t rtype; /* value = TRAP_T */
511 unsigned is_async : 1 ; /* asynchronous trap ? */
512 unsigned unused : 3 ; /* unused */
513 unsigned tl : 4 ; /* trap level at the time trap occurred */
514
515 unsigned cpuid : 6 ; /* cpu id */
516 unsigned ttype : 10; /* trap type for V9, only 9 bits matter */
517
518 uint16_t pstate; /* Pstate register in the trap */
519 uint16_t cpuid9_6 : 4;
520
521 uint16_t syscall : 12; /* If a system call, the syscall # */
522
523 uint64_t pc; /* PC before the trap (= post-trap TPC[TL]) */
524 uint64_t npc; /* NPC before trap (= post-trap TNPC[TL]) */
525} rstf_trapT;
526static void rstf_trapT_set_cpuid(rstf_trapT * tr, int cpuid) { tr->cpuid = cpuid & 0x3f; tr->cpuid9_6 = (cpuid>>6) & 0xf; }
527static int rstf_trapT_get_cpuid(const rstf_trapT * tr) { return (tr->cpuid9_6 << 6) | tr->cpuid; }
528
529typedef struct {
530 uint8_t rtype; /* value = TRAPEXIT_T */
531 uint8_t tl; /* trap level , after done/retry */
532 unsigned cpuid : 6 ; /* 10-bit cpu id */
533 unsigned cpuid9_6 : 4;
534 unsigned notused10 : 6;
535 uint32_t tstate; /* bottom 32 bits of tstate */
536
537 uint64_t unused64; /* used to be pc */
538 uint64_t unused64b; /* used to be npc */
539} rstf_trapexitT;
540static void rstf_trapexitT_set_cpuid(rstf_trapexitT * tr, int cpuid) { tr->cpuid = cpuid & 0x3f; tr->cpuid9_6 = (cpuid>>6) & 0xf; }
541static int rstf_trapexitT_get_cpuid(const rstf_trapexitT * tr) { return (tr->cpuid9_6 << 6) | tr->cpuid; }
542
543
544typedef struct {
545 uint8_t rtype; /* value = CPU_T */
546 uint8_t notused8;
547 uint16_t notused16;
548 uint16_t notused16b;
549 uint16_t cpu; /* CPU ID = 0, 1, etc */
550 uint64_t notused64;
551 uint64_t timestamp;
552} rstf_cpuT;
553
554typedef struct {
555 uint8_t rtype; /* value = DMA_T */
556 unsigned unused : 7; /* unused */
557 unsigned iswrite : 1; /* 1=write to memory, 0=read from memory */
558 uint16_t notused16;
559 uint32_t nbytes; /* # of bytes transfered in the DMA */
560 uint64_t start_pa; /* starting address for the DMA */
561 uint64_t notused64;
562} rstf_dmaT;
563
564typedef struct {
565 uint8_t rtype; /* value = TSB_ACCESS_T */
566 unsigned unused : 7;
567 unsigned isdata : 1; /* 1=data access, 0=instruction access */
568 uint16_t unused2 : 6;
569 uint16_t cpuid : 10; /* CPU ID = 0, 1, etc */
570 uint32_t notused32;
571 uint64_t pa; /* physical address of TSB access */
572 uint64_t va; /* virtual address of TSB access */
573} rstf_tsb_accessT;
574static void rstf_tsb_accessT_set_cpuid(rstf_tsb_accessT * tr, int cpuid) { tr->cpuid = cpuid; }
575static int rstf_tsb_accessT_get_cpuid(const rstf_tsb_accessT * tr) { return tr->cpuid; }
576
577
578/* A rstf_trapping_instrT record is output before a synchronous trap record to provide
579 * additional information about the cause of the trap. It is also output before an async trap
580 * with information about the instruction that would have executed if the trap hadn't been taken
581 *
582 * The trap record will typically be followed by an rstf_instrT record with the tr flag set.
583 */
584typedef struct {
585 uint8_t rtype; /* value = TRAPPING_INSTR_T */
586
587 /* values of hpstate.hpriv and pstate.priv when the trapping instr was initiated */
588 uint8_t hpriv: 1;
589 uint8_t priv : 1;
590
591 uint8_t iftrap : 1; // if true, only cpuid and ea_va are valid
592
593 uint8_t ea_va_valid : 1; // valid only if iftrap == 0
594 uint8_t ea_pa_valid : 1; // do not translate ea_va unless true
595 uint8_t unused3: 3;
596
597 uint16_t cpuid: 10;
598 uint16_t unused6: 6;
599
600 uint32_t instr; // valid only if iftrap == 0
601
602 uint64_t pc_va; // always valid
603
604 uint64_t ea_va; // only if ea_va_valid
605
606} rstf_trapping_instrT;
607static void rstf_trapping_instrT_set_cpuid(rstf_trapping_instrT * tr, int cpuid) { tr->cpuid = cpuid; }
608static int rstf_trapping_instrT_get_cpuid(const rstf_trapping_instrT * tr) { return tr->cpuid; }
609
610 //
611 // RST Bus trace format philosophy.
612 // (i) convert a minimal set of "common" data into a standard form
613 // which is sufficient for any generic-bus-trace analyzer
614 // (ii) to leave the bus-trace implementation specific data bits as-is,
615 // in a bus-trace specific set of 64-96 bits.
616 //
617 // There are major differences between different bus trace implementations
618 // (system, bus, logic analyzer) even only looking at the
619 // HPLA/Firetruck versus Tektronix/E10K traces.
620 // In particular, the transaction types alone are different.
621 // And as we collect more bus traces from different/new setups, this
622 // problem will only get worse.
623 //
624 // See rstf_bustrace.h for bus-trace implementation specific details.
625 // To access bus trace implementations specific fields use:
626 // #include <rstf/rstf_bustrace.h>
627 //
628 // Or, if you just need common fields (e.g. a cache simulator), use
629 // #include <rstf/rstf.h>
630 //
631 // Again, The bustrace record (here) in rstf.h only describes fields
632 // common to all bus trace records. These fields are those suitable
633 // for cache simulators and should be values present in all bus
634 // traces.
635
636
637#ifndef _rstf_bustrace_h
638
639enum {
640 // TX types must know so a cache simulator can do the right thing
641 // 07/26/2001
642
643 RST_BTTX_BADVAL = 0x0, // Make common unitialized value an error
644
645 // UPA
646 RST_BTTX_RTS = 0x10, // Read to Share
647 RST_BTTX_RTSA = 1, // Read to Share Always (I access)
648 RST_BTTX_RTO = 2, // Read to Own
649 RST_BTTX_RTD = 3, // Read to Discard
650 RST_BTTX_CGSS = 4, // CopybackGotoSState
651 RST_BTTX_NCR = 5, // NonCachedRead
652 RST_BTTX_NCBR = 6, // NonCachedBlockRead
653 RST_BTTX_NCBW = 7, // NonCachedBlockWrite
654 RST_BTTX_WB = 8, // Writeback
655 RST_BTTX_WI = 9, // WriteInvalidate
656 RST_BTTX_INV = 10, // Invalidate
657 RST_BTTX_CB = 11, // Copyback
658 RST_BTTX_CBI = 12, // CopybackInvalidate
659 RST_BTTX_CBD = 13, // CopybackToDiscard
660 RST_BTTX_NCW = 14, // NonCachedWrite
661 RST_BTTX_INT = 15, // Interrupt
662
663 // Additional Tx types in the firetruck bus
664 RST_BTTX_IDLE = 0x11, // Idle
665 RST_BTTX_ADMIN = 0x12, // Admin
666 RST_BTTX_RTSF = 0x13, // ReadToShareFork
667 RST_BTTX_RS = 0x14, // ReadStream
668
669 RST_BTTX_RSTADMIN = 0x18, // an administrative record (reserved)
670 RST_BTTX_LAST = 0x18 // any value greater than this is an error
671};
672
673 // In rstf_bustrace.h, u_btimpl64_t is defined as a union of structs
674 // but if we did not see rstf_bustrace.h, define it as an long long.
675 //
676typedef uint64_t u_btimpl64_t;
677
678#endif /* _rstf_bustrace_h */
679
680 // The common bus trace info if the user just includes <rstf/rstf.h>
681typedef struct {
682 uint8_t rtype; /* value = BUSTRACE_T */
683
684 unsigned dirtyvictim : 1; // this access create dirty victim?
685 unsigned shared : 1; // FT: anybody claim share this line? E10K:N/A
686 unsigned owned : 1; // FT: owned line asserted E10K: N/A
687 unsigned memcancel : 1; // E10=abort bit, FT=data cancel
688 unsigned bt_type : 4; /* type of bus trace, see rstf_bustrace.h */
689
690 unsigned txType : 6; // Transaction type
691 unsigned agentid : 10; // cpu/board/agent/module ID
692
693 unsigned tdiff : 1 ; // 1=timestamp is differental from prev rec,
694 unsigned nsScale : 1 ; // 1=timestamp is in nS; 0=timestamp in 100nS
695 unsigned timestamp : 20; // absolute=unsigned, time delta=signed
696
697
698 u_btimpl64_t btimpl64; // specific to a given bustrace
699 uint64_t addr_pa; // PA, bottom 6 bits may be unused
700} rstf_bustraceT;
701
702
703enum {
704 // ================
705 // register types
706 //
707 RSTREG_INT_RT = 1,
708 RSTREG_FLOAT_RT = 2,
709 RSTREG_PRIV_RT = 3,
710 RSTREG_OTHER_RT = 4, //
711 RSTREG_UNUSED_RT = 5, // register value bits are unused
712
713 // regtype[i]=RSTREG_CC_RT => regid[i] field holds icc+xcc values
714 // regid[i] bits 0:3 hold icc regid[i] bits 4:7 hold xcc
715 // XCC: n z v c ICC: n z v c
716 // Bits 7 6 5 4 3 2 1 0
717 RSTREG_CC_RT = 6,
718
719 // regtype[i]=RSTREG_CC_RT => regid[i] field holds icc+xcc values
720 // regid[i] bits 0:3 hold icc regid[i] bits 4:7 hold xcc
721 // XCC: n z v c ICC: n z v c
722 // Bits 7 6 5 4 3 2 1 0
723 RSTREG_FCC_RT = 7,
724
725 // regtype[i]=RSTREG_WININT_RT => regid[i] field holds winptr+regnum
726 // regid[i] bits 7:5 holds window pointer (0-8), for integer regs
727 // or global type (RSTREG_USER_GLOBAL thru
728 // RSTREG_ALTERNATE_GLOBAL) and global level
729 // for Millennium-type architectures
730 // Examples:
731 // %l5 of window 3 = 0x75 = 8b'011-10101 (l5 = 21 = 0x15)
732 // %l3 of window 7 = 0xf3 = 8b'111-10011 (l3 = 19 = 0x13)
733 // %ag3 = 0x63 = 8b'011-00011
734 // Transformation Functions:
735 // regid = (wp << 5) + regnum;
736 // wp = (regid >> 5); regnum = (regid & 0x1f);
737 RSTREG_WININT_RT = 8,
738
739 RSTREG_MMU_RT = 9, // MMU specific
740
741 RSTREG_LAST_RT = 10,
742
743 // ================
744 // register ID's
745 //
746
747 // int registers, %g0=0,%g7=7,%o0=8,%o7=15,%l0=16,%l7=23,%i0=24,%i7=31
748 RSTREG_iGLOBAL_R = 0,
749 RSTREG_iOUT_R = 8,
750 RSTREG_iLOCAL_R = 16,
751 RSTREG_iIN_R = 24,
752 RSTREG_iTHREAD_R = RSTREG_iGLOBAL_R+7, // %g7 = & kernel thread struct
753 RSTREG_iSP_R = RSTREG_iOUT_R+6,
754 RSTREG_iFP_R = RSTREG_iIN_R+6,
755
756 // float registers, SingleP=0..31, DoubleP=32..63, QuadP=64..95
757 // - A quad float occupies regval[0..1] and must be regtype[0].
758 // And, regtype[1] must be RSTREG_CC_RT or RSTREG_UNUSED_RT.
759
760 // priv registers (same encoding as in the RDPR instr)
761 // used when regtype=RSTREG_PRIV_RT
762 RSTREG_TPC_R = 0,
763 RSTREG_TNPC_R = 1,
764 RSTREG_TSTATE_R = 2,
765 RSTREG_TT_R = 3,
766 RSTREG_TICK_R = 4,
767 RSTREG_TBA_R = 5,
768 RSTREG_PSTATE_R = 6,
769 RSTREG_TL_R = 7,
770 RSTREG_PIL_R = 8,
771 RSTREG_CWP_R = 9,
772 RSTREG_CANSAVE_R = 10,
773 RSTREG_CANRESTORE_R = 11,
774 RSTREG_CLEANWIN_R = 12,
775 RSTREG_OTHERWIN_R = 13,
776 RSTREG_WSTATE_R = 14,
777 RSTREG_FQ_R = 15,
778 RSTREG_VERSION_R = 31,
779
780 // There is an instance of the following registers for each trap level
781 // We allocate enough space for 8 trap levels (as of 2001, MAXTL=4)
782 // Thus for TPC[ TL=3 ], use regid=RSTREG_TPC_RBASE+3
783 RSTREG_TPC_RBASE = 64,
784 RSTREG_TNPC_RBASE = 72,
785 RSTREG_TSTATE_RBASE = 80,
786 RSTREG_TT_RBASE = 88,
787
788 // other registers (same encoding as in the RDSTATE instr)
789 // used when regtype=RSTREG_OTHER_RT
790 RSTREG_Y_R = 0,
791 RSTREG_CC_R = 2,
792 RSTREG_ASI_R = 3,
793 // RSTREG_TICK_R = 4, (duplicated from above)
794 RSTREG_PC_R = 5,
795 RSTREG_FPRS_R = 6,
796 RSTREG_ASR_R = 7, // not used
797 RSTREG_OLDFSR_R = 8, // not used
798 RSTREG_ASR_PCR_R = 16,
799 RSTREG_ASR_PIC_R = 17,
800 RSTREG_ASR_IEU_CTRL_R = 18,
801 RSTREG_ASR_GSR_R = 19,
802 RSTREG_ASR_INTR_SET_R = 20,
803 RSTREG_ASR_INTR_CLR_R = 21,
804 RSTREG_ASR_INTR_WRITE_R = 22,
805 RSTREG_ASR_TICK_CMPR_R = 23,
806 RSTREG_ASR_STICK_REG_R = 24,
807 RSTREG_ASR_STICK_CMPR_R = 25,
808 RSTREG_ASR_STICK_THR_STR_R = 26,
809 RSTREG_ASR_NPC_R = 32,
810 RSTREG_ASR_FSR_R = 33,
811
812 // global types (used for global registers in regtype=RSTREG_WININT_RT)
813 RSTREG_USER_GLOBAL = 0, // %g0-g7
814 RSTREG_INTERRUPT_GLOBAL = 1, // %ig0-ig7
815 RSTREG_MMU_GLOBAL = 2, // %mg0-mg7
816 RSTREG_ALTERNATE_GLOBAL = 3, // %ag0-ag7
817
818 // mmu reg types. use encodings from ASI 0x58
819 RSTREG_MMU_PCONTEXT=0x8,
820 RSTREG_MMU_SCONTEXT=0x10,
821
822 RSTREG_LAST_MARKER = 15
823};
824
825/*
826 * This structure contains one or two register values
827 */
828typedef struct {
829 uint8_t rtype; /* value = REGVAL_T */
830 unsigned postInstr : 1; /* 0=values before instr, 1=values AFTER */
831 unsigned cpuid : 7; /* CPU */
832
833 uint8_t regtype[2]; /* type: Ex: regtype[0]=RSTREG_INT_RT */
834 uint8_t regid[2]; /* register Ex regid[0]=14 (%o6=%sp) */
835
836 uint16_t cpuid9_7 : 3;
837 uint16_t notused13 : 13;
838
839 uint64_t reg64[2]; /* reg64[i] described by regtype[i]/regid[i]*/
840} rstf_regvalT;
841static void rstf_regvalT_set_cpuid(rstf_regvalT * tr, int cpuid) { tr->cpuid = cpuid & 0x7f; tr->cpuid9_7 = (cpuid>>7) & 0x7; }
842static int rstf_regvalT_get_cpuid(const rstf_regvalT * tr) { return (tr->cpuid9_7 << 7) | tr->cpuid; }
843
844// A memory value record can be either a memval128T or memval64T
845// memval128T = 128 bits of aligned data.
846// Only give bits 4:43 of address. Must sign extend to get full addr
847// if isContRec==1, ignore addr bits and use address from previous rec
848// This is done because the record only has enough space for 43 bits
849// of address, so a 64 bit memval that precedes the 128 bit memval
850// provides the address.
851//
852typedef struct {
853 uint8_t rtype; /* value = MEMVAL_T */
854 unsigned ismemval128 : 1; // type of memval? 1=memval128T 0=memval64T
855 unsigned addrisVA : 1; // What type of addr? 1=VA 0=PA
856 unsigned isContRec : 1; // continuation? applies only to memval128T
857 unsigned zero3: 3; // should be zero
858 unsigned cpuid9_8 : 2;
859 unsigned cpuid : 8 ; // cpu id
860
861 // contain 40 bits <04:43> which must be sign extended to get the full addr
862 uint8_t addr36_43; // shift this value 36 bits to the right
863 uint32_t addr04_35; // addr = (long long) (addr04_35 << 4);
864 uint64_t val[2]; // must be ALIGNED 128 bits=16 bytes data
865} rstf_memval128T;
866static void rstf_memval128T_set_cpuid(rstf_memval128T * tr, int cpuid) { tr->cpuid = cpuid & 0xff; tr->cpuid9_8 = (cpuid>>8) & 3; }
867static int rstf_memval128T_get_cpuid(const rstf_memval128T * tr) { return (tr->cpuid9_8<<8)|tr->cpuid; }
868
869typedef struct {
870 uint8_t rtype; /* value = MEMVAL_T */
871 unsigned ismemval128 : 1; // type of memval? 1=memval128T 0=memval64T
872 unsigned addrisVA : 1; // What type of addr? 1=VA 0=PA
873 unsigned isContRec : 1; // this bit does not apply to rstf_memval64T
874 unsigned zero3: 3; // should be zero
875 unsigned cpuid9_8 : 2;
876 unsigned cpuid : 8 ; // cpu id
877 unsigned unused4 : 4 ; //
878 unsigned size : 4 ; // # of valid bytes in val (1-8)
879
880 uint32_t notused32; //
881 uint64_t addr; // 64 bit address
882 uint64_t val; // 64 bits = 8 bytes of data
883} rstf_memval64T;
884// cpuid accessor fns same as memval128
885static void rstf_memval64T_set_cpuid(rstf_memval64T * tr, int cpuid) { tr->cpuid = cpuid & 0xff; tr->cpuid9_8 = (cpuid>>8) & 3; }
886static int rstf_memval64T_get_cpuid(const rstf_memval64T * tr) { return (tr->cpuid9_8<<8)|tr->cpuid; }
887
888typedef struct {
889 uint8_t rtype; /* value = LEFTDELIM_T, RIGHTDELIM_T */
890 uint8_t id; /* left and right delims must match */
891 uint16_t what; /* type of data */
892 uint32_t length; /* length of data (bytes) in following recs */
893 uint64_t notused64;
894 uint64_t notused64a;
895} rstf_delimT;
896
897 // PHYSADDR_T: this record type is rarely used as of 7/2001
898typedef struct {
899 uint8_t rtype; /* value = PHYSADDR_T */
900 unsigned ea_valid : 1; /* does ea_pa contain a valid address */
901 unsigned cpuid : 7;
902 uint16_t cpuid9_7 : 3;
903 uint16_t notused13 : 13;
904 uint32_t notused32;
905 uint64_t pc_pa;
906 uint64_t ea_pa;
907} rstf_physaddrT;
908static void rstf_physaddrT_set_cpuid(rstf_physaddrT * tr, int cpuid) { tr->cpuid = cpuid & 0x7f; tr->cpuid9_7 = (cpuid>>7) & 0x7; }
909static int rstf_physaddrT_get_cpuid(const rstf_physaddrT * tr) { return (tr->cpuid9_7 << 7) | tr->cpuid; }
910
911 /* tell record #, before/after processing level LEV */
912typedef struct {
913 uint8_t rtype; /* value = FILEMARKER_T == RECNUM_T */
914 unsigned recNum : 1 ; /* 0 = filemark, 1 = recnum */
915 unsigned level : 7 ; /* LEV=level of the processing, 0=orig data */
916 uint8_t recType; /* rec type (e.g. INSTR_T) to set on count */
917 uint8_t cpuID; /* 0 = first CPU */
918 uint32_t cpuid9_8 : 2;
919 uint32_t notused30 : 30;
920 uint64_t incount; /* input record # */
921 uint64_t outcount; /* output record # (not used in recnum_T) */
922} rstf_filemarkerT;
923static void rstf_filemarkerT_set_cpuid(rstf_filemarkerT * tr, int cpuid) { tr->cpuID = cpuid & 0xff; tr->cpuid9_8 = (cpuid>>8) & 3; }
924static int rstf_filemarkerT_get_cpuid(const rstf_filemarkerT * tr) { return (tr->cpuid9_8<<8)|tr->cpuID; }
925
926
927// reset record number counter.
928typedef struct {
929 uint8_t rtype; /* value = FILEMARKER_T == RECNUM_T */
930 unsigned recNum : 1 ; /* 0 = filemark, 1 = recnum */
931 unsigned level : 7 ; /* not used */
932 uint8_t recType; /* type of record (e.g. INSTR_T) to set on count) */
933 uint8_t cpuID; /* 0 = first CPU */
934 uint32_t cpuid9_8 : 2;
935 uint32_t notused30 : 30;
936 uint64_t incount; /* new record # */
937 uint64_t notused64; /* not used */
938} rstf_recnumT;
939// accessor funcs same as filemarkerT
940
941typedef struct {
942 uint8_t rtype; /* value = STRDESC_T, STRCONT_T */
943 char string[23]; /* null terminated if STRDESC, no if STRCONT */
944} rstf_stringT;
945
946 // values in a STATUS_T record
947enum {
948 // values for the status field a STATUS_T record
949 // we start at 2 not 0, to catch the common uninitialized case.
950 RST_EOF = 2,
951 RST_ERROR = 3,
952 RST_ANALYZER_CMD = 4,
953 // let me know what else you want...
954
955 // analyzer specs
956 // Any/all analyzers are free to ignore these records
957 RST_AN_ALL_ANALYZERS = 3, /* request for all analyzers */
958 RST_AN_CACHESIM = 4, /* all cache simulators */
959 RST_AN_MPCACHESIM = 5,
960 RST_AN_CYCLESIM = 8,
961 RST_AN_SIM_HONEY = 9,
962 RST_AN_SIM_BB = 10,
963 RST_AN_AZTECS = 11,
964 RST_AN_MAYAS = 12,
965
966 // command
967 RST_ACMD_RESET_COUNTERS = 3,
968 RST_ACMD_DUMP_COUNTERS = 4,
969
970 RST_STATUS_END = 255
971};
972
973typedef struct {
974 uint8_t rtype; /* value = STATUS_T */
975 uint8_t status; /* enumerated value (e.g. RST_EOF) */
976 uint8_t analzyer; /* analyzer for ANALYZER_CMD */
977 uint8_t command; /* command for ANALYZER_CMD */
978 uint32_t notused32;
979 uint64_t notused64;
980 uint64_t notused64a;
981} rstf_statusT;
982
983typedef struct {
984 uint8_t rtype; /* value = PATCH_T */
985
986 unsigned unused : 7; /* */
987 unsigned isBegin : 1; /* 1=begin of patch, 0=end of patch */
988
989 uint8_t rewindrecs; /* # recs to rewind before applying patch */
990 uint8_t id; /* id should match begin/end pairs */
991
992 uint16_t length; /* # recs in patch, ignore beg/end patchT */
993 /* we count those beg/end of nested patches */
994
995 uint16_t notused32;
996
997 char descr[16]; /* may not be null-terminated */
998} rstf_patchT;
999
1000 // Categories and infotypes for HWINFO_T
1001 // If there are multiple values (e.g. sizes of caches)
1002 // use the INDEX field to differentiate.
1003 // NUMENT indicates how many vals there
1004enum {
1005 HWCAT_TRSRC = 2, // trace source
1006 HWINFO_RSTBLAZE = 2, //
1007 HWINFO_ATRACE = 3, //
1008 HWINFO_SHADE5 = 5, //
1009 HWINFO_SHADE6 = 6, //
1010 HWINFO_SIMICS = 7, //
1011
1012 HWCAT_SIMHW = 6, // a simulated hardware value
1013 HWCAT_HOSTHW = 7, // real machine hardware value
1014
1015 HWINFO_CPUTYPE = 2, // 1 = US-1, 3=US-3, etc
1016 HWINFO_NUMPROC = 3, //
1017 HWINFO_MEMSIZE = 4, // bytes
1018 HWINFO_CPUFREQ = 5, // Hertz [0]=cpufreq [1]=stick freq
1019 HWINFO_TLBSIZE = 8, // size of index-th TLB, val2=assoc
1020 HWINFO_CACHESPEC = 9, // size
1021 HWINFO_NUMNIC = 10, // number of NICS
1022 HWINFO_IPADDR = 11, // IP address
1023 HWINFO_DISKSIZE = 12, // bytes
1024 HWINFO_DISKDELAY = 14, // cpufreq cycles [0]=read delay [1]=write delay
1025 HWINFO_NREGWIN = 15, // Number of register windows
1026
1027 HWCAT_DUMMY = -1
1028};
1029
1030enum {
1031 SNOOP_RTO = 1,
1032 SNOOP_RTS = 2
1033};
1034
1035enum {
1036 DEVICE_CPU = 1
1037};
1038
1039
1040typedef struct {
1041 uint8_t rtype; /* value = SNOOP_T */
1042 uint8_t snoopreq; /* type of snoop request, values */
1043 uint16_t device_id; /* agent ID initiating the request */
1044 uint32_t size; /* size in bytes of snoop */
1045 uint64_t addr_pa;
1046 uint16_t device_type; /* What type of device */
1047 uint16_t notused16; /* reserved */
1048 uint32_t notused32; /* reserved */
1049} rstf_snoopT;
1050
1051typedef struct {
1052 uint8_t rtype; /* value = HWINFO_T */
1053 unsigned sim : 1;
1054 unsigned unused : 7;
1055 uint8_t category; /* category of info Ex: sim HW value */
1056 uint8_t infotype; /* type of value Ex: CPU freq or mem size */
1057 uint16_t entindex; /* if multiple entries (e.g. cache sizes) */
1058 uint16_t nument; /* total number of entries 0=> only 1 entry */
1059 uint64_t val; /* value */
1060 uint64_t val2;
1061} rstf_hwinfoT;
1062
1063/************************ RFS SUB-TRACE STUFF ***************************/
1064
1065/* Structure of an RST-Format Snap:
1066 *
1067 * ========
1068 * Header:
1069 * ========
1070 * Descr: rstf_stringT record identifying the trace as rfs format
1071 * The string should be the RFS descriptor 23-char string:
1072 * "RFS vX.YY RST-FMT SNAP\0"
1073 * X is rfs_major_version, YY is rfs_minor_version (version of the
1074 * RFS format SPECIFICATION)
1075 * ========
1076 * One or more RFS sections
1077 * ========
1078 *
1079 * An RFS section consists of an RFS section header and section data
1080 * The section header is of type rstf_rfs_section_headerT (defined below)
1081 * The various section data types are also defined below; these may be extended
1082 * if necessary
1083
1084 *
1085 * IMPORTANT: Since it is possible for the record-count for
1086 * the RST section to be unknown,
1087 * there can be only one RST section in a snap, and it MUST be the last section
1088 * FIXME: this constraint can be relaxed at the cost of slowing down
1089 * the compressor/analyzers etc
1090 */
1091
1092static const int rfs_major_version = 1;
1093static const int rfs_minor_version = 0;
1094
1095// all "reserved" fields in rfs structures should be initialized
1096// to 0 for consistency.
1097
1098
1099// a ridiculously large positive 64-bit number
1100static const int64_t rfs_unknown_nrecords = ((~0ull)>>1);
1101
1102
1103typedef struct {
1104 unsigned rtype : 8; // RFS_SECTION_HEADER_T
1105 unsigned section_type : 8; // same as the data rtype (eg RFS_CW_T
1106 // or RFS_BP_T or RFS_RST_T)
1107 unsigned reserved1 : 16;
1108
1109 uint32_t reserved2;
1110
1111 // n_records == rfs_unknown_nrecords indicates unknown record count:
1112 // reader must determine count from the input stream
1113 // This feature is ONLY supported for an RST section,
1114 // of which there can be only one
1115 int64_t n_records; // NOT including section header record.
1116
1117 uint64_t reserved3;
1118
1119 // the reserved fields may be used for a checksum (eg md5sum) in the future
1120} rstf_rfs_section_headerT;
1121
1122
1123
1124typedef struct {
1125 uint8_t rtype; // value = RFS_BT_T
1126 unsigned cpuid : 10;
1127 unsigned taken : 1;
1128 unsigned reserved: 13;
1129 unsigned instr; // instr word
1130 uint64_t pc_va; // branch pc
1131 uint64_t npc_va; // fall-through addr if branch not taken
1132} rstf_bpwarmingT;
1133static void rstf_bpwarmingT_set_cpuid(rstf_bpwarmingT * tr, int cpuid) { tr->cpuid = cpuid; }
1134static int rstf_bpwarmingT_get_cpuid(const rstf_bpwarmingT * tr) { return tr->cpuid; }
1135
1136enum cw_reftype_e {
1137 cw_reftype_NIL = 0,
1138 cw_reftype_I = 1,
1139 cw_reftype_R = 2,
1140 cw_reftype_W = 3,
1141 cw_reftype_PF_D = 4,
1142 cw_reftype_PF_I = 5,
1143 cw_reftype_DMA_R = 6,
1144 cw_reftype_DMA_W = 7,
1145
1146 cw_reftype_MAX
1147};
1148
1149
1150typedef struct {
1151 uint8_t rtype; // value = RFS_CW_T
1152
1153 unsigned cpuid : 10; // must be ZERO for DMA_R and DMA_W reftypes
1154 unsigned reftype : 6;
1155
1156 unsigned reserved1: 8;
1157
1158 union refinfo_u {
1159 uint32_t dma_size;
1160
1161 struct refinfo_s {
1162 unsigned asi : 8; // must be defined for ALL reference types
1163 // except DMA. For DMA, the dma_size field
1164 // overlaps with this struct
1165 unsigned va_valid: 1;
1166 unsigned fcn : 5; // for prefetch refs only. For others,
1167 // consider this as "reserved"
1168 unsigned reserved: 18;
1169 } s;
1170
1171 uint32_t l; // this is just to represent refinfo_s as a 32-bit
1172 // quantity that can be passed to functions
1173
1174 } refinfo;
1175
1176 // va must be ZERO for DMA_R or DMA_W. and if the refinfo.s.va_valid
1177 // bit is clear
1178 uint64_t va;
1179
1180 uint64_t pa;
1181} rstf_cachewarmingT;
1182static void rstf_cachewarmingT_set_cpuid(rstf_cachewarmingT * tr, int cpuid) { tr->cpuid = cpuid; }
1183static int rstf_cachewarmingT_get_cpuid(const rstf_cachewarmingT * tr) { return tr->cpuid; }
1184
1185/******************END OF RFS SUB-TRACE STUFF ***************************/
1186
1187 // my template for use in emacs. Ignore.
1188typedef struct { /* not done yet */
1189 uint8_t rtype; /* value = PROTO_T */
1190 uint8_t notused8;
1191 uint16_t notused16;
1192 uint32_t notused32;
1193 uint64_t notused64;
1194 uint64_t notused64a;
1195} rstf_whatT;
1196
1197typedef union {
1198 rstf_headerT header;
1199 rstf_instrT instr;
1200 rstf_traceinfo_levelT tlevel;
1201 rstf_cpuinfoT cpuinfo;
1202 rstf_cpuidinfoT cpuidinfo;
1203 rstf_tlbT tlb;
1204 rstf_threadT thread;
1205 rstf_pregT preg;
1206 rstf_trapT trap;
1207 rstf_trapexitT trapexit;
1208 rstf_trapping_instrT trapping_instr;
1209 rstf_cpuT cpu;
1210 rstf_dmaT dma;
1211 rstf_delimT delim;
1212 rstf_physaddrT physaddr;
1213 rstf_pavadiffT pavadiff;
1214 rstf_filemarkerT fmarker;
1215 rstf_hwinfoT hwinfo;
1216 rstf_recnumT recnum;
1217 rstf_stringT string;
1218 rstf_statusT status;
1219 rstf_patchT patch;
1220 rstf_regvalT regval;
1221 rstf_memval64T memval64;
1222 rstf_memval128T memval128;
1223 rstf_bustraceT bustrace;
1224 rstf_snoopT snoop;
1225 rstf_tsb_accessT tsb_access;
1226 rstf_rfs_section_headerT rfs_section_header;
1227 rstf_bpwarmingT bpwarming;
1228 rstf_cachewarmingT cachewarming;
1229
1230 // types for fields in the rst record
1231 rstf_protoT proto;
1232 rstf_uint8T arr8;
1233 rstf_uint16T arr16;
1234 rstf_uint32T arr32;
1235 rstf_uint64T arr64;
1236
1237#if defined(RSTF_USE_DEPRECATED)
1238 rstf_contextT context;
1239#endif
1240
1241} rstf_unionT;
1242
1243#define SIZEOF_RSTF (sizeof(rstf_unionT))
1244
1245// ================ 4) Useful functions ================
1246//
1247// Some macros and functions for dealing with rstf
1248//
1249
1250 // Do a compile-time vs run-time check on a record from a trace
1251int rstf_checkheader (const char* compile_time_ver, rstf_headerT *rec);
1252
1253 // Open a RST file for reading.
1254 // If the file is compressed (rstzip/rstzip2), automatically decompress
1255 // We use popen() internally, if filename is a compressed file
1256 // Returns
1257 // null on error and sets errno
1258 //
1259FILE* openRST (const char* filename);
1260void closeRST (FILE* f); // pclose(f); if compressed
1261int isPipeRST (FILE* f); // 1 if f is a pipe, as in from popen().
1262
1263 // initialize a header record with the current RST major/minor number.
1264 // The string
1265int init_rstf_header (rstf_headerT * headerp);
1266
1267 // initialize a header record with the current RST major/minor number.
1268int init_rstf_traceinfo_level (rstf_traceinfo_levelT * ti, int level);
1269
1270 // Initialize a single STR_DESC RST record STRP with the string STR
1271 // takes the last 22 chars if STR will not fully fit.
1272int init_rstf_string (rstf_stringT * strp, const char *str);
1273
1274 // Note: In most cases, rstf_snprintf() is easier to use.
1275 // Initialize upto MAXREC records with the string STR, using
1276 // STRDESC_T and STRCONT_T records. Handles strings of any length.
1277 // Returns the number of RST records used.
1278 // You must allocate the space to which STRP points.
1279 //
1280 // Ex:
1281 // rstf_unionT buff[128];
1282 // int currIdx = 37 ;
1283 // char charbuff [8192];
1284 // sprintf(charbuff, "A long bunch of data %s %d ...", ... );
1285 // rstf_sprintf( &buff[currIdx] , charbuff, 128-37-1 );
1286 //
1287int init_rstf_strbuff (rstf_stringT * strp, const char *str, int maxrec);
1288
1289 // Convenience fns:
1290 // rstf_sprintf():
1291 // initialize a RST record STRP with the sprintf output
1292 // if the resulting string is too long, the last 22 chars are used.
1293 //
1294 // rstf_snprintf()
1295 // initialize upto MAXREC RST records STRP with the sprintf output
1296 // if the resulting string is too long, the last characters are dropped.
1297 // Also, we use an 8K buffer, all chars beyond which are silently dropped.
1298 // Returns the number of RST records actually used.
1299 //
1300 // Ex:
1301 // rstf_unionT buff[...];
1302 // rstf_unionT * currRec = ... ;
1303 // struct passwd * pp = getpwuid( getuid() );
1304 // nr = rstf_sprintf( currRec, "Collected by user %s", pp->pw_name);
1305 // nr = rstf_snprintf( currRec+1, 4, "Some big long string %s", stringval);
1306 //
1307int rstf_sprintf (rstf_stringT * strp, const char* fmt, ...);
1308int rstf_snprintf (rstf_stringT * strp, int maxrec, const char* fmt, ...);
1309
1310 // Given a multi-record string, read it.
1311 // STRP points to the first of NREC consecutive (in an array) RST records.
1312 // These need not all be string, but must know how many recs we can read.
1313 // Returns the string in a static buffer.
1314 // If NRREAD != NULL, we return the number of RST records we skipped over.
1315 // Internally we use a 2048 char buffer.
1316const char* get_rstf_longstr (const rstf_stringT * strp, int nrec, int *nrread);
1317
1318 // 1) Return the result of running command COMMAND
1319 // The result is returned in a static buffer of size at least 4K.
1320 //
1321 // 2) Store the exit status at *EXIT_STATUS, if this addr is non-NULL
1322 // 3) Get at most MAXLINE lines of output from the COMMAND.
1323 //
1324char* unixcommand (const char * command, int MAXLINE, int* exit_status);
1325
1326 // returns a pointer to a statically allocated buffer
1327 // Ex: rstf_btTxtype2str (RST_BTTX_RTSA) ==> "RTSA"
1328const char* rstf_btTxtype2str (int txType);
1329
1330
1331 // the set cpuid function must be called *after* initializing the rtype field
1332 // the get cpuid function returns 0xffff if the cpuid field is not present in
1333 // the record type being queried.
1334static void rstf_set_cpuid(rstf_unionT * rec, int cpuid) {
1335 switch(rec->proto.rtype) {
1336 case INSTR_T:
1337 rstf_instrT_set_cpuid(&rec->instr, cpuid);
1338 break;
1339 case PAVADIFF_T:
1340 rstf_pavadiffT_set_cpuid(&rec->pavadiff, cpuid);
1341 break;
1342 case TLB_T:
1343 rstf_tlbT_set_cpuid(&rec->tlb, cpuid);
1344 break;
1345 case PREG_T:
1346 rstf_pregT_set_cpuid(&rec->preg, cpuid);
1347 break;
1348 case TRAP_T:
1349 rstf_trapT_set_cpuid(&rec->trap, cpuid);
1350 break;
1351 case TRAPEXIT_T:
1352 rstf_trapexitT_set_cpuid(&rec->trapexit, cpuid);
1353 break;
1354 case TSB_ACCESS_T:
1355 rstf_tsb_accessT_set_cpuid(&rec->tsb_access, cpuid);
1356 break;
1357 case TRAPPING_INSTR_T:
1358 rstf_trapping_instrT_set_cpuid(&rec->trapping_instr, cpuid);
1359 break;
1360 case REGVAL_T:
1361 rstf_regvalT_set_cpuid(&rec->regval, cpuid);
1362 break;
1363 case MEMVAL_T:
1364 rstf_memval128T_set_cpuid(&rec->memval128, cpuid);
1365 break;
1366 case PHYSADDR_T:
1367 rstf_physaddrT_set_cpuid(&rec->physaddr, cpuid);
1368 break;
1369 case FILEMARKER_T:
1370 rstf_filemarkerT_set_cpuid(&rec->fmarker, cpuid);
1371 break;
1372 case RFS_BT_T:
1373 rstf_bpwarmingT_set_cpuid(&rec->bpwarming, cpuid);
1374 break;
1375 case RFS_CW_T:
1376 rstf_cachewarmingT_set_cpuid(&rec->cachewarming, cpuid);
1377 break;
1378 default:
1379 break;
1380 // fprintf(stderr, "rstf.h: warning: set_cpuid meaningless for rtype=%d\n", rec->proto.rtype);
1381 } // swithc(rtype)
1382}
1383
1384static int16_t rstf_get_cpuid(const rstf_unionT * rec)
1385{
1386 switch(rec->proto.rtype) {
1387 case INSTR_T:
1388 return rstf_instrT_get_cpuid(&rec->instr);
1389 break;
1390 case PAVADIFF_T:
1391 return rstf_pavadiffT_get_cpuid(&rec->pavadiff);
1392 break;
1393 case TLB_T:
1394 return rstf_tlbT_get_cpuid(&rec->tlb);
1395 break;
1396 case PREG_T:
1397 return rstf_pregT_get_cpuid(&rec->preg);
1398 break;
1399 case TRAP_T:
1400 return rstf_trapT_get_cpuid(&rec->trap);
1401 break;
1402 case TRAPEXIT_T:
1403 return rstf_trapexitT_get_cpuid(&rec->trapexit);
1404 break;
1405 case TSB_ACCESS_T:
1406 return rstf_tsb_accessT_get_cpuid(&rec->tsb_access);
1407 case TRAPPING_INSTR_T:
1408 return rstf_trapping_instrT_get_cpuid(&rec->trapping_instr);
1409 case REGVAL_T:
1410 return rstf_regvalT_get_cpuid(&rec->regval);
1411 break;
1412 case MEMVAL_T:
1413 return rstf_memval128T_get_cpuid(&rec->memval128);
1414 break;
1415 case PHYSADDR_T:
1416 return rstf_physaddrT_get_cpuid(&rec->physaddr);
1417 break;
1418 case FILEMARKER_T:
1419 return rstf_filemarkerT_get_cpuid(&rec->fmarker);
1420 break;
1421 case RFS_BT_T:
1422 return rstf_bpwarmingT_get_cpuid(&rec->bpwarming);
1423 break;
1424 case RFS_CW_T:
1425 return rstf_cachewarmingT_get_cpuid(&rec->cachewarming);
1426 break;
1427 default:
1428 // fprintf(stderr, "rstf.h: warning: get_cpuid meaningless for rtype=%d\n", rec->proto.rtype);
1429 return -1;
1430 } // swithc(rtype)
1431} // static int16_T rstf_get_cpuid()
1432
1433
1434
1435 // Initialize the RST record pointed ty by RST_PTR, with the rtype RTYPE_VAL
1436 // Fill the rest of the record with zero data.
1437 // This macro code is as efficient as I (RQ) could make it.
1438 // Ex:
1439 // rstf_unionT array[256];
1440 // ...
1441 // INIT_RST_REC( &array[k], INSTR_T);
1442 // rstf_instrT * p = & ( array[k].instr );
1443 //
1444#define INIT_RST_REC(rstf_x_ptr,rtype_val) \
1445 do { \
1446 rstf_uint64T * p_x_rst = (rstf_uint64T*) (rstf_x_ptr); \
1447 p_x_rst->arr64[0] = (rtype_val); \
1448 p_x_rst->arr64[0] <<= (64-8); \
1449 p_x_rst->arr64[1] = 0; \
1450 p_x_rst->arr64[2] = 0; \
1451 } while (0==1)
1452
1453#define ZERO_RST_REC(rstf_x_ptr) \
1454 do { \
1455 rstf_uint64T * p_x_rst = (rstf_uint64T*) (rstf_x_ptr); \
1456 p_x_rst->arr64[0] = 0; \
1457 p_x_rst->arr64[1] = 0; \
1458 p_x_rst->arr64[2] = 0; \
1459 } while (0==1)
1460
1461 // The tte_data that blaze v2.40-v3.60 uses to mimic the US-III.
1462 // This type is now an official type in rstf.h
1463 //
1464struct rstf_tte_dataT {
1465 unsigned valid : 1; /* valid bit */
1466 unsigned size : 2; /* page size */
1467 unsigned nfo : 1; /* no-fault only */
1468 unsigned ie : 1; /* invert endianness */
1469 unsigned soft2 : 9; /* forced to zero */
1470 unsigned subpg : 2;
1471 unsigned sn : 1; /* snoop bit */
1472 unsigned diag_reserved : 2;
1473 unsigned diag_used : 1;
1474 unsigned io : 1;
1475 unsigned pa_tag_hi : 11; /* PA bits <42:32> hi+lo give 43 bit PA */
1476 unsigned pa_tag_lo : 19; /* PA bits <31:13> (use for 32-bit addr) */
1477 unsigned soft : 6; /* forced to zero */
1478 unsigned lock : 1; /* lock bit */
1479 unsigned cp : 1; /* cacheable physical */
1480 unsigned cv : 1; /* cacheable virtual */
1481 unsigned e : 1; /* side-effect */
1482 unsigned priv : 1; /* priviledged */
1483 unsigned writable : 1; /* writeable */
1484 unsigned global : 1; /* global (same as tag.g) */
1485};
1486
1487#ifdef __cplusplus
1488}
1489#endif
1490
1491#endif /* _rstf_h */