staticvoidout_of_bound(paddr_t addr) { panic("address = " FMT_PADDR " is out of bound of pmem [" FMT_PADDR ", " FMT_PADDR "] at pc = " FMT_WORD, addr, PMEM_LEFT, PMEM_RIGHT, cpu.pc); }
word_tpaddr_read(paddr_t addr, int len) { if (likely(in_pmem(addr))) return pmem_read(addr, len); IFDEF(CONFIG_DEVICE, return mmio_read(addr, len)); out_of_bound(addr); return0; }
// this is not consistent with uint8_t // but it is ok since we do not access the array directly staticconstuint32_t img [] = { 0x00000297, // auipc t0,0 0x00028823, // sb zero,16(t0) 0x0102c503, // lbu a0,16(t0) 0x00100073, // ebreak (used as nemu_trap) 0xdeadbeef, // some data };
staticvoidrestart() { /* Set the initial program counter. */ cpu.pc = RESET_VECTOR;
/* The zero register is always 0. */ cpu.gpr[0] = 0; }
make run + CC src/memory/paddr.c + LD /home/luyoung/ysyx-workbench/nemu/build/riscv32-nemu-interpreter make[1]: Entering directory '/home/luyoung/ysyx-workbench' make[1]: Leaving directory '/home/luyoung/ysyx-workbench' make[1]: Entering directory '/home/luyoung/ysyx-workbench' make[1]: Leaving directory '/home/luyoung/ysyx-workbench' /home/luyoung/ysyx-workbench/nemu/build/riscv32-nemu-interpreter --log=/home/luyoung/ysyx-workbench/nemu/build/nemu-log.txt [src/utils/log.c:30 init_log] Log is written to /home/luyoung/ysyx-workbench/nemu/build/nemu-log.txt [src/memory/paddr.c:55 init_mem] physical memory area [0x80000000, 0x87ffffff] [src/monitor/monitor.c:55 load_img] No image is given. Use the default build-in image. [src/monitor/monitor.c:28 welcome] Trace: ON [src/monitor/monitor.c:31 welcome] If trace is enabled, a log file will be generated to record the trace. This may lead to a large log file. If it is not necessary, you can disable it in menuconfig [src/monitor/monitor.c:34 welcome] Build time: 17:56:50, Aug 13 2024 Welcome to riscv32-NEMU! For help, type"help" [src/monitor/monitor.c:38 welcome] Exercise: Please remove me in the source code and compile NEMU again. (nemu) si 0x80000000: 00 00 02 97 auipc t0, 0 (nemu) si 2 0x80000004: 00 02 88 23 sb zero, 16(t0) 0x80000008: 01 02 c5 03 lbu a0, 16(t0) (nemu) si 0x8000000c: 00 10 00 73 ebreak [src/cpu/cpu-exec.c:162 cpu_exec] nemu: HIT GOOD TRAP at pc = 0x8000000c [src/cpu/cpu-exec.c:119 statistic] host time spent = 10,428 us [src/cpu/cpu-exec.c:120 statistic] total guest instructions = 4 [src/cpu/cpu-exec.c:122 statistic] simulation frequency = 383 inst/s (nemu) si Program execution has ended. To restart the program, exit NEMU and run again. (nemu) q
/* Simulate how the CPU works. */ voidcpu_exec(uint64_t n) { g_print_step = (n < MAX_INST_TO_PRINT); switch (nemu_state.state) { case NEMU_END: case NEMU_ABORT: printf( "Program execution has ended. To restart the program, exit " "NEMU and run again.\n"); return; default: nemu_state.state = NEMU_RUNNING; }
switch (nemu_state.state) { case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;
case NEMU_END: case NEMU_ABORT: Log("nemu: %s at pc = " FMT_WORD, (nemu_state.state == NEMU_ABORT ? ANSI_FMT("ABORT", ANSI_FG_RED) : (nemu_state.halt_ret == 0 ? ANSI_FMT("HIT GOOD TRAP", ANSI_FG_GREEN) : ANSI_FMT("HIT BAD TRAP", ANSI_FG_RED))), nemu_state.halt_pc); // fall through case NEMU_QUIT: statistic(); } }
switch (nemu_state.state) { case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;
case NEMU_END: case NEMU_ABORT: Log("nemu: %s at pc = " FMT_WORD, (nemu_state.state == NEMU_ABORT ? ANSI_FMT("ABORT", ANSI_FG_RED) : (nemu_state.halt_ret == 0 ? ANSI_FMT("HIT GOOD TRAP", ANSI_FG_GREEN) : ANSI_FMT("HIT BAD TRAP", ANSI_FG_RED))), nemu_state.halt_pc); // fall through case NEMU_QUIT: statistic(); }
switch (nemu_state.state) { case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;
case NEMU_END: case NEMU_ABORT: Log("nemu: %s at pc = " FMT_WORD, (nemu_state.state == NEMU_ABORT ? ANSI_FMT("ABORT", ANSI_FG_RED) : (nemu_state.halt_ret == 0 ? ANSI_FMT("HIT GOOD TRAP", ANSI_FG_GREEN) : ANSI_FMT("HIT BAD TRAP", ANSI_FG_RED))), nemu_state.halt_pc); // fall through case NEMU_QUIT: statistic(); break; }