Browse Source

Support multiple extensions at the same time

pull/646/head
Zitao Fang 6 years ago
committed by Andrew Waterman
parent
commit
3d19864f39
  1. 47
      riscv/processor.cc
  2. 5
      riscv/processor.h
  3. 26
      riscv/rocc.h
  4. 8
      spike_main/spike.cc

47
riscv/processor.cc

@ -24,7 +24,7 @@
processor_t::processor_t(const char* isa, const char* priv, const char* varch,
simif_t* sim, uint32_t id, bool halt_on_reset,
FILE* log_file)
: debug(false), halt_request(HR_NONE), sim(sim), ext(NULL), id(id), xlen(0),
: debug(false), halt_request(HR_NONE), sim(sim), id(id), xlen(0),
histogram_enabled(false), log_commits_enabled(false),
log_file(log_file), halt_on_reset(halt_on_reset),
extension_table(256, false), impl_table(256, false), last_pc(1), executions(1)
@ -39,8 +39,8 @@ processor_t::processor_t(const char* isa, const char* priv, const char* varch,
mmu = new mmu_t(sim, this);
disassembler = new disassembler_t(max_xlen);
if (ext)
for (auto disasm_insn : ext->get_disasms())
for (auto e : custom_extensions)
for (auto disasm_insn : e.second->get_disasms())
disassembler->add_insn(disasm_insn);
set_pmp_granularity(1 << PMP_SHIFT);
@ -425,8 +425,9 @@ reg_t processor_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t newT
void processor_t::set_debug(bool value)
{
debug = value;
if (ext)
ext->set_debug(value);
for (auto e : custom_extensions)
e.second->set_debug(value);
}
void processor_t::set_histogram(bool value)
@ -470,13 +471,33 @@ void processor_t::reset()
set_csr(CSR_PMPCFG0, PMP_R | PMP_W | PMP_X | PMP_NAPOT);
}
if (ext)
ext->reset(); // reset the extension
for (auto e : custom_extensions) // reset any extensions
e.second->reset();
if (sim)
sim->proc_reset(id);
}
extension_t* processor_t::get_extension()
{
switch (custom_extensions.size()) {
case 0: return NULL;
case 1: return custom_extensions.begin()->second;
default:
fprintf(stderr, "processor_t::get_extension() is ambiguous when multiple extensions\n");
fprintf(stderr, "are present!\n");
abort();
}
}
extension_t* processor_t::get_extension(const char* name)
{
auto it = custom_extensions.find(name);
if (it == custom_extensions.end())
abort();
return it->second;
}
void processor_t::set_pmp_num(reg_t n)
{
// check the number of pmp is in a reasonable range
@ -841,7 +862,7 @@ void processor_t::set_csr(int which, reg_t val)
reg_t supervisor_ints = supports_extension('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0;
reg_t vssip_int = supports_extension('H') ? MIP_VSSIP : 0;
reg_t hypervisor_ints = supports_extension('H') ? MIP_HS_MASK : 0;
reg_t coprocessor_ints = (ext != NULL) << IRQ_COP;
reg_t coprocessor_ints = (!custom_extensions.empty()) << IRQ_COP;
reg_t delegable_ints = supervisor_ints | coprocessor_ints;
reg_t all_ints = delegable_ints | hypervisor_ints | MIP_MSIP | MIP_MTIP | MIP_MEIP;
@ -926,7 +947,7 @@ void processor_t::set_csr(int which, reg_t val)
| (has_page ? (MSTATUS_MXR | MSTATUS_SUM | MSTATUS_TVM) : 0)
| (has_fs ? MSTATUS_FS : 0)
| (has_vs ? MSTATUS_VS : 0)
| (ext ? MSTATUS_XS : 0)
| (!custom_extensions.empty() ? MSTATUS_XS : 0)
| (has_gva ? MSTATUS_GVA : 0)
| (has_mpv ? MSTATUS_MPV : 0);
@ -1811,9 +1832,11 @@ void processor_t::register_extension(extension_t* x)
for (auto disasm_insn : x->get_disasms())
disassembler->add_insn(disasm_insn);
if (ext != NULL)
throw std::logic_error("only one extension may be registered");
ext = x;
if (!custom_extensions.insert(std::make_pair(x->name(), x)).second) {
fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name());
abort();
}
x->set_processor(this);
}

5
riscv/processor.h

@ -295,7 +295,8 @@ public:
supports_extension('D') ? 64 :
supports_extension('F') ? 32 : 0;
}
extension_t* get_extension() { return ext; }
extension_t* get_extension();
extension_t* get_extension(const char* name);
bool supports_extension(unsigned char ext) {
if (ext >= 'A' && ext <= 'Z')
return ((state.misa >> (ext - 'A')) & 1);
@ -430,7 +431,7 @@ public:
private:
simif_t* sim;
mmu_t* mmu; // main memory is always accessed via the mmu
extension_t* ext;
std::unordered_map<std::string, extension_t*> custom_extensions;
disassembler_t* disassembler;
state_t state;
uint32_t id;

26
riscv/rocc.h

@ -32,4 +32,30 @@ class rocc_t : public extension_t
std::vector<disasm_insn_t*> get_disasms();
};
#define define_custom_func(type_name, ext_name_str, func_name, method_name) \
static reg_t func_name(processor_t* p, insn_t insn, reg_t pc) \
{ \
type_name* rocc = static_cast<type_name*>(p->get_extension(ext_name_str)); \
rocc_insn_union_t u; \
u.i = insn; \
reg_t xs1 = u.r.xs1 ? RS1 : -1; \
reg_t xs2 = u.r.xs2 ? RS2 : -1; \
reg_t xd = rocc->method_name(u.r, xs1, xs2); \
if (u.r.xd) \
WRITE_RD(xd); \
return pc+4; \
} \
#define push_custom_insn(insn_list, opcode, opcode_mask, func_name_32, func_name_64) \
insn_list.push_back((insn_desc_t){opcode, opcode_mask, func_name_32, func_name_64})
#define ILLEGAL_INSN_FUNC &::illegal_instruction
#define ROCC_OPCODE0 0x0b
#define ROCC_OPCODE1 0x2b
#define ROCC_OPCODE2 0x5b
#define ROCC_OPCODE3 0x7b
#define ROCC_OPCODE_MASK 0x7f
#endif

8
spike_main/spike.cc

@ -45,6 +45,7 @@ static void help(int exit_code = 1)
fprintf(stderr, " The extlib flag for the library must come first.\n");
fprintf(stderr, " --log-cache-miss Generate a log of cache miss\n");
fprintf(stderr, " --extension=<name> Specify RoCC Extension\n");
fprintf(stderr, " This flag can be used multiple times.\n");
fprintf(stderr, " --extlib=<name> Shared library to load\n");
fprintf(stderr, " This flag can be used multiple times.\n");
fprintf(stderr, " --rbb-port=<port> Listen on <port> for remote bitbang connection\n");
@ -226,7 +227,7 @@ int main(int argc, char** argv)
bool log_cache = false;
bool log_commits = false;
const char *log_path = nullptr;
std::function<extension_t*()> extension;
std::vector<std::function<extension_t*()>> extensions;
const char* initrd = NULL;
const char* isa = DEFAULT_ISA;
const char* priv = DEFAULT_PRIV;
@ -323,7 +324,7 @@ int main(int argc, char** argv)
parser.option(0, "priv", 1, [&](const char* s){priv = s;});
parser.option(0, "varch", 1, [&](const char* s){varch = s;});
parser.option(0, "device", 1, device_parser);
parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);});
parser.option(0, "extension", 1, [&](const char* s){extensions.push_back(find_extension(s));});
parser.option(0, "dump-dts", 0, [&](const char *s){dump_dts = true;});
parser.option(0, "disable-dtb", 0, [&](const char *s){dtb_enabled = false;});
parser.option(0, "dtb", 1, [&](const char *s){dtb_file = s;});
@ -419,7 +420,8 @@ int main(int argc, char** argv)
{
if (ic) s.get_core(i)->get_mmu()->register_memtracer(&*ic);
if (dc) s.get_core(i)->get_mmu()->register_memtracer(&*dc);
if (extension) s.get_core(i)->register_extension(extension());
for (auto e : extensions)
s.get_core(i)->register_extension(e());
}
s.set_debug(debug);

Loading…
Cancel
Save