Skip to content

Commit

Permalink
[difftest] draft offline difftest
Browse files Browse the repository at this point in the history
  • Loading branch information
Clo91eaf committed Apr 22, 2024
1 parent 9a83b89 commit 14cce30
Show file tree
Hide file tree
Showing 18 changed files with 1,565 additions and 0 deletions.
38 changes: 38 additions & 0 deletions difftest/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
description = "A project for building spike interfaces and tests.";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
rust-overlay.url = "github:oxalica/rust-overlay";
};

outputs = { self, nixpkgs, flake-utils, rust-overlay }@inputs:
let
overlay = import ./nix/overlay.nix;
in
flake-utils.lib.eachDefaultSystem (system:
let
overlays = [ (import rust-overlay) overlay ];
pkgs = import nixpkgs { inherit system overlays; };
rs-toolchain = pkgs.rust-bin.stable.latest.default.override {
extensions = [ "rust-src" ];
};
in
{
legacyPackages = pkgs;
formatter = pkgs.nixpkgs-fmt;
devShells.default = pkgs.mkShell {
buildInputs = [
# Including latest cargo,clippy,cargo-fmt
rs-toolchain
# rust-analyzer comes from nixpkgs toolchain, I want the unwrapped version
pkgs.rust-analyzer-unwrapped
];

# To make rust-analyzer work correctly (The path prefix issue)
RUST_SRC_PATH = "${rs-toolchain}/lib/rustlib/src/rust/library";
};
})
// { inherit inputs; overlays.default = overlay; };
}
12 changes: 12 additions & 0 deletions difftest/libspike_interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.20)
project(libspike_interfaces)
set(CMAKE_CXX_STANDARD 17)

find_package(libspike REQUIRED)

add_library(spike_interfaces SHARED spike_interfaces.cc)

target_link_libraries(spike_interfaces PUBLIC libspike)
target_include_directories(spike_interfaces PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

install(TARGETS spike_interfaces)
134 changes: 134 additions & 0 deletions difftest/libspike_interfaces/spike_interfaces.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include "spike_interfaces.h"

constexpr uint32_t CSR_MSIMEND = 0x7cc;

cfg_t make_spike_cfg(const std::string &varch) {
cfg_t cfg;
cfg.initrd_bounds = std::make_pair((reg_t)0, (reg_t)0),
cfg.bootargs = nullptr;
cfg.isa = DEFAULT_ISA;
cfg.priv = DEFAULT_PRIV;
cfg.varch = varch.data();
cfg.misaligned = false;
cfg.endianness = endianness_little;
cfg.pmpregions = 16;
cfg.pmpgranularity = 4;
cfg.mem_layout = std::vector<mem_cfg_t>();
cfg.hartids = std::vector<size_t>();
cfg.explicit_hartids = false;
cfg.real_time_clint = false;
cfg.trigger_count = 4;
return cfg;
}

Spike::Spike(const char* arch, const char* set, const char* lvl)
: sim(),
varch(arch),
isa(set, lvl),
cfg(make_spike_cfg(varch)),
proc(
/*isa*/ &isa,
/*cfg*/ &cfg,
/*sim*/ &sim,
/*id*/ 0,
/*halt on reset*/ true,
/*log_file_t*/ nullptr,
/*sout*/ std::cerr) {
auto& csrmap = proc.get_state()->csrmap;
csrmap[CSR_MSIMEND] = std::make_shared<basic_csr_t>(&proc, CSR_MSIMEND, 1);
proc.enable_log_commits();
}

spike_t* spike_new(const char* arch, const char* set, const char* lvl) {
return new spike_t{new Spike(arch, set, lvl)};
}

const char* proc_disassemble(spike_processor_t* proc, reg_t pc) {
auto mmu = proc->p->get_mmu();
auto disasm = proc->p->get_disassembler();
auto fetch = mmu->load_insn(pc);
return strdup(disasm->disassemble(fetch.insn).c_str());
}

spike_processor_t* spike_get_proc(spike_t* spike) {
return new spike_processor_t{spike->s->get_proc()};
}

void proc_reset(spike_processor_t* proc) {
proc->p->reset();
}

spike_state_t* proc_get_state(spike_processor_t* proc) {
return new spike_state_t{proc->p->get_state()};
}

reg_t proc_func(spike_processor_t* proc, reg_t pc) {
auto mmu = proc->p->get_mmu();
auto fetch = mmu->load_insn(pc);
return fetch.func(proc->p, fetch.insn, pc);
}

reg_t proc_get_insn(spike_processor_t* proc, reg_t pc) {
auto mmu = proc->p->get_mmu();
auto fetch = mmu->load_insn(pc);
return fetch.insn.bits();
}

reg_t state_get_pc(spike_state_t* state) {
return state->s->pc;
}

static void state_set_serialized(spike_state_t* state, bool serialized) {
state->s->serialized = serialized;
}

uint64_t state_handle_pc(spike_state_t* state, uint64_t new_pc) {
if ((new_pc & 1) == 0) {
state_set_pc(state, new_pc);
} else {
switch (new_pc) {
case PC_SERIALIZE_BEFORE:
state_set_serialized(state, true);
break;
case PC_SERIALIZE_AFTER:
break;
default:
return -1;
}
}
return 0;
}

void state_set_pc(spike_state_t* state, uint64_t pc) {
state->s->pc = pc;
}


void destruct(void* ptr) {
if (ptr == nullptr)
return;
delete ptr;
}

reg_t state_exit(spike_state_t* state) {
auto& csrmap = state->s->csrmap;
return csrmap[CSR_MSIMEND]->read();
}

void spike_register_callback(ffi_callback callback) {
ffi_addr_to_mem = callback;

return;
}

void spike_destruct(spike_t* spike) {
delete spike;
}

void proc_destruct(spike_processor_t* proc) {
delete proc;
}

void state_destruct(spike_state_t* state) {
delete state;
}
63 changes: 63 additions & 0 deletions difftest/libspike_interfaces/spike_interfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef __SPIKE_INTERFCES_H__
#define __SPIKE_INTERFCES_H__

#include "cfg.h"
#include "decode_macros.h"
#include "disasm.h"
#include "mmu.h"
#include "processor.h"
#include "simif.h"
#include "spike_interfaces_c.h"

#ifdef __cplusplus
extern "C" {
#endif

ffi_callback ffi_addr_to_mem;

class sim_t : public simif_t {
public:
sim_t() {}
~sim_t() {}
char* addr_to_mem(reg_t addr) override { return ffi_addr_to_mem(addr); }
bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) override {}
bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) override {}
virtual void proc_reset(unsigned id) override {}
virtual const char* get_symbol(uint64_t addr) override {}
[[nodiscard]] const cfg_t& get_cfg() const override {}
[[nodiscard]] const std::map<size_t, processor_t*>& get_harts()
const override {}
};

class Spike {
public:
Spike(const char* arch, const char* set, const char* lvl);
processor_t* get_proc() { return &proc; }

private:
std::string varch;
cfg_t cfg;
sim_t sim;
isa_parser_t isa;
processor_t proc;
};

struct spike_t {
Spike* s;
ffi_callback ffi_addr_to_mem;
};
struct spike_processor_t {
processor_t* p;
};
struct spike_state_t {
state_t* s;
};
struct spike_mmu_t {
mmu_t* m;
};

#ifdef __cplusplus
}
#endif

#endif // __SPIKE_INTERFCES_H__
36 changes: 36 additions & 0 deletions difftest/libspike_interfaces/spike_interfaces_c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef __SPIKE_INTERFCES_C_H__
#define __SPIKE_INTERFCES_C_H__

#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef char* (*ffi_callback)(uint64_t);

typedef struct spike_t spike_t;
typedef struct spike_processor_t spike_processor_t;
typedef struct spike_state_t spike_state_t;

void spike_register_callback(ffi_callback callback);
spike_t* spike_new(const char* arch, const char* set, const char* lvl);
const char* proc_disassemble(spike_processor_t* proc, uint64_t pc);
void proc_reset(spike_processor_t* proc);
spike_processor_t* spike_get_proc(spike_t* spike);
spike_state_t* proc_get_state(spike_processor_t* proc);
uint64_t proc_func(spike_processor_t* proc, uint64_t pc);
uint64_t proc_get_insn(spike_processor_t* proc, reg_t pc);
uint64_t state_get_pc(spike_state_t* state);
uint64_t state_handle_pc(spike_state_t* state, uint64_t new_pc);
void state_set_pc(spike_state_t* state, uint64_t pc);
void spike_destruct(spike_t* spike);
void proc_destruct(spike_processor_t* proc);
void state_destruct(spike_state_t* state);
uint64_t state_exit(spike_state_t* state);

#ifdef __cplusplus
}
#endif

#endif // __SPIKE_INTERFCES_C_H__
1 change: 1 addition & 0 deletions difftest/offline_difftest/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
3 changes: 3 additions & 0 deletions difftest/offline_difftest/.rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
hard_tabs = true
tab_spaces = 2
indent_style = "Block"
Loading

0 comments on commit 14cce30

Please sign in to comment.