Skip to content

Commit ac13c78

Browse files
authored
Merge pull request #357 from ChinYikMing/encapsulate-io-handlers
Bind I/O handlers during emulator initialization
2 parents dc13bec + 8355777 commit ac13c78

File tree

3 files changed

+52
-52
lines changed

3 files changed

+52
-52
lines changed

src/main.c

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,6 @@ static bool opt_misaligned = false;
4949
static bool opt_prof_data = false;
5050
static char *prof_out_file;
5151

52-
#define MEMIO(op) on_mem_##op
53-
#define IO_HANDLER_IMPL(type, op, RW) \
54-
static IIF(RW)( \
55-
/* W */ void MEMIO(op)(riscv_word_t addr, riscv_##type##_t data), \
56-
/* R */ riscv_##type##_t MEMIO(op)(riscv_word_t addr)) \
57-
{ \
58-
IIF(RW) \
59-
(memory_##op(addr, (uint8_t *) &data), return memory_##op(addr)); \
60-
}
61-
62-
#define R 0
63-
#define W 1
64-
65-
IO_HANDLER_IMPL(word, ifetch, R)
66-
IO_HANDLER_IMPL(word, read_w, R)
67-
IO_HANDLER_IMPL(half, read_s, R)
68-
IO_HANDLER_IMPL(byte, read_b, R)
69-
70-
IO_HANDLER_IMPL(word, write_w, W)
71-
IO_HANDLER_IMPL(half, write_s, W)
72-
IO_HANDLER_IMPL(byte, write_b, W)
73-
74-
#undef R
75-
#undef W
76-
7752
static void print_usage(const char *filename)
7853
{
7954
fprintf(stderr,
@@ -227,28 +202,8 @@ int main(int argc, char **args)
227202
assert(attr.data.user);
228203
attr.data.user->elf_program = opt_prog_name;
229204

230-
/* install the I/O handlers for the RISC-V runtime */
231-
const riscv_io_t io = {
232-
/* memory read interface */
233-
.mem_ifetch = MEMIO(ifetch),
234-
.mem_read_w = MEMIO(read_w),
235-
.mem_read_s = MEMIO(read_s),
236-
.mem_read_b = MEMIO(read_b),
237-
238-
/* memory write interface */
239-
.mem_write_w = MEMIO(write_w),
240-
.mem_write_s = MEMIO(write_s),
241-
.mem_write_b = MEMIO(write_b),
242-
243-
/* system */
244-
.on_ecall = ecall_handler,
245-
.on_ebreak = ebreak_handler,
246-
.on_memcpy = memcpy_handler,
247-
.on_memset = memset_handler,
248-
};
249-
250205
/* create the RISC-V runtime */
251-
riscv_t *rv = rv_create(&io, &attr);
206+
riscv_t *rv = rv_create(&attr);
252207
if (!rv) {
253208
fprintf(stderr, "Unable to create riscv emulator\n");
254209
return 1;

src/riscv.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,38 @@ void rv_remap_stdstream(riscv_t *rv, fd_stream_pair_t *fsp, uint32_t fsp_size)
155155
}
156156
}
157157

158-
riscv_t *rv_create(const riscv_io_t *io, riscv_user_t rv_attr)
158+
#define MEMIO(op) on_mem_##op
159+
#define IO_HANDLER_IMPL(type, op, RW) \
160+
static IIF(RW)( \
161+
/* W */ void MEMIO(op)(riscv_word_t addr, riscv_##type##_t data), \
162+
/* R */ riscv_##type##_t MEMIO(op)(riscv_word_t addr)) \
163+
{ \
164+
IIF(RW) \
165+
(memory_##op(addr, (uint8_t *) &data), return memory_##op(addr)); \
166+
}
167+
168+
#define R 0
169+
#define W 1
170+
171+
IO_HANDLER_IMPL(word, ifetch, R)
172+
IO_HANDLER_IMPL(word, read_w, R)
173+
IO_HANDLER_IMPL(half, read_s, R)
174+
IO_HANDLER_IMPL(byte, read_b, R)
175+
176+
IO_HANDLER_IMPL(word, write_w, W)
177+
IO_HANDLER_IMPL(half, write_s, W)
178+
IO_HANDLER_IMPL(byte, write_b, W)
179+
180+
#undef R
181+
#undef W
182+
183+
riscv_t *rv_create(riscv_user_t rv_attr)
159184
{
160-
assert(io && rv_attr);
185+
assert(rv_attr);
161186

162187
riscv_t *rv = calloc(1, sizeof(riscv_t));
163188
assert(rv);
164189

165-
/* copy over the IO interface */
166-
memcpy(&rv->io, io, sizeof(riscv_io_t));
167-
168190
/* copy over the attr */
169191
rv->data = rv_attr;
170192

@@ -190,6 +212,27 @@ riscv_t *rv_create(const riscv_io_t *io, riscv_user_t rv_attr)
190212
assert(rv_set_pc(rv, hdr->e_entry));
191213

192214
elf_delete(elf);
215+
216+
/* install the I/O handlers */
217+
const riscv_io_t io = {
218+
/* memory read interface */
219+
.mem_ifetch = MEMIO(ifetch),
220+
.mem_read_w = MEMIO(read_w),
221+
.mem_read_s = MEMIO(read_s),
222+
.mem_read_b = MEMIO(read_b),
223+
224+
/* memory write interface */
225+
.mem_write_w = MEMIO(write_w),
226+
.mem_write_s = MEMIO(write_s),
227+
.mem_write_b = MEMIO(write_b),
228+
229+
/* system services or essential routines */
230+
.on_ecall = ecall_handler,
231+
.on_ebreak = ebreak_handler,
232+
.on_memcpy = memcpy_handler,
233+
.on_memset = memset_handler,
234+
};
235+
memcpy(&rv->io, &io, sizeof(riscv_io_t));
193236
} else {
194237
/* TODO: system emulator */
195238
}

src/riscv.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ typedef struct {
139139
riscv_mem_write_s mem_write_s;
140140
riscv_mem_write_b mem_write_b;
141141

142+
/* TODO: add peripheral I/O interfaces */
143+
142144
/* system */
143145
riscv_on_ecall on_ecall;
144146
riscv_on_ebreak on_ebreak;
@@ -150,7 +152,7 @@ typedef struct {
150152
void rv_run(riscv_t *rv);
151153

152154
/* create a RISC-V emulator */
153-
riscv_t *rv_create(const riscv_io_t *io, riscv_user_t attr);
155+
riscv_t *rv_create(riscv_user_t attr);
154156

155157
/* delete a RISC-V emulator */
156158
void rv_delete(riscv_t *rv);

0 commit comments

Comments
 (0)