Browse Source

Remove legacy HTIF; implement HTIF directly

pull/56/head
Andrew Waterman 10 years ago
parent
commit
036c908666
  1. 122
      riscv/htif.cc
  2. 31
      riscv/htif.h
  3. 5
      riscv/interactive.cc
  4. 11
      riscv/processor.cc
  5. 4
      riscv/processor.h
  6. 2
      riscv/riscv.mk.in
  7. 53
      riscv/sim.cc
  8. 33
      riscv/sim.h
  9. 1
      spike_main/spike.cc

122
riscv/htif.cc

@ -1,122 +0,0 @@
// See LICENSE for license details.
#include "htif.h"
#include "sim.h"
#include "mmu.h"
#include "encoding.h"
#include <unistd.h>
#include <stdexcept>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <stddef.h>
#include <poll.h>
htif_isasim_t::htif_isasim_t(sim_t* _sim, const std::vector<std::string>& args)
: htif_pthread_t(args), sim(_sim), reset(true), seqno(1)
{
}
bool htif_isasim_t::tick()
{
if (done())
return false;
do tick_once(); while (reset);
return true;
}
void htif_isasim_t::tick_once()
{
packet_header_t hdr;
recv(&hdr, sizeof(hdr));
char buf[hdr.get_packet_size()];
memcpy(buf, &hdr, sizeof(hdr));
recv(buf + sizeof(hdr), hdr.get_payload_size());
packet_t p(buf);
assert(hdr.seqno == seqno);
switch (hdr.cmd)
{
case HTIF_CMD_READ_MEM:
{
packet_header_t ack(HTIF_CMD_ACK, seqno, hdr.data_size, 0);
send(&ack, sizeof(ack));
uint64_t buf[hdr.data_size];
for (size_t i = 0; i < hdr.data_size; i++) {
reg_t addr = (hdr.addr + i) * HTIF_DATA_ALIGN;
try {
buf[i] = sim->debug_mmu->load_uint64(addr);
} catch (trap_load_access_fault& e) {
fprintf(stderr, "HTIF: attempt to read from illegal address 0x%" PRIx64 "\n", addr);
exit(-1);
}
}
send(buf, hdr.data_size * sizeof(buf[0]));
break;
}
case HTIF_CMD_WRITE_MEM:
{
const uint64_t* buf = (const uint64_t*)p.get_payload();
for (size_t i = 0; i < hdr.data_size; i++) {
reg_t addr = (hdr.addr + i) * HTIF_DATA_ALIGN;
try {
sim->debug_mmu->store_uint64(addr, buf[i]);
} catch (trap_store_access_fault& e) {
fprintf(stderr, "HTIF: attempt to write to illegal address 0x%" PRIx64 "\n", addr);
exit(-1);
}
}
packet_header_t ack(HTIF_CMD_ACK, seqno, 0, 0);
send(&ack, sizeof(ack));
break;
}
case HTIF_CMD_READ_CONTROL_REG:
case HTIF_CMD_WRITE_CONTROL_REG:
{
assert(hdr.data_size == 1);
reg_t coreid = hdr.addr >> 20;
reg_t regno = hdr.addr & ((1<<20)-1);
uint64_t old_val, new_val = 0 /* shut up gcc */;
packet_header_t ack(HTIF_CMD_ACK, seqno, 1, 0);
send(&ack, sizeof(ack));
processor_t* proc = sim->get_core(coreid);
bool write = hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG;
if (write)
memcpy(&new_val, p.get_payload(), sizeof(new_val));
switch (regno)
{
case CSR_MRESET:
old_val = !proc->running();
if (write)
{
reset = reset & (new_val & 1);
proc->reset(new_val & 1);
}
break;
default:
abort();
}
send(&old_val, sizeof(old_val));
break;
}
default:
abort();
}
seqno++;
}
bool htif_isasim_t::done()
{
if (reset)
return false;
return !sim->running();
}

31
riscv/htif.h

@ -1,31 +0,0 @@
// See LICENSE for license details.
#ifndef _HTIF_H
#define _HTIF_H
#include <fesvr/htif_pthread.h>
class sim_t;
struct packet;
// this class implements the host-target interface for program loading, etc.
// a simpler implementation would implement the high-level interface
// (read/write cr, read/write chunk) directly, but we implement the lower-
// level serialized interface to be more similar to real target machines.
class htif_isasim_t : public htif_pthread_t
{
public:
htif_isasim_t(sim_t* _sim, const std::vector<std::string>& args);
bool tick();
bool done();
private:
sim_t* sim;
bool reset;
uint8_t seqno;
void tick_once();
};
#endif

5
riscv/interactive.cc

@ -4,7 +4,6 @@
#include "disasm.h"
#include "sim.h"
#include "mmu.h"
#include "htif.h"
#include <sys/mman.h>
#include <termios.h>
#include <map>
@ -77,7 +76,7 @@ void sim_t::interactive()
funcs["help"] = &sim_t::interactive_help;
funcs["h"] = funcs["help"];
while (!htif->done())
while (!done())
{
std::cerr << ": " << std::flush;
std::string s = readline(2);
@ -150,7 +149,7 @@ void sim_t::interactive_run(const std::string& cmd, const std::vector<std::strin
size_t steps = args.size() ? atoll(args[0].c_str()) : -1;
ctrlc_pressed = false;
set_procs_debug(noisy);
for (size_t i = 0; i < steps && !ctrlc_pressed && !htif->done(); i++)
for (size_t i = 0; i < steps && !ctrlc_pressed && !done(); i++)
step(1);
}

11
riscv/processor.cc

@ -6,7 +6,6 @@
#include "config.h"
#include "sim.h"
#include "mmu.h"
#include "htif.h"
#include "disasm.h"
#include "gdbserver.h"
#include <cinttypes>
@ -24,13 +23,13 @@
processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
bool halt_on_reset)
: debug(false), sim(sim), ext(NULL), disassembler(new disassembler_t),
id(id), run(false), halt_on_reset(halt_on_reset)
id(id), halt_on_reset(halt_on_reset)
{
parse_isa_string(isa);
mmu = new mmu_t(sim, this);
reset(true);
reset();
register_base_instructions();
}
@ -139,12 +138,8 @@ void processor_t::set_histogram(bool value)
#endif
}
void processor_t::reset(bool value)
void processor_t::reset()
{
if (run == !value)
return;
run = !value;
state.reset();
state.dcsr.halt = halt_on_reset;
halt_on_reset = false;

4
riscv/processor.h

@ -106,9 +106,8 @@ public:
void set_debug(bool value);
void set_histogram(bool value);
void reset(bool value);
void reset();
void step(size_t n); // run for n cycles
bool running() { return run; }
void set_csr(int which, reg_t val);
void raise_interrupt(reg_t which);
reg_t get_csr(int which);
@ -144,7 +143,6 @@ private:
unsigned xlen;
reg_t isa;
std::string isa_string;
bool run; // !reset
bool histogram_enabled;
bool halt_on_reset;

2
riscv/riscv.mk.in

@ -7,7 +7,6 @@ riscv_subproject_deps = \
riscv_install_prog_srcs = \
riscv_hdrs = \
htif.h \
common.h \
decode.h \
devices.h \
@ -31,7 +30,6 @@ riscv_precompiled_hdrs = \
insn_template.h \
riscv_srcs = \
htif.cc \
processor.cc \
execute.cc \
sim.cc \

53
riscv/sim.cc

@ -2,7 +2,6 @@
#include "sim.h"
#include "mmu.h"
#include "htif.h"
#include "gdbserver.h"
#include <map>
#include <iostream>
@ -23,7 +22,7 @@ static void handle_signal(int sig)
sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted,
const std::vector<std::string>& args)
: htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))),
: htif_t(args), procs(std::max(nprocs, size_t(1))),
current_step(0), current_proc(0), debug(false), gdbserver(NULL)
{
signal(SIGINT, &handle_signal);
@ -62,11 +61,17 @@ sim_t::~sim_t()
free(mem);
}
int sim_t::run()
void sim_thread_main(void* arg)
{
((sim_t*)arg)->main();
}
void sim_t::main()
{
if (!debug && log)
set_procs_debug(true);
while (htif->tick())
while (!done())
{
if (debug || ctrlc_pressed)
interactive();
@ -76,7 +81,13 @@ int sim_t::run()
gdbserver->handle();
}
}
return htif->exit_code();
}
int sim_t::run()
{
host = context_t::current();
target.init(sim_thread_main, this);
return htif_t::run();
}
void sim_t::step(size_t n)
@ -96,19 +107,11 @@ void sim_t::step(size_t n)
rtc->increment(INTERLEAVE / INSNS_PER_RTC_TICK);
}
htif->tick();
host->switch_to();
}
}
}
bool sim_t::running()
{
for (size_t i = 0; i < procs.size(); i++)
if (procs[i]->running())
return true;
return false;
}
void sim_t::set_debug(bool value)
{
debug = value;
@ -204,3 +207,25 @@ void sim_t::make_config_string()
boot_rom.reset(new rom_device_t(rom));
bus.add_device(DEFAULT_RSTVEC, boot_rom.get());
}
// htif
void sim_t::idle()
{
target.switch_to();
}
void sim_t::read_chunk(addr_t taddr, size_t len, void* dst)
{
assert(len == 8);
auto data = debug_mmu->load_uint64(taddr);
memcpy(dst, &data, sizeof data);
}
void sim_t::write_chunk(addr_t taddr, size_t len, const void* src)
{
assert(len == 8);
uint64_t data;
memcpy(&data, src, sizeof data);
debug_mmu->store_uint64(taddr, data);
}

33
riscv/sim.h

@ -3,42 +3,37 @@
#ifndef _RISCV_SIM_H
#define _RISCV_SIM_H
#include <vector>
#include <string>
#include <memory>
#include "processor.h"
#include "devices.h"
#include "debug_module.h"
#include <fesvr/htif.h>
#include <fesvr/context.h>
#include <vector>
#include <string>
#include <memory>
class htif_isasim_t;
class mmu_t;
class gdbserver_t;
// this class encapsulates the processors and memory in a RISC-V machine.
class sim_t
class sim_t : public htif_t
{
public:
sim_t(const char* isa, size_t _nprocs, size_t mem_mb, bool halted,
const std::vector<std::string>& htif_args);
const std::vector<std::string>& args);
~sim_t();
// run the simulation to completion
int run();
bool running();
void set_debug(bool value);
void set_log(bool value);
void set_histogram(bool value);
void set_procs_debug(bool value);
void set_gdbserver(gdbserver_t* gdbserver) { this->gdbserver = gdbserver; }
htif_isasim_t* get_htif() { return htif.get(); }
const char* get_config_string() { return config_string.c_str(); }
// returns the number of processors in this simulator
size_t num_cores() { return procs.size(); }
processor_t* get_core(size_t i) { return procs.at(i); }
private:
std::unique_ptr<htif_isasim_t> htif;
char* mem; // main memory
size_t memsz; // memory size in bytes
mmu_t* debug_mmu; // debug port into main memory
@ -91,10 +86,22 @@ private:
reg_t get_mem(const std::vector<std::string>& args);
reg_t get_pc(const std::vector<std::string>& args);
friend class htif_isasim_t;
friend class processor_t;
friend class mmu_t;
friend class gdbserver_t;
// htif
friend void sim_thread_main(void*);
void main();
context_t* host;
context_t target;
void reset() { }
void idle();
void read_chunk(addr_t taddr, size_t len, void* dst);
void write_chunk(addr_t taddr, size_t len, const void* src);
size_t chunk_align() { return 8; }
size_t chunk_max_size() { return 8; }
};
extern volatile bool ctrlc_pressed;

1
spike_main/spike.cc

@ -3,7 +3,6 @@
#include "sim.h"
#include "mmu.h"
#include "gdbserver.h"
#include "htif.h"
#include "cachesim.h"
#include "extension.h"
#include <dlfcn.h>

Loading…
Cancel
Save