Browse Source

Merge branch 'deepsrc-b_fix_issue183'

pull/182/head
Andrew Waterman 8 years ago
parent
commit
403438d609
  1. 2
      debug_rom/Makefile
  2. 4
      debug_rom/debug_rom.S
  3. 32
      riscv/debug_module.cc
  4. 15
      riscv/debug_module.h
  5. 0
      riscv/debug_rom_defines.h
  6. 16
      riscv/execute.cc
  7. 2
      riscv/insns/c_slli.h
  8. 2
      riscv/insns/c_srai.h
  9. 2
      riscv/insns/c_srli.h
  10. 8
      riscv/interactive.cc
  11. 10
      riscv/jtag_dtm.cc
  12. 2
      riscv/mmu.cc
  13. 4
      riscv/mmu.h
  14. 23
      riscv/processor.cc
  15. 17
      riscv/processor.h
  16. 11
      riscv/sim.cc
  17. 15
      riscv/sim.h
  18. 1
      softfloat/softfloat.mk.in
  19. 10
      spike_main/spike.cc

2
debug_rom/Makefile

@ -7,7 +7,7 @@ OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy
COMPILE = $(CC) -nostdlib -nostartfiles -I.. -Tlink.ld
ELFS = debug_rom
DEPS = debug_rom.S link.ld debug_rom_defines.h
DEPS = debug_rom.S link.ld ../riscv/debug_rom_defines.h ../riscv/encoding.h
all: $(patsubst %,%.h,$(ELFS))

4
debug_rom/debug_rom.S

@ -1,8 +1,8 @@
// See LICENSE.SiFive for license details.
#include "riscv/encoding.h"
#include "debug_rom_defines.h"
#include "riscv/debug_rom_defines.h"
.option norvc
.global entry
.global exception

32
riscv/debug_module.cc

@ -6,7 +6,7 @@
#include "mmu.h"
#include "debug_rom/debug_rom.h"
#include "debug_rom/debug_rom_defines.h"
#include "debug_rom_defines.h"
#if 0
# define D(x) x
@ -16,10 +16,12 @@
///////////////////////// debug_module_t
debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits) :
debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits,
bool require_authentication) :
progbufsize(progbufsize),
program_buffer_bytes(4 + 4*progbufsize),
max_bus_master_bits(max_bus_master_bits),
require_authentication(require_authentication),
debug_progbuf_start(debug_data_start - program_buffer_bytes),
debug_abstract_start(debug_progbuf_start - debug_abstract_size*4),
sim(sim)
@ -65,7 +67,7 @@ void debug_module_t::reset()
dmstatus = {0};
dmstatus.impebreak = true;
dmstatus.authenticated = 1;
dmstatus.authenticated = !require_authentication;
dmstatus.version = 2;
abstractcs = {0};
@ -87,6 +89,8 @@ void debug_module_t::reset()
sbcs.access16 = true;
if (max_bus_master_bits >= 8)
sbcs.access8 = true;
challenge = random();
}
void debug_module_t::add_device(bus_t *bus) {
@ -462,6 +466,9 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
case DMI_SBDATA3:
result = sbdata[3];
break;
case DMI_AUTHDATA:
result = challenge;
break;
default:
result = 0;
D(fprintf(stderr, "Unexpected. Returning Error."));
@ -611,6 +618,11 @@ bool debug_module_t::perform_abstract_command()
bool debug_module_t::dmi_write(unsigned address, uint32_t value)
{
D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value));
if (!dmstatus.authenticated && address != DMI_AUTHDATA &&
address != DMI_DMCONTROL)
return false;
if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) {
unsigned i = address - DMI_DATA0;
if (!abstractcs.busy)
@ -643,6 +655,8 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
if (!dmcontrol.dmactive && get_field(value, DMI_DMCONTROL_DMACTIVE))
reset();
dmcontrol.dmactive = get_field(value, DMI_DMCONTROL_DMACTIVE);
if (!dmstatus.authenticated)
return true;
if (dmcontrol.dmactive) {
dmcontrol.haltreq = get_field(value, DMI_DMCONTROL_HALTREQ);
dmcontrol.resumereq = get_field(value, DMI_DMCONTROL_RESUMEREQ);
@ -725,6 +739,18 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
case DMI_SBDATA3:
sbdata[3] = value;
return true;
case DMI_AUTHDATA:
D(fprintf(stderr, "debug authentication: got 0x%x; 0x%x unlocks\n", value,
challenge + secret));
if (require_authentication) {
if (value == challenge + secret) {
dmstatus.authenticated = true;
} else {
dmstatus.authenticated = false;
challenge = random();
}
}
return true;
}
}
return false;

15
riscv/debug_module.h

@ -74,7 +74,14 @@ typedef struct {
class debug_module_t : public abstract_device_t
{
public:
debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits);
/*
* If require_authentication is true, then a debugger must authenticate as
* follows:
* 1. Read a 32-bit value from authdata:
* 2. Write the value that was read back, plus one, to authdata.
*/
debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits,
bool require_authentication);
~debug_module_t();
void add_device(bus_t *bus);
@ -96,7 +103,8 @@ class debug_module_t : public abstract_device_t
// Actual size of the program buffer, which is 1 word bigger than we let on
// to implement the implicit ebreak at the end.
unsigned program_buffer_bytes;
unsigned max_bus_master_bits ;
unsigned max_bus_master_bits;
bool require_authentication;
static const unsigned debug_data_start = 0x380;
unsigned debug_progbuf_start;
@ -134,6 +142,9 @@ class debug_module_t : public abstract_device_t
uint32_t sbaddress[4];
uint32_t sbdata[4];
uint32_t challenge;
const uint32_t secret = 1;
processor_t *current_proc() const;
void reset();
bool perform_abstract_command();

0
debug_rom/debug_rom_defines.h → riscv/debug_rom_defines.h

16
riscv/execute.cc

@ -2,7 +2,6 @@
#include "processor.h"
#include "mmu.h"
#include "sim.h"
#include <cassert>
@ -129,6 +128,13 @@ void processor_t::step(size_t n)
{
while (instret < n)
{
if (unlikely(!state.serialized && state.single_step == state.STEP_STEPPED)) {
state.single_step = state.STEP_NONE;
enter_debug_mode(DCSR_CAUSE_STEP);
// enter_debug_mode changed state.pc, so we can't just continue.
break;
}
if (unlikely(state.single_step == state.STEP_STEPPING)) {
state.single_step = state.STEP_STEPPED;
}
@ -137,17 +143,9 @@ void processor_t::step(size_t n)
if (debug && !state.serialized)
disasm(fetch.insn);
pc = execute_insn(this, pc, fetch);
bool serialize_before = (pc == PC_SERIALIZE_BEFORE);
advance_pc();
if (unlikely(state.single_step == state.STEP_STEPPED) && !serialize_before) {
state.single_step = state.STEP_NONE;
enter_debug_mode(DCSR_CAUSE_STEP);
// enter_debug_mode changed state.pc, so we can't just continue.
break;
}
if (unlikely(state.pc >= DEBUG_ROM_ENTRY &&
state.pc < DEBUG_END)) {
// We're waiting for the debugger to tell us something.

2
riscv/insns/c_slli.h

@ -1,3 +1,3 @@
require_extension('C');
require(insn.rvc_zimm() < xlen);
require(insn.rvc_zimm() < xlen && insn.rvc_zimm() > 0);
WRITE_RD(sext_xlen(RVC_RS1 << insn.rvc_zimm()));

2
riscv/insns/c_srai.h

@ -1,3 +1,3 @@
require_extension('C');
require(insn.rvc_zimm() < xlen);
require(insn.rvc_zimm() < xlen && insn.rvc_zimm() > 0);
WRITE_RVC_RS1S(sext_xlen(sext_xlen(RVC_RS1S) >> insn.rvc_zimm()));

2
riscv/insns/c_srli.h

@ -1,3 +1,3 @@
require_extension('C');
require(insn.rvc_zimm() < xlen);
require(insn.rvc_zimm() < xlen && insn.rvc_zimm() > 0);
WRITE_RVC_RS1S(sext_xlen(zext_xlen(RVC_RS1S) >> insn.rvc_zimm()));

8
riscv/interactive.cc

@ -168,7 +168,7 @@ reg_t sim_t::get_pc(const std::vector<std::string>& args)
throw trap_interactive();
processor_t *p = get_core(args[0]);
return p->state.pc;
return p->get_state()->pc;
}
void sim_t::interactive_pc(const std::string& cmd, const std::vector<std::string>& args)
@ -198,7 +198,7 @@ reg_t sim_t::get_reg(const std::vector<std::string>& args)
if (r >= NXPR)
throw trap_interactive();
return p->state.XPR[r];
return p->get_state()->XPR[r];
}
freg_t sim_t::get_freg(const std::vector<std::string>& args)
@ -213,7 +213,7 @@ freg_t sim_t::get_freg(const std::vector<std::string>& args)
if (r >= NFPR)
throw trap_interactive();
return p->state.FPR[r];
return p->get_state()->FPR[r];
}
void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::string>& args)
@ -223,7 +223,7 @@ void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::strin
processor_t *p = get_core(args[0]);
for (int r = 0; r < NXPR; ++r) {
fprintf(stderr, "%-4s: 0x%016" PRIx64 " ", xpr_name[r], p->state.XPR[r]);
fprintf(stderr, "%-4s: 0x%016" PRIx64 " ", xpr_name[r], p->get_state()->XPR[r]);
if ((r + 1) % 4 == 0)
fprintf(stderr, "\n");
}

10
riscv/jtag_dtm.cc

@ -14,7 +14,8 @@
enum {
IR_IDCODE=1,
IR_DTMCONTROL=0x10,
IR_DBUS=0x11
IR_DBUS=0x11,
IR_RESET=0x1c
};
#define DTMCONTROL_VERSION 0xf
@ -104,8 +105,11 @@ void jtag_dtm_t::set_pins(bool tck, bool tms, bool tdi) {
case SHIFT_IR:
_tdo = ir & 1;
break;
case UPDATE_IR:
break;
//case UPDATE_IR:
//if (ir == IR_RESET) {
// Make a reset happen
//}
//break;
default:
break;
}

2
riscv/mmu.cc

@ -4,7 +4,7 @@
#include "sim.h"
#include "processor.h"
mmu_t::mmu_t(sim_t* sim, processor_t* proc)
mmu_t::mmu_t(simif_t* sim, processor_t* proc)
: sim(sim), proc(proc),
check_triggers_fetch(false),
check_triggers_load(false),

4
riscv/mmu.h

@ -53,7 +53,7 @@ class trigger_matched_t
class mmu_t
{
public:
mmu_t(sim_t* sim, processor_t* proc);
mmu_t(simif_t* sim, processor_t* proc);
~mmu_t();
inline reg_t misaligned_load(reg_t addr, size_t size)
@ -240,7 +240,7 @@ public:
void register_memtracer(memtracer_t*);
private:
sim_t* sim;
simif_t* sim;
processor_t* proc;
memtracer_list_t tracer;
uint16_t fetch_temp;

23
riscv/processor.cc

@ -19,7 +19,7 @@
#undef STATE
#define STATE state
processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
processor_t::processor_t(const char* isa, simif_t* sim, uint32_t id,
bool halt_on_reset)
: debug(false), halt_request(false), sim(sim), ext(NULL), id(id),
halt_on_reset(halt_on_reset), last_pc(1), executions(1)
@ -64,10 +64,10 @@ void processor_t::parse_isa_string(const char* str)
const char* all_subsets = "imafdqc";
max_xlen = 64;
isa = reg_t(2) << 62;
state.misa = reg_t(2) << 62;
if (strncmp(p, "rv32", 4) == 0)
max_xlen = 32, isa = reg_t(1) << 30, p += 4;
max_xlen = 32, state.misa = reg_t(1) << 30, p += 4;
else if (strncmp(p, "rv64", 4) == 0)
p += 4;
else if (strncmp(p, "rv", 2) == 0)
@ -83,11 +83,11 @@ void processor_t::parse_isa_string(const char* str)
}
isa_string = "rv" + std::to_string(max_xlen) + p;
isa |= 1L << ('s' - 'a'); // advertise support for supervisor mode
isa |= 1L << ('u' - 'a'); // advertise support for user mode
state.misa |= 1L << ('s' - 'a'); // advertise support for supervisor mode
state.misa |= 1L << ('u' - 'a'); // advertise support for user mode
while (*p) {
isa |= 1L << (*p - 'a');
state.misa |= 1L << (*p - 'a');
if (auto next = strchr(all_subsets, *p)) {
all_subsets = next + 1;
@ -112,12 +112,13 @@ void processor_t::parse_isa_string(const char* str)
if (supports_extension('Q') && max_xlen < 64)
bad_isa_string(str);
max_isa = isa;
max_isa = state.misa;
}
void state_t::reset()
void state_t::reset(reg_t max_isa)
{
memset(this, 0, sizeof(*this));
misa = max_isa;
prv = PRV_M;
pc = DEFAULT_RSTVEC;
load_reservation = -1;
@ -146,7 +147,7 @@ void processor_t::set_histogram(bool value)
void processor_t::reset()
{
state.reset();
state.reset(max_isa);
state.dcsr.halt = halt_on_reset;
halt_on_reset = false;
set_csr(CSR_MSTATUS, state.mstatus);
@ -458,7 +459,7 @@ void processor_t::set_csr(int which, reg_t val)
mask |= 1L << ('C' - 'A');
mask &= max_isa;
isa = (val & mask) | (isa & ~mask);
state.misa = (val & mask) | (state.misa & ~mask);
break;
}
case CSR_TSELECT:
@ -607,7 +608,7 @@ reg_t processor_t::get_csr(int which)
case CSR_MSCRATCH: return state.mscratch;
case CSR_MCAUSE: return state.mcause;
case CSR_MTVAL: return state.mtval;
case CSR_MISA: return isa;
case CSR_MISA: return state.misa;
case CSR_MARCHID: return 0;
case CSR_MIMPID: return 0;
case CSR_MVENDORID: return 0;

17
riscv/processor.h

@ -9,12 +9,12 @@
#include <string>
#include <vector>
#include <map>
#include "debug_rom/debug_rom_defines.h"
#include "debug_rom_defines.h"
class processor_t;
class mmu_t;
typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);
class sim_t;
class simif_t;
class trap_t;
class extension_t;
class disassembler_t;
@ -86,7 +86,7 @@ typedef struct
// architectural state of a RISC-V hart
struct state_t
{
void reset();
void reset(reg_t max_isa);
static const int num_triggers = 4;
@ -96,6 +96,7 @@ struct state_t
// control and status registers
reg_t prv; // TODO: Can this be an enum instead?
reg_t misa;
reg_t mstatus;
reg_t mepc;
reg_t mtval;
@ -163,7 +164,7 @@ static int cto(reg_t val)
class processor_t : public abstract_device_t
{
public:
processor_t(const char* isa, sim_t* sim, uint32_t id, bool halt_on_reset=false);
processor_t(const char* isa, simif_t* sim, uint32_t id, bool halt_on_reset=false);
~processor_t();
void set_debug(bool value);
@ -175,6 +176,8 @@ public:
mmu_t* get_mmu() { return mmu; }
state_t* get_state() { return &state; }
unsigned get_xlen() { return xlen; }
unsigned get_max_xlen() { return max_xlen; }
std::string get_isa_string() { return isa_string; }
unsigned get_flen() {
return supports_extension('Q') ? 128 :
supports_extension('D') ? 64 :
@ -183,7 +186,7 @@ public:
extension_t* get_extension() { return ext; }
bool supports_extension(unsigned char ext) {
if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a';
return ext >= 'A' && ext <= 'Z' && ((isa >> (ext - 'A')) & 1);
return ext >= 'A' && ext <= 'Z' && ((state.misa >> (ext - 'A')) & 1);
}
void check_pc_alignment(reg_t pc) {
if (unlikely(pc & 2) && !supports_extension('C'))
@ -292,7 +295,7 @@ public:
void trigger_updated();
private:
sim_t* sim;
simif_t* sim;
mmu_t* mmu; // main memory is always accessed via the mmu
extension_t* ext;
disassembler_t* disassembler;
@ -300,7 +303,6 @@ private:
uint32_t id;
unsigned max_xlen;
unsigned xlen;
reg_t isa;
reg_t max_isa;
std::string isa_string;
bool histogram_enabled;
@ -320,7 +322,6 @@ private:
void enter_debug_mode(uint8_t cause);
friend class sim_t;
friend class mmu_t;
friend class clint_t;
friend class extension_t;

11
riscv/sim.cc

@ -27,10 +27,11 @@ sim_t::sim_t(const char* isa, size_t nprocs, bool halted, reg_t start_pc,
std::vector<std::pair<reg_t, mem_t*>> mems,
const std::vector<std::string>& args,
std::vector<int> const hartids, unsigned progsize,
unsigned max_bus_master_bits)
unsigned max_bus_master_bits, bool require_authentication)
: htif_t(args), mems(mems), procs(std::max(nprocs, size_t(1))),
start_pc(start_pc), current_step(0), current_proc(0), debug(false),
remote_bitbang(NULL), debug_module(this, progsize, max_bus_master_bits)
remote_bitbang(NULL),
debug_module(this, progsize, max_bus_master_bits, require_authentication)
{
signal(SIGINT, &handle_signal);
@ -247,7 +248,7 @@ void sim_t::make_dtb()
0x297, // auipc t0,0x0
0x28593 + (reset_vec_size * 4 << 20), // addi a1, t0, &dtb
0xf1402573, // csrr a0, mhartid
get_core(0)->xlen == 32 ?
get_core(0)->get_xlen() == 32 ?
0x0182a283u : // lw t0,24(t0)
0x0182b283u, // ld t0,24(t0)
0x28067, // jr t0
@ -277,8 +278,8 @@ void sim_t::make_dtb()
" reg = <" << i << ">;\n"
" status = \"okay\";\n"
" compatible = \"riscv\";\n"
" riscv,isa = \"" << procs[i]->isa_string << "\";\n"
" mmu-type = \"riscv," << (procs[i]->max_xlen <= 32 ? "sv32" : "sv48") << "\";\n"
" riscv,isa = \"" << procs[i]->get_isa_string() << "\";\n"
" mmu-type = \"riscv," << (procs[i]->get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n"
" clock-frequency = <" << CPU_HZ << ">;\n"
" CPU" << i << "_intc: interrupt-controller {\n"
" #interrupt-cells = <1>;\n"

15
riscv/sim.h

@ -15,14 +15,25 @@
class mmu_t;
class remote_bitbang_t;
// this is the interface to the simulator used by the processors and memory
class simif_t
{
public:
// should return NULL for MMIO addresses
virtual char* addr_to_mem(reg_t addr) = 0;
// used for MMIO addresses
virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0;
virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0;
};
// this class encapsulates the processors and memory in a RISC-V machine.
class sim_t : public htif_t
class sim_t : public htif_t, public simif_t
{
public:
sim_t(const char* isa, size_t _nprocs, bool halted, reg_t start_pc,
std::vector<std::pair<reg_t, mem_t*>> mems,
const std::vector<std::string>& args, const std::vector<int> hartids,
unsigned progsize, unsigned max_bus_master_bits);
unsigned progsize, unsigned max_bus_master_bits, bool require_authentication);
~sim_t();
// run the simulation to completion

1
softfloat/softfloat.mk.in

@ -2,6 +2,7 @@ softfloat_subproject_deps =
softfloat_hdrs = \
internals.h \
platform.h \
primitives.h \
primitiveTypes.h \
softfloat.h \

10
spike_main/spike.cc

@ -36,9 +36,10 @@ static void help()
fprintf(stderr, " --extlib=<name> Shared library to load\n");
fprintf(stderr, " --rbb-port=<port> Listen on <port> for remote bitbang connection\n");
fprintf(stderr, " --dump-dts Print device tree string and exit\n");
fprintf(stderr, " --progsize=<words> progsize for the debug module [default 2]\n");
fprintf(stderr, " --debug-sba=<bits> debug bus master supports up to "
fprintf(stderr, " --progsize=<words> Progsize for the debug module [default 2]\n");
fprintf(stderr, " --debug-sba=<bits> Debug bus master supports up to "
"<bits> wide accesses [default 0]\n");
fprintf(stderr, " --debug-auth Debug module requires debugger to authenticate\n");
exit(1);
}
@ -92,6 +93,7 @@ int main(int argc, char** argv)
bool use_rbb = false;
unsigned progsize = 2;
unsigned max_bus_master_bits = 0;
bool require_authentication = false;
std::vector<int> hartids;
auto const hartids_parser = [&](const char *s) {
@ -135,6 +137,8 @@ int main(int argc, char** argv)
parser.option(0, "progsize", 1, [&](const char* s){progsize = atoi(s);});
parser.option(0, "debug-sba", 1,
[&](const char* s){max_bus_master_bits = atoi(s);});
parser.option(0, "debug-auth", 0,
[&](const char* s){require_authentication = true;});
auto argv1 = parser.parse(argv);
std::vector<std::string> htif_args(argv1, (const char*const*)argv + argc);
@ -142,7 +146,7 @@ int main(int argc, char** argv)
mems = make_mems("2048");
sim_t s(isa, nprocs, halted, start_pc, mems, htif_args, std::move(hartids),
progsize, max_bus_master_bits);
progsize, max_bus_master_bits, require_authentication);
std::unique_ptr<remote_bitbang_t> remote_bitbang((remote_bitbang_t *) NULL);
std::unique_ptr<jtag_dtm_t> jtag_dtm(new jtag_dtm_t(&s.debug_module));
if (use_rbb) {

Loading…
Cancel
Save