-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathdiff-test.c
99 lines (84 loc) · 2.45 KB
/
diff-test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/***************************************************************************************
* Copyright (c) 2014-2021 Zihao Yu, Nanjing University
*
* NEMU is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/
#include "common.h"
#include <sys/prctl.h>
#include <signal.h>
#include <difftest.h>
#include _ISA_H_
bool gdb_connect_qemu(int);
bool gdb_memcpy_to_qemu(uint32_t, void *, int);
bool gdb_getregs(union isa_gdb_regs *);
bool gdb_setregs(union isa_gdb_regs *);
bool gdb_si();
void gdb_exit();
void init_isa();
void difftest_memcpy(paddr_t addr, void *buf, size_t n, bool direction) {
assert(direction == DIFFTEST_TO_REF);
if (direction == DIFFTEST_TO_REF) {
bool ok = gdb_memcpy_to_qemu(addr, buf, n);
assert(ok == 1);
}
}
void difftest_regcpy(void *dut, bool direction) {
union isa_gdb_regs qemu_r;
gdb_getregs(&qemu_r);
if (direction == DIFFTEST_TO_REF) {
memcpy(&qemu_r, dut, DIFFTEST_REG_SIZE);
gdb_setregs(&qemu_r);
} else {
memcpy(dut, &qemu_r, DIFFTEST_REG_SIZE);
}
}
void difftest_exec(uint64_t n) {
while (n --) gdb_si();
}
void difftest_init(int port) {
char buf[32];
sprintf(buf, "tcp::%d", port);
int ppid_before_fork = getpid();
int pid = fork();
if (pid == -1) {
perror("fork");
assert(0);
}
else if (pid == 0) {
// child
// install a parent death signal in the chlid
int r = prctl(PR_SET_PDEATHSIG, SIGTERM);
if (r == -1) {
perror("prctl error");
assert(0);
}
if (getppid() != ppid_before_fork) {
printf("parent has died!\n");
assert(0);
}
close(STDIN_FILENO);
execlp(ISA_QEMU_BIN, ISA_QEMU_BIN, ISA_QEMU_ARGS "-S", "-gdb", buf, "-nographic", NULL);
perror("exec");
assert(0);
}
else {
// father
gdb_connect_qemu(port);
printf("Connect to QEMU with %s tcpsuccessfully\n", buf);
atexit(gdb_exit);
init_isa();
}
}
void difftest_raise_intr(uint64_t NO) {
printf("raise_intr is not supported in QEMU-socket\n");
assert(0);
}