feat: serial device interfacing
authorMinep <lunaixsky@qq.com>
Sun, 3 Sep 2023 23:38:06 +0000 (00:38 +0100)
committerMinep <lunaixsky@qq.com>
Sun, 3 Sep 2023 23:41:45 +0000 (00:41 +0100)
feat: devzero
feat: simple cat implementation
fix: add default name for nameless device
chore: general clean up

35 files changed:
lunaix-os/arch/i386/exceptions/interrupts.c
lunaix-os/arch/i386/exceptions/intr_routines.c
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/char/devnull.c
lunaix-os/hal/char/devzero.c [new file with mode: 0644]
lunaix-os/hal/char/ps2kbd.c
lunaix-os/hal/char/serial.c [new file with mode: 0644]
lunaix-os/hal/char/uart/16550.h [new file with mode: 0644]
lunaix-os/hal/char/uart/16550_base.c [new file with mode: 0644]
lunaix-os/hal/char/uart/16550_pmio.c [new file with mode: 0644]
lunaix-os/hal/rng/rngx86.c
lunaix-os/hal/rtc/mc146818a.c
lunaix-os/includes/hal/serial.h [new file with mode: 0644]
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/device_num.h
lunaix-os/includes/lunaix/ds/fifo.h
lunaix-os/includes/lunaix/ds/mutex.h
lunaix-os/includes/usr/lunaix/device.h [new file with mode: 0644]
lunaix-os/includes/usr/lunaix/ioctl_defs.h
lunaix-os/includes/usr/lunaix/serial.h [new file with mode: 0644]
lunaix-os/kernel.mk
lunaix-os/kernel/debug/gdbstub.c
lunaix-os/kernel/debug/sdbg.c
lunaix-os/kernel/device/devdb.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/ds/fifo.c
lunaix-os/kernel/ds/mutex.c
lunaix-os/kernel/ds/waitq.c
lunaix-os/kernel/peripheral/serial.c [deleted file]
lunaix-os/kernel/proc0.c
lunaix-os/kernel/tty/lxconsole.c
lunaix-os/ksrc.excludes [new file with mode: 0644]
lunaix-os/usr/cat/main.c [new file with mode: 0644]
lunaix-os/usr/cat/makefile [new file with mode: 0644]
lunaix-os/usr/makefile

index c45f961018d8199e565536d6ccf07878b34647c8..5d4787ab94f33f637fca23ddd9ef93b2a423bcb5 100644 (file)
@@ -1,7 +1,8 @@
+#include <sys/cpu.h>
+#include <sys/i386_intr.h>
 #include <sys/interrupts.h>
 #include <sys/x86_isa.h>
 
 #include <sys/interrupts.h>
 #include <sys/x86_isa.h>
 
-#include <sys/cpu.h>
 #include <hal/intc.h>
 
 #include <lunaix/isrm.h>
 #include <hal/intc.h>
 
 #include <lunaix/isrm.h>
@@ -10,9 +11,6 @@
 #include <lunaix/process.h>
 #include <lunaix/sched.h>
 #include <lunaix/syslog.h>
 #include <lunaix/process.h>
 #include <lunaix/sched.h>
 #include <lunaix/syslog.h>
-#include <lunaix/tty/tty.h>
-
-#include <sys/i386_intr.h>
 
 LOG_MODULE("INTR")
 
 
 LOG_MODULE("INTR")
 
index 100df0ba2f84628321c4bb67031e98a6ca4d3807..d0b0d492915043264a0e54827a3eb012c47cc588 100644 (file)
@@ -7,7 +7,6 @@
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 #include <lunaix/trace.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 #include <lunaix/trace.h>
-#include <lunaix/tty/tty.h>
 
 #include <klibc/stdio.h>
 
 
 #include <klibc/stdio.h>
 
index c20e21dffe9bb248ae7f6f5c043b5556c34bab43..2b1176e4742dad14458240faf06b762afe2c2856 100644 (file)
@@ -443,7 +443,7 @@ static struct pci_device_def ahcidef = {
     .dev_vendor = PCI_ID_ANY,
     .dev_id = PCI_ID_ANY,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA, 0),
     .dev_vendor = PCI_ID_ANY,
     .dev_id = PCI_ID_ANY,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA, 0),
-                .name = "SATA AHCI",
+                .name = "Serial ATA Controller",
                 .init_for = ahci_driver_init }
 };
 EXPORT_DEVICE(ahci, &ahcidef.devdef, load_on_demand);
\ No newline at end of file
                 .init_for = ahci_driver_init }
 };
 EXPORT_DEVICE(ahci, &ahcidef.devdef, load_on_demand);
\ No newline at end of file
index 12bd00749b264b660b1c7ae4941a63753f4bfa25..0bdf99c25e4faf36fa5cbea0cc0423cd7edbe3f6 100644 (file)
@@ -43,7 +43,7 @@ pdev_nulldev_init(struct device_def*)
 
 static struct device_def devnull_def = {
     .name = "null",
 
 static struct device_def devnull_def = {
     .name = "null",
-    .class = DEVCLASS(DEVIF_NON, DEVFN_PSEUDO, 0, 0),
+    .class = DEVCLASS(DEVIF_NON, DEVFN_PSEUDO, DEV_BUILTIN, 0),
     .init = pdev_nulldev_init
 };
 EXPORT_DEVICE(nulldev, &devnull_def, load_earlystage);
     .init = pdev_nulldev_init
 };
 EXPORT_DEVICE(nulldev, &devnull_def, load_earlystage);
diff --git a/lunaix-os/hal/char/devzero.c b/lunaix-os/hal/char/devzero.c
new file mode 100644 (file)
index 0000000..d5f13c6
--- /dev/null
@@ -0,0 +1,35 @@
+#include <lunaix/device.h>
+#include <lunaix/mm/page.h>
+
+#include <klibc/string.h>
+
+static int
+__zero_rd_pg(struct device* dev, void* buf, size_t offset)
+{
+    memset(&((u8_t*)buf)[offset], 0, PG_SIZE);
+    return PG_SIZE;
+}
+
+static int
+__zero_rd(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    memset(&((u8_t*)buf)[offset], 0, len);
+    return len;
+}
+
+static int
+pdev_zerodev_init(struct device_def*)
+{
+    struct device* devzero = device_addseq(NULL, NULL, "zero");
+    devzero->ops.read_page = __zero_rd_pg;
+    devzero->ops.read = __zero_rd;
+
+    return 0;
+}
+
+static struct device_def devzero_def = {
+    .name = "zero",
+    .class = DEVCLASS(DEVIF_NON, DEVFN_PSEUDO, DEV_BUILTIN, 1),
+    .init = pdev_zerodev_init
+};
+EXPORT_DEVICE(zerodev, &devzero_def, load_earlystage);
index f59dcf30a35f96025e83954e68b5395a60b7d37c..d2be85dbe8b0dae0d4ec75c74dd5130efbb2d68c 100644 (file)
@@ -575,7 +575,7 @@ ps2_issue_dev_cmd(char cmd, u16_t arg)
 }
 
 static struct device_def devrtc_i8042kbd = {
 }
 
 static struct device_def devrtc_i8042kbd = {
-    .name = "ps2 keyboard",
+    .name = "i8042 Keyboard",
     .class = DEVCLASS(DEVIF_SOC, DEVFN_INPUT, DEV_X86LEGACY, 0),
     .init = ps2_kbd_init
 };
     .class = DEVCLASS(DEVIF_SOC, DEVFN_INPUT, DEV_X86LEGACY, 0),
     .init = ps2_kbd_init
 };
diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c
new file mode 100644 (file)
index 0000000..2c4a272
--- /dev/null
@@ -0,0 +1,193 @@
+#include <lunaix/device.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+#include <lunaix/status.h>
+
+#include <sys/mm/mempart.h>
+
+#include <hal/serial.h>
+
+static DEFINE_LLIST(serial_devs);
+static int serial_idx = 0;
+
+#define serial_device(dev) ((struct serial_dev*)(dev)->underlay)
+
+int
+serial_accept_one(struct serial_dev* sdev, u8_t val)
+{
+    return !!fifo_putone(&sdev->rxbuf, val);
+}
+
+int
+serial_accept_buffer(struct serial_dev* sdev, void* val, size_t len)
+{
+    return !!fifo_write(&sdev->rxbuf, val, len);
+}
+
+void
+serial_end_recv(struct serial_dev* sdev)
+{
+    pwake_one(&sdev->wq_rxdone);
+}
+
+void
+serial_end_xmit(struct serial_dev* sdev, size_t len)
+{
+    sdev->wr_len = len;
+    pwake_one(&sdev->wq_txdone);
+}
+
+int
+serial_readone_nowait(struct serial_dev* sdev, u8_t* val)
+{
+    mutex_lock(&sdev->lock);
+
+    int rd_len = fifo_readone(&sdev->rxbuf, val);
+
+    mutex_unlock(&sdev->lock);
+
+    return rd_len;
+}
+
+void
+serial_readone(struct serial_dev* sdev, u8_t* val)
+{
+    mutex_lock(&sdev->lock);
+
+    while (!fifo_readone(&sdev->rxbuf, val)) {
+        pwait(&sdev->wq_rxdone);
+    }
+
+    mutex_unlock(&sdev->lock);
+}
+
+size_t
+serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len)
+{
+    mutex_lock(&sdev->lock);
+
+    size_t rdlen;
+    while (!(rdlen = fifo_read(&sdev->rxbuf, buf, len))) {
+        pwait(&sdev->wq_rxdone);
+    }
+
+    mutex_unlock(&sdev->lock);
+
+    return rdlen;
+}
+
+int
+serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
+{
+    mutex_lock(&sdev->lock);
+
+    int rdlen = fifo_read(&sdev->rxbuf, buf, len);
+
+    mutex_unlock(&sdev->lock);
+
+    return rdlen;
+}
+
+int
+serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len)
+{
+    mutex_lock(&sdev->lock);
+
+    if (sdev->write(sdev, buf, len) == RXTX_DONE) {
+        goto done;
+    }
+
+    pwait(&sdev->wq_txdone);
+
+done:
+    int rdlen = sdev->wr_len;
+    mutex_unlock(&sdev->lock);
+
+    return rdlen;
+}
+
+int
+serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
+{
+    mutex_lock(&sdev->lock);
+
+    sdev->write(sdev, buf, len);
+    int rdlen = sdev->wr_len;
+
+    mutex_unlock(&sdev->lock);
+
+    return rdlen;
+}
+
+static int
+__serial_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], len);
+}
+
+static int
+__serial_read_page(struct device* dev, void* buf, size_t offset)
+{
+    return serial_readbuf(serial_device(dev), &((u8_t*)buf)[offset], MEM_PAGE);
+}
+
+static int
+__serial_write(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], len);
+}
+
+static int
+__serial_write_page(struct device* dev, void* buf, size_t offset)
+{
+    return serial_writebuf(serial_device(dev), &((u8_t*)buf)[offset], MEM_PAGE);
+}
+
+static int
+__serial_exec_command(struct device* dev, u32_t req, va_list args)
+{
+    struct serial_dev* sdev = serial_device(dev);
+
+    if (!sdev->exec_cmd) {
+        return ENOTSUP;
+    }
+
+    return sdev->exec_cmd(sdev, req, args);
+}
+
+#define RXBUF_SIZE 512
+
+struct serial_dev*
+serial_create()
+{
+    struct serial_dev* sdev = valloc(sizeof(struct serial_dev));
+    struct device* dev = device_addseq(NULL, sdev, "ttyS%d", serial_idx++);
+    dev->ops.read = __serial_read;
+    dev->ops.read_page = __serial_read_page;
+    dev->ops.write = __serial_write;
+    dev->ops.write_page = __serial_write_page;
+    dev->ops.exec_cmd = __serial_exec_command;
+
+    sdev->dev = dev;
+    dev->underlay = sdev;
+
+    fifo_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE, 0);
+    llist_append(&serial_devs, &sdev->sdev_list);
+    // llist_init_head(&sdev->cmds);
+
+    return sdev;
+}
+
+struct serial_dev*
+serial_get_avilable()
+{
+    struct serial_dev *pos, *n;
+    llist_for_each(pos, n, &serial_devs, sdev_list)
+    {
+        if (!mutex_on_hold(&pos->lock)) {
+            return pos;
+        }
+    }
+
+    return NULL;
+}
\ No newline at end of file
diff --git a/lunaix-os/hal/char/uart/16550.h b/lunaix-os/hal/char/uart/16550.h
new file mode 100644 (file)
index 0000000..a656575
--- /dev/null
@@ -0,0 +1,211 @@
+#ifndef __LUNAIX_16550_H
+#define __LUNAIX_16550_H
+
+#include <hal/serial.h>
+#include <lunaix/types.h>
+
+#define UART_rRxTX 0
+#define UART_rIE 1
+#define UART_rII 2
+#define UART_rFC 2
+#define UART_rLC 3
+#define UART_rMC 4
+#define UART_rLS 5
+#define UART_rMS 6
+#define UART_rSC 7
+#define UART_rDLL 0
+#define UART_rDLM 1
+
+#define UART_INTRX 0x1
+#define UART_DLAB (1 << 7)
+#define UART_LOOP (1 << 4)
+
+#define UART_rIE_ERBFI 1
+#define UART_rIE_ETBEI (1 << 1)
+#define UART_rIE_ELSI (1 << 2)
+#define UART_rIE_EDSSI (1 << 3)
+
+#define UART_rLS_THRE (1 << 5)
+#define UART_rLS_DR 1
+#define UART_rLS_BI (1 << 4)
+
+#define UART_rII_FIFOEN (0b11 << 6)
+#define UART_rII_ID 0b1110
+
+#define UART_rFC_EN 1
+#define UART_rFC_XMIT_RESET (1 << 2)
+#define UART_rFC_RCVR_RESET (1 << 1)
+
+#define UART_rMC_DTR 1
+#define UART_rMC_RTS (1 << 1)
+#define UART_rMC_IEN (1 << 3)
+
+#define UART_FIFO1 0b00
+#define UART_FIFO4 0b01
+#define UART_FIFO8 0b10
+#define UART_FIFO14 0b11
+
+#define UART_NO_INTR 0b0001
+#define UART_LINE_UDPDATE 0b0110
+#define UART_DATA_OK 0b0100
+#define UART_CHR_TIMEOUT 0b1100
+#define UART_SENT_ALL 0b0010
+#define UART_MODEM_UPDATE 0b0000
+
+struct uart16550
+{
+    struct llist_header local_ports;
+    struct serial_dev* sdev;
+    ptr_t base_addr;
+    int iv;
+
+    struct
+    {
+        u8_t rie;
+        u8_t rfc;
+        u8_t rmc;
+    } cntl_save;
+
+    u32_t (*read_reg)(struct uart16550* uart, ptr_t regoff);
+    void (*write_reg)(struct uart16550* uart, ptr_t regoff, u32_t val);
+};
+
+#define UART16550(sdev) ((struct uart16550*)(sdev)->backend)
+
+static inline void
+uart_setup(struct uart16550* uart)
+{
+    uart->write_reg(uart, UART_rMC, uart->cntl_save.rmc);
+    uart->write_reg(uart, UART_rIE, uart->cntl_save.rie);
+}
+
+static inline void
+uart_setie(struct uart16550* uart)
+{
+    uart->cntl_save.rie = uart->read_reg(uart, UART_rIE);
+    uart->write_reg(uart, UART_rIE, 0);
+}
+
+static inline void
+uart_clrie(struct uart16550* uart)
+{
+    uart->write_reg(uart, UART_rIE, uart->cntl_save.rie | 1);
+}
+
+struct uart16550*
+uart_alloc(ptr_t base_addr);
+
+void
+uart_free(struct uart16550*);
+
+static inline int
+uart_baud_divisor(struct uart16550* uart, int div)
+{
+    u32_t rlc = uart->read_reg(uart, UART_rLC);
+
+    uart->write_reg(uart, UART_rLC, UART_DLAB | rlc);
+    u8_t ls = (div & 0xff), ms = (div & 0xff00) >> 8;
+
+    uart->write_reg(uart, UART_rLS, ls);
+    uart->write_reg(uart, UART_rMS, ms);
+
+    uart->write_reg(uart, UART_rLC, rlc & ~UART_DLAB);
+
+    return 0;
+}
+
+static inline int
+uart_testport(struct uart16550* uart, char test_code)
+{
+    u32_t rmc = uart->cntl_save.rmc;
+    uart->write_reg(uart, UART_rMC, rmc | UART_LOOP);
+
+    uart->write_reg(uart, UART_rRxTX, test_code);
+
+    u32_t result = (char)uart->read_reg(uart, UART_rRxTX) == test_code;
+    uart->write_reg(uart, UART_rMC, rmc & ~UART_LOOP);
+
+    return result;
+}
+
+static inline int
+uart_pending_data(struct uart16550* uart)
+{
+    return uart->read_reg(uart, UART_rLS) & UART_rLS_DR;
+}
+
+static inline int
+uart_can_transmit(struct uart16550* uart)
+{
+    return uart->read_reg(uart, UART_rLS) & UART_rLS_THRE;
+}
+
+/**
+ * @brief End of receiving
+ *
+ * @param uart
+ * @return int
+ */
+static inline int
+uart_eorcv(struct uart16550* uart)
+{
+    return uart->read_reg(uart, UART_rLS) & UART_rLS_BI;
+}
+
+static inline int
+uart_enable_fifo(struct uart16550* uart, int trig_lvl)
+{
+    uart->cntl_save.rfc = UART_rFC_EN | (trig_lvl & 0b11);
+    uart->write_reg(uart, UART_rFC, uart->cntl_save.rfc);
+
+    return uart->read_reg(uart, UART_rII) & UART_rII_FIFOEN;
+}
+
+static inline void
+uart_clear_rxfifo(struct uart16550* uart)
+{
+    uart->write_reg(uart, UART_rFC, uart->cntl_save.rfc | UART_rFC_RCVR_RESET);
+}
+
+static inline void
+uart_clear_txfifo(struct uart16550* uart)
+{
+    uart->write_reg(uart, UART_rFC, uart->cntl_save.rfc | UART_rFC_XMIT_RESET);
+}
+
+static inline void
+uart_clear_fifo(struct uart16550* uart)
+{
+    u32_t rfc = uart->cntl_save.rfc | UART_rFC_XMIT_RESET | UART_rFC_RCVR_RESET;
+    uart->write_reg(uart, UART_rFC, rfc);
+}
+
+static inline int
+uart_intr_identify(struct uart16550* uart)
+{
+    u32_t rii = uart->read_reg(uart, UART_rII);
+    return (!!(rii & UART_rII_FIFOEN) << 3) | ((rii & UART_rII_ID) >> 1);
+}
+
+static inline u8_t
+uart_read_byte(struct uart16550* uart)
+{
+    return (u8_t)uart->read_reg(uart, UART_rRxTX);
+}
+
+static inline void
+uart_write_byte(struct uart16550* uart, u8_t val)
+{
+    uart->write_reg(uart, UART_rRxTX, val);
+}
+
+int
+uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args);
+
+int
+uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len);
+
+void
+uart_general_irq_handler(int iv, struct llist_header* ports);
+
+#endif /* __LUNAIX_16550_H */
diff --git a/lunaix-os/hal/char/uart/16550_base.c b/lunaix-os/hal/char/uart/16550_base.c
new file mode 100644 (file)
index 0000000..4ae45d7
--- /dev/null
@@ -0,0 +1,96 @@
+#include <lunaix/mm/valloc.h>
+#include <lunaix/status.h>
+
+#include <usr/lunaix/serial.h>
+
+#include "16550.h"
+
+struct uart16550*
+uart_alloc(ptr_t base_addr)
+{
+    struct uart16550* uart = valloc(sizeof(struct uart16550));
+
+    // load registers default value
+    uart->cntl_save.rmc = UART_rMC_DTR | UART_rMC_RTS | UART_rMC_IEN;
+    uart->cntl_save.rie = 0;
+
+    uart->base_addr = base_addr;
+    return uart;
+}
+
+void
+uart_free(struct uart16550* uart)
+{
+    vfree(uart);
+}
+
+int
+uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len)
+{
+    struct uart16550* uart = UART16550(sdev);
+
+    size_t i = 0;
+    while (i < len) {
+        while (!uart_can_transmit(uart))
+            ;
+        uart_write_byte(uart, data[i++]);
+    }
+
+    serial_end_xmit(sdev, len);
+
+    return RXTX_DONE;
+}
+
+int
+uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args)
+{
+    struct uart16550* uart = UART16550(sdev);
+    switch (req) {
+        case SERIO_RXEN:
+            uart_setie(uart);
+            break;
+        case SERIO_RXDA:
+            uart_clrie(uart);
+            break;
+        default:
+            return ENOTSUP;
+    }
+    return 0;
+}
+
+void
+uart_general_irq_handler(int iv, struct llist_header* ports)
+{
+    char tmpbuf[32];
+    struct uart16550 *pos, *n;
+    llist_for_each(pos, n, ports, local_ports)
+    {
+        int is = uart_intr_identify(pos);
+        if (iv == pos->iv && is == UART_DATA_OK) {
+            break;
+        }
+    }
+
+    if (!pos) {
+        return;
+    }
+
+    char recv;
+    int i = 0;
+    while ((recv = uart_read_byte(pos))) {
+        tmpbuf[i++] = recv;
+        if (likely(i < 32)) {
+            continue;
+        }
+
+        if (!serial_accept_buffer(pos->sdev, tmpbuf, i)) {
+            uart_clear_rxfifo(pos);
+            return;
+        }
+
+        i = 0;
+    }
+
+    serial_accept_buffer(pos->sdev, tmpbuf, i);
+    serial_end_recv(pos->sdev);
+}
diff --git a/lunaix-os/hal/char/uart/16550_pmio.c b/lunaix-os/hal/char/uart/16550_pmio.c
new file mode 100644 (file)
index 0000000..4342d98
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * @file 16550_pmio.c
+ * @author Lunaixsky (lunaxisky@qq.com)
+ * @brief 16550 UART with port mapped IO
+ * @version 0.1
+ * @date 2023-08-30
+ *
+ * @copyright Copyright (c) 2023
+ *
+ */
+#include <lunaix/device.h>
+#include <lunaix/isrm.h>
+
+#include <sys/port_io.h>
+
+#include "16550.h"
+
+#define DELAY 50
+
+static DEFINE_LLIST(com_ports);
+
+static u32_t
+com_regread(struct uart16550* uart, ptr_t regoff)
+{
+    u8_t val = port_rdbyte(uart->base_addr + regoff);
+    port_delay(DELAY);
+
+    return (u32_t)val;
+}
+
+static void
+com_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val)
+{
+    port_wrbyte(uart->base_addr + regoff, (u8_t)val);
+    port_delay(DELAY);
+}
+
+static void
+com_irq_handler(const isr_param* param)
+{
+    uart_general_irq_handler(param->execp->vector, &com_ports);
+}
+
+static int
+upiom_init(struct device_def* def)
+{
+    int irq3 = 3, irq4 = 4;
+    u16_t ioports[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
+    int* irqs[] = { &irq4, &irq3, &irq4, &irq3 };
+
+    struct uart16550* uart = NULL;
+
+    // COM 1...4
+    for (size_t i = 0; i < 4; i++) {
+        if (!uart) {
+            uart = uart_alloc(ioports[i]);
+            uart->read_reg = com_regread;
+            uart->write_reg = com_regwrite;
+        } else {
+            uart->base_addr = ioports[i];
+        }
+
+        if (!uart_testport(uart, 0xe3)) {
+            continue;
+        }
+
+        int irq = *irqs[i];
+        if (irq) {
+            /*
+             *  Since these irqs are overlapped, this particular setup is needed
+             * to avoid double-bind
+             */
+            uart->iv = isrm_bindirq(irq, com_irq_handler);
+            *((volatile int*)irqs[i]) = 0;
+        }
+
+        uart_setup(uart);
+        uart_enable_fifo(uart, UART_FIFO8);
+        llist_append(&com_ports, &uart->local_ports);
+
+        struct serial_dev* sdev = serial_create();
+        sdev->backend = uart;
+        sdev->write = uart_general_tx;
+        sdev->exec_cmd = uart_general_exec_cmd;
+
+        uart->sdev = sdev;
+
+        uart = NULL;
+    }
+
+    if (uart) {
+        uart_free(uart);
+    }
+
+    return 0;
+}
+
+static struct device_def uart_pmio_def = {
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_SERIAL, 0),
+    .name = "16550 Generic UART (I/O)",
+    .init = upiom_init
+};
+EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_earlystage);
\ No newline at end of file
index bb069d7f61d13025f05ad19a05abd248e360b343..af11802a43378de27c63f40ee62cb911e6ca4629 100644 (file)
@@ -39,7 +39,7 @@ pdev_randdev_init(struct device_def* devdef)
 }
 
 static struct device_def devrandx86_def = {
 }
 
 static struct device_def devrandx86_def = {
-    .name = "null",
+    .name = "x86 On-Chip RNG",
     .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_RNG, 0),
     .init = pdev_randdev_init
 };
     .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_RNG, 0),
     .init = pdev_randdev_init
 };
index e918ffdba83024aa0a578b608d62b3c0fea2b0fc..c36412a8d293aa2a2f55ab08db05db66a4cfee73 100644 (file)
@@ -216,7 +216,7 @@ rtc_init(struct device_def* devdef)
 }
 
 static struct device_def devrtc_mc146818 = {
 }
 
 static struct device_def devrtc_mc146818 = {
-    .name = "rtc_mc146818",
+    .name = "MC146818 RTC",
     .class = DEVCLASS(DEVIF_SOC, DEVFN_TIME, DEV_RTC, 1),
     .init = rtc_init
 };
     .class = DEVCLASS(DEVIF_SOC, DEVFN_TIME, DEV_RTC, 1),
     .init = rtc_init
 };
diff --git a/lunaix-os/includes/hal/serial.h b/lunaix-os/includes/hal/serial.h
new file mode 100644 (file)
index 0000000..b2fdf5e
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef __LUNAIX_SERIAL_H
+#define __LUNAIX_SERIAL_H
+
+#include <lunaix/device.h>
+#include <lunaix/ds/fifo.h>
+#include <lunaix/ds/llist.h>
+#include <lunaix/ds/mutex.h>
+#include <lunaix/ds/waitq.h>
+
+#define SERIAL_RW_RX 0x0
+#define SERIAL_RW_TX 0x1
+#define io_dir(flags) ((flags) & SERIAL_RW_TX)
+
+#define RXTX_DONE 0x1
+#define RXTX_WAIT 0x2
+
+#define SERIAL_AGAIN 0x1
+#define SERIAL_DONE 0x0
+
+struct serial_dev;
+typedef int (*rxtx_cb)(struct serial_dev*);
+
+struct serial_dev
+{
+    struct llist_header sdev_list;
+    struct device* dev;
+    mutex_t lock;
+    struct waitq wq_rxdone;
+    struct waitq wq_txdone;
+    void* backend;
+
+    struct fifo_buf rxbuf;
+    int wr_len;
+
+    /**
+     * @brief Write buffer to TX. The return code indicate
+     * the transaction is either done in synced mode (TX_DONE) or will be
+     * done asynchronously (TX_WAIT).
+     *
+     */
+    int (*write)(struct serial_dev* sdev, u8_t*, size_t);
+    int (*exec_cmd)(struct serial_dev* sdev, u32_t, va_list);
+};
+
+struct serial_dev*
+serial_create();
+
+void
+serial_readone(struct serial_dev* sdev, u8_t* val);
+
+int
+serial_readone_nowait(struct serial_dev* sdev, u8_t* val);
+
+size_t
+serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len);
+
+int
+serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len);
+
+int
+serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len);
+
+int
+serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len);
+
+struct serial_dev*
+serial_get_avilable();
+
+int
+serial_accept_one(struct serial_dev* sdev, u8_t val);
+
+int
+serial_accept_buffer(struct serial_dev* sdev, void* val, size_t len);
+
+void
+serial_end_recv(struct serial_dev* sdev);
+
+void
+serial_end_xmit(struct serial_dev* sdev, size_t len);
+
+#endif /* __LUNAIX_SERIAL_H */
index 52df8f0a0efcbde5c3fe6bf38d7e33d61ac207b9..cb2c2947a5b52264d33bcaed959faf18b7f4f3c8 100644 (file)
@@ -92,6 +92,10 @@ struct device
 
     struct
     {
 
     struct
     {
+        // TODO Think about where will they fit.
+        int (*acquire)(struct device* dev);
+        int (*release)(struct device* dev);
+
         int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
         int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
         int (*read_page)(struct device* dev, void* buf, size_t offset);
         int (*read)(struct device* dev, void* buf, size_t offset, size_t len);
         int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
         int (*read_page)(struct device* dev, void* buf, size_t offset);
@@ -181,6 +185,9 @@ device_create_byclass(struct devclass* class,
 struct hbucket*
 device_definitions_byif(int if_type);
 
 struct hbucket*
 device_definitions_byif(int if_type);
 
+struct device_def*
+devdef_byclass(struct devclass* class);
+
 void
 device_register_all();
 
 void
 device_register_all();
 
index 58e91223b3e2dbc0f9110d5cd4bd7e402bd9235b..704c39bc3a33dfa83060351e099352aab3c90f81 100644 (file)
@@ -49,9 +49,9 @@
             device for output into external environment
 */
 
             device for output into external environment
 */
 
-#define DEV_META(if_, function) (((if_)&0xffff) << 16) | ((function)&0xffff)
+#define DEV_META(if_, function) (((if_) & 0xffff) << 16) | ((function) & 0xffff)
 #define DEV_IF(meta) ((meta) >> 16)
 #define DEV_IF(meta) ((meta) >> 16)
-#define DEV_FN(meta) (((meta)&0xffff))
+#define DEV_FN(meta) (((meta) & 0xffff))
 
 #define DEVIF_NON 0x0
 #define DEVIF_SOC 0x1
 
 #define DEVIF_NON 0x0
 #define DEVIF_SOC 0x1
@@ -74,6 +74,7 @@
 #define DEV_RTC 0x3
 #define DEV_SATA 0x4
 #define DEV_NVME 0x5
 #define DEV_RTC 0x3
 #define DEV_SATA 0x4
 #define DEV_NVME 0x5
-#define DEV_BUS 0x5
+#define DEV_BUS 0x6
+#define DEV_SERIAL 0x7
 
 #endif /* __LUNAIX_DEVICE_NUM_H */
 
 #endif /* __LUNAIX_DEVICE_NUM_H */
index ecdbe5ebba220a8a3cc1c527e364036dbeed5f25..a8f5091fb4dad97b535eb276b84207a174280f13 100644 (file)
@@ -26,6 +26,9 @@ fifo_putone(struct fifo_buf* fbuf, u8_t data);
 size_t
 fifo_readone_async(struct fifo_buf* fbuf, u8_t* data);
 
 size_t
 fifo_readone_async(struct fifo_buf* fbuf, u8_t* data);
 
+size_t
+fifo_readone(struct fifo_buf* fbuf, u8_t* data);
+
 void
 fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr);
 
 void
 fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr);
 
index 97101ef4ce68090c086fc7d61020964a2e81659b..162186c05139b0376c552682e483c9ae0ba99e01 100644 (file)
@@ -1,25 +1,25 @@
 #ifndef __LUNAIX_MUTEX_H
 #define __LUNAIX_MUTEX_H
 
 #ifndef __LUNAIX_MUTEX_H
 #define __LUNAIX_MUTEX_H
 
-#include "semaphore.h"
 #include <lunaix/types.h>
 #include <lunaix/types.h>
+#include <stdatomic.h>
 
 typedef struct mutex_s
 {
 
 typedef struct mutex_s
 {
-    struct sem_t sem;
+    atomic_ulong lk;
     pid_t owner;
 } mutex_t;
 
 static inline void
 mutex_init(mutex_t* mutex)
 {
     pid_t owner;
 } mutex_t;
 
 static inline void
 mutex_init(mutex_t* mutex)
 {
-    sem_init(&mutex->sem, 1);
+    mutex->lk = ATOMIC_VAR_INIT(0);
 }
 
 static inline int
 mutex_on_hold(mutex_t* mutex)
 {
 }
 
 static inline int
 mutex_on_hold(mutex_t* mutex)
 {
-    return !atomic_load(&mutex->sem.counter);
+    return atomic_load(&mutex->lk);
 }
 
 void
 }
 
 void
diff --git a/lunaix-os/includes/usr/lunaix/device.h b/lunaix-os/includes/usr/lunaix/device.h
new file mode 100644 (file)
index 0000000..3045113
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __LUNAIX_UDEVICE_H
+#define __LUNAIX_UDEVICE_H
+
+#include "ioctl_defs.h"
+
+struct dev_info
+{
+    unsigned int extra;
+
+    struct
+    {
+        unsigned int meta;
+        unsigned int device;
+        unsigned int variant;
+    } dev_id;
+
+    struct
+    {
+        char* buf;
+        unsigned int buf_len;
+    } dev_name;
+};
+
+#endif /* __LUNAIX_UDEVICE_H */
index 9ca8cad3f648564379a0d820895f91fc38ad40d2..dd5709f6ca99c9559e923062129fdd83dce6389c 100644 (file)
@@ -1,11 +1,13 @@
 #ifndef __LUNAIX_SYS_IOCTL_DEFS_H
 #define __LUNAIX_SYS_IOCTL_DEFS_H
 
 #ifndef __LUNAIX_SYS_IOCTL_DEFS_H
 #define __LUNAIX_SYS_IOCTL_DEFS_H
 
-#define IOREQ(cmd, arg_num) ((((cmd)&0xffff) << 8) | ((arg_num)&0xff))
+#define IOREQ(cmd, arg_num) ((((cmd) & 0xffff) << 8) | ((arg_num) & 0xff))
 
 #define IOCMD(req) ((req) >> 8)
 
 
 #define IOCMD(req) ((req) >> 8)
 
-#define IOARGNUM(req) ((req)&0xff)
+#define IOARGNUM(req) ((req) & 0xff)
+
+#define DEVIOIDENT IOREQ(-1, 1)
 
 #define TIOCGPGRP IOREQ(1, 0)
 #define TIOCSPGRP IOREQ(1, 1)
 
 #define TIOCGPGRP IOREQ(1, 0)
 #define TIOCSPGRP IOREQ(1, 1)
diff --git a/lunaix-os/includes/usr/lunaix/serial.h b/lunaix-os/includes/usr/lunaix/serial.h
new file mode 100644 (file)
index 0000000..7cdd74b
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __LUNAIX_USERIAL_H
+#define __LUNAIX_USERIAL_H
+
+#include "ioctl_defs.h"
+
+#define SERIO_RXEN IOREQ(1, 0)
+#define SERIO_RXDA IOREQ(2, 0)
+
+#define SERIO_TXEN IOREQ(3, 0)
+#define SERIO_TXDA IOREQ(4, 0)
+
+#endif /* __LUNAIX_USERIAL_H */
index 5d645140271c724e8305e4d27b35f3e1680daca2..c5596f893ab13b9d7929583b201b15b66a693c48 100644 (file)
@@ -1,6 +1,8 @@
 include os.mkinc
 include toolchain.mkinc
 
 include os.mkinc
 include toolchain.mkinc
 
+kexclusion = $(shell cat ksrc.excludes)
+
 define ksrc_dirs
        kernel
        hal
 define ksrc_dirs
        kernel
        hal
@@ -19,6 +21,7 @@ kbin_dir := $(BUILD_DIR)
 kbin := $(BUILD_NAME)
 
 ksrc_files := $(foreach f, $(ksrc_dirs), $(shell find $(f) -name "*.[cS]"))
 kbin := $(BUILD_NAME)
 
 ksrc_files := $(foreach f, $(ksrc_dirs), $(shell find $(f) -name "*.[cS]"))
+ksrc_files := $(filter-out $(kexclusion),$(ksrc_files))
 ksrc_objs := $(addsuffix .o,$(ksrc_files))
 ksrc_deps := $(addsuffix .d,$(ksrc_files))
 
 ksrc_objs := $(addsuffix .o,$(ksrc_files))
 ksrc_deps := $(addsuffix .d,$(ksrc_files))
 
@@ -36,12 +39,12 @@ CFLAGS += -include flags.h
        @$(CC) $(CFLAGS) $(kinc_opts) -c $< -o $@
 
 $(kbin_dir)/modksyms: $(kbin)
        @$(CC) $(CFLAGS) $(kinc_opts) -c $< -o $@
 
 $(kbin_dir)/modksyms: $(kbin)
-       $(call status_,GEN,$@)
+       $(call status_,MOD,$@)
        @$(PY) scripts/syms_export.py --bits=32 --order=little -o "$@"  "$<" 
 
 .PHONY: __do_relink
 __do_relink: $(ksrc_objs)
        @$(PY) scripts/syms_export.py --bits=32 --order=little -o "$@"  "$<" 
 
 .PHONY: __do_relink
 __do_relink: $(ksrc_objs)
-       $(call status_,LD,$@)
+       $(call status_,LD,$(kbin))
        @$(CC) -T link/linker.ld -o $(kbin) $(ksrc_objs) $(LDFLAGS)
 
 .PHONY: all
        @$(CC) -T link/linker.ld -o $(kbin) $(ksrc_objs) $(LDFLAGS)
 
 .PHONY: all
index 072b6a42c8a4eb585f5585a44807a38cb3fbebe1..963e5ff7dafeafd49e185dd9cafb5dd4f5f43ef6 100644 (file)
@@ -32,8 +32,8 @@
  * SOFTWARE.
  */
 
  * SOFTWARE.
  */
 
+#include <hal/serial.h>
 #include <klibc/string.h>
 #include <klibc/string.h>
-#include <lunaix/peripheral/serial.h>
 #include <sdbg/gdbstub.h>
 #include <sys/port_io.h>
 
 #include <sdbg/gdbstub.h>
 #include <sys/port_io.h>
 
@@ -74,6 +74,7 @@ enum GDB_REGISTER
 struct gdb_state
 {
     int signum;
 struct gdb_state
 {
     int signum;
+    struct serial_dev* sdev;
     reg registers[GDB_CPU_NUM_REGISTERS];
 };
 
     reg registers[GDB_CPU_NUM_REGISTERS];
 };
 
@@ -884,13 +885,9 @@ gdb_send_error_packet(struct gdb_state* state,
 static int
 gdb_write(struct gdb_state* state, const char* buf, unsigned int len)
 {
 static int
 gdb_write(struct gdb_state* state, const char* buf, unsigned int len)
 {
-    while (len--) {
-        if (gdb_sys_putchar(state, *buf++) == GDB_EOF) {
-            return GDB_EOF;
-        }
-    }
+    int err = serial_rwbuf_sync(state->sdev, buf, len, SERIAL_RW_TX);
 
 
-    return 0;
+    return err < 0 ? GDB_EOF : 0;
 }
 
 /*
 }
 
 /*
@@ -913,14 +910,9 @@ gdb_read(struct gdb_state* state,
         return GDB_EOF;
     }
 
         return GDB_EOF;
     }
 
-    while (len--) {
-        if ((c = gdb_sys_getc(state)) == GDB_EOF) {
-            return GDB_EOF;
-        }
-        *buf++ = c;
-    }
+    int err = serial_rwbuf_sync(state->sdev, buf, buf_len, SERIAL_RW_RX);
 
 
-    return 0;
+    return err < 0 ? GDB_EOF : 0;
 }
 
 /*****************************************************************************
 }
 
 /*****************************************************************************
@@ -1271,7 +1263,7 @@ gdbstub_loop(isr_param* param)
 int
 gdb_sys_putchar(struct gdb_state* state, int ch)
 {
 int
 gdb_sys_putchar(struct gdb_state* state, int ch)
 {
-    gdb_x86_serial_putchar(ch);
+    serial_rwbuf_sync(state->sdev, &ch, 1, SERIAL_RW_TX);
     return ch;
 }
 
     return ch;
 }
 
@@ -1281,7 +1273,9 @@ gdb_sys_putchar(struct gdb_state* state, int ch)
 int
 gdb_sys_getc(struct gdb_state* state)
 {
 int
 gdb_sys_getc(struct gdb_state* state)
 {
-    return gdb_x86_serial_getc() & 0xff;
+    char ch;
+    serial_rwbuf_sync(state->sdev, &ch, 1, SERIAL_RW_RX);
+    return ch & 0xff;
 }
 
 /*
 }
 
 /*
index 42dc6c7a66cf8c0e744aee263c46c47a5bde813f..af33a452634ed9aa39f6255a21b01cf686b49372 100644 (file)
@@ -1,75 +1,41 @@
-#include <hal/acpi/acpi.h>
-#include <hal/intc.h>
+// FIXME Re-design needed!!
+
+#include <hal/serial.h>
 #include <klibc/stdio.h>
 #include <klibc/stdio.h>
-#include <lunaix/isrm.h>
-#include <lunaix/lxconsole.h>
-#include <lunaix/peripheral/serial.h>
 #include <lunaix/syslog.h>
 #include <sdbg/gdbstub.h>
 #include <sdbg/lsdbg.h>
 #include <sdbg/protocol.h>
 
 #include <lunaix/syslog.h>
 #include <sdbg/gdbstub.h>
 #include <sdbg/lsdbg.h>
 #include <sdbg/protocol.h>
 
+#include <lunaix/isrm.h>
+
 // #define USE_LSDBG_BACKEND
 
 LOG_MODULE("SDBG")
 
 volatile int debug_mode = 0;
 
 // #define USE_LSDBG_BACKEND
 
 LOG_MODULE("SDBG")
 
 volatile int debug_mode = 0;
 
-void
-sdbg_loop(const isr_param* param)
+// begin: @cmc
+#define DBG_START 0x636d6340UL
+
+// begin: @yay
+#define DBG_END 0x79617940UL
+
+static int
+sdbg_serial_callback(struct serial_dev* sdev)
 {
 {
-    // This is importnat, because we will handle any subsequent RX/TX in a
-    // synchronized way. And we don't want these irq queue up at our APIC and
-    // confuse the CPU after ACK with APIC.
-    serial_disable_irq(SERIAL_COM1);
-    struct exec_param* execp = param->execp;
-    if (execp->vector == 1 || execp->vector == 3) {
-        goto cont;
-    }
+    u32_t dbg_sig = *(u32_t*)sdev->rw.buf;
 
 
-    if (!debug_mode) {
-        // Oh... C.M.C. is about to help the debugging!
-        if (serial_rx_byte(SERIAL_COM1) != '@') {
-            goto done;
-        }
-        if (serial_rx_byte(SERIAL_COM1) != 'c') {
-            goto done;
-        }
-        if (serial_rx_byte(SERIAL_COM1) != 'm') {
-            goto done;
-        }
-        if (serial_rx_byte(SERIAL_COM1) != 'c') {
-            goto done;
-        }
+    if (dbg_sig == DBG_START) {
         debug_mode = 1;
         debug_mode = 1;
-    } else {
-        if (serial_rx_byte(SERIAL_COM1) != '@') {
-            goto cont;
-        }
-        if (serial_rx_byte(SERIAL_COM1) != 'y') {
-            goto cont;
-        }
-        if (serial_rx_byte(SERIAL_COM1) != 'a') {
-            goto cont;
-        }
-        if (serial_rx_byte(SERIAL_COM1) != 'y') {
-            goto cont;
-        }
+    } else if (dbg_sig == DBG_END) {
         debug_mode = 0;
         debug_mode = 0;
-        goto done;
     }
 
     }
 
-cont:
-    kprint_dbg(" DEBUG");
-#ifdef USE_LSDBG_BACKEND
-    lunaix_sdbg_loop(param);
-#else
-    gdbstub_loop(param);
-#endif
-    console_flush();
+    // Debugger should be run later
+    // TODO implement a defer execution mechanism (i.e., soft interrupt)
 
 
-done:
-    serial_enable_irq(SERIAL_COM1);
+    return SERIAL_AGAIN;
 }
 
 void
 }
 
 void
@@ -98,15 +64,29 @@ sdbg_imm(const isr_param* param)
             param->registers.es,
             param->registers.fs,
             param->registers.gs);
             param->registers.es,
             param->registers.fs,
             param->registers.gs);
-    console_flush();
     while (1)
         ;
 }
     while (1)
         ;
 }
+
+static char buf[4];
+
+static void
+__sdbg_breakpoint(const isr_param* param)
+{
+    gdbstub_loop(param);
+}
+
 void
 sdbg_init()
 {
 void
 sdbg_init()
 {
-    isrm_bindiv(INSTR_DEBUG, sdbg_loop); // #DB
-    isrm_bindiv(INSTR_BREAK, sdbg_loop); // #BRK
+    struct serial_dev* sdev = serial_get_avilable();
+
+    if (!sdev) {
+        kprintf(KERROR "no serial port available\n");
+        return;
+    }
+
+    kprintf("listening: %s\n", sdev->dev->name.value);
 
 
-    isrm_bindirq(COM1_IRQ, sdbg_loop);
+    serial_rwbuf_async(sdev, buf, 4, sdbg_serial_callback, SERIAL_RW_RX);
 }
\ No newline at end of file
 }
\ No newline at end of file
index cf58a9d982f3ea260e733a08eee8d6762f7ba48d..db45ed933b636cb6b4fa49ffbc67a356a1237344 100644 (file)
@@ -25,6 +25,10 @@ device_register_all()
         u32_t hash = devclass_hash(devdef->class);
         devdef->class.hash = hash;
 
         u32_t hash = devclass_hash(devdef->class);
         devdef->class.hash = hash;
 
+        if (!devdef->name) {
+            devdef->name = "<unspecified>";
+        }
+
         hashtable_hash_in(dev_registry, &devdef->hlist, hash);
         hashtable_hash_in(
           dev_byif, &devdef->hlist_if, DEV_IF(devdef->class.meta));
         hashtable_hash_in(dev_registry, &devdef->hlist, hash);
         hashtable_hash_in(
           dev_byif, &devdef->hlist_if, DEV_IF(devdef->class.meta));
@@ -150,14 +154,14 @@ __devdb_db_gonext(struct twimap* mapping)
 static void
 __devdb_twifs_lsdb(struct twimap* mapping)
 {
 static void
 __devdb_twifs_lsdb(struct twimap* mapping)
 {
-    char flags[32];
+    char flags[64];
     struct device_def* def = twimap_index(mapping, struct device_def*);
 
     int meta = def->class.meta;
     struct device_def* def = twimap_index(mapping, struct device_def*);
 
     int meta = def->class.meta;
-    ksnprintf(flags, 32, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta));
+    ksnprintf(flags, 64, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta));
 
     twimap_printf(mapping,
 
     twimap_printf(mapping,
-                  "%d:%d:%d %s (%s)\n",
+                  "%xh:%d:%d \"%s\" %s\n",
                   def->class.meta,
                   def->class.device,
                   def->class.variant,
                   def->class.meta,
                   def->class.device,
                   def->class.variant,
@@ -165,10 +169,18 @@ __devdb_twifs_lsdb(struct twimap* mapping)
                   flags);
 }
 
                   flags);
 }
 
+void
+__devdb_reset(struct twimap* map)
+{
+    map->index =
+      container_of(dev_registry_flat.next, struct device_def, dev_list);
+}
+
 static void
 devdb_twifs_plugin()
 {
     struct twimap* map = twifs_mapping(NULL, NULL, "devtab");
 static void
 devdb_twifs_plugin()
 {
     struct twimap* map = twifs_mapping(NULL, NULL, "devtab");
+    map->reset = __devdb_reset;
     map->read = __devdb_twifs_lsdb;
     map->go_next = __devdb_db_gonext;
 }
     map->read = __devdb_twifs_lsdb;
     map->go_next = __devdb_db_gonext;
 }
index b794334628ca696d4f44f0f8ab15722ac5fa5aaa..ae855ef52dcf51e80ed5f88d12c9e907b5622a6f 100644 (file)
@@ -1,4 +1,4 @@
-#include <klibc/stdio.h>
+
 #include <lunaix/device.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/twifs.h>
 #include <lunaix/device.h>
 #include <lunaix/fs.h>
 #include <lunaix/fs/twifs.h>
@@ -8,6 +8,11 @@
 #include <lunaix/syscall.h>
 #include <lunaix/syscall_utils.h>
 
 #include <lunaix/syscall.h>
 #include <lunaix/syscall_utils.h>
 
+#include <usr/lunaix/device.h>
+
+#include <klibc/stdio.h>
+#include <klibc/string.h>
+
 static DEFINE_LLIST(root_list);
 
 static volatile dev_t devid = 0;
 static DEFINE_LLIST(root_list);
 
 static volatile dev_t devid = 0;
@@ -202,26 +207,50 @@ device_getbyoffset(struct device* root_dev, int offset)
     return NULL;
 }
 
     return NULL;
 }
 
+static inline void
+device_populate_info(struct device* dev, struct dev_info* devinfo)
+{
+    devinfo->dev_id.meta = dev->class.meta;
+    devinfo->dev_id.device = dev->class.device;
+    devinfo->dev_id.variant = dev->class.variant;
+
+    if (!devinfo->dev_name.buf) {
+        return;
+    }
+
+    struct device_def* def = devdef_byclass(&dev->class);
+    size_t buflen = devinfo->dev_name.buf_len;
+
+    strncpy(devinfo->dev_name.buf, def->name, buflen);
+    devinfo->dev_name.buf[buflen - 1] = 0;
+}
+
 __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args)
 {
 __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args)
 {
-    int errno;
+    int errno = -1;
     struct v_fd* fd_s;
     struct v_fd* fd_s;
-    if ((errno = vfs_getfd(fd, &fd_s))) {
+    if ((errno &= vfs_getfd(fd, &fd_s))) {
         goto done;
     }
 
     struct device* dev = (struct device*)fd_s->file->inode->data;
     if (dev->magic != DEV_STRUCT_MAGIC) {
         goto done;
     }
 
     struct device* dev = (struct device*)fd_s->file->inode->data;
     if (dev->magic != DEV_STRUCT_MAGIC) {
-        errno = ENODEV;
+        errno &= ENODEV;
         goto done;
     }
 
         goto done;
     }
 
+    if (req == DEVIOIDENT) {
+        struct dev_info* devinfo = va_arg(args, struct dev_info*);
+        device_populate_info(dev, devinfo);
+        errno = 0;
+    }
+
     if (!dev->ops.exec_cmd) {
     if (!dev->ops.exec_cmd) {
-        errno = ENOTSUP;
+        errno &= ENOTSUP;
         goto done;
     }
 
         goto done;
     }
 
-    errno = dev->ops.exec_cmd(dev, req, args);
+    errno &= dev->ops.exec_cmd(dev, req, args);
 
 done:
     return DO_STATUS_OR_RETURN(errno);
 
 done:
     return DO_STATUS_OR_RETURN(errno);
index 3741ac9d07fe8ee5418917d9f107a4466b17df68..5ecddad57b00a6c70bd78dd3629b9cb4e505e957 100644 (file)
@@ -78,6 +78,16 @@ fifo_readone_async(struct fifo_buf* fbuf, u8_t* data)
     return 1;
 }
 
     return 1;
 }
 
+size_t
+fifo_readone(struct fifo_buf* fbuf, u8_t* data)
+{
+    mutex_lock(&fbuf->lock);
+    size_t retval = fifo_readone_async(fbuf, data);
+    mutex_unlock(&fbuf->lock);
+
+    return retval;
+}
+
 void
 fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr)
 {
 void
 fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr)
 {
@@ -105,6 +115,10 @@ fifo_write(struct fifo_buf* fbuf, void* data, size_t count)
 {
     size_t wr_count = 0, wr_pos = fbuf->wr_pos;
 
 {
     size_t wr_count = 0, wr_pos = fbuf->wr_pos;
 
+    if (!count) {
+        return 0;
+    }
+
     mutex_lock(&fbuf->lock);
 
     if (!fbuf->free_len) {
     mutex_lock(&fbuf->lock);
 
     if (!fbuf->free_len) {
index 7bfbf10620fe0b8bd6c453d67ddbff00b23b7052..6af1087be1859a7755b70c6c2e32f398e01490cb 100644 (file)
@@ -4,7 +4,16 @@
 void
 mutex_lock(mutex_t* mutex)
 {
 void
 mutex_lock(mutex_t* mutex)
 {
-    sem_wait(&mutex->sem);
+    if (atomic_load(&mutex->lk) && mutex->owner == __current->pid) {
+        atomic_fetch_add(&mutex->lk, 1);
+        return;
+    }
+
+    while (atomic_load(&mutex->lk)) {
+        sched_yieldk();
+    }
+
+    atomic_fetch_add(&mutex->lk, 1);
     mutex->owner = __current->pid;
 }
 
     mutex->owner = __current->pid;
 }
 
@@ -17,8 +26,8 @@ mutex_unlock(mutex_t* mutex)
 void
 mutex_unlock_for(mutex_t* mutex, pid_t pid)
 {
 void
 mutex_unlock_for(mutex_t* mutex, pid_t pid)
 {
-    if (mutex->owner != pid) {
+    if (mutex->owner != pid || !atomic_load(&mutex->lk)) {
         return;
     }
         return;
     }
-    sem_post(&mutex->sem);
+    atomic_fetch_sub(&mutex->lk, 1);
 }
\ No newline at end of file
 }
\ No newline at end of file
index 7045e36731cfc3db8adf5f68d6f099fa2ef244b8..caed3bc6f498a11a705c990d060aab2637d5081f 100644 (file)
@@ -5,6 +5,7 @@
 void
 pwait(waitq_t* queue)
 {
 void
 pwait(waitq_t* queue)
 {
+    assert(__current);
     // prevent race condition.
     cpu_disable_interrupt();
 
     // prevent race condition.
     cpu_disable_interrupt();
 
diff --git a/lunaix-os/kernel/peripheral/serial.c b/lunaix-os/kernel/peripheral/serial.c
deleted file mode 100644 (file)
index 8cdced6..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <sys/cpu.h>
-#include <lunaix/peripheral/serial.h>
-#include <lunaix/syslog.h>
-#include <sys/port_io.h>
-
-LOG_MODULE("UART")
-
-void
-serial_init_port(ptr_t port)
-{
-    // disable interrupt, use irq instead
-    port_wrbyte(COM_RIE(port), 0);
-
-    // baud rate config (DLAB = 1)
-    port_wrbyte(COM_RCLINE(port), 0x80);
-    port_wrbyte(COM_RRXTX(port), BAUD_9600);
-    port_wrbyte(COM_RIE(port), 0);
-
-    // transmission size = 7bits, no parity, 1 stop bits
-    port_wrbyte(COM_RCLINE(port), 0x2);
-
-    // rx trigger level = 14, clear rx/tx buffer, enable buffer
-    port_wrbyte(COM_RCFIFO(port), 0xcf);
-
-    port_wrbyte(COM_RCMODEM(port), 0x1e);
-
-    port_wrbyte(COM_RRXTX(port), 0xaa);
-
-    if (port_rdbyte(COM_RRXTX(port)) != 0xaa) {
-        kprintf(KWARN "port.%p: faulty\n", port);
-        return;
-    }
-
-    port_wrbyte(COM_RCMODEM(port), 0xf);
-    port_wrbyte(COM_RIE(port), 0x1);
-    kprintf("port.%p: ok\n", port);
-}
-
-void
-serial_init()
-{
-    cpu_disable_interrupt();
-    serial_init_port(SERIAL_COM1);
-    serial_init_port(SERIAL_COM2);
-    cpu_enable_interrupt();
-}
-
-char
-serial_rx_byte(ptr_t port)
-{
-    while (!(port_rdbyte(COM_RSLINE(port)) & 0x01))
-        ;
-
-    return port_rdbyte(COM_RRXTX(port));
-}
-
-void
-serial_rx_buffer(ptr_t port, char* data, size_t len)
-{
-    for (size_t i = 0; i < len; i++) {
-        data[i] = serial_rx_byte(port);
-    }
-}
-
-void
-serial_tx_byte(ptr_t port, char data)
-{
-    while (!(port_rdbyte(COM_RSLINE(port)) & 0x20))
-        ;
-
-    port_wrbyte(COM_RRXTX(port), data);
-}
-
-void
-serial_tx_buffer(ptr_t port, char* data, size_t len)
-{
-    for (size_t i = 0; i < len; i++) {
-        serial_tx_byte(port, data[i]);
-    }
-}
-
-void
-serial_clear_fifo(ptr_t port)
-{
-    port_wrbyte(COM_RIE(port), 0x0);
-    port_wrbyte(COM_RCFIFO(port), 0x00);
-
-    port_wrbyte(COM_RCFIFO(port), 0xcf);
-    port_wrbyte(COM_RIE(port), 0x1);
-}
-
-void
-serial_disable_irq(ptr_t port)
-{
-    port_wrbyte(COM_RIE(port), 0x0);
-}
-
-void
-serial_enable_irq(ptr_t port)
-{
-    port_wrbyte(COM_RIE(port), 0x1);
-}
\ No newline at end of file
index 4b430b5a15d801943b3244e9380b25768b6b82ee..93cc0207ef4819c648908eb2337e7d746b0ccee3 100644 (file)
@@ -100,11 +100,8 @@ init_platform()
 
     twifs_register_plugins();
 
 
     twifs_register_plugins();
 
-    // FIXME This 8025 serial should integrated into device layer
-    serial_init();
-
-    // debugger
-    sdbg_init();
+    // FIXME Re-design needed!!
+    // sdbg_init();
 
     // console
     console_start_flushing();
 
     // console
     console_start_flushing();
index 0bcb9b71213e015471405fcfee4dccffc4be1a80..46f4dd253ce00fbf9499e6e07f6947b5ca5008e6 100644 (file)
@@ -357,6 +357,7 @@ lxconsole_spawn_ttydev(struct device_def* devdef)
 }
 
 static struct device_def lxconsole_def = {
 }
 
 static struct device_def lxconsole_def = {
+    .name = "Lunaix Virtual Console",
     .class = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 0),
     .init = lxconsole_spawn_ttydev
 };
     .class = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 0),
     .init = lxconsole_spawn_ttydev
 };
diff --git a/lunaix-os/ksrc.excludes b/lunaix-os/ksrc.excludes
new file mode 100644 (file)
index 0000000..ca3e1a5
--- /dev/null
@@ -0,0 +1,2 @@
+kernel/debug/sdbg.c
+kernel/debug/gdbstub.c
\ No newline at end of file
diff --git a/lunaix-os/usr/cat/main.c b/lunaix-os/usr/cat/main.c
new file mode 100644 (file)
index 0000000..0a15f8c
--- /dev/null
@@ -0,0 +1,31 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define BUFSIZE 4096
+
+static char buffer[BUFSIZE];
+
+int
+main(int argc, const char* argv[])
+{
+    int fd = 0;
+    unsigned int size = 0;
+    for (int i = 1; i < argc; i++) {
+        fd = open(argv[i], FO_RDONLY);
+        if (fd < 0) {
+            printf("open failed: %s (error: %d)", argv[i], fd);
+            continue;
+        }
+
+        do {
+            size = read(fd, buffer, BUFSIZE);
+            write(stdout, buffer, size);
+        } while (size == BUFSIZE);
+
+        close(fd);
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/lunaix-os/usr/cat/makefile b/lunaix-os/usr/cat/makefile
new file mode 100644 (file)
index 0000000..33802bd
--- /dev/null
@@ -0,0 +1,21 @@
+define src_files
+       main.c
+endef
+
+obj_files := $(addsuffix .o,$(src_files))
+include_opt := $(addprefix -I,$(INCLUDES))
+
+out := $(BUILD_DIR)/bin
+
+%.c.o: %.c
+       $(call status_,CC,$<)
+       @$(CC) $(CFLAGS) $(include_opt) -c $< -o $@
+
+$(out)/$(BUILD_NAME): $(obj_files)
+       $(call status_,LD,$(@F))
+       @$(CC) -T $(LD_SCRIPT) -o $@ $< $(LIBC) $(LDFLAGS)
+
+all: $(out)/$(BUILD_NAME)
+
+clean:
+       @rm -f $(obj_files)
\ No newline at end of file
index 942a5e623ff4f07cad51a2a61aee7b6d78f3ab18..fa9c1c1f3ff20db324ef6334c25a5316d67cb043 100644 (file)
@@ -32,6 +32,7 @@ app-list := ls
 app-list += init
 app-list += signal_demo
 app-list += sh
 app-list += init
 app-list += signal_demo
 app-list += sh
+app-list += cat
 
 mkapp-list := $(addprefix app-, $(app-list))
 
 
 mkapp-list := $(addprefix app-, $(app-list))