2023-12-20 16:20:36 +00:00
|
|
|
/***************************************************************************************
|
|
|
|
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
|
|
|
*
|
|
|
|
* NEMU is licensed under Mulan PSL v2.
|
|
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
|
|
*
|
|
|
|
* See the Mulan PSL v2 for more details.
|
|
|
|
***************************************************************************************/
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
#include "../../include/common.h"
|
2023-12-20 16:20:36 +00:00
|
|
|
#include "mmu.h"
|
|
|
|
#include "sim.h"
|
|
|
|
#include <difftest-def.h>
|
|
|
|
|
|
|
|
#define NR_GPR MUXDEF(CONFIG_RVE, 16, 32)
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
static std::vector<std::pair<reg_t, abstract_device_t *>>
|
|
|
|
difftest_plugin_devices;
|
2023-12-20 16:20:36 +00:00
|
|
|
static std::vector<std::string> difftest_htif_args;
|
2024-08-13 10:49:08 +00:00
|
|
|
static std::vector<std::pair<reg_t, mem_t *>>
|
|
|
|
difftest_mem(1, std::make_pair(reg_t(DRAM_BASE), new mem_t(CONFIG_MSIZE)));
|
2023-12-20 16:20:36 +00:00
|
|
|
static debug_module_config_t difftest_dm_config = {
|
2024-08-13 10:49:08 +00:00
|
|
|
.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};
|
2023-12-20 16:20:36 +00:00
|
|
|
|
|
|
|
struct diff_context_t {
|
|
|
|
word_t gpr[MUXDEF(CONFIG_RVE, 16, 32)];
|
|
|
|
word_t pc;
|
|
|
|
};
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
static sim_t *s = NULL;
|
2023-12-20 16:20:36 +00:00
|
|
|
static processor_t *p = NULL;
|
|
|
|
static state_t *state = NULL;
|
|
|
|
|
|
|
|
void sim_t::diff_init(int port) {
|
|
|
|
p = get_core("0");
|
|
|
|
state = p->get_state();
|
|
|
|
}
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
void sim_t::diff_step(uint64_t n) { step(n); }
|
2023-12-20 16:20:36 +00:00
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
void sim_t::diff_get_regs(void *diff_context) {
|
|
|
|
struct diff_context_t *ctx = (struct diff_context_t *)diff_context;
|
2023-12-20 16:20:36 +00:00
|
|
|
for (int i = 0; i < NR_GPR; i++) {
|
|
|
|
ctx->gpr[i] = state->XPR[i];
|
|
|
|
}
|
|
|
|
ctx->pc = state->pc;
|
|
|
|
}
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
void sim_t::diff_set_regs(void *diff_context) {
|
|
|
|
struct diff_context_t *ctx = (struct diff_context_t *)diff_context;
|
2023-12-20 16:20:36 +00:00
|
|
|
for (int i = 0; i < NR_GPR; i++) {
|
|
|
|
state->XPR.write(i, (sword_t)ctx->gpr[i]);
|
|
|
|
}
|
|
|
|
state->pc = ctx->pc;
|
|
|
|
}
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
void sim_t::diff_memcpy(reg_t dest, void *src, size_t n) {
|
|
|
|
mmu_t *mmu = p->get_mmu();
|
2023-12-20 16:20:36 +00:00
|
|
|
for (size_t i = 0; i < n; i++) {
|
2024-08-13 10:49:08 +00:00
|
|
|
mmu->store<uint8_t>(dest + i, *((uint8_t *)src + i));
|
2023-12-20 16:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
__EXPORT void difftest_memcpy(paddr_t addr, void *buf, size_t n,
|
|
|
|
bool direction) {
|
2023-12-20 16:20:36 +00:00
|
|
|
if (direction == DIFFTEST_TO_REF) {
|
|
|
|
s->diff_memcpy(addr, buf, n);
|
|
|
|
} else {
|
|
|
|
assert(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
__EXPORT void difftest_regcpy(void *dut, bool direction) {
|
2023-12-20 16:20:36 +00:00
|
|
|
if (direction == DIFFTEST_TO_REF) {
|
|
|
|
s->diff_set_regs(dut);
|
|
|
|
} else {
|
|
|
|
s->diff_get_regs(dut);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-13 10:49:08 +00:00
|
|
|
__EXPORT void difftest_exec(uint64_t n) { s->diff_step(n); }
|
2023-12-20 16:20:36 +00:00
|
|
|
|
|
|
|
__EXPORT void difftest_init(int port) {
|
|
|
|
difftest_htif_args.push_back("");
|
2024-08-13 10:49:08 +00:00
|
|
|
const char *isa =
|
|
|
|
"RV" MUXDEF(CONFIG_RV64, "64", "32") MUXDEF(CONFIG_RVE, "E", "I") "MAFDC";
|
2023-12-20 16:20:36 +00:00
|
|
|
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,
|
2024-08-13 10:49:08 +00:00
|
|
|
/*default_endianness*/ endianness_little,
|
2023-12-20 16:20:36 +00:00
|
|
|
/*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);
|
2024-08-13 10:49:08 +00:00
|
|
|
s = new sim_t(&cfg, false, difftest_mem, difftest_plugin_devices,
|
|
|
|
difftest_htif_args, difftest_dm_config, nullptr, false, NULL,
|
|
|
|
false, NULL, true);
|
2023-12-20 16:20:36 +00:00
|
|
|
s->diff_init(port);
|
|
|
|
}
|
|
|
|
|
|
|
|
__EXPORT void difftest_raise_intr(uint64_t NO) {
|
|
|
|
trap_t t(NO);
|
|
|
|
p->take_trap_public(t, state->pc);
|
|
|
|
}
|
|
|
|
}
|