feat: standard vga support (mode switching, framebuffer remapping)
authorMinep <lunaixsky@qq.com>
Sat, 21 Oct 2023 21:40:52 +0000 (22:40 +0100)
committerMinep <lunaixsky@qq.com>
Sat, 21 Oct 2023 21:40:52 +0000 (22:40 +0100)
feat: better tty/term abstraction
feat: mask on pci device id to allow driver do fussy device matching
refactor: the variant field of device id is now to be the instance number
chore: clean up and re-formatting

49 files changed:
lunaix-os/.vscode/c_cpp_properties.json
lunaix-os/arch/i386/includes/sys/cpu.h
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/char/devnull.c
lunaix-os/hal/char/devzero.c
lunaix-os/hal/char/ps2kbd.c
lunaix-os/hal/char/serial.c
lunaix-os/hal/char/uart/16550_pmio.c
lunaix-os/hal/gfxa/vga/vga.c [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga.h [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga_mmio_ops.c [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga_pci.c [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga_pmio_ops.c [new file with mode: 0644]
lunaix-os/hal/pci.c
lunaix-os/hal/rng/rngx86.c
lunaix-os/hal/rtc/hwrtc.c
lunaix-os/hal/rtc/mc146818a.c
lunaix-os/hal/term/lcntls/ansi_cntl.c [new file with mode: 0644]
lunaix-os/hal/term/term.c [new file with mode: 0644]
lunaix-os/hal/timer/apic_timer.c
lunaix-os/hal/timer/hwtimer.c
lunaix-os/includes/hal/acpi/acpi.h
lunaix-os/includes/hal/pci.h
lunaix-os/includes/hal/serial.h
lunaix-os/includes/hal/term.h [new file with mode: 0644]
lunaix-os/includes/lunaix/compiler.h
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/device_num.h
lunaix-os/includes/usr/lunaix/device.h
lunaix-os/includes/usr/lunaix/ioctl_defs.h
lunaix-os/includes/usr/lunaix/types.h
lunaix-os/kernel/block/block.c
lunaix-os/kernel/device/devdb.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/device/input.c
lunaix-os/kernel/fs/pcache.c
lunaix-os/kernel/fs/probe_boot.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/kinit.c
lunaix-os/kernel/kprintf.c
lunaix-os/kernel/mm/cow.c [deleted file]
lunaix-os/kernel/mm/vmm.c
lunaix-os/kernel/process/taskfs.c
lunaix-os/kernel/tty/lxconsole.c
lunaix-os/makefile
lunaix-os/makeinc/qemu.mkinc
lunaix-os/usr/init/init.c
lunaix-os/usr/sh/sh.c
lunaix-os/usr/stat/main.c

index a2de1fb296041e62441a555da06a236594d7735d..3718f2b79c4963a1e235913610544496168ce8aa 100644 (file)
@@ -15,7 +15,7 @@
                 "-include flags.h"
             ],
             "defines": [],
-            "compilerPath": "${HOME}/opt/cross-compiler/bin/i686-elf-gcc",
+            "compilerPath": "${HOME}/opt/i686-gcc-12/bin/i686-elf-gcc",
             "cStandard": "gnu99",
             "intelliSenseMode": "gcc-x86"
         }
index 3289522af918840f3172ca4fe275049c86bb5483..78faf38f84aaa683bd7614b5b1a0e4f88b501155 100644 (file)
@@ -89,7 +89,7 @@ cpu_chvmspace(u32_t val)
 }
 
 /**
- * @brief Flush TLB
+ * @brief Flush a certain TLB record
  *
  * @return u32_t
  */
@@ -99,6 +99,10 @@ cpu_flush_page(ptr_t va)
     asm volatile("invlpg (%0)" ::"r"(va) : "memory");
 }
 
+/**
+ * @brief Flush entire TLB
+ *
+ */
 static inline void
 cpu_flush_vmspace()
 {
@@ -125,6 +129,11 @@ cpu_wait()
     asm("hlt");
 }
 
+/**
+ * @brief Read exeception address
+ *
+ * @return ptr_t
+ */
 static inline ptr_t
 cpu_ldeaddr()
 {
index 220038ac6d112602ceb17831117ac638f7f0ce3a..8794baba37684d43fd4f460918dd0bf6a2e480ce 100644 (file)
@@ -31,7 +31,7 @@
 #define HBA_CLB_SIZE 1024
 
 #define HBA_MY_IE (HBA_PxINTR_DHR | HBA_PxINTR_TFE | HBA_PxINTR_OF)
-#define AHCI_DEVCLASS DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA, 0)
+#define AHCI_DEVCLASS DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA)
 
 // #define DO_HBA_FULL_RESET
 
@@ -444,10 +444,9 @@ achi_register_ops(struct hba_port* port)
 
 static struct pci_device_def ahcidef = {
     .dev_class = AHCI_HBA_CLASS,
-    .dev_vendor = PCI_ID_ANY,
-    .dev_id = PCI_ID_ANY,
-    .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA, 0),
+    .ident_mask = 0x0,
+    .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
                 .name = "Serial ATA Controller",
                 .init_for = ahci_driver_init }
 };
-EXPORT_DEVICE(ahci, &ahcidef.devdef, load_on_demand);
\ No newline at end of file
+EXPORT_DEVICE(ahci, &ahcidef.devdef, load_pci_probe);
\ No newline at end of file
index 5d0aef5e6f72639dea3f8db0237ce686a2c5b85d..9806dc0359ec953f0573d7f2459234e854350227 100644 (file)
@@ -32,18 +32,20 @@ __null_rd(struct device* dev, void* buf, size_t offset, size_t len)
 static int
 pdev_nulldev_init(struct device_def* def)
 {
-    struct device* devnull = device_addseq(NULL, &def->class, NULL, "null");
+    struct device* devnull = device_allocseq(NULL, NULL);
     devnull->ops.write_page = __null_wr_pg;
     devnull->ops.write = __null_wr;
     devnull->ops.read_page = __null_rd_pg;
     devnull->ops.read = __null_rd;
 
+    device_register(devnull, &def->class, "null");
+
     return 0;
 }
 
 static struct device_def devnull_def = {
     .name = "null",
-    .class = DEVCLASS(DEVIF_NON, DEVFN_PSEUDO, DEV_BUILTIN, 0),
+    .class = DEVCLASSV(DEVIF_NON, DEVFN_PSEUDO, DEV_NULL, DEV_BUILTIN_NULL),
     .init = pdev_nulldev_init
 };
 EXPORT_DEVICE(nulldev, &devnull_def, load_earlystage);
index cd4a6ebd817a7d4024b6535e757d4c698c3e0b1f..f579047347cfc03f300b6edd7580eb4d49a541cc 100644 (file)
@@ -20,16 +20,18 @@ __zero_rd(struct device* dev, void* buf, size_t offset, size_t len)
 static int
 pdev_zerodev_init(struct device_def* def)
 {
-    struct device* devzero = device_addseq(NULL, &def->class, NULL, "zero");
+    struct device* devzero = device_allocseq(NULL, NULL);
     devzero->ops.read_page = __zero_rd_pg;
     devzero->ops.read = __zero_rd;
 
+    device_register(devzero, &def->class, "zero");
+
     return 0;
 }
 
 static struct device_def devzero_def = {
     .name = "zero",
-    .class = DEVCLASS(DEVIF_NON, DEVFN_PSEUDO, DEV_BUILTIN, 1),
+    .class = DEVCLASSV(DEVIF_NON, DEVFN_PSEUDO, DEV_ZERO, DEV_BUILTIN_ZERO),
     .init = pdev_zerodev_init
 };
 EXPORT_DEVICE(zerodev, &devzero_def, load_earlystage);
index 77568918fefa81669cec947f222dccae8b70ae2a..c86350bc190576158d3b615b63f948838e8dda25 100644 (file)
@@ -576,7 +576,7 @@ ps2_issue_dev_cmd(char cmd, u16_t arg)
 
 static struct device_def devrtc_i8042kbd = {
     .name = "i8042 Keyboard",
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_INPUT, DEV_X86LEGACY, 0),
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_INPUT, DEV_KBD),
     .init = ps2_kbd_init
 };
 EXPORT_DEVICE(i8042_kbd, &devrtc_i8042kbd, load_timerstage);
index 9297136a5b02a580862de8ef4c46effce27c7a07..ffe9acb5460581f92e75403e272425eeeda65a88 100644 (file)
@@ -40,11 +40,11 @@ serial_end_xmit(struct serial_dev* sdev, size_t len)
 int
 serial_readone_nowait(struct serial_dev* sdev, u8_t* val)
 {
-    mutex_lock(&sdev->lock);
+    device_lock(sdev->dev);
 
     int rd_len = fifo_readone(&sdev->rxbuf, val);
 
-    mutex_unlock(&sdev->lock);
+    device_unlock(sdev->dev);
 
     return rd_len;
 }
@@ -52,26 +52,26 @@ serial_readone_nowait(struct serial_dev* sdev, u8_t* val)
 void
 serial_readone(struct serial_dev* sdev, u8_t* val)
 {
-    mutex_lock(&sdev->lock);
+    device_lock(sdev->dev);
 
     while (!fifo_readone(&sdev->rxbuf, val)) {
         pwait(&sdev->wq_rxdone);
     }
 
-    mutex_unlock(&sdev->lock);
+    device_unlock(sdev->dev);
 }
 
 size_t
 serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len)
 {
-    mutex_lock(&sdev->lock);
+    device_lock(sdev->dev);
 
     size_t rdlen;
     while (!(rdlen = fifo_read(&sdev->rxbuf, buf, len))) {
         pwait(&sdev->wq_rxdone);
     }
 
-    mutex_unlock(&sdev->lock);
+    device_unlock(sdev->dev);
 
     return rdlen;
 }
@@ -79,11 +79,11 @@ 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)
 {
-    mutex_lock(&sdev->lock);
+    device_lock(sdev->dev);
 
     int rdlen = fifo_read(&sdev->rxbuf, buf, len);
 
-    mutex_unlock(&sdev->lock);
+    device_unlock(sdev->dev);
 
     return rdlen;
 }
@@ -91,7 +91,7 @@ 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)
 {
-    mutex_lock(&sdev->lock);
+    device_lock(sdev->dev);
 
     if (sdev->write(sdev, buf, len) == RXTX_DONE) {
         goto done;
@@ -101,7 +101,7 @@ serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len)
 
 done:
     int rdlen = sdev->wr_len;
-    mutex_unlock(&sdev->lock);
+    device_unlock(sdev->dev);
 
     return rdlen;
 }
@@ -109,12 +109,12 @@ done:
 int
 serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
 {
-    mutex_lock(&sdev->lock);
+    device_lock(sdev->dev);
 
     sdev->write(sdev, buf, len);
     int rdlen = sdev->wr_len;
 
-    mutex_unlock(&sdev->lock);
+    device_unlock(sdev->dev);
 
     return rdlen;
 }
@@ -161,8 +161,7 @@ struct serial_dev*
 serial_create(struct devclass* class)
 {
     struct serial_dev* sdev = valloc(sizeof(struct serial_dev));
-    struct device* dev =
-      device_addseq(NULL, class, sdev, "ttyS%d", serial_idx++);
+    struct device* dev = device_allocseq(NULL, sdev);
     dev->ops.read = __serial_read;
     dev->ops.read_page = __serial_read_page;
     dev->ops.write = __serial_write;
@@ -178,6 +177,9 @@ serial_create(struct devclass* class)
     llist_append(&serial_devs, &sdev->sdev_list);
     // llist_init_head(&sdev->cmds);
 
+    class->variant++;
+    device_register(dev, class, "ttyS%d", class->variant);
+
     return sdev;
 }
 
@@ -187,7 +189,7 @@ serial_get_avilable()
     struct serial_dev *pos, *n;
     llist_for_each(pos, n, &serial_devs, sdev_list)
     {
-        if (!mutex_on_hold(&pos->lock)) {
+        if (!device_locked(pos->dev)) {
             return pos;
         }
     }
index ed3a6186504b2210f6dcb7059145d218a143add2..9910051fa8f84d3dcbb8249b8d347c27439fc3a6 100644 (file)
@@ -97,7 +97,7 @@ upiom_init(struct device_def* def)
 }
 
 static struct device_def uart_pmio_def = {
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_SERIAL, 0),
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_UART16550),
     .name = "16550 Generic UART (I/O)",
     .init = upiom_init
 };
diff --git a/lunaix-os/hal/gfxa/vga/vga.c b/lunaix-os/hal/gfxa/vga/vga.c
new file mode 100644 (file)
index 0000000..08bc54b
--- /dev/null
@@ -0,0 +1,260 @@
+/**
+ * @file ga_vtm.c
+ * @author Lunaixsky (lunaxisky@qq.com)
+ * @brief video graphic adapter - text mode with simpiled ansi color code
+ * @version 0.1
+ * @date 2023-10-06
+ *
+ * @copyright Copyright (c) 2023
+ *
+ */
+
+#include <lunaix/compiler.h>
+#include <lunaix/device.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+
+#include <sys/cpu.h>
+
+#include "vga.h"
+
+#define ALL_FIELDS -1
+
+struct vga*
+vga_new_state(ptr_t reg_base, ptr_t fb, ptr_t alloced_fbsz)
+{
+    struct vga* state = valloc(sizeof(struct vga));
+    *state =
+      (struct vga){ .fb = fb, .fb_sz = alloced_fbsz, .io_off = reg_base };
+
+    return state;
+}
+
+void
+vga_config_rect(struct vga* state,
+                size_t width,
+                size_t height,
+                size_t freq,
+                int d9)
+{
+    size_t pel_sz = 8 + !!d9;
+
+    state->crt.h_cclk = width / pel_sz;
+    state->crt.v_cclk = height;
+    state->crt.freq = freq;
+
+    state->crt.pel_dot = pel_sz;
+}
+
+#define RETRACE_GAP 4
+
+static void
+vga_crt_update(struct vga* state)
+{
+#define R_BIT9(x, l) ((((x) & (1 << 9)) >> 9) << (l))
+#define R_BIT8(x, l) ((((x) & (1 << 8)) >> 8) << (l))
+    struct vga_regops* reg = &state->reg_ops;
+
+    u32_t hdisp = state->crt.h_cclk;
+    u32_t vdisp = state->crt.v_cclk;
+    u32_t hdisp_end = hdisp - 1;
+    u32_t vdisp_end = vdisp - 1;
+
+    // VGA spec said so
+    u32_t htotal = hdisp - 5;
+    u32_t vtotal = vdisp - 5;
+
+    u32_t hsync_end = (hdisp + RETRACE_GAP) & 0b11111;
+    u32_t vsync_end = (vdisp + RETRACE_GAP) & 0b01111;
+
+    reg->write(state, VGA_CRX, VGA_CR11, 0, 1 << 7);
+    reg->write(state, VGA_CRX, VGA_CR03, 1 << 7, 1 << 7);
+
+    // set values of first 8 registers. Note, we prefer no H_BLANK region
+    u32_t crt_regs[VGA_CRCOUNT] = {
+        [VGA_CR00] = htotal, [VGA_CR01] = hdisp - 1,
+        [VGA_CR02] = 0xff,   [VGA_CR03] = (1 << 7) | 31,
+        [VGA_CR04] = hdisp,  [VGA_CR05] = hsync_end,
+        [VGA_CR06] = vtotal
+    };
+
+    // overflow: bit 9/8 of vtotal
+    crt_regs[VGA_CR07] = R_BIT9(vtotal, 5) | R_BIT8(vtotal, 0);
+    // overflow: bit 9/8 of vdisp_end
+    crt_regs[VGA_CR07] |= R_BIT9(vdisp_end, 6) | R_BIT8(vdisp_end, 1);
+    // overflow: bit 9/8 of vsync_start
+    crt_regs[VGA_CR07] |= R_BIT9(vdisp, 7) | R_BIT8(vdisp, 2);
+
+    crt_regs[VGA_CR10] = vdisp; // vsync_start
+
+    // V_SYNC_END, Disable Vertical INTR (GD5446)
+    crt_regs[VGA_CR11] = vsync_end | (1 << 5);
+    crt_regs[VGA_CR12] = vdisp_end; // vdisp_end
+
+    // no V_BLANK region (v blank start/end = 0x3ff)
+    crt_regs[VGA_CR15] = 0xff;
+    crt_regs[VGA_CR16] = 0xff;
+    crt_regs[VGA_CR09] |= (1 << 5);
+    crt_regs[VGA_CR07] |= (1 << 3);
+
+    // no split line (0x3FF)
+    crt_regs[VGA_CR18] = 0xff;
+    crt_regs[VGA_CR07] |= (1 << 4);
+    crt_regs[VGA_CR09] |= (1 << 6);
+
+    // disable text cursor by default
+    crt_regs[VGA_CR0A] = (1 << 5);
+    // CRB: text cusor end, 0x00
+    // CRE-CRF: text cusor location, cleared, 0x00
+
+    // CRC-CRD: screen start address(lo/hi): 0x00, 0x00
+    //  i.e., screen content start at the beginning of framebuffer
+
+    if (!(state->options & VGA_MODE_GFX)) {
+        // AN Mode, each char heights 16 scan lines
+        crt_regs[VGA_CR09] |= 0xf;
+    } else {
+        // GFX Mode, individual scanline, no repeat
+    }
+
+    // framebuffer: 16bit granule
+    u32_t divsor = 2 * 2;
+    if (state->lut.len == 256) {
+        // if 8 bit color is used, 2 pixels per granule
+        divsor *= 2;
+    } else if ((state->options & VGA_MODE_GFX)) {
+        // otherwise (gfx mode), 4 pixels per granule
+        divsor *= 4;
+    } // AN mode, one granule per character
+    crt_regs[VGA_CR13] = (hdisp * state->crt.pel_dot) / divsor;
+
+    // Timing En, Word Mode, Address Warp,
+    crt_regs[VGA_CR17] = (0b10100011);
+
+    reg->set_seq(state, VGA_CRX, 0, crt_regs, VGA_CRCOUNT);
+}
+
+void
+vga_update_palette(struct vga* state)
+{
+    state->reg_ops.set_dac_palette(state);
+
+    u32_t index[16];
+    u32_t clr_len = MIN(state->lut.len, 16);
+    for (size_t i = 0; i < clr_len; i++) {
+        index[i] = i;
+    }
+
+    state->reg_ops.set_seq(state, VGA_ARX, 0, index, clr_len);
+}
+
+void
+vga_reload_config(struct vga* state)
+{
+    cpu_disable_interrupt();
+
+    struct vga_regops* reg = &state->reg_ops;
+
+    u32_t color = state->lut.len;
+    assert_msg((color == 2 || color == 4 || color == 16 || color == 256),
+               "invalid color depth");
+
+    if (!(state->options & VGA_MODE_GFX)) {
+        assert(color < 256);
+    }
+
+    // estimate actual fb size
+    u32_t dpc_sq = state->crt.pel_dot;
+    u32_t total_px = state->crt.h_cclk * state->crt.v_cclk;
+    if ((state->options & VGA_MODE_GFX)) {
+        total_px *= dpc_sq;
+        total_px = total_px / (1 + (color < 256));
+    } else {
+        total_px = total_px * 2;
+    }
+
+    assert(state->fb_sz >= total_px);
+    state->fb_sz = total_px;
+
+    reg->write(state, VGA_SRX, VGA_SR00, 0x0, ALL_FIELDS);
+
+    // RAM Enable, I/OAS
+    u32_t clk_f = state->crt.h_cclk * state->crt.v_cclk * state->crt.freq;
+    u32_t misc = 0b11;
+    clk_f = (clk_f * dpc_sq) / 1000000;
+
+    assert(clk_f && clk_f <= 28);
+
+    // require 28 MHz clock
+    if (clk_f > 25) {
+        misc |= 0b01 << 2;
+    }
+    // 25 MHz clock: 0b00 << 2
+
+    reg->write(state, VGA_MISCX, 0, misc, 0b1111);
+
+    // SEQN_CLK: shift every CCLK, DCLK passthrough, 8/9 DCLK
+    u32_t d89 = (state->crt.pel_dot != 9);
+    reg->write(state, VGA_SRX, VGA_SR01, d89, ALL_FIELDS);
+
+    // GR0-4
+    u32_t gr_regs[] = { 0, 0, 0, 0, 0 };
+    reg->set_seq(state, VGA_GRX, 0, gr_regs, 5);
+
+    // Setup CRT
+    vga_crt_update(state);
+
+    if ((state->options & VGA_MODE_GFX)) { // GFX MODE
+        // GFX mode, check if 8 bit color depth is required
+        u32_t c256 = (color == 256);
+        reg->write(state, VGA_ARX, VGA_AR10, 1 | (c256 << 6), ALL_FIELDS);
+
+        // All 4 maps enabled, chain 4 mode
+        reg->write(state, VGA_SRX, VGA_SR02, 0b1111, ALL_FIELDS);
+
+        // Chain-4, Odd/Even, Extended Memory
+        reg->write(state, VGA_SRX, VGA_SR04, 0b1010, ALL_FIELDS);
+
+        // check 256 color mode, RdM0, WrM0
+        reg->write(
+          state, VGA_GRX, VGA_GR05, (c256 << 6) | (1 << 4), ALL_FIELDS);
+
+        // Legacy GFX FB: 0xA000, GFX mode
+        reg->write(state, VGA_GRX, VGA_GR06, 0b0011, ALL_FIELDS);
+
+    } else { // AN MOODE
+        // Only map 0,1 enabled, (ascii and attribute)
+        reg->write(state, VGA_SRX, VGA_SR02, 0b0011, ALL_FIELDS);
+
+        // Character (AN) mode
+        reg->write(state, VGA_ARX, VGA_AR10, 0, ALL_FIELDS);
+
+        // Extended Memory
+        reg->write(state, VGA_SRX, VGA_SR04, 0b0010, ALL_FIELDS);
+
+        // Shift Reg, RdM0, WrM0
+        reg->write(state, VGA_GRX, VGA_GR05, (1 << 5), ALL_FIELDS);
+
+        // Legacy CGA FB: 0xB800, AN mode
+        reg->write(state, VGA_GRX, VGA_GR06, 0b1100, 0b1111);
+    }
+
+    // all planes not involved in color compare
+    reg->write(state, VGA_GRX, VGA_GR07, 0, ALL_FIELDS);
+    // No rotate, no bit ops with latched px
+    reg->write(state, VGA_GRX, VGA_GR03, 0, ALL_FIELDS);
+
+    // Load default bit mask
+    reg->write(state, VGA_GRX, VGA_GR08, 0xff, ALL_FIELDS);
+
+    reg->write(state, VGA_ARX, VGA_AR12, 0xf, ALL_FIELDS);
+    reg->write(state, VGA_ARX, VGA_AR11, 0b100, ALL_FIELDS);
+    reg->write(state, VGA_ARX, VGA_AR13, 0, ALL_FIELDS);
+    reg->write(state, VGA_ARX, VGA_AR14, 0, ALL_FIELDS);
+
+    vga_update_palette(state);
+
+    reg->write(state, VGA_SRX, VGA_SR00, 0x3, ALL_FIELDS);
+
+    cpu_enable_interrupt();
+}
diff --git a/lunaix-os/hal/gfxa/vga/vga.h b/lunaix-os/hal/gfxa/vga/vga.h
new file mode 100644 (file)
index 0000000..86afe4e
--- /dev/null
@@ -0,0 +1,232 @@
+#ifndef __LUNAIX_VGA_H
+#define __LUNAIX_VGA_H
+
+#include <lunaix/types.h>
+
+/* -- Attribute Controller -- */
+
+#define VGA_ARX 0
+// Attribute Mode Control Register
+#define VGA_AR10 0x10
+
+// Overscan Color Register
+#define VGA_AR11 0x11
+
+// Color Plane Enable Register
+#define VGA_AR12 0x12
+
+// Horizontal Pixel Panning Register
+#define VGA_AR13 0x13
+
+// Color Select Register
+#define VGA_AR14 0x14
+
+/* -- Sequencer -- */
+
+#define VGA_SRX 1
+// Reset Register
+#define VGA_SR00 0x00
+
+// Clocking Mode Register
+#define VGA_SR01 0x01
+
+// Map Mask Register
+#define VGA_SR02 0x02
+
+// Character Map Select Register
+#define VGA_SR03 0x03
+
+// Sequencer Memory Mode Register
+#define VGA_SR04 0x04
+
+/* -- GFX Controller -- */
+
+#define VGA_GRX 2
+// Set/Reset Register
+#define VGA_GR00 0x00
+
+// Enable Set/Reset Register
+#define VGA_GR01 0x01
+
+// Color Compare Register
+#define VGA_GR02 0x02
+
+// Data Rotate Register
+#define VGA_GR03 0x03
+
+// Read Map Select Register
+#define VGA_GR04 0x04
+
+// Graphics Mode Register
+#define VGA_GR05 0x05
+
+// Miscellaneous Graphics Register
+#define VGA_GR06 0x06
+
+// Color Don't Care Register
+#define VGA_GR07 0x07
+
+// Bit Mask Register
+#define VGA_GR08 0x08
+
+/* -- CRT Controller -- */
+
+#define VGA_CRX 3
+
+// Horizontal Total Register
+#define VGA_CR00 0x00
+
+// End Horizontal Display Register
+#define VGA_CR01 0x01
+
+// Start Horizontal Blanking Register
+#define VGA_CR02 0x02
+
+// End Horizontal Blanking Register
+#define VGA_CR03 0x03
+
+// Start Horizontal Retrace Register
+#define VGA_CR04 0x04
+
+// End Horizontal Retrace Register
+#define VGA_CR05 0x05
+
+// Vertical Total Register
+#define VGA_CR06 0x06
+
+// Overflow Register
+#define VGA_CR07 0x07
+
+// Preset Row Scan Register
+#define VGA_CR08 0x08
+
+// Maximum Scan Line Register
+#define VGA_CR09 0x09
+
+// Cursor Start Register
+#define VGA_CR0A 0x0A
+
+// Cursor End Register
+#define VGA_CR0B 0x0B
+
+// Start Address High Register
+#define VGA_CR0C 0x0C
+
+// Start Address Low Register
+#define VGA_CR0D 0x0D
+
+// Cursor Location High Register
+#define VGA_CR0E 0x0E
+
+// Cursor Location Low Register
+#define VGA_CR0F 0x0F
+
+// Vertical Retrace Start Register
+#define VGA_CR10 0x10
+
+// Vertical Retrace End Register
+#define VGA_CR11 0x11
+
+// Vertical Display End Register
+#define VGA_CR12 0x12
+
+// Offset Register
+#define VGA_CR13 0x13
+
+// Underline Location Register
+#define VGA_CR14 0x14
+
+// Start Vertical Blanking Register
+#define VGA_CR15 0x15
+
+// End Vertical Blanking
+#define VGA_CR16 0x16
+
+// CRTC Mode Control Register
+#define VGA_CR17 0x17
+
+// Line Compare Register
+#define VGA_CR18 0x18
+#define VGA_CRCOUNT 0x19
+
+/* -- Digital-Analogue Converter -- */
+
+// DAC register
+#define VGA_DACX 4
+
+// DAC Data Register
+#define VGA_DAC1 0x3C9
+
+// DAC State Register
+#define VGA_DAC2 0x3C7
+
+#define VGA_MISCX 5
+#define VGA_STATX 6
+
+#define VGA_REG_X 0
+#define VGA_REG_D 1
+
+#define VGA_MODE_GFX (0b0001)
+
+struct vga;
+
+struct vga_regops
+{
+    u32_t (*read)(struct vga*, u32_t type, u32_t index, u32_t mask);
+    void (*write)(struct vga*, u32_t type, u32_t index, u32_t val, u32_t mask);
+    void (
+      *set_seq)(struct vga*, u32_t type, size_t off, u32_t* seq, size_t len);
+    void (*set_dac_palette)(struct vga*);
+};
+
+struct vga
+{
+    ptr_t io_off;
+    ptr_t fb;
+    size_t fb_sz;
+    u32_t options;
+
+    struct
+    {
+        size_t h_cclk;  // horizontal char clock count;
+        size_t v_cclk;  // vertical char clock count;
+        size_t pel_dot; // pixel per dot clock
+        size_t freq;
+        size_t fb_off;
+    } crt;
+
+    struct
+    {
+        u32_t* colors;
+        u32_t len;
+    } lut;
+
+    struct vga_regops reg_ops;
+};
+
+/**
+ * @brief Create a new VGA state
+ *
+ * @param reg_base base address for register accessing
+ * @param fb address to frame buffer
+ * @param fb_sz size of usable frame buffer
+ * @return struct vga* VGA state
+ */
+struct vga*
+vga_new_state(ptr_t reg_base, ptr_t fb, ptr_t fb_sz);
+
+/**
+ * @brief Config VGA active displaying region dimension (resolution)
+ *
+ * @param width width in pixel counts
+ * @param hight height in pixel counts
+ * @param freq frame update frequency
+ * @param d9 use D9 character clock
+ */
+void
+vga_config_rect(struct vga*, size_t width, size_t hight, size_t freq, int d9);
+
+void
+vga_reload_config(struct vga*);
+
+#endif /* __LUNAIX_VGA_H */
diff --git a/lunaix-os/hal/gfxa/vga/vga_mmio_ops.c b/lunaix-os/hal/gfxa/vga/vga_mmio_ops.c
new file mode 100644 (file)
index 0000000..4ec8c3e
--- /dev/null
@@ -0,0 +1,90 @@
+#include "vga.h"
+
+typedef volatile u8_t vga_reg8;
+
+#define regaddr(type, i, vga)                                                  \
+    ((vga_reg8*)(vga_gfx_regmap[type][i] + (vga)->io_off))
+
+#define arx_reset(v) (void)(*regaddr(VGA_STATX, 1, v))
+
+// Port IO Address - 0x3C0
+static u32_t vga_gfx_regmap[][2] = {
+    [VGA_ARX] = { 0x0, 0x1 },    [VGA_SRX] = { 0x04, 0x05 },
+    [VGA_GRX] = { 0x0E, 0x0F },  [VGA_CRX] = { 0x14, 0x15 },
+    [VGA_DACX] = { 0x08, 0x09 }, [VGA_MISCX] = { 0x02, 0x0C },
+    [VGA_STATX] = { 0x02, 0x1A }
+};
+
+static u32_t
+vga_mmio_read(struct vga* v, u32_t type, u32_t index, u32_t mask)
+{
+    vga_reg8* reg_ix = regaddr(type, VGA_REG_X, v);
+    vga_reg8* reg_rd = regaddr(type, VGA_REG_D, v);
+    *reg_ix = (u8_t)index;
+    return ((u32_t)*reg_rd) & mask;
+}
+
+static void
+vga_mmio_write(struct vga* v, u32_t type, u32_t index, u32_t val, u32_t mask)
+{
+    index = index & 0xff;
+    val = val & mask;
+    vga_reg8* reg_ix = regaddr(type, VGA_REG_X, v);
+    if (type == VGA_ARX) {
+        // reset ARX filp-flop
+        arx_reset(v);
+        *reg_ix = ((u8_t)index) | 0x20;
+        *reg_ix = val;
+        return;
+    } else if (type == VGA_MISCX) {
+        *reg_ix = val;
+        return;
+    }
+
+    *((u16_t*)reg_ix) = (u16_t)(((val) << 8) | index);
+}
+
+static void
+vga_mmio_set_regs(struct vga* v, u32_t type, size_t off, u32_t* seq, size_t len)
+{
+    vga_reg8* reg_ix = regaddr(type, VGA_REG_X, v);
+    if (type == VGA_ARX) {
+        arx_reset(v);
+        for (size_t i = 0; i < len; i++) {
+            *reg_ix = (u8_t)(off + i) | 0x20;
+            *reg_ix = seq[i];
+        }
+
+    } else {
+        for (size_t i = 0; i < len; i++) {
+            *((u16_t*)reg_ix) = (u16_t)((seq[i] << 8) | ((off + i) & 0xff));
+        }
+    }
+}
+
+static void
+vga_mmio_set_dacp(struct vga* v)
+{
+#define R(c) (u8_t)(((c) & 0xff0000) >> 16)
+#define G(c) (u8_t)(((c) & 0x00ff00) >> 8)
+#define B(c) (u8_t)(((c) & 0x0000ff))
+
+    vga_reg8* reg_ix = regaddr(VGA_DACX, VGA_REG_X, v);
+    vga_reg8* reg_dat = regaddr(VGA_DACX, VGA_REG_D, v);
+
+    u32_t* color_map = v->lut.colors;
+
+    *reg_ix = 0;
+    for (size_t i = 0; i < v->lut.len; i++) {
+        u32_t color = color_map[i];
+        *reg_dat = R(color);
+        *reg_dat = G(color);
+        *reg_dat = B(color);
+    }
+}
+
+struct vga_regops vga_default_mmio_ops = { .read = vga_mmio_read,
+                                           .write = vga_mmio_write,
+                                           .set_seq = vga_mmio_set_regs,
+                                           .set_dac_palette =
+                                             vga_mmio_set_dacp };
\ No newline at end of file
diff --git a/lunaix-os/hal/gfxa/vga/vga_pci.c b/lunaix-os/hal/gfxa/vga/vga_pci.c
new file mode 100644 (file)
index 0000000..baf7fa4
--- /dev/null
@@ -0,0 +1,106 @@
+#include <lunaix/device.h>
+#include <lunaix/mm/mmio.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+#include <lunaix/status.h>
+
+#include <hal/pci.h>
+#include <sys/pci_hba.h>
+
+#include <klibc/string.h>
+
+#include "vga.h"
+
+extern struct vga_regops vga_default_mmio_ops;
+
+#define FB256K 256 << 10
+
+static u32_t palette[] = {
+    0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080,
+    0xc0c0c0, 0x808080, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff,
+    0x00ffff, 0xffffff, 0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7,
+    0x0000ff, 0x005f00, 0x005f5f, 0x005f87, 0x005faf, 0x005fd7, 0x005fff,
+    0x008700, 0x00875f, 0x008787, 0x0087af, 0x0087d7, 0x0087ff, 0x00af00,
+    0x00af5f, 0x00af87, 0x00afaf, 0x00afd7, 0x00afff, 0x00d700, 0x00d75f,
+    0x00d787, 0x00d7af, 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f, 0x00ff87,
+    0x00ffaf, 0x00ffd7, 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af,
+    0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7,
+    0x5f5fff, 0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff,
+    0x5faf00, 0x5faf5f, 0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700,
+    0x5fd75f, 0x5fd787, 0x5fd7af, 0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f,
+    0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff, 0x870000, 0x87005f, 0x870087,
+    0x8700af, 0x8700d7, 0x8700ff, 0x875f00, 0x875f5f, 0x875f87, 0x875faf,
+    0x875fd7, 0x875fff, 0x878700, 0x87875f, 0x878787, 0x8787af, 0x8787d7,
+    0x8787ff, 0x87af00, 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff,
+    0x87d700, 0x87d75f, 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00,
+    0x87ff5f, 0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f,
+    0xaf0087, 0xaf00af, 0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87,
+    0xaf5faf, 0xaf5fd7, 0xaf5fff, 0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af,
+    0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f, 0xafaf87, 0xafafaf, 0xafafd7,
+    0xafafff, 0xafd700, 0xafd75f, 0xafd787, 0xafd7af, 0xafd7d7, 0xafd7ff,
+    0xafff00, 0xafff5f, 0xafff87, 0xafffaf, 0xafffd7, 0xafffff, 0xd70000,
+    0xd7005f, 0xd70087, 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f,
+    0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787,
+    0xd787af, 0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf,
+    0xd7afd7, 0xd7afff, 0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7,
+    0xd7d7ff, 0xd7ff00, 0xd7ff5f, 0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff,
+    0xff0000, 0xff005f, 0xff0087, 0xff00af, 0xff00d7, 0xff00ff, 0xff5f00,
+    0xff5f5f, 0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff, 0xff8700, 0xff875f,
+    0xff8787, 0xff87af, 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f, 0xffaf87,
+    0xffafaf, 0xffafd7, 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af,
+    0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7,
+    0xffffff, 0x080808, 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a,
+    0x444444, 0x4e4e4e, 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080,
+    0x8a8a8a, 0x949494, 0x9e9e9e, 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6,
+    0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee
+};
+
+#define VGA_REG_OFF 0x0400
+
+static int
+vga_pci_init(struct device_def* devdef, struct device* pcidev_base)
+{
+    struct pci_device* pcidev = PCI_DEVICE(pcidev_base);
+
+    struct pci_base_addr* fb = &pcidev->bar[0];
+    struct pci_base_addr* mmio = &pcidev->bar[2];
+
+    if (PCI_BAR_ADDR_IO(mmio->type)) {
+        return EINVAL;
+    }
+
+    pci_reg_t cmd = pci_read_cspace(pcidev->cspace_base, PCI_REG_STATUS_CMD);
+
+    cmd |= (PCI_RCMD_MM_ACCESS | PCI_RCMD_DISABLE_INTR | PCI_RCMD_BUS_MASTER);
+
+    pci_write_cspace(pcidev->cspace_base, PCI_REG_STATUS_CMD, cmd);
+
+    ptr_t fb_mapped = (ptr_t)ioremap(fb->start, FB256K);
+    ptr_t mmio_mapped = (ptr_t)ioremap(mmio->start, mmio->size);
+
+    struct vga* vga_state =
+      vga_new_state(mmio_mapped + VGA_REG_OFF, fb_mapped, FB256K);
+    vga_state->reg_ops = vga_default_mmio_ops;
+    vga_state->lut.colors = palette;
+    vga_state->lut.len = 256;
+    vga_state->options = VGA_MODE_GFX;
+
+    vga_config_rect(vga_state, 640, 360, 60, 0);
+
+    // TEMP: Test the change of VGA display mode and resolution
+    // vga_reload_config(vga_state);
+
+    return 0;
+}
+
+#define VGA_PCI_CLASS 0x30000
+
+static struct pci_device_def vga_pci_devdef = {
+    .dev_class = VGA_PCI_CLASS,
+    .dev_ident = PCI_DEVIDENT(0x1234, 0x1111),
+    .ident_mask = -1,
+    .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_DISP, DEV_VGA),
+                .name = "VGA Generic Driver",
+                .init_for = vga_pci_init }
+};
+EXPORT_DEVICE(vga_pci, &vga_pci_devdef.devdef, load_pci_probe);
\ No newline at end of file
diff --git a/lunaix-os/hal/gfxa/vga/vga_pmio_ops.c b/lunaix-os/hal/gfxa/vga/vga_pmio_ops.c
new file mode 100644 (file)
index 0000000..7ad90fc
--- /dev/null
@@ -0,0 +1,9 @@
+#include "vga.h"
+
+static u32_t vga_gfx_regmap[][2] = {
+    [VGA_ARX] = { 0x3C0, 0x3C1 },  [VGA_SRX] = { 0x3C4, 0x3C5 },
+    [VGA_GRX] = { 0x3CE, 0x3CF },  [VGA_CRX] = { 0x3D4, 0x3D5 },
+    [VGA_DACX] = { 0x3C8, 0x3C9 }, [VGA_MISCX] = { 0x3CC, 0x3C2 }
+};
+
+// TODO
\ No newline at end of file
index 3859e0c368e073449860319e834b22b61715d18f..7a1967ed4b5d48d54057c1d6a837a8b772ed10bb 100644 (file)
@@ -21,6 +21,8 @@ LOG_MODULE("PCI")
 
 static DEFINE_LLIST(pci_devices);
 
+static struct device* pcidev_cat;
+
 void
 pci_probe_msi_info(struct pci_device* device);
 
@@ -42,8 +44,8 @@ pci_create_device(ptr_t pci_base, int devinfo)
             continue;
         }
 
-        int result = (pos->dev_vendor & vendor) == vendor &&
-                     (pos->dev_id & devid) == devid;
+        u32_t idm = pos->ident_mask;
+        int result = (pos->dev_ident & idm) == (devinfo & idm);
 
         if (result) {
             goto found;
@@ -63,14 +65,14 @@ found:
     device->cspace_base = pci_base;
     device->intr_info = intr;
 
-    device_prepare(&device->dev, &pos->devdef.class);
+    device_create(&device->dev, pcidev_cat, DEV_IFSYS, NULL);
 
     pci_probe_msi_info(device);
     pci_probe_bar_info(device);
 
     kappendf("%s (dev.%x:%x:%x) \n",
              pos->devdef.name,
-             pos->devdef.class.meta,
+             pos->devdef.class.fn_grp,
              pos->devdef.class.device,
              pos->devdef.class.variant);
 
@@ -86,6 +88,7 @@ found:
     }
 
     llist_append(&pci_devices, &device->dev_chain);
+    device_register(&device->dev, &pos->devdef.class, "%x:%x", vendor, devid);
 
     return device;
 
@@ -338,6 +341,8 @@ EXPORT_TWIFS_PLUGIN(pci_devs, pci_build_fsmapping);
 static int
 pci_load_devices(struct device_def* def)
 {
+    pcidev_cat = device_addcat(NULL, "pci");
+
     pci_scan();
 
     return 0;
@@ -345,7 +350,7 @@ pci_load_devices(struct device_def* def)
 
 static struct device_def pci_def = {
     .name = "pci3.0-hba",
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_BUSIF, DEV_BUS, 0),
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_BUSIF, DEV_PCI),
     .init = pci_load_devices
 };
 EXPORT_DEVICE(pci3hba, &pci_def, load_poststage);
index f398c662a0cb87c13666ec29ae872d34cf058098..3035f314dc6b238ca3f56afc0c20d791667845ae 100644 (file)
@@ -31,16 +31,18 @@ __rand_rd(struct device* dev, void* buf, size_t offset, size_t len)
 int
 pdev_randdev_init(struct device_def* devdef)
 {
-    struct device* devrand = device_addseq(NULL, &devdef->class, NULL, "rand");
+    struct device* devrand = device_allocseq(NULL, NULL);
     devrand->ops.read = __rand_rd;
     devrand->ops.read_page = __rand_rd_pg;
 
+    device_register(devrand, &devdef->class, "rand");
+
     return 0;
 }
 
 static struct device_def devrandx86_def = {
     .name = "x86 On-Chip RNG",
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_RNG, 0),
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_RNG),
     .init = pdev_randdev_init
 };
 EXPORT_DEVICE(randdev, &devrandx86_def, load_earlystage);
\ No newline at end of file
index 82f98eb9fbf2f132abe443b2783fe5f4fe789c16..87e7d1011942888a41d678725e0586c004982ea2 100644 (file)
@@ -84,15 +84,16 @@ hwrtc_alloc_new(struct device_def* def, char* name)
     }
 
     rtc_instance->name = name;
-    struct device* rtcdev =
-      device_addsys(NULL, &def->class, rtc_instance, "rtc%d", rtc_count);
+    struct device* rtcdev = device_allocsys(NULL, rtc_instance);
 
     rtcdev->ops.exec_cmd = hwrtc_ioctl;
     rtcdev->ops.read = hwrtc_read;
 
     rtc_instance->rtc_dev = rtcdev;
 
-    rtc_count++;
+    device_register(rtcdev, &def->class, "rtc%d", def->class.variant);
+
+    def->class.variant++;
 
     return rtc_instance;
 }
index dce0a5179ad8386212d9552d1f417259c50a5a2e..6b645279e9331def4ba43877f3318caeb83331ce 100644 (file)
@@ -217,7 +217,7 @@ rtc_init(struct device_def* devdef)
 
 static struct device_def devrtc_mc146818 = {
     .name = "MC146818 RTC",
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_TIME, DEV_RTC, 1),
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_TIME, DEV_RTC),
     .init = rtc_init
 };
 EXPORT_DEVICE(mc146818, &devrtc_mc146818, load_earlystage);
\ No newline at end of file
diff --git a/lunaix-os/hal/term/lcntls/ansi_cntl.c b/lunaix-os/hal/term/lcntls/ansi_cntl.c
new file mode 100644 (file)
index 0000000..a11781e
--- /dev/null
@@ -0,0 +1,57 @@
+#include <hal/term.h>
+
+#include <lunaix/process.h>
+
+#define CTRL_MNEMO(chr) (chr - 'A' + 1)
+
+static inline int
+__ansi_actcontrol(struct term* termdev, char chr)
+{
+    struct linebuffer* lbuf = &termdev->line;
+    switch (chr) {
+        case '\0':            // EOL
+        case CTRL_MNEMO('D'): // EOF
+            return 0;
+
+        case CTRL_MNEMO('C'): // INTR
+            signal_send(termdev->fggrp, SIGINT);
+            break;
+
+        case '\r': // CR
+            termdev->line.ptr = 0;
+            return 1;
+
+        case '\x08': // ERASE
+            return line_put_next(lbuf, chr, -1);
+
+        case CTRL_MNEMO('Q'): // QUIT
+            signal_send(termdev->fggrp, SIGKILL);
+            return 1;
+
+        case CTRL_MNEMO('Z'): // SUSP
+            signal_send(termdev->fggrp, SIGSTOP);
+            return 1;
+
+        default:
+            if ((int)chr < 32) {
+                line_put_next(lbuf, '^', 0);
+                chr += 64;
+            }
+            break;
+    }
+
+    return line_put_next(lbuf, chr, 0);
+}
+
+static size_t
+ansi_lcntl_process(struct term* termdev, char* line, size_t len)
+{
+    size_t i = 0;
+    while (i < len && __ansi_actcontrol(termdev, line[i])) {
+        i++;
+    }
+
+    return i;
+}
+
+struct term_lcntl ansi_line_controller = { .apply = ansi_lcntl_process };
\ No newline at end of file
diff --git a/lunaix-os/hal/term/term.c b/lunaix-os/hal/term/term.c
new file mode 100644 (file)
index 0000000..2130105
--- /dev/null
@@ -0,0 +1,312 @@
+#include <hal/term.h>
+#include <klibc/string.h>
+#include <lunaix/fs.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+#include <lunaix/status.h>
+
+#include <usr/lunaix/ioctl_defs.h>
+
+#define ANSI_LCNTL 0
+
+extern struct term_lcntl ansi_line_controller;
+static struct term_lcntl* line_controls[] = { [ANSI_LCNTL] =
+                                                &ansi_line_controller };
+#define LCNTL_TABLE_LEN (sizeof(line_controls) / sizeof(struct term_lcntl*))
+
+static int
+term_exec_cmd(struct device* dev, u32_t req, va_list args)
+{
+    struct term* term = (struct term*)dev->underlay;
+    int err = 0;
+
+    device_lock(dev);
+
+    switch (req) {
+        case TIOCSPGRP: {
+            pid_t pgid = va_arg(args, pid_t);
+            if (pgid < 0) {
+                err = EINVAL;
+                goto done;
+            }
+            term->fggrp = pgid;
+            break;
+        }
+        case TIOCGPGRP:
+            return term->fggrp;
+        case TIOCPUSH: {
+            u32_t lcntl_idx = va_arg(args, u32_t);
+            struct term_lcntl* lcntl = term_get_lcntl(lcntl_idx);
+
+            if (!lcntl) {
+                err = EINVAL;
+                goto done;
+            }
+
+            term_push_lcntl(term, lcntl);
+            break;
+        }
+        case TIOCPOP:
+            term_pop_lcntl(term);
+            break;
+        case TIOCSCDEV: {
+            int fd = va_arg(args, int);
+            struct v_fd* vfd;
+
+            if (vfs_getfd(fd, &vfd)) {
+                err = EINVAL;
+                goto done;
+            }
+
+            struct device* cdev = device_cast(vfd->file->inode->data);
+            if (!cdev) {
+                err = ENOTDEV;
+                goto done;
+            }
+            if (cdev->dev_type != DEV_IFSEQ) {
+                err = EINVAL;
+                goto done;
+            }
+
+            term_bind(term, cdev);
+            break;
+        }
+        case TIOCGCDEV: {
+            struct dev_info* devinfo = va_arg(args, struct dev_info*);
+
+            if (!term->chdev) {
+                err = ENODEV;
+                goto done;
+            }
+
+            if (devinfo) {
+                device_populate_info(term->chdev, devinfo);
+            }
+            break;
+        }
+        default:
+            err = EINVAL;
+            goto done;
+    }
+
+done:
+    device_unlock(dev);
+    return err;
+}
+
+static int
+term_write(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    struct term* term = (struct term*)dev->underlay;
+    size_t sz = MIN(len, term->line.sz_hlf);
+
+    if (!term->chdev) {
+        return ENODEV;
+    }
+
+    device_lock(term->dev);
+
+    memcpy(term->line.current, &((char*)buf)[offset], sz);
+
+    struct term_lcntl *lcntl, *n;
+    llist_for_each(lcntl, n, &term->lcntl_stack, lcntls)
+    {
+        sz = lcntl->apply(term, term->line.current, sz);
+        line_flip(&term->line);
+    }
+
+    int errcode = term_sendline(term, sz);
+
+    device_unlock(term->dev);
+
+    return errcode;
+}
+
+static int
+term_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    struct term* term = (struct term*)dev->underlay;
+    size_t sz = MIN(len, term->line.sz_hlf);
+
+    if (!term->chdev) {
+        return ENODEV;
+    }
+
+    device_lock(term->dev);
+
+    sz = term_readline(term, sz);
+    if (!sz) {
+        device_unlock(term->dev);
+        return 0;
+    }
+
+    struct term_lcntl *pos, *n;
+    llist_for_each(pos, n, &term->lcntl_stack, lcntls)
+    {
+        sz = pos->apply(term, term->line.current, sz);
+        line_flip(&term->line);
+    }
+
+    memcpy(&((char*)buf)[offset], term->line.current, sz);
+
+    device_unlock(term->dev);
+
+    return sz;
+}
+
+struct term*
+term_create()
+{
+    struct term* terminal = valloc(sizeof(struct term));
+
+    if (!terminal) {
+        return NULL;
+    }
+
+    terminal->dev = device_allocseq(NULL, terminal);
+
+    terminal->dev->ops.read = term_read;
+    terminal->dev->ops.write = term_write;
+
+    llist_init_head(&terminal->lcntl_stack);
+    line_alloc(&terminal->line, 1024);
+
+    return terminal;
+}
+
+int
+term_bind(struct term* term, struct device* chdev)
+{
+    device_lock(term->dev);
+
+    term->chdev = chdev;
+
+    device_unlock(term->dev);
+
+    return 0;
+}
+
+struct term_lcntl*
+term_get_lcntl(u32_t lcntl_index)
+{
+    if (lcntl_index >= LCNTL_TABLE_LEN) {
+        return NULL;
+    }
+
+    struct term_lcntl* lcntl_template = line_controls[lcntl_index];
+    struct term_lcntl* lcntl_instance = valloc(sizeof(struct term_lcntl));
+
+    if (!lcntl_instance) {
+        return NULL;
+    }
+
+    lcntl_instance->apply = lcntl_template->apply;
+
+    return lcntl_instance;
+}
+
+int
+term_push_lcntl(struct term* term, struct term_lcntl* lcntl)
+{
+    device_lock(term->dev);
+
+    llist_append(&term->lcntl_stack, &lcntl->lcntls);
+
+    device_unlock(term->dev);
+
+    return 0;
+}
+
+int
+term_pop_lcntl(struct term* term)
+{
+    if (term->lcntl_stack.prev == &term->lcntl_stack) {
+        return 0;
+    }
+
+    device_lock(term->dev);
+
+    struct term_lcntl* lcntl =
+      list_entry(term->lcntl_stack.prev, struct term_lcntl, lcntls);
+    llist_delete(term->lcntl_stack.prev);
+
+    vfree(lcntl);
+
+    device_unlock(term->dev);
+
+    return 1;
+}
+
+void
+line_flip(struct linebuffer* lbf)
+{
+    char* tmp = lbf->current;
+    lbf->current = lbf->next;
+    lbf->next = tmp;
+}
+
+void
+line_alloc(struct linebuffer* lbf, size_t sz_hlf)
+{
+    char* buffer = valloc(sz_hlf * 2);
+    lbf->current = buffer;
+    lbf->next = &buffer[sz_hlf];
+    lbf->sz_hlf = sz_hlf;
+}
+
+void
+line_free(struct linebuffer* lbf, size_t sz_hlf)
+{
+    void* ptr = (void*)MIN((ptr_t)lbf->current, (ptr_t)lbf->next);
+    vfree(ptr);
+}
+
+int
+term_sendline(struct term* tdev, size_t len)
+{
+    struct device* chdev = tdev->chdev;
+
+    device_lock(chdev);
+
+    int code = chdev->ops.write(chdev, tdev->line.current, 0, len);
+
+    device_unlock(chdev);
+
+    return code;
+}
+
+int
+term_readline(struct term* tdev, size_t len)
+{
+    struct device* chdev = tdev->chdev;
+
+    device_lock(chdev);
+
+    int code = chdev->ops.read(chdev, tdev->line.current, 0, len);
+
+    device_unlock(chdev);
+
+    return code;
+}
+
+int
+term_init(struct device_def* devdef)
+{
+    struct term* terminal = term_create();
+    struct device* tdev = device_allocseq(NULL, terminal);
+    tdev->ops.read = term_read;
+    tdev->ops.write = term_write;
+    tdev->ops.exec_cmd = term_exec_cmd;
+
+    devdef->class.variant++;
+    device_register(tdev, &devdef->class, "tty%d", devdef->class.variant);
+
+    return 0;
+}
+
+static struct device_def vterm_def = {
+    .class = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_VTERM),
+    .name = "virtual terminal",
+    .init = term_init
+};
+EXPORT_DEVICE(vterm, &vterm_def, load_on_demand);
\ No newline at end of file
index c52cebe5d03210d0cbde466b213c7b6fee97db55..e195f34e8099aac43a0ac3ef200fa2a3d0ef5a76 100644 (file)
@@ -150,12 +150,13 @@ apic_timer_init(struct hwtimer* timer, u32_t hertz, timer_tick_cb timer_cb)
 struct hwtimer*
 apic_hwtimer_context()
 {
-    static struct hwtimer apic_hwt = { .name = "apic_timer",
-                                       .class = DEVCLASS(
-                                         DEVIF_SOC, DEVFN_TIME, DEV_TIMER, 0),
-                                       .init = apic_timer_init,
-                                       .supported = apic_timer_check,
-                                       .systicks = apic_get_systicks };
+    static struct hwtimer apic_hwt = {
+        .name = "apic_timer",
+        .class = DEVCLASSV(DEVIF_SOC, DEVFN_TIME, DEV_TIMER, DEV_TIMER_APIC),
+        .init = apic_timer_init,
+        .supported = apic_timer_check,
+        .systicks = apic_get_systicks
+    };
 
     return &apic_hwt;
 }
index 4da156895fb3de77384edb9e0ac5dc5a75f058e5..91dca07459d8e9caf450ecbaab8c9cddd78d8f6d 100644 (file)
@@ -58,8 +58,9 @@ hwtimer_init(u32_t hertz, void* tick_callback)
 
     current_timer = hwt_ctx;
 
-    struct device* timerdev =
-      device_addsys(NULL, &hwt_ctx->class, hwt_ctx, hwt_ctx->name);
+    struct device* timerdev = device_allocsys(NULL, hwt_ctx);
 
     timerdev->ops.exec_cmd = __hwtimer_ioctl;
+
+    device_register(timerdev, &hwt_ctx->class, hwt_ctx->name);
 }
\ No newline at end of file
index de44d3aea936da422417b2185f1e912f2691532e..f362b2d08a6fa16af793d6f42694223240bd45f7 100644 (file)
@@ -15,8 +15,8 @@
 #define ACPI_RSDP_SIG_L 0x20445352 // 'RSD '
 #define ACPI_RSDP_SIG_H 0x20525450 // 'PTR '
 
-#define ACPI_MADT_SIG 0x43495041   // 'APIC'
-#define ACPI_FADT_SIG 0x50434146   // 'FACP' Notice that it is not 'FADT'.
+#define ACPI_MADT_SIG 0x43495041 // 'APIC'
+#define ACPI_FADT_SIG 0x50434146 // 'FACP' Notice that it is not 'FADT'.
 
 // 'MCFG' (Not part of ACPI standard. See PCI Firmware Spec.)
 #define ACPI_MCFG_SIG 0x4746434d
index 186c6773aadfadafc16875319817e4b4232fc601..3131aba50e414f33b101fcc2eedb3aa2fffd0f62 100644 (file)
 #define PCI_REG_STATUS_CMD 0x4
 #define PCI_REG_BAR(num) (0x10 + (num - 1) * 4)
 
-#define PCI_DEV_VENDOR(x) ((x)&0xffff)
-#define PCI_DEV_DEVID(x) (((x)&0xffff0000) >> 16)
-#define PCI_INTR_IRQ(x) ((x)&0xff)
-#define PCI_INTR_PIN(x) (((x)&0xff00) >> 8)
+#define PCI_DEV_VENDOR(x) ((x) & 0xffff)
+#define PCI_DEV_DEVID(x) (((x) & 0xffff0000) >> 16)
+#define PCI_INTR_IRQ(x) ((x) & 0xff)
+#define PCI_INTR_PIN(x) (((x) & 0xff00) >> 8)
 #define PCI_DEV_CLASS(x) ((x) >> 8)
-#define PCI_DEV_REV(x) (((x)&0xff))
+#define PCI_DEV_REV(x) (((x) & 0xff))
 #define PCI_BUS_NUM(x) (((x) >> 16) & 0xff)
 #define PCI_SLOT_NUM(x) (((x) >> 11) & 0x1f)
 #define PCI_FUNCT_NUM(x) (((x) >> 8) & 0x7)
 
-#define PCI_BAR_MMIO(x) (!((x)&0x1))
-#define PCI_BAR_CACHEABLE(x) ((x)&0x8)
-#define PCI_BAR_TYPE(x) ((x)&0x6)
+#define PCI_BAR_MMIO(x) (!((x) & 0x1))
+#define PCI_BAR_CACHEABLE(x) ((x) & 0x8)
+#define PCI_BAR_TYPE(x) ((x) & 0x6)
 #define PCI_BAR_ADDR_MM(x) ((x) & ~0xf)
 #define PCI_BAR_ADDR_IO(x) ((x) & ~0x3)
 
@@ -47,8 +47,8 @@
 #define PCI_RCMD_IO_ACCESS 1
 
 #define PCI_ADDRESS(bus, dev, funct)                                           \
-    (((bus)&0xff) << 16) | (((dev)&0xff) << 11) | (((funct)&0xff) << 8) |      \
-      0x80000000
+    (((bus) & 0xff) << 16) | (((dev) & 0xff) << 11) |                          \
+      (((funct) & 0xff) << 8) | 0x80000000
 
 #define PCI_ID_ANY (-1)
 
@@ -79,14 +79,18 @@ struct pci_device
     u16_t intr_info;
     struct pci_base_addr bar[6];
 };
+#define PCI_DEVICE(devbase) (container_of((devbase), struct pci_device, dev))
 
 typedef void* (*pci_drv_init)(struct pci_device*);
 
+#define PCI_DEVIDENT(vendor, id)                                               \
+    ((((id) & 0xffff) << 16) | (((vendor) & 0xffff)))
+
 struct pci_device_def
 {
     u32_t dev_class;
-    u32_t dev_vendor;
-    u32_t dev_id;
+    u32_t dev_ident;
+    u32_t ident_mask;
     struct device_def devdef;
 };
 
index 8346fd0422dd5ba22008b1f1dcc44aad3515f09b..1211ed04cb0793018d6f5a8799b48d637f1e5789 100644 (file)
@@ -24,7 +24,6 @@ struct serial_dev
 {
     struct llist_header sdev_list;
     struct device* dev;
-    mutex_t lock;
     struct waitq wq_rxdone;
     struct waitq wq_txdone;
     void* backend;
diff --git a/lunaix-os/includes/hal/term.h b/lunaix-os/includes/hal/term.h
new file mode 100644 (file)
index 0000000..79f8f67
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __LUNAIX_TERM_H
+#define __LUNAIX_TERM_H
+
+#include <lunaix/device.h>
+
+struct term;
+
+struct term_lcntl
+{
+    struct llist_header lcntls;
+    size_t (*apply)(struct term* termdev, char* line, size_t len);
+};
+
+struct linebuffer
+{
+    char* current;
+    char* next;
+    size_t sz_hlf;
+    off_t ptr;
+};
+
+struct term
+{
+    struct device* dev;
+    struct device* chdev;
+    struct llist_header lcntl_stack;
+    struct linebuffer line;
+    pid_t fggrp;
+};
+
+struct term*
+term_create();
+
+int
+term_bind(struct term* tdev, struct device* chdev);
+
+int
+term_push_lcntl(struct term* tdev, struct term_lcntl* lcntl);
+
+int
+term_pop_lcntl(struct term* tdev);
+
+struct term_lcntl*
+term_get_lcntl(u32_t lcntl_index);
+
+void
+line_flip(struct linebuffer* lbf);
+
+void
+line_alloc(struct linebuffer* lbf, size_t sz_hlf);
+
+void
+line_free(struct linebuffer* lbf, size_t sz_hlf);
+
+static inline int
+line_put_next(struct linebuffer* lbf, char val, int delta)
+{
+    size_t dptr = (size_t)(lbf->ptr + delta);
+    if (dptr >= lbf->sz_hlf) {
+        return 0;
+    }
+
+    lbf->next[dptr] = val;
+    lbf->ptr++;
+    return 1;
+}
+
+int
+term_sendline(struct term* tdev, size_t len);
+
+int
+term_readline(struct term* tdev, size_t len);
+
+#endif /* __LUNAIX_TERM_H */
index a97c8c5732df99854783832d0a639f6e6adc6387..72bffb713b5c4ec136323ac3d4c4d7d4a6c7437e 100644 (file)
@@ -5,5 +5,6 @@
 #define unlikely(x) __builtin_expect((x), 0)
 
 #define weak_alias(name) __attribute__((weak, alias(name)))
+#define weak __attribute__((weak))
 #define noret __attribute__((noreturn))
 #endif /* __LUNAIX_COMPILER_H */
index af21cb35d0062f1dbbe12f674c05819a14b4e9e3..2d9f82bda5fe7f6da6245256a2477a1055a182d3 100644 (file)
@@ -8,9 +8,11 @@
 #include <lunaix/ds/hstr.h>
 #include <lunaix/ds/ldga.h>
 #include <lunaix/ds/llist.h>
-#include <lunaix/ds/semaphore.h>
+#include <lunaix/ds/mutex.h>
 #include <lunaix/types.h>
 
+#include <usr/lunaix/device.h>
+
 /**
  * @brief Export a device definition
  *
@@ -20,6 +22,7 @@
     export_ldga_el_sfx(devdefs, id##_ldorder, ptr_t, devdef, load_order);
 
 #define load_on_demand ld_ondemand
+#define load_pci_probe ld_ondemand
 
 /**
  * @brief Mark the device definition should be loaded automatically as earlier
  * @brief Declare a device class
  *
  */
-#define DEVCLASS(devif, devfn, devkind, devvar)                                \
+#define DEVCLASS(devif, devfn, dev)                                            \
+    (struct devclass)                                                          \
+    {                                                                          \
+        .fn_grp = DEV_FNGRP(devif, devfn), .device = (dev), .variant = 0       \
+    }
+
+#define DEVCLASSV(devif, devfn, dev, devvar)                                   \
     (struct devclass)                                                          \
     {                                                                          \
-        .meta = DEV_META(devif, devfn), .device = (devkind),                   \
+        .fn_grp = DEV_FNGRP(devif, devfn), .device = (dev),                    \
         .variant = (devvar)                                                    \
     }
 
 #define DEV_IFCAT 0x2 // a device category (as device groupping)
 #define DEV_IFSYS 0x3 // a system device
 
-struct devclass
-{
-    u32_t meta;
-    u32_t device;
-    u32_t variant;
-    u32_t hash;
-};
-
 struct device
 {
     u32_t magic;
     struct llist_header siblings;
     struct llist_header children;
     struct device* parent;
+    mutex_t lock;
+
     // TODO investigate event polling
 
     struct hstr name;
-    struct devclass* class;
+    struct devident ident;
+
     u32_t dev_uid;
     int dev_type;
     char name_val[DEVICE_NAME_SIZE];
@@ -115,12 +119,6 @@ struct device_def
     int (*init_for)(struct device_def*, struct device*);
 };
 
-static inline u32_t devclass_hash(struct devclass class)
-{
-    return (((class.device & 0xffff) << 16) | (class.variant & 0xffff)) ^
-           ~class.meta;
-}
-
 static inline u32_t
 device_id_from_class(struct devclass* class)
 {
@@ -128,53 +126,43 @@ device_id_from_class(struct devclass* class)
 }
 
 void
-device_register_all();
+device_scan_drivers();
 
 void
-device_prepare(struct device* dev, struct devclass* class);
+device_setname_vargs(struct device* dev, char* fmt, va_list args);
 
 void
 device_setname(struct device* dev, char* fmt, ...);
 
 void
-device_setname(struct device* dev, char* fmt, ...);
+device_register(struct device* dev, struct devclass* class, char* fmt, ...);
 
-struct device*
-device_add_vargs(struct device* parent,
-                 void* underlay,
-                 char* name_fmt,
-                 u32_t type,
-                 struct devclass* class,
-                 va_list args);
+void
+device_create(struct device* dev,
+              struct device* parent,
+              u32_t type,
+              void* underlay);
 
 struct device*
-device_add(struct device* parent,
-           struct devclass* class,
-           void* underlay,
-           u32_t type,
-           char* name_fmt,
-           ...);
+device_alloc(struct device* parent, u32_t type, void* underlay);
 
-struct device*
-device_addsys(struct device* parent,
-              struct devclass* class,
-              void* underlay,
-              char* name_fmt,
-              ...);
+static inline struct device*
+device_allocsys(struct device* parent, void* underlay)
+{
+    return device_alloc(parent, DEV_IFSYS, underlay);
+}
 
-struct device*
-device_addseq(struct device* parent,
-              struct devclass* class,
-              void* underlay,
-              char* name_fmt,
-              ...);
+static inline struct device*
+device_allocseq(struct device* parent, void* underlay)
+{
+    return device_alloc(parent, DEV_IFSEQ, underlay);
+}
 
-struct device*
-device_addvol(struct device* parent,
-              struct devclass* class,
-              void* underlay,
-              char* name_fmt,
-              ...);
+static inline struct device*
+device_allocvol(struct device* parent, void* underlay)
+{
+    return device_alloc(parent, DEV_IFVOL, underlay);
+}
 
 struct device*
 device_addcat(struct device* parent, char* name_fmt, ...);
@@ -195,19 +183,19 @@ struct device*
 device_getbyoffset(struct device* root_dev, int pos);
 
 struct device*
-device_create_byclass(struct devclass* class,
-                      u32_t type,
-                      char* name,
-                      int* err_code);
+device_cast(void* obj);
 
 struct hbucket*
 device_definitions_byif(int if_type);
 
 struct device_def*
-devdef_byclass(struct devclass* class);
+devdef_byident(struct devident* class);
+
+void
+device_populate_info(struct device* dev, struct dev_info* devinfo);
 
 void
-device_register_all();
+device_scan_drivers();
 
 /*------ Load hooks ------*/
 
@@ -220,4 +208,22 @@ device_poststage();
 void
 device_timerstage();
 
+static inline void
+device_lock(struct device* dev)
+{
+    mutex_lock(&dev->lock);
+}
+
+static inline void
+device_unlock(struct device* dev)
+{
+    mutex_unlock(&dev->lock);
+}
+
+static inline int
+device_locked(struct device* dev)
+{
+    return mutex_on_hold(&dev->lock);
+}
+
 #endif /* __LUNAIX_DEVICE_H */
index d6052cdb0c09160e09e84828d32a342c3fa17113..ad2d8a71b12a509d7bcfd20ff0ae6f5576011c74 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __LUNAIX_DEVICE_NUM_H
 #define __LUNAIX_DEVICE_NUM_H
 
+#include <lunaix/types.h>
+
 /*
     Device metadata field (device_def::meta)
 
             device for output into external environment
 */
 
-#define DEV_META(if_, function) (((if_) & 0xffff) << 16) | ((function) & 0xffff)
-#define DEV_IF(meta) ((meta) >> 16)
-#define DEV_FN(meta) (((meta) & 0xffff))
+#define DEV_FNGRP(if_, function)                                               \
+    (((if_) & 0xffff) << 16) | ((function) & 0xffff)
+#define DEV_UNIQUE(devkind, variant)                                           \
+    (((devkind) & 0xffff) << 16) | ((variant) & 0xffff)
+#define DEV_KIND_FROM(unique) ((unique) >> 16)
+#define DEV_VAR_FROM(unique) ((unique) & 0xffff)
+
+#define DEV_IF(fngrp) ((fngrp) >> 16)
+#define DEV_FN(fngrp) (((fngrp) & 0xffff))
 
 #define DEVIF_NON 0x0
 #define DEVIF_SOC 0x1
 #define DEVFN_TIME 0x6
 #define DEVFN_BUSIF 0x7
 #define DEVFN_TTY 0x8
-
-#define DEV_BUILTIN 0x0
-#define DEV_X86LEGACY 0x1
-#define DEV_RNG 0x2
-#define DEV_RTC 0x3
-#define DEV_SATA 0x4
-#define DEV_NVME 0x5
-#define DEV_BUS 0x6
-#define DEV_SERIAL 0x7
-#define DEV_TIMER 0x8
+#define DEVFN_DISP 0x9
+
+#define DEV_BUILTIN 0
+#define DEV_BUILTIN_NULL 0
+#define DEV_BUILTIN_ZERO 1
+
+#define DEV_VTERM 1
+#define DEV_RNG 2
+#define DEV_RTC 3
+#define DEV_SATA 4
+#define DEV_NVME 5
+#define DEV_PCI 6
+#define DEV_UART16550 7
+
+#define DEV_TIMER 8
+#define DEV_TIMER_APIC 0
+#define DEV_TIMER_HEPT 1
+
+#define DEV_NULL 9
+#define DEV_ZERO 10
+#define DEV_KBD 11
+#define DEV_VGA 12
+
+struct devident
+{
+    u32_t fn_grp;
+    u32_t unique;
+};
+
+struct devclass
+{
+    u32_t fn_grp;
+    u32_t device;
+    u32_t variant;
+    u32_t hash;
+};
 
 #endif /* __LUNAIX_DEVICE_NUM_H */
index 3045113db0bc14ea0ffda766498d90c7bc3e34d0..9f8d2e03aed869ac185eebddc30a65929e507238 100644 (file)
@@ -9,9 +9,8 @@ struct dev_info
 
     struct
     {
-        unsigned int meta;
-        unsigned int device;
-        unsigned int variant;
+        unsigned int group;
+        unsigned int unique;
     } dev_id;
 
     struct
index dd5709f6ca99c9559e923062129fdd83dce6389c..d99e7674a1ce73fe65c8abaf1ab2b304bab74bb4 100644 (file)
 #define TIOCSPGRP IOREQ(1, 1)
 #define TIOCCLSBUF IOREQ(2, 0)
 #define TIOCFLUSH IOREQ(3, 0)
+#define TIOCPUSH IOREQ(4, 1)
+#define TIOCPOP IOREQ(5, 0)
+#define TIOCSCDEV IOREQ(6, 1)
+#define TIOCGCDEV IOREQ(7, 0)
 
 #define RTCIO_IUNMSK IOREQ(1, 0)
 #define RTCIO_IMSK IOREQ(2, 0)
index 9650b47a86badfaae05066800376829d7085f212..1c98912fbeae7730d87ed0080655dec6463f5a69 100644 (file)
@@ -33,8 +33,8 @@ typedef unsigned int ino_t;
 typedef struct dev_t
 {
     unsigned int meta;
-    unsigned int devident;
-    unsigned int dev_uid;
+    unsigned int unique;
+    unsigned int index;
 } dev_t;
 
 #endif /* __LUNAIX_TYPES_H */
index 76ef7787f36d3864b162a96f3df7c4916d57bf1c..c78cd26a1e522b1679c760c0c69caa2eb0d204f9 100644 (file)
@@ -318,16 +318,19 @@ __block_register(struct block_dev* bdev)
         return 0;
     }
 
-    struct device* dev =
-      device_addvol(blk_parent_dev, bdev->class, bdev, "sd%c", 'a' + free_slot);
+    struct device* dev = device_allocvol(blk_parent_dev, bdev);
     dev->ops.write = __block_write;
     dev->ops.write_page = __block_write_page;
     dev->ops.read = __block_read;
     dev->ops.read_page = __block_read_page;
 
     bdev->dev = dev;
-    strcpy(bdev->bdev_id, dev->name_val);
+
+    device_register(dev, bdev->class, "sd%c", 'a' + free_slot);
     dev_registry[free_slot++] = bdev;
+
+    strcpy(bdev->bdev_id, dev->name_val);
+
     return 1;
 }
 
@@ -341,8 +344,7 @@ blk_mount_part(struct block_dev* bdev,
     struct block_dev* pbdev = cake_grab(lbd_pile);
     memcpy(pbdev, bdev, sizeof(*bdev));
 
-    struct device* dev = device_addvol(
-      NULL, pbdev->class, pbdev, "%sp%d", bdev->bdev_id, index + 1);
+    struct device* dev = device_allocvol(NULL, pbdev);
     dev->ops.write = __block_write;
     dev->ops.write_page = __block_write_page;
     dev->ops.read = __block_read;
@@ -359,5 +361,7 @@ blk_mount_part(struct block_dev* bdev,
 
     llist_append(&bdev->parts, &pbdev->parts);
 
+    device_register(dev, pbdev->class, "%sp%d", bdev->bdev_id, index + 1);
+
     return pbdev;
 }
\ No newline at end of file
index f77afec56a02d4f4b9ffc164fd9a53e5191b1348..1c9ee4c7135cca4e0e5e9deed8005ed928884536 100644 (file)
@@ -2,6 +2,8 @@
 #include <lunaix/fs/twifs.h>
 #include <lunaix/status.h>
 
+#include <lib/hash.h>
+
 #include <klibc/stdio.h>
 
 static DECLARE_HASHTABLE(dev_registry, 32);
@@ -10,8 +12,14 @@ static DEFINE_LLIST(dev_registry_flat);
 
 static struct device* adhoc_devcat;
 
+static inline u32_t
+hash_dev(u32_t fngrp, u32_t dev)
+{
+    return (hash_32(fngrp, 16) << 16) | (hash_32(dev, 16));
+}
+
 void
-device_register_all()
+device_scan_drivers()
 {
     adhoc_devcat = device_addcat(NULL, "adhoc");
 
@@ -22,16 +30,16 @@ device_register_all()
     struct device_def* devdef;
     ldga_foreach(devdefs, struct device_def*, idx, devdef)
     {
-        u32_t hash = devclass_hash(devdef->class);
-        devdef->class.hash = hash;
+        struct devclass* devc = &devdef->class;
+        u32_t hash = hash_dev(devc->fn_grp, devc->device);
+        devc->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_byif, &devdef->hlist_if, DEV_IF(devc->fn_grp));
 
         llist_append(&dev_registry_flat, &devdef->dev_list);
     }
@@ -40,14 +48,13 @@ device_register_all()
 static int
 devclass_eq(struct devclass* c1, struct devclass* c2)
 {
-    return c1->meta == c2->meta && c1->variant == c2->variant &&
-           c1->device == c2->device;
+    return c1->fn_grp == c2->fn_grp && c1->device == c2->device;
 }
 
 struct device_def*
-devdef_byclass(struct devclass* class)
+devdef_byclass(struct devclass* devc)
 {
-    u32_t hash = devclass_hash(*class);
+    u32_t hash = hash_dev(devc->fn_grp, devc->device);
     int errno;
 
     struct device_def *pos, *n;
@@ -56,7 +63,7 @@ devdef_byclass(struct devclass* class)
         if (pos->class.hash != hash) {
             continue;
         }
-        if (devclass_eq(class, &pos->class)) {
+        if (devclass_eq(devc, &pos->class)) {
             break;
         }
     }
@@ -64,45 +71,12 @@ devdef_byclass(struct devclass* class)
     return pos;
 }
 
-struct device*
-device_create_byclass(struct devclass* class,
-                      u32_t type,
-                      char* name,
-                      int* err_code)
+struct device_def*
+devdef_byident(struct devident* ident)
 {
-    int errno;
-    struct device_def* devdef = devdef_byclass(class);
-
-    if (!devdef) {
-        *err_code = ENOENT;
-        return NULL;
-    }
-
-    if (!devdef->init_for) {
-        if (err_code) {
-            *err_code = ENOTSUP;
-        }
-        return NULL;
-    }
-
-    struct device* dev = device_add(adhoc_devcat, class, NULL, type, NULL);
-
-    errno = devdef->init_for(devdef, dev);
-    if (err_code && !errno) {
-        *err_code = errno;
-        device_remove(dev);
-        return NULL;
-    }
-
-    device_setname(dev,
-                   "%s_%d:%d:%d_%d",
-                   name,
-                   class->meta,
-                   class->device,
-                   class->device,
-                   dev->dev_uid);
-
-    return dev;
+    struct devclass derived = { .device = DEV_KIND_FROM(ident->unique),
+                                .fn_grp = ident->fn_grp };
+    return devdef_byclass(&derived);
 }
 
 struct hbucket*
@@ -157,14 +131,13 @@ __devdb_twifs_lsdb(struct twimap* mapping)
     char flags[64];
     struct device_def* def = twimap_index(mapping, struct device_def*);
 
-    int meta = def->class.meta;
+    int meta = def->class.fn_grp;
     ksnprintf(flags, 64, "if=%x,fn=%x", DEV_IF(meta), DEV_FN(meta));
 
     twimap_printf(mapping,
-                  "%xh:%d:%d \"%s\" %s\n",
-                  def->class.meta,
+                  "%xh:%d \"%s\" %s\n",
+                  def->class.fn_grp,
                   def->class.device,
-                  def->class.variant,
                   def->name,
                   flags);
 }
index d26808a4646dbe453ff276e6f2836b6e1e203f6d..b25a9c203594bab14d2d2892ca04bbe39d5e5796 100644 (file)
@@ -8,8 +8,6 @@
 #include <lunaix/syscall.h>
 #include <lunaix/syscall_utils.h>
 
-#include <usr/lunaix/device.h>
-
 #include <klibc/stdio.h>
 #include <klibc/string.h>
 
@@ -20,16 +18,6 @@ static volatile u32_t devid = 0;
 struct devclass default_devclass = {};
 
 void
-device_prepare(struct device* dev, struct devclass* class)
-{
-    dev->magic = DEV_STRUCT_MAGIC;
-    dev->dev_uid = devid++;
-    dev->class = class ? class : &default_devclass;
-
-    llist_init_head(&dev->children);
-}
-
-static void
 device_setname_vargs(struct device* dev, char* fmt, va_list args)
 {
     size_t strlen =
@@ -41,28 +29,24 @@ device_setname_vargs(struct device* dev, char* fmt, va_list args)
 }
 
 void
-device_setname(struct device* dev, char* fmt, ...)
+device_register(struct device* dev, struct devclass* class, char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
 
-    device_setname_vargs(dev, fmt, args);
-
-    va_end(args);
-}
+    if (fmt) {
+        device_setname_vargs(dev, fmt, args);
+    }
 
-struct device*
-device_add_vargs(struct device* parent,
-                 void* underlay,
-                 char* name_fmt,
-                 u32_t type,
-                 struct devclass* class,
-                 va_list args)
-{
-    struct device* dev = vzalloc(sizeof(struct device));
+    if (class) {
+        dev->ident = (struct devident){ .fn_grp = class->fn_grp,
+                                        .unique = DEV_UNIQUE(class->device,
+                                                             class->variant) };
+    }
 
-    device_prepare(dev, class);
+    dev->dev_uid = devid++;
 
+    struct device* parent = dev->parent;
     if (parent) {
         assert((parent->dev_type & DEV_MSKIF) == DEV_IFCAT);
         llist_append(&parent->children, &dev->siblings);
@@ -70,84 +54,47 @@ device_add_vargs(struct device* parent,
         llist_append(&root_list, &dev->siblings);
     }
 
-    if (name_fmt) {
-        device_setname_vargs(dev, name_fmt, args);
-    }
-
-    dev->parent = parent;
-    dev->underlay = underlay;
-    dev->dev_type = type;
-
-    return dev;
-}
-
-struct device*
-device_add(struct device* parent,
-           struct devclass* class,
-           void* underlay,
-           u32_t type,
-           char* name_fmt,
-           ...)
-{
-    va_list args;
-    va_start(args, name_fmt);
-
-    struct device* dev =
-      device_add_vargs(parent, underlay, name_fmt, type, class, args);
-
     va_end(args);
-    return dev;
 }
 
-struct device*
-device_addsys(struct device* parent,
-              struct devclass* class,
-              void* underlay,
-              char* name_fmt,
-              ...)
+void
+device_create(struct device* dev,
+              struct device* parent,
+              u32_t type,
+              void* underlay)
 {
-    va_list args;
-    va_start(args, name_fmt);
-
-    struct device* dev =
-      device_add_vargs(parent, underlay, name_fmt, DEV_IFSYS, class, args);
+    dev->magic = DEV_STRUCT_MAGIC;
+    dev->underlay = underlay;
+    dev->dev_type = type;
+    dev->parent = parent;
 
-    va_end(args);
-    return dev;
+    llist_init_head(&dev->children);
+    mutex_init(&dev->lock);
 }
 
 struct device*
-device_addseq(struct device* parent,
-              struct devclass* class,
-              void* underlay,
-              char* name_fmt,
-              ...)
+device_alloc(struct device* parent, u32_t type, void* underlay)
 {
-    va_list args;
-    va_start(args, name_fmt);
+    struct device* dev = vzalloc(sizeof(struct device));
 
-    struct device* dev =
-      device_add_vargs(parent, underlay, name_fmt, DEV_IFSEQ, class, args);
+    if (!dev) {
+        return NULL;
+    }
+
+    device_create(dev, parent, type, underlay);
 
-    va_end(args);
     return dev;
 }
 
-struct device*
-device_addvol(struct device* parent,
-              struct devclass* class,
-              void* underlay,
-              char* name_fmt,
-              ...)
+void
+device_setname(struct device* dev, char* fmt, ...)
 {
     va_list args;
-    va_start(args, name_fmt);
+    va_start(args, fmt);
 
-    struct device* dev =
-      device_add_vargs(parent, underlay, name_fmt, DEV_IFVOL, class, args);
+    device_setname_vargs(dev, fmt, args);
 
     va_end(args);
-    return dev;
 }
 
 struct device*
@@ -156,8 +103,10 @@ device_addcat(struct device* parent, char* name_fmt, ...)
     va_list args;
     va_start(args, name_fmt);
 
-    struct device* dev =
-      device_add_vargs(parent, NULL, name_fmt, DEV_IFCAT, NULL, args);
+    struct device* dev = device_alloc(parent, DEV_IFCAT, NULL);
+
+    device_setname_vargs(dev, name_fmt, args);
+    device_register(dev, NULL, NULL);
 
     va_end(args);
     return dev;
@@ -224,24 +173,34 @@ device_getbyoffset(struct device* root_dev, int offset)
     return NULL;
 }
 
-static inline void
+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;
+    devinfo->dev_id.group = dev->ident.fn_grp;
+    devinfo->dev_id.unique = dev->ident.unique;
 
     if (!devinfo->dev_name.buf) {
         return;
     }
 
-    struct device_def* def = devdef_byclass(dev->class);
+    struct device_def* def = devdef_byident(&dev->ident);
     size_t buflen = devinfo->dev_name.buf_len;
 
     strncpy(devinfo->dev_name.buf, def->name, buflen);
     devinfo->dev_name.buf[buflen - 1] = 0;
 }
 
+struct device*
+device_cast(void* obj)
+{
+    struct device* dev = (struct device*)obj;
+    if (dev && dev->magic == DEV_STRUCT_MAGIC) {
+        return dev;
+    }
+
+    return NULL;
+}
+
 __DEFINE_LXSYSCALL3(int, ioctl, int, fd, int, req, va_list, args)
 {
     int errno = -1;
index 252993f934d56bef8041e0c0af57e3ca92ebc05c..3d974a7987d84f12cea8251d778163b303a473ce 100644 (file)
@@ -80,8 +80,10 @@ input_add_device(struct devclass* class, char* name_fmt, ...)
     va_list args;
     va_start(args, name_fmt);
 
-    struct device* dev =
-      device_add_vargs(input_devcat, idev, name_fmt, DEV_IFSEQ, class, args);
+    struct device* dev = device_allocseq(input_devcat, idev);
+
+    device_setname_vargs(dev, name_fmt, args);
+    device_register(dev, class, NULL);
 
     idev->dev_if = dev;
     dev->ops.read = __input_dev_read;
index f1969bd524473f225a9beffa0c3b6d411f8053ea..8283fd1f56d899a222ff0d779891ca2b22457361 100644 (file)
@@ -133,23 +133,32 @@ pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
     struct pcache* pcache = inode->pg_cache;
     struct pcache_pg* pg;
 
-    while (buf_off < len) {
+    while (buf_off < len && errno >= 0) {
         u32_t wr_bytes = MIN(PG_SIZE - pg_off, len - buf_off);
 
-        pcache_get_page(pcache, fpos, &pg_off, &pg);
+        int new_page = pcache_get_page(pcache, fpos, &pg_off, &pg);
+
+        if (new_page) {
+            // Filling up the page
+            errno =
+              inode->default_fops->read_page(inode, pg->pg, PG_SIZE, pg->fpos);
 
-        if (!pg) {
-            errno = inode->default_fops->write(inode, data, wr_bytes, fpos);
             if (errno < 0) {
                 break;
             }
-        } else {
-            memcpy(pg->pg + pg_off, (data + buf_off), wr_bytes);
-            pcache_set_dirty(pcache, pg);
-
-            pg->len = pg_off + wr_bytes;
+            if (errno < PG_SIZE) {
+                // EOF
+                len = MIN(len, buf_off + errno);
+            }
+        } else if (!pg) {
+            errno = inode->default_fops->write(inode, data, wr_bytes, fpos);
+            continue;
         }
 
+        memcpy(pg->pg + pg_off, (data + buf_off), wr_bytes);
+        pcache_set_dirty(pcache, pg);
+
+        pg->len = pg_off + wr_bytes;
         buf_off += wr_bytes;
         fpos += wr_bytes;
     }
index a935fc44181b8c7ce9fd1fabbe3dafbcca1642a8..2ddc9b1317176f1cfbeda18ae8ac26411fb2934a 100644 (file)
@@ -23,10 +23,9 @@ probe_boot_medium()
         int errno =
           pos->ops.read(pos, (void*)volp, ISO9660_READ_OFF, ISO9660_BLKSZ);
         if (errno < 0) {
-            kprintf(KINFO "failed %x:%d:%d, /dev/%s\n",
-                    pos->class->meta,
-                    pos->class->device,
-                    pos->class->variant,
+            kprintf(KINFO "failed %xh:%xh, /dev/%s\n",
+                    pos->ident.fn_grp,
+                    pos->ident.unique,
                     pos->name.value);
             pos = NULL;
             goto done;
@@ -37,10 +36,9 @@ probe_boot_medium()
         }
 
         if (*(u32_t*)volp->sys_id == LUNAIX_ID) {
-            kprintf(KINFO "%x:%d:%d, /dev/%s, %s\n",
-                    pos->class->meta,
-                    pos->class->device,
-                    pos->class->variant,
+            kprintf(KINFO "%xh:%xh, /dev/%s, %s\n",
+                    pos->ident.fn_grp,
+                    pos->ident.unique,
                     pos->name.value,
                     (char*)volp->vol_id);
             break;
index cf376d23f132ad5e3dd56d368da195e54e317f2d..fbb0f9fddd9d6e3c32bab6054f6ee3f302dbe779 100644 (file)
@@ -1468,16 +1468,15 @@ __DEFINE_LXSYSCALL2(int, fstat, int, fd, struct file_stat*, stat)
             goto done;
         }
 
-        stat->st_rdev = (dev_t){ .meta = rdev->class->meta,
-                                 .devident = device_id_from_class(rdev->class),
-                                 .dev_uid = rdev->dev_uid };
+        stat->st_rdev = (dev_t){ .meta = rdev->ident.fn_grp,
+                                 .unique = rdev->ident.unique,
+                                 .index = rdev->dev_uid };
     }
 
     if (fdev) {
-        u32_t devident = device_id_from_class(fdev->class);
-        stat->st_dev = (dev_t){ .meta = fdev->class->meta,
-                                .devident = devident,
-                                .dev_uid = fdev->dev_uid };
+        stat->st_dev = (dev_t){ .meta = fdev->ident.fn_grp,
+                                .unique = fdev->ident.unique,
+                                .index = fdev->dev_uid };
     }
 
 done:
index f5944b50a90b6e9cbdf16c0f147a04f1ede590bb..cb31ca1af1ea60ef4324b1c6f0d06ebfd70d8095 100644 (file)
@@ -52,7 +52,7 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     /* Prepare stack trace environment */
     trace_modksyms_init(bhctx);
 
-    device_register_all();
+    device_scan_drivers();
 
     // crt
     tty_init(ioremap(0xB8000, PG_SIZE));
index 15c8c1400bb2387374365bcf940cc97f3b14d3d8..451abe06e139c596cdebf985d10cdee8d9d90bd8 100644 (file)
@@ -11,7 +11,7 @@
 static char* log_prefix[] = { "- ", "W ", "E ", "D " };
 static char* color_code[] = { "", "\033[6;0m", "\033[12;0m", "\033[9;0m" };
 
-void
+void 
 __kprintf_internal(const char* component,
                    int log_level,
                    const char* prefix,
diff --git a/lunaix-os/kernel/mm/cow.c b/lunaix-os/kernel/mm/cow.c
deleted file mode 100644 (file)
index a12d6e9..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <lunaix/mm/pmm.h>
-#include <lunaix/mm/vmm.h>
-
-#include <sys/mm/mempart.h>
-
-ptr_t
-vmm_dup_page(pid_t pid, ptr_t pa)
-{
-    ptr_t new_ppg = pmm_alloc_page(pid, 0);
-    vmm_set_mapping(VMS_SELF, PG_MOUNT_3, new_ppg, PG_PREM_RW, VMAP_NULL);
-    vmm_set_mapping(VMS_SELF, PG_MOUNT_4, pa, PG_PREM_RW, VMAP_NULL);
-
-    asm volatile("movl %1, %%edi\n"
-                 "movl %2, %%esi\n"
-                 "rep movsl\n" ::"c"(1024),
-                 "r"(PG_MOUNT_3),
-                 "r"(PG_MOUNT_4)
-                 : "memory", "%edi", "%esi");
-
-    vmm_del_mapping(VMS_SELF, PG_MOUNT_3);
-    vmm_del_mapping(VMS_SELF, PG_MOUNT_4);
-
-    return new_ppg;
-}
\ No newline at end of file
index 4cfb1a68bc40d1a912f951b3ef2256dcff4dd4e9..e21328f6c5f981d597de3371a133cf7b4c15e556 100644 (file)
@@ -3,7 +3,9 @@
 #include <lunaix/mm/vmm.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
+
 #include <sys/cpu.h>
+#include <sys/mm/mempart.h>
 
 LOG_MODULE("VMM")
 
@@ -199,4 +201,24 @@ vmm_unmount_pd(ptr_t mnt)
     l1pt->entry[(mnt >> 22)] = 0;
     cpu_flush_page(mnt);
     return mnt;
+}
+
+ptr_t
+vmm_dup_page(pid_t pid, ptr_t pa)
+{
+    ptr_t new_ppg = pmm_alloc_page(pid, 0);
+    vmm_set_mapping(VMS_SELF, PG_MOUNT_3, new_ppg, PG_PREM_RW, VMAP_NULL);
+    vmm_set_mapping(VMS_SELF, PG_MOUNT_4, pa, PG_PREM_RW, VMAP_NULL);
+
+    asm volatile("movl %1, %%edi\n"
+                 "movl %2, %%esi\n"
+                 "rep movsl\n" ::"c"(1024),
+                 "r"(PG_MOUNT_3),
+                 "r"(PG_MOUNT_4)
+                 : "memory", "%edi", "%esi");
+
+    vmm_del_mapping(VMS_SELF, PG_MOUNT_3);
+    vmm_del_mapping(VMS_SELF, PG_MOUNT_4);
+
+    return new_ppg;
 }
\ No newline at end of file
index 36ed5ee28d52aef1f8a6f84e627a278bbb3a2575..e11068f1a28511f0f23129bcf365713ff3fefb58 100644 (file)
@@ -129,7 +129,7 @@ taskfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
         return ENOENT;
     }
 
-    return taskfs_mknod(dnode, pid, 0, F_FILE);
+    return taskfs_mknod(dnode, pid, 0, F_DIR);
 }
 
 static struct v_file_ops taskfs_file_ops = { .close = default_file_close,
index 17dddfd1113f3e95a3e5ecb1eb0b5d1efc107572..5c18cbcf62cbbf12c29c4e976c919a8dfa24022f 100644 (file)
@@ -343,8 +343,7 @@ console_start_flushing()
 static int
 lxconsole_spawn_ttydev(struct device_def* devdef)
 {
-    struct device* tty_dev =
-      device_addseq(NULL, &devdef->class, &lx_console, "tty");
+    struct device* tty_dev = device_allocseq(NULL, &lx_console);
     tty_dev->ops.write = __tty_write;
     tty_dev->ops.write_page = __tty_write_pg;
     tty_dev->ops.read = __tty_read;
@@ -354,12 +353,14 @@ lxconsole_spawn_ttydev(struct device_def* devdef)
     waitq_init(&lx_reader);
     input_add_listener(__lxconsole_listener);
 
+    device_register(tty_dev, &devdef->class, "tty");
+
     return 0;
 }
 
 static struct device_def lxconsole_def = {
     .name = "Lunaix Virtual Console",
-    .class = DEVCLASS(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 0),
+    .class = DEVCLASSV(DEVIF_NON, DEVFN_TTY, DEV_BUILTIN, 12),
     .init = lxconsole_spawn_ttydev
 };
 EXPORT_DEVICE(lxconsole, &lxconsole_def, load_earlystage);
\ No newline at end of file
index af90c0644f797997749d3626796a9dcf0f3731df..af07f60420e38e2efa911775856cdd954a27bf5b 100644 (file)
@@ -91,8 +91,7 @@ debug-qemu: all-debug
        @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg
        @qemu-system-i386 $(call get_qemu_options,$(kimg))
        @sleep 1
-       @$(QEMU_MON_TERM) -- telnet 127.0.0.1 $(QEMU_MON_PORT)
-       @gdb -s $(kbuild_dir)/kernel.dbg -ex "target remote localhost:1234"
+       @QMPORT=$(QEMU_MON_PORT) gdb -s $(kbuild_dir)/kernel.dbg -ex "target remote localhost:1234"
 
 debug-qemu-vscode: all-debug
        @i686-elf-objcopy --only-keep-debug $(kbin) $(kbuild_dir)/kernel.dbg
index 12d21b8cbcb79b93a20ae80996a8a08ce055a432..eccf605875caa3f88080fed4a840b02a31eeba10 100644 (file)
@@ -8,6 +8,8 @@ get_qemu_options = -s -S -m 1G \
                                -no-shutdown \
                                -d cpu_reset \
                                -d trace:ide_dma_cb \
+                               -d trace:vga_std_write_io \
+                               -vga std,retrace=precise \
                                -serial telnet::12345,server,nowait\
                                -drive id=disk,file="machine/disk0.vdi",if=none \
                                -drive id=cdrom,file="$(1)",readonly=on,if=none,format=raw \
index b3eaae5f8457929bc284fbc3a69341466acfdfba..7f7ca5e95fcc39d9b8239cde1c76f64b59d31543 100644 (file)
@@ -19,8 +19,6 @@ main(int argc, const char** argv)
         return 0;
     }
 
-    printf("(%p) user space!\n", (void*)main);
-
     if ((err = symlink("/usr", "/mnt/lunaix-os/usr"))) {
         syslog(2, "symlink /usr:/mnt/lunaix-os/usr (%d)\n", errno);
         return 0;
index 8ce8617dfd271f4e6d96ebc749405968cf907408..0a91aa79179ebe95ef426653a2b315b4743837dd 100644 (file)
@@ -175,7 +175,6 @@ sh_loop()
 void
 main()
 {
-    printf("\n Simple shell. Use <PG_UP> or <PG_DOWN> to scroll.\n\n");
     sh_loop();
     _exit(0);
 }
\ No newline at end of file
index 541378f05997c9f7e95b6b6dc1675324336538e6..108f462b887ad42882698e1b5d0e885938a4286a 100644 (file)
@@ -63,10 +63,7 @@ main(int argc, char* argv[])
         dev = &stat.st_rdev;
     }
 
-    printf("Device: %xh:%d:%d;\n",
-           dev->meta,
-           dev->devident >> 16,
-           dev->devident & 0xffff);
+    printf("Device: %xh:%xh@%d;\n", dev->meta, dev->unique, dev->index);
 
     close(fd);
     return 0;