Skip to content

Commit

Permalink
Some changes
Browse files Browse the repository at this point in the history
- rewrite MMIO handler.
To adapt more MMIO in the future (e.g., VirtIO), the IIF(io) cannot be
used since it supports only binary. Thus, rewrite using switch case can
solve this.

- suppress warning.
In mmu-based read handler, warning 'non-void function does not return a
value in all control paths' could be reached, so add __UNREACHABLE() to
suppress it.

- keyboard hacking should be defined only when Linux kernel emulation.

- opt_trace only available when target RV32 file is ELF executable.

- map_file might be not available on non POSIX compatible machine, thus
  adding a fault back implementation when HAVE_MMAP is not set.
  • Loading branch information
ChinYikMing committed Nov 6, 2024
1 parent e1f9d0a commit 91c0287
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 35 deletions.
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
#include "utils.h"

/* enable program trace mode */
#if !RV32_HAS(SYSTEM) || (RV32_HAS(SYSTEM) && RV32_HAS(ELF_LOADER))
static bool opt_trace = false;
#endif

#if RV32_HAS(GDBSTUB)
/* enable program gdbstub mode */
Expand Down
34 changes: 24 additions & 10 deletions src/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <sys/mman.h>
#include <sys/stat.h>

#if RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
#include <termios.h>
#endif

#if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h>
#define FILENO(x) fileno(x)
Expand Down Expand Up @@ -177,6 +181,7 @@ void rv_remap_stdstream(riscv_t *rv, fd_stream_pair_t *fsp, uint32_t fsp_size)
(memory_##op(addr, (uint8_t *) &data), return memory_##op(addr)); \
}

#if !RV32_HAS(SYSTEM)
#define R 0
#define W 1

Expand All @@ -191,6 +196,7 @@ IO_HANDLER_IMPL(byte, write_b, W)

#undef R
#undef W
#endif

#if RV32_HAS(T2C)
static pthread_t t2c_thread;
Expand Down Expand Up @@ -225,31 +231,38 @@ static void map_file(char **ram_loc, const char *name)
struct stat st;
fstat(fd, &st);

#if HAVE_MMAP
/* remap to a memory region */
*ram_loc = mmap(*ram_loc, st.st_size, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE, fd, 0);
if (*ram_loc == MAP_FAILED) {
perror("mmap");
printf("name: %s\n", name);
close(fd);
exit(2);
}
#else
/* calloc and load data to a memory region */
*ram_loc = calloc(st.st_size, sizeof(uint8_t));
if (!*ram_loc) {
perror("calloc");
close(fd);
exit(2);
}
if (read(fd, *ram_loc, st.st_size) != st.st_size) {
perror("read");
close(fd);
exit(2);
}
#endif

// FIXME: used for unmap
// mapper[map_index].addr = *ram_loc;
// mapper[map_index].size = st.st_size;
// map_index++;

/* The kernel selects a nearby page boundary and attempts to create
/*
* The kernel selects a nearby page boundary and attempts to create
* the mapping.
*/
*ram_loc += st.st_size;

close(fd);
}
#endif

#include <termios.h>

static void reset_keyboard_input()
{
Expand All @@ -271,6 +284,7 @@ static void capture_keyboard_input()
term.c_lflag &= ~(ICANON | ECHO | ISIG); /* Disable echo as well */
tcsetattr(0, TCSANOW, &term);
}
#endif

riscv_t *rv_create(riscv_user_t rv_attr)
{
Expand Down
63 changes: 38 additions & 25 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,48 @@ void emu_update_uart_interrupts(riscv_t *rv)
plic_update_interrupts(attr->plic);
}

#define MMIO_PLIC 1
#define MMIO_UART 0
#define MMIO_R 1
#define MMIO_W 0

uint8_t ret_char;
enum SUPPORTED_MMIO {
MMIO_PLIC,
MMIO_UART,
};

/* clang-format off */
#define MMIO_OP(io, rw) \
IIF(io)( /* PLIC */ \
IIF(rw)( /* read */ \
read_val = plic_read(PRIV(rv)->plic, (addr & 0x3FFFFFF) >> 2); \
plic_update_interrupts(PRIV(rv)->plic); return read_val; \
, /* write */ \
plic_write(PRIV(rv)->plic, (addr & 0x3FFFFFF) >> 2, val); \
plic_update_interrupts(PRIV(rv)->plic); return; \
) \
, /* UART */ \
IIF(rw)( /* read */ \
/*return 0x60 | 0x1; */ \
ret_char = u8250_read(PRIV(rv)->uart, addr & 0xFFFFF);\
emu_update_uart_interrupts(rv);\
return ret_char;\
, /* write */ \
u8250_write(PRIV(rv)->uart, addr & 0xFFFFF, val);\
emu_update_uart_interrupts(rv);\
return;\
) \
)
#define MMIO_OP(io, rw) \
switch(io){ \
case MMIO_PLIC: \
IIF(rw)( /* read */ \
mmio_read_val = plic_read(PRIV(rv)->plic, (addr & 0x3FFFFFF) >> 2); \
plic_update_interrupts(PRIV(rv)->plic); \
return mmio_read_val; \
, /* write */ \
plic_write(PRIV(rv)->plic, (addr & 0x3FFFFFF) >> 2, val); \
plic_update_interrupts(PRIV(rv)->plic); \
return; \
) \
break; \
case MMIO_UART: \
IIF(rw)( /* read */ \
mmio_read_val = u8250_read(PRIV(rv)->uart, addr & 0xFFFFF); \
emu_update_uart_interrupts(rv); \
return mmio_read_val; \
, /* write */ \
u8250_write(PRIV(rv)->uart, addr & 0xFFFFF, val); \
emu_update_uart_interrupts(rv); \
return; \
) \
break; \
default: \
fprintf(stderr, "unknown MMIO type %d\n", io); \
break; \
}
/* clang-format on */

#define MMIO_READ() \
do { \
uint32_t read_val; \
uint32_t mmio_read_val; \
if ((addr >> 28) == 0xF) { /* MMIO at 0xF_______ */ \
/* 256 regions of 1MiB */ \
switch ((addr >> 20) & MASK(8)) { \
Expand Down Expand Up @@ -286,6 +295,8 @@ static uint32_t mmu_read_w(riscv_t *rv, const uint32_t addr)

MMIO_READ();
}

__UNREACHABLE;
}

static uint16_t mmu_read_s(riscv_t *rv, const uint32_t addr)
Expand Down Expand Up @@ -323,6 +334,8 @@ static uint8_t mmu_read_b(riscv_t *rv, const uint32_t addr)

MMIO_READ();
}

__UNREACHABLE;
}

static void mmu_write_w(riscv_t *rv, const uint32_t addr, const uint32_t val)
Expand Down

0 comments on commit 91c0287

Please sign in to comment.