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>
| 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>
|
35 36#include "arch/riscv/registers.hh" 37#include "base/bitfield.hh" 38#include "cpu/base.hh" 39#include "debug/RiscvMisc.hh" 40#include "params/RiscvISA.hh" 41#include "sim/core.hh" 42#include "sim/pseudo_inst.hh" 43 44namespace RiscvISA 45{ 46
| 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
|
47std::map<int, std::string> ISA::miscRegNames = { 48 {MISCREG_FFLAGS, "fflags"}, 49 {MISCREG_FRM, "frm"}, 50 {MISCREG_FCSR, "fcsr"}, 51 {MISCREG_CYCLE, "cycle"}, 52 {MISCREG_TIME, "time"}, 53 {MISCREG_INSTRET, "instret"}, 54 {MISCREG_CYCLEH, "cycleh"}, 55 {MISCREG_TIMEH, "timeh"}, 56 {MISCREG_INSTRETH, "instreth"},
| 48ISA::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"},
|
57
| 68
|
58 {MISCREG_SSTATUS, "sstatus"}, 59 {MISCREG_STVEC, "stvec"}, 60 {MISCREG_SIE, "sie"}, 61 {MISCREG_STIMECMP, "stimecmp"}, 62 {MISCREG_STIME, "stime"}, 63 {MISCREG_STIMEH, "stimeh"}, 64 {MISCREG_SSCRATCH, "sscratch"}, 65 {MISCREG_SEPC, "sepc"}, 66 {MISCREG_SCAUSE, "scause"}, 67 {MISCREG_SBADADDR, "sbadaddr"}, 68 {MISCREG_SIP, "sip"}, 69 {MISCREG_SPTBR, "sptbr"}, 70 {MISCREG_SASID, "sasid"}, 71 {MISCREG_CYCLEW, "cyclew"}, 72 {MISCREG_TIMEW, "timew"}, 73 {MISCREG_INSTRETW, "instretw"}, 74 {MISCREG_CYCLEHW, "cyclehw"}, 75 {MISCREG_TIMEHW, "timehw"}, 76 {MISCREG_INSTRETHW, "instrethw"},
| 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"},
|
77
| 80
|
78 {MISCREG_HSTATUS, "hstatus"}, 79 {MISCREG_HTVEC, "htvec"}, 80 {MISCREG_HTDELEG, "htdeleg"}, 81 {MISCREG_HTIMECMP, "htimecmp"}, 82 {MISCREG_HTIME, "htime"}, 83 {MISCREG_HTIMEH, "htimeh"}, 84 {MISCREG_HSCRATCH, "hscratch"}, 85 {MISCREG_HEPC, "hepc"}, 86 {MISCREG_HCAUSE, "hcause"}, 87 {MISCREG_HBADADDR, "hbadaddr"}, 88 {MISCREG_STIMEW, "stimew"}, 89 {MISCREG_STIMEHW, "stimehw"},
| 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"},
|
90
| 91
|
91 {MISCREG_MCPUID, "mcpuid"}, 92 {MISCREG_MIMPID, "mimpid"}, 93 {MISCREG_MHARTID, "mhartid"}, 94 {MISCREG_MSTATUS, "mstatus"}, 95 {MISCREG_MTVEC, "mtvec"}, 96 {MISCREG_MTDELEG, "mtdeleg"}, 97 {MISCREG_MIE, "mie"}, 98 {MISCREG_MTIMECMP, "mtimecmp"}, 99 {MISCREG_MTIME, "mtime"}, 100 {MISCREG_MTIMEH, "mtimeh"}, 101 {MISCREG_MSCRATCH, "mscratch"}, 102 {MISCREG_MEPC, "mepc"}, 103 {MISCREG_MCAUSE, "mcause"}, 104 {MISCREG_MBADADDR, "mbadaddr"}, 105 {MISCREG_MIP, "mip"}, 106 {MISCREG_MBASE, "mbase"}, 107 {MISCREG_MBOUND, "mbound"}, 108 {MISCREG_MIBASE, "mibase"}, 109 {MISCREG_MIBOUND, "mibound"}, 110 {MISCREG_MDBASE, "mdbase"}, 111 {MISCREG_MDBOUND, "mdbound"}, 112 {MISCREG_HTIMEW, "htimew"}, 113 {MISCREG_HTIMEHW, "htimehw"}, 114 {MISCREG_MTOHOST, "mtohost"}, 115 {MISCREG_MFROMHOST, "mfromhost"} 116};
| 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"},
|
117
| 118
|
118ISA::ISA(Params *p) : SimObject(p) 119{
| 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
|
120 miscRegFile.resize(NumMiscRegs); 121 clear(); 122} 123 124const RiscvISAParams * 125ISA::params() const 126{ 127 return dynamic_cast<const Params *>(_params); 128} 129 130void ISA::clear() 131{ 132 std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
| 156 miscRegFile.resize(NumMiscRegs); 157 clear(); 158} 159 160const RiscvISAParams * 161ISA::params() const 162{ 163 return dynamic_cast<const Params *>(_params); 164} 165 166void 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;
|
133} 134 135 136MiscReg 137ISA::readMiscRegNoEffect(int misc_reg) const 138{
| 174} 175 176 177MiscReg 178ISA::readMiscRegNoEffect(int misc_reg) const 179{
|
139 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", miscRegNames[misc_reg], 140 miscRegFile[misc_reg]);
| 180 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", 181 miscRegNames.at(misc_reg), miscRegFile[misc_reg]);
|
141 switch (misc_reg) { 142 case MISCREG_FFLAGS: 143 return bits(miscRegFile[MISCREG_FCSR], 4, 0); 144 case MISCREG_FRM: 145 return bits(miscRegFile[MISCREG_FCSR], 7, 5); 146 case MISCREG_FCSR: 147 return bits(miscRegFile[MISCREG_FCSR], 31, 0); 148 case MISCREG_CYCLE: 149 warn("Use readMiscReg to read the cycle CSR."); 150 return 0; 151 case MISCREG_TIME: 152 return std::time(nullptr); 153 case MISCREG_INSTRET: 154 warn("Use readMiscReg to read the instret CSR."); 155 return 0; 156 case MISCREG_CYCLEH: 157 warn("Use readMiscReg to read the cycleh CSR."); 158 return 0; 159 case MISCREG_TIMEH: 160 return std::time(nullptr) >> 32; 161 case MISCREG_INSTRETH: 162 warn("Use readMiscReg to read the instreth CSR."); 163 return 0;
| 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;
|
164 default: 165 return miscRegFile[misc_reg]; 166 } 167} 168 169MiscReg 170ISA::readMiscReg(int misc_reg, ThreadContext *tc) 171{ 172 switch (misc_reg) { 173 case MISCREG_INSTRET: 174 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", 175 miscRegNames[misc_reg], miscRegFile[misc_reg]); 176 return tc->getCpuPtr()->totalInsts(); 177 case MISCREG_CYCLE: 178 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", 179 miscRegNames[misc_reg], miscRegFile[misc_reg]); 180 return tc->getCpuPtr()->curCycle(); 181 case MISCREG_INSTRETH: 182 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", 183 miscRegNames[misc_reg], miscRegFile[misc_reg]); 184 return tc->getCpuPtr()->totalInsts() >> 32; 185 case MISCREG_CYCLEH: 186 DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", 187 miscRegNames[misc_reg], miscRegFile[misc_reg]); 188 return tc->getCpuPtr()->curCycle() >> 32;
| 208 default: 209 return miscRegFile[misc_reg]; 210 } 211} 212 213MiscReg 214ISA::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
|
189 default: 190 return readMiscRegNoEffect(misc_reg); 191 } 192} 193 194void 195ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val) 196{ 197 DPRINTF(RiscvMisc, "Setting CSR %s to 0x%016llx.\n",
| 235 default: 236 return readMiscRegNoEffect(misc_reg); 237 } 238} 239 240void 241ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val) 242{ 243 DPRINTF(RiscvMisc, "Setting CSR %s to 0x%016llx.\n",
|
198 miscRegNames[misc_reg], miscRegNames[misc_reg], val);
| 244 miscRegNames[misc_reg], val);
|
199 switch (misc_reg) { 200 case MISCREG_FFLAGS: 201 miscRegFile[MISCREG_FCSR] &= ~0x1F; 202 miscRegFile[MISCREG_FCSR] |= bits(val, 4, 0); 203 break; 204 case MISCREG_FRM: 205 miscRegFile[MISCREG_FCSR] &= ~0x70; 206 miscRegFile[MISCREG_FCSR] |= bits(val, 2, 0) << 5; 207 break; 208 case MISCREG_FCSR: 209 miscRegFile[MISCREG_FCSR] = bits(val, 7, 0); 210 break; 211 default: 212 miscRegFile[misc_reg] = val; 213 break; 214 } 215} 216 217void 218ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) 219{ 220 if (bits((unsigned)misc_reg, 11, 10) == 0x3) { 221 warn("Ignoring write to read-only CSR."); 222 return; 223 } 224 setMiscRegNoEffect(misc_reg, val); 225} 226 227} 228 229RiscvISA::ISA * 230RiscvISAParams::create() 231{ 232 return new RiscvISA::ISA(this); 233}
| 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 263void 264ISA::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 275RiscvISA::ISA * 276RiscvISAParams::create() 277{ 278 return new RiscvISA::ISA(this); 279}
|