1 | //===-- RegisterContextDarwin_riscv32.h -------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_RISCV32_H |
10 | #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_RISCV32_H |
11 | |
12 | #include "lldb/Target/RegisterContext.h" |
13 | #include "lldb/lldb-private.h" |
14 | |
15 | class RegisterContextDarwin_riscv32 : public lldb_private::RegisterContext { |
16 | public: |
17 | RegisterContextDarwin_riscv32(lldb_private::Thread &thread, |
18 | uint32_t concrete_frame_idx); |
19 | |
20 | ~RegisterContextDarwin_riscv32() override; |
21 | |
22 | void InvalidateAllRegisters() override; |
23 | |
24 | size_t GetRegisterCount() override; |
25 | |
26 | const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; |
27 | |
28 | size_t GetRegisterSetCount() override; |
29 | |
30 | const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; |
31 | |
32 | bool ReadRegister(const lldb_private::RegisterInfo *reg_info, |
33 | lldb_private::RegisterValue &value) override; |
34 | |
35 | bool WriteRegister(const lldb_private::RegisterInfo *reg_info, |
36 | const lldb_private::RegisterValue &value) override; |
37 | |
38 | bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; |
39 | |
40 | bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; |
41 | |
42 | uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, |
43 | uint32_t num) override; |
44 | |
45 | struct GPR { |
46 | uint32_t x0; |
47 | uint32_t x1; |
48 | uint32_t x2; |
49 | uint32_t x3; |
50 | uint32_t x4; |
51 | uint32_t x5; |
52 | uint32_t x6; |
53 | uint32_t x7; |
54 | uint32_t x8; |
55 | uint32_t x9; |
56 | uint32_t x10; |
57 | uint32_t x11; |
58 | uint32_t x12; |
59 | uint32_t x13; |
60 | uint32_t x14; |
61 | uint32_t x15; |
62 | uint32_t x16; |
63 | uint32_t x17; |
64 | uint32_t x18; |
65 | uint32_t x19; |
66 | uint32_t x20; |
67 | uint32_t x21; |
68 | uint32_t x22; |
69 | uint32_t x23; |
70 | uint32_t x24; |
71 | uint32_t x25; |
72 | uint32_t x26; |
73 | uint32_t x27; |
74 | uint32_t x28; |
75 | uint32_t x29; |
76 | uint32_t x30; |
77 | uint32_t x31; |
78 | uint32_t pc; |
79 | }; |
80 | |
81 | struct FPU { |
82 | uint32_t f0; |
83 | uint32_t f1; |
84 | uint32_t f2; |
85 | uint32_t f3; |
86 | uint32_t f4; |
87 | uint32_t f5; |
88 | uint32_t f6; |
89 | uint32_t f7; |
90 | uint32_t f8; |
91 | uint32_t f9; |
92 | uint32_t f10; |
93 | uint32_t f11; |
94 | uint32_t f12; |
95 | uint32_t f13; |
96 | uint32_t f14; |
97 | uint32_t f15; |
98 | uint32_t f16; |
99 | uint32_t f17; |
100 | uint32_t f18; |
101 | uint32_t f19; |
102 | uint32_t f20; |
103 | uint32_t f21; |
104 | uint32_t f22; |
105 | uint32_t f23; |
106 | uint32_t f24; |
107 | uint32_t f25; |
108 | uint32_t f26; |
109 | uint32_t f27; |
110 | uint32_t f28; |
111 | uint32_t f29; |
112 | uint32_t f30; |
113 | uint32_t f31; |
114 | uint32_t fcsr; |
115 | }; |
116 | |
117 | struct EXC { |
118 | uint32_t exception; |
119 | uint32_t fsr; |
120 | uint32_t far; |
121 | }; |
122 | |
123 | struct CSR { |
124 | uint32_t csr[1024]; |
125 | }; |
126 | |
127 | protected: |
128 | enum { |
129 | GPRRegSet = 2, // RV32_THREAD_STATE |
130 | EXCRegSet = 3, // RV32_EXCEPTION_STATE |
131 | FPURegSet = 4, // RV_FP32_STATE |
132 | CSRRegSet1 = 6, // RV_CSR_STATE1 |
133 | CSRRegSet2 = 7, // RV_CSR_STATE2 |
134 | CSRRegSet3 = 8, // RV_CSR_STATE3 |
135 | CSRRegSet4 = 9, // RV_CSR_STATE4 |
136 | CSRRegSet = 10 // full 16kbyte CSR reg bank |
137 | }; |
138 | |
139 | enum { |
140 | GPRWordCount = sizeof(GPR) / sizeof(uint32_t), |
141 | FPUWordCount = sizeof(FPU) / sizeof(uint32_t), |
142 | EXCWordCount = sizeof(EXC) / sizeof(uint32_t), |
143 | CSRWordCount = sizeof(CSR) / sizeof(uint32_t) |
144 | }; |
145 | |
146 | enum { Read = 0, Write = 1, kNumErrors = 2 }; |
147 | |
148 | GPR gpr; |
149 | FPU fpr; |
150 | EXC exc; |
151 | CSR csr; |
152 | int gpr_errs[2]; // Read/Write errors |
153 | int fpr_errs[2]; // Read/Write errors |
154 | int exc_errs[2]; // Read/Write errors |
155 | int csr_errs[2]; // Read/Write errors |
156 | |
157 | void InvalidateAllRegisterStates() { |
158 | SetError(flavor: GPRRegSet, err_idx: Read, err: -1); |
159 | SetError(flavor: FPURegSet, err_idx: Read, err: -1); |
160 | SetError(flavor: EXCRegSet, err_idx: Read, err: -1); |
161 | SetError(flavor: CSRRegSet, err_idx: Read, err: -1); |
162 | } |
163 | |
164 | int GetError(int flavor, uint32_t err_idx) const { |
165 | if (err_idx < kNumErrors) { |
166 | switch (flavor) { |
167 | // When getting all errors, just OR all values together to see if |
168 | // we got any kind of error. |
169 | case GPRRegSet: |
170 | return gpr_errs[err_idx]; |
171 | case FPURegSet: |
172 | return fpr_errs[err_idx]; |
173 | case EXCRegSet: |
174 | return exc_errs[err_idx]; |
175 | case CSRRegSet: |
176 | return csr_errs[err_idx]; |
177 | default: |
178 | break; |
179 | } |
180 | } |
181 | return -1; |
182 | } |
183 | |
184 | bool SetError(int flavor, uint32_t err_idx, int err) { |
185 | if (err_idx < kNumErrors) { |
186 | switch (flavor) { |
187 | case GPRRegSet: |
188 | gpr_errs[err_idx] = err; |
189 | return true; |
190 | |
191 | case FPURegSet: |
192 | fpr_errs[err_idx] = err; |
193 | return true; |
194 | |
195 | case EXCRegSet: |
196 | exc_errs[err_idx] = err; |
197 | return true; |
198 | |
199 | case CSRRegSet: |
200 | csr_errs[err_idx] = err; |
201 | return true; |
202 | |
203 | default: |
204 | break; |
205 | } |
206 | } |
207 | return false; |
208 | } |
209 | |
210 | bool RegisterSetIsCached(int set) const { return GetError(flavor: set, err_idx: Read) == 0; } |
211 | |
212 | void LogGPR(lldb_private::Log *log, const char *title); |
213 | |
214 | int ReadGPR(bool force); |
215 | |
216 | int ReadFPU(bool force); |
217 | |
218 | int ReadEXC(bool force); |
219 | |
220 | int ReadCSR(bool force); |
221 | |
222 | int WriteGPR(); |
223 | |
224 | int WriteFPU(); |
225 | |
226 | int WriteEXC(); |
227 | |
228 | int WriteCSR(); |
229 | |
230 | // Subclasses override these to do the actual reading. |
231 | virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0; |
232 | |
233 | virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpr) = 0; |
234 | |
235 | virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; |
236 | |
237 | virtual int DoReadCSR(lldb::tid_t tid, int flavor, CSR &exc) = 0; |
238 | |
239 | virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; |
240 | |
241 | virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpr) = 0; |
242 | |
243 | virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; |
244 | |
245 | virtual int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &exc) = 0; |
246 | |
247 | int ReadRegisterSet(uint32_t set, bool force); |
248 | |
249 | int WriteRegisterSet(uint32_t set); |
250 | |
251 | static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); |
252 | |
253 | static int GetSetForNativeRegNum(int reg_num); |
254 | |
255 | static size_t GetRegisterInfosCount(); |
256 | |
257 | static const lldb_private::RegisterInfo *GetRegisterInfos(); |
258 | }; |
259 | |
260 | #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_RISCV32_H |
261 | |