From fa0c5a86378739debad094c529b20917a08852a2 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Thu, 13 May 2021 11:49:20 +1000 Subject: [PATCH] TinyEmu: add recipe --- .../tinyemu/additional-files/tinyemu.rdef.in | 32 + .../patches/tinyemu-2019.12.21.patchset | 910 ++++++++++++++++++ .../tinyemu/tinyemu-2019.12.21.recipe | 85 ++ 3 files changed, 1027 insertions(+) create mode 100644 app-emulation/tinyemu/additional-files/tinyemu.rdef.in create mode 100644 app-emulation/tinyemu/patches/tinyemu-2019.12.21.patchset create mode 100644 app-emulation/tinyemu/tinyemu-2019.12.21.recipe diff --git a/app-emulation/tinyemu/additional-files/tinyemu.rdef.in b/app-emulation/tinyemu/additional-files/tinyemu.rdef.in new file mode 100644 index 000000000..0f80e0f50 --- /dev/null +++ b/app-emulation/tinyemu/additional-files/tinyemu.rdef.in @@ -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" +}; diff --git a/app-emulation/tinyemu/patches/tinyemu-2019.12.21.patchset b/app-emulation/tinyemu/patches/tinyemu-2019.12.21.patchset new file mode 100644 index 000000000..b6256651d --- /dev/null +++ b/app-emulation/tinyemu/patches/tinyemu-2019.12.21.patchset @@ -0,0 +1,910 @@ +From 28b0d93f3fd754e25cb75ce657f1247a0f69dc7d Mon Sep 17 00:00:00 2001 +From: X512 +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 + #include + #include ++#if !defined(__HAIKU__) + #include ++#endif + #include ++#if !defined(__HAIKU__) + #include ++#endif + #include + #include + #include +@@ -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 + #include + #include ++#ifndef __HAIKU__ + #include + #endif ++#endif + #include + #include + +@@ -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 ++ ++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 ++#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 + diff --git a/app-emulation/tinyemu/tinyemu-2019.12.21.recipe b/app-emulation/tinyemu/tinyemu-2019.12.21.recipe new file mode 100644 index 000000000..3f19fe463 --- /dev/null +++ b/app-emulation/tinyemu/tinyemu-2019.12.21.recipe @@ -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 +}