pa2.2: add memory tracer
This commit is contained in:
parent
c917083554
commit
0f7c6fd508
3 changed files with 66 additions and 3 deletions
18
nemu/Kconfig
18
nemu/Kconfig
|
@ -156,6 +156,24 @@ config ITRACE_BUFFER
|
||||||
int "Buffer size for intruction trace (unit: number of instructions)"
|
int "Buffer size for intruction trace (unit: number of instructions)"
|
||||||
default 10
|
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
|
config DIFFTEST
|
||||||
depends on TARGET_NATIVE_ELF
|
depends on TARGET_NATIVE_ELF
|
||||||
bool "Enable differential testing"
|
bool "Enable differential testing"
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
|
|
||||||
|
#define Trace(format, ...) \
|
||||||
|
_Log("[TRACE] " format "\n", ## __VA_ARGS__)
|
||||||
|
|
||||||
#define Log(format, ...) \
|
#define Log(format, ...) \
|
||||||
_Log(ANSI_FMT("[INFO] %s:%d %s() ", ANSI_FG_BLUE) format "\n", \
|
_Log(ANSI_FMT("[INFO] %s:%d %s() ", ANSI_FG_BLUE) format "\n", \
|
||||||
__FILE__, __LINE__, __func__, ## __VA_ARGS__)
|
__FILE__, __LINE__, __func__, ## __VA_ARGS__)
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "debug.h"
|
||||||
#include <memory/host.h>
|
#include <memory/host.h>
|
||||||
#include <memory/paddr.h>
|
#include <memory/paddr.h>
|
||||||
#include <device/mmio.h>
|
#include <device/mmio.h>
|
||||||
|
@ -23,6 +25,11 @@ static uint8_t *pmem = NULL;
|
||||||
#else // CONFIG_PMEM_GARRAY
|
#else // CONFIG_PMEM_GARRAY
|
||||||
static uint8_t pmem[CONFIG_MSIZE] PG_ALIGN = {};
|
static uint8_t pmem[CONFIG_MSIZE] PG_ALIGN = {};
|
||||||
#endif
|
#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; }
|
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; }
|
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);
|
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() {
|
void init_mem() {
|
||||||
#if defined(CONFIG_PMEM_MALLOC)
|
#if defined(CONFIG_PMEM_MALLOC)
|
||||||
pmem = malloc(CONFIG_MSIZE);
|
pmem = malloc(CONFIG_MSIZE);
|
||||||
assert(pmem);
|
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
|
#endif
|
||||||
IFDEF(CONFIG_MEM_RANDOM, memset(pmem, rand(), CONFIG_MSIZE));
|
IFDEF(CONFIG_MEM_RANDOM, memset(pmem, rand(), CONFIG_MSIZE));
|
||||||
Log("physical memory area [" FMT_PADDR ", " FMT_PADDR "]", PMEM_LEFT, PMEM_RIGHT);
|
Log("physical memory area [" FMT_PADDR ", " FMT_PADDR "]", PMEM_LEFT, PMEM_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
word_t paddr_read(paddr_t addr, int len) {
|
word_t paddr_read(paddr_t addr, int len) {
|
||||||
if (likely(in_pmem(addr))) return pmem_read(addr, len);
|
word_t result = 0;
|
||||||
IFDEF(CONFIG_DEVICE, return mmio_read(addr, len));
|
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);
|
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) {
|
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; }
|
if (likely(in_pmem(addr))) { pmem_write(addr, len, data); return; }
|
||||||
IFDEF(CONFIG_DEVICE, mmio_write(addr, len, data); return);
|
IFDEF(CONFIG_DEVICE, mmio_write(addr, len, data); return);
|
||||||
out_of_bound(addr);
|
out_of_bound(addr);
|
||||||
|
|
Loading…
Reference in a new issue