From 49baea5d3179efb935d459e885cc49b957fe9084 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 8 Mar 2024 11:32:33 +0800 Subject: [PATCH 01/40] delete useless code Signed-off-by: jiaxiaoyu --- src/checkpoint/serializer.cpp | 1 - src/cpu/cpu-exec.c | 6 ------ 2 files changed, 7 deletions(-) diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index ec13e5920..f3f460fc9 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index 2ba16f198..1119a4b47 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -319,11 +319,6 @@ uint64_t per_bb_profile(Decode *prev_s, Decode *s, bool control_taken) { simpoint_profiling(s->pc, false, abs_inst_count); } - // if (checkpoint_taking && able_to_take && - // ((recvd_manual_oneshot_cpt && !manual_cpt_quit) || - // profiling_started)) { - // // update cpu pc to point to next pc - //umod or not set force m mod extern bool able_to_take_cpt(); bool able_to_take = able_to_take_cpt() || force_cpt_mmode; @@ -331,7 +326,6 @@ uint64_t per_bb_profile(Decode *prev_s, Decode *s, bool control_taken) { return abs_inst_count; } - // if (!(workload_loaded||donot_skip_boot)) { return abs_inst_count; } From 255a606fe9f9853af5c0a844f1ca8ba0d96a1fc5 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 8 Mar 2024 11:31:14 +0800 Subject: [PATCH 02/40] checkpoint: add gcpt device, cpu regs will store in device mmio space, add protobuf, using for encode checkpoint memlayout Signed-off-by: jiaxiaoyu --- .gitmodules | 3 + Makefile | 9 +++ include/checkpoint/checkpoint.pb.h | 117 +++++++++++++++++++++++++++++ include/checkpoint/fill_protobuf.h | 37 +++++++++ include/checkpoint/serializer.h | 7 +- resource/nanopb | 1 + scripts/build.mk | 5 ++ src/checkpoint/checkpoint.pb.c | 15 ++++ src/checkpoint/fill_protobuf.c | 31 ++++++++ src/checkpoint/serializer.cpp | 108 ++++++++++++++------------ src/cpu/cpu-exec.c | 31 ++++---- src/device/device.c | 4 +- src/device/gcpt.c | 30 ++++++++ src/device/io/map.c | 2 +- 14 files changed, 334 insertions(+), 66 deletions(-) create mode 100644 include/checkpoint/checkpoint.pb.h create mode 100644 include/checkpoint/fill_protobuf.h create mode 160000 resource/nanopb create mode 100644 src/checkpoint/checkpoint.pb.c create mode 100644 src/checkpoint/fill_protobuf.c create mode 100644 src/device/gcpt.c diff --git a/.gitmodules b/.gitmodules index deaeaa1b3..89ac811d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "resource/simpoint/simpoint_repo"] path = resource/simpoint/simpoint_repo url = https://github.com/shinezyy/SimPoint.3.2-fix.git +[submodule "resource/nanopb"] + path = resource/nanopb + url = https://github.com/nanopb/nanopb diff --git a/Makefile b/Makefile index 56c97cfe1..f86dfe834 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,9 @@ ENGINE ?= $(call remove_quote,$(CONFIG_ENGINE)) INC_DIR += $(NEMU_HOME)/src/engine/$(ENGINE) DIRS-y += src/engine/$(ENGINE) +INC_DIR += $(NEMU_HOME)/include/checkpoint +DIRS-y += src/checkpoint src/profiling # profiling.c + DIRS-$(CONFIG_MODE_USER) += src/user SRCS-y += src/nemu-main.c @@ -57,6 +60,7 @@ SRCS-$(CONFIG_HAS_AUDIO) += src/device/audio.c SRCS-$(CONFIG_HAS_DISK) += src/device/disk.c SRCS-$(CONFIG_HAS_SDCARD) += src/device/sdcard.c SRCS-$(CONFIG_HAS_FLASH) += src/device/flash.c +SRCS-y += src/device/gcpt.c DIRS-y += src/profiling @@ -65,6 +69,11 @@ DIRS-y += src/checkpoint endif SRCS-y += $(shell find $(DIRS-y) -name "*.c") +SRCS-y += resource/nanopb/pb_common.c +SRCS-y += resource/nanopb/pb_decode.c +SRCS-y += resource/nanopb/pb_encode.c +INC_DIR += resource/nanopb +SRCS-y += $(patsub %.proto,%.pb.c,(shell find $(DIRS-y) -name "*.proto")) SRCS = $(SRCS-y) diff --git a/include/checkpoint/checkpoint.pb.h b/include/checkpoint/checkpoint.pb.h new file mode 100644 index 000000000..aaf3def6e --- /dev/null +++ b/include/checkpoint/checkpoint.pb.h @@ -0,0 +1,117 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.9-dev */ + +#ifndef PB_CHECKPOINT_PB_H_INCLUDED +#define PB_CHECKPOINT_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _checkpoint_header { + uint64_t magic_number; + uint64_t cpt_offset; + uint64_t cpu_num; + uint64_t single_core_size; + uint64_t version; +} checkpoint_header; + +typedef struct _single_core_rvgc_rvv_rvh_memlayout { + uint64_t pc_cpt_addr; + uint64_t mode_cpt_addr; + uint64_t mtime_cpt_addr; + uint64_t mtime_cmp_cpt_addr; + uint64_t misc_done_cpt_addr; + uint64_t misc_reserve; + uint64_t int_reg_cpt_addr; + uint64_t int_reg_done; + uint64_t float_reg_cpt_addr; + uint64_t float_reg_done; + uint64_t csr_reg_cpt_addr; + uint64_t csr_reg_done; + uint64_t csr_reserve; + uint64_t vector_reg_cpt_addr; + uint64_t vector_reg_done; +} single_core_rvgc_rvv_rvh_memlayout; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define checkpoint_header_init_default {0, 0, 0, 0, 0} +#define single_core_rvgc_rvv_rvh_memlayout_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define checkpoint_header_init_zero {0, 0, 0, 0, 0} +#define single_core_rvgc_rvv_rvh_memlayout_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define checkpoint_header_magic_number_tag 1 +#define checkpoint_header_cpt_offset_tag 2 +#define checkpoint_header_cpu_num_tag 3 +#define checkpoint_header_single_core_size_tag 5 +#define checkpoint_header_version_tag 6 +#define single_core_rvgc_rvv_rvh_memlayout_pc_cpt_addr_tag 12 +#define single_core_rvgc_rvv_rvh_memlayout_mode_cpt_addr_tag 13 +#define single_core_rvgc_rvv_rvh_memlayout_mtime_cpt_addr_tag 14 +#define single_core_rvgc_rvv_rvh_memlayout_mtime_cmp_cpt_addr_tag 15 +#define single_core_rvgc_rvv_rvh_memlayout_misc_done_cpt_addr_tag 16 +#define single_core_rvgc_rvv_rvh_memlayout_misc_reserve_tag 17 +#define single_core_rvgc_rvv_rvh_memlayout_int_reg_cpt_addr_tag 18 +#define single_core_rvgc_rvv_rvh_memlayout_int_reg_done_tag 19 +#define single_core_rvgc_rvv_rvh_memlayout_float_reg_cpt_addr_tag 20 +#define single_core_rvgc_rvv_rvh_memlayout_float_reg_done_tag 21 +#define single_core_rvgc_rvv_rvh_memlayout_csr_reg_cpt_addr_tag 22 +#define single_core_rvgc_rvv_rvh_memlayout_csr_reg_done_tag 23 +#define single_core_rvgc_rvv_rvh_memlayout_csr_reserve_tag 24 +#define single_core_rvgc_rvv_rvh_memlayout_vector_reg_cpt_addr_tag 25 +#define single_core_rvgc_rvv_rvh_memlayout_vector_reg_done_tag 26 + +/* Struct field encoding specification for nanopb */ +#define checkpoint_header_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT64, magic_number, 1) \ +X(a, STATIC, SINGULAR, UINT64, cpt_offset, 2) \ +X(a, STATIC, SINGULAR, UINT64, cpu_num, 3) \ +X(a, STATIC, SINGULAR, UINT64, single_core_size, 5) \ +X(a, STATIC, SINGULAR, UINT64, version, 6) +#define checkpoint_header_CALLBACK NULL +#define checkpoint_header_DEFAULT NULL + +#define single_core_rvgc_rvv_rvh_memlayout_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT64, pc_cpt_addr, 12) \ +X(a, STATIC, SINGULAR, UINT64, mode_cpt_addr, 13) \ +X(a, STATIC, SINGULAR, UINT64, mtime_cpt_addr, 14) \ +X(a, STATIC, SINGULAR, UINT64, mtime_cmp_cpt_addr, 15) \ +X(a, STATIC, SINGULAR, UINT64, misc_done_cpt_addr, 16) \ +X(a, STATIC, SINGULAR, UINT64, misc_reserve, 17) \ +X(a, STATIC, SINGULAR, UINT64, int_reg_cpt_addr, 18) \ +X(a, STATIC, SINGULAR, UINT64, int_reg_done, 19) \ +X(a, STATIC, SINGULAR, UINT64, float_reg_cpt_addr, 20) \ +X(a, STATIC, SINGULAR, UINT64, float_reg_done, 21) \ +X(a, STATIC, SINGULAR, UINT64, csr_reg_cpt_addr, 22) \ +X(a, STATIC, SINGULAR, UINT64, csr_reg_done, 23) \ +X(a, STATIC, SINGULAR, UINT64, csr_reserve, 24) \ +X(a, STATIC, SINGULAR, UINT64, vector_reg_cpt_addr, 25) \ +X(a, STATIC, SINGULAR, UINT64, vector_reg_done, 26) +#define single_core_rvgc_rvv_rvh_memlayout_CALLBACK NULL +#define single_core_rvgc_rvv_rvh_memlayout_DEFAULT NULL + +extern const pb_msgdesc_t checkpoint_header_msg; +extern const pb_msgdesc_t single_core_rvgc_rvv_rvh_memlayout_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define checkpoint_header_fields &checkpoint_header_msg +#define single_core_rvgc_rvv_rvh_memlayout_fields &single_core_rvgc_rvv_rvh_memlayout_msg + +/* Maximum encoded size of messages (where known) */ +#define CHECKPOINT_PB_H_MAX_SIZE single_core_rvgc_rvv_rvh_memlayout_size +#define checkpoint_header_size 55 +#define single_core_rvgc_rvv_rvh_memlayout_size 176 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/include/checkpoint/fill_protobuf.h b/include/checkpoint/fill_protobuf.h new file mode 100644 index 000000000..6b3f8b14a --- /dev/null +++ b/include/checkpoint/fill_protobuf.h @@ -0,0 +1,37 @@ +#ifndef __FILL_PROTOBUF_H__ +#define __FILL_PROTOBUF_H__ + +#include "checkpoint.pb.h" + +#define MAGIC_NUMBER 0xdeadbeef +__attribute__((unused)) +static checkpoint_header default_cpt_header = { + .magic_number = MAGIC_NUMBER, + .cpt_offset = sizeof(checkpoint_header) + sizeof(single_core_rvgc_rvv_rvh_memlayout), + .cpu_num = 1, + .single_core_size = 1 * 1024 * 1024, + .version = 0x20240125, +}; + +__attribute__((unused)) +static single_core_rvgc_rvv_rvh_memlayout default_cpt_percpu_layout = { + .pc_cpt_addr = 0x0, + .mode_cpt_addr = 0x8, + .mtime_cpt_addr = 0x10, + .mtime_cmp_cpt_addr = 0x18, + .misc_done_cpt_addr = 0x20, + .misc_reserve = 0x28, + .int_reg_cpt_addr = 0x1000, + .int_reg_done = 0x1128, + .float_reg_cpt_addr = 0x1130, + .float_reg_done = 0x1230, + .csr_reg_cpt_addr = 0x1238, + .csr_reg_done = 0x9238, + .csr_reserve = 0x9240, + .vector_reg_cpt_addr = 0x11240, + .vector_reg_done = 0x13240, +}; + +int cpt_header_encode(void *gcpt_mmio, checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_memlayout); + +#endif diff --git a/include/checkpoint/serializer.h b/include/checkpoint/serializer.h index 9045e4c67..329718b75 100644 --- a/include/checkpoint/serializer.h +++ b/include/checkpoint/serializer.h @@ -23,16 +23,19 @@ #include #include +extern "C" { +#include "checkpoint/checkpoint.pb.h" +} class Serializer { public: - void serialize(uint64_t inst_count); + void serialize(uint64_t inst_count, bool using_gcpt_mmio); void serializePMem(uint64_t inst_count); - void serializeRegs(); + void serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); explicit Serializer(); diff --git a/resource/nanopb b/resource/nanopb new file mode 160000 index 000000000..671672b4d --- /dev/null +++ b/resource/nanopb @@ -0,0 +1 @@ +Subproject commit 671672b4d7994a9b07a307ae654885c7202ae886 diff --git a/scripts/build.mk b/scripts/build.mk index 73593ec4e..e7d010bda 100644 --- a/scripts/build.mk +++ b/scripts/build.mk @@ -53,6 +53,11 @@ ifdef CONFIG_MEM_COMPRESS LDFLAGS += -lzstd endif +# Protobuf +%.pb.c: %.proto + @python resource/nanopb/generator/nanopb_generator.py --strip-path $< + @mv $(basename $<).pb.h include/checkpoint + # Compilation patterns $(OBJ_DIR)/%.o: %.c @echo + CC $< diff --git a/src/checkpoint/checkpoint.pb.c b/src/checkpoint/checkpoint.pb.c new file mode 100644 index 000000000..926a252cb --- /dev/null +++ b/src/checkpoint/checkpoint.pb.c @@ -0,0 +1,15 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.9-dev */ + +#include "checkpoint.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(checkpoint_header, checkpoint_header, AUTO) + + +PB_BIND(single_core_rvgc_rvv_rvh_memlayout, single_core_rvgc_rvv_rvh_memlayout, AUTO) + + + diff --git a/src/checkpoint/fill_protobuf.c b/src/checkpoint/fill_protobuf.c new file mode 100644 index 000000000..6f3bfd71d --- /dev/null +++ b/src/checkpoint/fill_protobuf.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +int cpt_header_encode(void *gcpt_mmio, checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_memlayout) { + int status; + + if (cpt_header == NULL) { + cpt_header = &default_cpt_header; + } + if (cpt_memlayout == NULL) { + cpt_memlayout = &default_cpt_percpu_layout; + } + + pb_ostream_t stream = + pb_ostream_from_buffer((void *)gcpt_mmio, sizeof(checkpoint_header) + sizeof(single_core_rvgc_rvv_rvh_memlayout)); + status = pb_encode_ex(&stream, checkpoint_header_fields, cpt_header, PB_ENCODE_NULLTERMINATED); + if (!status) { + printf("LOG: header encode error %s\n", stream.errmsg); + return 0; + } + + status = pb_encode_ex(&stream, single_core_rvgc_rvv_rvh_memlayout_fields, cpt_memlayout, PB_ENCODE_NULLTERMINATED); + if (!status) { + printf("LOG: body encode error %s\n", stream.errmsg); + return 0; + } + + return cpt_header->cpt_offset; +} diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index f3f460fc9..9f0d5f6ec 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -71,6 +71,10 @@ uint8_t *guest_to_host(paddr_t paddr); extern void log_buffer_flush(); extern void log_file_flush(); extern unsigned long MEMORY_SIZE; +extern uint8_t* get_gcpt_mmio_base(); +void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); +#include +#include } #ifdef CONFIG_MEM_COMPRESS @@ -167,47 +171,50 @@ void Serializer::serializePMem(uint64_t inst_count) {} #ifdef CONFIG_MEM_COMPRESS extern void csr_writeback(); -void Serializer::serializeRegs() { - auto *intRegCpt = (uint64_t *) (get_pmem() + IntRegStartAddr); +void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { + uint64_t buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->int_reg_cpt_addr; + auto *intRegCpt = (uint64_t *) (buffer_start); for (unsigned i = 0; i < 32; i++) { *(intRegCpt + i) = cpu.gpr[i]._64; } - Log("Writing int registers to checkpoint memory @[0x%x, 0x%x) [0x%x, 0x%x)", INT_REG_CPT_ADDR, - INT_REG_CPT_ADDR + 32 * 8, IntRegStartAddr, IntRegStartAddr + 32 * 8); + Log("Writing int registers to checkpoint memory @[0x%lx, 0x%lx) [0x%lx, 0x%lx)", + buffer_start, buffer_start + 32 * 8, + cpt_percpu_layout->int_reg_cpt_addr, cpt_percpu_layout->int_reg_cpt_addr + 32 * 8 + ); #ifndef CONFIG_FPU_NONE - auto *floatRegCpt = (uint64_t *)(get_pmem() + FloatRegStartAddr); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->float_reg_cpt_addr; + auto *floatRegCpt = (uint64_t *) (buffer_start); for (unsigned i = 0; i < 32; i++) { *(floatRegCpt + i) = cpu.fpr[i]._64; } - Log("Writing float registers to checkpoint memory @[0x%x, 0x%x) [0x%x, 0x%x)", FLOAT_REG_CPT_ADDR, - FLOAT_REG_CPT_ADDR + 32 * 8, FloatRegStartAddr, FloatRegStartAddr + 32 * 8); -#endif // CONFIG_FPU_NONE + Log("Writing float registers to checkpoint memory @[0x%lx, 0x%lx) [0x%lx, 0x%lx)", + buffer_start, buffer_start + 32 * 8, + cpt_percpu_layout->float_reg_cpt_addr, cpt_percpu_layout->float_reg_cpt_addr + 32 * 8 + ); +#endif // CONFIG_FPU_NONE #ifdef CONFIG_RVV - auto *vectorRegCpt = (uint64_t *) (get_pmem() + VecRegStartAddr); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->vector_reg_cpt_addr; + auto *vectorRegCpt = (uint64_t *) (buffer_start); for (unsigned i = 0; i < 32; i++) { for (unsigned j = 0; j < VENUM64; j++) { *(vectorRegCpt + (i * VENUM64) + j)=cpu.vr[i]._64[j]; } } Log("Writing Vector registers to checkpoint memory @[0x%x, 0x%x) [0x%x, 0x%x)", - FLOAT_REG_CPT_ADDR, FLOAT_REG_CPT_ADDR + 32 * 8, - VecRegStartAddr, VecRegStartAddr + 32 * 8 * VENUM64 + buffer_start, buffer_start + 32 * 8 * VENUM64, + cpt_percpu_layout->vector_reg_cpt_addr, cpt_percpu_layout->vector_reg_cpt_addr + 32 * 8 * VENUM64 ); #endif // CONFIG_RVV - - auto *pc = (uint64_t *) (get_pmem() + PCAddr); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->pc_cpt_addr; + auto *pc = (uint64_t *) (buffer_start); *pc = cpu.pc; - Log("Writing PC: 0x%lx at addr 0x%x", cpu.pc, PC_CPT_ADDR); + Log("Writing PC: 0x%lx at addr 0x%lx", cpu.pc, buffer_start); - - // csr_writeback(); - auto *csrCpt = (uint64_t *)(get_pmem() + CSRStartAddr); - // Log("csrCpt: %p\n",csrCpt); - // Log("Mstatus: 0x%x", mstatus->val); - // Log("CSR array mstatus: 0x%x", csr_array[0x300]); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->csr_reg_cpt_addr; + auto *csrCpt = (uint64_t *) (buffer_start); for (unsigned i = 0; i < 4096; i++) { rtlreg_t val = csr_array[i]; @@ -216,7 +223,6 @@ void Serializer::serializeRegs() { if (mip_tmp.mtip) { mip_tmp.mtip = 0; } - // Log("Saving mip: 0x%x", mip_tmp.val); val = mip_tmp.val; } @@ -228,10 +234,10 @@ void Serializer::serializeRegs() { } //prepare mstatus - mstatus_t *mstatus_prepare=(mstatus_t *)&csrCpt[0x300]; - mstatus_prepare->mpie=mstatus_prepare->mie; - mstatus_prepare->mie=0; - mstatus_prepare->mpp=cpu.mode; + mstatus_t *mstatus_for_cpt=(mstatus_t *)&csrCpt[0x300]; + mstatus_for_cpt->mpie=mstatus_for_cpt->mie; + mstatus_for_cpt->mie=0; + mstatus_for_cpt->mpp=cpu.mode; #ifdef CONFIG_RVH // checkpoint ub: mpp = 3, mpv = 1 @@ -239,24 +245,19 @@ void Serializer::serializeRegs() { #endif //prepare mepc - mepc_t *mepc_prepare=(mepc_t*)&csrCpt[0x341]; - mepc_prepare->val=cpu.pc; + mepc_t *mepc_for_cpt=(mepc_t*)&csrCpt[0x341]; + mepc_for_cpt->val=cpu.pc; - Log("Writing CSR to checkpoint memory @[0x%x, 0x%x) [0x%x, 0x%x)", - CSR_REG_CPT_ADDR, CSR_REG_CPT_ADDR + 4096 * 8, - CSRStartAddr, CSRStartAddr + 4096 * 8 + Log("Writing CSR to checkpoint memory @[0x%lx, 0x%lx) [0x%lx, 0x%lx)", + buffer_start, buffer_start + 4096 * 8, + cpt_percpu_layout->csr_reg_cpt_addr, cpt_percpu_layout->csr_reg_cpt_addr + 4096 * 8 ); - - auto *flag = (uint64_t *)(get_pmem() + CptFlagAddr); - *flag = CPT_MAGIC_BUMBER; - Log("Touching Flag: 0x%x at addr 0x%x", CPT_MAGIC_BUMBER, BOOT_FLAG_ADDR); - - auto *mode_flag = (uint64_t *) (get_pmem() + MODEAddr); + auto *mode_flag = (uint64_t *) (serialize_base_addr + cpt_percpu_layout->mode_cpt_addr); *mode_flag = cpu.mode; - Log("Record mode flag: 0x%lx at addr 0x%x", cpu.mode, MODE_CPT_ADDR); + Log("Record mode flag: 0x%lx at addr 0x%lx", cpu.mode, cpt_percpu_layout->mode_cpt_addr); - auto *mtime = (uint64_t *) (get_pmem() + MTIMEAddr); + auto *mtime = (uint64_t *) (serialize_base_addr + cpt_percpu_layout->mtime_cpt_addr); extern word_t paddr_read(paddr_t addr, int len, int type, int mode, vaddr_t vaddr); *mtime = ::paddr_read(CLINT_MMIO+0xBFF8, 8, MEM_TYPE_READ, MEM_TYPE_READ, MODE_M, CLINT_MMIO+0xBFF8); Log("Record time: 0x%lx at addr 0x%x", cpu.mode, MTIME_CPT_ADDR); @@ -271,10 +272,20 @@ void Serializer::serializeRegs() { void Serializer::serializeRegs() {} #endif -void Serializer::serialize(uint64_t inst_count) { - +void Serializer::serialize(uint64_t inst_count, bool using_gcpt_mmio) { #ifdef CONFIG_MEM_COMPRESS - serializeRegs(); + checkpoint_header cpt_header = default_cpt_header; + single_core_rvgc_rvv_rvh_memlayout cpt_percpu_layout = default_cpt_percpu_layout; + uint64_t serialize_reg_base_addr; + encode_cpt_header(&cpt_header, &cpt_percpu_layout); + + if (using_gcpt_mmio) { + serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_gcpt_mmio_base(); + }else { + serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_pmem(); + } + + serializeRegs(using_gcpt_mmio, (uint8_t*)serialize_reg_base_addr, &cpt_percpu_layout); serializePMem(inst_count); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); @@ -378,25 +389,28 @@ uint64_t Serializer::next_index(){ return index; } - extern "C" { +void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout){ + assert(cpt_header_encode(get_gcpt_mmio_base(), cpt_header, cpt_percpu_layout)); +} + void init_serializer() { serializer.init(); } -bool try_take_cpt(uint64_t icount) { +bool try_take_cpt(uint64_t icount, bool using_gcpt_mmio) { if (serializer.instrsCouldTakeCpt(icount)) { - serializer.serialize(icount); + serializer.serialize(icount, using_gcpt_mmio); serializer.notify_taken(icount); - Log("return true"); return true; } return false; } -void serialize_reg_to_mem() { - serializer.serializeRegs(); +void serialize_reg_to_mem(bool using_gcpt_mmio) { +// delete for now +// serializer.serializeRegs(using_gcpt_mmio, serialize_base_addr, cpt_percpu_layout); } } diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index 1119a4b47..ff169e8d0 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -86,6 +86,12 @@ static inline void debug_hook(vaddr_t pc, const char *asmbuf) { #endif +static bool using_gcpt_mmio = false; + +void set_using_gcpt_mmio(){ + using_gcpt_mmio = true; +} + void save_globals(Decode *s) { IFDEF(CONFIG_PERF_OPT, prev_s = s); } // Get the number of executed instructions: @@ -353,8 +359,8 @@ uint64_t per_bb_profile(Decode *prev_s, Decode *s, bool control_taken) { cpu.pc = s->pc; - extern bool try_take_cpt(uint64_t icount); - bool taken = try_take_cpt(abs_inst_count); + extern bool try_take_cpt(uint64_t icount, bool using_gcpt_mmio); + bool taken = try_take_cpt(abs_inst_count, using_gcpt_mmio); if (taken) { Log("Have taken checkpoint on pc 0x%lx", s->pc); if (recvd_manual_oneshot_cpt) { @@ -888,17 +894,16 @@ void cpu_exec(uint64_t n) { break; case NEMU_QUIT: - #ifndef CONFIG_SHARE - monitor_statistic(); - extern char *mapped_cpt_file; // defined in paddr.c - if (mapped_cpt_file != NULL) { - extern void serialize_reg_to_mem(); - serialize_reg_to_mem(); - } - break; - #else // CONFIG_SHARE - break; - #endif // CONFIG_SHARE +#ifndef CONFIG_SHARE + monitor_statistic(); + extern char *mapped_cpt_file; // defined in paddr.c + if (mapped_cpt_file != NULL) { + extern void serialize_reg_to_mem(bool using_gcpt_mmio); + serialize_reg_to_mem(using_gcpt_mmio); + } +#else + break; +#endif } pop_context(); } diff --git a/src/device/device.c b/src/device/device.c index 98c33cb51..5cdfe301e 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -36,6 +36,7 @@ void init_disk(); void init_sdcard(); void init_flash(); void load_flash_contents(const char *); +void init_gcpt(); void send_key(uint8_t, bool); void vga_update_screen(); @@ -99,9 +100,6 @@ void init_device() { IFDEF(CONFIG_HAS_DISK, init_disk()); IFDEF(CONFIG_HAS_SDCARD, init_sdcard()); IFDEF(CONFIG_HAS_FLASH, init_flash()); -#ifndef CONFIG_SHARE - IFDEF(CONFIG_HAS_FLASH, load_flash_contents(CONFIG_FLASH_IMG_PATH)); -#endif // CONFIG_SHARE // host alarm for device and timer update. add_alarm_handle(set_device_update_flag); diff --git a/src/device/gcpt.c b/src/device/gcpt.c new file mode 100644 index 000000000..5209b62e0 --- /dev/null +++ b/src/device/gcpt.c @@ -0,0 +1,30 @@ +#include "device/map.h" +#include + +#define CONFIG_GCPT_MMIO 50000000 +#define GCPT_MEM_SIZE (128 * 1024 * 1024) + +static uint8_t *gcpt_host_address = NULL; + +// read gcpt memory do not need any handle, just resturn data +static void gcpt_io_handler(uint32_t offset, int len, bool is_write) {} + +struct { + uint8_t *mmio_address; + uint8_t *host_address; + uint64_t size; +} gcpt_info = { + .size = GCPT_MEM_SIZE, + .host_address = 0, + .mmio_address = (uint8_t *)CONFIG_GCPT_MMIO, +}; + +uint8_t *get_gcpt_mmio_base() { + return gcpt_info.host_address; +} + +void init_gcpt() { + gcpt_host_address = new_space(gcpt_info.size); + gcpt_info.host_address=gcpt_host_address; + add_mmio_map("gcpt", (uint64_t)gcpt_info.mmio_address, gcpt_info.host_address, gcpt_info.size, gcpt_io_handler); +} diff --git a/src/device/io/map.c b/src/device/io/map.c index 0200b642d..70e79c4d9 100644 --- a/src/device/io/map.c +++ b/src/device/io/map.c @@ -19,7 +19,7 @@ #include #include -#define IO_SPACE_MAX (128 * 1024 * 1024) +#define IO_SPACE_MAX (256 * 1024 * 1024) static uint8_t io_space[IO_SPACE_MAX] PG_ALIGN = {}; static uint8_t *p_space = io_space; From ce063386514146e334fb3591ef14557a0e5792a8 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 8 Mar 2024 11:50:23 +0800 Subject: [PATCH 03/40] checkpoint: add using_gcpt_mmio arg Signed-off-by: jiaxiaoyu --- src/monitor/monitor.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index e076e0b3c..2dd3e1c1b 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -113,6 +113,7 @@ static inline int parse_args(int argc, char *argv[]) { {"cpt-mmode" , no_argument , NULL, 7}, {"map-cpt" , required_argument, NULL, 10}, {"checkpoint-format" , required_argument, NULL, 12}, + {"using-gcpt-device" , no_argument , NULL, 14}, // profiling {"simpoint-profile" , no_argument , NULL, 3}, @@ -227,6 +228,12 @@ static inline int parse_args(int argc, char *argv[]) { break; } + case 14: { + extern void set_using_gcpt_mmio(); + set_using_gcpt_mmio(); + break; + } + case 4: sscanf(optarg, "%d", &cpt_id); break; case 12: From 663dcd0e7b71e249d88b41a682d593e7bdd15cbf Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 8 Mar 2024 15:48:46 +0800 Subject: [PATCH 04/40] checkpoint: add compress gcpt and pmem space Signed-off-by: jiaxiaoyu --- include/checkpoint/serializer.h | 2 +- src/checkpoint/serializer.cpp | 49 +++++++++++++++++++++++++++------ src/device/gcpt.c | 4 +++ 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/include/checkpoint/serializer.h b/include/checkpoint/serializer.h index 329718b75..1dfcf5bc4 100644 --- a/include/checkpoint/serializer.h +++ b/include/checkpoint/serializer.h @@ -33,7 +33,7 @@ class Serializer public: void serialize(uint64_t inst_count, bool using_gcpt_mmio); - void serializePMem(uint64_t inst_count); + void serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr); void serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index 9f0d5f6ec..b7112bad0 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -75,14 +76,17 @@ extern uint8_t* get_gcpt_mmio_base(); void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); #include #include +extern uint64_t get_gcpt_mmio_size(); } #ifdef CONFIG_MEM_COMPRESS -void Serializer::serializePMem(uint64_t inst_count) { +void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr) { // We must dump registers before memory to store them in the Generic Arch CPT assert(regDumped); const size_t PMEM_SIZE = MEMORY_SIZE; - uint8_t *pmem = get_pmem(); + const size_t GCPT_MMIO_SIZE = get_gcpt_mmio_size(); + uint8_t *pmem = pmem_addr; + uint8_t *gcpt = gcpt_mmio_addr; if (restorer) { FILE *restore_fp = fopen(restorer, "rb"); @@ -118,6 +122,19 @@ void Serializer::serializePMem(uint64_t inst_count) { } uint64_t pass_size = 0; + if (using_gcpt_mmio) { + for (uint64_t gcpt_written = 0; gcpt_written < GCPT_MMIO_SIZE; gcpt_written += pass_size) { + pass_size = numeric_limits::max() < ((int64_t)GCPT_MMIO_SIZE - (int64_t)gcpt_written) + ? numeric_limits::max() + : ((int64_t)GCPT_MMIO_SIZE - (int64_t)gcpt_written); + if (gzwrite(compressed_mem, gcpt + gcpt_written, (uint32_t)pass_size) != (int)pass_size) { + xpanic("Write failed on physical memory checkpoint file\n"); + } + Log("Written 0x%lx bytes\n", pass_size); + } + + pass_size = 0; + } for (uint64_t written = 0; written < PMEM_SIZE; written += pass_size) { pass_size = numeric_limits::max() < ((int64_t)PMEM_SIZE - (int64_t)written) @@ -136,17 +153,31 @@ void Serializer::serializePMem(uint64_t inst_count) { } else if (compress_file_format == ZSTD_FORMAT) { filepath += "_.zstd"; // zstd compress - size_t const compress_buffer_size = ZSTD_compressBound(PMEM_SIZE); - void *const compress_buffer = malloc(compress_buffer_size); + size_t all_write_size; + if (using_gcpt_mmio) { + all_write_size = PMEM_SIZE + GCPT_MMIO_SIZE; + }else { + all_write_size = PMEM_SIZE; + } + + size_t const compress_buffer_size = ZSTD_compressBound(all_write_size); + uint8_t *const compress_buffer = (uint8_t*)malloc(compress_buffer_size); assert(compress_buffer); - size_t const compress_size = ZSTD_compress(compress_buffer, compress_buffer_size, pmem, PMEM_SIZE, 1); - assert(compress_size <= compress_buffer_size && compress_size != 0); + size_t gcpt_compress_size = 0; + if (using_gcpt_mmio) { + gcpt_compress_size = ZSTD_compress(compress_buffer, compress_buffer_size, gcpt, GCPT_MMIO_SIZE, 1); + assert(gcpt_compress_size <= compress_buffer_size && gcpt_compress_size != 0); + } + + size_t pmem_compress_size = ZSTD_compress(compress_buffer + gcpt_compress_size, compress_buffer_size, pmem, PMEM_SIZE, 1); + assert(pmem_compress_size + gcpt_compress_size <= compress_buffer_size && pmem_compress_size != 0); FILE *compress_file = fopen(filepath.c_str(), "wb"); - size_t fw_size = fwrite(compress_buffer, 1, compress_size, compress_file); + size_t fw_size = fwrite(compress_buffer, 1, pmem_compress_size + gcpt_compress_size, compress_file); - if (fw_size != (size_t)compress_size) { + if (fw_size != (size_t)pmem_compress_size + (size_t)gcpt_compress_size) { + fclose(compress_file); free(compress_buffer); xpanic("file write error: %s : %s \n", filepath.c_str(), strerror(errno)); } @@ -286,7 +317,7 @@ void Serializer::serialize(uint64_t inst_count, bool using_gcpt_mmio) { } serializeRegs(using_gcpt_mmio, (uint8_t*)serialize_reg_base_addr, &cpt_percpu_layout); - serializePMem(inst_count); + serializePMem(inst_count, using_gcpt_mmio, get_pmem(), get_gcpt_mmio_base()); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); #endif diff --git a/src/device/gcpt.c b/src/device/gcpt.c index 5209b62e0..8e517b69b 100644 --- a/src/device/gcpt.c +++ b/src/device/gcpt.c @@ -23,6 +23,10 @@ uint8_t *get_gcpt_mmio_base() { return gcpt_info.host_address; } +uint64_t get_gcpt_mmio_size(){ + return gcpt_info.size; +} + void init_gcpt() { gcpt_host_address = new_space(gcpt_info.size); gcpt_info.host_address=gcpt_host_address; From 704ff3ce7ab824e39c99345f5780f355ed040292 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 8 Mar 2024 15:54:46 +0800 Subject: [PATCH 05/40] is_gz/zstd_file: panic support filename Signed-off-by: jiaxiaoyu --- src/utils/filename.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/filename.c b/src/utils/filename.c index 0fec48c4f..90d882bbc 100644 --- a/src/utils/filename.c +++ b/src/utils/filename.c @@ -31,7 +31,7 @@ bool is_gz_file(const char *filename) size_t sz = read(fd, buf, 2); if (sz != 2) { close(fd); - xpanic("Couldn't read magic bytes from object file"); + xpanic("Couldn't read magic bytes from object file %s", filename); } close(fd); @@ -51,7 +51,7 @@ bool is_zstd_file(const char *filename){ size_t sz = read(fd, buf, 4); if (sz != 4) { close(fd); - xpanic("Couldn't read magic bytes from object file"); + xpanic("Couldn't read magic bytes from object file %s", filename); } close(fd); From 16da7793337d52fecd773c116f082083235ff78f Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Mon, 11 Mar 2024 17:20:53 +0800 Subject: [PATCH 06/40] finish zstd/gz checkpoint using gcpt device and restore from device Signed-off-by: jiaxiaoyu --- include/checkpoint/serializer.h | 15 +--- scripts/take_zstd.sh | 1 + src/checkpoint/serializer.cpp | 130 ++++++++++++++++---------------- src/device/gcpt.c | 12 ++- src/device/io/mmio.c | 6 +- src/monitor/image_loader.c | 34 ++++++++- src/monitor/monitor.c | 12 ++- 7 files changed, 117 insertions(+), 93 deletions(-) diff --git a/include/checkpoint/serializer.h b/include/checkpoint/serializer.h index 1dfcf5bc4..5d97b87f1 100644 --- a/include/checkpoint/serializer.h +++ b/include/checkpoint/serializer.h @@ -55,20 +55,7 @@ class Serializer uint64_t cptID; std::string weightIndicator; - const uint32_t IntRegStartAddr; - const uint32_t IntRegDoneFlag; - const uint32_t FloatRegStartAddr; - const uint32_t FloatRegDoneFlag; - const uint32_t CSRStartAddr; - const uint32_t CSRSDoneFlag; - const uint32_t VecRegStartAddr; - const uint32_t VecRegDoneFlag; - const uint32_t CptFlagAddr; - const uint32_t PCAddr; - const uint32_t MODEAddr; - const uint32_t MTIMEAddr; - const uint32_t MTIMECMPAddr; - const uint32_t MISCDoneFlag; + const int IntRegAddr; bool regDumped{false}; diff --git a/scripts/take_zstd.sh b/scripts/take_zstd.sh index 35251081c..c03df0d20 100644 --- a/scripts/take_zstd.sh +++ b/scripts/take_zstd.sh @@ -19,4 +19,5 @@ -C test \ -w linux \ -I 350000000 $V_WORKLOAD_HOME/OpenSBI_Linux6.6_h264ref_sss_vectorized \ + --using-gcpt-device \ --checkpoint-format zstd diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index b7112bad0..756867eed 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -46,23 +46,9 @@ using std::numeric_limits; using std::string; using std::to_string; -Serializer::Serializer() : - IntRegStartAddr(INT_REG_CPT_ADDR-BOOT_CODE), - IntRegDoneFlag(INT_REG_DONE-BOOT_CODE), - FloatRegStartAddr(FLOAT_REG_CPT_ADDR-BOOT_CODE), - FloatRegDoneFlag(FLOAT_REG_DONE-BOOT_CODE), - CSRStartAddr(CSR_REG_CPT_ADDR-BOOT_CODE), - CSRSDoneFlag(CSR_REG_DONE-BOOT_CODE), - VecRegStartAddr(VECTOR_REG_CPT_ADDR-BOOT_CODE), - VecRegDoneFlag(VECTOR_REG_DONE-BOOT_CODE), - CptFlagAddr(BOOT_FLAG_ADDR-BOOT_CODE), - PCAddr(PC_CPT_ADDR-BOOT_CODE), - MODEAddr(MODE_CPT_ADDR-BOOT_CODE), - MTIMEAddr(MTIME_CPT_ADDR-BOOT_CODE), - MTIMECMPAddr(MTIME_CMP_CPT_ADDR-BOOT_CODE), - MISCDoneFlag(MISC_DONE_CPT_ADDR-BOOT_CODE) -{ -} +Serializer::Serializer() + : IntRegAddr(0){} + extern "C" { uint8_t *get_pmem(); @@ -74,9 +60,10 @@ extern void log_file_flush(); extern unsigned long MEMORY_SIZE; extern uint8_t* get_gcpt_mmio_base(); void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); +extern uint64_t get_gcpt_mmio_size(); +#include #include #include -extern uint64_t get_gcpt_mmio_size(); } #ifdef CONFIG_MEM_COMPRESS @@ -87,6 +74,8 @@ void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_ const size_t GCPT_MMIO_SIZE = get_gcpt_mmio_size(); uint8_t *pmem = pmem_addr; uint8_t *gcpt = gcpt_mmio_addr; + Log("Host physical address: %p size: %lx", pmem, PMEM_SIZE); + Log("Host gcpt address: %p size: %lx", gcpt, GCPT_MMIO_SIZE); if (restorer) { FILE *restore_fp = fopen(restorer, "rb"); @@ -94,7 +83,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_ xpanic("Cannot open restorer %s\n", restorer); } - uint32_t restorer_size = 0xf00; + uint32_t restorer_size = 0xa000; fseek(restore_fp, 0, SEEK_SET); assert(restorer_size == fread(pmem, 1, restorer_size, restore_fp)); fclose(restore_fp); @@ -112,6 +101,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_ } if (compress_file_format == GZ_FORMAT) { + Log("Using GZ format generate checkpoint"); filepath += "_.gz"; gzFile compressed_mem = gzopen(filepath.c_str(), "wb"); if (compressed_mem == nullptr) { @@ -151,27 +141,35 @@ void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_ xpanic("Close failed on physical memory checkpoint file\n"); } } else if (compress_file_format == ZSTD_FORMAT) { + Log("Using ZSTD format generate checkpoint"); + filepath += "_.zstd"; + Log("Opening %s as checkpoint output file", filepath.c_str()); + // zstd compress - size_t all_write_size; + size_t gcpt_and_pmem_size; if (using_gcpt_mmio) { - all_write_size = PMEM_SIZE + GCPT_MMIO_SIZE; + gcpt_and_pmem_size = PMEM_SIZE + GCPT_MMIO_SIZE; }else { - all_write_size = PMEM_SIZE; + gcpt_and_pmem_size = PMEM_SIZE; } + Log("Gcpt and pmem size 0x%lx", gcpt_and_pmem_size); - size_t const compress_buffer_size = ZSTD_compressBound(all_write_size); + size_t const compress_buffer_size = ZSTD_compressBound(gcpt_and_pmem_size); uint8_t *const compress_buffer = (uint8_t*)malloc(compress_buffer_size); assert(compress_buffer); + // compress gcpt device memory size_t gcpt_compress_size = 0; if (using_gcpt_mmio) { gcpt_compress_size = ZSTD_compress(compress_buffer, compress_buffer_size, gcpt, GCPT_MMIO_SIZE, 1); assert(gcpt_compress_size <= compress_buffer_size && gcpt_compress_size != 0); + Log("compress gcpt success, compress size %ld", gcpt_compress_size); } size_t pmem_compress_size = ZSTD_compress(compress_buffer + gcpt_compress_size, compress_buffer_size, pmem, PMEM_SIZE, 1); assert(pmem_compress_size + gcpt_compress_size <= compress_buffer_size && pmem_compress_size != 0); + Log("pmem compress success, compress size %ld",pmem_compress_size); FILE *compress_file = fopen(filepath.c_str(), "wb"); size_t fw_size = fwrite(compress_buffer, 1, pmem_compress_size + gcpt_compress_size, compress_file); @@ -204,48 +202,46 @@ extern void csr_writeback(); void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { uint64_t buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->int_reg_cpt_addr; - auto *intRegCpt = (uint64_t *) (buffer_start); + auto *intRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { *(intRegCpt + i) = cpu.gpr[i]._64; } - Log("Writing int registers to checkpoint memory @[0x%lx, 0x%lx) [0x%lx, 0x%lx)", - buffer_start, buffer_start + 32 * 8, - cpt_percpu_layout->int_reg_cpt_addr, cpt_percpu_layout->int_reg_cpt_addr + 32 * 8 - ); + Log("Writing int registers to checkpoint memory @host_paddr: [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + buffer_start, buffer_start + 32 * 8, cpt_percpu_layout->int_reg_cpt_addr, + cpt_percpu_layout->int_reg_cpt_addr + 32 * 8); #ifndef CONFIG_FPU_NONE buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->float_reg_cpt_addr; - auto *floatRegCpt = (uint64_t *) (buffer_start); + auto *floatRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { *(floatRegCpt + i) = cpu.fpr[i]._64; } - Log("Writing float registers to checkpoint memory @[0x%lx, 0x%lx) [0x%lx, 0x%lx)", - buffer_start, buffer_start + 32 * 8, - cpt_percpu_layout->float_reg_cpt_addr, cpt_percpu_layout->float_reg_cpt_addr + 32 * 8 - ); -#endif // CONFIG_FPU_NONE + Log("Writing float registers to checkpoint memory @host_paddr: [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + buffer_start, buffer_start + 32 * 8, cpt_percpu_layout->float_reg_cpt_addr, + cpt_percpu_layout->float_reg_cpt_addr + 32 * 8); +#endif // CONFIG_FPU_NONE #ifdef CONFIG_RVV buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->vector_reg_cpt_addr; - auto *vectorRegCpt = (uint64_t *) (buffer_start); + auto *vectorRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { for (unsigned j = 0; j < VENUM64; j++) { - *(vectorRegCpt + (i * VENUM64) + j)=cpu.vr[i]._64[j]; + *(vectorRegCpt + (i * VENUM64) + j) = cpu.vr[i]._64[j]; } } - Log("Writing Vector registers to checkpoint memory @[0x%x, 0x%x) [0x%x, 0x%x)", - buffer_start, buffer_start + 32 * 8 * VENUM64, - cpt_percpu_layout->vector_reg_cpt_addr, cpt_percpu_layout->vector_reg_cpt_addr + 32 * 8 * VENUM64 - ); -#endif // CONFIG_RVV + Log("Writing vector registers to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + buffer_start, buffer_start + 32 * 8 * VENUM64, cpt_percpu_layout->vector_reg_cpt_addr, + cpt_percpu_layout->vector_reg_cpt_addr + 32 * 8 * VENUM64); +#endif // CONFIG_RVV buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->pc_cpt_addr; - auto *pc = (uint64_t *) (buffer_start); + auto *pc = (uint64_t *)(buffer_start); *pc = cpu.pc; - Log("Writing PC: 0x%lx at addr 0x%lx", cpu.pc, buffer_start); + Log("Writing PC: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", cpu.pc, + buffer_start, buffer_start + 8, cpt_percpu_layout->pc_cpt_addr, cpt_percpu_layout->pc_cpt_addr + 8); buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->csr_reg_cpt_addr; - auto *csrCpt = (uint64_t *) (buffer_start); + auto *csrCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 4096; i++) { rtlreg_t val = csr_array[i]; @@ -260,42 +256,48 @@ void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_add *(csrCpt + i) = val; if (csr_array[i] != 0) { - Log("CSR 0x%x: 0x%lx", i, *(csrCpt + i)); + Log("CSR id: 0x%x, value: 0x%lx", i, *(csrCpt + i)); } } - //prepare mstatus - mstatus_t *mstatus_for_cpt=(mstatus_t *)&csrCpt[0x300]; - mstatus_for_cpt->mpie=mstatus_for_cpt->mie; - mstatus_for_cpt->mie=0; - mstatus_for_cpt->mpp=cpu.mode; + // prepare mstatus + mstatus_t *mstatus_for_cpt = (mstatus_t *)&csrCpt[0x300]; + mstatus_for_cpt->mpie = mstatus_for_cpt->mie; + mstatus_for_cpt->mie = 0; + mstatus_for_cpt->mpp = cpu.mode; #ifdef CONFIG_RVH // checkpoint ub: mpp = 3, mpv = 1 mstatus_prepare->mpv=cpu.v; #endif - //prepare mepc - mepc_t *mepc_for_cpt=(mepc_t*)&csrCpt[0x341]; - mepc_for_cpt->val=cpu.pc; + // prepare mepc + mepc_t *mepc_for_cpt = (mepc_t *)&csrCpt[0x341]; + mepc_for_cpt->val = cpu.pc; - Log("Writing CSR to checkpoint memory @[0x%lx, 0x%lx) [0x%lx, 0x%lx)", - buffer_start, buffer_start + 4096 * 8, - cpt_percpu_layout->csr_reg_cpt_addr, cpt_percpu_layout->csr_reg_cpt_addr + 4096 * 8 - ); + Log("Writing CSR to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr [0x%lx, 0x%lx)", buffer_start, + buffer_start + 4096 * 8, cpt_percpu_layout->csr_reg_cpt_addr, cpt_percpu_layout->csr_reg_cpt_addr + 4096 * 8); - auto *mode_flag = (uint64_t *) (serialize_base_addr + cpt_percpu_layout->mode_cpt_addr); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mode_cpt_addr; + auto *mode_flag = (uint64_t *)(buffer_start); *mode_flag = cpu.mode; - Log("Record mode flag: 0x%lx at addr 0x%lx", cpu.mode, cpt_percpu_layout->mode_cpt_addr); + Log("Record mode flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + cpu.mode, buffer_start, buffer_start + 8, cpt_percpu_layout->mode_cpt_addr, + cpt_percpu_layout->mode_cpt_addr + 8); - auto *mtime = (uint64_t *) (serialize_base_addr + cpt_percpu_layout->mtime_cpt_addr); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mtime_cpt_addr; + auto *mtime = (uint64_t *)(buffer_start); extern word_t paddr_read(paddr_t addr, int len, int type, int mode, vaddr_t vaddr); *mtime = ::paddr_read(CLINT_MMIO+0xBFF8, 8, MEM_TYPE_READ, MEM_TYPE_READ, MODE_M, CLINT_MMIO+0xBFF8); - Log("Record time: 0x%lx at addr 0x%x", cpu.mode, MTIME_CPT_ADDR); + Log("Record time: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", *mtime, + buffer_start, buffer_start + 8, cpt_percpu_layout->mtime_cpt_addr, cpt_percpu_layout->mtime_cpt_addr + 8); + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mtime_cmp_cpt_addr; auto *mtime_cmp = (uint64_t *) (get_pmem() + MTIMECMPAddr); *mtime_cmp = ::paddr_read(CLINT_MMIO+0x4000, 8, MEM_TYPE_READ, MEM_TYPE_READ, MODE_M, CLINT_MMIO+0x4000); - Log("Record time: 0x%lx at addr 0x%x", cpu.mode, MTIME_CMP_CPT_ADDR); + Log("Record time_cmp flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + *mtime_cmp, buffer_start, buffer_start + 8, cpt_percpu_layout->mtime_cmp_cpt_addr, + cpt_percpu_layout->mtime_cmp_cpt_addr + 8); regDumped = true; } @@ -312,11 +314,11 @@ void Serializer::serialize(uint64_t inst_count, bool using_gcpt_mmio) { if (using_gcpt_mmio) { serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_gcpt_mmio_base(); - }else { + } else { serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_pmem(); } - serializeRegs(using_gcpt_mmio, (uint8_t*)serialize_reg_base_addr, &cpt_percpu_layout); + serializeRegs(using_gcpt_mmio, (uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); serializePMem(inst_count, using_gcpt_mmio, get_pmem(), get_gcpt_mmio_base()); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); diff --git a/src/device/gcpt.c b/src/device/gcpt.c index 8e517b69b..48ae5ce95 100644 --- a/src/device/gcpt.c +++ b/src/device/gcpt.c @@ -1,15 +1,14 @@ #include "device/map.h" #include -#define CONFIG_GCPT_MMIO 50000000 +#define CONFIG_GCPT_MMIO 0x60000000 #define GCPT_MEM_SIZE (128 * 1024 * 1024) -static uint8_t *gcpt_host_address = NULL; - // read gcpt memory do not need any handle, just resturn data -static void gcpt_io_handler(uint32_t offset, int len, bool is_write) {} +static void gcpt_io_handler(uint32_t offset, int len, bool is_write) { +} -struct { +static struct { uint8_t *mmio_address; uint8_t *host_address; uint64_t size; @@ -28,7 +27,6 @@ uint64_t get_gcpt_mmio_size(){ } void init_gcpt() { - gcpt_host_address = new_space(gcpt_info.size); - gcpt_info.host_address=gcpt_host_address; + gcpt_info.host_address = new_space(gcpt_info.size); add_mmio_map("gcpt", (uint64_t)gcpt_info.mmio_address, gcpt_info.host_address, gcpt_info.size, gcpt_io_handler); } diff --git a/src/device/io/mmio.c b/src/device/io/mmio.c index 7ced979c6..f71cf6a82 100644 --- a/src/device/io/mmio.c +++ b/src/device/io/mmio.c @@ -55,9 +55,9 @@ void add_mmio_map(const char *name, paddr_t addr, void *space, uint32_t len, io_ assert(nr_map < NR_MAP); maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1, .space = space, .callback = callback }; - // Log("Add mmio map '%s' at [" FMT_PADDR ", " FMT_PADDR "]", - // maps[nr_map].name, maps[nr_map].low, maps[nr_map].high); - // fflush(stdout); + Log("Add mmio map '%s' at [" FMT_PADDR ", " FMT_PADDR "]", + maps[nr_map].name, maps[nr_map].low, maps[nr_map].high); + fflush(stdout); nr_map ++; } diff --git a/src/monitor/image_loader.c b/src/monitor/image_loader.c index 21dc24f86..d1a804c39 100644 --- a/src/monitor/image_loader.c +++ b/src/monitor/image_loader.c @@ -13,12 +13,15 @@ * See the Mulan PSL v2 for more details. ***************************************************************************************/ +#include "checkpoint.pb.h" +#include "debug.h" #include #include #include #include #include #include +#include #include #include #include @@ -42,11 +45,26 @@ long load_gz_img(const char *filename) { // load file byte by byte to pmem uint64_t curr_size = 0; + + uint64_t cpt_offset = 0; + extern uint8_t *get_gcpt_mmio_base(); + extern uint64_t get_gcpt_mmio_size(); + while (curr_size < MEMORY_SIZE) { uint32_t bytes_read = gzread(compressed_mem, temp_page, chunk_size); if (bytes_read == 0) { break; } + + // restore checkpoint hardware status to device + if (cpt_offset < get_gcpt_mmio_size()) { + assert(get_gcpt_mmio_base()); + memcpy(get_gcpt_mmio_base() + cpt_offset, temp_page, chunk_size); + + cpt_offset += chunk_size; + continue; + } + for (uint32_t x = 0; x < bytes_read; x++) { pmem_current = pmem_start + curr_size + x; uint8_t read_data = *(temp_page + x); @@ -66,7 +84,7 @@ long load_gz_img(const char *filename) { return curr_size; } -long load_zstd_img(const char *filename){ +long load_zstd_img(const char *filename) { assert(filename); int fd = -1; @@ -141,8 +159,14 @@ long load_zstd_img(const char *filename){ uint8_t *pmem_start = (uint8_t *)guest_to_host(RESET_VECTOR); uint64_t *pmem_current; + // def checkpoint restore size + int64_t cpt_offset = 0; + extern uint8_t *get_gcpt_mmio_base(); + extern uint64_t get_gcpt_mmio_size(); + // decompress and write in memory uint64_t total_write_size = 0; + while (total_write_size < MEMORY_SIZE) { ZSTD_outBuffer output = {decompress_file_buffer, decompress_file_buffer_size * sizeof(uint64_t), 0}; @@ -164,6 +188,14 @@ long load_zstd_img(const char *filename){ assert(decompress_file_buffer_size * sizeof(uint64_t) == output.pos); + if (cpt_offset < get_gcpt_mmio_size()) { + assert(get_gcpt_mmio_base()); + memcpy(get_gcpt_mmio_base() + cpt_offset, decompress_file_buffer, output.pos); + + cpt_offset += output.pos; + continue; + } + for (uint64_t x = 0; x < decompress_file_buffer_size; x++) { pmem_current = (uint64_t *)(pmem_start + total_write_size) + x; uint64_t read_data = *(decompress_file_buffer + x); diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 2dd3e1c1b..a57f6c749 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -229,6 +229,7 @@ static inline int parse_args(int argc, char *argv[]) { } case 14: { + // --using-gcpt-device extern void set_using_gcpt_mmio(); set_using_gcpt_mmio(); break; @@ -278,6 +279,7 @@ static inline int parse_args(int argc, char *argv[]) { printf("\t--manual-oneshot-cpt Manually take one-shot cpt by send signal.\n"); printf("\t--manual-uniform-cpt Manually take uniform cpt by send signal.\n"); printf("\t--checkpoint-format Specify the checkpoint format('gz' or 'zstd'), default: 'gz'.\n"); + printf("\t--using-gcpt-device Specify using device store hardware status or not\n"); // printf("\t--map-cpt map to this file as pmem, which can be treated as a checkpoint.\n"); //comming back soon printf("\t--simpoint-profile simpoint profiling\n"); @@ -345,7 +347,12 @@ void init_monitor(int argc, char *argv[]) { /* Perform ISA dependent initialization. */ init_isa(); - int64_t img_size = 0; + /* Initialize devices. */ + init_device(); + + // when there is a gcpt[restorer], we put bbl after gcpt[restorer] + uint64_t bbl_start = 0; + long img_size = 0; // how large we should copy for difftest assert(img_file); uint64_t bbl_start = RESET_VECTOR; @@ -377,9 +384,6 @@ void init_monitor(int argc, char *argv[]) { /* Initialize differential testing. */ init_difftest(diff_so_file, img_size, difftest_port); - /* Initialize devices. */ - init_device(); - #endif /* Compile the regular expressions. */ From 9372be8a7195bfeb570aaeb3189ddad27e06b0f4 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 4 Dec 2024 12:06:27 +0800 Subject: [PATCH 07/40] fix ng checkpoint Signed-off-by: jiaxiaoyu --- src/checkpoint/serializer.cpp | 213 ++++++++++++++++++---------------- src/monitor/monitor.c | 55 +++++---- 2 files changed, 143 insertions(+), 125 deletions(-) diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index 756867eed..76946f033 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -46,9 +46,7 @@ using std::numeric_limits; using std::string; using std::to_string; -Serializer::Serializer() - : IntRegAddr(0){} - +Serializer Serializer(); extern "C" { uint8_t *get_pmem(); @@ -67,57 +65,52 @@ extern uint64_t get_gcpt_mmio_size(); } #ifdef CONFIG_MEM_COMPRESS -void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr) { +void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr) { // We must dump registers before memory to store them in the Generic Arch CPT assert(regDumped); const size_t PMEM_SIZE = MEMORY_SIZE; const size_t GCPT_MMIO_SIZE = get_gcpt_mmio_size(); - uint8_t *pmem = pmem_addr; - uint8_t *gcpt = gcpt_mmio_addr; - Log("Host physical address: %p size: %lx", pmem, PMEM_SIZE); - Log("Host gcpt address: %p size: %lx", gcpt, GCPT_MMIO_SIZE); - - if (restorer) { - FILE *restore_fp = fopen(restorer, "rb"); - if (!restore_fp) { - xpanic("Cannot open restorer %s\n", restorer); - } - - uint32_t restorer_size = 0xa000; - fseek(restore_fp, 0, SEEK_SET); - assert(restorer_size == fread(pmem, 1, restorer_size, restore_fp)); - fclose(restore_fp); - - Log("Put gcpt restorer %s to start of pmem", restorer); - } + Log("Host physical address: %p size: %lx", pmem_addr, PMEM_SIZE); + Log("Host gcpt address: %p size: %lx", gcpt_mmio_addr, GCPT_MMIO_SIZE); - string filepath; + string base_file_path; + string flash_file_path; + string memory_file_path; if (checkpoint_state == SimpointCheckpointing) { - filepath = pathManager.getOutputPath() + "_" + to_string(simpoint2Weights.begin()->first) + "_" + + base_file_path = pathManager.getOutputPath() + "_" + to_string(simpoint2Weights.begin()->first) + "_" + to_string(simpoint2Weights.begin()->second); } else { - filepath = pathManager.getOutputPath() + "_" + to_string(inst_count); + base_file_path = pathManager.getOutputPath() + "_" + to_string(inst_count); } if (compress_file_format == GZ_FORMAT) { Log("Using GZ format generate checkpoint"); - filepath += "_.gz"; - gzFile compressed_mem = gzopen(filepath.c_str(), "wb"); - if (compressed_mem == nullptr) { - cerr << "Failed to open " << filepath << endl; + flash_file_path += "_flash_.gz"; + memory_file_path += "_memory_.gz"; + gzFile flash_compressed_mem = gzopen(flash_file_path.c_str(), "wb"); + gzFile memory_compressed_mem = gzopen(memory_file_path.c_str(), "wb"); + if (flash_compressed_mem == nullptr) { + cerr << "Failed to open " << flash_file_path << endl; xpanic("Can't open physical memory checkpoint file!\n"); } else { - cout << "Opening " << filepath << " as checkpoint output file" << endl; + cout << "Opening " << flash_file_path << " as checkpoint output file" << endl; + } + + if (memory_compressed_mem == nullptr) { + cerr << "Failed to open " << memory_file_path << endl; + xpanic("Can't open physical memory checkpoint file!\n"); + } else { + cout << "Opening " << memory_file_path << " as checkpoint output file" << endl; } uint64_t pass_size = 0; - if (using_gcpt_mmio) { + if (write_to_flash) { for (uint64_t gcpt_written = 0; gcpt_written < GCPT_MMIO_SIZE; gcpt_written += pass_size) { pass_size = numeric_limits::max() < ((int64_t)GCPT_MMIO_SIZE - (int64_t)gcpt_written) ? numeric_limits::max() : ((int64_t)GCPT_MMIO_SIZE - (int64_t)gcpt_written); - if (gzwrite(compressed_mem, gcpt + gcpt_written, (uint32_t)pass_size) != (int)pass_size) { + if (gzwrite(flash_compressed_mem, gcpt_mmio_addr + gcpt_written, (uint32_t)pass_size) != (int)pass_size) { xpanic("Write failed on physical memory checkpoint file\n"); } Log("Written 0x%lx bytes\n", pass_size); @@ -131,61 +124,77 @@ void Serializer::serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_ ? numeric_limits::max() : ((int64_t)PMEM_SIZE - (int64_t)written); - if (gzwrite(compressed_mem, pmem + written, (uint32_t)pass_size) != (int)pass_size) { + if (gzwrite(memory_compressed_mem, pmem_addr + written, (uint32_t)pass_size) != (int)pass_size) { xpanic("Write failed on physical memory checkpoint file\n"); } Log("Written 0x%lx bytes\n", pass_size); } - if (gzclose(compressed_mem)) { - xpanic("Close failed on physical memory checkpoint file\n"); + if (gzclose(flash_compressed_mem)) { + xpanic("Close failed on physical checkpoint file\n"); + } + if (gzclose(memory_compressed_mem)) { + xpanic("Close failed on physical checkpoint file\n"); } + } else if (compress_file_format == ZSTD_FORMAT) { Log("Using ZSTD format generate checkpoint"); - filepath += "_.zstd"; - Log("Opening %s as checkpoint output file", filepath.c_str()); + flash_file_path += "_flash_.zstd"; + memory_file_path += "_memory_.zstd"; + + Log("Opening %s as checkpoint output file", flash_file_path.c_str()); + Log("Opening %s as memory output file", memory_file_path.c_str()); // zstd compress - size_t gcpt_and_pmem_size; - if (using_gcpt_mmio) { - gcpt_and_pmem_size = PMEM_SIZE + GCPT_MMIO_SIZE; - }else { - gcpt_and_pmem_size = PMEM_SIZE; - } - Log("Gcpt and pmem size 0x%lx", gcpt_and_pmem_size); + size_t flash_size = GCPT_MMIO_SIZE; + size_t memory_size = PMEM_SIZE; - size_t const compress_buffer_size = ZSTD_compressBound(gcpt_and_pmem_size); - uint8_t *const compress_buffer = (uint8_t*)malloc(compress_buffer_size); - assert(compress_buffer); + size_t const flash_compress_buffer_size = ZSTD_compressBound(flash_size); + size_t const memory_compress_buffer_size = ZSTD_compressBound(memory_size); + uint8_t *const flash_compress_buffer = (uint8_t*)malloc(flash_compress_buffer_size); + uint8_t *const memory_compress_buffer = (uint8_t*)malloc(memory_compress_buffer_size); + assert(flash_compress_buffer); + assert(memory_compress_buffer); // compress gcpt device memory - size_t gcpt_compress_size = 0; - if (using_gcpt_mmio) { - gcpt_compress_size = ZSTD_compress(compress_buffer, compress_buffer_size, gcpt, GCPT_MMIO_SIZE, 1); - assert(gcpt_compress_size <= compress_buffer_size && gcpt_compress_size != 0); - Log("compress gcpt success, compress size %ld", gcpt_compress_size); + size_t flash_compress_size = 0; + if (write_to_flash) { + flash_compress_size = ZSTD_compress(flash_compress_buffer, flash_compress_buffer_size, gcpt_mmio_addr, GCPT_MMIO_SIZE, 1); + assert(flash_compress_size <= flash_compress_buffer_size && flash_compress_size != 0); + Log("compress gcpt success, compress size %ld", flash_compress_size); } - size_t pmem_compress_size = ZSTD_compress(compress_buffer + gcpt_compress_size, compress_buffer_size, pmem, PMEM_SIZE, 1); - assert(pmem_compress_size + gcpt_compress_size <= compress_buffer_size && pmem_compress_size != 0); - Log("pmem compress success, compress size %ld",pmem_compress_size); + size_t memory_compress_size = ZSTD_compress(memory_compress_buffer, memory_compress_buffer_size, pmem_addr, PMEM_SIZE, 1); + assert(memory_compress_size <= memory_compress_buffer_size && memory_compress_size != 0); + Log("pmem compress success, compress size %ld", memory_compress_size); + + FILE *flash_compress_file = fopen(flash_file_path.c_str(), "wb"); + size_t flash_fw_size = fwrite(flash_compress_buffer, 1, flash_compress_size, flash_compress_file); - FILE *compress_file = fopen(filepath.c_str(), "wb"); - size_t fw_size = fwrite(compress_buffer, 1, pmem_compress_size + gcpt_compress_size, compress_file); + FILE *memory_compress_file = fopen(memory_file_path.c_str(), "wb"); + size_t memory_fw_size = fwrite(memory_compress_buffer, 1, memory_compress_size, memory_compress_file); + + if (flash_fw_size != flash_compress_size || flash_fw_size != memory_fw_size) { + fclose(flash_compress_file); + fclose(memory_compress_file); + free(flash_compress_buffer); + free(memory_compress_buffer); + xpanic("file write error: %s : %s, %s : %s \n", flash_file_path.c_str(), strerror(errno), memory_file_path.c_str(), strerror(errno)); + } - if (fw_size != (size_t)pmem_compress_size + (size_t)gcpt_compress_size) { - fclose(compress_file); - free(compress_buffer); - xpanic("file write error: %s : %s \n", filepath.c_str(), strerror(errno)); + if (fclose(flash_compress_file)) { + free(flash_compress_buffer); + xpanic("file close error: %s : %s \n", base_file_path.c_str(), strerror(errno)); } - if (fclose(compress_file)) { - free(compress_buffer); - xpanic("file close error: %s : %s \n", filepath.c_str(), strerror(errno)); + if (fclose(memory_compress_file)) { + free(memory_compress_buffer); + xpanic("file close error: %s : %s \n", base_file_path.c_str(), strerror(errno)); } - free(compress_buffer); + free(flash_compress_buffer); + free(memory_compress_buffer); } else { xpanic("You need to specify the compress file format using: --checkpoint-format\n"); } @@ -200,7 +209,8 @@ void Serializer::serializePMem(uint64_t inst_count) {} #ifdef CONFIG_MEM_COMPRESS extern void csr_writeback(); -void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { +void Serializer::serializeRegs(bool write_to_flash, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { + // int reg uint64_t buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->int_reg_cpt_addr; auto *intRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { @@ -210,6 +220,7 @@ void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_add buffer_start, buffer_start + 32 * 8, cpt_percpu_layout->int_reg_cpt_addr, cpt_percpu_layout->int_reg_cpt_addr + 32 * 8); + // fp reg #ifndef CONFIG_FPU_NONE buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->float_reg_cpt_addr; auto *floatRegCpt = (uint64_t *)(buffer_start); @@ -221,6 +232,7 @@ void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_add cpt_percpu_layout->float_reg_cpt_addr + 32 * 8); #endif // CONFIG_FPU_NONE + // rvv reg #ifdef CONFIG_RVV buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->vector_reg_cpt_addr; auto *vectorRegCpt = (uint64_t *)(buffer_start); @@ -234,57 +246,57 @@ void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_add cpt_percpu_layout->vector_reg_cpt_addr + 32 * 8 * VENUM64); #endif // CONFIG_RVV + // pc buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->pc_cpt_addr; auto *pc = (uint64_t *)(buffer_start); *pc = cpu.pc; Log("Writing PC: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", cpu.pc, buffer_start, buffer_start + 8, cpt_percpu_layout->pc_cpt_addr, cpt_percpu_layout->pc_cpt_addr + 8); + // csr reg + // donot need reset mip.x buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->csr_reg_cpt_addr; auto *csrCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 4096; i++) { - rtlreg_t val = csr_array[i]; - - if ((void *)mip == (void *)&csr_array[i]) { - mip_t mip_tmp = *mip; - if (mip_tmp.mtip) { - mip_tmp.mtip = 0; - } - val = mip_tmp.val; - } - - *(csrCpt + i) = val; - + *(csrCpt + i) = csr_array[i]; if (csr_array[i] != 0) { Log("CSR id: 0x%x, value: 0x%lx", i, *(csrCpt + i)); } } - // prepare mstatus - mstatus_t *mstatus_for_cpt = (mstatus_t *)&csrCpt[0x300]; - mstatus_for_cpt->mpie = mstatus_for_cpt->mie; - mstatus_for_cpt->mie = 0; - mstatus_for_cpt->mpp = cpu.mode; + // priv mode + buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mode_cpt_addr; + auto *mode_flag = (uint64_t *)(buffer_start); + *mode_flag = cpu.mode; + Log("Record mode flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + cpu.mode, buffer_start, buffer_start + 8, cpt_percpu_layout->mode_cpt_addr, + cpt_percpu_layout->mode_cpt_addr + 8); + + if (*mode_flag == PRV_M) { + Log("Generate this checkpoint from M mode !!!!!!!!!!!!!!"); + } + if (*mode_flag != PRV_M) { + // prepare mstatus + mstatus_t *tmp_mstatus = (mstatus_t *)&csrCpt[0x300]; + tmp_mstatus->mpie = tmp_mstatus->mie; + tmp_mstatus->mie = 0; + tmp_mstatus->mpp = cpu.mode; #ifdef CONFIG_RVH - // checkpoint ub: mpp = 3, mpv = 1 - mstatus_prepare->mpv=cpu.v; + // checkpoint ub: mpp = 3, mpv = 1 + tmp_mstatus->mpv = cpu.v; #endif - // prepare mepc - mepc_t *mepc_for_cpt = (mepc_t *)&csrCpt[0x341]; - mepc_for_cpt->val = cpu.pc; + // prepare mepc + mepc_t *mepc_for_cpt = (mepc_t *)&csrCpt[0x341]; + mepc_for_cpt->val = cpu.pc; + + } Log("Writing CSR to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr [0x%lx, 0x%lx)", buffer_start, buffer_start + 4096 * 8, cpt_percpu_layout->csr_reg_cpt_addr, cpt_percpu_layout->csr_reg_cpt_addr + 4096 * 8); - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mode_cpt_addr; - auto *mode_flag = (uint64_t *)(buffer_start); - *mode_flag = cpu.mode; - Log("Record mode flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", - cpu.mode, buffer_start, buffer_start + 8, cpt_percpu_layout->mode_cpt_addr, - cpt_percpu_layout->mode_cpt_addr + 8); - + // time buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mtime_cpt_addr; auto *mtime = (uint64_t *)(buffer_start); extern word_t paddr_read(paddr_t addr, int len, int type, int mode, vaddr_t vaddr); @@ -293,7 +305,7 @@ void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_add buffer_start, buffer_start + 8, cpt_percpu_layout->mtime_cpt_addr, cpt_percpu_layout->mtime_cpt_addr + 8); buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mtime_cmp_cpt_addr; - auto *mtime_cmp = (uint64_t *) (get_pmem() + MTIMECMPAddr); + auto *mtime_cmp = (uint64_t *)(buffer_start) + (0 * 8); *mtime_cmp = ::paddr_read(CLINT_MMIO+0x4000, 8, MEM_TYPE_READ, MEM_TYPE_READ, MODE_M, CLINT_MMIO+0x4000); Log("Record time_cmp flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", *mtime_cmp, buffer_start, buffer_start + 8, cpt_percpu_layout->mtime_cmp_cpt_addr, @@ -305,21 +317,21 @@ void Serializer::serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_add void Serializer::serializeRegs() {} #endif -void Serializer::serialize(uint64_t inst_count, bool using_gcpt_mmio) { +void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { #ifdef CONFIG_MEM_COMPRESS checkpoint_header cpt_header = default_cpt_header; single_core_rvgc_rvv_rvh_memlayout cpt_percpu_layout = default_cpt_percpu_layout; uint64_t serialize_reg_base_addr; encode_cpt_header(&cpt_header, &cpt_percpu_layout); - if (using_gcpt_mmio) { + if (write_to_flash) { serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_gcpt_mmio_base(); } else { serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_pmem(); } - serializeRegs(using_gcpt_mmio, (uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); - serializePMem(inst_count, using_gcpt_mmio, get_pmem(), get_gcpt_mmio_base()); + serializeRegs(write_to_flash, (uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); + serializePMem(inst_count, write_to_flash, get_pmem(), get_gcpt_mmio_base()); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); #endif @@ -410,7 +422,6 @@ void Serializer::notify_taken(uint64_t i) { } } -Serializer serializer; uint64_t Serializer::next_index(){ uint64_t index=0; if (checkpoint_state==SimpointCheckpointing&&!serializer.simpoint2Weights.empty()) { diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index a57f6c749..58c996734 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -44,6 +44,7 @@ static int batch_mode = false; static int difftest_port = 1234; char *max_instr = NULL; char compress_file_format = 0; // default is gz +static char* checkpoint_flash_path = NULL; extern char *mapped_cpt_file; // defined in paddr.c extern bool map_image_as_output_cpt; @@ -82,6 +83,8 @@ void sig_handler(int signum) { } } + + static inline int parse_args(int argc, char *argv[]) { const struct option table[] = { {"batch" , no_argument , NULL, 'b'}, @@ -94,26 +97,26 @@ static inline int parse_args(int argc, char *argv[]) { {"help" , no_argument , NULL, 'h'}, // path setting - {"output-base-dir" , required_argument, NULL, 'D'}, - {"workload-name" , required_argument, NULL, 'w'}, - {"config-name" , required_argument, NULL, 'C'}, + {"output-base-dir" , required_argument, NULL, 'D'}, + {"workload-name" , required_argument, NULL, 'w'}, + {"config-name" , required_argument, NULL, 'C'}, // restore cpt - {"restore" , no_argument , NULL, 'c'}, - {"cpt-restorer" , required_argument, NULL, 'r'}, - {"map-img-as-outcpt" , no_argument , NULL, 13}, + {"restore" , required_argument, NULL, 'c'}, + {"cpt-restorer" , required_argument, NULL, 'r'}, + {"map-img-as-outcpt" , no_argument , NULL, 13}, // take cpt - {"simpoint-dir" , required_argument, NULL, 'S'}, - {"uniform-cpt" , no_argument , NULL, 'u'}, - {"manual-oneshot-cpt" , no_argument , NULL, 11}, - {"manual-uniform-cpt" , no_argument , NULL, 9}, - {"cpt-interval" , required_argument, NULL, 5}, - {"warmup-interval" , required_argument, NULL, 14}, - {"cpt-mmode" , no_argument , NULL, 7}, - {"map-cpt" , required_argument, NULL, 10}, - {"checkpoint-format" , required_argument, NULL, 12}, - {"using-gcpt-device" , no_argument , NULL, 14}, + {"simpoint-dir" , required_argument, NULL, 'S'}, + {"uniform-cpt" , no_argument , NULL, 'u'}, + {"manual-oneshot-cpt" , no_argument , NULL, 11}, + {"manual-uniform-cpt" , no_argument , NULL, 9}, + {"cpt-interval" , required_argument, NULL, 5}, + {"warmup-interval" , required_argument, NULL, 14}, + {"cpt-mmode" , no_argument , NULL, 7}, + {"map-cpt" , required_argument, NULL, 10}, + {"checkpoint-format" , required_argument, NULL, 12}, + {"next-generation-checkpoint" , no_argument , NULL, 16}, // profiling {"simpoint-profile" , no_argument , NULL, 3}, @@ -151,6 +154,7 @@ static inline int parse_args(int argc, char *argv[]) { case 'c': checkpoint_restoring = true; + checkpoint_flash_path = optarg; Log("Restoring from checkpoint"); break; @@ -228,8 +232,8 @@ static inline int parse_args(int argc, char *argv[]) { break; } - case 14: { - // --using-gcpt-device + case 16: { + // --next-generation-checkpoint extern void set_using_gcpt_mmio(); set_using_gcpt_mmio(); break; @@ -279,7 +283,7 @@ static inline int parse_args(int argc, char *argv[]) { printf("\t--manual-oneshot-cpt Manually take one-shot cpt by send signal.\n"); printf("\t--manual-uniform-cpt Manually take uniform cpt by send signal.\n"); printf("\t--checkpoint-format Specify the checkpoint format('gz' or 'zstd'), default: 'gz'.\n"); - printf("\t--using-gcpt-device Specify using device store hardware status or not\n"); + printf("\t--next-generation-checkpoint Specify using flash store hardware status or not\n"); // printf("\t--map-cpt map to this file as pmem, which can be treated as a checkpoint.\n"); //comming back soon printf("\t--simpoint-profile simpoint profiling\n"); @@ -351,16 +355,19 @@ void init_monitor(int argc, char *argv[]) { init_device(); // when there is a gcpt[restorer], we put bbl after gcpt[restorer] - uint64_t bbl_start = 0; long img_size = 0; // how large we should copy for difftest assert(img_file); uint64_t bbl_start = RESET_VECTOR; - if (restorer) { - bbl_start += CONFIG_BBL_OFFSET_WITH_CPT; - } +#define RESET_FLASH 0x1000 + uint64_t gcpt_start = RESET_FLASH; + img_size = load_img(img_file, "image (checkpoint/bare metal app/bbl) form cmdline", bbl_start, 0); + if (checkpoint_restoring){ + img_size = load_img(checkpoint_flash_path, "checkpoint from cmdline", gcpt_start, 0); + } + if (restorer) { FILE *restore_fp = fopen(restorer, "rb"); Assert(restore_fp, "Can not open '%s'", restorer); @@ -378,7 +385,7 @@ void init_monitor(int argc, char *argv[]) { fclose(restore_fp); - load_img(restorer, "Gcpt restorer form cmdline", RESET_VECTOR, restore_size); + load_img(restorer, "Gcpt restorer form cmdline", gcpt_start, restore_size); } /* Initialize differential testing. */ From 492aa136c08839de5cc9dfee8000eb14cdbe9788 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 6 Dec 2024 15:18:53 +0800 Subject: [PATCH 08/40] feat(libcheckpoint): add support for libcheckpoint Signed-off-by: jiaxiaoyu --- Makefile | 5 +---- include/checkpoint/serializer.h | 4 ---- src/checkpoint/serializer.cpp | 16 ++++++++-------- src/device/device.c | 1 - src/device/flash.c | 8 ++++++++ src/device/gcpt.c | 32 -------------------------------- src/monitor/image_loader.c | 22 +++++++++++----------- 7 files changed, 28 insertions(+), 60 deletions(-) delete mode 100644 src/device/gcpt.c diff --git a/Makefile b/Makefile index f86dfe834..d0be2faf5 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,6 @@ ENGINE ?= $(call remove_quote,$(CONFIG_ENGINE)) INC_DIR += $(NEMU_HOME)/src/engine/$(ENGINE) DIRS-y += src/engine/$(ENGINE) -INC_DIR += $(NEMU_HOME)/include/checkpoint -DIRS-y += src/checkpoint src/profiling # profiling.c - DIRS-$(CONFIG_MODE_USER) += src/user SRCS-y += src/nemu-main.c @@ -60,7 +57,6 @@ SRCS-$(CONFIG_HAS_AUDIO) += src/device/audio.c SRCS-$(CONFIG_HAS_DISK) += src/device/disk.c SRCS-$(CONFIG_HAS_SDCARD) += src/device/sdcard.c SRCS-$(CONFIG_HAS_FLASH) += src/device/flash.c -SRCS-y += src/device/gcpt.c DIRS-y += src/profiling @@ -73,6 +69,7 @@ SRCS-y += resource/nanopb/pb_common.c SRCS-y += resource/nanopb/pb_decode.c SRCS-y += resource/nanopb/pb_encode.c INC_DIR += resource/nanopb +INC_DIR += include/checkpoint SRCS-y += $(patsub %.proto,%.pb.c,(shell find $(DIRS-y) -name "*.proto")) SRCS = $(SRCS-y) diff --git a/include/checkpoint/serializer.h b/include/checkpoint/serializer.h index 5d97b87f1..a1321a7d4 100644 --- a/include/checkpoint/serializer.h +++ b/include/checkpoint/serializer.h @@ -37,8 +37,6 @@ class Serializer void serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); - explicit Serializer(); - void init(); bool shouldTakeCpt(uint64_t num_insts); @@ -55,8 +53,6 @@ class Serializer uint64_t cptID; std::string weightIndicator; - const int IntRegAddr; - bool regDumped{false}; std::map simpoint2Weights; diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index 76946f033..e60a0ac9d 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -46,8 +46,6 @@ using std::numeric_limits; using std::string; using std::to_string; -Serializer Serializer(); - extern "C" { uint8_t *get_pmem(); word_t paddr_read(paddr_t addr, int len, int type, int trap_type, int mode, vaddr_t vaddr); @@ -56,9 +54,9 @@ uint8_t *guest_to_host(paddr_t paddr); extern void log_buffer_flush(); extern void log_file_flush(); extern unsigned long MEMORY_SIZE; -extern uint8_t* get_gcpt_mmio_base(); +extern uint8_t* get_flash_base(); void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); -extern uint64_t get_gcpt_mmio_size(); +extern uint64_t get_flash_size(); #include #include #include @@ -69,7 +67,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t // We must dump registers before memory to store them in the Generic Arch CPT assert(regDumped); const size_t PMEM_SIZE = MEMORY_SIZE; - const size_t GCPT_MMIO_SIZE = get_gcpt_mmio_size(); + const size_t GCPT_MMIO_SIZE = get_flash_size(); Log("Host physical address: %p size: %lx", pmem_addr, PMEM_SIZE); Log("Host gcpt address: %p size: %lx", gcpt_mmio_addr, GCPT_MMIO_SIZE); @@ -325,13 +323,13 @@ void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { encode_cpt_header(&cpt_header, &cpt_percpu_layout); if (write_to_flash) { - serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_gcpt_mmio_base(); + serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_flash_base(); } else { serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_pmem(); } serializeRegs(write_to_flash, (uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); - serializePMem(inst_count, write_to_flash, get_pmem(), get_gcpt_mmio_base()); + serializePMem(inst_count, write_to_flash, get_pmem(), get_flash_base()); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); #endif @@ -422,6 +420,8 @@ void Serializer::notify_taken(uint64_t i) { } } +Serializer serializer; + uint64_t Serializer::next_index(){ uint64_t index=0; if (checkpoint_state==SimpointCheckpointing&&!serializer.simpoint2Weights.empty()) { @@ -436,7 +436,7 @@ uint64_t Serializer::next_index(){ extern "C" { void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout){ - assert(cpt_header_encode(get_gcpt_mmio_base(), cpt_header, cpt_percpu_layout)); + assert(cpt_header_encode(get_flash_base(), cpt_header, cpt_percpu_layout)); } void init_serializer() { diff --git a/src/device/device.c b/src/device/device.c index 5cdfe301e..2b194edfe 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -36,7 +36,6 @@ void init_disk(); void init_sdcard(); void init_flash(); void load_flash_contents(const char *); -void init_gcpt(); void send_key(uint8_t, bool); void vga_update_screen(); diff --git a/src/device/flash.c b/src/device/flash.c index 4840f0e70..9c4429a34 100644 --- a/src/device/flash.c +++ b/src/device/flash.c @@ -22,6 +22,14 @@ static uint8_t *flash_base = (uint8_t *)0xf0000000ul; static FILE *fp = NULL; +uint8_t* get_flash_base(){ + return flash_base; +} + +uint64_t get_flash_size(){ + return CONFIG_FLASH_SIZE; +} + static void flash_io_handler(uint32_t offset, int len, bool is_write) { Assert(!is_write, "write to flash is illegal"); return; diff --git a/src/device/gcpt.c b/src/device/gcpt.c deleted file mode 100644 index 48ae5ce95..000000000 --- a/src/device/gcpt.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "device/map.h" -#include - -#define CONFIG_GCPT_MMIO 0x60000000 -#define GCPT_MEM_SIZE (128 * 1024 * 1024) - -// read gcpt memory do not need any handle, just resturn data -static void gcpt_io_handler(uint32_t offset, int len, bool is_write) { -} - -static struct { - uint8_t *mmio_address; - uint8_t *host_address; - uint64_t size; -} gcpt_info = { - .size = GCPT_MEM_SIZE, - .host_address = 0, - .mmio_address = (uint8_t *)CONFIG_GCPT_MMIO, -}; - -uint8_t *get_gcpt_mmio_base() { - return gcpt_info.host_address; -} - -uint64_t get_gcpt_mmio_size(){ - return gcpt_info.size; -} - -void init_gcpt() { - gcpt_info.host_address = new_space(gcpt_info.size); - add_mmio_map("gcpt", (uint64_t)gcpt_info.mmio_address, gcpt_info.host_address, gcpt_info.size, gcpt_io_handler); -} diff --git a/src/monitor/image_loader.c b/src/monitor/image_loader.c index d1a804c39..8b3db014c 100644 --- a/src/monitor/image_loader.c +++ b/src/monitor/image_loader.c @@ -13,7 +13,7 @@ * See the Mulan PSL v2 for more details. ***************************************************************************************/ -#include "checkpoint.pb.h" +#include "checkpoint/checkpoint.pb.h" #include "debug.h" #include #include @@ -47,8 +47,8 @@ long load_gz_img(const char *filename) { uint64_t curr_size = 0; uint64_t cpt_offset = 0; - extern uint8_t *get_gcpt_mmio_base(); - extern uint64_t get_gcpt_mmio_size(); + extern uint8_t *get_flash_base(); + extern uint64_t get_flash_size(); while (curr_size < MEMORY_SIZE) { uint32_t bytes_read = gzread(compressed_mem, temp_page, chunk_size); @@ -57,9 +57,9 @@ long load_gz_img(const char *filename) { } // restore checkpoint hardware status to device - if (cpt_offset < get_gcpt_mmio_size()) { - assert(get_gcpt_mmio_base()); - memcpy(get_gcpt_mmio_base() + cpt_offset, temp_page, chunk_size); + if (cpt_offset < get_flash_size()) { + assert(get_flash_base()); + memcpy(get_flash_base() + cpt_offset, temp_page, chunk_size); cpt_offset += chunk_size; continue; @@ -161,8 +161,8 @@ long load_zstd_img(const char *filename) { // def checkpoint restore size int64_t cpt_offset = 0; - extern uint8_t *get_gcpt_mmio_base(); - extern uint64_t get_gcpt_mmio_size(); + extern uint8_t *get_flash_base(); + extern uint64_t get_flash_size(); // decompress and write in memory uint64_t total_write_size = 0; @@ -188,9 +188,9 @@ long load_zstd_img(const char *filename) { assert(decompress_file_buffer_size * sizeof(uint64_t) == output.pos); - if (cpt_offset < get_gcpt_mmio_size()) { - assert(get_gcpt_mmio_base()); - memcpy(get_gcpt_mmio_base() + cpt_offset, decompress_file_buffer, output.pos); + if (cpt_offset < get_flash_size()) { + assert(get_flash_base()); + memcpy(get_flash_base() + cpt_offset, decompress_file_buffer, output.pos); cpt_offset += output.pos; continue; From 46ecdc2c542d8c9d0ff192c70d0a2126ee0d8536 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Tue, 10 Dec 2024 17:02:35 +0800 Subject: [PATCH 09/40] feat(libcheckpoint): migrate to libcheckpoint memlayout Signed-off-by: jiaxiaoyu --- include/checkpoint/fill_protobuf.h | 30 ++++---- include/checkpoint/serializer.h | 2 +- src/checkpoint/serializer.cpp | 119 ++++++++++++++++------------- 3 files changed, 83 insertions(+), 68 deletions(-) diff --git a/include/checkpoint/fill_protobuf.h b/include/checkpoint/fill_protobuf.h index 6b3f8b14a..497f373d3 100644 --- a/include/checkpoint/fill_protobuf.h +++ b/include/checkpoint/fill_protobuf.h @@ -15,21 +15,21 @@ static checkpoint_header default_cpt_header = { __attribute__((unused)) static single_core_rvgc_rvv_rvh_memlayout default_cpt_percpu_layout = { - .pc_cpt_addr = 0x0, - .mode_cpt_addr = 0x8, - .mtime_cpt_addr = 0x10, - .mtime_cmp_cpt_addr = 0x18, - .misc_done_cpt_addr = 0x20, - .misc_reserve = 0x28, - .int_reg_cpt_addr = 0x1000, - .int_reg_done = 0x1128, - .float_reg_cpt_addr = 0x1130, - .float_reg_done = 0x1230, - .csr_reg_cpt_addr = 0x1238, - .csr_reg_done = 0x9238, - .csr_reserve = 0x9240, - .vector_reg_cpt_addr = 0x11240, - .vector_reg_done = 0x13240, + .pc_cpt_addr = 0xECDB8, + .mode_cpt_addr = 0xECDC0, + .mtime_cpt_addr = 0xECDC8, + .mtime_cmp_cpt_addr = 0xECDD0, + .misc_done_cpt_addr = 0xECDD8, + .misc_reserve = 0xECDE0, + .int_reg_cpt_addr = 0xEDDE0, + .int_reg_done = 0xEDEE0, + .float_reg_cpt_addr = 0xEDEE8, + .float_reg_done = 0xEDFE8, + .csr_reg_cpt_addr = 0xEDFF0, + .csr_reg_done = 0xF5FF0, + .csr_reserve = 0xF5FF8, + .vector_reg_cpt_addr = 0xFDFF8, + .vector_reg_done = 0xFFFF8, }; int cpt_header_encode(void *gcpt_mmio, checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_memlayout); diff --git a/include/checkpoint/serializer.h b/include/checkpoint/serializer.h index a1321a7d4..b5d380777 100644 --- a/include/checkpoint/serializer.h +++ b/include/checkpoint/serializer.h @@ -35,7 +35,7 @@ class Serializer void serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr); - void serializeRegs(bool using_gcpt_mmio, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); + void serializeRegs(uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); void init(); diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index e60a0ac9d..13aee5d8b 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -84,17 +84,10 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t if (compress_file_format == GZ_FORMAT) { Log("Using GZ format generate checkpoint"); - flash_file_path += "_flash_.gz"; - memory_file_path += "_memory_.gz"; - gzFile flash_compressed_mem = gzopen(flash_file_path.c_str(), "wb"); + flash_file_path = base_file_path + "_flash_.gz"; + memory_file_path = base_file_path + "_memory_.gz"; gzFile memory_compressed_mem = gzopen(memory_file_path.c_str(), "wb"); - if (flash_compressed_mem == nullptr) { - cerr << "Failed to open " << flash_file_path << endl; - xpanic("Can't open physical memory checkpoint file!\n"); - } else { - cout << "Opening " << flash_file_path << " as checkpoint output file" << endl; - } - + gzFile flash_compressed_mem; if (memory_compressed_mem == nullptr) { cerr << "Failed to open " << memory_file_path << endl; xpanic("Can't open physical memory checkpoint file!\n"); @@ -104,6 +97,14 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t uint64_t pass_size = 0; if (write_to_flash) { + flash_compressed_mem = gzopen(flash_file_path.c_str(), "wb"); + if (flash_compressed_mem == nullptr) { + cerr << "Failed to open " << flash_file_path << endl; + xpanic("Can't open physical memory checkpoint file!\n"); + } else { + cout << "Opening " << flash_file_path << " as checkpoint output file" << endl; + } + for (uint64_t gcpt_written = 0; gcpt_written < GCPT_MMIO_SIZE; gcpt_written += pass_size) { pass_size = numeric_limits::max() < ((int64_t)GCPT_MMIO_SIZE - (int64_t)gcpt_written) ? numeric_limits::max() @@ -128,8 +129,10 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t Log("Written 0x%lx bytes\n", pass_size); } - if (gzclose(flash_compressed_mem)) { - xpanic("Close failed on physical checkpoint file\n"); + if(write_to_flash){ + if (gzclose(flash_compressed_mem)) { + xpanic("Close failed on physical checkpoint file\n"); + } } if (gzclose(memory_compressed_mem)) { xpanic("Close failed on physical checkpoint file\n"); @@ -138,8 +141,8 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t } else if (compress_file_format == ZSTD_FORMAT) { Log("Using ZSTD format generate checkpoint"); - flash_file_path += "_flash_.zstd"; - memory_file_path += "_memory_.zstd"; + flash_file_path += base_file_path + "_flash_.zstd"; + memory_file_path += base_file_path + "_memory_.zstd"; Log("Opening %s as checkpoint output file", flash_file_path.c_str()); Log("Opening %s as memory output file", memory_file_path.c_str()); @@ -150,40 +153,47 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t size_t const flash_compress_buffer_size = ZSTD_compressBound(flash_size); size_t const memory_compress_buffer_size = ZSTD_compressBound(memory_size); - uint8_t *const flash_compress_buffer = (uint8_t*)malloc(flash_compress_buffer_size); uint8_t *const memory_compress_buffer = (uint8_t*)malloc(memory_compress_buffer_size); + uint8_t *const flash_compress_buffer = (uint8_t*)malloc(flash_compress_buffer_size); + assert(flash_compress_buffer); assert(memory_compress_buffer); // compress gcpt device memory size_t flash_compress_size = 0; + FILE *flash_compress_file = NULL; + size_t flash_fw_size = 0; if (write_to_flash) { flash_compress_size = ZSTD_compress(flash_compress_buffer, flash_compress_buffer_size, gcpt_mmio_addr, GCPT_MMIO_SIZE, 1); assert(flash_compress_size <= flash_compress_buffer_size && flash_compress_size != 0); Log("compress gcpt success, compress size %ld", flash_compress_size); + + flash_compress_file = fopen(flash_file_path.c_str(), "wb"); + flash_fw_size = fwrite(flash_compress_buffer, 1, flash_compress_size, flash_compress_file); } size_t memory_compress_size = ZSTD_compress(memory_compress_buffer, memory_compress_buffer_size, pmem_addr, PMEM_SIZE, 1); assert(memory_compress_size <= memory_compress_buffer_size && memory_compress_size != 0); Log("pmem compress success, compress size %ld", memory_compress_size); - FILE *flash_compress_file = fopen(flash_file_path.c_str(), "wb"); - size_t flash_fw_size = fwrite(flash_compress_buffer, 1, flash_compress_size, flash_compress_file); - FILE *memory_compress_file = fopen(memory_file_path.c_str(), "wb"); size_t memory_fw_size = fwrite(memory_compress_buffer, 1, memory_compress_size, memory_compress_file); - if (flash_fw_size != flash_compress_size || flash_fw_size != memory_fw_size) { - fclose(flash_compress_file); + if (flash_fw_size != flash_compress_size || memory_fw_size != memory_compress_size) { + if(write_to_flash){ + fclose(flash_compress_file); + } fclose(memory_compress_file); free(flash_compress_buffer); free(memory_compress_buffer); xpanic("file write error: %s : %s, %s : %s \n", flash_file_path.c_str(), strerror(errno), memory_file_path.c_str(), strerror(errno)); } - if (fclose(flash_compress_file)) { - free(flash_compress_buffer); - xpanic("file close error: %s : %s \n", base_file_path.c_str(), strerror(errno)); + if(write_to_flash){ + if (fclose(flash_compress_file)) { + free(flash_compress_buffer); + xpanic("file close error: %s : %s \n", base_file_path.c_str(), strerror(errno)); + } } if (fclose(memory_compress_file)) { @@ -193,6 +203,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t free(flash_compress_buffer); free(memory_compress_buffer); + } else { xpanic("You need to specify the compress file format using: --checkpoint-format\n"); } @@ -207,53 +218,53 @@ void Serializer::serializePMem(uint64_t inst_count) {} #ifdef CONFIG_MEM_COMPRESS extern void csr_writeback(); -void Serializer::serializeRegs(bool write_to_flash, uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { +void Serializer::serializeRegs(uint8_t* serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { // int reg - uint64_t buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->int_reg_cpt_addr; - auto *intRegCpt = (uint64_t *)(buffer_start); + uint8_t* buffer_start = serialize_base_addr + cpt_percpu_layout->int_reg_cpt_addr; + uint64_t *intRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { *(intRegCpt + i) = cpu.gpr[i]._64; } - Log("Writing int registers to checkpoint memory @host_paddr: [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + Log("Writing int registers to checkpoint memory @host_paddr: [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", buffer_start, buffer_start + 32 * 8, cpt_percpu_layout->int_reg_cpt_addr, cpt_percpu_layout->int_reg_cpt_addr + 32 * 8); // fp reg #ifndef CONFIG_FPU_NONE - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->float_reg_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->float_reg_cpt_addr; auto *floatRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { *(floatRegCpt + i) = cpu.fpr[i]._64; } - Log("Writing float registers to checkpoint memory @host_paddr: [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + Log("Writing float registers to checkpoint memory @host_paddr: [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", buffer_start, buffer_start + 32 * 8, cpt_percpu_layout->float_reg_cpt_addr, cpt_percpu_layout->float_reg_cpt_addr + 32 * 8); #endif // CONFIG_FPU_NONE // rvv reg #ifdef CONFIG_RVV - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->vector_reg_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->vector_reg_cpt_addr; auto *vectorRegCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 32; i++) { for (unsigned j = 0; j < VENUM64; j++) { *(vectorRegCpt + (i * VENUM64) + j) = cpu.vr[i]._64[j]; } } - Log("Writing vector registers to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + Log("Writing vector registers to checkpoint memory @host_paddr [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", buffer_start, buffer_start + 32 * 8 * VENUM64, cpt_percpu_layout->vector_reg_cpt_addr, cpt_percpu_layout->vector_reg_cpt_addr + 32 * 8 * VENUM64); #endif // CONFIG_RVV // pc - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->pc_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->pc_cpt_addr; auto *pc = (uint64_t *)(buffer_start); *pc = cpu.pc; - Log("Writing PC: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", cpu.pc, + Log("Writing PC: 0x%lx to checkpoint memory @host_paddr [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", cpu.pc, buffer_start, buffer_start + 8, cpt_percpu_layout->pc_cpt_addr, cpt_percpu_layout->pc_cpt_addr + 8); // csr reg // donot need reset mip.x - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->csr_reg_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->csr_reg_cpt_addr; auto *csrCpt = (uint64_t *)(buffer_start); for (unsigned i = 0; i < 4096; i++) { *(csrCpt + i) = csr_array[i]; @@ -263,17 +274,13 @@ void Serializer::serializeRegs(bool write_to_flash, uint8_t *serialize_base_addr } // priv mode - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mode_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->mode_cpt_addr; auto *mode_flag = (uint64_t *)(buffer_start); *mode_flag = cpu.mode; - Log("Record mode flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + Log("Record mode flag: 0x%lx to checkpoint memory @host_paddr [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", cpu.mode, buffer_start, buffer_start + 8, cpt_percpu_layout->mode_cpt_addr, cpt_percpu_layout->mode_cpt_addr + 8); - if (*mode_flag == PRV_M) { - Log("Generate this checkpoint from M mode !!!!!!!!!!!!!!"); - } - if (*mode_flag != PRV_M) { // prepare mstatus mstatus_t *tmp_mstatus = (mstatus_t *)&csrCpt[0x300]; @@ -289,23 +296,29 @@ void Serializer::serializeRegs(bool write_to_flash, uint8_t *serialize_base_addr mepc_t *mepc_for_cpt = (mepc_t *)&csrCpt[0x341]; mepc_for_cpt->val = cpu.pc; + } else { + Log("Generate this checkpoint from M mode !!!!!!!!!!!!!!"); } - Log("Writing CSR to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr [0x%lx, 0x%lx)", buffer_start, + Log("Writing CSR to checkpoint memory @host_paddr [0x%p, 0x%p) @mem_layout_addr [0x%lx, 0x%lx)", buffer_start, buffer_start + 4096 * 8, cpt_percpu_layout->csr_reg_cpt_addr, cpt_percpu_layout->csr_reg_cpt_addr + 4096 * 8); + auto *flag = (uint64_t *)(serialize_base_addr + 0xECDB0); + *flag = CPT_MAGIC_BUMBER; + Log("Touching Flag: 0x%x at addr 0x%x", CPT_MAGIC_BUMBER, BOOT_FLAG_ADDR); + // time - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mtime_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->mtime_cpt_addr; auto *mtime = (uint64_t *)(buffer_start); extern word_t paddr_read(paddr_t addr, int len, int type, int mode, vaddr_t vaddr); *mtime = ::paddr_read(CLINT_MMIO+0xBFF8, 8, MEM_TYPE_READ, MEM_TYPE_READ, MODE_M, CLINT_MMIO+0xBFF8); - Log("Record time: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", *mtime, + Log("Record time: 0x%lx to checkpoint memory @host_paddr [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", *mtime, buffer_start, buffer_start + 8, cpt_percpu_layout->mtime_cpt_addr, cpt_percpu_layout->mtime_cpt_addr + 8); - buffer_start = (uint64_t)serialize_base_addr + cpt_percpu_layout->mtime_cmp_cpt_addr; + buffer_start = serialize_base_addr + cpt_percpu_layout->mtime_cmp_cpt_addr; auto *mtime_cmp = (uint64_t *)(buffer_start) + (0 * 8); *mtime_cmp = ::paddr_read(CLINT_MMIO+0x4000, 8, MEM_TYPE_READ, MEM_TYPE_READ, MODE_M, CLINT_MMIO+0x4000); - Log("Record time_cmp flag: 0x%lx to checkpoint memory @host_paddr [0x%lx, 0x%lx) @mem_layout_addr: [0x%lx, 0x%lx)", + Log("Record time_cmp flag: 0x%lx to checkpoint memory @host_paddr [0x%p, 0x%p) @mem_layout_addr: [0x%lx, 0x%lx)", *mtime_cmp, buffer_start, buffer_start + 8, cpt_percpu_layout->mtime_cmp_cpt_addr, cpt_percpu_layout->mtime_cmp_cpt_addr + 8); @@ -317,18 +330,20 @@ void Serializer::serializeRegs() {} void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { #ifdef CONFIG_MEM_COMPRESS - checkpoint_header cpt_header = default_cpt_header; + //checkpoint_header cpt_header = default_cpt_header; single_core_rvgc_rvv_rvh_memlayout cpt_percpu_layout = default_cpt_percpu_layout; - uint64_t serialize_reg_base_addr; - encode_cpt_header(&cpt_header, &cpt_percpu_layout); + uint8_t* serialize_reg_base_addr = NULL; + //encode_cpt_header(&cpt_header, &cpt_percpu_layout); if (write_to_flash) { - serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_flash_base(); + serialize_reg_base_addr = get_flash_base(); } else { - serialize_reg_base_addr = cpt_header.cpt_offset + (uint64_t)get_pmem(); + serialize_reg_base_addr = get_pmem(); } - serializeRegs(write_to_flash, (uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); + assert(serialize_reg_base_addr); + + serializeRegs((uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); serializePMem(inst_count, write_to_flash, get_pmem(), get_flash_base()); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); @@ -436,7 +451,7 @@ uint64_t Serializer::next_index(){ extern "C" { void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout){ - assert(cpt_header_encode(get_flash_base(), cpt_header, cpt_percpu_layout)); +// assert(cpt_header_encode(get_flash_base(), cpt_header, cpt_percpu_layout)); } void init_serializer() { From ba303bf007c9318f60d2e400f5ba83b117b50b0a Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Tue, 10 Dec 2024 17:10:59 +0800 Subject: [PATCH 10/40] feat(checkpoint): support generate checkpoint to memory archive and flash archive, and support load checkpoint from these files Signed-off-by: jiaxiaoyu --- include/memory/image_loader.h | 4 +-- src/cpu/difftest/dut.c | 1 + src/device/flash.c | 59 +++++++++++++++++++++++++++++++++-- src/isa/riscv32/init.c | 2 +- src/isa/riscv64/init.c | 25 +++------------ src/monitor/image_loader.c | 50 +++++++---------------------- src/monitor/monitor.c | 12 ++++--- 7 files changed, 85 insertions(+), 68 deletions(-) diff --git a/include/memory/image_loader.h b/include/memory/image_loader.h index b2ae74764..e7361ac54 100644 --- a/include/memory/image_loader.h +++ b/include/memory/image_loader.h @@ -19,9 +19,9 @@ #include -long load_gz_img(const char *filename); +long load_gz_img(const char *filename, uint64_t load_start, size_t img_size); -long load_zstd_img(const char *filename); +long load_zstd_img(const char *filename, uint64_t load_start, size_t img_size); long load_img(char *img_name, const char *which_img, uint64_t load_start, size_t img_size); diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index b250abc71..b13f7c525 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -110,6 +110,7 @@ void init_difftest(char *ref_so_file, long img_size, int port) { ref_difftest_init(port); ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF); + ref_difftest_memcpy(CONFIG_FLASH_START_ADDR, get_flash_base(), CONFIG_FLASH_SIZE, DIFFTEST_TO_REF); ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); } diff --git a/src/device/flash.c b/src/device/flash.c index 9c4429a34..4fe11ef6b 100644 --- a/src/device/flash.c +++ b/src/device/flash.c @@ -16,6 +16,7 @@ #include #include #include +#include // put flash below the physical memory and allow a max size of 256MB. // See the notes at paddr.c:79 for why we fix the address here. @@ -35,9 +36,54 @@ static void flash_io_handler(uint32_t offset, int len, bool is_write) { return; } +void convert_to_absolute_path(const char *input_path, char *output_path) { +#define PATH_MAX 4096 + if (input_path == NULL || output_path == NULL) { + fprintf(stderr, "Invalid input or output path\n"); + return; + } + + char expanded_path[PATH_MAX] = {0}; + + // Check for $(ENV) pattern + if (input_path[0] == '$' && input_path[1] == '(') { + const char *end = strchr(input_path, ')'); + if (end) { + char env_var[256] = {0}; + size_t var_length = end - input_path - 2; + + // Extract environment variable name + strncpy(env_var, input_path + 2, var_length); + env_var[var_length] = '\0'; + + // Get environment variable value + const char *env_value = getenv(env_var); + if (env_value) { + snprintf(expanded_path, sizeof(expanded_path), "%s%s", env_value, end + 1); + } else { + fprintf(stderr, "Environment variable %s not found\n", env_var); + return; + } + } else { + fprintf(stderr, "Invalid input format\n"); + return; + } + } else { + // If no $(ENV), copy the input path + strncpy(expanded_path, input_path, sizeof(expanded_path) - 1); + } + + // Convert to absolute path + if (realpath(expanded_path, output_path) == NULL) { + perror("realpath"); + } +#undef PATH_MAX +} + + void load_flash_contents(const char *flash_img) { // create mmap with zero contents - assert(CONFIG_FLASH_SIZE < 0x10000000UL); + assert(CONFIG_FLASH_SIZE <= 0x10000000UL); void *ret = mmap((void *)flash_base, CONFIG_FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); if (ret != flash_base) { @@ -45,7 +91,13 @@ void load_flash_contents(const char *flash_img) { assert(0); } - if (!flash_img || !(fp = fopen(flash_img, "r"))) { + char real_flash_img[4096]; + + if(flash_img) { + convert_to_absolute_path(flash_img, real_flash_img); + } + + if (!flash_img || !(fp = fopen(real_flash_img, "r"))) { // Log("Can not find flash image: %s", flash_img); // Log("Use built-in image instead"); uint32_t *p = (uint32_t *)flash_base; @@ -66,5 +118,8 @@ void load_flash_contents(const char *flash_img) { } void init_flash() { +#ifndef CONFIG_SHARE + load_flash_contents(CONFIG_FLASH_IMG_PATH); +#endif add_mmio_map("flash", CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, flash_io_handler); } diff --git a/src/isa/riscv32/init.c b/src/isa/riscv32/init.c index cef76819d..e6859df04 100644 --- a/src/isa/riscv32/init.c +++ b/src/isa/riscv32/init.c @@ -24,7 +24,7 @@ static const uint32_t img [] = { 0x0002a503, // lw a0,0(t0) 0x0000006b, // nemu_trap }; - +//RESET_VECTOR static void restart() { /* Set the initial program counter. */ cpu.pc = RESET_VECTOR; diff --git a/src/isa/riscv64/init.c b/src/isa/riscv64/init.c index ac81152ad..0299514f6 100644 --- a/src/isa/riscv64/init.c +++ b/src/isa/riscv64/init.c @@ -19,15 +19,6 @@ #include #include "local-include/csr.h" -#ifndef CONFIG_SHARE -static const uint32_t img [] = { - 0x800002b7, // lui t0,0x80000 - 0x0002a023, // sw zero,0(t0) - 0x0002a503, // lw a0,0(t0) - 0x0000006b, // nemu_trap -}; -#endif - void init_csr(); #ifdef CONFIG_RV_SDTRIG void init_trigger(); @@ -55,7 +46,11 @@ void init_isa() { init_custom_csr(); #ifndef CONFIG_RESET_FROM_MMIO +#ifdef CONFIG_HAS_FLASH + cpu.pc = CONFIG_FLASH_START_ADDR; +#else cpu.pc = RESET_VECTOR; +#endif #else cpu.pc = CONFIG_MMIO_RESET_VECTOR; #endif @@ -219,18 +214,6 @@ void init_isa() { sstateen0->val = SSTATEEN0_RESET; #endif // CONFIG_RV_SMSTATEEN -#ifndef CONFIG_SHARE - extern char *cpt_file; - extern bool checkpoint_restoring; - if (cpt_file == NULL && !checkpoint_restoring) { - #ifdef CONFIG_USE_SPARSEMM - sparse_mem_write(get_sparsemm(), RESET_VECTOR, sizeof(img), img); - #else - memcpy(guest_to_host(RESET_VECTOR), img, sizeof(img)); - #endif - } -#endif - init_riscv_timer(); if (!is_second_call) { diff --git a/src/monitor/image_loader.c b/src/monitor/image_loader.c index 8b3db014c..480b4f56e 100644 --- a/src/monitor/image_loader.c +++ b/src/monitor/image_loader.c @@ -34,37 +34,23 @@ #ifndef CONFIG_MODE_USER #ifdef CONFIG_MEM_COMPRESS -long load_gz_img(const char *filename) { +long load_gz_img(const char *filename, uint64_t load_start, size_t img_size) { gzFile compressed_mem = gzopen(filename, "rb"); Assert(compressed_mem, "Can not open '%s'", filename); const uint32_t chunk_size = 16384; uint8_t *temp_page = (uint8_t *)calloc(chunk_size, sizeof(long)); - uint8_t *pmem_start = (uint8_t *)guest_to_host(RESET_VECTOR); + uint8_t *pmem_start = (uint8_t *)(load_start); uint8_t *pmem_current; // load file byte by byte to pmem + size_t load_size = img_size == 0 ? MEMORY_SIZE : img_size; uint64_t curr_size = 0; - - uint64_t cpt_offset = 0; - extern uint8_t *get_flash_base(); - extern uint64_t get_flash_size(); - - while (curr_size < MEMORY_SIZE) { + while (curr_size < load_size) { uint32_t bytes_read = gzread(compressed_mem, temp_page, chunk_size); if (bytes_read == 0) { break; } - - // restore checkpoint hardware status to device - if (cpt_offset < get_flash_size()) { - assert(get_flash_base()); - memcpy(get_flash_base() + cpt_offset, temp_page, chunk_size); - - cpt_offset += chunk_size; - continue; - } - for (uint32_t x = 0; x < bytes_read; x++) { pmem_current = pmem_start + curr_size + x; uint8_t read_data = *(temp_page + x); @@ -84,7 +70,7 @@ long load_gz_img(const char *filename) { return curr_size; } -long load_zstd_img(const char *filename) { +long load_zstd_img(const char *filename, uint64_t load_start, size_t img_size) { assert(filename); int fd = -1; @@ -156,18 +142,14 @@ long load_zstd_img(const char *filename) { } // def phymem - uint8_t *pmem_start = (uint8_t *)guest_to_host(RESET_VECTOR); + uint8_t *pmem_start = (uint8_t *)(load_start); uint64_t *pmem_current; - // def checkpoint restore size - int64_t cpt_offset = 0; - extern uint8_t *get_flash_base(); - extern uint64_t get_flash_size(); - // decompress and write in memory - uint64_t total_write_size = 0; + size_t total_write_size = 0; + size_t load_size = img_size == 0 ? MEMORY_SIZE : img_size; - while (total_write_size < MEMORY_SIZE) { + while (total_write_size < load_size) { ZSTD_outBuffer output = {decompress_file_buffer, decompress_file_buffer_size * sizeof(uint64_t), 0}; @@ -188,14 +170,6 @@ long load_zstd_img(const char *filename) { assert(decompress_file_buffer_size * sizeof(uint64_t) == output.pos); - if (cpt_offset < get_flash_size()) { - assert(get_flash_base()); - memcpy(get_flash_base() + cpt_offset, decompress_file_buffer, output.pos); - - cpt_offset += output.pos; - continue; - } - for (uint64_t x = 0; x < decompress_file_buffer_size; x++) { pmem_current = (uint64_t *)(pmem_start + total_write_size) + x; uint64_t read_data = *(decompress_file_buffer + x); @@ -241,7 +215,7 @@ long load_img(char* img_name, char *which_img, uint64_t load_start, size_t img_s if (is_gz_file(loading_img)) { #ifdef CONFIG_MEM_COMPRESS Log("Loading GZ image %s", loading_img); - return load_gz_img(loading_img); + return load_gz_img(loading_img, load_start, img_size); #else panic("CONFIG_MEM_COMPRESS is disabled, turn it on in memuconfig!"); #endif @@ -250,7 +224,7 @@ long load_img(char* img_name, char *which_img, uint64_t load_start, size_t img_s if (is_zstd_file(loading_img)) { #ifdef CONFIG_MEM_COMPRESS Log("Loading Zstd image %s", loading_img); - return load_zstd_img(loading_img); + return load_zstd_img(loading_img, load_start, img_size); #else panic("CONFIG_MEM_COMPRESS is disabled, turn it on in memuconfig!"); #endif @@ -284,7 +258,7 @@ long load_img(char* img_name, char *which_img, uint64_t load_start, size_t img_s munmap(buf, size); } #else - int ret = fread(guest_to_host(load_start), size, 1, fp); + int ret = fread((uint8_t*)load_start, size, 1, fp); assert(ret == 1); #endif Log("Read %lu bytes from file %s to 0x%lx", size, img_name, load_start); diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 58c996734..c8a03a3d9 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -101,8 +101,9 @@ static inline int parse_args(int argc, char *argv[]) { {"workload-name" , required_argument, NULL, 'w'}, {"config-name" , required_argument, NULL, 'C'}, - // restore cpt + // checkpoint {"restore" , required_argument, NULL, 'c'}, + // gcpt-restore {"cpt-restorer" , required_argument, NULL, 'r'}, {"map-img-as-outcpt" , no_argument , NULL, 13}, @@ -358,16 +359,19 @@ void init_monitor(int argc, char *argv[]) { long img_size = 0; // how large we should copy for difftest assert(img_file); - uint64_t bbl_start = RESET_VECTOR; -#define RESET_FLASH 0x1000 - uint64_t gcpt_start = RESET_FLASH; + uint64_t bbl_start = (uint64_t)get_pmem(); + extern uint8_t* get_flash_base(); + uint64_t gcpt_start = (uint64_t)get_flash_base(); + // memory image or binary could load directly img_size = load_img(img_file, "image (checkpoint/bare metal app/bbl) form cmdline", bbl_start, 0); + // provide checkpoint flash file if (checkpoint_restoring){ img_size = load_img(checkpoint_flash_path, "checkpoint from cmdline", gcpt_start, 0); } + // provide gcpt restore if (restorer) { FILE *restore_fp = fopen(restorer, "rb"); Assert(restore_fp, "Can not open '%s'", restorer); From 3c23325797864f8367273d619ec90bd76d35d15f Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Tue, 10 Dec 2024 17:29:03 +0800 Subject: [PATCH 11/40] feat(cpt-defconfig): support next-generation checkpoint by default Signed-off-by: jiaxiaoyu --- configs/riscv64-xs-cpt_defconfig | 12 ++++++++++-- ready-to-run | 2 +- src/isa/riscv32/init.c | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/configs/riscv64-xs-cpt_defconfig b/configs/riscv64-xs-cpt_defconfig index 6638fef38..f11559955 100644 --- a/configs/riscv64-xs-cpt_defconfig +++ b/configs/riscv64-xs-cpt_defconfig @@ -27,6 +27,7 @@ CONFIG_RV_ZFH_MIN=y CONFIG_RV_ZFA=y CONFIG_RVV=y CONFIG_RV_ZVFH_MIN=y +CONFIG_RV_ZVFH=y CONFIG_RV_DEBUG=y CONFIG_RVH=y # CONFIG_RV_SDEXT is not set @@ -36,13 +37,16 @@ CONFIG_TDATA1_MCONTROL6=y # CONFIG_TDATA1_ITRIGGER is not set # CONFIG_TDATA1_ETRIGGER is not set CONFIG_TRIGGER_NUM=4 +# CONFIG_SDTRIG_EXTRA is not set # CONFIG_RV_AIA is not set CONFIG_RV_SSTC=y CONFIG_RV_SMRNMI=y # CONFIG_RV_SMDBLTRP is not set # CONFIG_RV_SSDBLTRP is not set +CONFIG_NMIE_INIT=y CONFIG_RV_ZICNTR=y CONFIG_RV_CSR_TIME=y +CONFIG_RV_ZIHINTPAUSE=y CONFIG_RV_ZIHPM=y CONFIG_RV_CSR_MCOUNTINHIBIT=y CONFIG_RV_CSR_MCOUNTINHIBIT_CNTR=y @@ -79,6 +83,7 @@ CONFIG_RV_ZCMOP=y CONFIG_RV_ZIMOP=y CONFIG_RV_ZCB=y CONFIG_RV_ZACAS=y +CONFIG_RESERVATION_SET_WIDTH=6 # end of ISA-dependent Options for riscv64 CONFIG_ENGINE_INTERPRETER=y @@ -166,7 +171,11 @@ CONFIG_VGA_SIZE_400x300=y CONFIG_HAS_SDCARD=y CONFIG_SDCARD_CTL_MMIO=0x40002000 CONFIG_SDCARD_IMG_PATH="" -# CONFIG_HAS_FLASH is not set +CONFIG_HAS_FLASH=y +CONFIG_FLASH_PRESET_CONTENT="0x0010029b,0x01f29293,0x00028067" +CONFIG_FLASH_START_ADDR=0x10000000 +CONFIG_FLASH_SIZE=0x10000000 +CONFIG_FLASH_IMG_PATH="$(NEMU_HOME)/resource/gcpt_restore/build/gcpt.bin" # CONFIG_FPU_HOST is not set CONFIG_FPU_SOFT=y # CONFIG_FPU_NONE is not set @@ -176,7 +185,6 @@ CONFIG_AC_NONE=y # CONFIG_VECTOR_AC_SOFT is not set CONFIG_MMIO_AC_SOFT=y CONFIG_AMO_AC_SOFT=y -CONFIG_RESERVATION_SET_WIDTH=6 # # Processor difftest reference config diff --git a/ready-to-run b/ready-to-run index 2faf29fbe..457f09189 160000 --- a/ready-to-run +++ b/ready-to-run @@ -1 +1 @@ -Subproject commit 2faf29fbe4c01cbfe36be30ebd5dc7fa59b01f05 +Subproject commit 457f091898b2bcd26c8f6e983f3df174f990af43 diff --git a/src/isa/riscv32/init.c b/src/isa/riscv32/init.c index e6859df04..cef76819d 100644 --- a/src/isa/riscv32/init.c +++ b/src/isa/riscv32/init.c @@ -24,7 +24,7 @@ static const uint32_t img [] = { 0x0002a503, // lw a0,0(t0) 0x0000006b, // nemu_trap }; -//RESET_VECTOR + static void restart() { /* Set the initial program counter. */ cpu.pc = RESET_VECTOR; From 5d6509dc645ce3a8c25b3a7c4407e75630ee5a46 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Tue, 10 Dec 2024 17:40:00 +0800 Subject: [PATCH 12/40] feat(checkpoint): support libcheckpoint memlayout need init submodule 'protobuf' first Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 816dad9c0..d5d8bd122 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,7 @@ jobs: echo "V_WORKLOAD_HOME=/nfs/home/share/ci-workloads/V-extension-tests" >> $GITHUB_ENV - name: Build NEMU interpreter for XS run: | + git submodule update --init --depth=1 make riscv64-xs_defconfig make -j - name: System - linux-hello-opensbi @@ -62,7 +63,6 @@ jobs: make clean-all # restore cpt - git submodule update --init --depth=1 ready-to-run make riscv64-xs-diff-spike_defconfig make -j bash ./scripts/restore_zstd.sh @@ -80,6 +80,7 @@ jobs: echo "NEMU_HOME=$GITHUB_WORKSPACE" >> $GITHUB_ENV - name: Build NEMU interpreter run: | + git submodule update --init --depth=1 make riscv64-nutshell_defconfig make -j - name: test boot linux @@ -108,7 +109,7 @@ jobs: echo "TEST_HOME=/nfs/home/share/ci-workloads/V-extension-tests" >> $GITHUB_ENV - name: Build NEMU with V extension and agnostic run: | - git submodule update --init --depth=1 ready-to-run + git submodule update --init --depth=1 make clean-all make riscv64-xs-diff-spike-agnostic_defconfig make -j @@ -134,7 +135,7 @@ jobs: - name: Build NEMU interpreter for diff with spike run: | - git submodule update --init --depth=1 ready-to-run + git submodule update --init --depth=1 make riscv64-xs-diff-spike_defconfig make -j @@ -254,7 +255,7 @@ jobs: - name: Build NEMU interpreter for diff with spike run: | - git submodule update --init --depth=1 ready-to-run + git submodule update --init --depth=1 make riscv64-xs-diff-spike_defconfig make -j From f5c5933189cce4827be5e4f6310efeae609819d1 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Tue, 10 Dec 2024 18:29:55 +0800 Subject: [PATCH 13/40] fix(flash): fix bugs using flash devices Signed-off-by: jiaxiaoyu --- include/device/flash.h | 22 ++++++++++++++++++++++ scripts/generate_so_for_difftest.sh | 1 + src/checkpoint/serializer.cpp | 14 +++++++------- src/cpu/difftest/dut.c | 5 ++++- src/device/flash.c | 9 +++------ src/monitor/monitor.c | 12 ++++++++++-- 6 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 include/device/flash.h diff --git a/include/device/flash.h b/include/device/flash.h new file mode 100644 index 000000000..ad810f4df --- /dev/null +++ b/include/device/flash.h @@ -0,0 +1,22 @@ +/*************************************************************************************** +* Copyright (c) 2014-2021 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. +***************************************************************************************/ + +#ifndef __DEVICE_FLASH_H__ +#define __DEVICE_FLASH_H__ + +extern uint8_t* flash_base; +uint64_t get_flash_size(); + +#endif diff --git a/scripts/generate_so_for_difftest.sh b/scripts/generate_so_for_difftest.sh index a343e0a25..02bf77ea8 100755 --- a/scripts/generate_so_for_difftest.sh +++ b/scripts/generate_so_for_difftest.sh @@ -12,6 +12,7 @@ touch $(pwd)/resource/gcpt_restore/build/gcpt.bin # indentation of Makefile, causing make failure after fetching the # berkeley-softfloat-3. This dry run fixed this by fetching the # dependencies for the first time. +git submodule update --init make riscv64-xs-ref_defconfig && \ (make -j `nproc` || true) diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index 13aee5d8b..1026d98f8 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -54,15 +54,16 @@ uint8_t *guest_to_host(paddr_t paddr); extern void log_buffer_flush(); extern void log_file_flush(); extern unsigned long MEMORY_SIZE; -extern uint8_t* get_flash_base(); void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); -extern uint64_t get_flash_size(); #include #include #include } +Serializer serializer; + #ifdef CONFIG_MEM_COMPRESS +#include void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr) { // We must dump registers before memory to store them in the Generic Arch CPT assert(regDumped); @@ -212,7 +213,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t regDumped = false; } #else -void Serializer::serializePMem(uint64_t inst_count) {} +void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr) {} #endif #ifdef CONFIG_MEM_COMPRESS @@ -325,7 +326,7 @@ void Serializer::serializeRegs(uint8_t* serialize_base_addr, single_core_rvgc_rv regDumped = true; } #else -void Serializer::serializeRegs() {} +void Serializer::serializeRegs(uint8_t* serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) {} #endif void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { @@ -336,7 +337,7 @@ void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { //encode_cpt_header(&cpt_header, &cpt_percpu_layout); if (write_to_flash) { - serialize_reg_base_addr = get_flash_base(); + serialize_reg_base_addr = flash_base; } else { serialize_reg_base_addr = get_pmem(); } @@ -344,7 +345,7 @@ void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { assert(serialize_reg_base_addr); serializeRegs((uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); - serializePMem(inst_count, write_to_flash, get_pmem(), get_flash_base()); + serializePMem(inst_count, write_to_flash, get_pmem(), flash_base); #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); #endif @@ -435,7 +436,6 @@ void Serializer::notify_taken(uint64_t i) { } } -Serializer serializer; uint64_t Serializer::next_index(){ uint64_t index=0; diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index b13f7c525..bb38cc6d3 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -20,6 +20,7 @@ #include #include #include +#include void (*ref_difftest_memcpy)(paddr_t addr, void *buf, size_t n, bool direction) = NULL; void (*ref_difftest_regcpy)(void *dut, bool direction) = NULL; @@ -110,7 +111,9 @@ void init_difftest(char *ref_so_file, long img_size, int port) { ref_difftest_init(port); ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF); - ref_difftest_memcpy(CONFIG_FLASH_START_ADDR, get_flash_base(), CONFIG_FLASH_SIZE, DIFFTEST_TO_REF); +#ifdef CONFIG_HAS_FLASH + ref_difftest_memcpy(CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, DIFFTEST_TO_REF); +#endif ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); } diff --git a/src/device/flash.c b/src/device/flash.c index 4fe11ef6b..5ac0c6733 100644 --- a/src/device/flash.c +++ b/src/device/flash.c @@ -15,17 +15,13 @@ #include #include +#include #include #include // put flash below the physical memory and allow a max size of 256MB. // See the notes at paddr.c:79 for why we fix the address here. -static uint8_t *flash_base = (uint8_t *)0xf0000000ul; -static FILE *fp = NULL; - -uint8_t* get_flash_base(){ - return flash_base; -} +uint8_t *flash_base = (uint8_t *)0xf0000000ul; uint64_t get_flash_size(){ return CONFIG_FLASH_SIZE; @@ -84,6 +80,7 @@ void convert_to_absolute_path(const char *input_path, char *output_path) { void load_flash_contents(const char *flash_img) { // create mmap with zero contents assert(CONFIG_FLASH_SIZE <= 0x10000000UL); + FILE *fp = NULL; void *ret = mmap((void *)flash_base, CONFIG_FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); if (ret != flash_base) { diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index c8a03a3d9..b6605abbc 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifndef CONFIG_SHARE void init_aligncheck(); @@ -360,16 +361,19 @@ void init_monitor(int argc, char *argv[]) { assert(img_file); uint64_t bbl_start = (uint64_t)get_pmem(); - extern uint8_t* get_flash_base(); - uint64_t gcpt_start = (uint64_t)get_flash_base(); +#ifdef CONFIG_HAS_FLASH + uint64_t gcpt_start = (uint64_t)flash_base; +#endif // memory image or binary could load directly img_size = load_img(img_file, "image (checkpoint/bare metal app/bbl) form cmdline", bbl_start, 0); +#ifdef CONFIG_HAS_FLASH // provide checkpoint flash file if (checkpoint_restoring){ img_size = load_img(checkpoint_flash_path, "checkpoint from cmdline", gcpt_start, 0); } +#endif // provide gcpt restore if (restorer) { @@ -389,7 +393,11 @@ void init_monitor(int argc, char *argv[]) { fclose(restore_fp); +#ifdef CONFIG_HAS_FLASH load_img(restorer, "Gcpt restorer form cmdline", gcpt_start, restore_size); +#else + load_img(restorer, "Gcpt restorer form cmdline", bbl_start, restore_size); +#endif } /* Initialize differential testing. */ From 0b71c23517bdb69cf69d20ac5b94fc709d3c62bd Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 11 Dec 2024 11:32:30 +0800 Subject: [PATCH 14/40] set limit, just using next generation checkpoint when flash device enable Signed-off-by: jiaxiaoyu --- src/checkpoint/serializer.cpp | 65 +++++++++++++++++++++++++++-------- src/cpu/cpu-exec.c | 10 +++--- src/monitor/monitor.c | 7 ++-- 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/checkpoint/serializer.cpp b/src/checkpoint/serializer.cpp index 1026d98f8..7ff006071 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -53,6 +53,9 @@ uint8_t *guest_to_host(paddr_t paddr); #include extern void log_buffer_flush(); extern void log_file_flush(); +#ifdef CONFIG_HAS_FLASH +#include +#endif extern unsigned long MEMORY_SIZE; void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); #include @@ -63,17 +66,19 @@ void encode_cpt_header(checkpoint_header *cpt_header, single_core_rvgc_rvv_rvh_m Serializer serializer; #ifdef CONFIG_MEM_COMPRESS -#include void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr) { // We must dump registers before memory to store them in the Generic Arch CPT assert(regDumped); const size_t PMEM_SIZE = MEMORY_SIZE; - const size_t GCPT_MMIO_SIZE = get_flash_size(); Log("Host physical address: %p size: %lx", pmem_addr, PMEM_SIZE); + +#ifdef CONFIG_HAS_FLASH + const size_t GCPT_MMIO_SIZE = get_flash_size(); Log("Host gcpt address: %p size: %lx", gcpt_mmio_addr, GCPT_MMIO_SIZE); + string flash_file_path; +#endif string base_file_path; - string flash_file_path; string memory_file_path; if (checkpoint_state == SimpointCheckpointing) { @@ -85,10 +90,12 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t if (compress_file_format == GZ_FORMAT) { Log("Using GZ format generate checkpoint"); +#ifdef CONFIG_HAS_FLASH flash_file_path = base_file_path + "_flash_.gz"; + gzFile flash_compressed_mem; +#endif memory_file_path = base_file_path + "_memory_.gz"; gzFile memory_compressed_mem = gzopen(memory_file_path.c_str(), "wb"); - gzFile flash_compressed_mem; if (memory_compressed_mem == nullptr) { cerr << "Failed to open " << memory_file_path << endl; xpanic("Can't open physical memory checkpoint file!\n"); @@ -98,6 +105,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t uint64_t pass_size = 0; if (write_to_flash) { +#ifdef CONFIG_HAS_FLASH flash_compressed_mem = gzopen(flash_file_path.c_str(), "wb"); if (flash_compressed_mem == nullptr) { cerr << "Failed to open " << flash_file_path << endl; @@ -117,6 +125,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t } pass_size = 0; +#endif } for (uint64_t written = 0; written < PMEM_SIZE; written += pass_size) { @@ -131,9 +140,11 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t } if(write_to_flash){ +#ifdef CONFIG_HAS_FLASH if (gzclose(flash_compressed_mem)) { xpanic("Close failed on physical checkpoint file\n"); } +#endif } if (gzclose(memory_compressed_mem)) { xpanic("Close failed on physical checkpoint file\n"); @@ -142,28 +153,32 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t } else if (compress_file_format == ZSTD_FORMAT) { Log("Using ZSTD format generate checkpoint"); - flash_file_path += base_file_path + "_flash_.zstd"; memory_file_path += base_file_path + "_memory_.zstd"; - - Log("Opening %s as checkpoint output file", flash_file_path.c_str()); Log("Opening %s as memory output file", memory_file_path.c_str()); // zstd compress - size_t flash_size = GCPT_MMIO_SIZE; size_t memory_size = PMEM_SIZE; - - size_t const flash_compress_buffer_size = ZSTD_compressBound(flash_size); size_t const memory_compress_buffer_size = ZSTD_compressBound(memory_size); uint8_t *const memory_compress_buffer = (uint8_t*)malloc(memory_compress_buffer_size); - uint8_t *const flash_compress_buffer = (uint8_t*)malloc(flash_compress_buffer_size); - - assert(flash_compress_buffer); assert(memory_compress_buffer); - // compress gcpt device memory + __attribute__((unused)) size_t flash_compress_size = 0; + __attribute__((unused)) FILE *flash_compress_file = NULL; + __attribute__((unused)) size_t flash_fw_size = 0; + +#ifdef CONFIG_HAS_FLASH + flash_file_path += base_file_path + "_flash_.zstd"; + Log("Opening %s as checkpoint output file", flash_file_path.c_str()); + + size_t flash_size = GCPT_MMIO_SIZE; + size_t const flash_compress_buffer_size = ZSTD_compressBound(flash_size); + uint8_t *const flash_compress_buffer = (uint8_t*)malloc(flash_compress_buffer_size); + assert(flash_compress_buffer); + + // compress gcpt device memory if (write_to_flash) { flash_compress_size = ZSTD_compress(flash_compress_buffer, flash_compress_buffer_size, gcpt_mmio_addr, GCPT_MMIO_SIZE, 1); assert(flash_compress_size <= flash_compress_buffer_size && flash_compress_size != 0); @@ -172,6 +187,7 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t flash_compress_file = fopen(flash_file_path.c_str(), "wb"); flash_fw_size = fwrite(flash_compress_buffer, 1, flash_compress_size, flash_compress_file); } +#endif size_t memory_compress_size = ZSTD_compress(memory_compress_buffer, memory_compress_buffer_size, pmem_addr, PMEM_SIZE, 1); assert(memory_compress_size <= memory_compress_buffer_size && memory_compress_size != 0); @@ -182,19 +198,28 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t if (flash_fw_size != flash_compress_size || memory_fw_size != memory_compress_size) { if(write_to_flash){ +#ifdef CONFIG_HAS_FLASH fclose(flash_compress_file); +#endif } fclose(memory_compress_file); +#ifdef CONFIG_HAS_FLASH free(flash_compress_buffer); +#endif free(memory_compress_buffer); - xpanic("file write error: %s : %s, %s : %s \n", flash_file_path.c_str(), strerror(errno), memory_file_path.c_str(), strerror(errno)); +#ifdef CONFIG_HAS_FLASH + printf("file write error: %s : %s\n", flash_file_path.c_str(), strerror(errno)); +#endif + xpanic("file write error: %s : %s\n", memory_file_path.c_str(), strerror(errno)); } if(write_to_flash){ +#ifdef CONFIG_HAS_FLASH if (fclose(flash_compress_file)) { free(flash_compress_buffer); xpanic("file close error: %s : %s \n", base_file_path.c_str(), strerror(errno)); } +#endif } if (fclose(memory_compress_file)) { @@ -202,7 +227,9 @@ void Serializer::serializePMem(uint64_t inst_count, bool write_to_flash, uint8_t xpanic("file close error: %s : %s \n", base_file_path.c_str(), strerror(errno)); } +#ifdef CONFIG_HAS_FLASH free(flash_compress_buffer); +#endif free(memory_compress_buffer); } else { @@ -337,7 +364,11 @@ void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { //encode_cpt_header(&cpt_header, &cpt_percpu_layout); if (write_to_flash) { +#ifdef CONFIG_HAS_FLASH serialize_reg_base_addr = flash_base; +#else + serialize_reg_base_addr = get_pmem(); +#endif } else { serialize_reg_base_addr = get_pmem(); } @@ -345,7 +376,11 @@ void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { assert(serialize_reg_base_addr); serializeRegs((uint8_t *)serialize_reg_base_addr, &cpt_percpu_layout); +#ifdef CONFIG_HAS_FLASH serializePMem(inst_count, write_to_flash, get_pmem(), flash_base); +#else + serializePMem(inst_count, write_to_flash, get_pmem(), NULL); +#endif #else xpanic("You should enable CONFIG_MEM_COMPRESS in menuconfig"); #endif diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index ff169e8d0..935affeb1 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -86,10 +86,10 @@ static inline void debug_hook(vaddr_t pc, const char *asmbuf) { #endif -static bool using_gcpt_mmio = false; +static bool using_next_generation_checkpoint = false; -void set_using_gcpt_mmio(){ - using_gcpt_mmio = true; +void set_using_gcpt_mmio(bool value){ + using_next_generation_checkpoint = value; } void save_globals(Decode *s) { IFDEF(CONFIG_PERF_OPT, prev_s = s); } @@ -360,7 +360,7 @@ uint64_t per_bb_profile(Decode *prev_s, Decode *s, bool control_taken) { cpu.pc = s->pc; extern bool try_take_cpt(uint64_t icount, bool using_gcpt_mmio); - bool taken = try_take_cpt(abs_inst_count, using_gcpt_mmio); + bool taken = try_take_cpt(abs_inst_count, using_next_generation_checkpoint); if (taken) { Log("Have taken checkpoint on pc 0x%lx", s->pc); if (recvd_manual_oneshot_cpt) { @@ -899,7 +899,7 @@ void cpu_exec(uint64_t n) { extern char *mapped_cpt_file; // defined in paddr.c if (mapped_cpt_file != NULL) { extern void serialize_reg_to_mem(bool using_gcpt_mmio); - serialize_reg_to_mem(using_gcpt_mmio); + serialize_reg_to_mem(using_next_generation_checkpoint); } #else break; diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index b6605abbc..db9c9a614 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -51,6 +51,8 @@ extern char *mapped_cpt_file; // defined in paddr.c extern bool map_image_as_output_cpt; extern char *reg_dump_file; extern char *mem_dump_file; +static bool using_generation_checkpoint; + #ifdef CONFIG_MEMORY_REGION_ANALYSIS extern char *memory_region_record_file; #endif @@ -236,8 +238,9 @@ static inline int parse_args(int argc, char *argv[]) { case 16: { // --next-generation-checkpoint - extern void set_using_gcpt_mmio(); - set_using_gcpt_mmio(); + using_generation_checkpoint = true; + extern void set_using_gcpt_mmio(bool value); + set_using_gcpt_mmio(using_generation_checkpoint); break; } From 0108e0a695d544814d301aeda6d3b16f17995cd1 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 11 Dec 2024 11:32:58 +0800 Subject: [PATCH 15/40] fix take checkpoint script Signed-off-by: jiaxiaoyu --- scripts/take_zstd.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/take_zstd.sh b/scripts/take_zstd.sh index c03df0d20..d52529053 100644 --- a/scripts/take_zstd.sh +++ b/scripts/take_zstd.sh @@ -19,5 +19,5 @@ -C test \ -w linux \ -I 350000000 $V_WORKLOAD_HOME/OpenSBI_Linux6.6_h264ref_sss_vectorized \ - --using-gcpt-device \ + --next-generation-checkpoint \ --checkpoint-format zstd From 62b4f6a42b1d9a3e612f1845af7e6a61280fef4e Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Tue, 17 Dec 2024 10:36:28 +0800 Subject: [PATCH 16/40] fix(difftest attach): add pmp and pmp cfg copy to difftest attach Signed-off-by: jiaxiaoyu --- include/cpu/difftest.h | 2 ++ src/cpu/difftest/dut.c | 12 ++++++++---- src/isa/riscv64/difftest/dut.c | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/cpu/difftest.h b/include/cpu/difftest.h index fcaba3c38..27d2b246f 100644 --- a/include/cpu/difftest.h +++ b/include/cpu/difftest.h @@ -39,6 +39,8 @@ static inline void difftest_attach() {} extern void (*ref_difftest_memcpy)(paddr_t dest, void *src, size_t n, bool direction); extern void (*ref_difftest_regcpy)(void *c, bool direction); extern void (*ref_difftest_exec)(uint64_t n); +extern void (*ref_difftest_pmpcpy)(void *dut, bool direction); +extern void (*ref_difftest_pmp_cfg_cpy)(void *dut, bool direction); extern void (*ref_difftest_raise_intr)(uint64_t NO); extern void (*ref_difftest_dirty_fsvs)(const uint64_t dirties); #ifdef CONFIG_DIFFTEST_STORE_COMMIT diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index bb38cc6d3..56effb0e5 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -24,6 +24,8 @@ void (*ref_difftest_memcpy)(paddr_t addr, void *buf, size_t n, bool direction) = NULL; void (*ref_difftest_regcpy)(void *dut, bool direction) = NULL; +void (*ref_difftest_pmpcpy)(void *dut, bool direction) = NULL; +void (*ref_difftest_pmp_cfg_cpy)(void *dut, bool direction) = NULL; void (*ref_difftest_exec)(uint64_t n) = NULL; void (*ref_difftest_raise_intr)(uint64_t NO) = NULL; void (*ref_difftest_dirty_fsvs)(const uint64_t dirties) = NULL; @@ -99,6 +101,12 @@ void init_difftest(char *ref_so_file, long img_size, int port) { void (*ref_difftest_init)(int) = dlsym(handle, "difftest_init"); assert(ref_difftest_init); + ref_difftest_pmpcpy = dlsym(handle, "difftest_pmpcpy"); + assert(ref_difftest_pmpcpy); + + ref_difftest_pmp_cfg_cpy = dlsym(handle, "difftest_pmp_cfg_cpy"); + assert(ref_difftest_pmp_cfg_cpy); + #ifdef CONFIG_DIFFTEST_REF_SPIKE ref_difftest_store_commit = dlsym(handle, "difftest_store_commit"); assert(ref_difftest_store_commit); @@ -111,15 +119,11 @@ void init_difftest(char *ref_so_file, long img_size, int port) { ref_difftest_init(port); ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF); -#ifdef CONFIG_HAS_FLASH - ref_difftest_memcpy(CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, DIFFTEST_TO_REF); -#endif ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); } static void checkregs(CPU_state *ref, vaddr_t pc) { if (!isa_difftest_checkregs(ref, pc)) { - isa_reg_display(); IFDEF(CONFIG_IQUEUE, iqueue_dump()); nemu_state.state = NEMU_ABORT; nemu_state.halt_pc = pc; diff --git a/src/isa/riscv64/difftest/dut.c b/src/isa/riscv64/difftest/dut.c index abde8c008..272b178b7 100644 --- a/src/isa/riscv64/difftest/dut.c +++ b/src/isa/riscv64/difftest/dut.c @@ -118,6 +118,7 @@ bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) { void isa_difftest_attach() { csr_prepare(); ref_difftest_memcpy(CONFIG_MBASE, guest_to_host(CONFIG_MBASE), MEMORY_SIZE, DIFFTEST_TO_REF); - assert(0); //FIXME ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); + ref_difftest_pmpcpy(&csr_array[CSR_PMPADDR_BASE], DIFFTEST_TO_REF); + ref_difftest_pmp_cfg_cpy(csr_array, DIFFTEST_TO_REF); } From 362421f34a96bdf9ca53e40e4f222e486bc662d0 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 18 Dec 2024 10:50:33 +0800 Subject: [PATCH 17/40] feat(flash): skip flash difftest Signed-off-by: jiaxiaoyu --- src/cpu/cpu-exec.c | 49 +++++++++++++++++++++++++++++++++++++++++-- src/monitor/monitor.c | 7 +++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index 935affeb1..4d1e9900b 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -54,6 +54,12 @@ static uint64_t g_timer = 0; // unit: us static bool g_print_step = false; const rtlreg_t rzero = 0; rtlreg_t tmp_reg[4]; +#ifdef CONFIG_DIFFTEST +#ifdef CONFIG_HAS_FLASH +static bool not_attach = true; +static bool could_attach = false; +#endif +#endif static uint64_t n_remain_total; // instructions remaining in cpu_exec() static int n_remain; // instructions remaining in execute() @@ -221,13 +227,27 @@ _Noreturn void longjmp_exception(int ex_cause) { static bool manual_cpt_quit = false; #define FILL_EXEC_TABLE(name) [concat(EXEC_ID_, name)] = &&concat(exec_, name), +#ifdef CONFIG_DIFFTEST +#ifdef CONFIG_HAS_FLASH +#define CHECK_DIFFTEST_ATTACH(target) \ +if(not_attach) {if(prev_s->pc >= CONFIG_FLASH_START_ADDR && prev_s->pc < CONFIG_FLASH_START_ADDR + CONFIG_FLASH_SIZE) {if (!(target >= CONFIG_FLASH_START_ADDR && target < CONFIG_FLASH_START_ADDR + CONFIG_FLASH_SIZE)) {not_attach = false; could_attach = true;}}} +#else +#define CHECK_DIFFTEST_ATTACH(target) \ +if(false) {} +#endif +#else +#define CHECK_DIFFTEST_ATTACH(target) \ +if(false) {} +#endif + // this rtl_j() is only used in PERF_OPT #define rtl_j(s, target) \ do { \ /* Settle instruction counting for the last bb. */ \ IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ - s = s->tnext; \ + CHECK_DIFFTEST_ATTACH(s->tnext->pc) \ is_ctrl = true; \ + s = s->tnext; \ br_taken = true; \ goto end_of_bb; \ } while (0) @@ -237,8 +257,9 @@ static bool manual_cpt_quit = false; do { \ /* Settle instruction counting for the last bb. */ \ IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ - s = jr_fetch(s, *(target)); \ + CHECK_DIFFTEST_ATTACH(*target) \ is_ctrl = true; \ + s = jr_fetch(s, *(target)); \ br_taken = true; \ goto end_of_bb; \ } while (0) @@ -275,10 +296,12 @@ static bool manual_cpt_quit = false; } \ } while (0) + #define rtl_priv_jr(s, target) \ do { \ /* Settle instruction counting for the last bb. */ \ IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ + CHECK_DIFFTEST_ATTACH(*target) \ is_ctrl = true; \ s = jr_fetch(s, *(target)); \ if (g_sys_state_flag) { \ @@ -401,6 +424,7 @@ static void execute(int n) { // main loop while (true) { + #if defined(CONFIG_DEBUG) || defined(CONFIG_DIFFTEST) || defined(CONFIG_IQUEUE) this_s = s; #endif @@ -463,7 +487,19 @@ static void execute(int n) { IFDEF(CONFIG_INSTR_CNT_BY_INSTR, n_remain -= 1); save_globals(s); + debug_difftest(this_s, s); + +#ifdef CONFIG_DIFFTEST +#ifdef CONFIG_HAS_FLASH + if(could_attach) { + difftest_attach(); + could_attach = false; + } +#endif +#endif + + } end_of_loop: @@ -492,6 +528,15 @@ static void execute(int n) { debug_difftest(this_s, s); save_globals(s); +#ifdef CONFIG_DIFFTEST +#ifdef CONFIG_HAS_FLASH + if(could_attach) { + difftest_attach(); + could_attach = false; + } +#endif +#endif + } #else #define FILL_EXEC_TABLE(name) [concat(EXEC_ID_, name)] = concat(exec_, name), diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index db9c9a614..025a1a449 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -406,6 +406,13 @@ void init_monitor(int argc, char *argv[]) { /* Initialize differential testing. */ init_difftest(diff_so_file, img_size, difftest_port); +#ifdef CONFIG_DIFFTEST +#ifdef CONFIG_HAS_FLASH + extern void difftest_detach(); + difftest_detach(); +#endif +#endif + #endif /* Compile the regular expressions. */ From 3a487092445297c66c907daf18c0b3aff721003f Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 18 Dec 2024 18:41:20 +0800 Subject: [PATCH 18/40] feat: add new config file to support libcheckpoint Signed-off-by: jiaxiaoyu --- configs/riscv64-xs-cpt-flash_defconfig | 209 +++++++++++++++++++++++++ configs/riscv64-xs-cpt_defconfig | 15 +- 2 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 configs/riscv64-xs-cpt-flash_defconfig diff --git a/configs/riscv64-xs-cpt-flash_defconfig b/configs/riscv64-xs-cpt-flash_defconfig new file mode 100644 index 000000000..353d27ed7 --- /dev/null +++ b/configs/riscv64-xs-cpt-flash_defconfig @@ -0,0 +1,209 @@ +# +# Automatically generated file; DO NOT EDIT. +# NEMU Configuration Menu +# +# CONFIG_ISA_x86 is not set +# CONFIG_ISA_mips32 is not set +# CONFIG_ISA_riscv32 is not set +CONFIG_ISA_riscv64=y +CONFIG_ISA="riscv64" +CONFIG_ILEN_MIN=2 +CONFIG_ISA64=y + +# +# ISA-dependent Options for riscv64 +# +CONFIG_CLINT_MMIO=0x38000000 +# CONFIG_MULTICORE_DIFF is not set +CONFIG_RVB=y +CONFIG_RV_CBO=y +CONFIG_RVK=y +CONFIG_RV_ZICOND=y +# CONFIG_RV_ZFH is not set +CONFIG_RV_ZFH_MIN=y +CONFIG_RV_ZFA=y +CONFIG_RVV=y +CONFIG_RV_ZVFH_MIN=y +CONFIG_RV_ZVFH=y +CONFIG_RV_DEBUG=y +CONFIG_RVH=y +# CONFIG_RV_SDEXT is not set +CONFIG_RV_SDTRIG=y +CONFIG_TDATA1_MCONTROL6=y +# CONFIG_TDATA1_ICOUNT is not set +# CONFIG_TDATA1_ITRIGGER is not set +# CONFIG_TDATA1_ETRIGGER is not set +CONFIG_TRIGGER_NUM=4 +# CONFIG_SDTRIG_EXTRA is not set +# CONFIG_RV_AIA is not set +# CONFIG_RV_SSTC is not set +CONFIG_RV_SMRNMI=y +# CONFIG_RV_SMDBLTRP is not set +# CONFIG_RV_SSDBLTRP is not set +CONFIG_NMIE_INIT=y +CONFIG_RV_ZICNTR=y +CONFIG_RV_CSR_TIME=y +CONFIG_RV_ZIHINTPAUSE=y +CONFIG_RV_ZIHPM=y +CONFIG_RV_CSR_MCOUNTINHIBIT=y +CONFIG_RV_CSR_MCOUNTINHIBIT_CNTR=y +CONFIG_RV_CSR_MCOUNTINHIBIT_HPM=y +# CONFIG_RV_PMP_ENTRY_0 is not set +CONFIG_RV_PMP_ENTRY_16=y +# CONFIG_RV_PMP_ENTRY_64 is not set +CONFIG_RV_PMP_CSR=y +CONFIG_RV_PMP_NUM=16 +CONFIG_RV_PMP_ACTIVE_NUM=16 +CONFIG_PMP_GRANULARITY=12 + +# +# PMP Check Disabled when enabling PERF_OPT +# +CONFIG_RV_SVINVAL=y +# CONFIG_RV_SV39 is not set +CONFIG_RV_SV48=y +CONFIG_RV_SVNAPOT=y +CONFIG_RV_SVPBMT=y +CONFIG_RV_SSNPM=y +CONFIG_RV_SMNPM=y +CONFIG_RV_SMMPM=y +CONFIG_RV_SSCOFPMF=y +CONFIG_RV_SHLCOFIDELEG=y +CONFIG_RV_SMSTATEEN=y +CONFIG_MISA_UNCHANGEABLE=y +CONFIG_XTVEC_VECTORED_MODE=y +CONFIG_TVAL_EX_II=y +CONFIG_FS_CLEAN_STATE=y +CONFIG_USE_XS_ARCH_CSRS=y +# CONFIG_RVV_AGNOSTIC is not set +CONFIG_RV_ZCMOP=y +CONFIG_RV_ZIMOP=y +CONFIG_RV_ZCB=y +CONFIG_RV_ZACAS=y +CONFIG_RESERVATION_SET_WIDTH=6 +# end of ISA-dependent Options for riscv64 + +CONFIG_ENGINE_INTERPRETER=y +CONFIG_ENGINE="interpreter" +CONFIG_MODE_SYSTEM=y +# CONFIG_MODE_USER is not set + +# +# Build Options +# +CONFIG_CC_GCC=y +# CONFIG_CC_GPP is not set +# CONFIG_CC_CLANG is not set +CONFIG_CC="gcc" +# CONFIG_CC_O0 is not set +# CONFIG_CC_O1 is not set +CONFIG_CC_O2=y +# CONFIG_CC_O3 is not set +CONFIG_CC_OPT="-O2" +CONFIG_CC_NATIVE_ARCH=y +CONFIG_CC_LTO=y +# CONFIG_CC_DEBUG is not set +# CONFIG_CC_ASAN is not set +# end of Build Options + +# +# Testing and Debugging +# +# CONFIG_DEBUG is not set +# CONFIG_DIFFTEST is not set +CONFIG_DIFFTEST_REF_PATH="none" +CONFIG_DIFFTEST_REF_NAME="none" +# CONFIG_DETERMINISTIC is not set +# CONFIG_IQUEUE is not set +# CONFIG_MEMLOG is not set +# CONFIG_TRANSLOG is not set +# CONFIG_EXITLOG is not set +# CONFIG_TRACE_INST is not set +# CONFIG_TRACE_BB is not set +# CONFIG_SIMPOINT_LOG is not set +# end of Testing and Debugging + +# +# Memory Configuration +# +CONFIG_MBASE=0x80000000 +# CONFIG_USE_SPARSEMM is not set +CONFIG_MSIZE=0x200000000 +CONFIG_PADDRBITS=48 +# CONFIG_STORE_LOG is not set +# CONFIG_BR_LOG is not set +CONFIG_BBL_OFFSET_WITH_CPT=0x100000 +# CONFIG_RESET_FROM_MMIO is not set +CONFIG_PC_RESET_OFFSET=0x0 +CONFIG_USE_MMAP=y +# CONFIG_MEM_RANDOM is not set +CONFIG_MEM_COMPRESS=y +CONFIG_ENABLE_CONFIG_MMIO_SPACE=y +CONFIG_MMIO_SPACE_RANGE="0x0, 0x7FFFFFFF" +# end of Memory Configuration + +CONFIG_DEVICE=y +CONFIG_HAS_PORT_IO=y +# CONFIG_HAS_SERIAL is not set +CONFIG_HAS_UARTLITE=y +CONFIG_UARTLITE_PORT=0x3f8 +CONFIG_UARTLITE_MMIO=0x40600000 +# CONFIG_UARTLITE_INPUT_FIFO is not set +CONFIG_UARTLITE_ASSERT_FOUR=y +# CONFIG_HAS_UART_SNPS is not set +CONFIG_HAS_PLIC=y +CONFIG_PLIC_ADDRESS=0x3c000000 +CONFIG_HAS_TIMER=y +CONFIG_RTC_PORT=0x48 +CONFIG_RTC_MMIO=0xa1000048 +CONFIG_HAS_KEYBOARD=y +CONFIG_I8042_DATA_PORT=0x60 +CONFIG_I8042_DATA_MMIO=0xa1000060 +CONFIG_HAS_VGA=y +CONFIG_FB_ADDR=0x50000000 +CONFIG_VGA_CTL_PORT=0x100 +CONFIG_VGA_CTL_MMIO=0x40001000 +# CONFIG_VGA_SHOW_SCREEN is not set +CONFIG_VGA_SIZE_400x300=y +# CONFIG_VGA_SIZE_800x600 is not set +# CONFIG_HAS_AUDIO is not set +# CONFIG_HAS_DISK is not set +CONFIG_HAS_SDCARD=y +CONFIG_SDCARD_CTL_MMIO=0x40002000 +CONFIG_SDCARD_IMG_PATH="" +CONFIG_HAS_FLASH=y +CONFIG_FLASH_PRESET_CONTENT="0x0010029b,0x01f29293,0x00028067" +CONFIG_FLASH_START_ADDR=0x10000000 +CONFIG_FLASH_SIZE=0x10000000 +CONFIG_FLASH_IMG_PATH="$(NEMU_HOME)/resource/gcpt_restore/build/gcpt.bin" +# CONFIG_FPU_HOST is not set +CONFIG_FPU_SOFT=y +# CONFIG_FPU_NONE is not set +# CONFIG_AC_HOST is not set +# CONFIG_AC_SOFT is not set +CONFIG_AC_NONE=y +CONFIG_VECTOR_AC_SOFT=y +CONFIG_MMIO_AC_SOFT=y +CONFIG_AMO_AC_SOFT=y + +# +# Processor difftest reference config +# +# CONFIG_SHARE is not set +# end of Processor difftest reference config + +# +# Miscellaneous +# +CONFIG_TIMER_GETTIMEOFDAY=y +# CONFIG_TIMER_CLOCK_GETTIME is not set +# CONFIG_MEMORY_REGION_ANALYSIS is not set +CONFIG_REPORT_ILLEGAL_INSTR=y +CONFIG_RT_CHECK=y +CONFIG_PERF_OPT=y +CONFIG_TCACHE_SIZE=8192 +CONFIG_BB_LIST_SIZE=1024 +CONFIG_BB_POOL_SIZE=1024 +CONFIG_DISABLE_INSTR_CNT=y +CONFIG_ENABLE_INSTR_CNT=y +# end of Miscellaneous diff --git a/configs/riscv64-xs-cpt_defconfig b/configs/riscv64-xs-cpt_defconfig index f11559955..7564e574e 100644 --- a/configs/riscv64-xs-cpt_defconfig +++ b/configs/riscv64-xs-cpt_defconfig @@ -65,11 +65,11 @@ CONFIG_PMP_GRANULARITY=12 CONFIG_RV_SVINVAL=y # CONFIG_RV_SV39 is not set CONFIG_RV_SV48=y -CONFIG_RV_SVNAPOT=y -CONFIG_RV_SVPBMT=y CONFIG_RV_SSNPM=y CONFIG_RV_SMNPM=y CONFIG_RV_SMMPM=y +CONFIG_RV_SVNAPOT=y +CONFIG_RV_SVPBMT=y CONFIG_RV_SSCOFPMF=y CONFIG_RV_SHLCOFIDELEG=y CONFIG_RV_SMSTATEEN=y @@ -82,8 +82,8 @@ CONFIG_USE_XS_ARCH_CSRS=y CONFIG_RV_ZCMOP=y CONFIG_RV_ZIMOP=y CONFIG_RV_ZCB=y -CONFIG_RV_ZACAS=y CONFIG_RESERVATION_SET_WIDTH=6 +CONFIG_RV_ZACAS=y # end of ISA-dependent Options for riscv64 CONFIG_ENGINE_INTERPRETER=y @@ -123,6 +123,8 @@ CONFIG_DIFFTEST_REF_NAME="none" # CONFIG_TRACE_INST is not set # CONFIG_TRACE_BB is not set # CONFIG_SIMPOINT_LOG is not set +# CONFIG_BR_LOG is not set +# CONFIG_BR_LOG_OUTPUT is not set # end of Testing and Debugging # @@ -133,7 +135,6 @@ CONFIG_MBASE=0x80000000 CONFIG_MSIZE=0x200000000 CONFIG_PADDRBITS=48 # CONFIG_STORE_LOG is not set -# CONFIG_BR_LOG is not set CONFIG_BBL_OFFSET_WITH_CPT=0x100000 # CONFIG_RESET_FROM_MMIO is not set CONFIG_PC_RESET_OFFSET=0x0 @@ -171,11 +172,7 @@ CONFIG_VGA_SIZE_400x300=y CONFIG_HAS_SDCARD=y CONFIG_SDCARD_CTL_MMIO=0x40002000 CONFIG_SDCARD_IMG_PATH="" -CONFIG_HAS_FLASH=y -CONFIG_FLASH_PRESET_CONTENT="0x0010029b,0x01f29293,0x00028067" -CONFIG_FLASH_START_ADDR=0x10000000 -CONFIG_FLASH_SIZE=0x10000000 -CONFIG_FLASH_IMG_PATH="$(NEMU_HOME)/resource/gcpt_restore/build/gcpt.bin" +# CONFIG_HAS_FLASH is not set # CONFIG_FPU_HOST is not set CONFIG_FPU_SOFT=y # CONFIG_FPU_NONE is not set From 30d8ac3f3ba96d4f9668ecd6f440c5f50fa956aa Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 11:02:35 +0800 Subject: [PATCH 19/40] feat: update ci, support check checkpoint with flash Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 13 ++ .../riscv64-xs-diff-spike-withflash_defconfig | 216 ++++++++++++++++++ scripts/restore_zstd.sh | 7 +- scripts/restore_zstd_from_flash.sh | 22 ++ scripts/take_zstd.sh | 1 - scripts/take_zstd_from_flash.sh | 23 ++ 6 files changed, 278 insertions(+), 4 deletions(-) create mode 100644 configs/riscv64-xs-diff-spike-withflash_defconfig create mode 100755 scripts/restore_zstd_from_flash.sh create mode 100644 scripts/take_zstd_from_flash.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5d8bd122..7827a18d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,19 @@ jobs: bash ./scripts/restore_zstd.sh make clean-all + #take cpt with flash + make clean-all + make riscv64-xs-cpt-flash_defconfig + make -j + bash ./scripts/take_zstd_from_flash.sh + make clean-all + + #restore cpt from flash, with difftest + make riscv64-xs-diff-spike-withflash_defconfig + make -j + bash ./scripts/restore_zstd_from_flash.sh + make clean-all + basic-nutshell: runs-on: nemu continue-on-error: false diff --git a/configs/riscv64-xs-diff-spike-withflash_defconfig b/configs/riscv64-xs-diff-spike-withflash_defconfig new file mode 100644 index 000000000..4b486f466 --- /dev/null +++ b/configs/riscv64-xs-diff-spike-withflash_defconfig @@ -0,0 +1,216 @@ +# +# Automatically generated file; DO NOT EDIT. +# NEMU Configuration Menu +# +# CONFIG_ISA_x86 is not set +# CONFIG_ISA_mips32 is not set +# CONFIG_ISA_riscv32 is not set +CONFIG_ISA_riscv64=y +CONFIG_ISA="riscv64" +CONFIG_ILEN_MIN=2 +CONFIG_ISA64=y + +# +# ISA-dependent Options for riscv64 +# +CONFIG_CLINT_MMIO=0x38000000 +# CONFIG_MULTICORE_DIFF is not set +CONFIG_RVB=y +CONFIG_RV_CBO=y +CONFIG_RVK=y +CONFIG_RV_ZICOND=y +CONFIG_RV_ZFH=y +CONFIG_RV_ZFH_MIN=y +CONFIG_RV_ZFA=y +CONFIG_RVV=y +CONFIG_RV_ZVFH_MIN=y +CONFIG_RV_ZVFH=y +CONFIG_RV_DEBUG=y +CONFIG_RVH=y +# CONFIG_RV_SDEXT is not set +CONFIG_RV_SDTRIG=y +CONFIG_TDATA1_MCONTROL6=y +# CONFIG_TDATA1_ICOUNT is not set +# CONFIG_TDATA1_ITRIGGER is not set +# CONFIG_TDATA1_ETRIGGER is not set +CONFIG_TRIGGER_NUM=4 +# CONFIG_SDTRIG_EXTRA is not set +# CONFIG_RV_AIA is not set +CONFIG_RV_SSTC=y +CONFIG_RV_SMRNMI=y +CONFIG_RV_SMDBLTRP=y +# CONFIG_MDT_INIT is not set +CONFIG_RV_SSDBLTRP=y +CONFIG_NMIE_INIT=y +CONFIG_RV_ZICNTR=y +CONFIG_RV_CSR_TIME=y +CONFIG_RV_ZIHINTPAUSE=y +CONFIG_RV_ZIHPM=y +CONFIG_RV_CSR_MCOUNTINHIBIT=y +CONFIG_RV_CSR_MCOUNTINHIBIT_CNTR=y +CONFIG_RV_CSR_MCOUNTINHIBIT_HPM=y +# CONFIG_RV_PMP_ENTRY_0 is not set +CONFIG_RV_PMP_ENTRY_16=y +# CONFIG_RV_PMP_ENTRY_64 is not set +CONFIG_RV_PMP_CSR=y +CONFIG_RV_PMP_NUM=16 +CONFIG_RV_PMP_ACTIVE_NUM=16 +CONFIG_PMP_GRANULARITY=12 + +# +# PMP Check Disabled when enabling PERF_OPT +# +CONFIG_RV_SVINVAL=y +# CONFIG_RV_SV39 is not set +CONFIG_RV_SV48=y +CONFIG_RV_SSNPM=y +CONFIG_RV_SMNPM=y +CONFIG_RV_SMMPM=y +CONFIG_RV_SVNAPOT=y +CONFIG_RV_SVPBMT=y +CONFIG_RV_SSCOFPMF=y +# CONFIG_RV_SHLCOFIDELEG is not set +# CONFIG_RV_SMSTATEEN is not set +CONFIG_MISA_UNCHANGEABLE=y +CONFIG_XTVEC_VECTORED_MODE=y +CONFIG_TVAL_EX_II=y +CONFIG_FS_CLEAN_STATE=y +CONFIG_USE_XS_ARCH_CSRS=y +# CONFIG_RVV_AGNOSTIC is not set +CONFIG_RV_ZCMOP=y +CONFIG_RV_ZIMOP=y +CONFIG_RV_ZCB=y +CONFIG_RESERVATION_SET_WIDTH=6 +CONFIG_RV_ZACAS=y +# end of ISA-dependent Options for riscv64 + +CONFIG_ENGINE_INTERPRETER=y +CONFIG_ENGINE="interpreter" +CONFIG_MODE_SYSTEM=y +# CONFIG_MODE_USER is not set + +# +# Build Options +# +CONFIG_CC_GCC=y +# CONFIG_CC_GPP is not set +# CONFIG_CC_CLANG is not set +CONFIG_CC="gcc" +# CONFIG_CC_O0 is not set +# CONFIG_CC_O1 is not set +CONFIG_CC_O2=y +# CONFIG_CC_O3 is not set +CONFIG_CC_OPT="-O2" +# CONFIG_CC_NATIVE_ARCH is not set +CONFIG_CC_LTO=y +# CONFIG_CC_DEBUG is not set +# CONFIG_CC_ASAN is not set +# end of Build Options + +# +# Testing and Debugging +# +# CONFIG_DEBUG is not set +CONFIG_DIFFTEST=y +# CONFIG_DIFFTEST_REF_QEMU_DL is not set +# CONFIG_DIFFTEST_REF_QEMU_SOCKET is not set +# CONFIG_DIFFTEST_REF_KVM is not set +# CONFIG_DIFFTEST_REF_NEMU is not set +CONFIG_DIFFTEST_REF_SPIKE=y +# CONFIG_DIFFTEST_STORE_COMMIT is not set +CONFIG_DIFFTEST_REF_PATH="none" +CONFIG_DIFFTEST_REF_NAME="none" +# CONFIG_DETERMINISTIC is not set +# CONFIG_IQUEUE is not set +# CONFIG_MEMLOG is not set +# CONFIG_TRANSLOG is not set +# CONFIG_EXITLOG is not set +# CONFIG_TRACE_INST is not set +# CONFIG_TRACE_BB is not set +# CONFIG_SIMPOINT_LOG is not set +# CONFIG_BR_LOG is not set +# CONFIG_BR_LOG_OUTPUT is not set +# end of Testing and Debugging + +# +# Memory Configuration +# +CONFIG_MBASE=0x80000000 +# CONFIG_USE_SPARSEMM is not set +CONFIG_MSIZE=0x200000000 +CONFIG_PADDRBITS=48 +# CONFIG_STORE_LOG is not set +CONFIG_BBL_OFFSET_WITH_CPT=0x100000 +# CONFIG_RESET_FROM_MMIO is not set +CONFIG_PC_RESET_OFFSET=0x0 +CONFIG_USE_MMAP=y +CONFIG_MEM_COMPRESS=y +CONFIG_ENABLE_CONFIG_MMIO_SPACE=y +CONFIG_MMIO_SPACE_RANGE="0x0, 0x7FFFFFFF" +# end of Memory Configuration + +CONFIG_DEVICE=y +CONFIG_HAS_PORT_IO=y +# CONFIG_HAS_SERIAL is not set +CONFIG_HAS_UARTLITE=y +CONFIG_UARTLITE_PORT=0x3f8 +CONFIG_UARTLITE_MMIO=0x40600000 +# CONFIG_UARTLITE_INPUT_FIFO is not set +CONFIG_UARTLITE_ASSERT_FOUR=y +# CONFIG_HAS_UART_SNPS is not set +CONFIG_HAS_PLIC=y +CONFIG_PLIC_ADDRESS=0x3c000000 +CONFIG_HAS_TIMER=y +CONFIG_RTC_PORT=0x48 +CONFIG_RTC_MMIO=0xa1000048 +CONFIG_HAS_KEYBOARD=y +CONFIG_I8042_DATA_PORT=0x60 +CONFIG_I8042_DATA_MMIO=0xa1000060 +CONFIG_HAS_VGA=y +CONFIG_FB_ADDR=0x50000000 +CONFIG_VGA_CTL_PORT=0x100 +CONFIG_VGA_CTL_MMIO=0x40001000 +# CONFIG_VGA_SHOW_SCREEN is not set +CONFIG_VGA_SIZE_400x300=y +# CONFIG_VGA_SIZE_800x600 is not set +# CONFIG_HAS_AUDIO is not set +# CONFIG_HAS_DISK is not set +CONFIG_HAS_SDCARD=y +CONFIG_SDCARD_CTL_MMIO=0x40002000 +CONFIG_SDCARD_IMG_PATH="" +CONFIG_HAS_FLASH=y +CONFIG_FLASH_PRESET_CONTENT="0x0010029b,0x01f29293,0x00028067" +CONFIG_FLASH_START_ADDR=0x10000000 +CONFIG_FLASH_SIZE=0x10000000 +CONFIG_FLASH_IMG_PATH="$(NEMU_HOME)/resource/gcpt_restore/build/gcpt.bin" +# CONFIG_FPU_HOST is not set +CONFIG_FPU_SOFT=y +# CONFIG_FPU_NONE is not set +# CONFIG_AC_HOST is not set +# CONFIG_AC_SOFT is not set +CONFIG_AC_NONE=y +# CONFIG_VECTOR_AC_SOFT is not set +# CONFIG_MMIO_AC_SOFT is not set +# CONFIG_AMO_AC_SOFT is not set + +# +# Processor difftest reference config +# +# CONFIG_SHARE is not set +# end of Processor difftest reference config + +# +# Miscellaneous +# +CONFIG_TIMER_GETTIMEOFDAY=y +# CONFIG_TIMER_CLOCK_GETTIME is not set +# CONFIG_MEMORY_REGION_ANALYSIS is not set +CONFIG_REPORT_ILLEGAL_INSTR=y +CONFIG_RT_CHECK=y +CONFIG_PERF_OPT=y +CONFIG_TCACHE_SIZE=8192 +CONFIG_BB_LIST_SIZE=1024 +CONFIG_BB_POOL_SIZE=1024 +# CONFIG_DISABLE_INSTR_CNT is not set +CONFIG_ENABLE_INSTR_CNT=y +# end of Miscellaneous diff --git a/scripts/restore_zstd.sh b/scripts/restore_zstd.sh index 5aaaa26d0..d558b1e11 100755 --- a/scripts/restore_zstd.sh +++ b/scripts/restore_zstd.sh @@ -13,8 +13,9 @@ # See the Mulan PSL v2 for more details. #**************************************************************************************/ -cpt=`find output_top/test/linux/50000000 -name "*.zstd"` +mem_cpt=`find output_top/test/linux/50000000 -name "*_memory_.zstd"` + ./build/riscv64-nemu-interpreter -b\ --diff ${SPIKE_SO}\ - --restore -I 100000000 \ - $cpt + -I 100000000 \ + $mem_cpt diff --git a/scripts/restore_zstd_from_flash.sh b/scripts/restore_zstd_from_flash.sh new file mode 100755 index 000000000..94425bf4a --- /dev/null +++ b/scripts/restore_zstd_from_flash.sh @@ -0,0 +1,22 @@ +#*************************************************************************************** +# Copyright (c) 2020-2022 Institute of Computing Technology, Chinese Academy of Sciences +# +# 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. +#**************************************************************************************/ + +mem_cpt=`find output_top/test/linux/50000000 -name "*_memory_.zstd"` +flash_cpt=`find output_top/test/linux/50000000 -name "*_flash_.zstd"` + +./build/riscv64-nemu-interpreter -b \ + --diff ${SPIKE_SO} \ + --restore $flash_cpt -I 100000000 \ + $mem_cpt diff --git a/scripts/take_zstd.sh b/scripts/take_zstd.sh index d52529053..35251081c 100644 --- a/scripts/take_zstd.sh +++ b/scripts/take_zstd.sh @@ -19,5 +19,4 @@ -C test \ -w linux \ -I 350000000 $V_WORKLOAD_HOME/OpenSBI_Linux6.6_h264ref_sss_vectorized \ - --next-generation-checkpoint \ --checkpoint-format zstd diff --git a/scripts/take_zstd_from_flash.sh b/scripts/take_zstd_from_flash.sh new file mode 100644 index 000000000..d52529053 --- /dev/null +++ b/scripts/take_zstd_from_flash.sh @@ -0,0 +1,23 @@ +#*************************************************************************************** +# Copyright (c) 2020-2022 Institute of Computing Technology, Chinese Academy of Sciences +# +# 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. +#**************************************************************************************/ + +./build/riscv64-nemu-interpreter \ + --cpt-interval 50000000 -u -b \ + -D output_top \ + -C test \ + -w linux \ + -I 350000000 $V_WORKLOAD_HOME/OpenSBI_Linux6.6_h264ref_sss_vectorized \ + --next-generation-checkpoint \ + --checkpoint-format zstd From 9cfad1ad2eea260f2c5ccfe06e28ff2398251d45 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 11:21:36 +0800 Subject: [PATCH 20/40] fix(config): update config for more accurate instruction counting Signed-off-by: jiaxiaoyu --- configs/riscv64-xs-cpt-flash_defconfig | 3 ++- configs/riscv64-xs-diff-spike-withflash_defconfig | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/riscv64-xs-cpt-flash_defconfig b/configs/riscv64-xs-cpt-flash_defconfig index 353d27ed7..2519ec2f0 100644 --- a/configs/riscv64-xs-cpt-flash_defconfig +++ b/configs/riscv64-xs-cpt-flash_defconfig @@ -204,6 +204,7 @@ CONFIG_PERF_OPT=y CONFIG_TCACHE_SIZE=8192 CONFIG_BB_LIST_SIZE=1024 CONFIG_BB_POOL_SIZE=1024 -CONFIG_DISABLE_INSTR_CNT=y +CONFIG_INSTR_CNT_BY_BB=y +# CONFIG_INSTR_CNT_BY_INSTR_PERF_OPT is not set CONFIG_ENABLE_INSTR_CNT=y # end of Miscellaneous diff --git a/configs/riscv64-xs-diff-spike-withflash_defconfig b/configs/riscv64-xs-diff-spike-withflash_defconfig index 4b486f466..9c45166ae 100644 --- a/configs/riscv64-xs-diff-spike-withflash_defconfig +++ b/configs/riscv64-xs-diff-spike-withflash_defconfig @@ -211,6 +211,7 @@ CONFIG_PERF_OPT=y CONFIG_TCACHE_SIZE=8192 CONFIG_BB_LIST_SIZE=1024 CONFIG_BB_POOL_SIZE=1024 -# CONFIG_DISABLE_INSTR_CNT is not set +CONFIG_INSTR_CNT_BY_BB=y +# CONFIG_INSTR_CNT_BY_INSTR_PERF_OPT is not set CONFIG_ENABLE_INSTR_CNT=y # end of Miscellaneous From f15cc7cf405e7e7574e322d15fa5b3e411c90092 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 11:43:58 +0800 Subject: [PATCH 21/40] fix(jrelop): check difftest attch when exec jrelop Signed-off-by: jiaxiaoyu --- src/cpu/cpu-exec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index 4d1e9900b..2cd8acbdb 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -271,6 +271,7 @@ if(false) {} IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ is_ctrl = true; \ if (interpret_relop(relop, *src1, *src2)) { \ + CHECK_DIFFTEST_ATTACH(s->tnext->pc) \ s = s->tnext; \ br_taken = true; \ } else \ From 01c5f7c62ed8a2b42a3feb7df1e6a7be9a308df5 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 16:41:38 +0800 Subject: [PATCH 22/40] Bump submodule(ready-to-run): Bump spike ref, nemu ref in ready-to-run Signed-off-by: jiaxiaoyu --- ready-to-run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ready-to-run b/ready-to-run index 457f09189..95e8f429a 160000 --- a/ready-to-run +++ b/ready-to-run @@ -1 +1 @@ -Subproject commit 457f091898b2bcd26c8f6e983f3df174f990af43 +Subproject commit 95e8f429ac221b773ced168746ac1424d01f0019 From fc5e44a1b975b907e039188cd7070b10f6974068 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 16:50:11 +0800 Subject: [PATCH 23/40] fix(difftest): Enable pmp register copy only when flash exists Signed-off-by: jiaxiaoyu --- src/cpu/difftest/dut.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index 56effb0e5..fc5226e2f 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -101,11 +101,13 @@ void init_difftest(char *ref_so_file, long img_size, int port) { void (*ref_difftest_init)(int) = dlsym(handle, "difftest_init"); assert(ref_difftest_init); +#ifdef CONFIG_HAS_FLASH ref_difftest_pmpcpy = dlsym(handle, "difftest_pmpcpy"); assert(ref_difftest_pmpcpy); ref_difftest_pmp_cfg_cpy = dlsym(handle, "difftest_pmp_cfg_cpy"); assert(ref_difftest_pmp_cfg_cpy); +#endif #ifdef CONFIG_DIFFTEST_REF_SPIKE ref_difftest_store_commit = dlsym(handle, "difftest_store_commit"); @@ -173,11 +175,15 @@ void difftest_detach() { } void difftest_attach() { +#ifdef CONFIG_HAS_FLASH is_detach = false; is_skip_ref = false; skip_dut_nr_instr = 0; isa_difftest_attach(); +#else + assert(0); // fix me +#endif } #else From 8a5a36d43befa6d750a4db7efbad5fdd0220721a Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 16:54:04 +0800 Subject: [PATCH 24/40] fix(ci): The restore parameter has changed its function and is used to specify the checkpoint file. Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7827a18d1..799b42128 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -274,13 +274,13 @@ jobs: - name: Run Vector-spec06-checkpoint with Spike DiffTest run: | - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/hmmer_nph3_1886_0.000268086.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/hmmer_retro_6200_0.0378585.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/h264ref_sss_88321_0.0346343.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/h264ref_foreman.baseline_8028_0.0414445.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/h264ref_foreman.main_3027_0.0443573.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/libquantum_41028_0.0840681.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/bzip2_402_0.00785398.gz -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/hmmer_nph3_1886_0.000268086.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/hmmer_retro_6200_0.0378585.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/h264ref_sss_88321_0.0346343.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/h264ref_foreman.baseline_8028_0.0414445.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/h264ref_foreman.main_3027_0.0443573.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/libquantum_41028_0.0840681.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 + ./build/riscv64-nemu-interpreter $TEST_HOME/bzip2_402_0.00785398.gz -b --diff ${SPIKE_SO} -r $TEST_HOME/v-gcpt.bin -I 40000000 - name: Run OpenSBI+Linux+Vectorized_h264 with Spike DiffTest run: | From f04e4c27c3e6ea8e3c45780b2bb757b17fffb5ac Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 17:40:16 +0800 Subject: [PATCH 25/40] feat(ci): Replace the local spike-so used by nutshell with the spike-so of ready-to-run Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 3 ++- ready-to-run | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 799b42128..20fe165d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ on: env: CI_WORKLOADS: /nfs/home/share/ci-workloads SPIKE_SO: ./ready-to-run/riscv64-spike-so + NUTSHELL_SPIKE_SO: ./ready-to-run/riscv64-nutshell-spike-so jobs: compilation-all: @@ -106,7 +107,7 @@ jobs: make -j - name: test boot linux with difftest run: | - ./build/riscv64-nemu-interpreter -b --diff ${CI_WORKLOADS}/nutshell/riscv64-spike-so ${CI_WORKLOADS}/linux-hello/bbl.bin + ./build/riscv64-nemu-interpreter -b --diff ${NUTSHELL_SPIKE_SO} ${CI_WORKLOADS}/linux-hello/bbl.bin diff-spike-guard: # NEMU should report error if RVV agnostic is enabled when comparing against Spike ref; It should crash in the expected way diff --git a/ready-to-run b/ready-to-run index 95e8f429a..669fa105d 160000 --- a/ready-to-run +++ b/ready-to-run @@ -1 +1 @@ -Subproject commit 95e8f429ac221b773ced168746ac1424d01f0019 +Subproject commit 669fa105d2fbbef777b6e6b607cb4a52ff0e4374 From a055d5cda1fec79dd610ab07a93673bea9a325dc Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 17:47:07 +0800 Subject: [PATCH 26/40] feat(difftest): add detach and attach log Signed-off-by: jiaxiaoyu --- src/cpu/difftest/dut.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index fc5226e2f..611753b32 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -171,11 +171,13 @@ void difftest_step(vaddr_t pc, vaddr_t npc) { checkregs(&ref_r, pc); } void difftest_detach() { + Log("Difftest detach now!"); is_detach = true; } void difftest_attach() { #ifdef CONFIG_HAS_FLASH + Log("Difftest attach now!"); is_detach = false; is_skip_ref = false; skip_dut_nr_instr = 0; From c013291279f0173d66b0483ae9b7e7f2909579ec Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 19 Dec 2024 17:59:15 +0800 Subject: [PATCH 27/40] fix(ci): The restore parameter has changed its function and is used to specify the checkpoint file. Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 20fe165d2..37e1ad1f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,7 +128,7 @@ jobs: make riscv64-xs-diff-spike-agnostic_defconfig make -j set -x - ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} --restore $TEST_HOME/hmmer_retro_6200_0.0378585.gz -r $TEST_HOME/v-gcpt.bin -I 2000000 > crash.log || exit_code=$? + ./build/riscv64-nemu-interpreter -b --diff ${SPIKE_SO} $TEST_HOME/hmmer_retro_6200_0.0378585.gz -r $TEST_HOME/v-gcpt.bin -I 2000000 > crash.log || exit_code=$? if [ ${exit_code} -eq 0 ]; then echo "Difftest is broken, it should report error!" exit 1; fi match=$(grep "wrong.*=.*ffff" crash.log -c) if [ ${match} -eq 0 ]; then echo "Difftest is broken, it should report at least one agnostic related difference!" exit 1; fi From f796a2581f216fed69c333a72cb70ccad8431ba3 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 20 Dec 2024 11:19:35 +0800 Subject: [PATCH 28/40] fix(ci): Delete intermediates Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37e1ad1f8..5c2792541 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,7 @@ jobs: make -j bash ./scripts/restore_zstd.sh make clean-all + rm -rf output_top #take cpt with flash make clean-all From 0513f74a6fe382cf2367d3f1d6817698de7e31e6 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 20 Dec 2024 18:29:10 +0800 Subject: [PATCH 29/40] Bump submodule(ready-to-run): Bump spike ref in ready-to-run Signed-off-by: jiaxiaoyu --- ready-to-run | 2 +- src/cpu/difftest/dut.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ready-to-run b/ready-to-run index 669fa105d..6cf1f93cd 160000 --- a/ready-to-run +++ b/ready-to-run @@ -1 +1 @@ -Subproject commit 669fa105d2fbbef777b6e6b607cb4a52ff0e4374 +Subproject commit 6cf1f93cda970e279630656ec9d266165a760809 diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index 611753b32..0e675d72d 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -126,6 +126,7 @@ void init_difftest(char *ref_so_file, long img_size, int port) { static void checkregs(CPU_state *ref, vaddr_t pc) { if (!isa_difftest_checkregs(ref, pc)) { + isa_reg_display(); IFDEF(CONFIG_IQUEUE, iqueue_dump()); nemu_state.state = NEMU_ABORT; nemu_state.halt_pc = pc; From 8264153e4c6189a9f98996f74db1e745c064c3db Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Fri, 20 Dec 2024 18:49:56 +0800 Subject: [PATCH 30/40] debug Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c2792541..758258ac5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,6 +76,7 @@ jobs: make -j bash ./scripts/take_zstd_from_flash.sh make clean-all + cp output_top /nfs/home/share/jxy_output_top -r #restore cpt from flash, with difftest make riscv64-xs-diff-spike-withflash_defconfig From 923297cc0a01eac139c3af6565e888744b37fe41 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 14:37:41 +0800 Subject: [PATCH 31/40] feat(difftest): Supports selective difftest of mmio address space Signed-off-by: jiaxiaoyu --- include/device/map.h | 18 ++++++++++++++---- include/device/mmio.h | 2 +- src/cpu/cpu-exec.c | 42 ----------------------------------------- src/cpu/difftest/dut.c | 19 ++++++++++++++----- src/device/flash.c | 2 +- src/device/io/mmio.c | 16 ++++++++-------- src/device/io/port-io.c | 8 ++++---- src/device/keyboard.c | 4 ++-- src/device/plic.c | 2 +- src/device/sdcard.c | 2 +- src/device/timer.c | 4 ++-- src/device/uartlite.c | 4 ++-- src/device/vga.c | 6 +++--- src/isa/riscv64/clint.c | 2 +- src/memory/paddr.c | 5 +++-- src/monitor/monitor.c | 14 ++++---------- 16 files changed, 61 insertions(+), 89 deletions(-) diff --git a/include/device/map.h b/include/device/map.h index dada95654..5ec0af012 100644 --- a/include/device/map.h +++ b/include/device/map.h @@ -21,12 +21,20 @@ typedef void(*io_callback_t)(uint32_t, int, bool); uint8_t* new_space(int size); +typedef enum { + SKIP_FREE = 0, + MMIO_READ = 1, + MMIO_WRITE= 2, + MMIO_EXEC = 4, +}SKIP_REF_FLAG; + typedef struct { const char *name; // we treat ioaddr_t as paddr_t here paddr_t low; paddr_t high; void *space; + int skip_ref_flag; io_callback_t callback; } IOMap; @@ -34,11 +42,13 @@ static inline bool map_inside(IOMap *map, paddr_t addr) { return (addr >= map->low && addr <= map->high); } -static inline int find_mapid_by_addr(IOMap *maps, int size, paddr_t addr) { +static inline int find_mapid_by_addr(IOMap *maps, int size, paddr_t addr, int type) { int i; for (i = 0; i < size; i ++) { if (map_inside(maps + i, addr)) { - difftest_skip_ref(); + if((type & (maps + i)->skip_ref_flag) != 0) { + difftest_skip_ref(); + } return i; } } @@ -46,9 +56,9 @@ static inline int find_mapid_by_addr(IOMap *maps, int size, paddr_t addr) { } void add_pio_map(const char *name, ioaddr_t addr, - void *space, uint32_t len, io_callback_t callback); + void *space, uint32_t len, int skip_ref_flag, io_callback_t callback); void add_mmio_map(const char *name, paddr_t addr, - void *space, uint32_t len, io_callback_t callback); + void *space, uint32_t len, int skip_ref_flag, io_callback_t callback); word_t map_read(paddr_t addr, int len, IOMap *map); void map_write(paddr_t addr, int len, word_t data, IOMap *map); diff --git a/include/device/mmio.h b/include/device/mmio.h index 7afb73813..306de0df0 100644 --- a/include/device/mmio.h +++ b/include/device/mmio.h @@ -18,7 +18,7 @@ #include -bool mmio_is_real_device(paddr_t addr); +bool mmio_is_real_device(paddr_t addr, int type); word_t mmio_read(paddr_t addr, int len); void mmio_write(paddr_t addr, int len, word_t data); diff --git a/src/cpu/cpu-exec.c b/src/cpu/cpu-exec.c index 2cd8acbdb..5a51afe1f 100644 --- a/src/cpu/cpu-exec.c +++ b/src/cpu/cpu-exec.c @@ -54,12 +54,6 @@ static uint64_t g_timer = 0; // unit: us static bool g_print_step = false; const rtlreg_t rzero = 0; rtlreg_t tmp_reg[4]; -#ifdef CONFIG_DIFFTEST -#ifdef CONFIG_HAS_FLASH -static bool not_attach = true; -static bool could_attach = false; -#endif -#endif static uint64_t n_remain_total; // instructions remaining in cpu_exec() static int n_remain; // instructions remaining in execute() @@ -227,25 +221,11 @@ _Noreturn void longjmp_exception(int ex_cause) { static bool manual_cpt_quit = false; #define FILL_EXEC_TABLE(name) [concat(EXEC_ID_, name)] = &&concat(exec_, name), -#ifdef CONFIG_DIFFTEST -#ifdef CONFIG_HAS_FLASH -#define CHECK_DIFFTEST_ATTACH(target) \ -if(not_attach) {if(prev_s->pc >= CONFIG_FLASH_START_ADDR && prev_s->pc < CONFIG_FLASH_START_ADDR + CONFIG_FLASH_SIZE) {if (!(target >= CONFIG_FLASH_START_ADDR && target < CONFIG_FLASH_START_ADDR + CONFIG_FLASH_SIZE)) {not_attach = false; could_attach = true;}}} -#else -#define CHECK_DIFFTEST_ATTACH(target) \ -if(false) {} -#endif -#else -#define CHECK_DIFFTEST_ATTACH(target) \ -if(false) {} -#endif - // this rtl_j() is only used in PERF_OPT #define rtl_j(s, target) \ do { \ /* Settle instruction counting for the last bb. */ \ IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ - CHECK_DIFFTEST_ATTACH(s->tnext->pc) \ is_ctrl = true; \ s = s->tnext; \ br_taken = true; \ @@ -257,7 +237,6 @@ if(false) {} do { \ /* Settle instruction counting for the last bb. */ \ IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ - CHECK_DIFFTEST_ATTACH(*target) \ is_ctrl = true; \ s = jr_fetch(s, *(target)); \ br_taken = true; \ @@ -271,7 +250,6 @@ if(false) {} IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ is_ctrl = true; \ if (interpret_relop(relop, *src1, *src2)) { \ - CHECK_DIFFTEST_ATTACH(s->tnext->pc) \ s = s->tnext; \ br_taken = true; \ } else \ @@ -302,7 +280,6 @@ if(false) {} do { \ /* Settle instruction counting for the last bb. */ \ IFDEF(CONFIG_INSTR_CNT_BY_BB, n_remain -= s->idx_in_bb); \ - CHECK_DIFFTEST_ATTACH(*target) \ is_ctrl = true; \ s = jr_fetch(s, *(target)); \ if (g_sys_state_flag) { \ @@ -491,16 +468,6 @@ static void execute(int n) { debug_difftest(this_s, s); -#ifdef CONFIG_DIFFTEST -#ifdef CONFIG_HAS_FLASH - if(could_attach) { - difftest_attach(); - could_attach = false; - } -#endif -#endif - - } end_of_loop: @@ -529,15 +496,6 @@ static void execute(int n) { debug_difftest(this_s, s); save_globals(s); -#ifdef CONFIG_DIFFTEST -#ifdef CONFIG_HAS_FLASH - if(could_attach) { - difftest_attach(); - could_attach = false; - } -#endif -#endif - } #else #define FILL_EXEC_TABLE(name) [concat(EXEC_ID_, name)] = concat(exec_, name), diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index 0e675d72d..9cc113aa9 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -27,6 +27,7 @@ void (*ref_difftest_regcpy)(void *dut, bool direction) = NULL; void (*ref_difftest_pmpcpy)(void *dut, bool direction) = NULL; void (*ref_difftest_pmp_cfg_cpy)(void *dut, bool direction) = NULL; void (*ref_difftest_exec)(uint64_t n) = NULL; +void (*ref_difftest_flash_cpy)(uint8_t* flash_bin, size_t size) = NULL; void (*ref_difftest_raise_intr)(uint64_t NO) = NULL; void (*ref_difftest_dirty_fsvs)(const uint64_t dirties) = NULL; int (*ref_difftest_store_commit)(uint64_t *addr, uint64_t *data, uint8_t *mask) = NULL; @@ -44,6 +45,7 @@ static bool is_detach = false; // can not produce consistent behavior with NEMU void difftest_skip_ref() { if (is_detach) return; + printf("skip ref\n"); is_skip_ref = true; // If such an instruction is one of the instruction packing in QEMU // (see below), we end the process of catching up with QEMU's pc to @@ -74,7 +76,7 @@ void difftest_set_patch(void (*fn)(void *arg), void *arg) { patch_arg = arg; } -void init_difftest(char *ref_so_file, long img_size, int port) { +void init_difftest(char *ref_so_file, long img_size, long flash_size, int port) { assert(ref_so_file != NULL); void *handle; @@ -107,6 +109,9 @@ void init_difftest(char *ref_so_file, long img_size, int port) { ref_difftest_pmp_cfg_cpy = dlsym(handle, "difftest_pmp_cfg_cpy"); assert(ref_difftest_pmp_cfg_cpy); + + ref_difftest_flash_cpy = dlsym(handle, "difftest_load_flash"); + assert(ref_difftest_flash_cpy); #endif #ifdef CONFIG_DIFFTEST_REF_SPIKE @@ -121,6 +126,9 @@ void init_difftest(char *ref_so_file, long img_size, int port) { ref_difftest_init(port); ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF); +#ifdef CONFIG_HAS_FLASH + ref_difftest_flash_cpy(flash_base, flash_size); +#endif ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); } @@ -177,16 +185,17 @@ void difftest_detach() { } void difftest_attach() { -#ifdef CONFIG_HAS_FLASH Log("Difftest attach now!"); is_detach = false; is_skip_ref = false; skip_dut_nr_instr = 0; - isa_difftest_attach(); -#else + + // There are multiple non-register states for spike, + // and entering attach from any execution phase requires + // the ability to correctly implement the settings for + // these states, and the expected repair effort would be enormous assert(0); // fix me -#endif } #else diff --git a/src/device/flash.c b/src/device/flash.c index 5ac0c6733..a7a84cc63 100644 --- a/src/device/flash.c +++ b/src/device/flash.c @@ -118,5 +118,5 @@ void init_flash() { #ifndef CONFIG_SHARE load_flash_contents(CONFIG_FLASH_IMG_PATH); #endif - add_mmio_map("flash", CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, flash_io_handler); + add_mmio_map("flash", CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, SKIP_FREE, flash_io_handler); } diff --git a/src/device/io/mmio.c b/src/device/io/mmio.c index f71cf6a82..2eb4031ba 100644 --- a/src/device/io/mmio.c +++ b/src/device/io/mmio.c @@ -29,8 +29,8 @@ static_assert(MMIO_SPEC_NUM % 2 == 0, "The address space of mmio needs to be spe #endif // CONFIG_ENABLE_CONFIG_MMIO_SPACE -static inline IOMap* fetch_mmio_map(paddr_t addr) { - int mapid = find_mapid_by_addr(maps, nr_map, addr); +static inline IOMap* fetch_mmio_map(paddr_t addr, int type) { + int mapid = find_mapid_by_addr(maps, nr_map, addr, type); return (mapid == -1 ? NULL : &maps[mapid]); } @@ -51,10 +51,10 @@ bool is_in_mmio(paddr_t addr) { } /* device interface */ -void add_mmio_map(const char *name, paddr_t addr, void *space, uint32_t len, io_callback_t callback) { +void add_mmio_map(const char *name, paddr_t addr, void *space, uint32_t len, int skip_ref_flag, io_callback_t callback) { assert(nr_map < NR_MAP); maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1, - .space = space, .callback = callback }; + .space = space, .skip_ref_flag = skip_ref_flag, .callback = callback }; Log("Add mmio map '%s' at [" FMT_PADDR ", " FMT_PADDR "]", maps[nr_map].name, maps[nr_map].low, maps[nr_map].high); fflush(stdout); @@ -62,8 +62,8 @@ void add_mmio_map(const char *name, paddr_t addr, void *space, uint32_t len, io_ nr_map ++; } -bool mmio_is_real_device(paddr_t addr) { - IOMap *map = fetch_mmio_map(addr); +bool mmio_is_real_device(paddr_t addr, int type) { + IOMap *map = fetch_mmio_map(addr, type); return map != NULL && addr <= map->high && addr >= map->low; } @@ -71,10 +71,10 @@ bool mmio_is_real_device(paddr_t addr) { /* bus interface */ __attribute__((noinline)) word_t mmio_read(paddr_t addr, int len) { - return map_read(addr, len, fetch_mmio_map(addr)); + return map_read(addr, len, fetch_mmio_map(addr, MMIO_READ)); } __attribute__((noinline)) void mmio_write(paddr_t addr, int len, word_t data) { - map_write(addr, len, data, fetch_mmio_map(addr)); + map_write(addr, len, data, fetch_mmio_map(addr, MMIO_WRITE)); } diff --git a/src/device/io/port-io.c b/src/device/io/port-io.c index 27c7e4964..5ca60b082 100644 --- a/src/device/io/port-io.c +++ b/src/device/io/port-io.c @@ -22,11 +22,11 @@ static IOMap maps[NR_MAP] = {}; static int nr_map = 0; /* device interface */ -void add_pio_map(const char *name, ioaddr_t addr, void *space, uint32_t len, io_callback_t callback) { +void add_pio_map(const char *name, ioaddr_t addr, void *space, uint32_t len, int skip_ref_flag, io_callback_t callback) { assert(nr_map < NR_MAP); assert(addr + len <= PORT_IO_SPACE_MAX); maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1, - .space = space, .callback = callback }; + .space = space, .skip_ref_flag = skip_ref_flag, .callback = callback }; Log("Add port-io map '%s' at [" FMT_PADDR ", " FMT_PADDR "]", maps[nr_map].name, maps[nr_map].low, maps[nr_map].high); @@ -36,7 +36,7 @@ void add_pio_map(const char *name, ioaddr_t addr, void *space, uint32_t len, io_ /* CPU interface */ uint32_t pio_read(ioaddr_t addr, int len) { assert(addr + len - 1 < PORT_IO_SPACE_MAX); - int mapid = find_mapid_by_addr(maps, nr_map, addr); + int mapid = find_mapid_by_addr(maps, nr_map, addr, MMIO_READ); #ifdef CONFIG_PA assert(mapid != -1); #else @@ -47,7 +47,7 @@ uint32_t pio_read(ioaddr_t addr, int len) { void pio_write(ioaddr_t addr, int len, uint32_t data) { assert(addr + len - 1 < PORT_IO_SPACE_MAX); - int mapid = find_mapid_by_addr(maps, nr_map, addr); + int mapid = find_mapid_by_addr(maps, nr_map, addr, MMIO_WRITE); #ifdef CONFIG_PA assert(mapid != -1); #else diff --git a/src/device/keyboard.c b/src/device/keyboard.c index b3c192130..4ec4b9993 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -74,7 +74,7 @@ static void i8042_data_io_handler(uint32_t offset, int len, bool is_write) { void init_i8042() { i8042_data_port_base = (uint32_t *)new_space(4); i8042_data_port_base[0] = _KEY_NONE; - add_pio_map ("keyboard", CONFIG_I8042_DATA_PORT, i8042_data_port_base, 4, i8042_data_io_handler); - add_mmio_map("keyboard", CONFIG_I8042_DATA_MMIO, i8042_data_port_base, 4, i8042_data_io_handler); + add_pio_map ("keyboard", CONFIG_I8042_DATA_PORT, i8042_data_port_base, 4, MMIO_READ|MMIO_WRITE|MMIO_EXEC, i8042_data_io_handler); + add_mmio_map("keyboard", CONFIG_I8042_DATA_MMIO, i8042_data_port_base, 4, MMIO_READ|MMIO_WRITE|MMIO_EXEC, i8042_data_io_handler); init_keymap(); } diff --git a/src/device/plic.c b/src/device/plic.c index d7c18ae6f..885e56c97 100644 --- a/src/device/plic.c +++ b/src/device/plic.c @@ -11,5 +11,5 @@ static void plic_io_handler(uint32_t offset, int len, bool is_write) { void init_plic(const char *flash_img) { plic_base = new_space(PLIC_SIZE); // TOO MUCH - add_mmio_map("plic", CONFIG_PLIC_ADDRESS, plic_base, PLIC_SIZE, plic_io_handler); + add_mmio_map("plic", CONFIG_PLIC_ADDRESS, plic_base, PLIC_SIZE, MMIO_READ|MMIO_WRITE|MMIO_EXEC, plic_io_handler); } diff --git a/src/device/sdcard.c b/src/device/sdcard.c index c5b23a75c..a8ffc1e16 100644 --- a/src/device/sdcard.c +++ b/src/device/sdcard.c @@ -125,7 +125,7 @@ static void sdcard_io_handler(uint32_t offset, int len, bool is_write) { void init_sdcard() { base = (uint32_t *)new_space(0x80); - add_mmio_map("sdhci", CONFIG_SDCARD_CTL_MMIO, base, 0x80, sdcard_io_handler); + add_mmio_map("sdhci", CONFIG_SDCARD_CTL_MMIO, base, 0x80, MMIO_READ|MMIO_WRITE|MMIO_EXEC, sdcard_io_handler); //base[SDEDM] = (8 << 4); // number of data in fifo diff --git a/src/device/timer.c b/src/device/timer.c index 38af3d8b7..df877d09c 100644 --- a/src/device/timer.c +++ b/src/device/timer.c @@ -37,7 +37,7 @@ static void timer_intr() { void init_timer() { rtc_port_base = (uint32_t *)new_space(8); - add_pio_map ("rtc", CONFIG_RTC_PORT, rtc_port_base, 8, rtc_io_handler); - add_mmio_map("rtc", CONFIG_RTC_MMIO, rtc_port_base, 8, rtc_io_handler); + add_pio_map ("rtc", CONFIG_RTC_PORT, rtc_port_base, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, rtc_io_handler); + add_mmio_map("rtc", CONFIG_RTC_MMIO, rtc_port_base, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, rtc_io_handler); add_alarm_handle(timer_intr); } diff --git a/src/device/uartlite.c b/src/device/uartlite.c index 0db9e4e70..f20ce065d 100644 --- a/src/device/uartlite.c +++ b/src/device/uartlite.c @@ -140,9 +140,9 @@ static void serial_io_handler(uint32_t offset, int len, bool is_write) { void init_uartlite() { serial_base = new_space(0xd); #ifdef CONFIG_UARTLITE_PORT - add_pio_map("uartlite", CONFIG_UARTLITE_PORT, serial_base, 0xd, serial_io_handler); + add_pio_map("uartlite", CONFIG_UARTLITE_PORT, serial_base, 0xd, MMIO_READ|MMIO_WRITE|MMIO_EXEC, serial_io_handler); #endif - add_mmio_map("uartlite", CONFIG_UARTLITE_MMIO, serial_base, 0xd, serial_io_handler); + add_mmio_map("uartlite", CONFIG_UARTLITE_MMIO, serial_base, 0xd, MMIO_READ|MMIO_WRITE|MMIO_EXEC, serial_io_handler); #ifdef CONFIG_UARTLITE_INPUT_FIFO init_fifo(); diff --git a/src/device/vga.c b/src/device/vga.c index 6001789b3..3f3068262 100644 --- a/src/device/vga.c +++ b/src/device/vga.c @@ -65,10 +65,10 @@ void init_vga() { vgactl_port_base = (uint32_t *)new_space(8); vgactl_port_base[0] = ((SCREEN_W) << 16) | (SCREEN_H); #ifndef CONFIG_SHARE - add_pio_map ("screen", CONFIG_VGA_CTL_PORT, vgactl_port_base, 8, NULL); + add_pio_map ("screen", CONFIG_VGA_CTL_PORT, vgactl_port_base, MMIO_READ|MMIO_WRITE|MMIO_EXEC, 8, NULL); #endif - add_mmio_map("screen", CONFIG_VGA_CTL_MMIO, vgactl_port_base, 8, NULL); + add_mmio_map("screen", CONFIG_VGA_CTL_MMIO, vgactl_port_base, MMIO_READ|MMIO_WRITE|MMIO_EXEC, 8, NULL); vmem = (uint32_t (*)[SCREEN_W])new_space(SCREEN_SIZE); - add_mmio_map("vmem", CONFIG_FB_ADDR, vmem, SCREEN_SIZE, NULL); + add_mmio_map("vmem", CONFIG_FB_ADDR, vmem, SCREEN_SIZE, MMIO_READ|MMIO_WRITE|MMIO_EXEC, NULL); } diff --git a/src/isa/riscv64/clint.c b/src/isa/riscv64/clint.c index 2de55a768..655b77c1c 100644 --- a/src/isa/riscv64/clint.c +++ b/src/isa/riscv64/clint.c @@ -59,5 +59,5 @@ static void clint_io_handler(uint32_t offset, int len, bool is_write) { void init_clint() { clint_base = (uint64_t *)new_space(0x10000); init_mtimer_regs(&clint_base[CLINT_MTIME], &clint_base[CLINT_MTIMECMP]); - add_mmio_map("clint", CONFIG_CLINT_MMIO, (uint8_t *)clint_base, 0x10000, clint_io_handler); + add_mmio_map("clint", CONFIG_CLINT_MMIO, (uint8_t *)clint_base, 0x10000, MMIO_READ|MMIO_WRITE|MMIO_EXEC, clint_io_handler); } diff --git a/src/memory/paddr.c b/src/memory/paddr.c index 64d441acc..9720a5496 100644 --- a/src/memory/paddr.c +++ b/src/memory/paddr.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -228,7 +229,7 @@ word_t paddr_read(paddr_t addr, int len, int type, int trap_type, int mode, vadd // check if the address is misaligned isa_mmio_misalign_data_addr_check(addr, vaddr, len, MEM_TYPE_READ, cross_page_load); #ifdef CONFIG_ENABLE_CONFIG_MMIO_SPACE - if (!mmio_is_real_device(addr)) { + if (!mmio_is_real_device(addr, MMIO_READ)) { raise_read_access_fault(trap_type, vaddr); return 0; } @@ -355,7 +356,7 @@ void paddr_write(paddr_t addr, int len, word_t data, int mode, vaddr_t vaddr) { // check if the address is misaligned isa_mmio_misalign_data_addr_check(addr, vaddr, len, MEM_TYPE_WRITE, cross_page_store); #ifdef CONFIG_ENABLE_CONFIG_MMIO_SPACE - if (!mmio_is_real_device(addr)) { + if (!mmio_is_real_device(addr, MMIO_WRITE)) { raise_access_fault(EX_SAF, vaddr); return; } diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 025a1a449..3ba11aebd 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -33,7 +33,7 @@ void init_log(const char *log_file, const bool fast_log, const bool small_log); void init_mem(); void init_regex(); void init_wp_pool(); -void init_difftest(char *ref_so_file, long img_size, int port); +void init_difftest(char *ref_so_file, long img_size, long flash_size, int port); void init_device(); static char *log_file = NULL; @@ -361,6 +361,7 @@ void init_monitor(int argc, char *argv[]) { // when there is a gcpt[restorer], we put bbl after gcpt[restorer] long img_size = 0; // how large we should copy for difftest + long flash_size = 0; // how large we should copy flash for difftest assert(img_file); uint64_t bbl_start = (uint64_t)get_pmem(); @@ -374,7 +375,7 @@ void init_monitor(int argc, char *argv[]) { #ifdef CONFIG_HAS_FLASH // provide checkpoint flash file if (checkpoint_restoring){ - img_size = load_img(checkpoint_flash_path, "checkpoint from cmdline", gcpt_start, 0); + flash_size = load_img(checkpoint_flash_path, "checkpoint from cmdline", gcpt_start, 0); } #endif @@ -404,14 +405,7 @@ void init_monitor(int argc, char *argv[]) { } /* Initialize differential testing. */ - init_difftest(diff_so_file, img_size, difftest_port); - -#ifdef CONFIG_DIFFTEST -#ifdef CONFIG_HAS_FLASH - extern void difftest_detach(); - difftest_detach(); -#endif -#endif + init_difftest(diff_so_file, img_size, flash_size, difftest_port); #endif From 1771d440ce9afa02bd20dca0190d5be1964e8145 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 15:38:28 +0800 Subject: [PATCH 32/40] delete useless output Signed-off-by: jiaxiaoyu --- src/cpu/difftest/dut.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index 9cc113aa9..50976a16c 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -45,7 +45,6 @@ static bool is_detach = false; // can not produce consistent behavior with NEMU void difftest_skip_ref() { if (is_detach) return; - printf("skip ref\n"); is_skip_ref = true; // If such an instruction is one of the instruction packing in QEMU // (see below), we end the process of catching up with QEMU's pc to From ee6b1eccaed66091e50fdacfdd3ccdb692411724 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 15:46:57 +0800 Subject: [PATCH 33/40] delete debug code Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 758258ac5..5c2792541 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,7 +76,6 @@ jobs: make -j bash ./scripts/take_zstd_from_flash.sh make clean-all - cp output_top /nfs/home/share/jxy_output_top -r #restore cpt from flash, with difftest make riscv64-xs-diff-spike-withflash_defconfig From aed3ce19be020793b59779ad0958a985f75429b3 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 15:56:42 +0800 Subject: [PATCH 34/40] bump ready-to-run Signed-off-by: jiaxiaoyu --- ready-to-run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ready-to-run b/ready-to-run index 6cf1f93cd..b3f12b070 160000 --- a/ready-to-run +++ b/ready-to-run @@ -1 +1 @@ -Subproject commit 6cf1f93cda970e279630656ec9d266165a760809 +Subproject commit b3f12b070b60cf5380e6d3282437892723e0e909 From dbf91da12a0ff53b5265784e1923cc5bf62cbd99 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 16:28:04 +0800 Subject: [PATCH 35/40] fix compile in centos docker Signed-off-by: jiaxiaoyu --- src/memory/paddr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/memory/paddr.c b/src/memory/paddr.c index 9720a5496..60138679b 100644 --- a/src/memory/paddr.c +++ b/src/memory/paddr.c @@ -254,7 +254,7 @@ word_t paddr_read(paddr_t addr, int len, int type, int trap_type, int mode, vadd // check if the address is misaligned isa_mmio_misalign_data_addr_check(addr, vaddr, len, MEM_TYPE_READ, cross_page_load); #ifdef CONFIG_ENABLE_CONFIG_MMIO_SPACE - if (!mmio_is_real_device(addr)) { + if (!mmio_is_real_device(addr, MMIO_READ)) { raise_read_access_fault(trap_type, vaddr); return 0; } @@ -380,7 +380,7 @@ void paddr_write(paddr_t addr, int len, word_t data, int mode, vaddr_t vaddr) { // check if the address is misaligned isa_mmio_misalign_data_addr_check(addr, vaddr, len, MEM_TYPE_WRITE, cross_page_store); #ifdef CONFIG_ENABLE_CONFIG_MMIO_SPACE - if (!mmio_is_real_device(addr)) { + if (!mmio_is_real_device(addr, MMIO_WRITE)) { raise_access_fault(EX_SAF, vaddr); return; } From ff7fd5f04532e4c681f795658dacce406babf96a Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 18:46:29 +0800 Subject: [PATCH 36/40] fix ci error Signed-off-by: jiaxiaoyu --- .github/workflows/ci.yml | 1 + src/cpu/difftest/dut.c | 2 +- src/device/flash.c | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c2792541..7e944674e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,7 @@ jobs: - name: Setup env run: | echo "NEMU_HOME=$GITHUB_WORKSPACE" >> $GITHUB_ENV + git submodule update --init --depth=1 - name: Try to compile id: list_configs run: | diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index 50976a16c..82734b424 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -126,7 +126,7 @@ void init_difftest(char *ref_so_file, long img_size, long flash_size, int port) ref_difftest_init(port); ref_difftest_memcpy(RESET_VECTOR, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF); #ifdef CONFIG_HAS_FLASH - ref_difftest_flash_cpy(flash_base, flash_size); + ref_difftest_flash_cpy(flash_base, flash_size ? flash_size : CONFIG_FLASH_SIZE); #endif ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); } diff --git a/src/device/flash.c b/src/device/flash.c index a7a84cc63..951a386c9 100644 --- a/src/device/flash.c +++ b/src/device/flash.c @@ -80,6 +80,7 @@ void convert_to_absolute_path(const char *input_path, char *output_path) { void load_flash_contents(const char *flash_img) { // create mmap with zero contents assert(CONFIG_FLASH_SIZE <= 0x10000000UL); + Log("Flash load img from %s\n", flash_img); FILE *fp = NULL; void *ret = mmap((void *)flash_base, CONFIG_FLASH_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); @@ -95,8 +96,8 @@ void load_flash_contents(const char *flash_img) { } if (!flash_img || !(fp = fopen(real_flash_img, "r"))) { - // Log("Can not find flash image: %s", flash_img); - // Log("Use built-in image instead"); + Log("Can not find flash image: %s", flash_img); + Log("Use built-in image instead"); uint32_t *p = (uint32_t *)flash_base; sscanf(CONFIG_FLASH_PRESET_CONTENT, "%x,%x,%x", p, p + 1, p + 2); } else { From 27a70199214f99da13ae7b1e35ce7f0e3b0dc249 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Wed, 25 Dec 2024 18:53:57 +0800 Subject: [PATCH 37/40] fix ci error Signed-off-by: jiaxiaoyu --- configs/riscv64-nutshell-diff-spike_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/riscv64-nutshell-diff-spike_defconfig b/configs/riscv64-nutshell-diff-spike_defconfig index 878578aae..c3ff807ae 100644 --- a/configs/riscv64-nutshell-diff-spike_defconfig +++ b/configs/riscv64-nutshell-diff-spike_defconfig @@ -117,7 +117,7 @@ CONFIG_RTC_MMIO=0xa1000048 # CONFIG_HAS_SDCARD is not set CONFIG_HAS_FLASH=y CONFIG_FLASH_PRESET_CONTENT="0x0010029b,0x01f29293,0x00028067" -CONFIG_FLASH_START_ADDR=0x10000000 +CONFIG_FLASH_START_ADDR=0x40000000 CONFIG_FLASH_SIZE=0x00000100 CONFIG_FLASH_IMG_PATH="" # CONFIG_FPU_HOST is not set From e3ebffe2f7929234220d43228fb04b3c3ce06f5a Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 26 Dec 2024 10:43:55 +0800 Subject: [PATCH 38/40] fix mmio skip diff flag Signed-off-by: jiaxiaoyu --- src/device/audio.c | 7 +++---- src/device/disk.c | 4 ++-- src/device/serial.c | 4 ++-- src/device/uart_snps.c | 2 +- src/isa/x86/device/i8237a.c | 2 +- src/isa/x86/device/i8253.c | 2 +- src/isa/x86/device/i8259a.c | 4 ++-- src/isa/x86/device/ioport80.c | 2 +- src/isa/x86/device/mc146818rtc.c | 2 +- 9 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/device/audio.c b/src/device/audio.c index 116ca601c..c714e9f37 100644 --- a/src/device/audio.c +++ b/src/device/audio.c @@ -70,10 +70,9 @@ static void audio_io_handler(uint32_t offset, int len, bool is_write) { void init_audio() { uint32_t space_size = sizeof(uint32_t) * nr_reg; audio_base = (uint32_t *)new_space(space_size); - add_pio_map ("audio", CONFIG_AUDIO_CTL_PORT, audio_base, space_size, audio_io_handler); - add_mmio_map("audio", CONFIG_AUDIO_CTL_MMIO, audio_base, space_size, audio_io_handler); + add_pio_map ("audio", CONFIG_AUDIO_CTL_PORT, audio_base, space_size, MMIO_READ|MMIO_WRITE|MMIO_EXEC, audio_io_handler); + add_mmio_map("audio", CONFIG_AUDIO_CTL_MMIO, audio_base, space_size, MMIO_READ|MMIO_WRITE|MMIO_EXEC, audio_io_handler); audio_base[reg_sbuf_size] = CONFIG_SB_SIZE; sbuf = (uint8_t *)new_space(CONFIG_SB_SIZE); - add_mmio_map("audio-sbuf", CONFIG_SB_ADDR, sbuf, CONFIG_SB_SIZE, NULL); -} + add_mmio_map("audio-sbuf", CONFIG_SB_ADDR, sbuf, CONFIG_SB_SIZE, MMIO_READ|MMIO_WRITE|MMIO_EXEC, NULL); diff --git a/src/device/disk.c b/src/device/disk.c index b55cc13ae..2c3ae3586 100644 --- a/src/device/disk.c +++ b/src/device/disk.c @@ -50,8 +50,8 @@ static void disk_io_handler(uint32_t offset, int len, bool is_write) { void init_disk() { uint32_t space_size = sizeof(uint32_t) * NR_REG; disk_base = (uint32_t *)new_space(space_size); - add_pio_map ("disk", CONFIG_DISK_CTL_PORT, disk_base, space_size, disk_io_handler); - add_mmio_map("disk", CONFIG_DISK_CTL_MMIO, disk_base, space_size, disk_io_handler); + add_pio_map ("disk", CONFIG_DISK_CTL_PORT, disk_base, space_size, MMIO_READ|MMIO_WRITE|MMIO_EXEC, disk_io_handler); + add_mmio_map("disk", CONFIG_DISK_CTL_MMIO, disk_base, space_size, MMIO_READ|MMIO_WRITE|MMIO_EXEC, disk_io_handler); const char *path = CONFIG_DISK_IMG_PATH; fp = fopen(path, "r"); diff --git a/src/device/serial.c b/src/device/serial.c index d28ecef4f..3aaf66dca 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -135,8 +135,8 @@ static void serial_io_handler(uint32_t offset, int len, bool is_write) { void init_serial() { printf("init_serial\n"); serial_base = new_space(8); - add_pio_map ("serial", CONFIG_SERIAL_PORT, serial_base, 8, serial_io_handler); - add_mmio_map("serial", CONFIG_SERIAL_MMIO, serial_base, 8, serial_io_handler); + add_pio_map ("serial", CONFIG_SERIAL_PORT, serial_base, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, serial_io_handler); + add_mmio_map("serial", CONFIG_SERIAL_MMIO, serial_base, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, serial_io_handler); #ifdef CONFIG_SERIAL_INPUT_FIFO init_fifo(); diff --git a/src/device/uart_snps.c b/src/device/uart_snps.c index 4a1908821..aca25b8a1 100644 --- a/src/device/uart_snps.c +++ b/src/device/uart_snps.c @@ -172,7 +172,7 @@ void init_uart_snps() { serial_base = new_space(0x100); serial_base[LSR] = 0x60; serial_base[USR] = 0x0; - add_mmio_map("uart_snps", UART0_BASE, serial_base, 0x100, serial_io_handler); + add_mmio_map("uart_snps", UART0_BASE, serial_base, 0x100, MMIO_READ|MMIO_WRITE|MMIO_EXEC, serial_io_handler); #ifdef CONFIG_UART_SNPS_INPUT_FIFO init_fifo(); diff --git a/src/isa/x86/device/i8237a.c b/src/isa/x86/device/i8237a.c index 00a683b00..9a244f567 100644 --- a/src/isa/x86/device/i8237a.c +++ b/src/isa/x86/device/i8237a.c @@ -24,6 +24,6 @@ static void i8237a_io_handler(uint32_t offset, int len, bool is_write) { void init_i8237a() { i8237a_base = (void *)new_space(1); - add_pio_map("i8237a-page0", I8237A_PAGE_0_PORT, i8237a_base, 1, i8237a_io_handler); + add_pio_map("i8237a-page0", I8237A_PAGE_0_PORT, i8237a_base, 1, MMIO_READ|MMIO_WRITE|MMIO_EXEC, i8237a_io_handler); i8237a_base[0] = 0xff; } diff --git a/src/isa/x86/device/i8253.c b/src/isa/x86/device/i8253.c index b6eaec4d9..87a75230a 100644 --- a/src/isa/x86/device/i8253.c +++ b/src/isa/x86/device/i8253.c @@ -24,5 +24,5 @@ static void i8253_io_handler(uint32_t offset, int len, bool is_write) { void init_i8253() { i8253_base = (void *)new_space(4); - add_pio_map("i8253-pit", I8253_PORT, i8253_base, 4, i8253_io_handler); + add_pio_map("i8253-pit", I8253_PORT, i8253_base, 4, MMIO_READ|MMIO_WRITE|MMIO_EXEC, i8253_io_handler); } diff --git a/src/isa/x86/device/i8259a.c b/src/isa/x86/device/i8259a.c index 94ed38d5e..1a7872da6 100644 --- a/src/isa/x86/device/i8259a.c +++ b/src/isa/x86/device/i8259a.c @@ -25,6 +25,6 @@ static void i8259a_io_handler(uint32_t offset, int len, bool is_write) { void init_i8259a() { i8259a_base = (void *)new_space(2); - add_pio_map("i8259a-master", I8259A_MASTER_PORT, i8259a_base, 2, i8259a_io_handler); - add_pio_map("i8259a-slave", I8259A_SLAVE_PORT, i8259a_base, 2, i8259a_io_handler); + add_pio_map("i8259a-master", I8259A_MASTER_PORT, i8259a_base, 2, MMIO_READ|MMIO_WRITE|MMIO_EXEC, i8259a_io_handler); + add_pio_map("i8259a-slave", I8259A_SLAVE_PORT, i8259a_base, 2, MMIO_READ|MMIO_WRITE|MMIO_EXEC, i8259a_io_handler); } diff --git a/src/isa/x86/device/ioport80.c b/src/isa/x86/device/ioport80.c index 8e4871895..c8eac17cf 100644 --- a/src/isa/x86/device/ioport80.c +++ b/src/isa/x86/device/ioport80.c @@ -25,5 +25,5 @@ static void ioport80_io_handler(uint32_t offset, int len, bool is_write) { void init_ioport80() { ioport80_base = (void *)new_space(1); - add_pio_map("ioport80", IOPORT80_PORT, ioport80_base, 1, ioport80_io_handler); + add_pio_map("ioport80", IOPORT80_PORT, ioport80_base, 1, MMIO_READ|MMIO_WRITE|MMIO_EXEC, ioport80_io_handler); } diff --git a/src/isa/x86/device/mc146818rtc.c b/src/isa/x86/device/mc146818rtc.c index eff5db1cd..e0a971cec 100644 --- a/src/isa/x86/device/mc146818rtc.c +++ b/src/isa/x86/device/mc146818rtc.c @@ -24,5 +24,5 @@ static void rtc_io_handler(uint32_t offset, int len, bool is_write) { void init_mc146818rtc() { rtc_base = (void *)new_space(2); - add_pio_map("mc146818rtc", RTC_PORT, rtc_base, 2, rtc_io_handler); + add_pio_map("mc146818rtc", RTC_PORT, rtc_base, 2, MMIO_READ|MMIO_WRITE|MMIO_EXEC, rtc_io_handler); } From 0230e0f72534dbc34ccc122e395f04ac63931e7b Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 26 Dec 2024 11:55:18 +0800 Subject: [PATCH 39/40] fix mmio skip difftest ref Signed-off-by: jiaxiaoyu --- src/device/audio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/device/audio.c b/src/device/audio.c index c714e9f37..00c68c479 100644 --- a/src/device/audio.c +++ b/src/device/audio.c @@ -76,3 +76,4 @@ void init_audio() { sbuf = (uint8_t *)new_space(CONFIG_SB_SIZE); add_mmio_map("audio-sbuf", CONFIG_SB_ADDR, sbuf, CONFIG_SB_SIZE, MMIO_READ|MMIO_WRITE|MMIO_EXEC, NULL); +} From c023a91d8845f48cd2525f127dc523f84b5e8d69 Mon Sep 17 00:00:00 2001 From: jiaxiaoyu Date: Thu, 26 Dec 2024 14:47:49 +0800 Subject: [PATCH 40/40] fix mmio map Signed-off-by: jiaxiaoyu --- src/device/vga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/vga.c b/src/device/vga.c index 3f3068262..5415aa766 100644 --- a/src/device/vga.c +++ b/src/device/vga.c @@ -65,9 +65,9 @@ void init_vga() { vgactl_port_base = (uint32_t *)new_space(8); vgactl_port_base[0] = ((SCREEN_W) << 16) | (SCREEN_H); #ifndef CONFIG_SHARE - add_pio_map ("screen", CONFIG_VGA_CTL_PORT, vgactl_port_base, MMIO_READ|MMIO_WRITE|MMIO_EXEC, 8, NULL); + add_pio_map ("screen", CONFIG_VGA_CTL_PORT, vgactl_port_base, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, NULL); #endif - add_mmio_map("screen", CONFIG_VGA_CTL_MMIO, vgactl_port_base, MMIO_READ|MMIO_WRITE|MMIO_EXEC, 8, NULL); + add_mmio_map("screen", CONFIG_VGA_CTL_MMIO, vgactl_port_base, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, NULL); vmem = (uint32_t (*)[SCREEN_W])new_space(SCREEN_SIZE); add_mmio_map("vmem", CONFIG_FB_ADDR, vmem, SCREEN_SIZE, MMIO_READ|MMIO_WRITE|MMIO_EXEC, NULL);