Skip to content

Instantly share code, notes, and snippets.

@X547
Last active May 16, 2021 14:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save X547/4d345a9ebe65ebc954baf13807cf61be to your computer and use it in GitHub Desktop.
Save X547/4d345a9ebe65ebc954baf13807cf61be to your computer and use it in GitHub Desktop.
From 2baa0abbbb8a97b0c1eb70b1aeafcf7fdba25ad4 Mon Sep 17 00:00:00 2001
From: X512 <danger_mail@list.ru>
Date: Wed, 12 May 2021 18:03:24 +0900
Subject: WIP: Haiku patches, share UART with RISC-V machine
---
Makefile | 9 +-
cutils.h | 2 +-
fs_disk.c | 15 +++
riscv_cpu.c | 7 +-
riscv_machine.c | 26 ++++-
sdl.c | 2 +-
temu.c | 18 ++--
uart.c | 228 +++++++++++++++++++++++++++++++++++++++
uart.h | 58 ++++++++++
x86_machine.c | 275 +-----------------------------------------------
10 files changed, 349 insertions(+), 291 deletions(-)
create mode 100644 uart.c
create mode 100644 uart.h
diff --git a/Makefile b/Makefile
index 390ae37..dc059cd 100644
--- a/Makefile
+++ b/Makefile
@@ -24,12 +24,12 @@
# if set, network filesystem is enabled. libcurl and libcrypto
# (openssl) must be installed.
-CONFIG_FS_NET=y
+#CONFIG_FS_NET=y
# SDL support (optional)
CONFIG_SDL=y
# if set, compile the 128 bit emulator. Note: the 128 bit target does
# not compile if gcc does not support the int128 type (32 bit hosts).
-CONFIG_INT128=y
+#CONFIG_INT128=y
# build x86 emulator
CONFIG_X86EMU=y
# win32 build (not usable yet)
@@ -62,7 +62,7 @@ endif
all: $(PROGS)
-EMU_OBJS:=virtio.o pci.o fs.o cutils.o iomem.o simplefb.o \
+EMU_OBJS:=virtio.o uart.o pci.o fs.o cutils.o iomem.o simplefb.o \
json.o machine.o temu.o
ifdef CONFIG_SLIRP
@@ -72,7 +72,8 @@ endif
ifndef CONFIG_WIN32
EMU_OBJS+=fs_disk.o
-EMU_LIBS=-lrt
+#EMU_LIBS=-lrt
+EMU_LIBS=-lnetwork
endif
ifdef CONFIG_FS_NET
CFLAGS+=-DCONFIG_FS_NET
diff --git a/cutils.h b/cutils.h
index 689542e..19283e2 100644
--- a/cutils.h
+++ b/cutils.h
@@ -84,7 +84,7 @@ static inline int min_int(int a, int b)
void *mallocz(size_t size);
-#if defined(_WIN32)
+#if defined(_WIN32) || defined(__HAIKU__)
static inline uint32_t bswap_32(uint32_t v)
{
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
diff --git a/fs_disk.c b/fs_disk.c
index bf96c89..11708d9 100644
--- a/fs_disk.c
+++ b/fs_disk.c
@@ -27,9 +27,13 @@
#include <inttypes.h>
#include <assert.h>
#include <stdarg.h>
+#if !defined(__HAIKU__)
#include <sys/statfs.h>
+#endif
#include <sys/stat.h>
+#if !defined(__HAIKU__)
#include <sys/sysmacros.h>
+#endif
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
@@ -144,6 +148,7 @@ static void stat_to_qid(FSQID *qid, const struct stat *st)
static void fs_statfs(FSDevice *fs1, FSStatFS *st)
{
+#if !defined(__HAIKU__)
FSDeviceDisk *fs = (FSDeviceDisk *)fs1;
struct statfs st1;
statfs(fs->root_path, &st1);
@@ -153,6 +158,7 @@ static void fs_statfs(FSDevice *fs1, FSStatFS *st)
st->f_bavail = st1.f_bavail;
st->f_files = st1.f_files;
st->f_ffree = st1.f_ffree;
+#endif
}
static char *compose_path(const char *path, const char *name)
@@ -312,6 +318,10 @@ static int fs_readdir(FSDevice *fs, FSFile *f, uint64_t offset,
if ((pos + len) > count)
break;
offset = telldir(f->u.dirp);
+#if defined(__HAIKU__)
+ d_type = 0;
+ type = P9_QTFILE;
+#else
d_type = de->d_type;
if (d_type == DT_UNKNOWN) {
char *path;
@@ -330,6 +340,7 @@ static int fs_readdir(FSDevice *fs, FSFile *f, uint64_t offset,
type = P9_QTSYMLINK;
else
type = P9_QTFILE;
+#endif
buf[pos++] = type;
put_le32(buf + pos, 0); /* version */
pos += 4;
@@ -507,6 +518,9 @@ static int fs_mknod(FSDevice *fs, FSQID *qid,
FSFile *f, const char *name, uint32_t mode, uint32_t major,
uint32_t minor, uint32_t gid)
{
+#if defined(__HAIKU__)
+ return -errno_to_p9(ENOTSUP);
+#else
char *path;
struct stat st;
@@ -522,6 +536,7 @@ static int fs_mknod(FSDevice *fs, FSQID *qid,
free(path);
stat_to_qid(qid, &st);
return 0;
+#endif
}
static int fs_readlink(FSDevice *fs, char *buf, int buf_size, FSFile *f)
diff --git a/riscv_cpu.c b/riscv_cpu.c
index ba4fa4c..cfb910a 100644
--- a/riscv_cpu.c
+++ b/riscv_cpu.c
@@ -40,7 +40,7 @@
#error CONFIG_RISCV_MAX_XLEN must be defined
#endif
-//#define DUMP_INVALID_MEM_ACCESS
+#define DUMP_INVALID_MEM_ACCESS
//#define DUMP_MMU_EXCEPTIONS
//#define DUMP_INTERRUPTS
//#define DUMP_INVALID_CSR
@@ -377,6 +377,8 @@ int target_read_slow(RISCVCPUState *s, mem_uint_t *pval,
#ifdef DUMP_INVALID_MEM_ACCESS
printf("target_read_slow: invalid physical address 0x");
print_target_ulong(paddr);
+ printf(", PC: ");
+ print_target_ulong(s->pc);
printf("\n");
#endif
return 0;
@@ -464,7 +466,10 @@ int target_write_slow(RISCVCPUState *s, target_ulong addr,
#ifdef DUMP_INVALID_MEM_ACCESS
printf("target_write_slow: invalid physical address 0x");
print_target_ulong(paddr);
+ printf(", PC: ");
+ print_target_ulong(s->pc);
printf("\n");
+ exit(1);
#endif
} else if (pr->is_ram) {
phys_mem_set_dirty_bit(pr, paddr - pr->addr);
diff --git a/riscv_machine.c b/riscv_machine.c
index a7149fd..0e27da4 100644
--- a/riscv_machine.c
+++ b/riscv_machine.c
@@ -35,6 +35,7 @@
#include "cutils.h"
#include "iomem.h"
#include "riscv_cpu.h"
+#include "uart.h"
#include "virtio.h"
#include "machine.h"
@@ -56,6 +57,7 @@ typedef struct RISCVMachine {
/* HTIF */
uint64_t htif_tohost, htif_fromhost;
+ SerialState *serial_state;
VIRTIODevice *keyboard_dev;
VIRTIODevice *mouse_dev;
@@ -74,6 +76,9 @@ typedef struct RISCVMachine {
#define PLIC_BASE_ADDR 0x40100000
#define PLIC_SIZE 0x00400000
#define FRAMEBUFFER_BASE_ADDR 0x41000000
+#define UART_BASE_ADDR 0x10000000
+#define UART_SIZE 0x100
+#define UART_IRQ 10
#define RTC_FREQ 10000000
#define RTC_FREQ_DIV 16 /* arbitrary, relative to CPU freq to have a
@@ -192,6 +197,14 @@ static void htif_poll(RISCVMachine *s)
}
#endif
+static void serial_write_cb(void *opaque, const uint8_t *buf, int buf_len)
+{
+ RISCVMachine *s = opaque;
+ if (s->common.console) {
+ s->common.console->write_data(s->common.console->opaque, buf, buf_len);
+ }
+}
+
static uint32_t clint_read(void *opaque, uint32_t offset, int size_log2)
{
RISCVMachine *m = opaque;
@@ -696,6 +709,14 @@ static int riscv_build_fdt(RISCVMachine *m, uint8_t *dst,
fdt_prop_u32(s, "phandle", plic_phandle);
fdt_end_node(s); /* plic */
+
+ fdt_begin_node_num(s, "serial", UART_BASE_ADDR);
+ fdt_prop_str(s, "compatible", "ns16550a");
+ fdt_prop_tab_u64_2(s, "reg", UART_BASE_ADDR, UART_SIZE);
+ tab[0] = plic_phandle;
+ tab[1] = UART_IRQ;
+ fdt_prop_tab_u32(s, "interrupts-extended", tab, 2);
+ fdt_end_node(s); /* serial */
for(i = 0; i < m->virtio_count; i++) {
fdt_begin_node_num(s, "virtio", VIRTIO_BASE_ADDR + i * VIRTIO_SIZE);
@@ -739,7 +760,7 @@ static int riscv_build_fdt(RISCVMachine *m, uint8_t *dst,
fdt_end_node(s); /* / */
size = fdt_output(s, dst);
-#if 0
+#if 1
{
FILE *f;
f = fopen("/tmp/riscvemu.dtb", "wb");
@@ -881,6 +902,9 @@ static VirtMachine *riscv_machine_init(const VirtMachineParams *p)
s, htif_read, htif_write, DEVIO_SIZE32);
s->common.console = p->console;
+ s->serial_state = serial_init(s->mem_map, UART_BASE_ADDR, &s->plic_irq[UART_IRQ],
+ serial_write_cb, s);
+
memset(vbus, 0, sizeof(*vbus));
vbus->mem_map = s->mem_map;
vbus->addr = VIRTIO_BASE_ADDR;
diff --git a/sdl.c b/sdl.c
index c2afeba..fba33aa 100644
--- a/sdl.c
+++ b/sdl.c
@@ -84,7 +84,7 @@ static void sdl_update(FBDevice *fb_dev, void *opaque,
SDL_UpdateRect(screen, r.x, r.y, r.w, r.h);
}
-#if defined(_WIN32)
+#if defined(_WIN32) || defined(__HAIKU__)
static int sdl_get_keycode(const SDL_KeyboardEvent *ev)
{
diff --git a/temu.c b/temu.c
index 7c07f3b..f5372d8 100644
--- a/temu.c
+++ b/temu.c
@@ -36,8 +36,10 @@
#include <termios.h>
#include <sys/ioctl.h>
#include <net/if.h>
+#ifndef __HAIKU__
#include <linux/if_tun.h>
#endif
+#endif
#include <sys/stat.h>
#include <signal.h>
@@ -346,7 +348,7 @@ static BlockDevice *block_device_init(const char *filename,
return bs;
}
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__HAIKU__)
typedef struct {
int fd;
@@ -763,7 +765,7 @@ int main(int argc, char **argv)
} else
#endif
{
-#ifdef _WIN32
+#if defined(_WIN32)
fprintf(stderr, "Filesystem access not supported yet\n");
exit(1);
#else
@@ -788,7 +790,7 @@ int main(int argc, char **argv)
exit(1);
} else
#endif
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__HAIKU__)
if (!strcmp(p->tab_eth[i].driver, "tap")) {
p->tab_eth[i].net = tun_open(p->tab_eth[i].ifname);
if (!p->tab_eth[i].net)
@@ -805,16 +807,14 @@ int main(int argc, char **argv)
#ifdef CONFIG_SDL
if (p->display_device) {
sdl_init(p->width, p->height);
- } else
+ }
#endif
- {
#ifdef _WIN32
- fprintf(stderr, "Console not supported yet\n");
- exit(1);
+ fprintf(stderr, "Console not supported yet\n");
+ exit(1);
#else
- p->console = console_init(allow_ctrlc);
+ p->console = console_init(allow_ctrlc);
#endif
- }
p->rtc_real_time = TRUE;
s = virt_machine_init(p);
diff --git a/uart.c b/uart.c
new file mode 100644
index 0000000..147160d
--- /dev/null
+++ b/uart.c
@@ -0,0 +1,228 @@
+#include "uart.h"
+#include <stdint.h>
+
+static void serial_write(void *opaque, uint32_t offset,
+ uint32_t val, int size_log2);
+static uint32_t serial_read(void *opaque, uint32_t offset, int size_log2);
+
+SerialState *serial_init(PhysMemoryMap *port_map, int addr,
+ IRQSignal *irq,
+ void (*write_func)(void *opaque, const uint8_t *buf, int buf_len), void *opaque)
+{
+ SerialState *s;
+ s = mallocz(sizeof(*s));
+
+ /* all 8 bit registers */
+ s->divider = 0;
+ s->rbr = 0; /* receive register */
+ s->ier = 0;
+ s->iir = UART_IIR_NO_INT; /* read only */
+ s->lcr = 0;
+ s->mcr = 0;
+ s->lsr = UART_LSR_TEMT | UART_LSR_THRE; /* read only */
+ s->msr = 0;
+ s->scr = 0;
+ s->fcr = 0;
+
+ s->irq = irq;
+ s->write_func = write_func;
+ s->opaque = opaque;
+
+ cpu_register_device(port_map, addr, 8, s, serial_read, serial_write,
+ DEVIO_SIZE8);
+ return s;
+}
+
+static void serial_update_irq(SerialState *s)
+{
+ if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
+ s->iir = UART_IIR_RDI;
+ } else if ((s->lsr & UART_LSR_THRE) && (s->ier & UART_IER_THRI)) {
+ s->iir = UART_IIR_THRI;
+ } else {
+ s->iir = UART_IIR_NO_INT;
+ }
+ if (s->iir != UART_IIR_NO_INT) {
+ set_irq(s->irq, 1);
+ } else {
+ set_irq(s->irq, 0);
+ }
+}
+
+#if 0
+/* send remainining chars in fifo */
+Serial.prototype.write_tx_fifo = function()
+{
+ if (s->tx_fifo != "") {
+ s->write_func(s->tx_fifo);
+ s->tx_fifo = "";
+
+ s->lsr |= UART_LSR_THRE;
+ s->lsr |= UART_LSR_TEMT;
+ s->update_irq();
+ }
+}
+#endif
+
+static void serial_write(void *opaque, uint32_t offset,
+ uint32_t val, int size_log2)
+{
+ SerialState *s = opaque;
+ int addr;
+
+ addr = offset & 7;
+ switch(addr) {
+ default:
+ case 0:
+ if (s->lcr & UART_LCR_DLAB) {
+ s->divider = (s->divider & 0xff00) | val;
+ } else {
+#if 0
+ if (s->fcr & UART_FCR_FE) {
+ s->tx_fifo += String.fromCharCode(val);
+ s->lsr &= ~UART_LSR_THRE;
+ serial_update_irq(s);
+ if (s->tx_fifo.length >= UART_FIFO_LENGTH) {
+ /* write to the terminal */
+ s->write_tx_fifo();
+ }
+ } else
+#endif
+ {
+ uint8_t ch;
+ s->lsr &= ~UART_LSR_THRE;
+ serial_update_irq(s);
+
+ /* write to the terminal */
+ ch = val;
+ s->write_func(s->opaque, &ch, 1);
+ s->lsr |= UART_LSR_THRE;
+ s->lsr |= UART_LSR_TEMT;
+ serial_update_irq(s);
+ }
+ }
+ break;
+ case 1:
+ if (s->lcr & UART_LCR_DLAB) {
+ s->divider = (s->divider & 0x00ff) | (val << 8);
+ } else {
+ s->ier = val;
+ serial_update_irq(s);
+ }
+ break;
+ case 2:
+#if 0
+ if ((s->fcr ^ val) & UART_FCR_FE) {
+ /* clear fifos */
+ val |= UART_FCR_XFR | UART_FCR_RFR;
+ }
+ if (val & UART_FCR_XFR)
+ s->tx_fifo = "";
+ if (val & UART_FCR_RFR)
+ s->rx_fifo = "";
+ s->fcr = val & UART_FCR_FE;
+#endif
+ break;
+ case 3:
+ s->lcr = val;
+ break;
+ case 4:
+ s->mcr = val;
+ break;
+ case 5:
+ break;
+ case 6:
+ s->msr = val;
+ break;
+ case 7:
+ s->scr = val;
+ break;
+ }
+}
+
+static uint32_t serial_read(void *opaque, uint32_t offset, int size_log2)
+{
+ SerialState *s = opaque;
+ int ret, addr;
+
+ addr = offset & 7;
+ switch(addr) {
+ default:
+ case 0:
+ if (s->lcr & UART_LCR_DLAB) {
+ ret = s->divider & 0xff;
+ } else {
+ ret = s->rbr;
+ s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
+ serial_update_irq(s);
+#if 0
+ /* try to receive next chars */
+ s->send_char_from_fifo();
+#endif
+ }
+ break;
+ case 1:
+ if (s->lcr & UART_LCR_DLAB) {
+ ret = (s->divider >> 8) & 0xff;
+ } else {
+ ret = s->ier;
+ }
+ break;
+ case 2:
+ ret = s->iir;
+ if (s->fcr & UART_FCR_FE)
+ ret |= UART_IIR_FE;
+ break;
+ case 3:
+ ret = s->lcr;
+ break;
+ case 4:
+ ret = s->mcr;
+ break;
+ case 5:
+ ret = s->lsr;
+ break;
+ case 6:
+ ret = s->msr;
+ break;
+ case 7:
+ ret = s->scr;
+ break;
+ }
+ return ret;
+}
+
+void serial_send_break(SerialState *s)
+{
+ s->rbr = 0;
+ s->lsr |= UART_LSR_BI | UART_LSR_DR;
+ serial_update_irq(s);
+}
+
+#if 0
+static void serial_send_char(SerialState *s, int ch)
+{
+ s->rbr = ch;
+ s->lsr |= UART_LSR_DR;
+ serial_update_irq(s);
+}
+
+Serial.prototype.send_char_from_fifo = function()
+{
+ var fifo;
+
+ fifo = s->rx_fifo;
+ if (fifo != "" && !(s->lsr & UART_LSR_DR)) {
+ s->send_char(fifo.charCodeAt(0));
+ s->rx_fifo = fifo.substr(1, fifo.length - 1);
+ }
+}
+
+/* queue the string in the UART receive fifo and send it ASAP */
+Serial.prototype.send_chars = function(str)
+{
+ s->rx_fifo += str;
+ s->send_char_from_fifo();
+}
+
+#endif
diff --git a/uart.h b/uart.h
new file mode 100644
index 0000000..12b92ec
--- /dev/null
+++ b/uart.h
@@ -0,0 +1,58 @@
+#ifndef _UART_H_
+#define _UART_H_
+
+#include <stddef.h>
+#include "cutils.h"
+#include "iomem.h"
+
+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
+
+#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
+#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
+#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
+#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
+
+#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
+#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
+
+#define UART_IIR_MSI 0x00 /* Modem status interrupt */
+#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
+#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
+#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
+#define UART_IIR_FE 0xC0 /* Fifo enabled */
+
+#define UART_LSR_TEMT 0x40 /* Transmitter empty */
+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+#define UART_LSR_BI 0x10 /* Break interrupt indicator */
+#define UART_LSR_FE 0x08 /* Frame error indicator */
+#define UART_LSR_PE 0x04 /* Parity error indicator */
+#define UART_LSR_OE 0x02 /* Overrun error indicator */
+#define UART_LSR_DR 0x01 /* Receiver data ready */
+
+#define UART_FCR_XFR 0x04 /* XMIT Fifo Reset */
+#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
+#define UART_FCR_FE 0x01 /* FIFO Enable */
+
+#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
+
+typedef struct {
+ uint8_t divider;
+ uint8_t rbr; /* receive register */
+ uint8_t ier;
+ uint8_t iir; /* read only */
+ uint8_t lcr;
+ uint8_t mcr;
+ uint8_t lsr; /* read only */
+ uint8_t msr;
+ uint8_t scr;
+ uint8_t fcr;
+ IRQSignal *irq;
+ void (*write_func)(void *opaque, const uint8_t *buf, int buf_len);
+ void *opaque;
+} SerialState;
+
+SerialState *serial_init(PhysMemoryMap *port_map, int addr,
+ IRQSignal *irq,
+ void (*write_func)(void *opaque, const uint8_t *buf, int buf_len), void *opaque);
+
+#endif // _UART_H_
diff --git a/x86_machine.c b/x86_machine.c
index db8f6bb..8497a45 100644
--- a/x86_machine.c
+++ b/x86_machine.c
@@ -36,6 +36,7 @@
#include "cutils.h"
#include "iomem.h"
#include "virtio.h"
+#include "uart.h"
#include "x86_cpu.h"
#include "machine.h"
#include "pci.h"
@@ -980,280 +981,6 @@ static int pit_update_irq(PITState *pit)
return delay / (PIT_FREQ / 1000);
}
-/***********************************************************/
-/* serial port emulation */
-
-#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
-
-#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
-#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
-#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
-#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
-
-#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
-#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
-
-#define UART_IIR_MSI 0x00 /* Modem status interrupt */
-#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
-#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
-#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
-#define UART_IIR_FE 0xC0 /* Fifo enabled */
-
-#define UART_LSR_TEMT 0x40 /* Transmitter empty */
-#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
-#define UART_LSR_BI 0x10 /* Break interrupt indicator */
-#define UART_LSR_FE 0x08 /* Frame error indicator */
-#define UART_LSR_PE 0x04 /* Parity error indicator */
-#define UART_LSR_OE 0x02 /* Overrun error indicator */
-#define UART_LSR_DR 0x01 /* Receiver data ready */
-
-#define UART_FCR_XFR 0x04 /* XMIT Fifo Reset */
-#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
-#define UART_FCR_FE 0x01 /* FIFO Enable */
-
-#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
-
-typedef struct {
- uint8_t divider;
- uint8_t rbr; /* receive register */
- uint8_t ier;
- uint8_t iir; /* read only */
- uint8_t lcr;
- uint8_t mcr;
- uint8_t lsr; /* read only */
- uint8_t msr;
- uint8_t scr;
- uint8_t fcr;
- IRQSignal *irq;
- void (*write_func)(void *opaque, const uint8_t *buf, int buf_len);
- void *opaque;
-} SerialState;
-
-static void serial_write(void *opaque, uint32_t offset,
- uint32_t val, int size_log2);
-static uint32_t serial_read(void *opaque, uint32_t offset, int size_log2);
-
-SerialState *serial_init(PhysMemoryMap *port_map, int addr,
- IRQSignal *irq,
- void (*write_func)(void *opaque, const uint8_t *buf, int buf_len), void *opaque)
-{
- SerialState *s;
- s = mallocz(sizeof(*s));
-
- /* all 8 bit registers */
- s->divider = 0;
- s->rbr = 0; /* receive register */
- s->ier = 0;
- s->iir = UART_IIR_NO_INT; /* read only */
- s->lcr = 0;
- s->mcr = 0;
- s->lsr = UART_LSR_TEMT | UART_LSR_THRE; /* read only */
- s->msr = 0;
- s->scr = 0;
- s->fcr = 0;
-
- s->irq = irq;
- s->write_func = write_func;
- s->opaque = opaque;
-
- cpu_register_device(port_map, addr, 8, s, serial_read, serial_write,
- DEVIO_SIZE8);
- return s;
-}
-
-static void serial_update_irq(SerialState *s)
-{
- if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
- s->iir = UART_IIR_RDI;
- } else if ((s->lsr & UART_LSR_THRE) && (s->ier & UART_IER_THRI)) {
- s->iir = UART_IIR_THRI;
- } else {
- s->iir = UART_IIR_NO_INT;
- }
- if (s->iir != UART_IIR_NO_INT) {
- set_irq(s->irq, 1);
- } else {
- set_irq(s->irq, 0);
- }
-}
-
-#if 0
-/* send remainining chars in fifo */
-Serial.prototype.write_tx_fifo = function()
-{
- if (s->tx_fifo != "") {
- s->write_func(s->tx_fifo);
- s->tx_fifo = "";
-
- s->lsr |= UART_LSR_THRE;
- s->lsr |= UART_LSR_TEMT;
- s->update_irq();
- }
-}
-#endif
-
-static void serial_write(void *opaque, uint32_t offset,
- uint32_t val, int size_log2)
-{
- SerialState *s = opaque;
- int addr;
-
- addr = offset & 7;
- switch(addr) {
- default:
- case 0:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0xff00) | val;
- } else {
-#if 0
- if (s->fcr & UART_FCR_FE) {
- s->tx_fifo += String.fromCharCode(val);
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
- if (s->tx_fifo.length >= UART_FIFO_LENGTH) {
- /* write to the terminal */
- s->write_tx_fifo();
- }
- } else
-#endif
- {
- uint8_t ch;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
-
- /* write to the terminal */
- ch = val;
- s->write_func(s->opaque, &ch, 1);
- s->lsr |= UART_LSR_THRE;
- s->lsr |= UART_LSR_TEMT;
- serial_update_irq(s);
- }
- }
- break;
- case 1:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0x00ff) | (val << 8);
- } else {
- s->ier = val;
- serial_update_irq(s);
- }
- break;
- case 2:
-#if 0
- if ((s->fcr ^ val) & UART_FCR_FE) {
- /* clear fifos */
- val |= UART_FCR_XFR | UART_FCR_RFR;
- }
- if (val & UART_FCR_XFR)
- s->tx_fifo = "";
- if (val & UART_FCR_RFR)
- s->rx_fifo = "";
- s->fcr = val & UART_FCR_FE;
-#endif
- break;
- case 3:
- s->lcr = val;
- break;
- case 4:
- s->mcr = val;
- break;
- case 5:
- break;
- case 6:
- s->msr = val;
- break;
- case 7:
- s->scr = val;
- break;
- }
-}
-
-static uint32_t serial_read(void *opaque, uint32_t offset, int size_log2)
-{
- SerialState *s = opaque;
- int ret, addr;
-
- addr = offset & 7;
- switch(addr) {
- default:
- case 0:
- if (s->lcr & UART_LCR_DLAB) {
- ret = s->divider & 0xff;
- } else {
- ret = s->rbr;
- s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
- serial_update_irq(s);
-#if 0
- /* try to receive next chars */
- s->send_char_from_fifo();
-#endif
- }
- break;
- case 1:
- if (s->lcr & UART_LCR_DLAB) {
- ret = (s->divider >> 8) & 0xff;
- } else {
- ret = s->ier;
- }
- break;
- case 2:
- ret = s->iir;
- if (s->fcr & UART_FCR_FE)
- ret |= UART_IIR_FE;
- break;
- case 3:
- ret = s->lcr;
- break;
- case 4:
- ret = s->mcr;
- break;
- case 5:
- ret = s->lsr;
- break;
- case 6:
- ret = s->msr;
- break;
- case 7:
- ret = s->scr;
- break;
- }
- return ret;
-}
-
-void serial_send_break(SerialState *s)
-{
- s->rbr = 0;
- s->lsr |= UART_LSR_BI | UART_LSR_DR;
- serial_update_irq(s);
-}
-
-#if 0
-static void serial_send_char(SerialState *s, int ch)
-{
- s->rbr = ch;
- s->lsr |= UART_LSR_DR;
- serial_update_irq(s);
-}
-
-Serial.prototype.send_char_from_fifo = function()
-{
- var fifo;
-
- fifo = s->rx_fifo;
- if (fifo != "" && !(s->lsr & UART_LSR_DR)) {
- s->send_char(fifo.charCodeAt(0));
- s->rx_fifo = fifo.substr(1, fifo.length - 1);
- }
-}
-
-/* queue the string in the UART receive fifo and send it ASAP */
-Serial.prototype.send_chars = function(str)
-{
- s->rx_fifo += str;
- s->send_char_from_fifo();
-}
-
-#endif
#ifdef DEBUG_BIOS
static void bios_debug_write(void *opaque, uint32_t offset,
--
2.30.2
From da1e4672ff3f6fa53ee0c7ea72e6e116b8903999 Mon Sep 17 00:00:00 2001
From: X512 <danger_mail@list.ru>
Date: Sun, 16 May 2021 22:58:16 +0900
Subject: implement `utime` register
---
riscv_cpu.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/riscv_cpu.c b/riscv_cpu.c
index cfb910a..b765be6 100644
--- a/riscv_cpu.c
+++ b/riscv_cpu.c
@@ -29,6 +29,8 @@
#include <assert.h>
#include <fcntl.h>
+#include <OS.h> // system_time()
+
#include "cutils.h"
#include "iomem.h"
#include "riscv_cpu.h"
@@ -748,6 +750,9 @@ static int csr_read(RISCVCPUState *s, target_ulong *pval, uint32_t csr,
}
val = (int64_t)s->insn_counter;
break;
+ case 0xc01: /* utime */
+ val = system_time();
+ break;
case 0xc80: /* mcycleh */
case 0xc82: /* minstreth */
if (s->cur_xlen != 32)
--
2.30.2
From beafad98395ef74fc64c9b3461ee46879d9ae647 Mon Sep 17 00:00:00 2001
From: X512 <danger_mail@list.ru>
Date: Sun, 16 May 2021 22:58:38 +0900
Subject: virtio: increase queue size, style changes for Pe editor
---
virtio.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/virtio.c b/virtio.c
index 8d07f44..56746db 100644
--- a/virtio.c
+++ b/virtio.c
@@ -93,7 +93,7 @@
#define MAX_QUEUE 8
#define MAX_CONFIG_SPACE_SIZE 256
-#define MAX_QUEUE_NUM 16
+#define MAX_QUEUE_NUM 32
typedef struct {
uint32_t ready; /* 0 or 1 */
@@ -977,8 +977,8 @@ static void virtio_config_change_notify(VIRTIODevice *s)
set_irq(s->irq, 1);
}
-/*********************************************************************/
-/* block device */
+
+//#pragma mark block device
typedef struct {
uint32_t type;
@@ -1131,8 +1131,8 @@ VIRTIODevice *virtio_block_init(VIRTIOBusDef *bus, BlockDevice *bs)
return (VIRTIODevice *)s;
}
-/*********************************************************************/
-/* network device */
+
+//#pragma mark network device
typedef struct VIRTIONetDevice {
VIRTIODevice common;
@@ -1257,8 +1257,8 @@ VIRTIODevice *virtio_net_init(VIRTIOBusDef *bus, EthernetDevice *es)
return (VIRTIODevice *)s;
}
-/*********************************************************************/
-/* console device */
+
+//#pragma mark console device
typedef struct VIRTIOConsoleDevice {
VIRTIODevice common;
@@ -1359,8 +1359,8 @@ VIRTIODevice *virtio_console_init(VIRTIOBusDef *bus, CharacterDevice *cs)
return (VIRTIODevice *)s;
}
-/*********************************************************************/
-/* input device */
+
+//#pragma mark input device
enum {
VIRTIO_INPUT_CFG_UNSET = 0x00,
@@ -1643,8 +1643,8 @@ VIRTIODevice *virtio_input_init(VIRTIOBusDef *bus, VirtioInputTypeEnum type)
return (VIRTIODevice *)s;
}
-/*********************************************************************/
-/* 9p filesystem device */
+
+//#pragma mark 9p filesystem device
typedef struct {
struct list_head link;
--
2.30.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment