isa.cc revision 12695
112027Sjungma@eit.uni-kl.de/*
212027Sjungma@eit.uni-kl.de * Copyright (c) 2016 RISC-V Foundation
312027Sjungma@eit.uni-kl.de * Copyright (c) 2016 The University of Virginia
412027Sjungma@eit.uni-kl.de * All rights reserved.
512027Sjungma@eit.uni-kl.de *
612027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without
712027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are
812027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright
912027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer;
1012027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright
1112027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the
1212027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution;
1312027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its
1412027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from
1512027Sjungma@eit.uni-kl.de * this software without specific prior written permission.
1612027Sjungma@eit.uni-kl.de *
1712027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1812027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1912027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2112027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2212027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2312027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2412027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2512027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2612027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2712027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2812027Sjungma@eit.uni-kl.de *
2912027Sjungma@eit.uni-kl.de * Authors: Alec Roelke
3012027Sjungma@eit.uni-kl.de */
3112027Sjungma@eit.uni-kl.de#include "arch/riscv/isa.hh"
3212027Sjungma@eit.uni-kl.de
3312027Sjungma@eit.uni-kl.de#include <ctime>
3412027Sjungma@eit.uni-kl.de#include <set>
3512027Sjungma@eit.uni-kl.de#include <sstream>
3612027Sjungma@eit.uni-kl.de
3712027Sjungma@eit.uni-kl.de#include "arch/riscv/registers.hh"
3812027Sjungma@eit.uni-kl.de#include "base/bitfield.hh"
3912027Sjungma@eit.uni-kl.de#include "cpu/base.hh"
4012027Sjungma@eit.uni-kl.de#include "debug/RiscvMisc.hh"
4112027Sjungma@eit.uni-kl.de#include "params/RiscvISA.hh"
4212027Sjungma@eit.uni-kl.de#include "sim/core.hh"
4312027Sjungma@eit.uni-kl.de#include "sim/pseudo_inst.hh"
4412027Sjungma@eit.uni-kl.de
4512027Sjungma@eit.uni-kl.denamespace RiscvISA
4612027Sjungma@eit.uni-kl.de{
4712027Sjungma@eit.uni-kl.de
4812027Sjungma@eit.uni-kl.deISA::ISA(Params *p) : SimObject(p)
4912027Sjungma@eit.uni-kl.de{
5012027Sjungma@eit.uni-kl.de    miscRegFile.resize(NumMiscRegs);
5112027Sjungma@eit.uni-kl.de    clear();
5212027Sjungma@eit.uni-kl.de}
5312027Sjungma@eit.uni-kl.de
5412027Sjungma@eit.uni-kl.deconst RiscvISAParams *
5512027Sjungma@eit.uni-kl.deISA::params() const
5612027Sjungma@eit.uni-kl.de{
5712027Sjungma@eit.uni-kl.de    return dynamic_cast<const Params *>(_params);
5812027Sjungma@eit.uni-kl.de}
5912027Sjungma@eit.uni-kl.de
6012027Sjungma@eit.uni-kl.devoid ISA::clear()
6112027Sjungma@eit.uni-kl.de{
6212027Sjungma@eit.uni-kl.de    std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
6312027Sjungma@eit.uni-kl.de
6412027Sjungma@eit.uni-kl.de    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      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 {
178        setMiscRegNoEffect(misc_reg, val);
179    }
180}
181
182}
183
184RiscvISA::ISA *
185RiscvISAParams::create()
186{
187    return new RiscvISA::ISA(this);
188}