Skip to content

Commit

Permalink
feat(ref): prefer using load_flash_bin_v2 (#533)
Browse files Browse the repository at this point in the history
When the flash image is not specified explicitly, load_flash_bin
does not know the initial values of flash. Currently the REF loads
the same initial instructions as DiffTest, which is not a good
practice.
  • Loading branch information
poemonsense authored Dec 30, 2024
1 parent 0db57c1 commit 9f77665
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 53 deletions.
63 changes: 26 additions & 37 deletions src/test/csrc/common/flash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,85 +21,74 @@
#include "perf.h"
#endif // CONFIG_DIFFTEST_PERFCNT

static uint64_t *flash_base;
static long flash_bin_size = 0;
static char *flash_path = NULL;

unsigned long EMU_FLASH_SIZE = DEFAULT_EMU_FLASH_SIZE;

const char *get_flash_path() {
return flash_path;
}
long get_flash_size() {
return flash_bin_size;
}
flash_device_t flash_dev = {.size = DEFAULT_EMU_FLASH_SIZE, .img_path = NULL};

void flash_read(uint32_t addr, uint64_t *data) {
#ifdef CONFIG_DIFFTEST_PERFCNT
difftest_calls[perf_flash_read]++;
difftest_bytes[perf_flash_read] += 12;
#endif // CONFIG_DIFFTEST_PERFCNT
if (!flash_base) {
if (!flash_dev.base) {
return;
}
//addr must be 8 bytes aligned first
uint32_t aligned_addr = addr & FLASH_ALIGH_MASK;
uint64_t rIdx = aligned_addr / sizeof(uint64_t);
if (rIdx >= EMU_FLASH_SIZE / sizeof(uint64_t)) {
if (rIdx >= flash_dev.size / sizeof(uint64_t)) {
printf("[warning] read addr %x is out of bound\n", addr);
*data = 0;
} else {
*data = flash_base[rIdx];
*data = flash_dev.base[rIdx];
}
}

void init_flash(const char *flash_bin) {
flash_base = (uint64_t *)mmap(NULL, EMU_FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (flash_base == (uint64_t *)MAP_FAILED) {
flash_dev.base = (uint64_t *)mmap(NULL, flash_dev.size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (flash_dev.base == (uint64_t *)MAP_FAILED) {
printf("Warning: Insufficient phisical memory for flash\n");
EMU_FLASH_SIZE = 10 * 1024UL; //10 KB
flash_base = (uint64_t *)mmap(NULL, EMU_FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (flash_base == (uint64_t *)MAP_FAILED) {
printf("Error: Cound not mmap 0x%lx bytes for flash\n", EMU_FLASH_SIZE);
flash_dev.size = 10 * 1024UL; //10 KB
flash_dev.base = (uint64_t *)mmap(NULL, flash_dev.size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (flash_dev.base == (uint64_t *)MAP_FAILED) {
printf("Error: Cound not mmap 0x%lx bytes for flash\n", flash_dev.size);
assert(0);
}
}
Info("Using simulated %luB flash\n", EMU_FLASH_SIZE);
Info("Using simulated %luB flash\n", flash_dev.size);

if (!flash_bin) {
/** no specified flash_path ,use defualt 3 instructions*/
/** no specified flash_path, use defualt 3 instructions */
// addiw t0,zero,1
// slli to,to, 0x1f
// jr t0
flash_base[0] = 0x01f292930010029b;
flash_base[1] = 0x00028067;
flash_dev.base[0] = 0x01f292930010029b;
flash_dev.base[1] = 0x00028067;
flash_dev.img_size = 2 * sizeof(uint64_t);
return;
}

/** no specified flash_path ,use defualt 3 instructions*/
flash_path = (char *)flash_bin;
Info("use %s as flash bin\n", flash_path);
flash_dev.img_path = (char *)flash_bin;
Info("use %s as flash bin\n", flash_dev.img_path);

FILE *flash_fp = fopen(flash_path, "r");
FILE *flash_fp = fopen(flash_dev.img_path, "r");
if (!flash_fp) {
eprintf(ANSI_COLOR_MAGENTA "[error] flash img not found\n");
exit(1);
}

fseek(flash_fp, 0, SEEK_END);
flash_bin_size = ftell(flash_fp);
if (flash_bin_size > EMU_FLASH_SIZE) {
printf("[warning] flash image size %ld bytes is out of bound, cut the image into %ld bytes\n", flash_bin_size,
EMU_FLASH_SIZE);
flash_bin_size = EMU_FLASH_SIZE;
flash_dev.img_size = ftell(flash_fp);
if (flash_dev.img_size > flash_dev.size) {
printf("[warning] flash image size %ld bytes is out of bound, cut the image into %ld bytes\n", flash_dev.img_size,
flash_dev.size);
flash_dev.img_size = flash_dev.size;
}
fseek(flash_fp, 0, SEEK_SET);
int ret = fread(flash_base, flash_bin_size, 1, flash_fp);
int ret = fread(flash_dev.base, flash_dev.img_size, 1, flash_fp);
assert(ret == 1);
fclose(flash_fp);
}

void flash_finish() {
munmap(flash_base, EMU_FLASH_SIZE);
flash_base = NULL;
munmap(flash_dev.base, flash_dev.size);
flash_dev.base = NULL;
}
10 changes: 8 additions & 2 deletions src/test/csrc/common/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@

#include "common.h"

const char *get_flash_path();
long get_flash_size();
typedef struct {
uint64_t *base;
uint64_t size;
char *img_path;
uint64_t img_size;
} flash_device_t;

extern flash_device_t flash_dev;

void init_flash(const char *flash_bin);
void flash_finish();
Expand Down
2 changes: 1 addition & 1 deletion src/test/csrc/difftest/difftest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ void Difftest::do_first_instr_commit() {
has_commit = 1;
nemu_this_pc = FIRST_INST_ADDRESS;

proxy->flash_init(get_flash_path(), get_flash_size());
proxy->flash_init((const uint8_t *)flash_dev.base, flash_dev.img_size, flash_dev.img_path);
simMemory->clone_on_demand(
[this](uint64_t offset, void *src, size_t n) {
uint64_t dest_addr = PMEM_BASE + offset;
Expand Down
16 changes: 5 additions & 11 deletions src/test/csrc/difftest/refproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,18 +250,12 @@ void RefProxy::display(DiffTestState *dut) {
}
};

void RefProxy::flash_init(const char *flash_bin, size_t size) {
if (load_flash_bin) {
void RefProxy::flash_init(const uint8_t *flash_base, size_t size, const char *flash_bin) {
if (load_flash_bin_v2) {
load_flash_bin_v2(flash_base, size);
} else if (load_flash_bin) {
// This API is deprecated because flash_bin may be an empty pointer
load_flash_bin(flash_bin, size);
} else if (load_flash_bin_v2) {
std::ifstream file(flash_bin, std::ios::binary);
if (!file) {
std::cout << "Error loading flash file " << flash_bin << std::endl;
assert(0);
}
std::vector<uint8_t> flash_data(size);
file.read(reinterpret_cast<char *>(flash_data.data()), size);
load_flash_bin_v2(flash_data.data(), size);
} else {
std::cout << "Require load_flash_bin or load_flash_bin_v2 to initialize the flash" << std::endl;
assert(0);
Expand Down
4 changes: 2 additions & 2 deletions src/test/csrc/difftest/refproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class RefProxyConfig {

#define REF_OPTIONAL(f) \
f(load_flash_bin, difftest_load_flash, void, const char*, size_t) \
f(load_flash_bin_v2, difftest_load_flash_v2, void, uint8_t*, size_t) \
f(load_flash_bin_v2, difftest_load_flash_v2, void, const uint8_t*, size_t) \
f(ref_status, difftest_status, int, ) \
f(ref_close, difftest_close, void, ) \
f(ref_set_ramsize, difftest_set_ramsize, void, size_t) \
Expand Down Expand Up @@ -309,7 +309,7 @@ class RefProxy : public AbstractRefProxy {
}
}

void flash_init(const char *flash_bin, size_t size);
void flash_init(const uint8_t *flash_base, size_t size, const char *flash_bin);

inline void get_store_event_other_info(void *info) {
if (ref_get_store_event_other_info) {
Expand Down

0 comments on commit 9f77665

Please sign in to comment.