diff --git a/include/memory/memory.h b/include/memory/memory.h index 9f852d69363b1d8acedb3a998308478aff52b300..64d54e33907f6b154fca48d12f46cf4e99ddecd3 100644 --- a/include/memory/memory.h +++ b/include/memory/memory.h @@ -3,6 +3,7 @@ #include "common.h" +#define PMEM_SIZE (128 * 1024 * 1024) extern uint8_t pmem[]; /* convert the guest physical address in the guest program to host virtual address in NEMU */ diff --git a/src/cpu/exec/exec.c b/src/cpu/exec/exec.c index 740a928907385b5028bdf0f7501a5eeaeae0b3a7..496bcd212fbd4c4a48b34e47a9b697868ff03186 100644 --- a/src/cpu/exec/exec.c +++ b/src/cpu/exec/exec.c @@ -178,7 +178,7 @@ make_group(gp7, /* 0x90 */ EMPTY, EMPTY, EMPTY, IDEXW(setcc_E, setcc, 1), /* 0x94 */ IDEXW(setcc_E, setcc, 1), IDEXW(setcc_E, setcc, 1), IDEXW(setcc_E, setcc, 1), EMPTY, /* 0x98 */ EMPTY, EMPTY, EMPTY, EMPTY, - /* 0x9c */ EMPTY, EMPTY, EMPTY, IDEXW(setcc_E, setcc, 1), + /* 0x9c */ EMPTY, EMPTY, IDEXW(setcc_E, setcc, 1), IDEXW(setcc_E, setcc, 1), /* 0xa0 */ EMPTY, EMPTY, EMPTY, EMPTY, /* 0xa4 */ IDEX(Ib_G2E, shld), IDEX(cl_G2E, shld), EMPTY, EMPTY, /* 0xa8 */ EMPTY, EMPTY, EMPTY, EMPTY, diff --git a/src/cpu/reg.c b/src/cpu/reg.c index 2f85402abe114b5a38f767e391dbbbd76552ade3..111fcba0f489dca3b779f0fd7c91a267f5cf7182 100644 --- a/src/cpu/reg.c +++ b/src/cpu/reg.c @@ -41,3 +41,11 @@ void reg_test() { assert(eip_sample == cpu.eip); } + +void display_reg() { + int i; + for (i = 0; i < 8; i ++) { + printf("%s: 0x%08x\n", regsl[i], cpu.gpr[i]._32); + } + printf("eip: 0x%08x\n", cpu.eip); +} diff --git a/src/memory/memory.c b/src/memory/memory.c index 55287166210039d19edc8b514b33bb006e5d5e9a..8f1c839402e873e32d36383287cc708bdf4103ae 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -2,8 +2,6 @@ #include "device/mmio.h" #include "memory/mmu.h" -#define PMEM_SIZE (128 * 1024 * 1024) - #define pmem_rw(addr, type) *(type *)({\ Assert(addr < PMEM_SIZE, "physical address(0x%08x) is out of bound", addr); \ guest_to_host(addr); \ diff --git a/src/monitor/debug/ui.c b/src/monitor/debug/ui.c index f0415ffaa9c4738cb23c063a7d970b55be122e9d..1b0563a2775e6820ecccadcffbc7b3a921ebf0f9 100644 --- a/src/monitor/debug/ui.c +++ b/src/monitor/debug/ui.c @@ -32,12 +32,40 @@ static int cmd_c(char *args) { return 0; } +static int cmd_si(char *args) { + /* extract the first argument */ + char *arg = strtok(NULL, " "); + + if (arg == NULL) { + /* no argument given */ + cpu_exec(1); + } + else { + int n = strtol(arg, NULL, 10); + printf("si %d\n", n); + cpu_exec(n); + } + return 0; +} + static int cmd_q(char *args) { return -1; } static int cmd_help(char *args); +void difftest_detach(); +void difftest_attach(); +static int cmd_detach(char *args) { + difftest_detach(); + return 0; +} + +static int cmd_attach(char *args) { + difftest_attach(); + return 0; +} + static struct { char *name; char *description; @@ -45,6 +73,9 @@ static struct { } cmd_table [] = { { "help", "Display informations about all supported commands", cmd_help }, { "c", "Continue the execution of the program", cmd_c }, + { "si", "step", cmd_si }, + { "detach", "detach diff test", cmd_detach }, + { "attach", "attach diff test", cmd_attach }, { "q", "Exit NEMU", cmd_q }, /* TODO: Add more commands */ diff --git a/src/monitor/diff-test/diff-test.c b/src/monitor/diff-test/diff-test.c index 3c51b79bed82414e8ed0f615e0d387dda8431352..64db51e5e32ce18cc74db193ea4e1eda6adb9485 100644 --- a/src/monitor/diff-test/diff-test.c +++ b/src/monitor/diff-test/diff-test.c @@ -12,6 +12,7 @@ static void (*ref_difftest_exec)(uint64_t n); static bool is_skip_ref; static bool is_skip_dut; static uint32_t eflags_skip_mask; +static bool is_detach; void difftest_skip_ref() { is_skip_ref = true; } void difftest_skip_dut() { is_skip_dut = true; } @@ -78,6 +79,8 @@ void init_difftest(char *ref_so_file, long img_size) { void difftest_step(uint32_t eip) { CPU_state ref_r; + if (is_detach) return; + if (is_skip_dut) { is_skip_dut = false; return; @@ -121,3 +124,57 @@ void difftest_step(uint32_t eip) { eflags_skip_mask = 0; } } + +void difftest_detach() { + is_detach = true; +} + +void difftest_attach() { +#ifndef DIFF_TEST + return; +#endif + + is_detach = false; + is_skip_ref = false; + is_skip_dut = false; + + // first copy the image + ref_difftest_memcpy_from_dut(ENTRY_START, guest_to_host(ENTRY_START), PMEM_SIZE - ENTRY_START); + + // then set some special registers + uint8_t code[] = { + // we put this code at 0x7e00 + 0xb8, 0x00, 0x00, 0x00, 0x00, // mov $0x0, %eax + 0x0f, 0x22, 0xd8, // mov %eax, %cr3 + 0xb8, 0x00, 0x00, 0x00, 0x00, // mov $0x0, %eax + 0x0f, 0x22, 0xc0, // mov %eax, %cr0 + 0x0f, 0x01, 0x1d, 0x40, 0x7e, 0x00, 0x00, // lidtl (0x7e40) + }; + uint8_t idtdesc[6]; + + *(uint32_t *)(code + 1) = cpu.cr3.val; + *(uint32_t *)(code + 9) = cpu.cr0.val; + + idtdesc[0] = cpu.idtr.limit & 0xff; + idtdesc[1] = cpu.idtr.limit >> 8; + *(uint32_t *)(idtdesc + 2) = cpu.idtr.base; + + assert(sizeof(code) < 0x40); + ref_difftest_memcpy_from_dut(0x7e00, code, sizeof(code)); + ref_difftest_memcpy_from_dut(0x7e40, idtdesc, sizeof(idtdesc)); + + CPU_state r = cpu; + r.eip = 0x7e00; + ref_difftest_setregs(&r); + ref_difftest_exec(5); + + //rtl_computer_eflags(&cpu.eflags); + cpu.eflags = + (cpu.OF << EFLAGS_BIT_OF) | + (cpu.CF << EFLAGS_BIT_CF) | + (cpu.IF << EFLAGS_BIT_IF) | + (cpu.SF << EFLAGS_BIT_SF) | + (cpu.CF << EFLAGS_BIT_CF); + + ref_difftest_setregs(&cpu); +}