From 0f7c6fd508ac81de10b99b276d23371c72903008 Mon Sep 17 00:00:00 2001 From: xinyangli Date: Wed, 13 Mar 2024 18:14:17 +0800 Subject: [PATCH] pa2.2: add memory tracer --- nemu/Kconfig | 18 ++++++++++++++++ nemu/include/debug.h | 3 +++ nemu/src/memory/paddr.c | 48 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/nemu/Kconfig b/nemu/Kconfig index 20f7705..9243aba 100644 --- a/nemu/Kconfig +++ b/nemu/Kconfig @@ -156,6 +156,24 @@ config ITRACE_BUFFER int "Buffer size for intruction trace (unit: number of instructions)" default 10 +config MTRACE + depends on TRACE && TARGET_NATIVE_ELF && ENGINE_INTERPRETER + bool "Enable memory tracer" + + +config MTRACE_RANGE + depends on MTRACE + string "Memory trace active range" + default "0x0-0xfffffff" + help + Memory tracer will only print memory access in these ranges. + Use comma to seperate between ranges. + +config MTRACE_RANGE_MAX + depends on MTRACE + int "Max range count in MTRACE_RANGE" + default 10 + config DIFFTEST depends on TARGET_NATIVE_ELF bool "Enable differential testing" diff --git a/nemu/include/debug.h b/nemu/include/debug.h index df88556..057f8bf 100644 --- a/nemu/include/debug.h +++ b/nemu/include/debug.h @@ -20,6 +20,9 @@ #include #include +#define Trace(format, ...) \ + _Log("[TRACE] " format "\n", ## __VA_ARGS__) + #define Log(format, ...) \ _Log(ANSI_FMT("[INFO] %s:%d %s() ", ANSI_FG_BLUE) format "\n", \ __FILE__, __LINE__, __func__, ## __VA_ARGS__) diff --git a/nemu/src/memory/paddr.c b/nemu/src/memory/paddr.c index ee30e70..437debd 100644 --- a/nemu/src/memory/paddr.c +++ b/nemu/src/memory/paddr.c @@ -13,6 +13,8 @@ * See the Mulan PSL v2 for more details. ***************************************************************************************/ +#include "common.h" +#include "debug.h" #include #include #include @@ -23,6 +25,11 @@ static uint8_t *pmem = NULL; #else // CONFIG_PMEM_GARRAY static uint8_t pmem[CONFIG_MSIZE] PG_ALIGN = {}; #endif +#ifdef CONFIG_MTRACE +static word_t mtrace_start[CONFIG_MTRACE_RANGE_MAX] = {0}; +static word_t mtrace_end[CONFIG_MTRACE_RANGE_MAX] = {0}; +static int range_count = 0; +#endif uint8_t* guest_to_host(paddr_t paddr) { return pmem + paddr - CONFIG_MBASE; } paddr_t host_to_guest(uint8_t *haddr) { return haddr - pmem + CONFIG_MBASE; } @@ -41,23 +48,58 @@ static void out_of_bound(paddr_t addr) { addr, PMEM_LEFT, PMEM_RIGHT, cpu.pc); } +#ifdef CONFIG_MTRACE +static void mtrace_print(char type, word_t addr, int len, word_t data) { + for (int i = 0; i < range_count; i++) + if (addr <= mtrace_end[i] && addr >= mtrace_start[i] ) { + Trace("Mem %c " FMT_PADDR "%d D " FMT_PADDR, type, addr, len, data); + break; + } +} +#endif + void init_mem() { #if defined(CONFIG_PMEM_MALLOC) pmem = malloc(CONFIG_MSIZE); assert(pmem); +#endif +#ifdef CONFIG_MTRACE + char range[sizeof(CONFIG_MTRACE_RANGE)] = CONFIG_MTRACE_RANGE; + char *saveptr, *ptr; + ptr = strtok_r(range, ",", &saveptr); + for (range_count = 0; range_count < CONFIG_MTRACE_RANGE_MAX; ) { + word_t start, end; + Assert(sscanf(ptr, FMT_PADDR "-" FMT_PADDR, &start, &end) == 2, "Config option MTRACE_RANGE has wrong format"); + mtrace_start[range_count] = start; + mtrace_end[range_count] = end; + + range_count++; + ptr = strtok_r(NULL, ",", &saveptr); + if (!ptr) break; + } + Trace("MTRACE ranges: "); + for (int i = 0; i < range_count; i++) { + Trace("[0x%x, 0x%x]", mtrace_start[i], mtrace_end[i]); + } #endif IFDEF(CONFIG_MEM_RANDOM, memset(pmem, rand(), CONFIG_MSIZE)); Log("physical memory area [" FMT_PADDR ", " FMT_PADDR "]", PMEM_LEFT, PMEM_RIGHT); } word_t paddr_read(paddr_t addr, int len) { - if (likely(in_pmem(addr))) return pmem_read(addr, len); - IFDEF(CONFIG_DEVICE, return mmio_read(addr, len)); + word_t result = 0; + if (likely(in_pmem(addr))) { result = pmem_read(addr, len); goto mtrace;} + IFDEF(CONFIG_DEVICE, result = mmio_read(addr, len); goto mtrace) out_of_bound(addr); - return 0; + +mtrace: + IFDEF(CONFIG_MTRACE, mtrace_print('R', addr, len, result)); + + return result; } void paddr_write(paddr_t addr, int len, word_t data) { + IFDEF(CONFIG_MTRACE, mtrace_print('W', addr, len, data)); if (likely(in_pmem(addr))) { pmem_write(addr, len, data); return; } IFDEF(CONFIG_DEVICE, mmio_write(addr, len, data); return); out_of_bound(addr);