diff --git a/.gitignore b/.gitignore index dcecdc1..e9c6af4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,5 @@ -**/.gdbinit -!*/ +*/.gdbinit difftest/ -!/nemu/* -!/nexus-am/* -!/nanos-lite/* -!/navy-apps/* -!/npc/* -!Makefile -!README.md -!.gitignore -!init.sh /fceux-am /nvboard **/.cache diff --git a/nemu/configs/libdefconfig b/nemu/configs/libdefconfig new file mode 100644 index 0000000..1408a84 --- /dev/null +++ b/nemu/configs/libdefconfig @@ -0,0 +1,87 @@ +# +# Automatically generated file; DO NOT EDIT. +# NEMU Configuration Menu +# +# CONFIG_ISA_x86 is not set +# CONFIG_ISA_mips32 is not set +CONFIG_ISA_riscv=y +# CONFIG_ISA_loongarch32r is not set +CONFIG_ISA="riscv32" + +# +# ISA-dependent Options for riscv +# +# CONFIG_RV64 is not set +# CONFIG_RVE is not set +# end of ISA-dependent Options for riscv + +CONFIG_ENGINE_INTERPRETER=y +CONFIG_ENGINE="interpreter" +CONFIG_MODE_SYSTEM=y +# CONFIG_TARGET_NATIVE_ELF is not set +CONFIG_TARGET_SHARE=y +# CONFIG_TARGET_AM 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_LTO is not set +# CONFIG_CC_DEBUG is not set +# CONFIG_CC_ASAN is not set +# end of Build Options + +# +# Testing and Debugging +# +CONFIG_LOG_TRACE=y +# CONFIG_LOG_INFO is not set +# CONFIG_LOG_WARNING is not set +# CONFIG_LOG_ERROR is not set +CONFIG_LOG_LEVEL=4 +CONFIG_TRACE=y +CONFIG_TRACE_START=0 +CONFIG_TRACE_END=10000 +# CONFIG_MTRACE is not set +CONFIG_DIFFTEST_REF_PATH="none" +CONFIG_DIFFTEST_REF_NAME="none" +# end of Testing and Debugging + +# +# Memory Configuration +# +CONFIG_MBASE=0x80000000 +CONFIG_MSIZE=0x8000000 +CONFIG_PC_RESET_OFFSET=0 +# CONFIG_PMEM_MALLOC is not set +CONFIG_PMEM_GARRAY=y +CONFIG_MEM_RANDOM=y +# end of Memory Configuration + +CONFIG_DEVICE=y +CONFIG_HAS_SERIAL=y +CONFIG_SERIAL_MMIO=0x10000000 +# CONFIG_SERIAL_INPUT_FIFO is not set +CONFIG_HAS_TIMER=y +CONFIG_RTC_MMIO=0x10001000 +# CONFIG_HAS_KEYBOARD is not set +# CONFIG_HAS_VGA is not set +# CONFIG_HAS_AUDIO is not set +# CONFIG_HAS_DISK is not set +# CONFIG_HAS_SDCARD is not set + +# +# Miscellaneous +# +CONFIG_TIMER_GETTIMEOFDAY=y +# CONFIG_TIMER_CLOCK_GETTIME is not set +CONFIG_RT_CHECK=y +# end of Miscellaneous diff --git a/nemu/default.nix b/nemu/default.nix index 1977e53..9f1276a 100644 --- a/nemu/default.nix +++ b/nemu/default.nix @@ -1,19 +1,26 @@ -{ pkgs, - lib, - stdenv, - dtc, - mini-gdbstub, - am-kernels ? null, - defconfig ? "alldefconfig", +{ stdenv +, lib +, gnumake +, pkg-config +, bison +, flex +, dtc +, check +, mini-gdbstub +, readline +, libllvm +, SDL2 +, am-kernels ? "" +, defconfig ? "alldefconfig" }: stdenv.mkDerivation rec { pname = "nemu"; - version = "2024-03-02"; + version = "2024-08-15"; src = ./.; - nativeBuildInputs = with pkgs; [ + nativeBuildInputs = [ gnumake pkg-config flex @@ -21,14 +28,15 @@ stdenv.mkDerivation rec { dtc ]; - buildInputs = with pkgs; [ + buildInputs = [ + SDL2 readline libllvm mini-gdbstub ]; checkInputs = [ - pkgs.check + check am-kernels ]; @@ -41,26 +49,23 @@ stdenv.mkDerivation rec { make ''; - doCheck = (am-kernels != null); - checkPhase = if doCheck then '' + doCheck = (am-kernels != ""); + checkPhase = '' export NEMU_IMAGES_PATH=${am-kernels}/share/am-kernels make test - '' else ""; + ''; installPhase = '' - mkdir -p $out/bin - mkdir -p $out/lib + if [ -d "./lib" ] && [ "$(ls -A ./lib)" ]; then + mkdir -p "$out/lib" + fi + if [ -d "./bin" ] && [ "$(ls -A ./bin)" ]; then + mkdir -p $out/bin + fi make PREFIX=$out install ''; shellHook = '' export NEMU_HOME=$(pwd) ''; - - meta = with lib; { - description = "NJU EMUlator, a full system x86/mips32/riscv32/riscv64 emulator for teaching"; - homepage = "https://github.com/NJU-ProjectN/nemu.git"; - license = with licenses; [ ]; - maintainers = with maintainers; [ ]; - }; } diff --git a/nemu/tests/Makefile b/nemu/tests/Makefile index 1575102..ffbe26f 100644 --- a/nemu/tests/Makefile +++ b/nemu/tests/Makefile @@ -1,5 +1,4 @@ -TEST_SRCS += tests/expr_test.c -YACC = bison +TEST_SRCS += $(OBJ_DIR)/%: %.c $(TEST_OBJS) app @mkdir -p $(dir $@) diff --git a/nemu/tests/expr_test.c b/nemu/tests/expr_test.c deleted file mode 100644 index d581cf2..0000000 --- a/nemu/tests/expr_test.c +++ /dev/null @@ -1,244 +0,0 @@ -#include "macro.h" -#include "sys/types.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char buf[65536] = {}, ref_buf[65536] = {}; -static char code_buf[65536 + 128] = {}; // a little larger than `buf` -const int buf_start_pos = 0; -char *buf_ptr = buf + buf_start_pos, *ref_buf_ptr = ref_buf; -static char *code_format = "#include \n" - "#include \n" - "int main() { " - " uint32_t result = %s; " - " printf(\"%%u\", result); " - " return 0; " - "}"; - -void gen(char c) { - *(buf_ptr++) = c; - *(ref_buf_ptr++) = c; -} - -void gen_num(void) { - uint32_t num = rand(); - int len = 0, ref_len = 0; - switch (rand() % 3) { - case 0: - len = snprintf(buf_ptr, 100, "%u", num); - ref_len = snprintf(ref_buf_ptr, 100, "%uU", num); - break; - case 1: - len = snprintf(buf_ptr, 100, "0x%x", num); - ref_len = snprintf(ref_buf_ptr, 100, "%uU", num); - break; - case 2: - len = snprintf(buf_ptr, 100, "%d", num); - ref_len = snprintf(ref_buf_ptr, 100, "%d", num); - break; - default: - assert(0); - } - buf_ptr += len; - ref_buf_ptr += ref_len; -} - -void gen_rand_op(void) { - switch (rand() % 4) { - case 0: - gen('+'); - break; - case 1: - gen('-'); - break; - case 2: - gen('*'); - break; - case 3: - gen('/'); - break; - } -} - -void gen_rand_expr(void) { - int choice = rand() % 3; - if (buf_ptr - buf > 2000) { - choice = 0; - } - switch (choice) { - case 0: - gen_num(); - break; - case 1: - gen('('); - gen_rand_expr(); - gen(')'); - break; - default: - gen_rand_expr(); - gen(' '); - gen_rand_op(); - gen(' '); - gen_rand_expr(); - break; - } -} - -START_TEST(test_expr_random_100) { - srand(time(0) + _i * 100); - gen_rand_expr(); - - sprintf(code_buf, code_format, ref_buf); - - FILE *fp = fopen("/tmp/.code.c", "w"); - ck_assert(fp != NULL); - fputs(code_buf, fp); - fclose(fp); - - int ret = - system("gcc /tmp/.code.c -Werror=div-by-zero -o /tmp/.expr 2>/dev/null"); - if (ret == 256) { - // Probably devide by zero. Skip - goto clean_up; - } - ck_assert_msg(!ret, "system ret: %d, error: %s", ret, strerror(ret)); - - fp = popen("/tmp/.expr", "r"); - ck_assert(fp != NULL); - - uint32_t reference; - ret = fscanf(fp, "%u", &reference); - ck_assert(ret == 1); - pclose(fp); - // fprintf(stderr, "\n\tbuf = %s\n\taddr = %u, reference = %u", buf, addr, - // reference); - - yy_scan_string(buf + buf_start_pos); - uint32_t addr; - ck_assert(!yyparse(&addr)); - yylex_destroy(); - - ck_assert_msg(addr == reference, - "\n\tbuf = %s\n\t(addr = %u) != (reference = %u)\n", buf, addr, - reference); - -clean_up: - while (buf_ptr != buf + buf_start_pos) { - *(--buf_ptr) = '\0'; - } - while (ref_buf_ptr != ref_buf) { - *(--ref_buf_ptr) = '\0'; - } -} -END_TEST - -struct { - const char *expr; - uint32_t reference; -} exprs[] = { - {"-1", 0xFFFFFFFFU}, - {"-0x1", 0xFFFFFFFFU}, - {"0--1", 0x1}, - {"0--0x1", 0x1}, -}, reg_exprs[] = { - {"$ra", 0x1}, - {"0x2 + 4*-$a7", 0xFFFFFFBEU}, - {"0x1831/$gp + 13", 2077U}, - {"$$0 == 123", 0}, - {"$$0 == 0", 1}, -}; -START_TEST(test_expr_negative_operand) { - yy_scan_string(exprs[_i].expr); - uint32_t addr; - ck_assert(!yyparse(&addr)); - yylex_destroy(); - - ck_assert_msg(addr == exprs[_i].reference, - "\n\texpr = %s\n\t(addr = %u) != (reference = %u)\n", exprs[_i].expr, - addr, exprs[_i].reference); -} -END_TEST - -extern const char *regs[]; -START_TEST(test_expr_plain_register) { - int i, j, result; - char buf[30] = {}; - uint32_t value; - // NOTE: need to fix this if want to support more arch - buf[0] = '$'; - for (i = 0; i < 32; i++) { - ck_assert(strncpy(buf + 1, regs[i], 10) != NULL); - gpr(i) = i; - yy_scan_string(buf); - result = yyparse(&value); - yylex_destroy(); - ck_assert_msg(result == 0, "expr = %s\n", buf); - - ck_assert(value == i); - for (j = 1; j < 10; j++) { - buf[j] = '\0'; - } - } - -} -END_TEST - -START_TEST(test_expr_register) { - int i; - uint32_t value; - for (i = 0; i < 32; i++) { - gpr(i) = i; - } - - yy_scan_string(reg_exprs[_i].expr); - ck_assert(!yyparse(&value)); - yylex_destroy(); - - ck_assert_msg(value == reg_exprs[_i].reference, - "\n\texpr = %s\n\t(addr = %u) != (reference = %u)\n", reg_exprs[_i].expr, - value, reg_exprs[_i].reference); -} -END_TEST - -Suite *expr_suite(void) { - Suite *s; - TCase *tc_core; - - s = suite_create("Expr test"); - tc_core = tcase_create("Core"); - - tcase_add_loop_test(tc_core, test_expr_random_100, 0, 20); - tcase_add_loop_test(tc_core, test_expr_negative_operand, 0, - sizeof(exprs) / sizeof(exprs[0])); - tcase_add_loop_test(tc_core, test_expr_register, 0, - sizeof(reg_exprs) / sizeof(reg_exprs[0])); - tcase_add_test(tc_core, test_expr_plain_register); - suite_add_tcase(s, tc_core); - - return s; -} - -int main(void) { - int number_failed; - Suite *s; - SRunner *sr; - - s = expr_suite(); - sr = srunner_create(s); - - srunner_run_all(sr, CK_NORMAL); - number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - - return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -}