gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
nativetrace.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2011, 2014, 2016-2017, 2025 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 * Copyright (c) 2006 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
42
43#include "arch/arm/regs/cc.hh"
44#include "arch/arm/regs/int.hh"
45#include "arch/arm/regs/misc.hh"
46#include "arch/arm/regs/vec.hh"
47#include "base/compiler.hh"
48#include "cpu/thread_context.hh"
49#include "debug/ExecRegDelta.hh"
50#include "params/ArmNativeTrace.hh"
51#include "sim/byteswap.hh"
52
53namespace gem5
54{
55
56using namespace ArmISA;
57
58namespace trace {
59
60[[maybe_unused]] static const char *regNames[] = {
61 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
62 "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
63 "cpsr", "f0", "f1", "f2", "f3", "f4", "f5", "f6",
64 "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14",
65 "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22",
66 "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",
67 "f31", "fpscr"
68};
69
71 : NativeTrace(p), stopOnPCError(p.stop_on_pc_error)
72{}
73
74void
76{
78 current = (current + 1) % 2;
80
81 memcpy(newState, oldState, sizeof(state[0]));
82
83 uint64_t diffVector;
84 parent->read(&diffVector, sizeof(diffVector));
85 diffVector = letoh(diffVector);
86
87 int changes = 0;
88 for (int i = 0; i < STATE_NUMVALS; i++) {
89 if (diffVector & 0x1) {
90 changed[i] = true;
91 changes++;
92 } else {
93 changed[i] = false;
94 }
95 diffVector >>= 1;
96 }
97
98 auto values = std::make_unique<uint64_t[]>(changes);
99 parent->read(values.get(), changes * sizeof(uint64_t));
100 int pos = 0;
101 for (int i = 0; i < STATE_NUMVALS; i++) {
102 if (changed[i]) {
103 newState[i] = letoh(values[pos++]);
104 changed[i] = (newState[i] != oldState[i]);
105 }
106 }
107}
108
109void
111{
113 current = (current + 1) % 2;
115
116 // Regular int regs
117 for (int i = 0; i < 15; i++) {
118 newState[i] = tc->getReg(intRegClass[i]);
119 changed[i] = (oldState[i] != newState[i]);
120 }
121
122 //R15, aliased with the PC
123 newState[STATE_PC] = tc->pcState().as<ArmISA::PCState>().npc();
125
126 //CPSR
127 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
128 cpsr.nz = tc->getReg(cc_reg::Nz);
129 cpsr.c = tc->getReg(cc_reg::C);
130 cpsr.v = tc->getReg(cc_reg::V);
131 cpsr.ge = tc->getReg(cc_reg::Ge);
132
133 newState[STATE_CPSR] = cpsr;
135
136 for (int i = 0; i < NumVecV7ArchRegs; i++) {
137 ArmISA::VecRegContainer vec_container;
138 tc->getReg(vecRegClass[i], &vec_container);
139 auto *vec = vec_container.as<uint64_t>();
140 newState[STATE_F0 + 2*i] = vec[0];
141 newState[STATE_F0 + 2*i + 1] = vec[1];
142 }
144 tc->getReg(cc_reg::Fp);
145}
146
147void
149{
150 ThreadContext *tc = record->getThread();
151 // This area is read only on the target. It can't stop there to tell us
152 // what's going on, so we should skip over anything there also.
153 if (tc->pcState().as<ArmISA::PCState>().npc() > 0xffff0000)
154 return;
155 nState.update(this);
156 mState.update(tc);
157
158 // If a syscall just happened native trace needs another tick
159 if ((mState.oldState[STATE_PC] == nState.oldState[STATE_PC]) &&
160 (mState.newState[STATE_PC] - 4 == nState.newState[STATE_PC])) {
161 DPRINTF(ExecRegDelta, "Advancing to match PCs after syscall\n");
162 nState.update(this);
163
164 }
165
166 bool errorFound = false;
167 // Regular int regs
168 for (int i = 0; i < STATE_NUMVALS; i++) {
169 if (nState.changed[i] || mState.changed[i]) {
170 bool oldMatch = (mState.oldState[i] == nState.oldState[i]);
171 bool newMatch = (mState.newState[i] == nState.newState[i]);
172 if (oldMatch && newMatch) {
173 // The more things change, the more they stay the same.
174 continue;
175 }
176
177 errorFound = true;
178
179#ifndef NDEBUG
180 const char *vergence = " ";
181 if (oldMatch && !newMatch) {
182 vergence = "<>";
183 } else if (!oldMatch && newMatch) {
184 vergence = "><";
185 }
186
187 if (!nState.changed[i]) {
188 DPRINTF(ExecRegDelta, "%s [%5s] "\
189 "Native: %#010x "\
190 "M5: %#010x => %#010x\n",
191 vergence, regNames[i],
192 nState.newState[i],
193 mState.oldState[i], mState.newState[i]);
194 } else if (!mState.changed[i]) {
195 DPRINTF(ExecRegDelta, "%s [%5s] "\
196 "Native: %#010x => %#010x "\
197 "M5: %#010x \n",
198 vergence, regNames[i],
199 nState.oldState[i], nState.newState[i],
200 mState.newState[i]);
201 } else {
202 DPRINTF(ExecRegDelta, "%s [%5s] "\
203 "Native: %#010x => %#010x "\
204 "M5: %#010x => %#010x\n",
205 vergence, regNames[i],
206 nState.oldState[i], nState.newState[i],
207 mState.oldState[i], mState.newState[i]);
208 }
209#endif
210 }
211 }
212 if (errorFound) {
213 StaticInstPtr inst = record->getStaticInst();
214 assert(inst);
215 bool ran = true;
216 if (inst->isMicroop()) {
217 ran = false;
218 inst = record->getMacroStaticInst();
219 }
220 assert(inst);
221 record->traceInst(inst, ran);
222
223 bool pcError = (mState.newState[STATE_PC] !=
224 nState.newState[STATE_PC]);
225 if (stopOnPCError && pcError)
226 panic("Native trace detected an error in control flow!");
227 }
228}
229
230} // namespace trace
231} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
Target & as()
Definition pcstate.hh:73
bool isMicroop() const
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual RegVal getReg(const RegId &reg) const
virtual const PCStateBase & pcState() const =0
VecElem * as()
View interposers.
Definition vec_reg.hh:194
ArmNativeTraceParams Params
ArmNativeTrace(const Params &p)
void check(NativeTraceRecord *record)
void traceInst(const StaticInstPtr &inst, bool ran)
Definition exetrace.cc:61
StaticInstPtr getMacroStaticInst() const
ThreadContext * getThread() const
StaticInstPtr getStaticInst() const
NativeTrace(const Params &p)
void read(void *ptr, size_t size)
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
constexpr RegId V
Definition cc.hh:96
constexpr RegId C
Definition cc.hh:95
constexpr RegId Fp
Definition cc.hh:98
constexpr RegId Ge
Definition cc.hh:97
constexpr RegId Nz
Definition cc.hh:94
const RegClass intRegClass
Definition int.hh:173
Bitfield< 7 > i
Definition misc_types.hh:67
const int NumVecV7ArchRegs
Definition vec.hh:79
@ MISCREG_CPSR
Definition misc.hh:79
@ MISCREG_FPSCR
Definition misc.hh:90
gem5::VecRegContainer< NumVecElemPerVecReg *sizeof(VecElem)> VecRegContainer
Definition vec.hh:64
constexpr RegClass vecRegClass
Definition vec.hh:100
Bitfield< 0 > p
Bitfield< 25 > vec
Definition misc.hh:113
static const char * regNames[]
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
T letoh(T value)
Definition byteswap.hh:173
RefCountingPtr< StaticInst > StaticInstPtr
uint64_t state[2][STATE_NUMVALS]

Generated on Mon Oct 27 2025 04:13:00 for gem5 by doxygen 1.14.0