mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / arm / tracers / tarmac_parser.hh
1 /*
2 * Copyright (c) 2011,2017-2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Giacomo Gabrielli
38 */
39
40 /**
41 * @file This module implements a bridge between TARMAC traces, as generated by
42 * other models, and gem5 (AtomicCPU model). Its goal is to detect possible
43 * inconsistencies between the two models as soon as they occur. The module
44 * takes a TARMAC trace as input, which is used to compare the architectural
45 * state of the two models after each simulated instruction.
46 */
47
48 #ifndef __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__
49 #define __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__
50
51 #include <fstream>
52 #include <unordered_map>
53
54 #include "arch/arm/registers.hh"
55 #include "base/trace.hh"
56 #include "base/types.hh"
57 #include "cpu/static_inst.hh"
58 #include "cpu/thread_context.hh"
59 #include "mem/request.hh"
60 #include "params/TarmacParser.hh"
61 #include "sim/insttracer.hh"
62 #include "tarmac_base.hh"
63
64 namespace Trace {
65
66 class TarmacParserRecord : public TarmacBaseRecord
67 {
68 public:
69 /**
70 * Event triggered to check the value of the destination registers. Needed
71 * to handle some cases where registers are modified after the trace record
72 * has been dumped. E.g., the SVC instruction updates the CPSR and SPSR as
73 * part of the fault handling routine.
74 */
75 struct TarmacParserRecordEvent: public Event
76 {
77 /**
78 * Reference to the TARMAC trace object to which this record belongs.
79 */
80 TarmacParser& parent;
81 /** Current thread context. */
82 ThreadContext* thread;
83 /** Current instruction. */
84 const StaticInstPtr inst;
85 /** PC of the current instruction. */
86 ArmISA::PCState pc;
87 /** True if a mismatch has been detected for this instruction. */
88 bool mismatch;
89 /**
90 * True if a mismatch has been detected for this instruction on PC or
91 * opcode.
92 */
93 bool mismatchOnPcOrOpcode;
94
95 TarmacParserRecordEvent(TarmacParser& _parent,
96 ThreadContext *_thread,
97 const StaticInstPtr _inst,
98 ArmISA::PCState _pc,
99 bool _mismatch,
100 bool _mismatch_on_pc_or_opcode) :
101 parent(_parent), thread(_thread), inst(_inst), pc(_pc),
102 mismatch(_mismatch),
103 mismatchOnPcOrOpcode(_mismatch_on_pc_or_opcode)
104 {
105 }
106
107 void process();
108 const char *description() const;
109 };
110
111 struct ParserInstEntry : public InstEntry
112 {
113 public:
114 uint64_t seq_num;
115 };
116
117 struct ParserRegEntry : public RegEntry
118 {
119 public:
120 char repr[16];
121 };
122
123 struct ParserMemEntry : public MemEntry
124 { };
125
126 static const int MaxLineLength = 256;
127
128 /**
129 * Print a mismatch header containing the instruction fields as reported
130 * by gem5.
131 */
132 static void printMismatchHeader(const StaticInstPtr inst,
133 ArmISA::PCState pc);
134
135 TarmacParserRecord(Tick _when, ThreadContext *_thread,
136 const StaticInstPtr _staticInst, ArmISA::PCState _pc,
137 TarmacParser& _parent,
138 const StaticInstPtr _macroStaticInst = NULL);
139
140 void dump() override;
141
142 /**
143 * Performs a memory access to read the value written by a previous write.
144 * @return False if the result of the memory access should be ignored
145 * (faulty memory access, etc.).
146 */
147 bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
148 unsigned flags);
149
150 private:
151 /**
152 * Advances the TARMAC trace up to the next instruction,
153 * register, or memory access record. The collected data is stored
154 * in one of {inst/reg/mem}_record.
155 * @return False if EOF is reached.
156 */
157 bool advanceTrace();
158
159 /** Returns the string representation of an instruction set state. */
160 const char *iSetStateToStr(ISetState isetstate) const;
161
162 /** Buffer for instruction trace records. */
163 static ParserInstEntry instRecord;
164
165 /** Buffer for register trace records. */
166 static ParserRegEntry regRecord;
167
168 /** Buffer for memory access trace records (stores only). */
169 static ParserMemEntry memRecord;
170
171 /** Type of last parsed record. */
172 static TarmacRecordType currRecordType;
173
174 /** Buffer used for trace file parsing. */
175 static char buf[MaxLineLength];
176
177 /** List of records of destination registers. */
178 static std::list<ParserRegEntry> destRegRecords;
179
180 /** Map from misc. register names to indexes. */
181 using MiscRegMap = std::unordered_map<std::string, RegIndex>;
182 static MiscRegMap miscRegMap;
183
184 /**
185 * True if a TARMAC instruction record has already been parsed for this
186 * instruction.
187 */
188 bool parsingStarted;
189
190 /** True if a mismatch has been detected for this instruction. */
191 bool mismatch;
192
193 /**
194 * True if a mismatch has been detected for this instruction on PC or
195 * opcode.
196 */
197 bool mismatchOnPcOrOpcode;
198
199 /** Request for memory write checks. */
200 RequestPtr memReq;
201
202 /** Max. vector length (SVE). */
203 static int8_t maxVectorLength;
204
205 protected:
206 TarmacParser& parent;
207 };
208
209 /**
210 * Tarmac Parser: this tracer parses an existing Tarmac trace and it
211 * diffs it with gem5 simulation status, comparing results and
212 * reporting architectural mismatches if any.
213 */
214 class TarmacParser : public InstTracer
215 {
216 friend class TarmacParserRecord;
217
218 public:
219 typedef TarmacParserParams Params;
220
221 TarmacParser(const Params *p) : InstTracer(p), startPc(p->start_pc),
222 exitOnDiff(p->exit_on_diff),
223 exitOnInsnDiff(p->exit_on_insn_diff),
224 memWrCheck(p->mem_wr_check),
225 ignoredAddrRange(p->ignore_mem_addr),
226 cpuId(p->cpu_id),
227 macroopInProgress(false)
228 {
229 assert(!(exitOnDiff && exitOnInsnDiff));
230
231 trace.open(p->path_to_trace.c_str());
232 if (startPc == 0x0) {
233 started = true;
234 } else {
235 advanceTraceToStartPc();
236 started = false;
237 }
238 }
239
240 virtual ~TarmacParser()
241 {
242 trace.close();
243 }
244
245 InstRecord *
246 getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst,
247 ArmISA::PCState pc,
248 const StaticInstPtr macroStaticInst = NULL)
249 {
250 if (!started && pc.pc() == startPc)
251 started = true;
252
253 if (started)
254 return new TarmacParserRecord(when, tc, staticInst, pc, *this,
255 macroStaticInst);
256 else
257 return NULL;
258 }
259
260 private:
261 /** Helper function to advance the trace up to startPc. */
262 void advanceTraceToStartPc();
263
264 /** TARMAC trace file. */
265 std::ifstream trace;
266
267 /**
268 * Tracing starts when the PC gets this value for the first time (ignored
269 * if 0x0).
270 */
271 Addr startPc;
272
273 /**
274 * If true, the simulation is stopped as the first mismatch is detected.
275 */
276 bool exitOnDiff;
277
278 /**
279 * If true, the simulation is stopped as the first mismatch is detected on
280 * PC or opcode.
281 */
282 bool exitOnInsnDiff;
283
284 /** If true, memory write accesses are checked. */
285 bool memWrCheck;
286
287 /** Ignored addresses (ignored if empty). */
288 AddrRange ignoredAddrRange;
289
290 /** If true, the trace format includes the CPU id. */
291 bool cpuId;
292
293 /** True if tracing has started. */
294 bool started;
295
296 /** True if a macroop is currently in progress. */
297 bool macroopInProgress;
298 };
299
300 } // namespace Trace
301
302 #endif // __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__