feat: gfxm: a layer provides user space access to low level interfacing of graphic...
authorMinep <lunaixsky@qq.com>
Tue, 24 Oct 2023 14:15:59 +0000 (15:15 +0100)
committerMinep <lunaixsky@qq.com>
Tue, 24 Oct 2023 14:20:26 +0000 (15:20 +0100)
chore: clear things up

13 files changed:
lunaix-os/.gitignore
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/gfxa/gfxm.c [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga.c
lunaix-os/hal/gfxa/vga/vga.h
lunaix-os/hal/gfxa/vga/vga_gfxm_ops.c [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga_mmio_ops.c
lunaix-os/hal/gfxa/vga/vga_pci.c
lunaix-os/hal/pci.c
lunaix-os/includes/hal/gfxm.h [new file with mode: 0644]
lunaix-os/includes/hal/pci.h
lunaix-os/includes/lunaix/device_num.h
lunaix-os/includes/usr/lunaix/gfx.h [new file with mode: 0644]

index b48c6045eadab1375a9423aefe33ab5382727501..31f081b6273c44b7ecb4165bd914acc3257786fd 100644 (file)
@@ -10,5 +10,7 @@ draft/
 iso_inspect/
 unused/
 
 iso_inspect/
 unused/
 
+.gdb_history
+
 **.o
 **.d
\ No newline at end of file
 **.o
 **.d
\ No newline at end of file
index 8794baba37684d43fd4f460918dd0bf6a2e480ce..2aa37e504824531e9d8e0504c862a84094b04277 100644 (file)
@@ -444,9 +444,9 @@ achi_register_ops(struct hba_port* port)
 
 static struct pci_device_def ahcidef = {
     .dev_class = AHCI_HBA_CLASS,
 
 static struct pci_device_def ahcidef = {
     .dev_class = AHCI_HBA_CLASS,
-    .ident_mask = 0x0,
+    .ident_mask = PCI_MATCH_ANY,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
                 .name = "Serial ATA Controller",
                 .init_for = ahci_driver_init }
 };
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
                 .name = "Serial ATA Controller",
                 .init_for = ahci_driver_init }
 };
-EXPORT_DEVICE(ahci, &ahcidef.devdef, load_pci_probe);
\ No newline at end of file
+EXPORT_PCI_DEVICE(ahci, &ahcidef);
\ No newline at end of file
diff --git a/lunaix-os/hal/gfxa/gfxm.c b/lunaix-os/hal/gfxa/gfxm.c
new file mode 100644 (file)
index 0000000..26532a2
--- /dev/null
@@ -0,0 +1,150 @@
+#include <lunaix/compiler.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+#include <lunaix/status.h>
+
+#include <hal/gfxm.h>
+
+#include <klibc/string.h>
+
+DEFINE_LLIST(gfxa_flat);
+DECLARE_HASHTABLE(gfxa_idset, 8);
+
+struct device* gfxa_devcat = NULL;
+static int id = 0;
+
+static struct devclass gfxa_class = DEVCLASS(DEV_BUILTIN, DEVFN_DISP, DEV_GFXA);
+
+static int
+__gfxa_cmd_router(struct device* dev, u32_t req, va_list args)
+{
+    struct gfxa* gfxa = (struct gfxa*)dev->underlay;
+    struct disp_profile* disp = &gfxa->disp_info;
+
+    switch (req) {
+        case GFX_ADAPTER_INFO: {
+            struct gfxa_info* info = va_arg(args, struct gfxa_info*);
+            *info =
+              (struct gfxa_info){ .disp_mode = { .w_px = disp->mon.w_px,
+                                                 .h_px = disp->mon.h_px,
+                                                 .freq = disp->mon.freq,
+                                                 .depth = disp->mon.depth } };
+            gfxa->ops.hwioctl(gfxa, req, args);
+            break;
+        };
+        case GFX_ADAPTER_CHMODE: {
+            struct gfxa_mon* mon_info = va_arg(args, struct gfxa_mon*);
+            gfxa->disp_info.mon = *mon_info;
+
+            return gfxa->ops.update_profile(gfxa);
+        };
+        case GFX_ADAPTER_VMCPY:
+        case GFX_ADAPTER_LFBCPY: {
+            void* buf = va_arg(args, void*);
+            off_t off = va_arg(args, off_t);
+            size_t len = va_arg(args, size_t);
+            if (req == GFX_ADAPTER_VMCPY) {
+                return gfxa->ops.vmcpy(gfxa, buf, off, len);
+            }
+            return gfxa->ops.lfbcpy(gfxa, buf, off, len);
+        };
+        case GFX_ADAPTER_REG_WR:
+        case GFX_ADAPTER_REG_RD: {
+            u32_t* reg_addrmap = va_arg(args, u32_t*);
+            void* reg_val = va_arg(args, void*);
+            size_t reg_count = va_arg(args, size_t);
+
+            if (req == GFX_ADAPTER_LUT_RD) {
+                return gfxa->ops.rreads(gfxa, reg_addrmap, reg_val, reg_count);
+            }
+            return gfxa->ops.rwrites(gfxa, reg_addrmap, reg_val, reg_count);
+        };
+        case GFX_ADAPTER_LUT_RD: {
+            struct gfxa_clut* clut = va_arg(args, struct gfxa_clut*);
+            if (!clut->val || !clut->len) {
+                return disp->clut.len;
+            }
+
+            size_t clut_len = MIN(clut->len, disp->clut.len);
+            memcpy(clut->val, disp->clut.val, clut_len * sizeof(color_t));
+            return clut_len;
+        };
+        case GFX_ADAPTER_LUT_WR: {
+            struct gfxa_clut* clut = va_arg(args, struct gfxa_clut*);
+            int err = gfxm_set_lut(gfxa, clut->val, clut->len);
+            if (!err) {
+                err = gfxa->ops.update_profile(gfxa);
+            }
+            return err;
+        };
+        default:
+            return gfxa->ops.hwioctl(gfxa, req, args);
+    }
+
+    return 0;
+}
+
+struct gfxa*
+gfxm_alloc_adapter(void* hw_obj)
+{
+    if (unlikely(!gfxa_devcat)) {
+        gfxa_devcat = device_addcat(NULL, "gfx");
+    }
+
+    struct gfxa* gfxa = valloc(sizeof(struct gfxa));
+    struct device* gfxa_dev = device_allocsys(gfxa_devcat, gfxa);
+
+    *gfxa = (struct gfxa){ .dev = gfxa_dev, .hw_obj = hw_obj };
+
+    gfxa_dev->ops.exec_cmd = __gfxa_cmd_router;
+
+    return gfxa;
+}
+
+void
+gfxm_register(struct gfxa* gfxa)
+{
+    gfxa->id = gfxa_class.variant++;
+
+    llist_append(&gfxa_flat, &gfxa->gfxas);
+    hashtable_hash_in(gfxa_idset, &gfxa->gfxas_id, gfxa->id);
+
+    device_register(gfxa->dev, &gfxa_class, "gfxa%d", gfxa->id);
+}
+
+struct gfxa*
+gfxm_adapter(int gfxa_id)
+{
+    struct gfxa *pos, *n;
+    hashtable_hash_foreach(gfxa_idset, gfxa_id, pos, n, gfxas_id)
+    {
+        if (pos->id == gfxa_id) {
+            return pos;
+        }
+    }
+
+    return NULL;
+}
+
+int
+gfxm_set_lut(struct gfxa* gfxa, u32_t* lut, size_t len)
+{
+    // It is generally not feasible for graphic adapter with >256 colors still
+    // using color lut
+    if (unlikely(len > 256)) {
+        return EINVAL;
+    }
+
+    struct disp_profile* disp = &gfxa->disp_info;
+    size_t lutsz = len * sizeof(*lut);
+
+    if (disp->clut.len != len) {
+        vfree_safe(disp->clut.val);
+        disp->clut.val = valloc(lutsz);
+        disp->clut.len = len;
+    }
+
+    memcpy(disp->clut.val, lut, lutsz);
+
+    return 0;
+}
\ No newline at end of file
index 08bc54ba29ee039614f3255e286fe0d329789521..020e00ce36ab2952df6bddeb76802e40a81d18d6 100644 (file)
@@ -13,6 +13,7 @@
 #include <lunaix/device.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/spike.h>
 #include <lunaix/device.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/spike.h>
+#include <lunaix/status.h>
 
 #include <sys/cpu.h>
 
 
 #include <sys/cpu.h>
 
@@ -119,7 +120,7 @@ vga_crt_update(struct vga* state)
 
     // framebuffer: 16bit granule
     u32_t divsor = 2 * 2;
 
     // framebuffer: 16bit granule
     u32_t divsor = 2 * 2;
-    if (state->lut.len == 256) {
+    if (state->crt.depth == 256) {
         // if 8 bit color is used, 2 pixels per granule
         divsor *= 2;
     } else if ((state->options & VGA_MODE_GFX)) {
         // if 8 bit color is used, 2 pixels per granule
         divsor *= 2;
     } else if ((state->options & VGA_MODE_GFX)) {
@@ -135,32 +136,35 @@ vga_crt_update(struct vga* state)
 }
 
 void
 }
 
 void
-vga_update_palette(struct vga* state)
+vga_update_palette(struct vga* state, u32_t* lut, size_t len)
 {
 {
-    state->reg_ops.set_dac_palette(state);
-
     u32_t index[16];
     u32_t index[16];
-    u32_t clr_len = MIN(state->lut.len, 16);
+    u32_t clr_len = MIN(len, 16);
     for (size_t i = 0; i < clr_len; i++) {
         index[i] = i;
     }
 
     for (size_t i = 0; i < clr_len; i++) {
         index[i] = i;
     }
 
+    state->reg_ops.set_dac_palette(state, lut, len);
     state->reg_ops.set_seq(state, VGA_ARX, 0, index, clr_len);
 }
 
     state->reg_ops.set_seq(state, VGA_ARX, 0, index, clr_len);
 }
 
-void
+int
 vga_reload_config(struct vga* state)
 {
     cpu_disable_interrupt();
 
 vga_reload_config(struct vga* state)
 {
     cpu_disable_interrupt();
 
+    int err = 0;
     struct vga_regops* reg = &state->reg_ops;
 
     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");
+    u32_t color = state->crt.depth;
+    if (!(color == 2 || color == 4 || color == 16 || color == 256)) {
+        err = EINVAL;
+        goto done;
+    }
 
 
-    if (!(state->options & VGA_MODE_GFX)) {
-        assert(color < 256);
+    if (!(state->options & VGA_MODE_GFX) && color > 256) {
+        err = EINVAL;
+        goto done;
     }
 
     // estimate actual fb size
     }
 
     // estimate actual fb size
@@ -173,17 +177,20 @@ vga_reload_config(struct vga* state)
         total_px = total_px * 2;
     }
 
         total_px = total_px * 2;
     }
 
-    assert(state->fb_sz >= total_px);
-    state->fb_sz = total_px;
+    if (state->fb_sz && state->fb_sz < total_px) {
+        err = EINVAL;
+    }
 
 
-    reg->write(state, VGA_SRX, VGA_SR00, 0x0, ALL_FIELDS);
+    state->fb_sz = total_px;
 
     // 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;
 
 
     // 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);
+    if (!(clk_f && clk_f <= 28)) {
+        err = EINVAL;
+    }
 
     // require 28 MHz clock
     if (clk_f > 25) {
 
     // require 28 MHz clock
     if (clk_f > 25) {
@@ -191,6 +198,7 @@ vga_reload_config(struct vga* state)
     }
     // 25 MHz clock: 0b00 << 2
 
     }
     // 25 MHz clock: 0b00 << 2
 
+    reg->write(state, VGA_SRX, VGA_SR00, 0x0, ALL_FIELDS);
     reg->write(state, VGA_MISCX, 0, misc, 0b1111);
 
     // SEQN_CLK: shift every CCLK, DCLK passthrough, 8/9 DCLK
     reg->write(state, VGA_MISCX, 0, misc, 0b1111);
 
     // SEQN_CLK: shift every CCLK, DCLK passthrough, 8/9 DCLK
@@ -219,8 +227,8 @@ vga_reload_config(struct vga* state)
         reg->write(
           state, VGA_GRX, VGA_GR05, (c256 << 6) | (1 << 4), ALL_FIELDS);
 
         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);
+        // Legacy GFX FB (for compatibility): 0xb8000, GFX mode
+        reg->write(state, VGA_GRX, VGA_GR06, 0b1111, ALL_FIELDS);
 
     } else { // AN MOODE
         // Only map 0,1 enabled, (ascii and attribute)
 
     } else { // AN MOODE
         // Only map 0,1 enabled, (ascii and attribute)
@@ -252,9 +260,9 @@ vga_reload_config(struct vga* state)
     reg->write(state, VGA_ARX, VGA_AR13, 0, ALL_FIELDS);
     reg->write(state, VGA_ARX, VGA_AR14, 0, 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);
 
     reg->write(state, VGA_SRX, VGA_SR00, 0x3, ALL_FIELDS);
 
+done:
     cpu_enable_interrupt();
     cpu_enable_interrupt();
+    return err;
 }
 }
index 86afe4e06b3a6b7c984b6559264a664dc734e260..cd4a1b0ad8829e853878104a58faa1fc6beada23 100644 (file)
@@ -176,7 +176,7 @@ struct vga_regops
     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 (*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*);
+    void (*set_dac_palette)(struct vga*, u32_t*, size_t);
 };
 
 struct vga
 };
 
 struct vga
@@ -193,14 +193,9 @@ struct vga
         size_t pel_dot; // pixel per dot clock
         size_t freq;
         size_t fb_off;
         size_t pel_dot; // pixel per dot clock
         size_t freq;
         size_t fb_off;
+        size_t depth;
     } crt;
 
     } crt;
 
-    struct
-    {
-        u32_t* colors;
-        u32_t len;
-    } lut;
-
     struct vga_regops reg_ops;
 };
 
     struct vga_regops reg_ops;
 };
 
@@ -226,7 +221,10 @@ vga_new_state(ptr_t reg_base, ptr_t fb, ptr_t fb_sz);
 void
 vga_config_rect(struct vga*, size_t width, size_t hight, size_t freq, int d9);
 
 void
 vga_config_rect(struct vga*, size_t width, size_t hight, size_t freq, int d9);
 
-void
+int
 vga_reload_config(struct vga*);
 
 vga_reload_config(struct vga*);
 
+void
+vga_update_palette(struct vga* state, u32_t* lut, size_t len);
+
 #endif /* __LUNAIX_VGA_H */
 #endif /* __LUNAIX_VGA_H */
diff --git a/lunaix-os/hal/gfxa/vga/vga_gfxm_ops.c b/lunaix-os/hal/gfxa/vga/vga_gfxm_ops.c
new file mode 100644 (file)
index 0000000..0813da3
--- /dev/null
@@ -0,0 +1,71 @@
+#include "vga.h"
+#include <hal/gfxm.h>
+#include <klibc/string.h>
+
+static int
+__vga_gfxa_update_profile(struct gfxa* gfxa)
+{
+    struct vga* v = (struct vga*)gfxa->hw_obj;
+    struct disp_profile* profile = &gfxa->disp_info;
+
+    v->crt.depth = profile->mon.depth;
+    v->options = VGA_MODE_GFX;
+
+    vga_config_rect(
+      v, profile->mon.w_px, profile->mon.h_px, profile->mon.freq, 0);
+
+    int err = vga_reload_config(v);
+
+    if (!err && profile->clut.val) {
+        vga_update_palette(v, profile->clut.val, profile->clut.len);
+    }
+
+    return err;
+}
+
+static int
+__vga_gfxa_rreads(struct gfxa* gfxa, u32_t* map, void* rxbuf, size_t map_sz)
+{
+    return 0;
+}
+
+static int
+__vga_gfxa_rwrites(struct gfxa* gfxa, u32_t* map, void* txbuf, size_t map_sz)
+{
+    return 0;
+}
+
+static int
+__vga_gfxa_vmcpy(struct gfxa* gfxa, void* buf, off_t off, size_t sz)
+{
+    struct vga* v = (struct vga*)gfxa->hw_obj;
+
+    if (off + sz > v->fb_sz) {
+        return 0;
+    }
+
+    ptr_t vram_start = v->fb + off;
+    memcpy((void*)vram_start, buf, sz);
+
+    return sz;
+}
+
+static int
+__vga_gfxa_lfbcpy(struct gfxa* gfxa, void* buf, off_t off, size_t sz)
+{
+    return __vga_gfxa_vmcpy(gfxa, buf, off, sz);
+}
+
+static int
+__vga_gfxa_hwioctl(struct gfxa* gfxa, int req, va_list args)
+{
+    // TODO
+    return 0;
+}
+
+struct gfxa_ops vga_gfxa_ops = { .update_profile = __vga_gfxa_update_profile,
+                                 .rreads = __vga_gfxa_rreads,
+                                 .rwrites = __vga_gfxa_rwrites,
+                                 .vmcpy = __vga_gfxa_vmcpy,
+                                 .lfbcpy = __vga_gfxa_lfbcpy,
+                                 .hwioctl = __vga_gfxa_hwioctl };
\ No newline at end of file
index 4ec8c3ead5bc44906094e0da5483d1c80509f14a..5e2193e152fd261bcf2930b9a535e36850c131a1 100644 (file)
@@ -63,7 +63,7 @@ vga_mmio_set_regs(struct vga* v, u32_t type, size_t off, u32_t* seq, size_t len)
 }
 
 static void
 }
 
 static void
-vga_mmio_set_dacp(struct vga* v)
+vga_mmio_set_dacp(struct vga* v, u32_t* lut, size_t len)
 {
 #define R(c) (u8_t)(((c) & 0xff0000) >> 16)
 #define G(c) (u8_t)(((c) & 0x00ff00) >> 8)
 {
 #define R(c) (u8_t)(((c) & 0xff0000) >> 16)
 #define G(c) (u8_t)(((c) & 0x00ff00) >> 8)
@@ -72,11 +72,9 @@ vga_mmio_set_dacp(struct vga* v)
     vga_reg8* reg_ix = regaddr(VGA_DACX, VGA_REG_X, v);
     vga_reg8* reg_dat = regaddr(VGA_DACX, VGA_REG_D, v);
 
     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;
     *reg_ix = 0;
-    for (size_t i = 0; i < v->lut.len; i++) {
-        u32_t color = color_map[i];
+    for (size_t i = 0; i < len; i++) {
+        u32_t color = lut[i];
         *reg_dat = R(color);
         *reg_dat = G(color);
         *reg_dat = B(color);
         *reg_dat = R(color);
         *reg_dat = G(color);
         *reg_dat = B(color);
index baf7fa4f49f8461e07e2d8df2f6888d82c038b48..5d4ed8d3e100bcf1867d6d84c6171a05c7c98269 100644 (file)
@@ -4,6 +4,7 @@
 #include <lunaix/spike.h>
 #include <lunaix/status.h>
 
 #include <lunaix/spike.h>
 #include <lunaix/status.h>
 
+#include <hal/gfxm.h>
 #include <hal/pci.h>
 #include <sys/pci_hba.h>
 
 #include <hal/pci.h>
 #include <sys/pci_hba.h>
 
@@ -81,14 +82,17 @@ vga_pci_init(struct device_def* devdef, struct device* pcidev_base)
     struct vga* vga_state =
       vga_new_state(mmio_mapped + VGA_REG_OFF, fb_mapped, FB256K);
     vga_state->reg_ops = vga_default_mmio_ops;
     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);
+    struct gfxa* vga_gfxa = gfxm_alloc_adapter(vga_state);
+    extern struct gfxa_ops vga_gfxa_ops;
+    vga_gfxa->ops = vga_gfxa_ops;
 
 
-    // TEMP: Test the change of VGA display mode and resolution
-    // vga_reload_config(vga_state);
+    // Preload a VESA-compilant configuration
+    vga_gfxa->disp_info = (struct disp_profile){
+        .mon = { .w_px = 640, .h_px = 480, .freq = 60, .depth = 16 }
+    };
+
+    gfxm_register(vga_gfxa);
 
     return 0;
 }
 
     return 0;
 }
@@ -98,9 +102,9 @@ vga_pci_init(struct device_def* devdef, struct device* pcidev_base)
 static struct pci_device_def vga_pci_devdef = {
     .dev_class = VGA_PCI_CLASS,
     .dev_ident = PCI_DEVIDENT(0x1234, 0x1111),
 static struct pci_device_def vga_pci_devdef = {
     .dev_class = VGA_PCI_CLASS,
     .dev_ident = PCI_DEVIDENT(0x1234, 0x1111),
-    .ident_mask = -1,
+    .ident_mask = PCI_MATCH_EXACT,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_DISP, DEV_VGA),
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_DISP, DEV_VGA),
-                .name = "VGA Generic Driver",
+                .name = "Generic VGA",
                 .init_for = vga_pci_init }
 };
                 .init_for = vga_pci_init }
 };
-EXPORT_DEVICE(vga_pci, &vga_pci_devdef.devdef, load_pci_probe);
\ No newline at end of file
+EXPORT_PCI_DEVICE(vga_pci, &vga_pci_devdef);
\ No newline at end of file
index 7a1967ed4b5d48d54057c1d6a837a8b772ed10bb..bc1e7cca7f307729e897261b18226bb53e8e75f6 100644 (file)
@@ -304,6 +304,19 @@ __pci_bar_gonext(struct twimap* map)
     return 1;
 }
 
     return 1;
 }
 
+static void
+__pci_read_binding(struct twimap* map)
+{
+    struct pci_device* pcidev = twimap_data(map, struct pci_device*);
+    // check if device binding has been initialized
+    struct device* dev = device_cast(&pcidev->dev);
+    if (!dev) {
+        return;
+    }
+
+    twimap_printf(map, "0x%x:0x%x", dev->ident.fn_grp, dev->ident.unique);
+}
+
 void
 pci_build_fsmapping()
 {
 void
 pci_build_fsmapping()
 {
@@ -329,6 +342,9 @@ pci_build_fsmapping()
         map = twifs_mapping(pci_dev, pos, "class");
         map->read = __pci_read_class;
 
         map = twifs_mapping(pci_dev, pos, "class");
         map->read = __pci_read_class;
 
+        map = twifs_mapping(pci_dev, pos, "binding");
+        map->read = __pci_read_binding;
+
         map = twifs_mapping(pci_dev, pos, "io_bases");
         map->read = __pci_bar_read;
         map->go_next = __pci_bar_gonext;
         map = twifs_mapping(pci_dev, pos, "io_bases");
         map->read = __pci_bar_read;
         map->go_next = __pci_bar_gonext;
diff --git a/lunaix-os/includes/hal/gfxm.h b/lunaix-os/includes/hal/gfxm.h
new file mode 100644 (file)
index 0000000..bb30d50
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __LUNAIX_GFXM_H
+#define __LUNAIX_GFXM_H
+
+#include <lunaix/device.h>
+#include <usr/lunaix/gfx.h>
+
+struct gfxa;
+
+struct disp_profile
+{
+    struct gfxa_mon mon;
+
+    struct
+    {
+        color_t* val;
+        size_t len;
+    } clut;
+};
+
+struct gfxa_ops
+{
+    int (*update_profile)(struct gfxa*);
+    /**
+     * @brief Read adapter registers
+     *
+     */
+    int (*rreads)(struct gfxa*, u32_t* map, void* rxbuf, size_t map_sz);
+    /**
+     * @brief Write adapter registers
+     *
+     */
+    int (*rwrites)(struct gfxa*, u32_t* map, void* txbuf, size_t map_sz);
+    /**
+     * @brief send data to VRAM
+     *
+     */
+    int (*vmcpy)(struct gfxa*, void*, off_t, size_t);
+    /**
+     * @brief send logical frame buffer to adapter
+     *
+     */
+    int (*lfbcpy)(struct gfxa*, void*, off_t, size_t);
+    /**
+     * @brief Execute hardware dependent ioctl command
+     *
+     */
+    int (*hwioctl)(struct gfxa*, int, va_list);
+};
+
+struct gfxa
+{
+    struct device* dev;
+    struct llist_header gfxas;
+    struct hlist_node gfxas_id;
+    struct disp_profile disp_info;
+    int id;
+    void* hw_obj;
+
+    struct gfxa_ops ops;
+};
+
+struct gfxa*
+gfxm_alloc_adapter(void* hw_obj);
+
+void
+gfxm_register(struct gfxa*);
+
+struct gfxa*
+gfxm_adapter(int gfxa_id);
+
+int
+gfxm_set_lut(struct gfxa*, color_t* lut, size_t len);
+
+#endif /* __LUNAIX_GFXM_H */
\ No newline at end of file
index 3131aba50e414f33b101fcc2eedb3aa2fffd0f62..8c18997bc4fc14f0b96f278e70968c17557d5241 100644 (file)
@@ -6,6 +6,13 @@
 #include <lunaix/ds/llist.h>
 #include <lunaix/types.h>
 
 #include <lunaix/ds/llist.h>
 #include <lunaix/types.h>
 
+#define EXPORT_PCI_DEVICE(id, pci_devdef)                                      \
+    EXPORT_DEVICE(id, &(pci_devdef)->devdef, load_pci_probe)
+
+#define PCI_MATCH_EXACT -1
+#define PCI_MATCH_ANY 0
+#define PCI_MATCH_VENDOR 0xffff
+
 #define PCI_TDEV 0x0
 #define PCI_TPCIBRIDGE 0x1
 #define PCI_TCARDBRIDGE 0x2
 #define PCI_TDEV 0x0
 #define PCI_TPCIBRIDGE 0x1
 #define PCI_TCARDBRIDGE 0x2
index ad2d8a71b12a509d7bcfd20ff0ae6f5576011c74..af1814af5b19ce69e8ba607b8b475a5ee8c4e92d 100644 (file)
@@ -96,7 +96,8 @@
 #define DEV_NULL 9
 #define DEV_ZERO 10
 #define DEV_KBD 11
 #define DEV_NULL 9
 #define DEV_ZERO 10
 #define DEV_KBD 11
-#define DEV_VGA 12
+#define DEV_GFXA 12
+#define DEV_VGA 13
 
 struct devident
 {
 
 struct devident
 {
diff --git a/lunaix-os/includes/usr/lunaix/gfx.h b/lunaix-os/includes/usr/lunaix/gfx.h
new file mode 100644 (file)
index 0000000..e583be1
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __LUNAIX_UGFX_H
+#define __LUNAIX_UGFX_H
+
+#define GFX_CMDA(type, cmd_id) (((type) << 8) | ((cmd_id) & 0xf))
+
+#define GFX_ADAPTER_INFO 1
+#define GFX_ADAPTER_REG_RD 2
+#define GFX_ADAPTER_REG_WR 3
+#define GFX_ADAPTER_CHMODE 4
+#define GFX_ADAPTER_LUT_WR 5
+#define GFX_ADAPTER_LUT_RD 6
+#define GFX_ADAPTER_VMCPY 7
+#define GFX_ADAPTER_LFBCPY 8
+
+typedef unsigned int color_t;
+
+struct gfxa_info
+{
+    struct
+    {
+        unsigned int w_px;
+        unsigned int h_px;
+        unsigned int depth;
+        unsigned int freq;
+    } disp_mode;
+
+    void* hwdep_info;
+};
+
+struct gfxa_mon
+{
+    unsigned int w_px;
+    unsigned int h_px;
+    unsigned int depth;
+    unsigned int freq;
+};
+
+struct gfxa_clut
+{
+    color_t* val;
+    size_t len;
+};
+
+#endif /* __LUNAIX_UGFX_H */