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 false;
return it->second->store(addr - -it->first, len, bytes); 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 <map>
#include <vector> #include <vector>
class processor_t;
class abstract_device_t { class abstract_device_t {
public: public:
virtual bool load(reg_t addr, size_t len, uint8_t* bytes) = 0; 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); rom_device_t(std::vector<char> data);
bool load(reg_t addr, size_t len, uint8_t* bytes); bool load(reg_t addr, size_t len, uint8_t* bytes);
bool store(reg_t addr, size_t len, const uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes);
const std::vector<char>& contents() { return data; }
private: private:
std::vector<char> data; 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 #endif

8
riscv/encoding.h

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

17
riscv/processor.cc

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

2
riscv/processor.h

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

2
riscv/riscv.mk.in

@ -41,6 +41,8 @@ riscv_srcs = \
rocc.cc \ rocc.cc \
regnames.cc \ regnames.cc \
devices.cc \ devices.cc \
rom.cc \
rtc.cc \
$(riscv_gen_srcs) \ $(riscv_gen_srcs) \
riscv_test_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, sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb,
const std::vector<std::string>& args) const std::vector<std::string>& args)
: htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))), : 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); signal(SIGINT, &handle_signal);
// allocate target machine's memory, shrinking it as necessary // 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++) for (size_t i = 0; i < procs.size(); i++)
procs[i] = new processor_t(isa, this, i); procs[i] = new processor_t(isa, this, i);
rtc.reset(new rtc_t(procs));
make_config_string(); make_config_string();
} }
@ -94,7 +95,7 @@ void sim_t::step(size_t n)
procs[current_proc]->yield_load_reservation(); procs[current_proc]->yield_load_reservation();
if (++current_proc == procs.size()) { if (++current_proc == procs.size()) {
current_proc = 0; current_proc = 0;
rtc += INTERLEAVE / INSNS_PER_RTC_TICK; rtc->increment(INTERLEAVE / INSNS_PER_RTC_TICK);
} }
htif->tick(); htif->tick();
@ -161,12 +162,19 @@ void sim_t::make_config_string()
size_t device_tree_addr = memsz; size_t device_tree_addr = memsz;
size_t cpu_addr = memsz + csr_size; 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; std::stringstream s;
s << std::hex << s << std::hex <<
"platform {\n" "platform {\n"
" vendor ucb;\n" " vendor ucb;\n"
" arch spike;\n" " arch spike;\n"
"};\n" "};\n"
"rtc {\n"
" addr 0x" << rtc_addr << ";\n"
"};\n"
"ram {\n" "ram {\n"
" 0 {\n" " 0 {\n"
" addr 0;\n" " addr 0;\n"
@ -180,6 +188,7 @@ void sim_t::make_config_string()
" " << "0 {\n" << // hart 0 on core i " " << "0 {\n" << // hart 0 on core i
" isa " << procs[i]->isa_string << ";\n" " isa " << procs[i]->isa_string << ";\n"
" addr 0x" << cpu_addr << ";\n" " addr 0x" << cpu_addr << ";\n"
" timecmp 0x" << (rtc_addr + 8*(1+i)) << ";\n"
" };\n" " };\n"
" };\n"; " };\n";
bus.add_device(cpu_addr, procs[i]); bus.add_device(cpu_addr, procs[i]);
@ -192,5 +201,5 @@ void sim_t::make_config_string()
vec.push_back(0); vec.push_back(0);
assert(vec.size() <= csr_size); assert(vec.size() <= csr_size);
config_string.reset(new rom_device_t(vec)); 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 mmu_t* debug_mmu; // debug port into main memory
std::vector<processor_t*> procs; std::vector<processor_t*> procs;
std::unique_ptr<rom_device_t> config_string; std::unique_ptr<rom_device_t> config_string;
std::unique_ptr<rtc_t> rtc;
reg_t config_string_addr;
bus_t bus; bus_t bus;
processor_t* get_core(const std::string& i); processor_t* get_core(const std::string& i);
void step(size_t n); // step through simulation void step(size_t n); // step through simulation
static const size_t INTERLEAVE = 5000; static const size_t INTERLEAVE = 5000;
static const size_t INSNS_PER_RTC_TICK = 100; // 10 MHz clock for 1 BIPS core 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_step;
size_t current_proc; size_t current_proc;
bool debug; bool debug;

1
spike_main/disasm.cc

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

Loading…
Cancel
Save