riscv: add remote gdb support
[gem5.git] / src / arch / riscv / isa.cc
1 /*
2 * Copyright (c) 2016 RISC-V Foundation
3 * Copyright (c) 2016 The University of Virginia
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Authors: Alec Roelke
30 */
31 #include "arch/riscv/isa.hh"
32
33 #include <ctime>
34 #include <set>
35 #include <sstream>
36
37 #include "arch/riscv/registers.hh"
38 #include "base/bitfield.hh"
39 #include "cpu/base.hh"
40 #include "debug/RiscvMisc.hh"
41 #include "params/RiscvISA.hh"
42 #include "sim/core.hh"
43 #include "sim/pseudo_inst.hh"
44
45 namespace RiscvISA
46 {
47
48 ISA::ISA(Params *p) : SimObject(p)
49 {
50 miscRegNames = {
51 {MISCREG_USTATUS, "ustatus"},
52 {MISCREG_UIE, "uie"},
53 {MISCREG_UTVEC, "utvec"},
54 {MISCREG_USCRATCH, "uscratch"},
55 {MISCREG_UEPC, "uepc"},
56 {MISCREG_UCAUSE, "ucause"},
57 {MISCREG_UBADADDR, "ubadaddr"},
58 {MISCREG_UIP, "uip"},
59 {MISCREG_FFLAGS, "fflags"},
60 {MISCREG_FRM, "frm"},
61 {MISCREG_FCSR, "fcsr"},
62 {MISCREG_CYCLE, "cycle"},
63 {MISCREG_TIME, "time"},
64 {MISCREG_INSTRET, "instret"},
65 {MISCREG_CYCLEH, "cycleh"},
66 {MISCREG_TIMEH, "timeh"},
67 {MISCREG_INSTRETH, "instreth"},
68
69 {MISCREG_SSTATUS, "sstatus"},
70 {MISCREG_SEDELEG, "sedeleg"},
71 {MISCREG_SIDELEG, "sideleg"},
72 {MISCREG_SIE, "sie"},
73 {MISCREG_STVEC, "stvec"},
74 {MISCREG_SSCRATCH, "sscratch"},
75 {MISCREG_SEPC, "sepc"},
76 {MISCREG_SCAUSE, "scause"},
77 {MISCREG_SBADADDR, "sbadaddr"},
78 {MISCREG_SIP, "sip"},
79 {MISCREG_SPTBR, "sptbr"},
80
81 {MISCREG_HSTATUS, "hstatus"},
82 {MISCREG_HEDELEG, "hedeleg"},
83 {MISCREG_HIDELEG, "hideleg"},
84 {MISCREG_HIE, "hie"},
85 {MISCREG_HTVEC, "htvec"},
86 {MISCREG_HSCRATCH, "hscratch"},
87 {MISCREG_HEPC, "hepc"},
88 {MISCREG_HCAUSE, "hcause"},
89 {MISCREG_HBADADDR, "hbadaddr"},
90 {MISCREG_HIP, "hip"},
91
92 {MISCREG_MVENDORID, "mvendorid"},
93 {MISCREG_MARCHID, "marchid"},
94 {MISCREG_MIMPID, "mimpid"},
95 {MISCREG_MHARTID, "mhartid"},
96 {MISCREG_MSTATUS, "mstatus"},
97 {MISCREG_MISA, "misa"},
98 {MISCREG_MEDELEG, "medeleg"},
99 {MISCREG_MIDELEG, "mideleg"},
100 {MISCREG_MIE, "mie"},
101 {MISCREG_MTVEC, "mtvec"},
102 {MISCREG_MSCRATCH, "mscratch"},
103 {MISCREG_MEPC, "mepc"},
104 {MISCREG_MCAUSE, "mcause"},
105 {MISCREG_MBADADDR, "mbadaddr"},
106 {MISCREG_MIP, "mip"},
107 {MISCREG_MBASE, "mbase"},
108 {MISCREG_MBOUND, "mbound"},
109 {MISCREG_MIBASE, "mibase"},
110 {MISCREG_MIBOUND, "mibound"},
111 {MISCREG_MDBASE, "mdbase"},
112 {MISCREG_MDBOUND, "mdbound"},
113 {MISCREG_MCYCLE, "mcycle"},
114 {MISCREG_MINSTRET, "minstret"},
115 {MISCREG_MUCOUNTEREN, "mucounteren"},
116 {MISCREG_MSCOUNTEREN, "mscounteren"},
117 {MISCREG_MHCOUNTEREN, "mhcounteren"},
118
119 {MISCREG_TSELECT, "tselect"},
120 {MISCREG_TDATA1, "tdata1"},
121 {MISCREG_TDATA2, "tdata2"},
122 {MISCREG_TDATA3, "tdata3"},
123 {MISCREG_DCSR, "dcsr"},
124 {MISCREG_DPC, "dpc"},
125 {MISCREG_DSCRATCH, "dscratch"}
126 };
127 for (int i = 0; i < NumHpmcounter; i++)
128 {
129 int hpmcounter = MISCREG_HPMCOUNTER_BASE + i;
130 std::stringstream ss;
131 ss << "hpmcounter" << hpmcounter;
132 miscRegNames[hpmcounter] = ss.str();
133 }
134 for (int i = 0; i < NumHpmcounterh; i++)
135 {
136 int hpmcounterh = MISCREG_HPMCOUNTERH_BASE + i;
137 std::stringstream ss;
138 ss << "hpmcounterh" << hpmcounterh;
139 miscRegNames[hpmcounterh] = ss.str();
140 }
141 for (int i = 0; i < NumMhpmcounter; i++)
142 {
143 int mhpmcounter = MISCREG_MHPMCOUNTER_BASE + i;
144 std::stringstream ss;
145 ss << "mhpmcounter" << mhpmcounter;
146 miscRegNames[mhpmcounter] = ss.str();
147 }
148 for (int i = 0; i < NumMhpmevent; i++)
149 {
150 int mhpmevent = MISCREG_MHPMEVENT_BASE + i;
151 std::stringstream ss;
152 ss << "mhpmcounterh" << mhpmevent;
153 miscRegNames[mhpmevent] = ss.str();
154 }
155
156 miscRegFile.resize(NumMiscRegs);
157 clear();
158 }
159
160 const RiscvISAParams *
161 ISA::params() const
162 {
163 return dynamic_cast<const Params *>(_params);
164 }
165
166 void ISA::clear()
167 {
168 std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
169
170 miscRegFile[MISCREG_MVENDORID] = 0;
171 miscRegFile[MISCREG_MARCHID] = 0;
172 miscRegFile[MISCREG_MIMPID] = 0;
173 miscRegFile[MISCREG_MISA] = 0x8000000000101129ULL;
174 }
175
176
177 MiscReg
178 ISA::readMiscRegNoEffect(int misc_reg) const
179 {
180 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
181 miscRegNames.at(misc_reg), miscRegFile[misc_reg]);
182 switch (misc_reg) {
183 case MISCREG_FFLAGS:
184 return bits(miscRegFile[MISCREG_FCSR], 4, 0);
185 case MISCREG_FRM:
186 return bits(miscRegFile[MISCREG_FCSR], 7, 5);
187 case MISCREG_FCSR:
188 return bits(miscRegFile[MISCREG_FCSR], 31, 0);
189 case MISCREG_CYCLE:
190 warn("Use readMiscReg to read the cycle CSR.");
191 return 0;
192 case MISCREG_TIME:
193 return std::time(nullptr);
194 case MISCREG_INSTRET:
195 warn("Use readMiscReg to read the instret CSR.");
196 return 0;
197 case MISCREG_CYCLEH:
198 warn("Use readMiscReg to read the cycleh CSR.");
199 return 0;
200 case MISCREG_TIMEH:
201 return std::time(nullptr) >> 32;
202 case MISCREG_INSTRETH:
203 warn("Use readMiscReg to read the instreth CSR.");
204 return 0;
205 case MISCREG_MHARTID:
206 warn("Use readMiscReg to read the mhartid CSR.");
207 return 0;
208 default:
209 return miscRegFile[misc_reg];
210 }
211 }
212
213 MiscReg
214 ISA::readMiscReg(int misc_reg, ThreadContext *tc)
215 {
216 switch (misc_reg) {
217 case MISCREG_INSTRET:
218 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
219 miscRegNames[misc_reg], miscRegFile[misc_reg]);
220 return tc->getCpuPtr()->totalInsts();
221 case MISCREG_CYCLE:
222 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
223 miscRegNames[misc_reg], miscRegFile[misc_reg]);
224 return tc->getCpuPtr()->curCycle();
225 case MISCREG_INSTRETH:
226 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
227 miscRegNames[misc_reg], miscRegFile[misc_reg]);
228 return tc->getCpuPtr()->totalInsts() >> 32;
229 case MISCREG_CYCLEH:
230 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n",
231 miscRegNames[misc_reg], miscRegFile[misc_reg]);
232 return tc->getCpuPtr()->curCycle() >> 32;
233 case MISCREG_MHARTID:
234 return 0; // TODO: make this the hardware thread or cpu id
235 default:
236 return readMiscRegNoEffect(misc_reg);
237 }
238 }
239
240 void
241 ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
242 {
243 DPRINTF(RiscvMisc, "Setting CSR %s to 0x%016llx.\n",
244 miscRegNames[misc_reg], val);
245 switch (misc_reg) {
246 case MISCREG_FFLAGS:
247 miscRegFile[MISCREG_FCSR] &= ~0x1F;
248 miscRegFile[MISCREG_FCSR] |= bits(val, 4, 0);
249 break;
250 case MISCREG_FRM:
251 miscRegFile[MISCREG_FCSR] &= ~0x70;
252 miscRegFile[MISCREG_FCSR] |= bits(val, 2, 0) << 5;
253 break;
254 case MISCREG_FCSR:
255 miscRegFile[MISCREG_FCSR] = bits(val, 7, 0);
256 break;
257 default:
258 miscRegFile[misc_reg] = val;
259 break;
260 }
261 }
262
263 void
264 ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
265 {
266 if (bits((unsigned)misc_reg, 11, 10) == 0x3) {
267 warn("Ignoring write to read-only CSR.");
268 return;
269 }
270 setMiscRegNoEffect(misc_reg, val);
271 }
272
273 }
274
275 RiscvISA::ISA *
276 RiscvISAParams::create()
277 {
278 return new RiscvISA::ISA(this);
279 }