diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 816dad9c0..7e944674e 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: @@ -22,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: | @@ -40,6 +42,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,11 +65,24 @@ 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 make clean-all + rm -rf output_top + + #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 @@ -80,6 +96,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 @@ -92,7 +109,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 @@ -108,12 +125,12 @@ 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 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 @@ -134,7 +151,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,19 +271,19 @@ 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 - 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: | 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..d0be2faf5 100644 --- a/Makefile +++ b/Makefile @@ -65,6 +65,12 @@ 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 +INC_DIR += include/checkpoint +SRCS-y += $(patsub %.proto,%.pb.c,(shell find $(DIRS-y) -name "*.proto")) SRCS = $(SRCS-y) 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 diff --git a/configs/riscv64-xs-cpt-flash_defconfig b/configs/riscv64-xs-cpt-flash_defconfig new file mode 100644 index 000000000..2519ec2f0 --- /dev/null +++ b/configs/riscv64-xs-cpt-flash_defconfig @@ -0,0 +1,210 @@ +# +# 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_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-cpt_defconfig b/configs/riscv64-xs-cpt_defconfig index 6638fef38..7564e574e 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 @@ -61,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 @@ -78,6 +82,7 @@ CONFIG_USE_XS_ARCH_CSRS=y 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 @@ -118,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 # @@ -128,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 @@ -176,7 +182,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/configs/riscv64-xs-diff-spike-withflash_defconfig b/configs/riscv64-xs-diff-spike-withflash_defconfig new file mode 100644 index 000000000..9c45166ae --- /dev/null +++ b/configs/riscv64-xs-diff-spike-withflash_defconfig @@ -0,0 +1,217 @@ +# +# 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_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/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..497f373d3 --- /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 = 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); + +#endif diff --git a/include/checkpoint/serializer.h b/include/checkpoint/serializer.h index 9045e4c67..b5d380777 100644 --- a/include/checkpoint/serializer.h +++ b/include/checkpoint/serializer.h @@ -23,18 +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 serializePMem(uint64_t inst_count, bool using_gcpt_mmio, uint8_t *pmem_addr, uint8_t *gcpt_mmio_addr); - void serializeRegs(); - - explicit Serializer(); + void serializeRegs(uint8_t *serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout); void init(); @@ -52,21 +53,6 @@ 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; - bool regDumped{false}; std::map simpoint2Weights; 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/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/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/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/ready-to-run b/ready-to-run index 2faf29fbe..b3f12b070 160000 --- a/ready-to-run +++ b/ready-to-run @@ -1 +1 @@ -Subproject commit 2faf29fbe4c01cbfe36be30ebd5dc7fa59b01f05 +Subproject commit b3f12b070b60cf5380e6d3282437892723e0e909 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/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/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_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 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 ec13e5920..7ff006071 100644 --- a/src/checkpoint/serializer.cpp +++ b/src/checkpoint/serializer.cpp @@ -27,9 +27,9 @@ #include #include -#include #include #include +#include #include #include @@ -46,24 +46,6 @@ 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) -{ -} - 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); @@ -71,89 +53,185 @@ 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 +#include +#include } +Serializer serializer; + #ifdef CONFIG_MEM_COMPRESS -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) { // 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(); - - if (restorer) { - FILE *restore_fp = fopen(restorer, "rb"); - if (!restore_fp) { - xpanic("Cannot open restorer %s\n", restorer); - } - - uint32_t restorer_size = 0xf00; - fseek(restore_fp, 0, SEEK_SET); - assert(restorer_size == fread(pmem, 1, restorer_size, restore_fp)); - fclose(restore_fp); + Log("Host physical address: %p size: %lx", pmem_addr, PMEM_SIZE); - Log("Put gcpt restorer %s to start of pmem", restorer); - } +#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 filepath; + string base_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) { - filepath += "_.gz"; - gzFile compressed_mem = gzopen(filepath.c_str(), "wb"); - if (compressed_mem == nullptr) { - cerr << "Failed to open " << filepath << endl; + 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"); + 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 " << filepath << " as checkpoint output file" << endl; + cout << "Opening " << memory_file_path << " as checkpoint output file" << endl; } 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; + 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() + : ((int64_t)GCPT_MMIO_SIZE - (int64_t)gcpt_written); + 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); + } + + pass_size = 0; +#endif + } for (uint64_t written = 0; written < PMEM_SIZE; written += pass_size) { pass_size = numeric_limits::max() < ((int64_t)PMEM_SIZE - (int64_t)written) ? 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(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"); } + } else if (compress_file_format == ZSTD_FORMAT) { - filepath += "_.zstd"; + Log("Using ZSTD format generate checkpoint"); + + memory_file_path += base_file_path + "_memory_.zstd"; + Log("Opening %s as memory output file", memory_file_path.c_str()); + // zstd compress - size_t const compress_buffer_size = ZSTD_compressBound(PMEM_SIZE); - void *const compress_buffer = malloc(compress_buffer_size); - assert(compress_buffer); + size_t memory_size = PMEM_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); + assert(memory_compress_buffer); + + __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); + 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); + } +#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); + Log("pmem compress success, compress size %ld", memory_compress_size); - 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); + 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); - FILE *compress_file = fopen(filepath.c_str(), "wb"); - size_t fw_size = fwrite(compress_buffer, 1, compress_size, compress_file); + 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); +#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 (fw_size != (size_t)compress_size) { - free(compress_buffer); - xpanic("file write error: %s : %s \n", filepath.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(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); +#ifdef CONFIG_HAS_FLASH + free(flash_compress_buffer); +#endif + free(memory_compress_buffer); + } else { xpanic("You need to specify the compress file format using: --checkpoint-format\n"); } @@ -162,121 +240,147 @@ void Serializer::serializePMem(uint64_t inst_count) { 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 extern void csr_writeback(); -void Serializer::serializeRegs() { - auto *intRegCpt = (uint64_t *) (get_pmem() + IntRegStartAddr); +void Serializer::serializeRegs(uint8_t* serialize_base_addr, single_core_rvgc_rvv_rvh_memlayout *cpt_percpu_layout) { + // int reg + 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 @[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 @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 - auto *floatRegCpt = (uint64_t *)(get_pmem() + FloatRegStartAddr); + 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 @[0x%x, 0x%x) [0x%x, 0x%x)", FLOAT_REG_CPT_ADDR, - FLOAT_REG_CPT_ADDR + 32 * 8, FloatRegStartAddr, FloatRegStartAddr + 32 * 8); + 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 - auto *vectorRegCpt = (uint64_t *) (get_pmem() + VecRegStartAddr); + 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]; + *(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 - ); -#endif // CONFIG_RVV - - - auto *pc = (uint64_t *) (get_pmem() + PCAddr); + 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 = 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 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_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]); + // csr reg + // donot need reset mip.x + 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++) { - 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; - } - // Log("Saving mip: 0x%x", mip_tmp.val); - val = mip_tmp.val; - } - - *(csrCpt + i) = val; - + *(csrCpt + i) = csr_array[i]; 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_prepare=(mstatus_t *)&csrCpt[0x300]; - mstatus_prepare->mpie=mstatus_prepare->mie; - mstatus_prepare->mie=0; - mstatus_prepare->mpp=cpu.mode; - + // priv mode + 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%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) { + // 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_prepare=(mepc_t*)&csrCpt[0x341]; - mepc_prepare->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%x, 0x%x) [0x%x, 0x%x)", - CSR_REG_CPT_ADDR, CSR_REG_CPT_ADDR + 4096 * 8, - CSRStartAddr, CSRStartAddr + 4096 * 8 - ); + } else { + Log("Generate this checkpoint from M mode !!!!!!!!!!!!!!"); + } + 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 *)(get_pmem() + CptFlagAddr); + 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); - auto *mode_flag = (uint64_t *) (get_pmem() + MODEAddr); - *mode_flag = cpu.mode; - Log("Record mode flag: 0x%lx at addr 0x%x", cpu.mode, MODE_CPT_ADDR); - - auto *mtime = (uint64_t *) (get_pmem() + MTIMEAddr); + // time + 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 at addr 0x%x", cpu.mode, MTIME_CPT_ADDR); + 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); - auto *mtime_cmp = (uint64_t *) (get_pmem() + MTIMECMPAddr); + 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: 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%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); 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) { - +void Serializer::serialize(uint64_t inst_count, bool write_to_flash) { #ifdef CONFIG_MEM_COMPRESS - serializeRegs(); - serializePMem(inst_count); + //checkpoint_header cpt_header = default_cpt_header; + single_core_rvgc_rvv_rvh_memlayout cpt_percpu_layout = default_cpt_percpu_layout; + uint8_t* serialize_reg_base_addr = NULL; + //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(); + } + + 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 @@ -367,7 +471,7 @@ 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()) { @@ -379,25 +483,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_flash_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 2ba16f198..5a51afe1f 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_next_generation_checkpoint = false; + +void set_using_gcpt_mmio(bool value){ + using_next_generation_checkpoint = value; +} + void save_globals(Decode *s) { IFDEF(CONFIG_PERF_OPT, prev_s = s); } // Get the number of executed instructions: @@ -220,8 +226,8 @@ 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 = s->tnext; \ is_ctrl = true; \ + s = s->tnext; \ br_taken = true; \ goto end_of_bb; \ } while (0) @@ -231,8 +237,8 @@ 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)); \ is_ctrl = true; \ + s = jr_fetch(s, *(target)); \ br_taken = true; \ goto end_of_bb; \ } while (0) @@ -269,6 +275,7 @@ static bool manual_cpt_quit = false; } \ } while (0) + #define rtl_priv_jr(s, target) \ do { \ /* Settle instruction counting for the last bb. */ \ @@ -319,11 +326,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 +333,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; } @@ -359,8 +360,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_next_generation_checkpoint); if (taken) { Log("Have taken checkpoint on pc 0x%lx", s->pc); if (recvd_manual_oneshot_cpt) { @@ -401,6 +402,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 +465,9 @@ static void execute(int n) { IFDEF(CONFIG_INSTR_CNT_BY_INSTR, n_remain -= 1); save_globals(s); + debug_difftest(this_s, s); + } end_of_loop: @@ -894,17 +898,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_next_generation_checkpoint); + } +#else + break; +#endif } pop_context(); } diff --git a/src/cpu/difftest/dut.c b/src/cpu/difftest/dut.c index b250abc71..82734b424 100644 --- a/src/cpu/difftest/dut.c +++ b/src/cpu/difftest/dut.c @@ -20,10 +20,14 @@ #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; +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; @@ -71,7 +75,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; @@ -98,6 +102,17 @@ 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); + + ref_difftest_flash_cpy = dlsym(handle, "difftest_load_flash"); + assert(ref_difftest_flash_cpy); +#endif + #ifdef CONFIG_DIFFTEST_REF_SPIKE ref_difftest_store_commit = dlsym(handle, "difftest_store_commit"); assert(ref_difftest_store_commit); @@ -110,6 +125,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 ? flash_size : CONFIG_FLASH_SIZE); +#endif ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF); } @@ -161,15 +179,22 @@ 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() { + Log("Difftest attach now!"); is_detach = false; is_skip_ref = false; skip_dut_nr_instr = 0; - isa_difftest_attach(); + + // 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 } #else diff --git a/src/device/audio.c b/src/device/audio.c index 116ca601c..00c68c479 100644 --- a/src/device/audio.c +++ b/src/device/audio.c @@ -70,10 +70,10 @@ 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/device.c b/src/device/device.c index 98c33cb51..2b194edfe 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -99,9 +99,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/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/flash.c b/src/device/flash.c index 4840f0e70..951a386c9 100644 --- a/src/device/flash.c +++ b/src/device/flash.c @@ -15,21 +15,73 @@ #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 *flash_base = (uint8_t *)0xf0000000ul; + +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; } +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); + 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); if (ret != flash_base) { @@ -37,9 +89,15 @@ void load_flash_contents(const char *flash_img) { assert(0); } - if (!flash_img || !(fp = fopen(flash_img, "r"))) { - // Log("Can not find flash image: %s", flash_img); - // Log("Use built-in image instead"); + 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; sscanf(CONFIG_FLASH_PRESET_CONTENT, "%x,%x,%x", p, p + 1, p + 2); } else { @@ -58,5 +116,8 @@ void load_flash_contents(const char *flash_img) { } void init_flash() { - add_mmio_map("flash", CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, flash_io_handler); +#ifndef CONFIG_SHARE + load_flash_contents(CONFIG_FLASH_IMG_PATH); +#endif + add_mmio_map("flash", CONFIG_FLASH_START_ADDR, flash_base, CONFIG_FLASH_SIZE, SKIP_FREE, flash_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; diff --git a/src/device/io/mmio.c b/src/device/io/mmio.c index 7ced979c6..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,19 +51,19 @@ 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 }; - // Log("Add mmio map '%s' at [" FMT_PADDR ", " FMT_PADDR "]", - // maps[nr_map].name, maps[nr_map].low, maps[nr_map].high); - // fflush(stdout); + .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); 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/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/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/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/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..5415aa766 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, 8, MMIO_READ|MMIO_WRITE|MMIO_EXEC, 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, 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, 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/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); } 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/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); } diff --git a/src/memory/paddr.c b/src/memory/paddr.c index 64d441acc..60138679b 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; } @@ -253,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; } @@ -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; } @@ -379,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; } diff --git a/src/monitor/image_loader.c b/src/monitor/image_loader.c index 21dc24f86..480b4f56e 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/checkpoint.pb.h" +#include "debug.h" #include #include #include #include #include #include +#include #include #include #include @@ -31,18 +34,19 @@ #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; - 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; @@ -66,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; @@ -138,12 +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; // decompress and write in memory - uint64_t total_write_size = 0; - while (total_write_size < MEMORY_SIZE) { + size_t total_write_size = 0; + size_t load_size = img_size == 0 ? MEMORY_SIZE : img_size; + + while (total_write_size < load_size) { ZSTD_outBuffer output = {decompress_file_buffer, decompress_file_buffer_size * sizeof(uint64_t), 0}; @@ -209,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 @@ -218,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 @@ -252,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 e076e0b3c..3ba11aebd 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(); @@ -32,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; @@ -44,11 +45,14 @@ 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; 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 @@ -82,6 +86,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,25 +100,27 @@ 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}, + // checkpoint + {"restore" , required_argument, NULL, 'c'}, + // gcpt-restore + {"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}, + {"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}, @@ -150,6 +158,7 @@ static inline int parse_args(int argc, char *argv[]) { case 'c': checkpoint_restoring = true; + checkpoint_flash_path = optarg; Log("Restoring from checkpoint"); break; @@ -227,6 +236,14 @@ static inline int parse_args(int argc, char *argv[]) { break; } + case 16: { + // --next-generation-checkpoint + using_generation_checkpoint = true; + extern void set_using_gcpt_mmio(bool value); + set_using_gcpt_mmio(using_generation_checkpoint); + break; + } + case 4: sscanf(optarg, "%d", &cpt_id); break; case 12: @@ -271,6 +288,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--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"); @@ -338,15 +356,30 @@ 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] + 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 = RESET_VECTOR; - if (restorer) { - bbl_start += CONFIG_BBL_OFFSET_WITH_CPT; - } + uint64_t bbl_start = (uint64_t)get_pmem(); +#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){ + flash_size = load_img(checkpoint_flash_path, "checkpoint from cmdline", gcpt_start, 0); + } +#endif + + // provide gcpt restore if (restorer) { FILE *restore_fp = fopen(restorer, "rb"); Assert(restore_fp, "Can not open '%s'", restorer); @@ -364,14 +397,15 @@ void init_monitor(int argc, char *argv[]) { fclose(restore_fp); - load_img(restorer, "Gcpt restorer form cmdline", RESET_VECTOR, restore_size); +#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. */ - init_difftest(diff_so_file, img_size, difftest_port); - - /* Initialize devices. */ - init_device(); + init_difftest(diff_so_file, img_size, flash_size, difftest_port); #endif 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);