Compare commits
No commits in common. "8ee1551dc2857091fca6456c1367aab7090899fe" and "a5790308f094f7c3aacdccde53627839e80f9004" have entirely different histories.
8ee1551dc2
...
a5790308f0
11 changed files with 105 additions and 88 deletions
1
am-kernels
Submodule
1
am-kernels
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 8c4ea046225e2dce599dc36aeef6c4c857996d00
|
1
diffu
Submodule
1
diffu
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 645b0f607ae510fda4d71b8152ea932a2b38bc32
|
11
flake.nix
11
flake.nix
|
@ -11,8 +11,6 @@
|
|||
url = "git+https://git.xinyang.life/xin/nur.git";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
# diffu.url = "github:xinyangli/diffu";
|
||||
# am-kernels.url = "git+https://git.xinyang.life/xin/am-kernels.git";
|
||||
};
|
||||
|
||||
outputs = { self, flake-utils, nixpkgs, nixpkgs-circt162, pre-commit-hooks, nur-xin }@inputs:
|
||||
|
@ -67,9 +65,13 @@
|
|||
abstract-machine = pkgs.callPackage ./abstract-machine { isa = "native"; };
|
||||
nemu = pkgs.callPackage ./nemu { };
|
||||
nemu-lib = pkgs.callPackage ./nemu { };
|
||||
am-kernels = pkgs.callPackage ./am-kernels { abstract-machine = abstract-machine; arch = "native"; };
|
||||
|
||||
rv32Cross = rec {
|
||||
abstract-machine = rv32CrossConfig.callPackage ./abstract-machine { isa = "riscv"; platform = [ "nemu" "npc" ]; };
|
||||
am-kernels-npc = rv32CrossConfig.callPackage ./am-kernels { inherit abstract-machine; arch = "riscv-npc"; };
|
||||
am-kernels-nemu = rv32CrossConfig.callPackage ./am-kernels { inherit abstract-machine; arch = "riscv-nemu"; };
|
||||
am-kernels = rv32CrossConfig.callPackage ./am-kernels { abstract-machine = abstract-machine; arch = "riscv"; };
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -92,13 +94,13 @@
|
|||
self.packages.${system}.nemu
|
||||
];
|
||||
NEMU_HOME = "/home/xin/repo/ysyx-workbench/nemu";
|
||||
# NEMU_IMAGES_PATH = self.packages.${system}.rv32Cross.am-kernels-nemu + "/share/am-kernels";
|
||||
NEMU_IMAGES_PATH = self.packages.${system}.rv32Cross.am-kernels-nemu + "/share/am-kernels";
|
||||
};
|
||||
|
||||
devShells.npc = pkgs.mkShell.override { stdenv = pkgs.ccacheStdenv; } {
|
||||
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
||||
CHISEL_FIRTOOL_PATH = "${nixpkgs-circt162.legacyPackages.${system}.circt}/bin";
|
||||
# NPC_IMAGES_PATH = "${self.packages.${system}.rv32Cross.am-kernels-npc}/share/am-kernels";
|
||||
NPC_IMAGES_PATH = "${self.packages.${system}.rv32Cross.am-kernels-npc}/share/am-kernels";
|
||||
packages = with pkgs; [
|
||||
clang-tools
|
||||
cmake
|
||||
|
@ -123,6 +125,7 @@
|
|||
flex
|
||||
bison
|
||||
verilator
|
||||
self.packages.${system}.rv32Cross.am-kernels-npc
|
||||
];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
menuconfig DEVICE
|
||||
depends on !TARGET_SHARE
|
||||
bool "Devices"
|
||||
default n
|
||||
help
|
||||
|
|
|
@ -13,17 +13,17 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
#include <isa.h>
|
||||
#include <memory/host.h>
|
||||
#include <memory/vaddr.h>
|
||||
#include <device/map.h>
|
||||
|
||||
#define IO_SPACE_MAX (2 * 1024 * 1024)
|
||||
|
||||
static uint8_t *io_space = NULL;
|
||||
static uint8_t *p_space = NULL;
|
||||
|
||||
uint8_t *new_space(int size) {
|
||||
uint8_t* new_space(int size) {
|
||||
uint8_t *p = p_space;
|
||||
// page aligned;
|
||||
size = (size + (PAGE_SIZE - 1)) & ~PAGE_MASK;
|
||||
|
@ -33,25 +33,17 @@ uint8_t *new_space(int size) {
|
|||
}
|
||||
|
||||
static void check_bound(IOMap *map, paddr_t addr) {
|
||||
#ifndef CONFIG_TARGET_SHARE
|
||||
if (map == NULL) {
|
||||
Assert(map != NULL,
|
||||
"address (" FMT_PADDR ") is out of bound at pc = " FMT_WORD, addr,
|
||||
cpu.pc);
|
||||
Assert(map != NULL, "address (" FMT_PADDR ") is out of bound at pc = " FMT_WORD, addr, cpu.pc);
|
||||
} else {
|
||||
Assert(addr <= map->high && addr >= map->low,
|
||||
"address (" FMT_PADDR ") is out of bound {%s} [" FMT_PADDR
|
||||
", " FMT_PADDR "] at pc = " FMT_WORD,
|
||||
addr, map->name, map->low, map->high, cpu.pc);
|
||||
"address (" FMT_PADDR ") is out of bound {%s} [" FMT_PADDR ", " FMT_PADDR "] at pc = " FMT_WORD,
|
||||
addr, map->name, map->low, map->high, cpu.pc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void invoke_callback(io_callback_t c, paddr_t offset, int len,
|
||||
bool is_write) {
|
||||
if (c != NULL) {
|
||||
c(offset, len, is_write);
|
||||
}
|
||||
static void invoke_callback(io_callback_t c, paddr_t offset, int len, bool is_write) {
|
||||
if (c != NULL) { c(offset, len, is_write); }
|
||||
}
|
||||
|
||||
void init_map() {
|
||||
|
|
|
@ -86,16 +86,38 @@ static void decode_operand(Decode *s, int *rd, word_t *src1, word_t *src2,
|
|||
int rs2 = BITS(i, 24, 20);
|
||||
*rd = BITS(i, 11, 7);
|
||||
switch (type) {
|
||||
// clang-format off
|
||||
case TYPE_R: src1R(); src2R(); break;
|
||||
case TYPE_I: src1R(); immI(); break;
|
||||
case TYPE_U: immU(); break;
|
||||
case TYPE_J: immJ(); break;
|
||||
case TYPE_S: src1R(); src2R(); immS(); break;
|
||||
case TYPE_B: src1R(); src2R(); immB(); break;
|
||||
case TYPE_CSR: src1R(); csr(); break;
|
||||
case TYPE_CSRI: csr(); uimm(); break;
|
||||
// clang-format on
|
||||
case TYPE_R:
|
||||
src1R();
|
||||
src2R();
|
||||
break;
|
||||
case TYPE_I:
|
||||
src1R();
|
||||
immI();
|
||||
break;
|
||||
case TYPE_U:
|
||||
immU();
|
||||
break;
|
||||
case TYPE_J:
|
||||
immJ();
|
||||
break;
|
||||
case TYPE_S:
|
||||
src1R();
|
||||
src2R();
|
||||
immS();
|
||||
break;
|
||||
case TYPE_B:
|
||||
src1R();
|
||||
src2R();
|
||||
immB();
|
||||
break;
|
||||
case TYPE_CSR:
|
||||
src1R();
|
||||
csr();
|
||||
break;
|
||||
case TYPE_CSRI:
|
||||
csr();
|
||||
uimm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,9 +271,6 @@ static int decode_exec(Decode *s) {
|
|||
|
||||
// "Previledge"
|
||||
// -- CSR instructions
|
||||
// src2: R(read register)
|
||||
// src1: R(write source)
|
||||
// imm: write data()
|
||||
INSTPAT(
|
||||
"??????? ????? ????? 001 ????? 11100 11", csrrw, CSR, do {
|
||||
R(rd) = read_csr(cpu.csr, src2);
|
||||
|
|
|
@ -52,11 +52,13 @@ word_t isa_reg_str2val(const char *s, bool *success) {
|
|||
}
|
||||
|
||||
int isa_read_reg(void *args, int regno, size_t *reg_value) {
|
||||
if (regno > 32) {
|
||||
if (regno > 33) {
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
if (regno == 32) {
|
||||
if (regno == 33) {
|
||||
*reg_value = cpu.csr[MTVEC];
|
||||
} else if (regno == 32) {
|
||||
*reg_value = cpu.pc;
|
||||
} else {
|
||||
*reg_value = cpu.gpr[regno];
|
||||
|
@ -65,11 +67,13 @@ int isa_read_reg(void *args, int regno, size_t *reg_value) {
|
|||
}
|
||||
|
||||
int isa_write_reg(void *args, int regno, size_t data) {
|
||||
if (regno > 32) {
|
||||
if (regno > 33) {
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
if (regno == 32) {
|
||||
if (regno == 33) {
|
||||
cpu.csr[MTVEC] = data;
|
||||
} else if (regno == 32) {
|
||||
cpu.pc = data;
|
||||
} else {
|
||||
cpu.gpr[regno] = data;
|
||||
|
@ -77,6 +81,6 @@ int isa_write_reg(void *args, int regno, size_t data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
__EXPORT arch_info_t isa_arch_info = {.reg_num = 32,
|
||||
__EXPORT arch_info_t isa_arch_info = {.reg_num = 33,
|
||||
.reg_byte = MUXDEF(CONFIG_RV64, 8, 4),
|
||||
.target_desc = TARGET_RV32};
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
#include "utils.h"
|
||||
#include <device/mmio.h>
|
||||
#include <isa.h>
|
||||
#include <memory/host.h>
|
||||
|
@ -45,14 +44,9 @@ static void pmem_write(paddr_t addr, int len, word_t data) {
|
|||
}
|
||||
|
||||
static void out_of_bound(paddr_t addr) {
|
||||
#ifdef CONFIG_TARGET_SHARE
|
||||
// Do not panic when used as a library. Give an error in log
|
||||
Error("Out of bound at 0x%x", addr);
|
||||
#else
|
||||
panic("address = " FMT_PADDR " is out of bound of pmem [" FMT_PADDR
|
||||
", " FMT_PADDR "] at pc = " FMT_WORD,
|
||||
addr, PMEM_LEFT, PMEM_RIGHT, cpu.pc);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTRACE
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include <vector>
|
||||
|
||||
|
@ -19,7 +18,7 @@ typedef struct {
|
|||
|
||||
__EXPORT size_t nemu_dbg_state_size = sizeof(DbgState);
|
||||
__EXPORT bool nemu_do_difftest = true;
|
||||
__EXPORT arch_info_t nemu_isa_arch_info = isa_arch_info;
|
||||
__EXPORT arch_info_t nemu_isa_arch_info;
|
||||
|
||||
__EXPORT int nemu_read_mem(void *args, size_t addr, size_t len, void *val) {
|
||||
if (!in_pmem(addr))
|
||||
|
|
|
@ -59,8 +59,7 @@ extern "C" void init_disasm(const char *triple) {
|
|||
llvm::MCRegisterInfo *gMRI = nullptr;
|
||||
auto target = llvm::TargetRegistry::lookupTarget(gTriple, errstr);
|
||||
if (!target) {
|
||||
llvm::errs() << "Can't find target for " << gTriple << ": " << errstr
|
||||
<< "\n";
|
||||
llvm::errs() << "Can't find target for " << gTriple << ": " << errstr << "\n";
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
@ -78,24 +77,22 @@ extern "C" void init_disasm(const char *triple) {
|
|||
gMRI = target->createMCRegInfo(gTriple);
|
||||
auto AsmInfo = target->createMCAsmInfo(*gMRI, gTriple, MCOptions);
|
||||
#if LLVM_VERSION_MAJOR >= 13
|
||||
auto llvmTripleTwine = Twine(triple);
|
||||
auto llvmtriple = llvm::Triple(llvmTripleTwine);
|
||||
auto Ctx = new llvm::MCContext(llvmtriple, AsmInfo, gMRI, nullptr);
|
||||
auto llvmTripleTwine = Twine(triple);
|
||||
auto llvmtriple = llvm::Triple(llvmTripleTwine);
|
||||
auto Ctx = new llvm::MCContext(llvmtriple,AsmInfo, gMRI, nullptr);
|
||||
#else
|
||||
auto Ctx = new llvm::MCContext(AsmInfo, gMRI, nullptr);
|
||||
auto Ctx = new llvm::MCContext(AsmInfo, gMRI, nullptr);
|
||||
#endif
|
||||
gDisassembler = target->createMCDisassembler(*gSTI, *Ctx);
|
||||
gIP = target->createMCInstPrinter(llvm::Triple(gTriple),
|
||||
AsmInfo->getAssemblerDialect(), *AsmInfo,
|
||||
*gMII, *gMRI);
|
||||
AsmInfo->getAssemblerDialect(), *AsmInfo, *gMII, *gMRI);
|
||||
gIP->setPrintImmHex(true);
|
||||
gIP->setPrintBranchImmAsAddress(true);
|
||||
if (isa == "riscv32" || isa == "riscv64")
|
||||
gIP->applyTargetSpecificCLOption("no-aliases");
|
||||
}
|
||||
|
||||
extern "C" void disassemble(char *str, int size, uint64_t pc, uint8_t *code,
|
||||
int nbyte) {
|
||||
extern "C" void disassemble(char *str, int size, uint64_t pc, uint8_t *code, int nbyte) {
|
||||
MCInst inst;
|
||||
llvm::ArrayRef<uint8_t> arr(code, nbyte);
|
||||
uint64_t dummy_size = 0;
|
||||
|
|
|
@ -13,35 +13,35 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include "../../include/common.h"
|
||||
#include "mmu.h"
|
||||
#include "sim.h"
|
||||
#include "../../include/common.h"
|
||||
#include <difftest-def.h>
|
||||
|
||||
#define NR_GPR MUXDEF(CONFIG_RVE, 16, 32)
|
||||
|
||||
static std::vector<std::pair<reg_t, abstract_device_t *>>
|
||||
difftest_plugin_devices;
|
||||
static std::vector<std::pair<reg_t, abstract_device_t*>> difftest_plugin_devices;
|
||||
static std::vector<std::string> difftest_htif_args;
|
||||
static std::vector<std::pair<reg_t, mem_t *>>
|
||||
difftest_mem(1, std::make_pair(reg_t(DRAM_BASE), new mem_t(CONFIG_MSIZE)));
|
||||
static std::vector<std::pair<reg_t, mem_t*>> difftest_mem(
|
||||
1, std::make_pair(reg_t(DRAM_BASE), new mem_t(CONFIG_MSIZE)));
|
||||
static debug_module_config_t difftest_dm_config = {
|
||||
.progbufsize = 2,
|
||||
.max_sba_data_width = 0,
|
||||
.require_authentication = false,
|
||||
.abstract_rti = 0,
|
||||
.support_hasel = true,
|
||||
.support_abstract_csr_access = true,
|
||||
.support_abstract_fpr_access = true,
|
||||
.support_haltgroups = true,
|
||||
.support_impebreak = true};
|
||||
.progbufsize = 2,
|
||||
.max_sba_data_width = 0,
|
||||
.require_authentication = false,
|
||||
.abstract_rti = 0,
|
||||
.support_hasel = true,
|
||||
.support_abstract_csr_access = true,
|
||||
.support_abstract_fpr_access = true,
|
||||
.support_haltgroups = true,
|
||||
.support_impebreak = true
|
||||
};
|
||||
|
||||
struct diff_context_t {
|
||||
word_t gpr[MUXDEF(CONFIG_RVE, 16, 32)];
|
||||
word_t pc;
|
||||
};
|
||||
|
||||
static sim_t *s = NULL;
|
||||
static sim_t* s = NULL;
|
||||
static processor_t *p = NULL;
|
||||
static state_t *state = NULL;
|
||||
|
||||
|
@ -50,35 +50,36 @@ void sim_t::diff_init(int port) {
|
|||
state = p->get_state();
|
||||
}
|
||||
|
||||
void sim_t::diff_step(uint64_t n) { step(n); }
|
||||
void sim_t::diff_step(uint64_t n) {
|
||||
step(n);
|
||||
}
|
||||
|
||||
void sim_t::diff_get_regs(void *diff_context) {
|
||||
struct diff_context_t *ctx = (struct diff_context_t *)diff_context;
|
||||
void sim_t::diff_get_regs(void* diff_context) {
|
||||
struct diff_context_t* ctx = (struct diff_context_t*)diff_context;
|
||||
for (int i = 0; i < NR_GPR; i++) {
|
||||
ctx->gpr[i] = state->XPR[i];
|
||||
}
|
||||
ctx->pc = state->pc;
|
||||
}
|
||||
|
||||
void sim_t::diff_set_regs(void *diff_context) {
|
||||
struct diff_context_t *ctx = (struct diff_context_t *)diff_context;
|
||||
void sim_t::diff_set_regs(void* diff_context) {
|
||||
struct diff_context_t* ctx = (struct diff_context_t*)diff_context;
|
||||
for (int i = 0; i < NR_GPR; i++) {
|
||||
state->XPR.write(i, (sword_t)ctx->gpr[i]);
|
||||
}
|
||||
state->pc = ctx->pc;
|
||||
}
|
||||
|
||||
void sim_t::diff_memcpy(reg_t dest, void *src, size_t n) {
|
||||
mmu_t *mmu = p->get_mmu();
|
||||
void sim_t::diff_memcpy(reg_t dest, void* src, size_t n) {
|
||||
mmu_t* mmu = p->get_mmu();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
mmu->store<uint8_t>(dest + i, *((uint8_t *)src + i));
|
||||
mmu->store<uint8_t>(dest+i, *((uint8_t*)src+i));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
__EXPORT void difftest_memcpy(paddr_t addr, void *buf, size_t n,
|
||||
bool direction) {
|
||||
__EXPORT void difftest_memcpy(paddr_t addr, void *buf, size_t n, bool direction) {
|
||||
if (direction == DIFFTEST_TO_REF) {
|
||||
s->diff_memcpy(addr, buf, n);
|
||||
} else {
|
||||
|
@ -86,7 +87,7 @@ __EXPORT void difftest_memcpy(paddr_t addr, void *buf, size_t n,
|
|||
}
|
||||
}
|
||||
|
||||
__EXPORT void difftest_regcpy(void *dut, bool direction) {
|
||||
__EXPORT void difftest_regcpy(void* dut, bool direction) {
|
||||
if (direction == DIFFTEST_TO_REF) {
|
||||
s->diff_set_regs(dut);
|
||||
} else {
|
||||
|
@ -94,27 +95,31 @@ __EXPORT void difftest_regcpy(void *dut, bool direction) {
|
|||
}
|
||||
}
|
||||
|
||||
__EXPORT void difftest_exec(uint64_t n) { s->diff_step(n); }
|
||||
__EXPORT void difftest_exec(uint64_t n) {
|
||||
s->diff_step(n);
|
||||
}
|
||||
|
||||
__EXPORT void difftest_init(int port) {
|
||||
difftest_htif_args.push_back("");
|
||||
const char *isa =
|
||||
"RV" MUXDEF(CONFIG_RV64, "64", "32") MUXDEF(CONFIG_RVE, "E", "I") "MAFDC";
|
||||
const char *isa = "RV" MUXDEF(CONFIG_RV64, "64", "32") MUXDEF(CONFIG_RVE, "E", "I") "MAFDC";
|
||||
cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0),
|
||||
/*default_bootargs=*/nullptr,
|
||||
/*default_isa=*/isa,
|
||||
/*default_priv=*/DEFAULT_PRIV,
|
||||
/*default_varch=*/DEFAULT_VARCH,
|
||||
/*default_misaligned=*/false,
|
||||
/*default_endianness*/ endianness_little,
|
||||
/*default_endianness*/endianness_little,
|
||||
/*default_pmpregions=*/16,
|
||||
/*default_mem_layout=*/std::vector<mem_cfg_t>(),
|
||||
/*default_hartids=*/std::vector<size_t>(1),
|
||||
/*default_real_time_clint=*/false,
|
||||
/*default_trigger_count=*/4);
|
||||
s = new sim_t(&cfg, false, difftest_mem, difftest_plugin_devices,
|
||||
difftest_htif_args, difftest_dm_config, nullptr, false, NULL,
|
||||
false, NULL, true);
|
||||
s = new sim_t(&cfg, false,
|
||||
difftest_mem, difftest_plugin_devices, difftest_htif_args,
|
||||
difftest_dm_config, nullptr, false, NULL,
|
||||
false,
|
||||
NULL,
|
||||
true);
|
||||
s->diff_init(port);
|
||||
}
|
||||
|
||||
|
@ -122,4 +127,5 @@ __EXPORT void difftest_raise_intr(uint64_t NO) {
|
|||
trap_t t(NO);
|
||||
p->take_trap_public(t, state->pc);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue