From 8fce4520de1f257819b16f9253fa28dcdae743f4 Mon Sep 17 00:00:00 2001 From: Minep Date: Mon, 4 Sep 2023 00:38:06 +0100 Subject: [PATCH] feat: serial device interfacing feat: devzero feat: simple cat implementation fix: add default name for nameless device chore: general clean up --- lunaix-os/arch/i386/exceptions/interrupts.c | 6 +- .../arch/i386/exceptions/intr_routines.c | 1 - lunaix-os/hal/ahci/ahci.c | 2 +- lunaix-os/hal/char/devnull.c | 2 +- lunaix-os/hal/char/devzero.c | 35 +++ lunaix-os/hal/char/ps2kbd.c | 2 +- lunaix-os/hal/char/serial.c | 193 ++++++++++++++++ lunaix-os/hal/char/uart/16550.h | 211 ++++++++++++++++++ lunaix-os/hal/char/uart/16550_base.c | 96 ++++++++ lunaix-os/hal/char/uart/16550_pmio.c | 103 +++++++++ lunaix-os/hal/rng/rngx86.c | 2 +- lunaix-os/hal/rtc/mc146818a.c | 2 +- lunaix-os/includes/hal/serial.h | 81 +++++++ lunaix-os/includes/lunaix/device.h | 7 + lunaix-os/includes/lunaix/device_num.h | 7 +- lunaix-os/includes/lunaix/ds/fifo.h | 3 + lunaix-os/includes/lunaix/ds/mutex.h | 8 +- lunaix-os/includes/usr/lunaix/device.h | 24 ++ lunaix-os/includes/usr/lunaix/ioctl_defs.h | 6 +- lunaix-os/includes/usr/lunaix/serial.h | 12 + lunaix-os/kernel.mk | 7 +- lunaix-os/kernel/debug/gdbstub.c | 26 +-- lunaix-os/kernel/debug/sdbg.c | 94 +++----- lunaix-os/kernel/device/devdb.c | 18 +- lunaix-os/kernel/device/device.c | 41 +++- lunaix-os/kernel/ds/fifo.c | 14 ++ lunaix-os/kernel/ds/mutex.c | 15 +- lunaix-os/kernel/ds/waitq.c | 1 + lunaix-os/kernel/peripheral/serial.c | 102 --------- lunaix-os/kernel/proc0.c | 7 +- lunaix-os/kernel/tty/lxconsole.c | 1 + lunaix-os/ksrc.excludes | 2 + lunaix-os/usr/cat/main.c | 31 +++ lunaix-os/usr/cat/makefile | 21 ++ lunaix-os/usr/makefile | 1 + 35 files changed, 971 insertions(+), 213 deletions(-) create mode 100644 lunaix-os/hal/char/devzero.c create mode 100644 lunaix-os/hal/char/serial.c create mode 100644 lunaix-os/hal/char/uart/16550.h create mode 100644 lunaix-os/hal/char/uart/16550_base.c create mode 100644 lunaix-os/hal/char/uart/16550_pmio.c create mode 100644 lunaix-os/includes/hal/serial.h create mode 100644 lunaix-os/includes/usr/lunaix/device.h create mode 100644 lunaix-os/includes/usr/lunaix/serial.h delete mode 100644 lunaix-os/kernel/peripheral/serial.c create mode 100644 lunaix-os/ksrc.excludes create mode 100644 lunaix-os/usr/cat/main.c create mode 100644 lunaix-os/usr/cat/makefile diff --git a/lunaix-os/arch/i386/exceptions/interrupts.c b/lunaix-os/arch/i386/exceptions/interrupts.c index c45f961..5d4787a 100644 --- a/lunaix-os/arch/i386/exceptions/interrupts.c +++ b/lunaix-os/arch/i386/exceptions/interrupts.c @@ -1,7 +1,8 @@ +#include +#include #include #include -#include #include #include @@ -10,9 +11,6 @@ #include #include #include -#include - -#include LOG_MODULE("INTR") diff --git a/lunaix-os/arch/i386/exceptions/intr_routines.c b/lunaix-os/arch/i386/exceptions/intr_routines.c index 100df0b..d0b0d49 100644 --- a/lunaix-os/arch/i386/exceptions/intr_routines.c +++ b/lunaix-os/arch/i386/exceptions/intr_routines.c @@ -7,7 +7,6 @@ #include #include #include -#include #include diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index c20e21d..2b1176e 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -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), - .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 diff --git a/lunaix-os/hal/char/devnull.c b/lunaix-os/hal/char/devnull.c index 12bd007..0bdf99c 100644 --- a/lunaix-os/hal/char/devnull.c +++ b/lunaix-os/hal/char/devnull.c @@ -43,7 +43,7 @@ pdev_nulldev_init(struct device_def*) 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); diff --git a/lunaix-os/hal/char/devzero.c b/lunaix-os/hal/char/devzero.c new file mode 100644 index 0000000..d5f13c6 --- /dev/null +++ b/lunaix-os/hal/char/devzero.c @@ -0,0 +1,35 @@ +#include +#include + +#include + +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); diff --git a/lunaix-os/hal/char/ps2kbd.c b/lunaix-os/hal/char/ps2kbd.c index f59dcf3..d2be85d 100644 --- a/lunaix-os/hal/char/ps2kbd.c +++ b/lunaix-os/hal/char/ps2kbd.c @@ -575,7 +575,7 @@ ps2_issue_dev_cmd(char cmd, u16_t arg) } 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 }; diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c new file mode 100644 index 0000000..2c4a272 --- /dev/null +++ b/lunaix-os/hal/char/serial.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include + +#include + +#include + +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 index 0000000..a656575 --- /dev/null +++ b/lunaix-os/hal/char/uart/16550.h @@ -0,0 +1,211 @@ +#ifndef __LUNAIX_16550_H +#define __LUNAIX_16550_H + +#include +#include + +#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 index 0000000..4ae45d7 --- /dev/null +++ b/lunaix-os/hal/char/uart/16550_base.c @@ -0,0 +1,96 @@ +#include +#include + +#include + +#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 index 0000000..4342d98 --- /dev/null +++ b/lunaix-os/hal/char/uart/16550_pmio.c @@ -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 +#include + +#include + +#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 diff --git a/lunaix-os/hal/rng/rngx86.c b/lunaix-os/hal/rng/rngx86.c index bb069d7..af11802 100644 --- a/lunaix-os/hal/rng/rngx86.c +++ b/lunaix-os/hal/rng/rngx86.c @@ -39,7 +39,7 @@ pdev_randdev_init(struct device_def* devdef) } 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 }; diff --git a/lunaix-os/hal/rtc/mc146818a.c b/lunaix-os/hal/rtc/mc146818a.c index e918ffd..c36412a 100644 --- a/lunaix-os/hal/rtc/mc146818a.c +++ b/lunaix-os/hal/rtc/mc146818a.c @@ -216,7 +216,7 @@ rtc_init(struct device_def* devdef) } static struct device_def devrtc_mc146818 = { - .name = "rtc_mc146818", + .name = "MC146818 RTC", .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 index 0000000..b2fdf5e --- /dev/null +++ b/lunaix-os/includes/hal/serial.h @@ -0,0 +1,81 @@ +#ifndef __LUNAIX_SERIAL_H +#define __LUNAIX_SERIAL_H + +#include +#include +#include +#include +#include + +#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 */ diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index 52df8f0..cb2c294 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -92,6 +92,10 @@ struct device 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); @@ -181,6 +185,9 @@ device_create_byclass(struct devclass* class, struct hbucket* device_definitions_byif(int if_type); +struct device_def* +devdef_byclass(struct devclass* class); + void device_register_all(); diff --git a/lunaix-os/includes/lunaix/device_num.h b/lunaix-os/includes/lunaix/device_num.h index 58e9122..704c39b 100644 --- a/lunaix-os/includes/lunaix/device_num.h +++ b/lunaix-os/includes/lunaix/device_num.h @@ -49,9 +49,9 @@ 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_FN(meta) (((meta)&0xffff)) +#define DEV_FN(meta) (((meta) & 0xffff)) #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_BUS 0x5 +#define DEV_BUS 0x6 +#define DEV_SERIAL 0x7 #endif /* __LUNAIX_DEVICE_NUM_H */ diff --git a/lunaix-os/includes/lunaix/ds/fifo.h b/lunaix-os/includes/lunaix/ds/fifo.h index ecdbe5e..a8f5091 100644 --- a/lunaix-os/includes/lunaix/ds/fifo.h +++ b/lunaix-os/includes/lunaix/ds/fifo.h @@ -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(struct fifo_buf* fbuf, u8_t* data); + void fifo_set_rdptr(struct fifo_buf* fbuf, size_t rdptr); diff --git a/lunaix-os/includes/lunaix/ds/mutex.h b/lunaix-os/includes/lunaix/ds/mutex.h index 97101ef..162186c 100644 --- a/lunaix-os/includes/lunaix/ds/mutex.h +++ b/lunaix-os/includes/lunaix/ds/mutex.h @@ -1,25 +1,25 @@ #ifndef __LUNAIX_MUTEX_H #define __LUNAIX_MUTEX_H -#include "semaphore.h" #include +#include typedef struct mutex_s { - struct sem_t sem; + atomic_ulong lk; 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) { - return !atomic_load(&mutex->sem.counter); + return atomic_load(&mutex->lk); } void diff --git a/lunaix-os/includes/usr/lunaix/device.h b/lunaix-os/includes/usr/lunaix/device.h new file mode 100644 index 0000000..3045113 --- /dev/null +++ b/lunaix-os/includes/usr/lunaix/device.h @@ -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 */ diff --git a/lunaix-os/includes/usr/lunaix/ioctl_defs.h b/lunaix-os/includes/usr/lunaix/ioctl_defs.h index 9ca8cad..dd5709f 100644 --- a/lunaix-os/includes/usr/lunaix/ioctl_defs.h +++ b/lunaix-os/includes/usr/lunaix/ioctl_defs.h @@ -1,11 +1,13 @@ #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 IOARGNUM(req) ((req)&0xff) +#define IOARGNUM(req) ((req) & 0xff) + +#define DEVIOIDENT 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 index 0000000..7cdd74b --- /dev/null +++ b/lunaix-os/includes/usr/lunaix/serial.h @@ -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 */ diff --git a/lunaix-os/kernel.mk b/lunaix-os/kernel.mk index 5d64514..c5596f8 100644 --- a/lunaix-os/kernel.mk +++ b/lunaix-os/kernel.mk @@ -1,6 +1,8 @@ include os.mkinc include toolchain.mkinc +kexclusion = $(shell cat ksrc.excludes) + 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]")) +ksrc_files := $(filter-out $(kexclusion),$(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) - $(call status_,GEN,$@) + $(call status_,MOD,$@) @$(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 diff --git a/lunaix-os/kernel/debug/gdbstub.c b/lunaix-os/kernel/debug/gdbstub.c index 072b6a4..963e5ff 100644 --- a/lunaix-os/kernel/debug/gdbstub.c +++ b/lunaix-os/kernel/debug/gdbstub.c @@ -32,8 +32,8 @@ * SOFTWARE. */ +#include #include -#include #include #include @@ -74,6 +74,7 @@ enum GDB_REGISTER struct gdb_state { int signum; + struct serial_dev* sdev; 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) { - 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; } - 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) { - gdb_x86_serial_putchar(ch); + serial_rwbuf_sync(state->sdev, &ch, 1, SERIAL_RW_TX); return ch; } @@ -1281,7 +1273,9 @@ gdb_sys_putchar(struct gdb_state* state, int ch) 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; } /* diff --git a/lunaix-os/kernel/debug/sdbg.c b/lunaix-os/kernel/debug/sdbg.c index 42dc6c7..af33a45 100644 --- a/lunaix-os/kernel/debug/sdbg.c +++ b/lunaix-os/kernel/debug/sdbg.c @@ -1,75 +1,41 @@ -#include -#include +// FIXME Re-design needed!! + +#include #include -#include -#include -#include #include #include #include #include +#include + // #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; - } 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; - 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 @@ -98,15 +64,29 @@ sdbg_imm(const isr_param* param) param->registers.es, param->registers.fs, param->registers.gs); - console_flush(); while (1) ; } + +static char buf[4]; + +static void +__sdbg_breakpoint(const isr_param* param) +{ + gdbstub_loop(param); +} + 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 diff --git a/lunaix-os/kernel/device/devdb.c b/lunaix-os/kernel/device/devdb.c index cf58a9d..db45ed9 100644 --- a/lunaix-os/kernel/device/devdb.c +++ b/lunaix-os/kernel/device/devdb.c @@ -25,6 +25,10 @@ device_register_all() u32_t hash = devclass_hash(devdef->class); devdef->class.hash = hash; + if (!devdef->name) { + devdef->name = ""; + } + 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) { - char flags[32]; + char flags[64]; 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, - "%d:%d:%d %s (%s)\n", + "%xh:%d:%d \"%s\" %s\n", def->class.meta, def->class.device, def->class.variant, @@ -165,10 +169,18 @@ __devdb_twifs_lsdb(struct twimap* mapping) 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"); + map->reset = __devdb_reset; map->read = __devdb_twifs_lsdb; map->go_next = __devdb_db_gonext; } diff --git a/lunaix-os/kernel/device/device.c b/lunaix-os/kernel/device/device.c index b794334..ae855ef 100644 --- a/lunaix-os/kernel/device/device.c +++ b/lunaix-os/kernel/device/device.c @@ -1,4 +1,4 @@ -#include + #include #include #include @@ -8,6 +8,11 @@ #include #include +#include + +#include +#include + 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; } +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) { - int errno; + int errno = -1; 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) { - errno = ENODEV; + errno &= ENODEV; 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) { - errno = ENOTSUP; + errno &= ENOTSUP; 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); diff --git a/lunaix-os/kernel/ds/fifo.c b/lunaix-os/kernel/ds/fifo.c index 3741ac9..5ecddad 100644 --- a/lunaix-os/kernel/ds/fifo.c +++ b/lunaix-os/kernel/ds/fifo.c @@ -78,6 +78,16 @@ fifo_readone_async(struct fifo_buf* fbuf, u8_t* data) 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) { @@ -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; + if (!count) { + return 0; + } + mutex_lock(&fbuf->lock); if (!fbuf->free_len) { diff --git a/lunaix-os/kernel/ds/mutex.c b/lunaix-os/kernel/ds/mutex.c index 7bfbf10..6af1087 100644 --- a/lunaix-os/kernel/ds/mutex.c +++ b/lunaix-os/kernel/ds/mutex.c @@ -4,7 +4,16 @@ 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; } @@ -17,8 +26,8 @@ mutex_unlock(mutex_t* mutex) void mutex_unlock_for(mutex_t* mutex, pid_t pid) { - if (mutex->owner != pid) { + if (mutex->owner != pid || !atomic_load(&mutex->lk)) { return; } - sem_post(&mutex->sem); + atomic_fetch_sub(&mutex->lk, 1); } \ No newline at end of file diff --git a/lunaix-os/kernel/ds/waitq.c b/lunaix-os/kernel/ds/waitq.c index 7045e36..caed3bc 100644 --- a/lunaix-os/kernel/ds/waitq.c +++ b/lunaix-os/kernel/ds/waitq.c @@ -5,6 +5,7 @@ void pwait(waitq_t* queue) { + assert(__current); // 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 index 8cdced6..0000000 --- a/lunaix-os/kernel/peripheral/serial.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include - -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 diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 4b430b5..93cc020 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -100,11 +100,8 @@ init_platform() 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(); diff --git a/lunaix-os/kernel/tty/lxconsole.c b/lunaix-os/kernel/tty/lxconsole.c index 0bcb9b7..46f4dd2 100644 --- a/lunaix-os/kernel/tty/lxconsole.c +++ b/lunaix-os/kernel/tty/lxconsole.c @@ -357,6 +357,7 @@ lxconsole_spawn_ttydev(struct device_def* devdef) } static struct device_def lxconsole_def = { + .name = "Lunaix Virtual Console", .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 index 0000000..ca3e1a5 --- /dev/null +++ b/lunaix-os/ksrc.excludes @@ -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 index 0000000..0a15f8c --- /dev/null +++ b/lunaix-os/usr/cat/main.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +#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 index 0000000..33802bd --- /dev/null +++ b/lunaix-os/usr/cat/makefile @@ -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 diff --git a/lunaix-os/usr/makefile b/lunaix-os/usr/makefile index 942a5e6..fa9c1c1 100644 --- a/lunaix-os/usr/makefile +++ b/lunaix-os/usr/makefile @@ -32,6 +32,7 @@ app-list := ls app-list += init app-list += signal_demo app-list += sh +app-list += cat mkapp-list := $(addprefix app-, $(app-list)) -- 2.27.0