TinyEmu: add recipe

This commit is contained in:
Gerasim Troeglazov
2021-05-13 11:49:20 +10:00
parent 1f0e168e1e
commit fa0c5a8637
3 changed files with 1027 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
resource app_flags B_MULTIPLE_LAUNCH;
resource app_version {
major = @MAJOR@,
middle = @MIDDLE@,
minor = @MINOR@,
variety = B_APPV_FINAL,
internal = 0,
short_info = "TinyEmu",
long_info = "@LONG_INFO@"
};
resource app_signature "@APP_SIGNATURE@";
resource vector_icon {
$"6E63696609020006023A04153D236BBDB07B3A5EB14A336448019E00FFFFFFFF"
$"FFAA00020006023827C73BDA22BC0BE2384A444B907C47205D00FFFFFFFFFFD4"
$"82020106023ED062354433B559313EE278459C72465CA10092B8EBFF15569E02"
$"0106023E03F63A5E99BC5E8B4003EA44F89F46C73B00FFFFFFFF15569E020006"
$"023CE58E3213B9B0B70F3BC95949F6DE48785200FFAA00FFAC73040200060237"
$"AC85382719B8ED62387F754A8B8D489E2500FFCD6EFFC9860503013D5B050104"
$"016B0B06069A0E31284C333F3A5132423A3B3A443AB95B0A0431283824522F4C"
$"330A044C3F4C33532F533B0A043A514C3F513C414C0A033E564C4A4C5D0A044C"
$"4A534553554C5D0606BA0E282A2E2639313728BD66BBC13839333C3433BBC8BC"
$"092F2A0605B60227492A3539362BBB2BBFBE2A3A37530A042A3B30393D503753"
$"0A054C5E595E60565F4B4B520A0539534D555D443E3A27490A0A08020A09000A"
$"07090001020304050607081001178322040A03020608000A020107000A010101"
$"000A04020203000A000100000A020104000A060105000A050100100117810004"
};

View File

@@ -0,0 +1,910 @@
From 28b0d93f3fd754e25cb75ce657f1247a0f69dc7d 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
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

View File

@@ -0,0 +1,85 @@
SUMMARY="A system emulator for the RISC-V architecture"
DESCRIPTION="TinyEMU is a system emulator for the RISC-V architecture. \
Its purpose is to be small and simple while being complete.
Main features:
RISC-V system emulator supporting the RV128IMAFDQC base ISA \
(user level ISA version 2.2, priviledged architecture version 1.10) \
including:
* 32/64/128 bit integer registers
* 32/64/128 bit floating point instructions (using the SoftFP Library)
* Compressed instructions
* Dynamic XLEN change
* VirtIO console, network, block device, input and 9P filesystem
* Graphical display with SDL
* JSON configuration file
* Remote HTTP block device and filesystem
* Small code, easy to modify, few external dependancies."
HOMEPAGE="https://bellard.org/tinyemu/"
COPYRIGHT="2017-2019 Fabrice Bellard"
LICENSE="MIT"
REVISION="1"
SOURCE_URI="https://bellard.org/tinyemu/tinyemu-${portVersion//./-}.tar.gz"
CHECKSUM_SHA256="be8351f2121819b3172fcedce5cb1826fa12c87da1b7ed98f269d3e802a05555"
SOURCE_DIR="tinyemu-${portVersion//./-}"
PATCHES="tinyemu-$portVersion.patchset"
ADDITIONAL_FILES="tinyemu.rdef.in"
ARCHITECTURES="!x86_gcc2 x86_64"
SECONDARY_ARCHITECTURES="x86"
commandSuffix=$secondaryArchSuffix
commandBinDir=$binDir
if [ "$targetArchitecture" = x86_gcc2 ]; then
commandSuffix=
commandBinDir=$prefix/bin
fi
PROVIDES="
tinyemu$secondaryArchSuffix = $portVersion
cmd:temu$commandSuffix = $portVersion
"
REQUIRES="
haiku$secondaryArchSuffix
lib:libcrypto$secondaryArchSuffix
lib:libcurl$secondaryArchSuffix
lib:libSDL_1.2$secondaryArchSuffix
"
BUILD_REQUIRES="
haiku${secondaryArchSuffix}_devel
devel:libcrypto$secondaryArchSuffix
devel:libcurl$secondaryArchSuffix
devel:libsdl$secondaryArchSuffix
"
BUILD_PREREQUIRES="
cmd:gcc$secondaryArchSuffix
cmd:make
"
BUILD()
{
make $jobArgs
}
INSTALL()
{
mkdir $commandBinDir
cp temu $commandBinDir
local APP_SIGNATURE="application/x-vnd.tinyemu"
local MAJOR="`echo "$portVersion" | cut -d. -f1`"
local MIDDLE="`echo "$portVersion" | cut -d. -f2`"
local MINOR="`echo "$portVersion" | cut -d. -f3`"
local LONG_INFO="$SUMMARY"
sed \
-e "s|@APP_SIGNATURE@|$APP_SIGNATURE|" \
-e "s|@MAJOR@|$MAJOR|" \
-e "s|@MIDDLE@|$MIDDLE|" \
-e "s|@MINOR@|$MINOR|" \
-e "s|@LONG_INFO@|$LONG_INFO|" \
$portDir/additional-files/tinyemu.rdef.in > tinyemu.rdef
addResourcesToBinaries tinyemu.rdef $commandBinDir/temu
}