8 #include <sys/syscall.h>
9 #include <sys/utsname.h>
13 //#include "encoding.h"
15 //#define NO_FP_MACROS
16 #include "caveat_fp.h"
25 #include "riscv-opc.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
;
51 int proxy_ecall( struct core_t
* cpu
)
53 static long previous
= 0;
54 assert(insn(cpu
->pc
)->op_code
== Op_ecall
);
56 long guest
= ecall_fetch(cpu
, args
);
59 fprintf(stderr
, "system call %ld has no mapping to host system\n", guest
);
60 fprintf(stderr
, "Arguments(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
61 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
64 struct ecall_entry
const *entry
= ecall_entry(guest
);
65 long host
= entry
->number
;
66 char const *name
= entry
->name
;
69 fprintf(stderr
, "%10ld: %s[%ld:%ld](%lx, %lx, %lx, %lx, %lx, %lx)", cpu
->counter
.insn_executed
-previous
,
71 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
72 previous
= cpu
->counter
.insn_executed
;
78 fprintf(stderr
, "system call %s(#%ld) not supported on host system\n", name
, host
);
82 case 12: /* sys_brk */
83 args
[0] = emulate_brk(args
[0], ¤t
);
87 #if (defined(SYS_exit) || defined(SYS_exit_group))
95 #endif /* (defined(SYS_exit) || defined(SYS_exit_group)) */
97 #ifdef SYS_rt_sigaction
98 case SYS_rt_sigaction
:
99 fprintf(stderr
, "Trying to call rt_sigaction, always succeed without error.\n");
100 args
[0] = 0; // always succeed without error
102 #endif /* SYS_rt_sigaction */
109 #ifdef SYS_gettimeofday
110 case SYS_gettimeofday
:
111 #define PRETEND_MIPS 1000
115 tv
.tv_sec
= (cpu
->counter
.insn_executed
/ PRETEND_MIPS
) / 1000000;
116 tv
.tv_usec
= (cpu
->counter
.insn_executed
/ PRETEND_MIPS
) % 1000000;
117 tv
.tv_sec
+= cpu
->counter
.start_timeval
.tv_sec
;
118 tv
.tv_usec
+= cpu
->counter
.start_timeval
.tv_usec
;
119 tv
.tv_sec
+= tv
.tv_usec
/ 1000000; // microseconds overflow
120 tv
.tv_usec
%= 1000000;
121 // fprintf(stderr, "gettimeofday(sec=%ld, usec=%4ld)\n", tv.tv_sec, tv.tv_usec);
122 memcpy((void *)args
[0], &tv
, sizeof tv
);
129 #endif /* SYS_gettimeofday */
133 if (args
[0] <= 2) { // Don't close stdin, stdout, stderr
142 args
[0] = syscall(host
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
146 fprintf(stderr
, " return %lx\n", args
[0]);
149 ecall_store(args
, cpu
);
155 static void set_csr( struct core_t
* cpu
, int which
, long val
)
159 cpu
->state
.ustatus
= val
;
162 cpu
->state
.fcsr
.flags
= val
;
164 softfloat_exceptionFlags
= val
;
169 cpu
->state
.fcsr
.rmode
= val
;
172 cpu
->state
.fcsr_v
= val
;
175 fprintf(stderr
, "Unsupported set_csr(%d, val=%lx)\n", which
, val
);
179 softfloat_roundingMode
= cpu
->state
.fcsr
.rmode
;
181 fesetround(riscv_to_c_rm(cpu
->state
.fcsr
.rmode
));
185 static long get_csr( struct core_t
* cpu
, int which
)
189 return cpu
->state
.ustatus
;
192 cpu
->state
.fcsr
.flags
= softfloat_exceptionFlags
;
195 return cpu
->state
.fcsr
.flags
;
197 return cpu
->state
.fcsr
.rmode
;
199 return cpu
->state
.fcsr_v
;
201 fprintf(stderr
, "Unsupported get_csr(%d)\n", which
);
206 void proxy_csr( struct core_t
* cpu
, const struct insn_t
* p
, int which
)
208 enum Opcode_t op
= p
->op_code
;
209 int regop
= op
==Op_csrrw
|| op
==Op_csrrs
|| op
==Op_csrrc
;
211 long value
= regop
? p
->op_rs1
: p
->op_constant
>>12;
212 if (op
==Op_csrrw
|| op
==Op_csrrwi
) {
214 old_val
= get_csr(cpu
, which
);
215 set_csr(cpu
, which
, value
);
218 old_val
= get_csr(cpu
, which
);
219 if (regop
|| value
!= 0) {
220 if (op
==Op_csrrs
|| op
==Op_csrrsi
)
221 value
= old_val
| value
;
223 value
= old_val
& ~value
;
224 set_csr(cpu
, which
, value
);
227 cpu
->reg
[p
->op_rd
].l
= old_val
;