8 #include <sys/syscall.h>
9 #include <sys/utsname.h>
13 //#include "encoding.h"
15 //#define NO_FP_MACROS
16 #include "caveat_fp.h"
24 #include "riscv-opc.h"
25 #include "ecall_nums.h"
30 static Addr_t
emulate_brk(Addr_t addr
, struct pinfo_t
* info
)
33 if (addr
< info
->brk_min
)
34 newbrk
= info
->brk_min
;
35 else if (addr
> info
->brk_max
)
36 newbrk
= info
->brk_max
;
39 info
->brk
= ROUNDUP(info
->brk_min
, RISCV_PGSIZE
);
41 uintptr_t newbrk_page
= ROUNDUP(newbrk
, RISCV_PGSIZE
);
42 if (info
->brk
> newbrk_page
)
43 munmap((void*)newbrk_page
, info
->brk
- newbrk_page
);
44 else if (info
->brk
< newbrk_page
)
45 assert(mmap((void*)info
->brk
, newbrk_page
- info
->brk
, -1, MAP_FIXED
|MAP_PRIVATE
|MAP_ANONYMOUS
, 0, 0) == (void*)info
->brk
);
46 info
->brk
= newbrk_page
;
52 int proxy_ecall( struct core_t
* cpu
)
54 static long previous
=0;
55 assert(insn(cpu
->pc
)->op_code
== Op_ecall
);
56 long rvnum
= cpu
->reg
[17].l
;
57 if (rvnum
< 0 || rvnum
>= rv_syscall_entries
) {
59 fprintf(stderr
, "RISC-V system call %ld has no mapping to host system\n", rvnum
);
60 fprintf(stderr
, "Arguments(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
61 cpu
->reg
[10].l
, cpu
->reg
[11].l
, cpu
->reg
[12].l
, cpu
->reg
[13].l
, cpu
->reg
[14].l
, cpu
->reg
[15].l
);
64 long sysnum
= rv_to_host
[rvnum
].sysnum
;
66 fprintf(stderr
, "%10ld: %s[%ld:%ld](%lx, %lx, %lx, %lx, %lx, %lx)", cpu
->counter
.insn_executed
-previous
,
67 rv_to_host
[rvnum
].name
, rvnum
, sysnum
,
68 cpu
->reg
[10].l
, cpu
->reg
[11].l
, cpu
->reg
[12].l
, cpu
->reg
[13].l
, cpu
->reg
[14].l
, cpu
->reg
[15].l
);
69 previous
= cpu
->counter
.insn_executed
;
75 fprintf(stderr
, "RISCV-V system call %s(#%ld) not supported on host system\n", rv_to_host
[rvnum
].name
, sysnum
);
79 case 12: /* sys_brk */
80 cpu
->reg
[10].l
= emulate_brk(cpu
->reg
[10].l
, ¤t
);
84 case 60: /* sys_exit */
85 case 231: /* sys_exit_group */\
88 case 13: /* sys_rt_sigaction */
89 fprintf(stderr
, "Trying to call rt_sigaction, always succeed without error.\n");
90 cpu
->reg
[10].l
= 0; // always succeed without error
93 case 56: /* sys_clone */
96 case 96: /* gettimeofday */
97 #define PRETEND_MIPS 1000
101 tv
.tv_sec
= (cpu
->counter
.insn_executed
/ PRETEND_MIPS
) / 1000000;
102 tv
.tv_usec
= (cpu
->counter
.insn_executed
/ PRETEND_MIPS
) % 1000000;
103 tv
.tv_sec
+= cpu
->counter
.start_timeval
.tv_sec
;
104 tv
.tv_usec
+= cpu
->counter
.start_timeval
.tv_usec
;
105 tv
.tv_sec
+= tv
.tv_usec
/ 1000000; // microseconds overflow
106 tv
.tv_usec
%= 1000000;
107 // fprintf(stderr, "gettimeofday(sec=%ld, usec=%4ld)\n", tv.tv_sec, tv.tv_usec);
108 memcpy(cpu
->reg
[10].p
, &tv
, sizeof tv
);
116 case 3: /* sys_close */
117 if (cpu
->reg
[10].l
<= 2) { // Don't close stdin, stdout, stderr
125 cpu
->reg
[10].l
= syscall(sysnum
, cpu
->reg
[10].l
, cpu
->reg
[11].l
, cpu
->reg
[12].l
, cpu
->reg
[13].l
, cpu
->reg
[14].l
, cpu
->reg
[15].l
);
129 fprintf(stderr
, " return %lx\n", cpu
->reg
[10].l
);
135 static void set_csr( struct core_t
* cpu
, int which
, long val
)
139 cpu
->state
.ustatus
= val
;
142 cpu
->state
.fcsr
.flags
= val
;
144 softfloat_exceptionFlags
= val
;
149 cpu
->state
.fcsr
.rmode
= val
;
152 cpu
->state
.fcsr_v
= val
;
155 fprintf(stderr
, "Unsupported set_csr(%d, val=%lx)\n", which
, val
);
159 softfloat_roundingMode
= cpu
->state
.fcsr
.rmode
;
161 fesetround(riscv_to_c_rm(cpu
->state
.fcsr
.rmode
));
165 static long get_csr( struct core_t
* cpu
, int which
)
169 return cpu
->state
.ustatus
;
172 cpu
->state
.fcsr
.flags
= softfloat_exceptionFlags
;
175 return cpu
->state
.fcsr
.flags
;
177 return cpu
->state
.fcsr
.rmode
;
179 return cpu
->state
.fcsr_v
;
181 fprintf(stderr
, "Unsupported get_csr(%d)\n", which
);
186 void proxy_csr( struct core_t
* cpu
, const struct insn_t
* p
, int which
)
188 enum Opcode_t op
= p
->op_code
;
189 int regop
= op
==Op_csrrw
|| op
==Op_csrrs
|| op
==Op_csrrc
;
191 long value
= regop
? p
->op_rs1
: p
->op_constant
>>12;
192 if (op
==Op_csrrw
|| op
==Op_csrrwi
) {
194 old_val
= get_csr(cpu
, which
);
195 set_csr(cpu
, which
, value
);
198 old_val
= get_csr(cpu
, which
);
199 if (regop
|| value
!= 0) {
200 if (op
==Op_csrrs
|| op
==Op_csrrsi
)
201 value
= old_val
| value
;
203 value
= old_val
& ~value
;
204 set_csr(cpu
, which
, value
);
207 cpu
->reg
[p
->op_rd
].l
= old_val
;