misc: Updated the RELEASE-NOTES and version number
[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
38 /**
39 * @file This module implements a bridge between TARMAC traces, as generated by
40 * other models, and gem5 (AtomicCPU model). Its goal is to detect possible
41 * inconsistencies between the two models as soon as they occur. The module
42 * takes a TARMAC trace as input, which is used to compare the architectural
43 * state of the two models after each simulated instruction.
44 */
45
46 #ifndef __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__
47 #define __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__
48
49 #include <fstream>
50 #include <unordered_map>
51
52 #include "arch/arm/registers.hh"
53 #include "base/trace.hh"
54 #include "base/types.hh"
55 #include "cpu/static_inst.hh"
56 #include "cpu/thread_context.hh"
57 #include "mem/request.hh"
58 #include "params/TarmacParser.hh"
59 #include "sim/insttracer.hh"
60 #include "tarmac_base.hh"
61
62 namespace Trace {
63
64 class TarmacParserRecord : public TarmacBaseRecord
65 {
66 public:
67 /**
68 * Event triggered to check the value of the destination registers. Needed
69 * to handle some cases where registers are modified after the trace record
70 * has been dumped. E.g., the SVC instruction updates the CPSR and SPSR as
71 * part of the fault handling routine.
72 */
73 struct TarmacParserRecordEvent: public Event
74 {
75 /**
76 * Reference to the TARMAC trace object to which this record belongs.
77 */
78 TarmacParser& parent;
79 /** Current thread context. */
80 ThreadContext* thread;
81 /** Current instruction. */
82 const StaticInstPtr inst;
83 /** PC of the current instruction. */
84 ArmISA::PCState pc;
85 /** True if a mismatch has been detected for this instruction. */
86 bool mismatch;
87 /**
88 * True if a mismatch has been detected for this instruction on PC or
89 * opcode.
90 */
91 bool mismatchOnPcOrOpcode;
92
93 TarmacParserRecordEvent(TarmacParser& _parent,
94 ThreadContext *_thread,
95 const StaticInstPtr _inst,
96 ArmISA::PCState _pc,
97 bool _mismatch,
98 bool _mismatch_on_pc_or_opcode) :
99 parent(_parent), thread(_thread), inst(_inst), pc(_pc),
100 mismatch(_mismatch),
101 mismatchOnPcOrOpcode(_mismatch_on_pc_or_opcode)
102 {
103 }
104
105 void process();
106 const char *description() const;
107 };
108
109 struct ParserInstEntry : public InstEntry
110 {
111 public:
112 uint64_t seq_num;
113 };
114
115 struct ParserRegEntry : public RegEntry
116 {
117 public:
118 char repr[16];
119 };
120
121 struct ParserMemEntry : public MemEntry
122 { };
123
124 static const int MaxLineLength = 256;
125
126 /**
127 * Print a mismatch header containing the instruction fields as reported
128 * by gem5.
129 */
130 static void printMismatchHeader(const StaticInstPtr inst,
131 ArmISA::PCState pc);
132
133 TarmacParserRecord(Tick _when, ThreadContext *_thread,
134 const StaticInstPtr _staticInst, ArmISA::PCState _pc,
135 TarmacParser& _parent,
136 const StaticInstPtr _macroStaticInst = NULL);
137
138 void dump() override;
139
140 /**
141 * Performs a memory access to read the value written by a previous write.
142 * @return False if the result of the memory access should be ignored
143 * (faulty memory access, etc.).
144 */
145 bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
146 unsigned flags);
147
148 private:
149 /**
150 * Advances the TARMAC trace up to the next instruction,
151 * register, or memory access record. The collected data is stored
152 * in one of {inst/reg/mem}_record.
153 * @return False if EOF is reached.
154 */
155 bool advanceTrace();
156
157 /** Returns the string representation of an instruction set state. */
158 const char *iSetStateToStr(ISetState isetstate) const;
159
160 /** Buffer for instruction trace records. */
161 static ParserInstEntry instRecord;
162
163 /** Buffer for register trace records. */
164 static ParserRegEntry regRecord;
165
166 /** Buffer for memory access trace records (stores only). */
167 static ParserMemEntry memRecord;
168
169 /** Type of last parsed record. */
170 static TarmacRecordType currRecordType;
171
172 /** Buffer used for trace file parsing. */
173 static char buf[MaxLineLength];
174
175 /** List of records of destination registers. */
176 static std::list<ParserRegEntry> destRegRecords;
177
178 /** Map from misc. register names to indexes. */
179 using MiscRegMap = std::unordered_map<std::string, RegIndex>;
180 static MiscRegMap miscRegMap;
181
182 /**
183 * True if a TARMAC instruction record has already been parsed for this
184 * instruction.
185 */
186 bool parsingStarted;
187
188 /** True if a mismatch has been detected for this instruction. */
189 bool mismatch;
190
191 /**
192 * True if a mismatch has been detected for this instruction on PC or
193 * opcode.
194 */
195 bool mismatchOnPcOrOpcode;
196
197 /** Request for memory write checks. */
198 RequestPtr memReq;
199
200 /** Max. vector length (SVE). */
201 static int8_t maxVectorLength;
202
203 protected:
204 TarmacParser& parent;
205 };
206
207 /**
208 * Tarmac Parser: this tracer parses an existing Tarmac trace and it
209 * diffs it with gem5 simulation status, comparing results and
210 * reporting architectural mismatches if any.
211 */
212 class TarmacParser : public InstTracer
213 {
214 friend class TarmacParserRecord;
215
216 public:
217 typedef TarmacParserParams Params;
218
219 TarmacParser(const Params *p) : InstTracer(p), startPc(p->start_pc),
220 exitOnDiff(p->exit_on_diff),
221 exitOnInsnDiff(p->exit_on_insn_diff),
222 memWrCheck(p->mem_wr_check),
223 ignoredAddrRange(p->ignore_mem_addr),
224 cpuId(p->cpu_id),
225 macroopInProgress(false)
226 {
227 assert(!(exitOnDiff && exitOnInsnDiff));
228
229 trace.open(p->path_to_trace.c_str());
230 if (startPc == 0x0) {
231 started = true;
232 } else {
233 advanceTraceToStartPc();
234 started = false;
235 }
236 }
237
238 virtual ~TarmacParser()
239 {
240 trace.close();
241 }
242
243 InstRecord *
244 getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst,
245 ArmISA::PCState pc,
246 const StaticInstPtr macroStaticInst = NULL)
247 {
248 if (!started && pc.pc() == startPc)
249 started = true;
250
251 if (started)
252 return new TarmacParserRecord(when, tc, staticInst, pc, *this,
253 macroStaticInst);
254 else
255 return NULL;
256 }
257
258 private:
259 /** Helper function to advance the trace up to startPc. */
260 void advanceTraceToStartPc();
261
262 /** TARMAC trace file. */
263 std::ifstream trace;
264
265 /**
266 * Tracing starts when the PC gets this value for the first time (ignored
267 * if 0x0).
268 */
269 Addr startPc;
270
271 /**
272 * If true, the simulation is stopped as the first mismatch is detected.
273 */
274 bool exitOnDiff;
275
276 /**
277 * If true, the simulation is stopped as the first mismatch is detected on
278 * PC or opcode.
279 */
280 bool exitOnInsnDiff;
281
282 /** If true, memory write accesses are checked. */
283 bool memWrCheck;
284
285 /** Ignored addresses (ignored if empty). */
286 AddrRange ignoredAddrRange;
287
288 /** If true, the trace format includes the CPU id. */
289 bool cpuId;
290
291 /** True if tracing has started. */
292 bool started;
293
294 /** True if a macroop is currently in progress. */
295 bool macroopInProgress;
296 };
297
298 } // namespace Trace
299
300 #endif // __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__