1 |
5 |
sergeykhbr |
/*
|
2 |
|
|
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
|
3 |
|
|
*
|
4 |
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5 |
|
|
* you may not use this file except in compliance with the License.
|
6 |
|
|
* You may obtain a copy of the License at
|
7 |
|
|
*
|
8 |
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
9 |
|
|
*
|
10 |
|
|
* Unless required by applicable law or agreed to in writing, software
|
11 |
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
12 |
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 |
|
|
* See the License for the specific language governing permissions and
|
14 |
|
|
* limitations under the License.
|
15 |
|
|
*/
|
16 |
|
|
|
17 |
|
|
#ifndef __DEBUGGER_COMMON_CPU_GENERIC_H__
|
18 |
|
|
#define __DEBUGGER_COMMON_CPU_GENERIC_H__
|
19 |
|
|
|
20 |
|
|
#include <iclass.h>
|
21 |
|
|
#include <iservice.h>
|
22 |
|
|
#include <ihap.h>
|
23 |
|
|
#include <async_tqueue.h>
|
24 |
|
|
#include "coreservices/ithread.h"
|
25 |
|
|
#include "coreservices/icpugen.h"
|
26 |
|
|
#include "coreservices/icpufunctional.h"
|
27 |
|
|
#include "coreservices/imemop.h"
|
28 |
|
|
#include "coreservices/iclock.h"
|
29 |
|
|
#include "coreservices/iclklistener.h"
|
30 |
|
|
#include "coreservices/ireset.h"
|
31 |
|
|
#include "coreservices/isrccode.h"
|
32 |
|
|
#include "generic/mapreg.h"
|
33 |
|
|
#include "debug/debugmap.h"
|
34 |
|
|
#include <fstream>
|
35 |
|
|
|
36 |
|
|
namespace debugger {
|
37 |
|
|
|
38 |
|
|
class GenericStatusType : public MappedReg64Type {
|
39 |
|
|
public:
|
40 |
|
|
GenericStatusType(IService *parent, const char *name, uint64_t addr) :
|
41 |
|
|
MappedReg64Type(parent, name, addr) {
|
42 |
|
|
}
|
43 |
|
|
protected:
|
44 |
|
|
virtual uint64_t aboutToRead(uint64_t cur_val);
|
45 |
|
|
virtual uint64_t aboutToWrite(uint64_t new_val);
|
46 |
|
|
};
|
47 |
|
|
|
48 |
|
|
class FetchedBreakpointType : public MappedReg64Type {
|
49 |
|
|
public:
|
50 |
|
|
FetchedBreakpointType(IService *parent, const char *name, uint64_t addr)
|
51 |
|
|
: MappedReg64Type(parent, name, addr) {
|
52 |
|
|
}
|
53 |
|
|
protected:
|
54 |
|
|
virtual uint64_t aboutToWrite(uint64_t new_val);
|
55 |
|
|
};
|
56 |
|
|
|
57 |
|
|
class AddBreakpointType : public MappedReg64Type {
|
58 |
|
|
public:
|
59 |
|
|
AddBreakpointType(IService *parent, const char *name, uint64_t addr)
|
60 |
|
|
: MappedReg64Type(parent, name, addr) {
|
61 |
|
|
}
|
62 |
|
|
protected:
|
63 |
|
|
virtual uint64_t aboutToWrite(uint64_t new_val);
|
64 |
|
|
};
|
65 |
|
|
|
66 |
|
|
class RemoveBreakpointType : public MappedReg64Type {
|
67 |
|
|
public:
|
68 |
|
|
RemoveBreakpointType(IService *parent, const char *name, uint64_t addr)
|
69 |
|
|
: MappedReg64Type(parent, name, addr) {
|
70 |
|
|
}
|
71 |
|
|
protected:
|
72 |
|
|
virtual uint64_t aboutToWrite(uint64_t new_val);
|
73 |
|
|
};
|
74 |
|
|
|
75 |
|
|
class StepCounterType : public MappedReg64Type {
|
76 |
|
|
public:
|
77 |
|
|
StepCounterType(IService *parent, const char *name, uint64_t addr)
|
78 |
|
|
: MappedReg64Type(parent, name, addr) {
|
79 |
|
|
}
|
80 |
|
|
protected:
|
81 |
|
|
virtual uint64_t aboutToRead(uint64_t cur_val);
|
82 |
|
|
};
|
83 |
|
|
|
84 |
|
|
class CpuGeneric : public IService,
|
85 |
|
|
public IThread,
|
86 |
|
|
public ICpuGeneric,
|
87 |
|
|
public ICpuFunctional,
|
88 |
|
|
public IClock,
|
89 |
|
|
public IResetListener,
|
90 |
|
|
public IHap {
|
91 |
|
|
public:
|
92 |
|
|
explicit CpuGeneric(const char *name);
|
93 |
|
|
~CpuGeneric();
|
94 |
|
|
|
95 |
|
|
/** IService interface */
|
96 |
|
|
virtual void postinitService();
|
97 |
|
|
|
98 |
|
|
/** ICpuGeneric interface */
|
99 |
|
|
virtual void raiseSignal(int idx) = 0;
|
100 |
|
|
virtual void lowerSignal(int idx) = 0;
|
101 |
|
|
virtual void nb_transport_debug_port(DebugPortTransactionType *trans,
|
102 |
|
|
IDbgNbResponse *cb);
|
103 |
|
|
|
104 |
|
|
/** ICpuFunctional */
|
105 |
|
|
virtual uint64_t getPC() { return pc_.getValue().val; }
|
106 |
|
|
virtual void setBranch(uint64_t npc);
|
107 |
|
|
virtual void pushStackTrace();
|
108 |
|
|
virtual void popStackTrace();
|
109 |
|
|
virtual uint64_t getPrvLevel() { return cur_prv_level; }
|
110 |
|
|
virtual void setPrvLevel(uint64_t lvl) { cur_prv_level = lvl; }
|
111 |
|
|
virtual void dma_memop(Axi4TransactionType *tr);
|
112 |
|
|
virtual bool isOn() { return estate_ != CORE_OFF; }
|
113 |
|
|
virtual bool isHalt() { return estate_ == CORE_Halted; }
|
114 |
|
|
virtual bool isSwBreakpoint() { return sw_breakpoint_; }
|
115 |
|
|
virtual bool isHwBreakpoint() { return hw_breakpoint_; }
|
116 |
|
|
virtual void go();
|
117 |
|
|
virtual void halt(const char *descr);
|
118 |
|
|
virtual void step();
|
119 |
|
|
virtual void addHwBreakpoint(uint64_t addr);
|
120 |
|
|
virtual void removeHwBreakpoint(uint64_t addr);
|
121 |
|
|
virtual void skipBreakpoint();
|
122 |
|
|
protected:
|
123 |
|
|
virtual uint64_t getResetAddress() { return resetVector_.to_uint64(); }
|
124 |
|
|
virtual EEndianessType endianess() = 0;
|
125 |
|
|
virtual GenericInstruction *decodeInstruction(Reg64Type *cache) = 0;
|
126 |
|
|
virtual void generateIllegalOpcode() = 0;
|
127 |
|
|
virtual void handleTrap() = 0;
|
128 |
|
|
virtual void trackContextStart() {}
|
129 |
|
|
virtual void trackContextEnd() {}
|
130 |
|
|
|
131 |
|
|
public:
|
132 |
|
|
/** IClock */
|
133 |
|
|
virtual uint64_t getStepCounter() { return step_cnt_; }
|
134 |
|
|
virtual void registerStepCallback(IClockListener *cb, uint64_t t);
|
135 |
|
|
virtual double getFreqHz() {
|
136 |
|
|
return static_cast<double>(freqHz_.to_int64());
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
/** IResetListener interface */
|
140 |
|
|
virtual void reset(bool active);
|
141 |
|
|
|
142 |
|
|
/** IHap */
|
143 |
|
|
virtual void hapTriggered(IFace *isrc, EHapType type, const char *descr);
|
144 |
|
|
|
145 |
|
|
protected:
|
146 |
|
|
/** IThread interface */
|
147 |
|
|
virtual void busyLoop();
|
148 |
|
|
|
149 |
|
|
void updatePipeline();
|
150 |
|
|
bool updateState();
|
151 |
|
|
void fetchILine();
|
152 |
|
|
void updateDebugPort();
|
153 |
|
|
void updateQueue();
|
154 |
|
|
bool checkHwBreakpoint();
|
155 |
|
|
|
156 |
|
|
protected:
|
157 |
|
|
AttributeType isEnable_;
|
158 |
|
|
AttributeType freqHz_;
|
159 |
|
|
AttributeType sysBus_;
|
160 |
|
|
AttributeType dbgBus_;
|
161 |
|
|
AttributeType sysBusWidthBytes_;
|
162 |
|
|
AttributeType sourceCode_;
|
163 |
|
|
AttributeType stackTraceSize_;
|
164 |
|
|
AttributeType generateRegTraceFile_;
|
165 |
|
|
AttributeType generateMemTraceFile_;
|
166 |
|
|
AttributeType resetVector_;
|
167 |
|
|
AttributeType sysBusMasterID_;
|
168 |
|
|
AttributeType hwBreakpoints_;
|
169 |
|
|
|
170 |
|
|
ISourceCode *isrc_;
|
171 |
|
|
IMemoryOperation *isysbus_;
|
172 |
|
|
IMemoryOperation *idbgbus_;
|
173 |
|
|
GenericInstruction *instr_;
|
174 |
|
|
|
175 |
|
|
uint64_t step_cnt_;
|
176 |
|
|
uint64_t hw_stepping_break_;
|
177 |
|
|
bool branch_;
|
178 |
|
|
unsigned oplen_;
|
179 |
|
|
MappedReg64Type pc_;
|
180 |
|
|
MappedReg64Type npc_;
|
181 |
|
|
GenericStatusType status_;
|
182 |
|
|
MappedReg64Type stepping_cnt_;
|
183 |
|
|
StepCounterType clock_cnt_;
|
184 |
|
|
StepCounterType executed_cnt_;
|
185 |
|
|
MappedReg64Type stackTraceCnt_; // Hardware stack trace buffer
|
186 |
|
|
GenericReg64Bank stackTraceBuf_; // [[from,to],*]
|
187 |
|
|
MappedReg64Type br_control_; // Enable/disable Trap on break
|
188 |
|
|
MappedReg64Type br_fetch_addr_; // Skip breakpoint at address
|
189 |
|
|
FetchedBreakpointType br_fetch_instr_; // Use this instruction on address
|
190 |
|
|
AddBreakpointType br_hw_add_;
|
191 |
|
|
RemoveBreakpointType br_hw_remove_;
|
192 |
|
|
|
193 |
|
|
Reg64Type pc_z_;
|
194 |
|
|
uint64_t interrupt_pending_;
|
195 |
|
|
bool sw_breakpoint_;
|
196 |
|
|
bool skip_sw_breakpoint_;
|
197 |
|
|
bool hw_breakpoint_;
|
198 |
|
|
uint64_t hw_break_addr_; // Last hit breakpoint to skip it on next step
|
199 |
|
|
|
200 |
|
|
event_def eventConfigDone_;
|
201 |
|
|
ClockAsyncTQueueType queue_;
|
202 |
|
|
|
203 |
|
|
enum ECoreState {
|
204 |
|
|
CORE_OFF,
|
205 |
|
|
CORE_Halted,
|
206 |
|
|
CORE_Normal,
|
207 |
|
|
CORE_Stepping
|
208 |
|
|
} estate_;
|
209 |
|
|
|
210 |
|
|
Axi4TransactionType trans_;
|
211 |
|
|
Reg64Type cacheline_[512/4];
|
212 |
|
|
struct DebugPortType {
|
213 |
|
|
bool valid;
|
214 |
|
|
DebugPortTransactionType *trans;
|
215 |
|
|
IDbgNbResponse *cb;
|
216 |
|
|
} dport_;
|
217 |
|
|
|
218 |
|
|
uint64_t cur_prv_level;
|
219 |
|
|
|
220 |
|
|
std::ofstream *reg_trace_file;
|
221 |
|
|
std::ofstream *mem_trace_file;
|
222 |
|
|
};
|
223 |
|
|
|
224 |
|
|
} // namespace debugger
|
225 |
|
|
|
226 |
|
|
#endif // __DEBUGGER_COMMON_CPU_GENERIC_H__
|