PCI 16x50 UART Controller, O2 Enablement (#39)
authorLunaixsky <lunaixsky@qq.com>
Sun, 21 Jul 2024 19:45:46 +0000 (20:45 +0100)
committerGitHub <noreply@github.com>
Sun, 21 Jul 2024 19:45:46 +0000 (20:45 +0100)
* add PCI 16x50 uart controller, refactor the 16x50 structure

* refactor the pci detection mechanism, allow custom compatibility
  check logic.

* fix bug in pci device definition binding where only bind once

* refactor the 16x50 controller structure, move pmio and mmio
  as separated component and does not need to couple with interface

* fix issue where x86:isrm_ivexalloc alloc duplicated interrupt vector

* change the signature of ioremap to return ptr_t instead of generic
  pointer

* fix issue in LunaConfig header export, where non string type being
  joined as a string type

* add config term for 16x50 controller.

* rework the usr/testp, allow user to specify serial interface

* usr/ls, add a slash after directory file name to distinguish

* add the implementation for iounmap

* refactor pci dev to use latest change in pci

* remove the out-dated, mask based compatibility check scheme

* rectify the issues with -O2 optimization

* refactor: allow Lunaix to compile with -O2 optimization
* add LConfig terms for PCI related features
* add LConfig terms for AHCI related features
* refactor the pci device code base with latest pci refactoring
* fix: fail to read bool type config term when the value of the
       term is False
* refactor: LConfig: allow omit the `LConfig` when doing include

* remove legacy file

47 files changed:
lunaix-os/LConfig
lunaix-os/arch/generic/includes/sys/pci_hba.h [deleted file]
lunaix-os/arch/x86/boot/x86_64/kremap64.c
lunaix-os/arch/x86/exceptions/intr_routines.c
lunaix-os/arch/x86/exceptions/isrm.c
lunaix-os/arch/x86/hal/LBuild
lunaix-os/arch/x86/hal/apic.c
lunaix-os/arch/x86/hal/ioapic.c
lunaix-os/arch/x86/hal/pci.c [moved from lunaix-os/arch/x86/includes/sys/pci_hba.h with 69% similarity]
lunaix-os/arch/x86/includes/sys/abi64.h
lunaix-os/hal/LConfig [new file with mode: 0644]
lunaix-os/hal/ahci/LBuild
lunaix-os/hal/ahci/LConfig [new file with mode: 0644]
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/ahci/ahci_pci.c
lunaix-os/hal/bus/LBuild
lunaix-os/hal/bus/LConfig [new file with mode: 0644]
lunaix-os/hal/bus/pci.c
lunaix-os/hal/char/LConfig [new file with mode: 0644]
lunaix-os/hal/char/serial.c
lunaix-os/hal/char/uart/16550_pmio.c [deleted file]
lunaix-os/hal/char/uart/16x50.h [moved from lunaix-os/hal/char/uart/16550.h with 84% similarity]
lunaix-os/hal/char/uart/16x50_base.c [moved from lunaix-os/hal/char/uart/16550_base.c with 84% similarity]
lunaix-os/hal/char/uart/16x50_isa.c [new file with mode: 0644]
lunaix-os/hal/char/uart/16x50_mmio.c [new file with mode: 0644]
lunaix-os/hal/char/uart/16x50_pci.c [new file with mode: 0644]
lunaix-os/hal/char/uart/16x50_pmio.c [new file with mode: 0644]
lunaix-os/hal/char/uart/LBuild
lunaix-os/hal/char/uart/LConfig [new file with mode: 0644]
lunaix-os/hal/gfxa/vga/vga_pci.c
lunaix-os/includes/hal/pci.h
lunaix-os/includes/lunaix/kpreempt.h
lunaix-os/includes/lunaix/mm/mmio.h
lunaix-os/includes/lunaix/mm/page.h
lunaix-os/kernel/LConfig
lunaix-os/kernel/kinit.c
lunaix-os/kernel/mm/mmio.c
lunaix-os/live_debug.sh
lunaix-os/makeinc/toolchain.mkinc
lunaix-os/scripts/build-tools/integration/config_io.py
lunaix-os/scripts/build-tools/integration/render_ishell.py
lunaix-os/scripts/build-tools/lcfg/builtins.py
lunaix-os/scripts/qemu.py
lunaix-os/scripts/qemus/qemu_x86_dev.json
lunaix-os/usr/LBuild
lunaix-os/usr/ls.c
lunaix-os/usr/testp.c

index ecd4a032dca06aef54962f3be95b5f55be4bd926..fef122188449c0736e5c46540d2efa1b549d2ea4 100644 (file)
@@ -1,7 +1,8 @@
 import time
 
-include("kernel/LConfig")
-include("arch/LConfig")
+include("kernel")
+include("arch")
+include("hal")
 
 @Term("Version")
 @ReadOnly
diff --git a/lunaix-os/arch/generic/includes/sys/pci_hba.h b/lunaix-os/arch/generic/includes/sys/pci_hba.h
deleted file mode 100644 (file)
index f3747bf..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __LUNAIX_ARCH_PCI_HBA_H
-#define __LUNAIX_ARCH_PCI_HBA_H
-
-#include <hal/pci.h>
-#include <lunaix/types.h>
-
-#define PCI_MSI_BASE 0
-
-static inline pci_reg_t
-pci_read_cspace(ptr_t base, int offset)
-{
-    return 0;
-}
-
-static inline void
-pci_write_cspace(ptr_t base, int offset, pci_reg_t data)
-{
-    return;
-}
-
-static inline u16_t 
-pci_config_msi_data(int vector) {
-    return vector;
-}
-
-static inline ptr_t 
-pci_get_msi_base() {
-    return 0;
-}
-
-#endif /* __LUNAIX_ARCH_PCI_HBA_H */
index ee9d298bac8e58951e029562a8509bb5ef0c016e..bf3bb33dd552ff80c73272c1c6bf256ff887854b 100644 (file)
@@ -178,9 +178,12 @@ ptr_t boot_text
 remap_kernel()
 {
     ptr_t kmap_pa = to_kphysical(&kpt);
-    for (size_t i = 0; i < sizeof(kpt); i++) {
-        ((u8_t*)kmap_pa)[i] = 0;
-    }
+    
+    asm volatile("movq %1, %%rdi\n"
+                 "rep stosb\n" ::"c"(sizeof(kpt)),
+                 "r"(kmap_pa),
+                 "a"(0)
+                 : "rdi", "memory");
 
     do_remap();
 
index 05f547e9c60c441b8d6c3e52e21fb2b1ea24a90b..d355927dd2b83851a052dbb9532b0153fc1ae669 100644 (file)
@@ -39,6 +39,12 @@ intr_routine_general_protection(const struct hart_state* state)
     __print_panic_msg("general protection", state);
 }
 
+void
+intr_routine_invl_opcode(const struct hart_state* state)
+{
+    __print_panic_msg("invalid opcode", state);
+}
+
 void
 intr_routine_sys_panic(const struct hart_state* state)
 {
@@ -89,6 +95,7 @@ intr_routine_init()
     isrm_bindiv(FAULT_GENERAL_PROTECTION, intr_routine_general_protection);
     isrm_bindiv(FAULT_PAGE_FAULT, intr_routine_page_fault);
     isrm_bindiv(FAULT_STACK_SEG_FAULT, intr_routine_page_fault);
+    isrm_bindiv(FAULT_INVALID_OPCODE, intr_routine_invl_opcode);
 
     isrm_bindiv(LUNAIX_SYS_PANIC, intr_routine_sys_panic);
     isrm_bindiv(LUNAIX_SCHED, intr_routine_sched);
index 89ff616bd0f9b9d0ef4a7b0698f6483329f46ecb..dcd576aad1c5f177a873c8e45295e91b22d48973 100644 (file)
@@ -51,6 +51,11 @@ __ivalloc_within(size_t a, size_t b, isr_cb handler)
             k++;
         }
 
+        if (j == 8) {
+            j = 0;
+            continue;
+        }
+
         if (k > b) {
             break;
         }
index 66fff6a1c7fddeca6e48c2c2aac9c920887ba9e8..f3a3cae2abf28b9a22cdc2783f8c2407b8f139ef 100644 (file)
@@ -5,5 +5,6 @@ sources([
     "ps2kbd.c",
     "apic_timer.c",
     "ioapic.c",
-    "mc146818a.c"
+    "mc146818a.c",
+    "pci.c"
 ])
\ No newline at end of file
index 4e2501f93a95f600290eba6348b3cca112abd168..34b243eed6b0ce12f8b28116f9620b23b877f941 100644 (file)
@@ -43,7 +43,7 @@ apic_init()
     // As we are going to use APIC, disable the old 8259 PIC
     pic_disable();
 
-    _apic_base = (ptr_t)ioremap(__APIC_BASE_PADDR, 4096);
+    _apic_base = ioremap(__APIC_BASE_PADDR, 4096);
 
     // Hardware enable the APIC
     // By setting bit 11 of IA32_APIC_BASE register
index 83ce6a09a2a476588cfe321d2a7f9a0b1654cb02..1e0755a1426807990508dc1a78a0b8b809585ba0 100644 (file)
@@ -38,7 +38,7 @@ ioapic_init()
     acpi_context* acpi_ctx = acpi_get_context();
 
     _ioapic_base =
-      (ptr_t)ioremap(acpi_ctx->madt.ioapic->ioapic_addr & ~0xfff, 4096);
+        ioremap(acpi_ctx->madt.ioapic->ioapic_addr & ~0xfff, 4096);
 }
 
 void
similarity index 69%
rename from lunaix-os/arch/x86/includes/sys/pci_hba.h
rename to lunaix-os/arch/x86/hal/pci.c
index 74d9c033a9b605c52d62a71b406ba8dee91e6ef1..f1321b2a7a7d71aeb435f0ebce803dc9ad4e3897 100644 (file)
@@ -1,37 +1,33 @@
-#ifndef __LUNAIX_PCI_HBA_H
-#define __LUNAIX_PCI_HBA_H
-
 #include <hal/pci.h>
-#include <lunaix/types.h>
-
-#include "port_io.h"
+#include <sys/port_io.h>
 
+#ifdef CONFIG_PCI_PMIO
 #define PCI_CONFIG_ADDR 0xcf8
 #define PCI_CONFIG_DATA 0xcfc
 
-static inline pci_reg_t
+pci_reg_t
 pci_read_cspace(ptr_t base, int offset)
 {
     port_wrdword(PCI_CONFIG_ADDR, base | (offset & ~0x3));
     return port_rddword(PCI_CONFIG_DATA);
 }
 
-static inline void
+void
 pci_write_cspace(ptr_t base, int offset, pci_reg_t data)
 {
     port_wrdword(PCI_CONFIG_ADDR, base | (offset & ~0x3));
     port_wrdword(PCI_CONFIG_DATA, data);
 }
 
-static inline u16_t 
+#endif
+
+u16_t
 pci_config_msi_data(int vector) {
     return vector;
 }
 
-static inline ptr_t 
+ptr_t
 pci_get_msi_base() {
     return 0xFEE00000;
 }
 
-
-#endif /* __LUNAIX_PCI_HBA_H */
index 1c93cc1fd2cc97084f61eacf122ee1830e80212b..1dce9b03d1842e974d3ffc9e4a08b87d0e2fb7ad 100644 (file)
@@ -32,7 +32,7 @@ static inline ptr_t must_inline
 abi_get_callframe()
 {
     ptr_t val;
-    asm("movq %%rbp, %0" : "=r"(val)::);
+    asm volatile("movq %%rbp, %0" : "=r"(val)::"memory");
     return val;
 }
 
diff --git a/lunaix-os/hal/LConfig b/lunaix-os/hal/LConfig
new file mode 100644 (file)
index 0000000..35385c9
--- /dev/null
@@ -0,0 +1,9 @@
+include("char")
+include("bus")
+include("ahci")
+
+@Collection
+def hal():
+    """ Lunaix hardware asbtraction layer """
+
+    pass
\ No newline at end of file
index 8c081c6b12d91fb9619391ffbae6cf0d8d7a11c6..7da89abe6dd9091e128a120b371f37d8184b83d4 100644 (file)
@@ -1,9 +1,10 @@
-sources([
-    "ahci_pci.c",
-    "hbadev_export.c",
-    "ahci.c",
-    "utils.c",
-    "io_event.c",
-    "atapi.c",
-    "ata.c"
-])
\ No newline at end of file
+if config("ahci_enable"):
+    sources([
+        "ahci_pci.c",
+        "hbadev_export.c",
+        "ahci.c",
+        "utils.c",
+        "io_event.c",
+        "atapi.c",
+        "ata.c"
+    ])
\ No newline at end of file
diff --git a/lunaix-os/hal/ahci/LConfig b/lunaix-os/hal/ahci/LConfig
new file mode 100644 (file)
index 0000000..b957881
--- /dev/null
@@ -0,0 +1,18 @@
+
+@Collection
+def sata_ahci():
+
+    add_to_collection(hal)
+
+    @Term
+    def ahci_enable():
+        """ Enable the support of SATA AHCI. 
+            Must require PCI at current stage """
+        
+        type(bool)
+        default(True)
+
+        if not v(pci_enable):
+            set_value(False)
+
+        
\ No newline at end of file
index bd84bf8a6f6cf88eb946bf3f605a7df7e5fba05d..82375e0a9dda85670435f1e2c21d4e09ea40b392 100644 (file)
@@ -14,7 +14,6 @@
 #include <hal/ahci/scsi.h>
 #include <hal/pci.h>
 
-#include <sys/pci_hba.h>
 #include <sys/port_io.h>
 
 #include <klibc/string.h>
index 0ecde58061af4ed37a1e78ab8e7c706355d57cf7..6c59cf8455e76935d7220cc9b95581171788c7fb 100644 (file)
@@ -2,25 +2,33 @@
 
 #include <hal/ahci/ahci.h>
 #include <hal/pci.h>
-#include <sys/pci_hba.h>
 
 static int
 ahci_pci_bind(struct device_def* def, struct device* dev)
 {
-    struct pci_device* ahci_dev = container_of(dev, struct pci_device, dev);
+    struct pci_device* ahci_dev;
+    struct pci_base_addr* bar6;
+    struct ahci_driver* ahci_drv;
 
-    struct pci_base_addr* bar6 = &ahci_dev->bar[5];
-    assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO.");
+    ahci_dev = PCI_DEVICE(dev);
+    bar6 = pci_device_bar(ahci_dev, 5);
+    assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO.");
 
-    pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD);
+    pci_reg_t cmd = 0;
+    pci_cmd_set_bus_master(&cmd);
+    pci_cmd_set_mmio(&cmd);
+    pci_cmd_set_msi(&cmd);
+    pci_apply_command(ahci_dev, cmd);
 
-    // 禁用传统中断(因为我们使用MSI),启用MMIO访问,允许PCI设备间访问
-    cmd |= (PCI_RCMD_MM_ACCESS | PCI_RCMD_DISABLE_INTR | PCI_RCMD_BUS_MASTER);
-
-    pci_write_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD, cmd);
-
-    int iv = isrm_ivexalloc(ahci_hba_isr);
-    pci_setup_msi(ahci_dev, iv);
+    int iv;
+    if (pci_capability_msi(ahci_dev)) {
+        iv = isrm_ivexalloc(ahci_hba_isr);
+        pci_setup_msi(ahci_dev, iv);
+    }
+    else {
+        iv = pci_intr_irq(ahci_dev);
+        iv = isrm_bindirq(iv, ahci_hba_isr);
+    }
 
     struct ahci_driver_param param = {
         .mmio_base = bar6->start,
@@ -28,7 +36,7 @@ ahci_pci_bind(struct device_def* def, struct device* dev)
         .ahci_iv = iv,
     };
 
-    struct ahci_driver* ahci_drv = ahci_driver_init(&param);
+    ahci_drv = ahci_driver_init(&param);
     pci_bind_instance(ahci_dev, ahci_drv);
 
     return 0;
@@ -40,12 +48,19 @@ ahci_pci_init(struct device_def* def)
     return pci_bind_definition_all(pcidev_def(def));
 }
 
+static bool
+ahci_pci_compat(struct pci_device_def* def, 
+                struct pci_device* pcidev)
+{
+    return pci_device_class(pcidev) == AHCI_HBA_CLASS;
+}
+
+
 static struct pci_device_def ahcidef = {
-    .dev_class = AHCI_HBA_CLASS,
-    .ident_mask = PCI_MATCH_ANY,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
-                .name = "Generic SATA",
+                .name = "Generic AHCI",
                 .init = ahci_pci_init,
-                .bind = ahci_pci_bind }
+                .bind = ahci_pci_bind },
+    .test_compatibility = ahci_pci_compat
 };
 EXPORT_PCI_DEVICE(ahci, &ahcidef, load_postboot);
\ No newline at end of file
index a485ce79f8c17d2c81af2d0c5df7b7ccebd2ffaf..3b5ff38ba1cdee2a21bd59d94282fb9b20fb8c0a 100644 (file)
@@ -1,3 +1,3 @@
-sources([
-    "pci.c"
-])
\ No newline at end of file
+
+if config("pci_enable"):
+    sources("pci.c")
\ No newline at end of file
diff --git a/lunaix-os/hal/bus/LConfig b/lunaix-os/hal/bus/LConfig
new file mode 100644 (file)
index 0000000..74e3dbf
--- /dev/null
@@ -0,0 +1,35 @@
+
+@Collection
+def bus_if():
+    """ System/platform bus interface """
+
+    add_to_collection(hal)
+
+    @Term
+    def pci_enable():
+        """ Peripheral Component Interconnect (PCI) Bus """
+        type(bool)
+        default(True)
+
+    @Term
+    def pcie_ext():
+        """ Enable support of PCI-Express extension """
+        type(bool)
+        default(False)
+
+        return v(pci_enable)
+
+    @Term
+    def pci_pmio():
+        """ Use port-mapped I/O interface for controlling PCI """
+        type(bool)
+
+        has_pcie = v(pcie_ext)
+        is_x86 = v(arch) in [ "i386", "x86_64" ]
+
+        default(not has_pcie)
+        
+        if not is_x86 or has_pcie:
+            set_value(False)
+
+        return is_x86 and v(pci_enable)
\ No newline at end of file
index af7a256f50b47614298cc213eb8821a83f40059d..6d26d09d7d4c4e789267c6f934ed8a31403cd487 100644 (file)
@@ -9,7 +9,6 @@
  *
  */
 #include <hal/pci.h>
-#include <sys/pci_hba.h>
 
 #include <klibc/string.h>
 #include <lunaix/fs/twifs.h>
@@ -71,23 +70,19 @@ pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo)
 }
 
 int
-pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
+pci_bind_definition(struct pci_device_def* pcidef, bool* more)
 {
-    u32_t class = pcidev_def->dev_class;
-    u32_t devid_mask = pcidev_def->ident_mask;
-    u32_t devid = pcidev_def->dev_ident & devid_mask;
-
-    if (!pcidev_def->devdef.bind) {
+    if (!pcidef->devdef.bind) {
         ERROR("pcidev %xh:%xh.%d is unbindable",
-              pcidev_def->devdef.class.fn_grp,
-              pcidev_def->devdef.class.device,
-              pcidev_def->devdef.class.variant);
+              pcidef->devdef.class.fn_grp,
+              pcidef->devdef.class.device,
+              pcidef->devdef.class.variant);
         return EINVAL;
     }
 
-    *more = 0;
+    *more = false;
 
-    int bind_attempted = 0;
+    bool bind_attempted = 0;
     int errno = 0;
 
     struct device_def* devdef;
@@ -98,23 +93,22 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
             continue;
         }
 
-        if (class != PCI_DEV_CLASS(pos->class_info)) {
-            continue;
-        }
+        bool matched;
 
-        int matched = (pos->device_info & devid_mask) == devid;
+        assert(pcidef->test_compatibility);
+        matched = pcidef->test_compatibility(pcidef, pos);
 
         if (!matched) {
             continue;
         }
 
         if (bind_attempted) {
-            *more = 1;
+            *more = true;
             break;
         }
 
-        bind_attempted = 1;
-        devdef = &pcidev_def->devdef;
+        bind_attempted = true;
+        devdef = &pcidef->devdef;
         errno = devdef->bind(devdef, &pos->dev);
 
         if (errno) {
@@ -127,7 +121,7 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
             continue;
         }
 
-        pos->binding.def = &pcidev_def->devdef;
+        pos->binding.def = &pcidef->devdef;
     }
 
     return errno;
@@ -136,9 +130,10 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more)
 int
 pci_bind_definition_all(struct pci_device_def* pcidef)
 {
-    int more = 0, e = 0;
+    int e = 0;
+    bool more = false;
     do {
-        if (!(e = pci_bind_definition(pcidef, &more))) {
+        if ((e = pci_bind_definition(pcidef, &more))) {
             break;
         }
     } while (more);
@@ -201,7 +196,7 @@ pci_probe_bar_info(struct pci_device* device)
 {
     u32_t bar;
     struct pci_base_addr* ba;
-    for (size_t i = 0; i < 6; i++) {
+    for (size_t i = 0; i < PCI_BAR_COUNT; i++) {
         ba = &device->bar[i];
         ba->size = pci_bar_sizing(device, &bar, i + 1);
         if (PCI_BAR_MMIO(bar)) {
@@ -327,6 +322,21 @@ pci_get_device_by_class(u32_t class)
     return NULL;
 }
 
+void
+pci_apply_command(struct pci_device* pcidev, pci_reg_t cmd)
+{
+    pci_reg_t rcmd;
+    ptr_t base;
+
+    base = pcidev->cspace_base;
+    rcmd = pci_read_cspace(base, PCI_REG_STATUS_CMD);
+
+    cmd  = cmd & 0xffff;
+    rcmd = (rcmd & 0xffff0000) | cmd;
+
+    pci_write_cspace(base, PCI_REG_STATUS_CMD, rcmd);
+}
+
 static void
 __pci_read_cspace(struct twimap* map)
 {
diff --git a/lunaix-os/hal/char/LConfig b/lunaix-os/hal/char/LConfig
new file mode 100644 (file)
index 0000000..1b5ead4
--- /dev/null
@@ -0,0 +1,7 @@
+include("uart")
+
+@Collection
+def char_device():
+    """ Controlling support of character devices """
+
+    add_to_collection(hal)
index dea044fb668ccbaee58b97d932a870078f746f65..15a9c9ed098113e963c7af5c52af1284d9a45dd2 100644 (file)
@@ -3,12 +3,15 @@
 #include <lunaix/spike.h>
 #include <lunaix/owloysius.h>
 #include <lunaix/status.h>
+#include <lunaix/syslog.h>
 
 #include <sys/mm/pagetable.h>
 
 #include <hal/serial.h>
 #include <hal/term.h>
 
+LOG_MODULE("serial")
+
 #define lock_sdev(sdev) device_lock((sdev)->dev)
 #define unlock_sdev(sdev) device_unlock((sdev)->dev)
 #define unlock_and_wait(sdev, wq)                                              \
@@ -267,10 +270,13 @@ serial_create(struct devclass* class, char* if_ident)
     
     device_grant_capability(dev, cap_meta(tp_cap));
 
-    register_device(dev, class, "s%d", class->variant);
+    register_device(dev, class, "%s%d", if_ident, class->variant);
 
     term_create(dev, if_ident);
 
+    INFO("interface: %s, %xh:%xh.%d", dev->name_val, 
+            class->fn_grp, class->device, class->variant);
+
     class->variant++;
     return sdev;
 }
diff --git a/lunaix-os/hal/char/uart/16550_pmio.c b/lunaix-os/hal/char/uart/16550_pmio.c
deleted file mode 100644 (file)
index 62d403a..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file 16550_pmio.c
- * @author Lunaixsky (lunaxisky@qq.com)
- * @brief 16550 UART with port mapped IO
- * @version 0.1
- * @date 2023-08-30
- *
- * @copyright Copyright (c) 2023
- *
- */
-#include <lunaix/device.h>
-#include <lunaix/generic/isrm.h>
-
-#include <sys/port_io.h>
-
-#include "16550.h"
-
-#define DELAY 50
-
-static DEFINE_LLIST(com_ports);
-
-static u32_t
-com_regread(struct uart16550* uart, ptr_t regoff)
-{
-    u8_t val = port_rdbyte(uart->base_addr + regoff);
-    port_delay(DELAY);
-
-    return (u32_t)val;
-}
-
-static void
-com_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val)
-{
-    port_wrbyte(uart->base_addr + regoff, (u8_t)val);
-    port_delay(DELAY);
-}
-
-static void
-com_irq_handler(const struct hart_state* hstate)
-{
-    int vector = hart_vector_stamp(hstate);
-    uart_general_irq_handler(vector, &com_ports);
-}
-
-static int
-upiom_init(struct device_def* def)
-{
-    int irq3 = 3, irq4 = 4;
-    u16_t ioports[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
-    int* irqs[] = { &irq4, &irq3, &irq4, &irq3 };
-
-    struct uart16550* uart = NULL;
-
-    // COM 1...4
-    for (size_t i = 0; i < 4; i++) {
-        if (!uart) {
-            uart = uart_alloc(ioports[i]);
-            uart->read_reg = com_regread;
-            uart->write_reg = com_regwrite;
-        } else {
-            uart->base_addr = ioports[i];
-        }
-
-        if (!uart_testport(uart, 0xe3)) {
-            continue;
-        }
-
-        int irq = *irqs[i];
-        if (irq) {
-            /*
-             *  Since these irqs are overlapped, this particular setup is needed
-             * to avoid double-bind
-             */
-            uart->iv = isrm_bindirq(irq, com_irq_handler);
-            *((volatile int*)irqs[i]) = 0;
-        }
-
-        uart_enable_fifo(uart, UART_FIFO8);
-        llist_append(&com_ports, &uart->local_ports);
-
-        struct serial_dev* sdev = serial_create(&def->class, "S");
-        sdev->backend = uart;
-        sdev->write = uart_general_tx;
-        sdev->exec_cmd = uart_general_exec_cmd;
-
-        uart->sdev = sdev;
-
-        uart_setup(uart);
-        uart_setie(uart);
-        uart = NULL;
-    }
-
-    if (uart) {
-        uart_free(uart);
-    }
-
-    return 0;
-}
-
-static struct device_def uart_pmio_def = {
-    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_UART16550),
-    .name = "16550 Generic UART (I/O)",
-    .init = upiom_init
-};
-EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_onboot);
\ No newline at end of file
similarity index 84%
rename from lunaix-os/hal/char/uart/16550.h
rename to lunaix-os/hal/char/uart/16x50.h
index 5b4040b695a152fdcb001fad89930ff54103dd59..addedfaa828de493b192aa2e507e742a89ea722c 100644 (file)
 #define UART_SENT_ALL 0b0010
 #define UART_MODEM_UPDATE 0b0000
 
+#define UART_LCR_RESET \
+            (UART_rLC_STOPB | \
+            UART_rLC_PAREN | \
+            UART_rLC_PAREVN | \
+            UART_rLC_DLAB | 0b11)
+
 struct uart16550
 {
     struct llist_header local_ports;
@@ -220,6 +226,34 @@ int
 uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len);
 
 void
-uart_general_irq_handler(int iv, struct llist_header* ports);
+uart_handle_irq_overlap(int iv, struct llist_header* ports);
+
+void
+uart_handle_irq(int iv, struct uart16550 *uart);
+
+static inline struct serial_dev*
+uart_create_serial(struct uart16550* uart, struct devclass* class, 
+                         struct llist_header* ports, char* if_ident)
+{
+    llist_append(ports, &uart->local_ports);
+
+    struct serial_dev* sdev = serial_create(class, if_ident);
+    sdev->backend = uart;
+    sdev->write = uart_general_tx;
+    sdev->exec_cmd = uart_general_exec_cmd;
+
+    uart->sdev = sdev;
+
+    uart_setup(uart);
+    uart_setie(uart);
+
+    return sdev;
+}
+
+struct uart16550*
+uart16x50_pmio_create(ptr_t base);
+
+struct uart16550*
+uart16x50_mmio_create(ptr_t base, ptr_t size);
 
 #endif /* __LUNAIX_16550_H */
similarity index 84%
rename from lunaix-os/hal/char/uart/16550_base.c
rename to lunaix-os/hal/char/uart/16x50_base.c
index a84e3d0d0c88f9e9e01e8b6b7591d3fc3a3a6651..6e94b847fd4acfd82a75234d0022cb0b4a0bf044 100644 (file)
@@ -4,7 +4,7 @@
 #include <usr/lunaix/serial.h>
 #include <usr/lunaix/term.h>
 
-#include "16550.h"
+#include "16x50.h"
 
 struct uart16550*
 uart_alloc(ptr_t base_addr)
@@ -42,12 +42,6 @@ uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len)
     return RXTX_DONE;
 }
 
-#define UART_LCR_RESET \
-    (UART_rLC_STOPB | \
-     UART_rLC_PAREN | \
-     UART_rLC_PAREVN | \
-     UART_rLC_DLAB | 0b11)
-
 static void
 uart_set_control_mode(struct uart16550* uart, tcflag_t cflags)
 {
@@ -88,9 +82,8 @@ uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args)
 }
 
 void
-uart_general_irq_handler(int iv, struct llist_header* ports)
+uart_handle_irq_overlap(int iv, struct llist_header* ports)
 {
-    char tmpbuf[32];
     struct uart16550 *pos, *n;
     llist_for_each(pos, n, ports, local_ports)
     {
@@ -103,24 +96,31 @@ uart_general_irq_handler(int iv, struct llist_header* ports)
     return;
 
 done:
+    uart_handle_irq(iv, pos);
+}
+
+void
+uart_handle_irq(int iv, struct uart16550 *uart)
+{
+    char tmpbuf[32];
     char recv;
     int i = 0;
-    while ((recv = uart_read_byte(pos))) {
+    while ((recv = uart_read_byte(uart))) {
         tmpbuf[i++] = recv;
         if (likely(i < 32)) {
             continue;
         }
 
-        if (!serial_accept_buffer(pos->sdev, tmpbuf, i)) {
-            uart_clear_rxfifo(pos);
+        if (!serial_accept_buffer(uart->sdev, tmpbuf, i)) {
+            uart_clear_rxfifo(uart);
             return;
         }
 
         i = 0;
     }
 
-    serial_accept_buffer(pos->sdev, tmpbuf, i);
-    serial_accept_one(pos->sdev, 0);
+    serial_accept_buffer(uart->sdev, tmpbuf, i);
+    serial_accept_one(uart->sdev, 0);
 
-    serial_end_recv(pos->sdev);
-}
+    serial_end_recv(uart->sdev);
+}
\ No newline at end of file
diff --git a/lunaix-os/hal/char/uart/16x50_isa.c b/lunaix-os/hal/char/uart/16x50_isa.c
new file mode 100644 (file)
index 0000000..d8d2e1b
--- /dev/null
@@ -0,0 +1,64 @@
+#include <lunaix/device.h>
+#include <lunaix/generic/isrm.h>
+#include <lunaix/syslog.h>
+
+#include <sys/port_io.h>
+
+#include "16x50.h"
+
+LOG_MODULE("16x50-isa");
+
+static DEFINE_LLIST(com_ports);
+
+static void
+com_irq_handler(const struct hart_state* hstate)
+{
+    int vector = hart_vector_stamp(hstate);
+    uart_handle_irq_overlap(vector, &com_ports);
+}
+
+static int
+upiom_init(struct device_def* def)
+{
+    int irq3 = 3, irq4 = 4;
+    u16_t ioports[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
+    int* irqs[] = { &irq4, &irq3, &irq4, &irq3 };
+
+    struct uart16550* uart = NULL;
+    ptr_t base;
+
+    // COM 1...4
+    for (size_t i = 0; i < 4; i++) {
+
+        base = ioports[i];
+        uart = uart16x50_pmio_create(base);
+        if (!uart) {
+            WARN("port 0x%x not accessible", base);
+            continue;
+        }
+
+        int irq = *irqs[i];
+        if (irq) {
+            /*
+             *  Since these irqs are overlapped, this particular setup is needed
+             * to avoid double-bind
+             */
+            uart->iv = isrm_bindirq(irq, com_irq_handler);
+            *((volatile int*)irqs[i]) = 0;
+        }
+
+        INFO("base: 0x%x, irq=%d", 
+                base, irq, uart->iv);
+
+        uart_create_serial(uart, &def->class, &com_ports, "S");
+    }
+
+    return 0;
+}
+
+static struct device_def uart_pmio_def = {
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_UART16550),
+    .name = "16550 UART (PIO)",
+    .init = upiom_init
+};
+EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_onboot);
\ No newline at end of file
diff --git a/lunaix-os/hal/char/uart/16x50_mmio.c b/lunaix-os/hal/char/uart/16x50_mmio.c
new file mode 100644 (file)
index 0000000..2e32b75
--- /dev/null
@@ -0,0 +1,39 @@
+#include <lunaix/device.h>
+#include <lunaix/generic/isrm.h>
+#include <lunaix/mm/mmio.h>
+
+#include "16x50.h"
+
+static u32_t
+uart_mmio_regread(struct uart16550* uart, ptr_t regoff)
+{
+    return (u32_t)(*(u8_t*)(uart->base_addr + regoff));
+}
+
+static void
+uart_mmio_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val)
+{
+    *(u8_t*)(uart->base_addr + regoff) = (u8_t)val;
+}
+
+struct uart16550*
+uart16x50_mmio_create(ptr_t base, ptr_t size)
+{
+    ptr_t mmio_base;
+    struct uart16550* uart;
+
+    base = ioremap(base, size);
+    uart = uart_alloc(base);
+    uart->read_reg = uart_mmio_regread;
+    uart->write_reg = uart_mmio_regwrite;
+
+    if (!uart_testport(uart, 0xe3)) {
+        iounmap(base, size);
+        uart_free(uart);
+        return NULL;
+    }
+
+    uart_enable_fifo(uart, UART_FIFO8);
+
+    return uart;
+}
\ No newline at end of file
diff --git a/lunaix-os/hal/char/uart/16x50_pci.c b/lunaix-os/hal/char/uart/16x50_pci.c
new file mode 100644 (file)
index 0000000..880fd2d
--- /dev/null
@@ -0,0 +1,125 @@
+#include <lunaix/device.h>
+#include <lunaix/generic/isrm.h>
+#include <lunaix/syslog.h>
+#include <lunaix/mm/mmio.h>
+
+#include <hal/pci.h>
+
+#include "16x50.h"
+
+#define PCI_DEVICE_16x50_UART    0x070000
+
+LOG_MODULE("16x50-pci")
+
+static DEFINE_LLIST(pci_ports);
+
+static void
+uart_msi_irq_handler(const struct hart_state* hstate)
+{
+    int vector;
+    struct uart16550* uart;
+    
+    vector = hart_vector_stamp(hstate);
+    uart = (struct uart16550*)isrm_get_payload(hstate);
+
+    assert(uart);
+    uart_handle_irq(vector, uart);
+}
+
+static void
+uart_intx_irq_handler(const struct hart_state* hstate)
+{
+    int vector = hart_vector_stamp(hstate);
+    uart_handle_irq_overlap(vector, &pci_ports);
+}
+
+static int
+pci16550_init(struct device_def* def)
+{
+    return pci_bind_definition_all(pcidev_def(def));
+}
+
+static bool
+pci16650_check_compat(struct pci_device_def* def, 
+                      struct pci_device* pcidev)
+{
+    unsigned int classid;
+    classid = pci_device_class(pcidev);
+
+    return (classid & 0xffff00) == PCI_DEVICE_16x50_UART;
+}
+
+static int
+pci16650_binder(struct device_def* def, struct device* dev)
+{
+    int irq;
+    struct pci_base_addr* bar;
+    struct pci_device* pcidev;
+    struct uart16550* uart;
+    struct serial_dev* sdev;
+    
+    pcidev = PCI_DEVICE(dev);
+
+    pci_reg_t cmd = 0;
+
+    for (int i = 0; i < PCI_BAR_COUNT; i++) 
+    {
+        cmd = 0;
+        pci_cmd_set_msi(&cmd);
+        
+        bar = pci_device_bar(pcidev, i);
+        if (bar->size == 0) {
+            continue;
+        }
+                
+        if (!pci_bar_mmio_space(bar)) {
+            pci_cmd_set_pmio(&cmd);
+            pci_apply_command(pcidev, cmd);
+
+            uart = uart16x50_pmio_create(bar->start);
+        }
+        else {
+            pci_cmd_set_mmio(&cmd);
+            pci_apply_command(pcidev, cmd);
+
+            uart = uart16x50_mmio_create(bar->start, bar->size);
+        }
+
+        if (!uart) {
+            WARN("not accessible (BAR #%d)", i);
+            continue;
+        }
+
+        if (pci_capability_msi(pcidev)) {
+            irq = isrm_ivexalloc(uart_msi_irq_handler);
+            isrm_set_payload(irq, __ptr(uart));
+            pci_setup_msi(pcidev, irq);
+        }
+        else {
+            irq = pci_intr_irq(pcidev);
+            irq = isrm_bindirq(irq, uart_intx_irq_handler);
+        }
+
+        INFO("base: 0x%x (%s), irq=%d (%s)", 
+                bar->start, 
+                pci_bar_mmio_space(bar) ? "mmio" : "pmio",
+                irq, 
+                pci_capability_msi(pcidev) ? "msi" : "intx, re-routed");
+        
+        uart->iv = irq;
+
+        sdev = uart_create_serial(uart, &def->class, &pci_ports, "PCI");
+        pci_bind_instance(pcidev, sdev);
+    }
+
+    return 0;
+}
+
+static struct pci_device_def uart_pci_def = {
+    .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_CHAR, DEV_UART16550),
+                .name = "16550 UART (PCI/MMIO)",
+                .init = pci16550_init,
+                .bind = pci16650_binder },
+    .test_compatibility = pci16650_check_compat
+};
+EXPORT_PCI_DEVICE(uart16550_pci, &uart_pci_def, load_onboot);
\ No newline at end of file
diff --git a/lunaix-os/hal/char/uart/16x50_pmio.c b/lunaix-os/hal/char/uart/16x50_pmio.c
new file mode 100644 (file)
index 0000000..76ab3bc
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * @file 16550_pmio.c
+ * @author Lunaixsky (lunaxisky@qq.com)
+ * @brief 16550 UART with port mapped IO
+ * @version 0.1
+ * @date 2023-08-30
+ *
+ * @copyright Copyright (c) 2023
+ *
+ */
+#include <lunaix/device.h>
+#include <lunaix/generic/isrm.h>
+
+#include <sys/port_io.h>
+
+#include "16x50.h"
+
+#define DELAY 50
+
+static u32_t
+com_regread(struct uart16550* uart, ptr_t regoff)
+{
+    u8_t val = port_rdbyte(uart->base_addr + regoff);
+    port_delay(DELAY);
+
+    return (u32_t)val;
+}
+
+static void
+com_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val)
+{
+    port_wrbyte(uart->base_addr + regoff, (u8_t)val);
+    port_delay(DELAY);
+}
+
+
+struct uart16550*
+uart16x50_pmio_create(ptr_t base)
+{
+    struct uart16550* uart;
+
+    uart = uart_alloc(base);
+    uart->read_reg = com_regread;
+    uart->write_reg = com_regwrite;
+
+    if (!uart_testport(uart, 0xe3)) {
+        uart_free(uart);
+        return NULL;
+    }
+
+    uart_enable_fifo(uart, UART_FIFO8);
+
+    return uart;
+}
index 1fbc933387f803a9ccb3887bc213da799f0c55b2..83088c659775567aec63e6887517442122d9901f 100644 (file)
@@ -1,4 +1,11 @@
 sources([
-    "16550_base.c",
-    "16550_pmio.c"
-])
\ No newline at end of file
+    "16x50_base.c",
+    "16x50_pmio.c",
+    "16x50_mmio.c",
+])
+
+if config("xt_16x50"):
+    sources("16x50_isa.c")
+
+if config("pci_16x50"):
+    sources("16x50_pci.c")
\ No newline at end of file
diff --git a/lunaix-os/hal/char/uart/LConfig b/lunaix-os/hal/char/uart/LConfig
new file mode 100644 (file)
index 0000000..9ed1f09
--- /dev/null
@@ -0,0 +1,25 @@
+
+@Collection("16x50 Serial Controller")
+def uart_16x50():
+    """ 16x50 serial controller  """
+
+    # hal/char/LConfig::char_device
+    add_to_collection(char_device)
+
+    @Term("16x50 XT-Compat")
+    def xt_16x50():
+        """ Enable the 16x50 for PC-compatible platform  """
+
+        type(bool)
+
+        is_x86 = v(arch) in ["i386", "x86_64"]
+        default(is_x86)
+
+        return is_x86
+    
+    @Term("16x50 PCI")
+    def pci_16x50():
+        """ Enable the support of PCI 16x50 """
+        type(bool)
+
+        default(True)
\ No newline at end of file
index 09476db5efd958f5ad57ef7b13e4286dbb5fe7a1..1109e5a3f222415a2c72f511680eb6e82f77bd5c 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <hal/gfxm.h>
 #include <hal/pci.h>
-#include <sys/pci_hba.h>
 
 #include <klibc/string.h>
 
@@ -76,8 +75,8 @@ vga_pci_bind(struct device_def* devdef, struct device* pcidev_base)
 
     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);
+    ptr_t fb_mapped = ioremap(fb->start, FB256K);
+    ptr_t mmio_mapped = ioremap(mmio->start, mmio->size);
 
     struct vga* vga_state =
       vga_new_state(mmio_mapped + VGA_REG_OFF, fb_mapped, FB256K);
@@ -105,13 +104,19 @@ vga_pci_init(struct device_def* def)
 
 #define VGA_PCI_CLASS 0x30000
 
+static bool
+vga_pci_compat(struct pci_device_def* def, 
+                struct pci_device* pcidev)
+{
+    return pci_device_class(pcidev) == VGA_PCI_CLASS;
+}
+
+
 static struct pci_device_def vga_pci_devdef = {
-    .dev_class = VGA_PCI_CLASS,
-    .dev_ident = PCI_DEVIDENT(0x1234, 0x1111),
-    .ident_mask = PCI_MATCH_EXACT,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_DISP, DEV_VGA),
                 .name = "Generic VGA",
                 .init = vga_pci_init,
-                .bind = vga_pci_bind }
+                .bind = vga_pci_bind },
+    .test_compatibility = vga_pci_compat
 };
 EXPORT_PCI_DEVICE(vga_pci, &vga_pci_devdef, load_onboot);
\ No newline at end of file
index da450906870f2c88a38578e9dd6eda0c51a25340..d457a1ed276da5d78398e9869ba1f05a1492e9e9 100644 (file)
@@ -38,6 +38,7 @@
 #define PCI_BAR_TYPE(x) ((x) & 0x6)
 #define PCI_BAR_ADDR_MM(x) ((x) & ~0xf)
 #define PCI_BAR_ADDR_IO(x) ((x) & ~0x3)
+#define PCI_BAR_COUNT 6
 
 #define PCI_MSI_ADDR_LO(msi_base) ((msi_base) + 4)
 #define PCI_MSI_ADDR_HI(msi_base) ((msi_base) + 8)
@@ -116,10 +117,9 @@ typedef void* (*pci_drv_init)(struct pci_device*);
 
 struct pci_device_def
 {
-    u32_t dev_class;
-    u32_t dev_ident;
-    u32_t ident_mask;
     struct device_def devdef;
+
+    bool (*test_compatibility)(struct pci_device_def*, struct pci_device*);
 };
 #define pcidev_def(dev_def_ptr)                                                \
     container_of((dev_def_ptr), struct pci_device_def, devdef)
@@ -176,9 +176,98 @@ void
 pci_probe_msi_info(struct pci_device* device);
 
 int
-pci_bind_definition(struct pci_device_def* pcidev_def, int* more);
+pci_bind_definition(struct pci_device_def* pcidev_def, bool* more);
 
 int
 pci_bind_definition_all(struct pci_device_def* pcidef);
 
+static inline unsigned int
+pci_device_vendor(struct pci_device* pcidev)
+{
+    return PCI_DEV_VENDOR(pcidev->device_info);
+}
+
+static inline unsigned int
+pci_device_devid(struct pci_device* pcidev)
+{
+    return PCI_DEV_DEVID(pcidev->device_info);
+}
+
+static inline unsigned int
+pci_device_class(struct pci_device* pcidev)
+{
+    return PCI_DEV_CLASS(pcidev->class_info);
+}
+
+static inline struct pci_base_addr*
+pci_device_bar(struct pci_device* pcidev, int index)
+{
+    return &pcidev->bar[index];
+}
+
+static inline void
+pci_cmd_set_mmio(pci_reg_t* cmd)
+{
+    *cmd |= PCI_RCMD_MM_ACCESS;
+}
+
+
+static inline void
+pci_cmd_set_pmio(pci_reg_t* cmd)
+{
+    *cmd |= PCI_RCMD_IO_ACCESS;
+}
+
+static inline void
+pci_cmd_set_msi(pci_reg_t* cmd)
+{
+    *cmd |= PCI_RCMD_DISABLE_INTR;
+}
+
+static inline void
+pci_cmd_set_bus_master(pci_reg_t* cmd)
+{
+    *cmd |= PCI_RCMD_BUS_MASTER;
+}
+
+static inline void
+pci_cmd_set_fast_b2b(pci_reg_t* cmd)
+{
+    *cmd |= PCI_RCMD_FAST_B2B;
+}
+
+static inline bool
+pci_bar_mmio_space(struct pci_base_addr* bar)
+{
+    return (bar->type & BAR_TYPE_MMIO);
+}
+
+static inline bool
+pci_capability_msi(struct pci_device* pcidev)
+{
+    return !!pcidev->msi_loc;
+}
+
+static inline int
+pci_intr_irq(struct pci_device* pcidev)
+{
+    return PCI_INTR_IRQ(pcidev->intr_info);
+}
+
+void
+pci_apply_command(struct pci_device* pcidev, pci_reg_t cmd);
+
+pci_reg_t
+pci_read_cspace(ptr_t base, int offset);
+
+void
+pci_write_cspace(ptr_t base, int offset, pci_reg_t data);
+
+u16_t
+pci_config_msi_data(int vector);
+
+ptr_t
+pci_get_msi_base();
+
+
 #endif /* __LUNAIX_PCI_H */
index d20deba48ab8711fea2c870ae52a9c3b58c4495f..e622e05dbea1981ae4ce416cd0d095cf844197b4 100644 (file)
@@ -3,7 +3,8 @@
 
 #include <sys/abi.h>
 
-#define _preemptible __attribute__((section(".kf.preempt")))
+#define _preemptible \
+        __attribute__((section(".kf.preempt"))) no_inline
 
 #define ensure_preempt_caller()                                 \
     do {                                                        \
index 18d1c4fa3dc73bdbb18920b3df92361297bf87cc..29b0786863702c054018c10abd62dd7db10f23a8 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <lunaix/types.h>
 
-void*
+ptr_t
 ioremap(ptr_t paddr, u32_t size);
 
 void
index 23d5c646dd5e13b6da907e45c8a1b00d90a82ca1..0f9fb0c0aacff04179c5587aaca31ba7f9c3a9c2 100644 (file)
@@ -284,6 +284,13 @@ vmap_range(pfn_t start, size_t npages, pte_attr_t prot)
     return vmap_ptes_at(_pte, LFT_SIZE, npages);
 }
 
+static inline void
+vunmap_range(pfn_t start, size_t npages)
+{
+    pte_t* ptep = mkptep_va(VMS_SELF, start);
+    vmm_set_ptes_contig(ptep, null_pte, LFT_SIZE, npages);
+}
+
 
 /**
  * @brief Allocate a page in kernel space.
index c820fd008342ce454fed95b0a51a046a1ab6917b..37b9005dc28ec86ea902d8ff38e85c529a69e2c0 100644 (file)
@@ -3,4 +3,4 @@ def kernel_feature():
     """ Config kernel features """
     pass
 
-include("mm/LConfig")
\ No newline at end of file
+include("mm")
\ No newline at end of file
index 685c3d0e7fd3ca943c06300e6393dc73a5599f10..ca28001f8bc66b255604297d727267455743ea3d 100644 (file)
@@ -43,7 +43,7 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     /* Begin kernel bootstrapping sequence */
     boot_begin(bhctx);
 
-    tty_init(ioremap(0xB8000, PAGE_SIZE));
+    tty_init((void*)ioremap(0xB8000, PAGE_SIZE));
     
     /* Setup kernel memory layout and services */
     kmem_init(bhctx);
index b91ab0e425c491a79f1e334aa1090d3aa4e728ea..dbb1870afe9083437f7656d177fe579542184618 100644 (file)
@@ -2,7 +2,7 @@
 #include <lunaix/mm/page.h>
 #include <lunaix/spike.h>
 
-void*
+ptr_t
 ioremap(ptr_t paddr, u32_t size)
 {
     // FIXME implement a page policy interface allow to decouple the 
@@ -14,21 +14,13 @@ ioremap(ptr_t paddr, u32_t size)
     // Ensure the range is reservable (not already in use)
     assert(pmm_onhold_range(start, npages));
 
-    return (void*)vmap_range(start, npages, KERNEL_DATA);
+    ptr_t addr = vmap_range(start, npages, KERNEL_DATA);
+    return addr + va_offset(paddr);
 }
 
 void
 iounmap(ptr_t vaddr, u32_t size)
 {
-    // FIXME
-    fail("need fix");
-
-    // pte_t* ptep = mkptep_va(VMS_SELF, vaddr);
-    // for (size_t i = 0; i < size; i += PAGE_SIZE, ptep++) {
-    //     pte_t pte = pte_at(ptep);
-
-    //     set_pte(ptep, null_pte);
-    //     if (pte_isloaded(pte))
-    //         return_page(ppage_pa(pte_paddr(pte)));
-    // }
+    assert(vaddr >= VMAP && vaddr < VMAP_END);
+    vunmap_range(pfn(vaddr), leaf_count(size));
 }
\ No newline at end of file
index e10f71cc733ce304795ca1c1156e1c3400146919..6462f5d6581ae81e0dc25540f8d1f384bdf75c8e 100755 (executable)
@@ -4,7 +4,7 @@ hmp_port=45454
 gdb_port=1234
 default_cmd="console=/dev/ttyS0"
 
-make CMDLINE=${default_cmd} ARCH=${ARCH} MODE=debug image -j5 || exit -1
+make CMDLINE=${default_cmd} ARCH=${ARCH} MODE=${MODE:-debug} image -j5 || exit -1
 
 ./scripts/qemu.py \
     scripts/qemus/qemu_x86_dev.json \
index a53848831733e7708a7c01e5fbb354d51506f3f4..486e9ce74ccf5c178a800dcd587f6a82c58e539b 100644 (file)
@@ -14,21 +14,12 @@ W := -Wall -Wextra -Werror \
                -Wno-discarded-qualifiers\
                -Werror=incompatible-pointer-types
 
-OFLAGS := -fno-gcse\
-                 -fno-gcse-lm\
-                 -fno-cse-follow-jumps\
-                 -fno-cse-skip-blocks\
-                 -fno-optimize-strlen\
-                 -fno-inline-functions-called-once \
-                 -fno-inline-small-functions \
-                 -fno-indirect-inlining\
-                 -fno-omit-frame-pointer
+OFLAGS := -fno-omit-frame-pointer
 
-CFLAGS := -std=gnu99 $(OFLAGS) $(W)
+CFLAGS := -std=gnu99 $(OFLAGS) $(W) -g
 
 ifeq ($(MODE),debug)
        O = -Og
-       CFLAGS += -g
 endif
 
 CFLAGS += $(O)
index 33079fffe65d5d504105474bb5081757d32956d7..15e1ba8da776ea5c892c568bd783b51318399274 100644 (file)
@@ -26,7 +26,7 @@ class CHeaderConfigProvider(ConfigIOProvider):
             v = self.serialize_value(v)
             if v is None or v is False:
                 result.insert(0, "//")
-            else:
+            elif isinstance(v, str):
                 result.append(v)
 
             lines.append(" ".join(result))
index 5eacf55a344494a49d3232e0bab99ff9a281e525..4fdee85d7433d8abab58e48e7867954bf658dfc0 100644 (file)
@@ -207,7 +207,7 @@ class InteractiveShell(InteractiveRenderer):
     def do_read(self, node_name):
         view, _ = self.resolve(node_name)
         rd_val = view.read(self.__sctx)
-        if not rd_val:
+        if rd_val is None:
             raise ShellException(f"config node {view.label} is not readable")
     
         print(rd_val)
index f32b9b6237b23bc8f20f5122722726c23a1cc209..f072303bc2a94f5384a329f011a55034b92c294c 100644 (file)
@@ -13,8 +13,12 @@ def v(env, caller, term):
 def include(env, caller, file):
     fobj = caller.get_fo()
     path = os.path.dirname(fobj.filename())
+    path = join_path(path, file)
+    
+    if os.path.isdir(path):
+        path = join_path(path, "LConfig")
 
-    env.resolve_module(join_path(path, file))
+    env.resolve_module(path)
 
 @contextual("type", caller_type=[LCTermNode])
 def term_type(env, caller, type):
index 53383269765a872bc00abea70cd109860955c07b..ce843da3312625477a31d04d603bace64f777670 100755 (executable)
@@ -80,13 +80,14 @@ class PCISerialDevice(QEMUPeripherals):
         super().__init__("pci-serial", opt)
 
     def get_qemu_opts(self):
-        name = f"chrdev.{hex(self.__hash__())[2:]}"
-        cmds = [ "pci-serial", f"chardev={name}" ]
+        uniq = hex(self.__hash__())[2:]
+        name = f"chrdev.{uniq}"
+        cmds = [ "pci-serial", f"id=uart.{uniq}", f"chardev={name}" ]
         chrdev = [ "file", f"id={name}" ]
         
         logfile = get_config(self._opt, "logfile", required=True)
         chrdev.append(f"path={logfile}")
-        ()
+
         return [ 
             "-chardev", join_attrs(chrdev),
             "-device", join_attrs(cmds)
@@ -196,7 +197,7 @@ class QEMUExec:
 
         trace_opts = get_config(debug, "traced", [])
         for trace in trace_opts:
-            cmds += [ "-d", f"trace:{trace}"]
+            cmds += [ "--trace", f"{trace}"]
 
         return cmds
     
index 474ad1a1c9b2396b6433e6cdb38241d35b8b0e96..e006691bd09d566b86519cbd8d2fa617a6da54f8 100644 (file)
             "addr": ":12345",
             "logfile": "lunaix_ttyS0.log"
         },
+        {
+            "class": "pci-serial",
+            "logfile": "ttyPCI0.log"
+        },
+        {
+            "class": "pci-serial",
+            "logfile": "ttyPCI1.log"
+        },
         {
             "class": "rtc",
             "base": "utc"
index 03a89ee28577f41c3803a9dcb3699ca96d16661d..ec56dcba7d81548da4826917c69a93f84bf0a508 100644 (file)
@@ -36,3 +36,5 @@ if config("arch") == "x86_64":
 else:
     compile_opts("-m32")
     linking_opts("-m32")
+
+compile_opts("-mno-sse")
\ No newline at end of file
index ece96e4a9947fef95f83188dccba73705da9a4f4..698d0256fd17f25a7f9d9034154982b79d14525f 100644 (file)
@@ -20,7 +20,7 @@ main(int argc, const char* argv[])
 
     while ((dent = readdir(dir))) {
         if (dent->d_type == DT_DIR) {
-            printf(" %s\n", dent->d_name);
+            printf(" %s/\n", dent->d_name);
         } else if (dent->d_type == DT_SYMLINK) {
             printf(" %s@\n", dent->d_name);
         } else {
index 8011c304b028451d289a211a49a3f2bbe318601d..ee33fe6f69710ee37c05b6635dd2cb880a6763da 100644 (file)
@@ -6,26 +6,32 @@
 #include <unistd.h>
 
 void
-test_serial()
+test_serial(char* dev, int wr)
 {
-    int fd = open("/dev/ttyS0", FO_WRONLY);
+    int fd = open(dev, FO_WRONLY);
     if (fd < 0) {
-        printf("ttyS0 not accessable (%d)\n", errno);
+        printf("tty %s not accessable (%d)\n", dev, errno);
         return;
     }
 
-    char buf[32];
     int sz = 0;
+    char buf[256];
 
-    printf("ttyS0 input: ");
+    if (!wr) {
+        printf("tty input: ");
 
-    if ((sz = read(fd, buf, 31)) < 0) {
-        printf("write to ttyS0 failed (%d)\n", errno);
-    }
+        if ((sz = read(fd, buf, 31)) < 0) {
+            printf("read to tty failed (%d)\n", errno);
+        }
 
-    buf[sz] = 0;
+        buf[sz] = 0;
 
-    printf("%s", buf);
+        printf("%s", buf);
+    }
+    else {
+        int size = snprintf(buf, 256, "serial test: %s", dev);
+        write(fd, buf, size);
+    }
 
     close(fd);
 }
@@ -33,18 +39,14 @@ test_serial()
 int
 main(int argc, char* argv[])
 {
-    if (argc <= 1) {
+    if (argc != 2) {
+        printf("usage: testp path_to_dev\n");
         return 1;
     }
 
     char* target = argv[1];
 
-    if (!strcmp(target, "serial")) {
-        test_serial();
-    } else {
-        printf("unknown test: %s\n", target);
-        return 1;
-    }
+    test_serial(target, 1);
 
     return 0;
 }
\ No newline at end of file