isa.cc (12695:3df197da6069) isa.cc (13548:b76f99d052bb)
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
45namespace RiscvISA
46{
47
48ISA::ISA(Params *p) : SimObject(p)
49{
50 miscRegFile.resize(NumMiscRegs);
51 clear();
52}
53
54const RiscvISAParams *
55ISA::params() const
56{
57 return dynamic_cast<const Params *>(_params);
58}
59
60void ISA::clear()
61{
62 std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
63
64 miscRegFile[MISCREG_PRV] = PRV_M;
65 miscRegFile[MISCREG_ISA] = (2ULL << MXL_OFFSET) | 0x14112D;
66 miscRegFile[MISCREG_VENDORID] = 0;
67 miscRegFile[MISCREG_ARCHID] = 0;
68 miscRegFile[MISCREG_IMPID] = 0;
69 miscRegFile[MISCREG_STATUS] = (2ULL << UXL_OFFSET) | (2ULL << SXL_OFFSET) |
70 (1ULL << FS_OFFSET);
71 miscRegFile[MISCREG_MCOUNTEREN] = 0x7;
72 miscRegFile[MISCREG_SCOUNTEREN] = 0x7;
73}
74
75bool
76ISA::hpmCounterEnabled(int misc_reg) const
77{
78 int hpmcounter = misc_reg - MISCREG_CYCLE;
79 if (hpmcounter < 0 || hpmcounter > 31)
80 panic("Illegal HPM counter %d\n", hpmcounter);
81 int counteren;
82 switch (readMiscRegNoEffect(MISCREG_PRV)) {
83 case PRV_M:
84 return true;
85 case PRV_S:
86 counteren = MISCREG_MCOUNTEREN;
87 break;
88 case PRV_U:
89 counteren = MISCREG_SCOUNTEREN;
90 break;
91 default:
92 panic("Unknown privilege level %d\n", miscRegFile[MISCREG_PRV]);
93 return false;
94 }
95 return (miscRegFile[counteren] & (1ULL << (hpmcounter))) > 0;
96}
97
98MiscReg
99ISA::readMiscRegNoEffect(int misc_reg) const
100{
101 if (misc_reg > NumMiscRegs || misc_reg < 0) {
102 // Illegal CSR
103 panic("Illegal CSR index %#x\n", misc_reg);
104 return -1;
105 }
106 DPRINTF(RiscvMisc, "Reading MiscReg %d: %#llx.\n", misc_reg,
107 miscRegFile[misc_reg]);
108 return miscRegFile[misc_reg];
109}
110
111MiscReg
112ISA::readMiscReg(int misc_reg, ThreadContext *tc)
113{
114 switch (misc_reg) {
115 case MISCREG_CYCLE:
116 if (hpmCounterEnabled(MISCREG_CYCLE)) {
117 DPRINTF(RiscvMisc, "Cycle counter at: %llu.\n",
118 tc->getCpuPtr()->curCycle());
119 return tc->getCpuPtr()->curCycle();
120 } else {
121 warn("Cycle counter disabled.\n");
122 return 0;
123 }
124 case MISCREG_TIME:
125 if (hpmCounterEnabled(MISCREG_TIME)) {
126 DPRINTF(RiscvMisc, "Wall-clock counter at: %llu.\n",
127 std::time(nullptr));
128 return std::time(nullptr);
129 } else {
130 warn("Wall clock disabled.\n");
131 return 0;
132 }
133 case MISCREG_INSTRET:
134 if (hpmCounterEnabled(MISCREG_INSTRET)) {
135 DPRINTF(RiscvMisc, "Instruction counter at: %llu.\n",
136 tc->getCpuPtr()->totalInsts());
137 return tc->getCpuPtr()->totalInsts();
138 } else {
139 warn("Instruction counter disabled.\n");
140 return 0;
141 }
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
45namespace RiscvISA
46{
47
48ISA::ISA(Params *p) : SimObject(p)
49{
50 miscRegFile.resize(NumMiscRegs);
51 clear();
52}
53
54const RiscvISAParams *
55ISA::params() const
56{
57 return dynamic_cast<const Params *>(_params);
58}
59
60void ISA::clear()
61{
62 std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
63
64 miscRegFile[MISCREG_PRV] = PRV_M;
65 miscRegFile[MISCREG_ISA] = (2ULL << MXL_OFFSET) | 0x14112D;
66 miscRegFile[MISCREG_VENDORID] = 0;
67 miscRegFile[MISCREG_ARCHID] = 0;
68 miscRegFile[MISCREG_IMPID] = 0;
69 miscRegFile[MISCREG_STATUS] = (2ULL << UXL_OFFSET) | (2ULL << SXL_OFFSET) |
70 (1ULL << FS_OFFSET);
71 miscRegFile[MISCREG_MCOUNTEREN] = 0x7;
72 miscRegFile[MISCREG_SCOUNTEREN] = 0x7;
73}
74
75bool
76ISA::hpmCounterEnabled(int misc_reg) const
77{
78 int hpmcounter = misc_reg - MISCREG_CYCLE;
79 if (hpmcounter < 0 || hpmcounter > 31)
80 panic("Illegal HPM counter %d\n", hpmcounter);
81 int counteren;
82 switch (readMiscRegNoEffect(MISCREG_PRV)) {
83 case PRV_M:
84 return true;
85 case PRV_S:
86 counteren = MISCREG_MCOUNTEREN;
87 break;
88 case PRV_U:
89 counteren = MISCREG_SCOUNTEREN;
90 break;
91 default:
92 panic("Unknown privilege level %d\n", miscRegFile[MISCREG_PRV]);
93 return false;
94 }
95 return (miscRegFile[counteren] & (1ULL << (hpmcounter))) > 0;
96}
97
98MiscReg
99ISA::readMiscRegNoEffect(int misc_reg) const
100{
101 if (misc_reg > NumMiscRegs || misc_reg < 0) {
102 // Illegal CSR
103 panic("Illegal CSR index %#x\n", misc_reg);
104 return -1;
105 }
106 DPRINTF(RiscvMisc, "Reading MiscReg %d: %#llx.\n", misc_reg,
107 miscRegFile[misc_reg]);
108 return miscRegFile[misc_reg];
109}
110
111MiscReg
112ISA::readMiscReg(int misc_reg, ThreadContext *tc)
113{
114 switch (misc_reg) {
115 case MISCREG_CYCLE:
116 if (hpmCounterEnabled(MISCREG_CYCLE)) {
117 DPRINTF(RiscvMisc, "Cycle counter at: %llu.\n",
118 tc->getCpuPtr()->curCycle());
119 return tc->getCpuPtr()->curCycle();
120 } else {
121 warn("Cycle counter disabled.\n");
122 return 0;
123 }
124 case MISCREG_TIME:
125 if (hpmCounterEnabled(MISCREG_TIME)) {
126 DPRINTF(RiscvMisc, "Wall-clock counter at: %llu.\n",
127 std::time(nullptr));
128 return std::time(nullptr);
129 } else {
130 warn("Wall clock disabled.\n");
131 return 0;
132 }
133 case MISCREG_INSTRET:
134 if (hpmCounterEnabled(MISCREG_INSTRET)) {
135 DPRINTF(RiscvMisc, "Instruction counter at: %llu.\n",
136 tc->getCpuPtr()->totalInsts());
137 return tc->getCpuPtr()->totalInsts();
138 } else {
139 warn("Instruction counter disabled.\n");
140 return 0;
141 }
142 case MISCREG_IP:
143 return tc->getCpuPtr()->getInterruptController(tc->threadId())
144 ->readIP();
145 case MISCREG_IE:
146 return tc->getCpuPtr()->getInterruptController(tc->threadId())
147 ->readIE();
142 default:
143 // Try reading HPM counters
144 // As a placeholder, all HPM counters are just cycle counters
145 if (misc_reg >= MISCREG_HPMCOUNTER03 &&
146 misc_reg <= MISCREG_HPMCOUNTER31) {
147 if (hpmCounterEnabled(misc_reg)) {
148 DPRINTF(RiscvMisc, "HPM counter %d: %llu.\n",
149 misc_reg - MISCREG_CYCLE, tc->getCpuPtr()->curCycle());
150 return tc->getCpuPtr()->curCycle();
151 } else {
152 warn("HPM counter %d disabled.\n", misc_reg - MISCREG_CYCLE);
153 return 0;
154 }
155 }
156 return readMiscRegNoEffect(misc_reg);
157 }
158}
159
160void
161ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
162{
163 if (misc_reg > NumMiscRegs || misc_reg < 0) {
164 // Illegal CSR
165 panic("Illegal CSR index %#x\n", misc_reg);
166 }
167 DPRINTF(RiscvMisc, "Setting MiscReg %d to %#x.\n", misc_reg, val);
168 miscRegFile[misc_reg] = val;
169}
170
171void
172ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
173{
174 if (misc_reg >= MISCREG_CYCLE && misc_reg <= MISCREG_HPMCOUNTER31) {
175 // Ignore writes to HPM counters for now
176 warn("Ignoring write to %s.\n", CSRData.at(misc_reg).name);
177 } else {
148 default:
149 // Try reading HPM counters
150 // As a placeholder, all HPM counters are just cycle counters
151 if (misc_reg >= MISCREG_HPMCOUNTER03 &&
152 misc_reg <= MISCREG_HPMCOUNTER31) {
153 if (hpmCounterEnabled(misc_reg)) {
154 DPRINTF(RiscvMisc, "HPM counter %d: %llu.\n",
155 misc_reg - MISCREG_CYCLE, tc->getCpuPtr()->curCycle());
156 return tc->getCpuPtr()->curCycle();
157 } else {
158 warn("HPM counter %d disabled.\n", misc_reg - MISCREG_CYCLE);
159 return 0;
160 }
161 }
162 return readMiscRegNoEffect(misc_reg);
163 }
164}
165
166void
167ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
168{
169 if (misc_reg > NumMiscRegs || misc_reg < 0) {
170 // Illegal CSR
171 panic("Illegal CSR index %#x\n", misc_reg);
172 }
173 DPRINTF(RiscvMisc, "Setting MiscReg %d to %#x.\n", misc_reg, val);
174 miscRegFile[misc_reg] = val;
175}
176
177void
178ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
179{
180 if (misc_reg >= MISCREG_CYCLE && misc_reg <= MISCREG_HPMCOUNTER31) {
181 // Ignore writes to HPM counters for now
182 warn("Ignoring write to %s.\n", CSRData.at(misc_reg).name);
183 } else {
178 setMiscRegNoEffect(misc_reg, val);
184 switch (misc_reg) {
185 case MISCREG_IP:
186 return tc->getCpuPtr()->getInterruptController(tc->threadId())
187 ->setIP(val);
188 case MISCREG_IE:
189 return tc->getCpuPtr()->getInterruptController(tc->threadId())
190 ->setIE(val);
191 default:
192 setMiscRegNoEffect(misc_reg, val);
193 }
179 }
180}
181
182}
183
184RiscvISA::ISA *
185RiscvISAParams::create()
186{
187 return new RiscvISA::ISA(this);
188}
194 }
195}
196
197}
198
199RiscvISA::ISA *
200RiscvISAParams::create()
201{
202 return new RiscvISA::ISA(this);
203}