2 * Copyright (c) 2016 RISC-V Foundation
3 * Copyright (c) 2016 The University of Virginia
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.
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.
29 * Authors: Alec Roelke
31 #include "arch/riscv/isa.hh"
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"
48 ISA::ISA(Params
*p
) : SimObject(p
)
51 {MISCREG_USTATUS
, "ustatus"},
53 {MISCREG_UTVEC
, "utvec"},
54 {MISCREG_USCRATCH
, "uscratch"},
55 {MISCREG_UEPC
, "uepc"},
56 {MISCREG_UCAUSE
, "ucause"},
57 {MISCREG_UBADADDR
, "ubadaddr"},
59 {MISCREG_FFLAGS
, "fflags"},
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"},
69 {MISCREG_SSTATUS
, "sstatus"},
70 {MISCREG_SEDELEG
, "sedeleg"},
71 {MISCREG_SIDELEG
, "sideleg"},
73 {MISCREG_STVEC
, "stvec"},
74 {MISCREG_SSCRATCH
, "sscratch"},
75 {MISCREG_SEPC
, "sepc"},
76 {MISCREG_SCAUSE
, "scause"},
77 {MISCREG_SBADADDR
, "sbadaddr"},
79 {MISCREG_SPTBR
, "sptbr"},
81 {MISCREG_HSTATUS
, "hstatus"},
82 {MISCREG_HEDELEG
, "hedeleg"},
83 {MISCREG_HIDELEG
, "hideleg"},
85 {MISCREG_HTVEC
, "htvec"},
86 {MISCREG_HSCRATCH
, "hscratch"},
87 {MISCREG_HEPC
, "hepc"},
88 {MISCREG_HCAUSE
, "hcause"},
89 {MISCREG_HBADADDR
, "hbadaddr"},
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"},
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"}
127 for (int i
= 0; i
< NumHpmcounter
; i
++)
129 int hpmcounter
= MISCREG_HPMCOUNTER_BASE
+ i
;
130 std::stringstream ss
;
131 ss
<< "hpmcounter" << hpmcounter
;
132 miscRegNames
[hpmcounter
] = ss
.str();
134 for (int i
= 0; i
< NumHpmcounterh
; i
++)
136 int hpmcounterh
= MISCREG_HPMCOUNTERH_BASE
+ i
;
137 std::stringstream ss
;
138 ss
<< "hpmcounterh" << hpmcounterh
;
139 miscRegNames
[hpmcounterh
] = ss
.str();
141 for (int i
= 0; i
< NumMhpmcounter
; i
++)
143 int mhpmcounter
= MISCREG_MHPMCOUNTER_BASE
+ i
;
144 std::stringstream ss
;
145 ss
<< "mhpmcounter" << mhpmcounter
;
146 miscRegNames
[mhpmcounter
] = ss
.str();
148 for (int i
= 0; i
< NumMhpmevent
; i
++)
150 int mhpmevent
= MISCREG_MHPMEVENT_BASE
+ i
;
151 std::stringstream ss
;
152 ss
<< "mhpmcounterh" << mhpmevent
;
153 miscRegNames
[mhpmevent
] = ss
.str();
156 miscRegFile
.resize(NumMiscRegs
);
160 const RiscvISAParams
*
163 return dynamic_cast<const Params
*>(_params
);
168 std::fill(miscRegFile
.begin(), miscRegFile
.end(), 0);
170 miscRegFile
[MISCREG_MVENDORID
] = 0;
171 miscRegFile
[MISCREG_MARCHID
] = 0;
172 miscRegFile
[MISCREG_MIMPID
] = 0;
173 miscRegFile
[MISCREG_MISA
] = 0x8000000000101129ULL
;
178 ISA::readMiscRegNoEffect(int misc_reg
) const
180 DPRINTF(RiscvMisc
, "Reading CSR %s (0x%016llx).\n",
181 miscRegNames
.at(misc_reg
), miscRegFile
[misc_reg
]);
184 return bits(miscRegFile
[MISCREG_FCSR
], 4, 0);
186 return bits(miscRegFile
[MISCREG_FCSR
], 7, 5);
188 return bits(miscRegFile
[MISCREG_FCSR
], 31, 0);
190 warn("Use readMiscReg to read the cycle CSR.");
193 return std::time(nullptr);
194 case MISCREG_INSTRET
:
195 warn("Use readMiscReg to read the instret CSR.");
198 warn("Use readMiscReg to read the cycleh CSR.");
201 return std::time(nullptr) >> 32;
202 case MISCREG_INSTRETH
:
203 warn("Use readMiscReg to read the instreth CSR.");
205 case MISCREG_MHARTID
:
206 warn("Use readMiscReg to read the mhartid CSR.");
209 return miscRegFile
[misc_reg
];
214 ISA::readMiscReg(int misc_reg
, ThreadContext
*tc
)
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();
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;
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
236 return readMiscRegNoEffect(misc_reg
);
241 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
)
243 DPRINTF(RiscvMisc
, "Setting CSR %s to 0x%016llx.\n",
244 miscRegNames
[misc_reg
], val
);
247 miscRegFile
[MISCREG_FCSR
] &= ~0x1F;
248 miscRegFile
[MISCREG_FCSR
] |= bits(val
, 4, 0);
251 miscRegFile
[MISCREG_FCSR
] &= ~0x70;
252 miscRegFile
[MISCREG_FCSR
] |= bits(val
, 2, 0) << 5;
255 miscRegFile
[MISCREG_FCSR
] = bits(val
, 7, 0);
258 miscRegFile
[misc_reg
] = val
;
264 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
, ThreadContext
*tc
)
266 if (bits((unsigned)misc_reg
, 11, 10) == 0x3) {
267 warn("Ignoring write to read-only CSR.");
270 setMiscRegNoEffect(misc_reg
, val
);
276 RiscvISAParams::create()
278 return new RiscvISA::ISA(this);