Browse Source

Remove MTIME[CMP]; add RTC device

pull/40/merge
Andrew Waterman 10 years ago
parent
commit
a9c5b05eca
  1. 18
      riscv/devices.cc
  2. 16
      riscv/devices.h
  3. 8
      riscv/encoding.h
  4. 17
      riscv/processor.cc
  5. 2
      riscv/processor.h
  6. 2
      riscv/riscv.mk.in
  7. 19
      riscv/rom.cc
  8. 34
      riscv/rtc.cc
  9. 15
      riscv/sim.cc
  10. 3
      riscv/sim.h
  11. 1
      spike_main/disasm.cc

18
riscv/devices.cc

@ -20,21 +20,3 @@ bool bus_t::store(reg_t addr, size_t len, const uint8_t* bytes)
return false;
return it->second->store(addr - -it->first, len, bytes);
}
rom_device_t::rom_device_t(std::vector<char> data)
: data(data)
{
}
bool rom_device_t::load(reg_t addr, size_t len, uint8_t* bytes)
{
if (addr + len > data.size())
return false;
memcpy(bytes, &data[addr], len);
return true;
}
bool rom_device_t::store(reg_t addr, size_t len, const uint8_t* bytes)
{
return false;
}

16
riscv/devices.h

@ -5,6 +5,8 @@
#include <map>
#include <vector>
class processor_t;
class abstract_device_t {
public:
virtual bool load(reg_t addr, size_t len, uint8_t* bytes) = 0;
@ -27,8 +29,22 @@ class rom_device_t : public abstract_device_t {
rom_device_t(std::vector<char> data);
bool load(reg_t addr, size_t len, uint8_t* bytes);
bool store(reg_t addr, size_t len, const uint8_t* bytes);
const std::vector<char>& contents() { return data; }
private:
std::vector<char> data;
};
class rtc_t : public abstract_device_t {
public:
rtc_t(std::vector<processor_t*>&);
bool load(reg_t addr, size_t len, uint8_t* bytes);
bool store(reg_t addr, size_t len, const uint8_t* bytes);
size_t size() { return regs.size() * sizeof(regs[0]); }
void increment(reg_t inc);
private:
std::vector<processor_t*>& procs;
std::vector<uint64_t> regs;
uint64_t time() { return regs[0]; }
};
#endif

8
riscv/encoding.h

@ -653,7 +653,6 @@
#define CSR_MIDELEG 0x303
#define CSR_MIE 0x304
#define CSR_MTVEC 0x305
#define CSR_MTIMECMP 0x321
#define CSR_MSCRATCH 0x340
#define CSR_MEPC 0x341
#define CSR_MCAUSE 0x342
@ -669,7 +668,6 @@
#define CSR_MSTIME_DELTA 0x705
#define CSR_MSINSTRET_DELTA 0x706
#define CSR_MCYCLE 0xf00
#define CSR_MTIME 0xf01
#define CSR_MINSTRET 0xf02
#define CSR_MISA 0xf10
#define CSR_MVENDORID 0xf11
@ -683,7 +681,6 @@
#define CSR_CYCLEH 0xc80
#define CSR_TIMEH 0xc81
#define CSR_INSTRETH 0xc82
#define CSR_MTIMECMPH 0x361
#define CSR_MUCYCLE_DELTAH 0x780
#define CSR_MUTIME_DELTAH 0x781
#define CSR_MUINSTRET_DELTAH 0x782
@ -691,7 +688,6 @@
#define CSR_MSTIME_DELTAH 0x785
#define CSR_MSINSTRET_DELTAH 0x786
#define CSR_MCYCLEH 0xf80
#define CSR_MTIMEH 0xf81
#define CSR_MINSTRETH 0xf82
#define CAUSE_MISALIGNED_FETCH 0x0
#define CAUSE_FAULT_FETCH 0x1
@ -961,7 +957,6 @@ DECLARE_CSR(medeleg, CSR_MEDELEG)
DECLARE_CSR(mideleg, CSR_MIDELEG)
DECLARE_CSR(mie, CSR_MIE)
DECLARE_CSR(mtvec, CSR_MTVEC)
DECLARE_CSR(mtimecmp, CSR_MTIMECMP)
DECLARE_CSR(mscratch, CSR_MSCRATCH)
DECLARE_CSR(mepc, CSR_MEPC)
DECLARE_CSR(mcause, CSR_MCAUSE)
@ -977,7 +972,6 @@ DECLARE_CSR(mscycle_delta, CSR_MSCYCLE_DELTA)
DECLARE_CSR(mstime_delta, CSR_MSTIME_DELTA)
DECLARE_CSR(msinstret_delta, CSR_MSINSTRET_DELTA)
DECLARE_CSR(mcycle, CSR_MCYCLE)
DECLARE_CSR(mtime, CSR_MTIME)
DECLARE_CSR(minstret, CSR_MINSTRET)
DECLARE_CSR(misa, CSR_MISA)
DECLARE_CSR(mvendorid, CSR_MVENDORID)
@ -991,7 +985,6 @@ DECLARE_CSR(mreset, CSR_MRESET)
DECLARE_CSR(cycleh, CSR_CYCLEH)
DECLARE_CSR(timeh, CSR_TIMEH)
DECLARE_CSR(instreth, CSR_INSTRETH)
DECLARE_CSR(mtimecmph, CSR_MTIMECMPH)
DECLARE_CSR(mucycle_deltah, CSR_MUCYCLE_DELTAH)
DECLARE_CSR(mutime_deltah, CSR_MUTIME_DELTAH)
DECLARE_CSR(muinstret_deltah, CSR_MUINSTRET_DELTAH)
@ -999,7 +992,6 @@ DECLARE_CSR(mscycle_deltah, CSR_MSCYCLE_DELTAH)
DECLARE_CSR(mstime_deltah, CSR_MSTIME_DELTAH)
DECLARE_CSR(msinstret_deltah, CSR_MSINSTRET_DELTAH)
DECLARE_CSR(mcycleh, CSR_MCYCLEH)
DECLARE_CSR(mtimeh, CSR_MTIMEH)
DECLARE_CSR(minstreth, CSR_MINSTRETH)
#endif
#ifdef DECLARE_CAUSE

17
riscv/processor.cc

@ -165,8 +165,6 @@ static int ctz(reg_t val)
void processor_t::take_interrupt()
{
check_timer();
reg_t pending_interrupts = state.mip & state.mie;
reg_t mie = get_field(state.mstatus, MSTATUS_MIE);
@ -181,12 +179,6 @@ void processor_t::take_interrupt()
raise_interrupt(ctz(enabled_interrupts));
}
void processor_t::check_timer()
{
if (sim->rtc >= state.mtimecmp)
state.mip |= MIP_MTIP;
}
static bool validate_priv(reg_t priv)
{
return priv == PRV_U || priv == PRV_S || priv == PRV_M;
@ -355,10 +347,6 @@ void processor_t::set_csr(int which, reg_t val)
case CSR_MSCRATCH: state.mscratch = val; break;
case CSR_MCAUSE: state.mcause = val; break;
case CSR_MBADADDR: state.mbadaddr = val; break;
case CSR_MTIMECMP:
state.mip &= ~MIP_MTIP;
state.mtimecmp = val;
break;
case CSR_MTOHOST:
if (state.tohost == 0)
state.tohost = val;
@ -415,10 +403,8 @@ reg_t processor_t::get_csr(int which)
case CSR_MSCYCLE_DELTAH: if (xlen > 32) break; else return 0;
case CSR_MSTIME_DELTAH: if (xlen > 32) break; else return 0;
case CSR_MSINSTRET_DELTAH: if (xlen > 32) break; else return 0;
case CSR_MTIME: return sim->rtc;
case CSR_MCYCLE: return state.minstret;
case CSR_MINSTRET: return state.minstret;
case CSR_MTIMEH: if (xlen > 32) break; else return sim->rtc >> 32;
case CSR_MCYCLEH: if (xlen > 32) break; else return state.minstret >> 32;
case CSR_MINSTRETH: if (xlen > 32) break; else return state.minstret >> 32;
case CSR_SSTATUS: {
@ -450,7 +436,6 @@ reg_t processor_t::get_csr(int which)
case CSR_MSCRATCH: return state.mscratch;
case CSR_MCAUSE: return state.mcause;
case CSR_MBADADDR: return state.mbadaddr;
case CSR_MTIMECMP: return state.mtimecmp;
case CSR_MISA: return isa;
case CSR_MARCHID: return 0;
case CSR_MIMPID: return 0;
@ -465,7 +450,7 @@ reg_t processor_t::get_csr(int which)
case CSR_MFROMHOST:
sim->get_htif()->tick(); // not necessary, but faster
return state.fromhost;
case CSR_MCFGADDR: return sim->memsz;
case CSR_MCFGADDR: return sim->config_string_addr;
}
throw trap_illegal_instruction();
}

2
riscv/processor.h

@ -45,7 +45,6 @@ struct state_t
reg_t mstatus;
reg_t mepc;
reg_t mbadaddr;
reg_t mtimecmp;
reg_t mscratch;
reg_t mcause;
reg_t minstret;
@ -136,6 +135,7 @@ private:
friend class sim_t;
friend class mmu_t;
friend class rtc_t;
friend class extension_t;
void parse_isa_string(const char* isa);

2
riscv/riscv.mk.in

@ -41,6 +41,8 @@ riscv_srcs = \
rocc.cc \
regnames.cc \
devices.cc \
rom.cc \
rtc.cc \
$(riscv_gen_srcs) \
riscv_test_srcs =

19
riscv/rom.cc

@ -0,0 +1,19 @@
#include "devices.h"
rom_device_t::rom_device_t(std::vector<char> data)
: data(data)
{
}
bool rom_device_t::load(reg_t addr, size_t len, uint8_t* bytes)
{
if (addr + len > data.size())
return false;
memcpy(bytes, &data[addr], len);
return true;
}
bool rom_device_t::store(reg_t addr, size_t len, const uint8_t* bytes)
{
return false;
}

34
riscv/rtc.cc

@ -0,0 +1,34 @@
#include "devices.h"
#include "processor.h"
rtc_t::rtc_t(std::vector<processor_t*>& procs)
: procs(procs), regs(1 + procs.size())
{
}
bool rtc_t::load(reg_t addr, size_t len, uint8_t* bytes)
{
if (addr + len > size())
return false;
memcpy(bytes, (uint8_t*)&regs[0] + addr, len);
return true;
}
bool rtc_t::store(reg_t addr, size_t len, const uint8_t* bytes)
{
if (addr + len > size() || addr < 8)
return false;
memcpy((uint8_t*)&regs[0] + addr, bytes, len);
increment(0);
return true;
}
void rtc_t::increment(reg_t inc)
{
regs[0] += inc;
for (size_t i = 0; i < procs.size(); i++) {
procs[i]->state.mip &= ~MIP_MTIP;
if (regs[0] >= regs[1+i])
procs[i]->state.mip |= MIP_MTIP;
}
}

15
riscv/sim.cc

@ -22,7 +22,7 @@ static void handle_signal(int sig)
sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb,
const std::vector<std::string>& args)
: htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))),
rtc(0), current_step(0), current_proc(0), debug(false)
current_step(0), current_proc(0), debug(false)
{
signal(SIGINT, &handle_signal);
// allocate target machine's memory, shrinking it as necessary
@ -45,6 +45,7 @@ sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb,
for (size_t i = 0; i < procs.size(); i++)
procs[i] = new processor_t(isa, this, i);
rtc.reset(new rtc_t(procs));
make_config_string();
}
@ -94,7 +95,7 @@ void sim_t::step(size_t n)
procs[current_proc]->yield_load_reservation();
if (++current_proc == procs.size()) {
current_proc = 0;
rtc += INTERLEAVE / INSNS_PER_RTC_TICK;
rtc->increment(INTERLEAVE / INSNS_PER_RTC_TICK);
}
htif->tick();
@ -161,12 +162,19 @@ void sim_t::make_config_string()
size_t device_tree_addr = memsz;
size_t cpu_addr = memsz + csr_size;
reg_t rtc_addr = memsz;
bus.add_device(rtc_addr, rtc.get());
config_string_addr = rtc_addr + rtc->size();
std::stringstream s;
s << std::hex <<
"platform {\n"
" vendor ucb;\n"
" arch spike;\n"
"};\n"
"rtc {\n"
" addr 0x" << rtc_addr << ";\n"
"};\n"
"ram {\n"
" 0 {\n"
" addr 0;\n"
@ -180,6 +188,7 @@ void sim_t::make_config_string()
" " << "0 {\n" << // hart 0 on core i
" isa " << procs[i]->isa_string << ";\n"
" addr 0x" << cpu_addr << ";\n"
" timecmp 0x" << (rtc_addr + 8*(1+i)) << ";\n"
" };\n"
" };\n";
bus.add_device(cpu_addr, procs[i]);
@ -192,5 +201,5 @@ void sim_t::make_config_string()
vec.push_back(0);
assert(vec.size() <= csr_size);
config_string.reset(new rom_device_t(vec));
bus.add_device(memsz, config_string.get());
bus.add_device(config_string_addr, config_string.get());
}

3
riscv/sim.h

@ -44,13 +44,14 @@ private:
mmu_t* debug_mmu; // debug port into main memory
std::vector<processor_t*> procs;
std::unique_ptr<rom_device_t> config_string;
std::unique_ptr<rtc_t> rtc;
reg_t config_string_addr;
bus_t bus;
processor_t* get_core(const std::string& i);
void step(size_t n); // step through simulation
static const size_t INTERLEAVE = 5000;
static const size_t INSNS_PER_RTC_TICK = 100; // 10 MHz clock for 1 BIPS core
reg_t rtc;
size_t current_step;
size_t current_proc;
bool debug;

1
spike_main/disasm.cc

@ -7,7 +7,6 @@
#include <sstream>
#include <stdlib.h>
struct : public arg_t {
std::string to_string(insn_t insn) const {
return std::to_string((int)insn.i_imm()) + '(' + xpr_name[insn.rs1()] + ')';

Loading…
Cancel
Save