refactor: make pci device driver loading passive, pci bus scanner will not load them...
authorMinep <lunaixsky@qq.com>
Sat, 4 Nov 2023 19:27:18 +0000 (19:27 +0000)
committerMinep <lunaixsky@qq.com>
Sat, 4 Nov 2023 19:37:26 +0000 (19:37 +0000)
          this allow greater flexibility and decouple the pci bus scanning and the driver init dependency.
refactor: move acpi as a loadable device
refactor: remove the nonsense "len" parameter from {read|write}_page file ops
refactor: decouple the ahci main driver from the pci interfacing
refacror: move the mounting of some kernel fs to user space.
refactor: rename the device loading stage to make more sense.
chores: some house-keeping stuff

60 files changed:
lunaix-os/arch/i386/exceptions/interrupts.c
lunaix-os/arch/i386/exceptions/intr_routines.c
lunaix-os/arch/i386/mm/pfault.c
lunaix-os/hal/acpi/acpi.c
lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/ahci/ahci_pci.c [new file with mode: 0644]
lunaix-os/hal/ahci/io_event.c
lunaix-os/hal/char/devnull.c
lunaix-os/hal/char/devzero.c
lunaix-os/hal/char/ps2kbd.c
lunaix-os/hal/char/uart/16550_pmio.c
lunaix-os/hal/gfxa/vga/vga_pci.c
lunaix-os/hal/pci.c
lunaix-os/hal/rng/rngx86.c
lunaix-os/hal/rtc/mc146818a.c
lunaix-os/hal/rtc/rtc_device.c [moved from lunaix-os/hal/rtc/hwrtc.c with 84% similarity]
lunaix-os/hal/timer/apic_timer.c
lunaix-os/hal/timer/timer_device.c [moved from lunaix-os/hal/timer/hwtimer.c with 71% similarity]
lunaix-os/includes/hal/acpi/acpi.h
lunaix-os/includes/hal/ahci/ahci.h
lunaix-os/includes/hal/hwrtc.h
lunaix-os/includes/hal/hwtimer.h
lunaix-os/includes/hal/pci.h
lunaix-os/includes/lunaix/blkio.h
lunaix-os/includes/lunaix/clock.h
lunaix-os/includes/lunaix/compiler.h
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/device_num.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/iso9660.h
lunaix-os/includes/lunaix/spike.h
lunaix-os/includes/lunaix/syslog.h
lunaix-os/includes/lunaix/trace.h
lunaix-os/kernel/block/blkpart_gpt.c
lunaix-os/kernel/block/block.c
lunaix-os/kernel/debug/sdbg.c
lunaix-os/kernel/debug/trace.c
lunaix-os/kernel/device/devdb.c
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/fs/defaults.c
lunaix-os/kernel/fs/iso9660/file.c
lunaix-os/kernel/fs/iso9660/inode.c
lunaix-os/kernel/fs/mount.c
lunaix-os/kernel/fs/path_walk.c
lunaix-os/kernel/fs/pcache.c
lunaix-os/kernel/fs/ramfs/ramfs.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/twimap.c
lunaix-os/kernel/kinit.c
lunaix-os/kernel/kprint/kp_records.c
lunaix-os/kernel/kprint/kp_records.h
lunaix-os/kernel/kprint/kprintf.c
lunaix-os/kernel/mm/mmap.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/process/taskfs.c
lunaix-os/kernel/time/clock.c
lunaix-os/kernel/tty/lxconsole.c
lunaix-os/link/linker.ld
lunaix-os/makeinc/qemu.mkinc
lunaix-os/usr/init/init.c

index 84a29c1ea4f98384ad250233cc6188357dc1ae5c..a323008b977886e0609802122776d931a7e7d52d 100644 (file)
@@ -28,7 +28,7 @@ intr_handler(isr_param* param)
         goto done;
     }
 
-    kprintf(KERROR "INT %u: (%x) [%p: %p] Unknown",
+    ERROR("INT %u: (%x) [%p: %p] Unknown",
             execp->vector,
             execp->err_code,
             execp->cs,
index 33b33c8e92ef091abb3c29ae59d79a33f602b38f..77a13722f0373a61b15d5c00d83263c5f88b7de0 100644 (file)
@@ -23,7 +23,7 @@ extern u32_t debug_resv;
 void
 __print_panic_msg(const char* msg, const isr_param* param)
 {
-    kprintf(KERROR "panic: %s", msg);
+    ERROR("panic: %s", msg);
     trace_printstack_isr(param);
 }
 
index 2533d0bac8dc1829f6361ae7caa5428e9bd1e495..165062c6fd965ca20c4536f930f004c22b3512a7 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <klibc/string.h>
 
+LOG_MODULE("pf")
+
 static u32_t
 get_ptattr(struct mm_region* vmr)
 {
@@ -25,15 +27,6 @@ get_ptattr(struct mm_region* vmr)
     return ptattr & 0xfff;
 }
 
-static void
-kprintf(const char* fmt, ...)
-{
-    va_list args;
-    va_start(args, fmt);
-    __kprintf("PFAULT", fmt, args);
-    va_end(args);
-}
-
 #define COW_MASK (REGION_RSHARED | REGION_READ | REGION_WRITE)
 
 extern void
@@ -67,10 +60,10 @@ intr_routine_page_fault(const isr_param* param)
     if (PG_IS_PRESENT(*pte)) {
         if (((errcode ^ mapping.flags) & PG_ALLOW_USER)) {
             // invalid access
-            kprintf(KDEBUG "invalid user access. (%p->%p, attr:0x%x)",
-                    mapping.va,
-                    mapping.pa,
-                    mapping.flags);
+            DEBUG("invalid user access. (%p->%p, attr:0x%x)",
+                  mapping.va,
+                  mapping.pa,
+                  mapping.flags);
             goto segv_term;
         }
         if ((hit_region->attr & COW_MASK) == COW_MASK) {
@@ -128,12 +121,11 @@ intr_routine_page_fault(const isr_param* param)
 
         int errno = 0;
         if (mseg_off < hit_region->flen) {
-            errno =
-              file->ops->read_page(file->inode, (void*)ptr, PG_SIZE, mfile_off);
+            errno = file->ops->read_page(file->inode, (void*)ptr, mfile_off);
         }
 
         if (errno < 0) {
-            kprintf(KERROR "fail to populate page (%d)", errno);
+            ERROR("fail to populate page (%d)", errno);
             goto segv_term;
         }
 
@@ -148,15 +140,15 @@ intr_routine_page_fault(const isr_param* param)
         ;
 
 oom:
-    kprintf(KERROR "out of memory");
+    ERROR("out of memory");
 
 segv_term:
-    kprintf(KERROR "(pid: %d) Segmentation fault on %p (%p:%p,e=0x%x)",
-            __current->pid,
-            ptr,
-            param->execp->cs,
-            param->execp->eip,
-            param->execp->err_code);
+    ERROR("(pid: %d) Segmentation fault on %p (%p:%p,e=0x%x)",
+          __current->pid,
+          ptr,
+          param->execp->cs,
+          param->execp->eip,
+          param->execp->err_code);
 
     sigset_add(__current->sigctx.sig_pending, _SIGSEGV);
 
index 67915fa3092b86c0ddf34d04fac1ad46d32fbf45..5732ec8e176802ece8c38383b0a95e3c589a8830 100644 (file)
@@ -1,5 +1,6 @@
 #include <hal/acpi/acpi.h>
 
+#include <lunaix/device.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
@@ -15,48 +16,6 @@ LOG_MODULE("ACPI")
 int
 acpi_rsdp_validate(acpi_rsdp_t* rsdp);
 
-acpi_rsdp_t*
-acpi_locate_rsdp();
-
-int
-acpi_init()
-{
-    acpi_rsdp_t* rsdp = acpi_locate_rsdp();
-
-    assert_msg(rsdp, "Fail to locate ACPI_RSDP");
-    assert_msg(acpi_rsdp_validate(rsdp), "Invalid ACPI_RSDP (checksum failed)");
-
-    acpi_rsdt_t* rsdt = rsdp->rsdt;
-
-    ctx = vzalloc(sizeof(acpi_context));
-    assert_msg(ctx, "Fail to create ACPI context");
-
-    strncpy(ctx->oem_id, rsdt->header.oem_id, 6);
-    ctx->oem_id[6] = '\0';
-
-    size_t entry_n = (rsdt->header.length - sizeof(acpi_sdthdr_t)) >> 2;
-    for (size_t i = 0; i < entry_n; i++) {
-        acpi_sdthdr_t* sdthdr =
-          (acpi_sdthdr_t*)((acpi_apic_t**)&(rsdt->entry))[i];
-        switch (sdthdr->signature) {
-            case ACPI_MADT_SIG:
-                madt_parse((acpi_madt_t*)sdthdr, ctx);
-                break;
-            case ACPI_FADT_SIG:
-                // FADT just a plain structure, no need to parse.
-                ctx->fadt = *(acpi_fadt_t*)sdthdr;
-                break;
-            case ACPI_MCFG_SIG:
-                mcfg_parse(sdthdr, ctx);
-                break;
-            default:
-                break;
-        }
-    }
-
-    return 0;
-}
-
 acpi_context*
 acpi_get_context()
 {
@@ -106,4 +65,49 @@ acpi_locate_rsdp()
     }
 
     return rsdp;
-}
\ No newline at end of file
+}
+
+static int
+acpi_init(struct device_def* devdef)
+{
+    acpi_rsdp_t* rsdp = acpi_locate_rsdp();
+
+    assert_msg(rsdp, "Fail to locate ACPI_RSDP");
+    assert_msg(acpi_rsdp_validate(rsdp), "Invalid ACPI_RSDP (checksum failed)");
+
+    acpi_rsdt_t* rsdt = rsdp->rsdt;
+
+    ctx = vzalloc(sizeof(acpi_context));
+    assert_msg(ctx, "Fail to create ACPI context");
+
+    strncpy(ctx->oem_id, rsdt->header.oem_id, 6);
+    ctx->oem_id[6] = '\0';
+
+    size_t entry_n = (rsdt->header.length - sizeof(acpi_sdthdr_t)) >> 2;
+    for (size_t i = 0; i < entry_n; i++) {
+        acpi_sdthdr_t* sdthdr =
+          (acpi_sdthdr_t*)((acpi_apic_t**)&(rsdt->entry))[i];
+        switch (sdthdr->signature) {
+            case ACPI_MADT_SIG:
+                madt_parse((acpi_madt_t*)sdthdr, ctx);
+                break;
+            case ACPI_FADT_SIG:
+                // FADT just a plain structure, no need to parse.
+                ctx->fadt = *(acpi_fadt_t*)sdthdr;
+                break;
+            case ACPI_MCFG_SIG:
+                mcfg_parse(sdthdr, ctx);
+                break;
+            default:
+                break;
+        }
+    }
+
+    return 0;
+}
+
+struct device_def acpi_sysdev = { .name = "ACPI Proxy",
+                                  .class =
+                                    DEVCLASS(DEVIF_FMW, DEVFN_CFG, DEV_ACPI),
+                                  .init = acpi_init };
+EXPORT_DEVICE(acpi, &acpi_sysdev, load_sysconf);
\ No newline at end of file
index 33dc87e3a05287e859baebcdd06c1f6b4e337aeb..3d90845ef795ce8e9f70432a8f0dadea51fc77c3 100644 (file)
@@ -49,9 +49,6 @@ static struct devclass ahci_class = AHCI_DEVCLASS;
 extern void
 ahci_fsexport(struct block_dev* bdev, void* fs_node);
 
-extern void
-__ahci_hba_isr(const isr_param* param);
-
 extern void
 __ahci_blkio_handler(struct blkio_req* req);
 
@@ -80,32 +77,18 @@ __hba_reset_port(hba_reg_t* port_reg)
     port_reg[HBA_RPxSCTL] &= ~0xf;
 }
 
-int
-ahci_driver_init(struct device_def* def, struct device* dev)
+struct ahci_driver*
+ahci_driver_init(struct ahci_driver_param* param)
 {
-    struct pci_device* ahci_dev = container_of(dev, struct pci_device, dev);
-
-    struct pci_base_addr* bar6 = &ahci_dev->bar[5];
-    assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO.");
-
-    pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_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);
-    isrm_set_payload(iv, (ptr_t)&ahcis);
-
     struct ahci_driver* ahci_drv = vzalloc(sizeof(*ahci_drv));
     struct ahci_hba* hba = &ahci_drv->hba;
-    ahci_drv->id = iv;
+    ahci_drv->id = param->ahci_iv;
+
+    isrm_set_payload(param->ahci_iv, (ptr_t)&ahcis);
 
     llist_append(&ahcis, &ahci_drv->ahci_drvs);
 
-    hba->base = (hba_reg_t*)ioremap(bar6->start, bar6->size);
+    hba->base = (hba_reg_t*)ioremap(param->mmio_base, param->mmio_size);
 
 #ifdef DO_HBA_FULL_RESET
     // 重置HBA
@@ -186,7 +169,7 @@ ahci_driver_init(struct device_def* def, struct device* dev)
         port_regs[HBA_RPxCMD] |= HBA_PxCMD_ST;
 
         if (!ahci_init_device(port)) {
-            kprintf(KERROR "init fail: 0x%x@p%d", port->regs[HBA_RPxSIG], i);
+            ERROR("init fail: 0x%x@p%d", port->regs[HBA_RPxSIG], i);
             continue;
         }
 
@@ -200,8 +183,7 @@ ahci_driver_init(struct device_def* def, struct device* dev)
         ahci_register_device(hbadev);
     }
 
-    pci_bind_instance(ahci_dev, ahci_drv);
-    return 0;
+    return ahci_drv;
 }
 
 void
@@ -441,12 +423,3 @@ achi_register_ops(struct hba_port* port)
         port->device->ops.submit = scsi_submit;
     }
 }
-
-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 = "Serial ATA Controller",
-                .bind = ahci_driver_init }
-};
-EXPORT_PCI_DEVICE(ahci, &ahcidef);
\ No newline at end of file
diff --git a/lunaix-os/hal/ahci/ahci_pci.c b/lunaix-os/hal/ahci/ahci_pci.c
new file mode 100644 (file)
index 0000000..0ecde58
--- /dev/null
@@ -0,0 +1,51 @@
+#include <lunaix/spike.h>
+
+#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_base_addr* bar6 = &ahci_dev->bar[5];
+    assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO.");
+
+    pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_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);
+
+    struct ahci_driver_param param = {
+        .mmio_base = bar6->start,
+        .mmio_size = bar6->size,
+        .ahci_iv = iv,
+    };
+
+    struct ahci_driver* ahci_drv = ahci_driver_init(&param);
+    pci_bind_instance(ahci_dev, ahci_drv);
+
+    return 0;
+}
+
+static int
+ahci_pci_init(struct device_def* def)
+{
+    return pci_bind_definition_all(pcidev_def(def));
+}
+
+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",
+                .init = ahci_pci_init,
+                .bind = ahci_pci_bind }
+};
+EXPORT_PCI_DEVICE(ahci, &ahcidef, load_postboot);
\ No newline at end of file
index 2ce49ef4e1c9701c8c2070436396e72dc7d0936d..2ad988a4239936f1279127daea516f55d5c34c35 100644 (file)
@@ -7,7 +7,7 @@
 LOG_MODULE("io_evt")
 
 void
-__ahci_hba_isr(const isr_param* param)
+ahci_hba_isr(const isr_param* param)
 {
     struct ahci_hba* hba;
     struct ahci_driver *pos, *n;
index 9806dc0359ec953f0573d7f2459234e854350227..7dfd0a780ddcc620e6acb44da4cfad8a29790151 100644 (file)
@@ -48,4 +48,4 @@ static struct device_def devnull_def = {
     .class = DEVCLASSV(DEVIF_NON, DEVFN_PSEUDO, DEV_NULL, DEV_BUILTIN_NULL),
     .init = pdev_nulldev_init
 };
-EXPORT_DEVICE(nulldev, &devnull_def, load_earlystage);
+EXPORT_DEVICE(nulldev, &devnull_def, load_onboot);
index f579047347cfc03f300b6edd7580eb4d49a541cc..f976c266f21d291635090496a0947db133bbee44 100644 (file)
@@ -34,4 +34,4 @@ static struct device_def devzero_def = {
     .class = DEVCLASSV(DEVIF_NON, DEVFN_PSEUDO, DEV_ZERO, DEV_BUILTIN_ZERO),
     .init = pdev_zerodev_init
 };
-EXPORT_DEVICE(zerodev, &devzero_def, load_earlystage);
+EXPORT_DEVICE(zerodev, &devzero_def, load_onboot);
index 5cbbae8c5015ee38612b0d8ecbcb9a5904c9cef4..a5cc93d11c1fe71028f93bbb337e19de54ca6164 100644 (file)
@@ -248,14 +248,14 @@ ps2_kbd_init(struct device_def* devdef)
     //      https://bochs.sourceforge.io/cgi-bin/lxr/source/bios/rombios32.c#L1314
     //      */
     //     if (!(acpi_ctx->fadt.boot_arch & IAPC_ARCH_8042)) {
-    //         kprintf(KERROR "not found\n");
+    //         ERROR("not found\n");
     //         // FUTURE: Some alternative fallback on this? Check PCI bus for
     //         USB
     //         // controller instead?
     //         return;
     //     }
     // } else {
-    //     kprintf(KWARN "outdated FADT used, assuming exists.\n");
+    //     WARN("outdated FADT used, assuming exists.\n");
     // }
 
     char result;
@@ -277,14 +277,14 @@ ps2_kbd_init(struct device_def* devdef)
     // 4、控制器自检
     result = ps2_issue_cmd_wretry(PS2_CMD_SELFTEST, PS2_NO_ARG);
     if (result != PS2_RESULT_TEST_OK) {
-        kprintf(KWARN "controller self-test failed. (%x)", result);
+        WARN("controller self-test failed. (%x)", result);
         goto done;
     }
 
     // 5、设备自检(端口1自检,通常是我们的键盘)
     result = ps2_issue_cmd_wretry(PS2_CMD_SELFTEST_PORT1, PS2_NO_ARG);
     if (result != 0) {
-        kprintf(KERROR "interface test on port 1 failed. (%x)", result);
+        ERROR("interface test on port 1 failed. (%x)", result);
         goto done;
     }
 
@@ -456,7 +456,7 @@ intr_ps2_kbd_handler(const isr_param* param)
 #endif
 
 #ifdef KBD_DBGLOG
-    kprintf(KDEBUG "%x\n", scancode & 0xff);
+    DEBUG("%x\n", scancode & 0xff);
 #endif
 
     switch (kbd_state.state) {
@@ -532,7 +532,7 @@ ps2_issue_cmd_wretry(char cmd, u16_t arg)
         c++;
     }
     if (c >= 5) {
-        kprintf(KWARN "max attempt reached.");
+        WARN("max attempt reached.");
     }
     return r;
 }
@@ -574,4 +574,4 @@ static struct device_def devrtc_i8042kbd = {
     .class = DEVCLASS(DEVIF_SOC, DEVFN_INPUT, DEV_KBD),
     .init = ps2_kbd_init
 };
-EXPORT_DEVICE(i8042_kbd, &devrtc_i8042kbd, load_earlystage);
+EXPORT_DEVICE(i8042_kbd, &devrtc_i8042kbd, load_onboot);
index 9910051fa8f84d3dcbb8249b8d347c27439fc3a6..81d06422e910b5570df022e8fdd388c4d996d15a 100644 (file)
@@ -101,4 +101,4 @@ static struct device_def uart_pmio_def = {
     .name = "16550 Generic UART (I/O)",
     .init = upiom_init
 };
-EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_earlystage);
\ No newline at end of file
+EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_onboot);
\ No newline at end of file
index fe77652c7b01233dc55661e4b7901ba71f304a0b..09476db5efd958f5ad57ef7b13e4286dbb5fe7a1 100644 (file)
@@ -59,7 +59,7 @@ static u32_t palette[] = {
 #define VGA_REG_OFF 0x0400
 
 static int
-vga_pci_init(struct device_def* devdef, struct device* pcidev_base)
+vga_pci_bind(struct device_def* devdef, struct device* pcidev_base)
 {
     struct pci_device* pcidev = PCI_DEVICE(pcidev_base);
 
@@ -97,6 +97,12 @@ vga_pci_init(struct device_def* devdef, struct device* pcidev_base)
     return 0;
 }
 
+static int
+vga_pci_init(struct device_def* def)
+{
+    return pci_bind_definition_all(pcidev_def(def));
+}
+
 #define VGA_PCI_CLASS 0x30000
 
 static struct pci_device_def vga_pci_devdef = {
@@ -105,6 +111,7 @@ static struct pci_device_def vga_pci_devdef = {
     .ident_mask = PCI_MATCH_EXACT,
     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_DISP, DEV_VGA),
                 .name = "Generic VGA",
-                .bind = vga_pci_init }
+                .init = vga_pci_init,
+                .bind = vga_pci_bind }
 };
-EXPORT_PCI_DEVICE(vga_pci, &vga_pci_devdef);
\ No newline at end of file
+EXPORT_PCI_DEVICE(vga_pci, &vga_pci_devdef, load_onboot);
\ No newline at end of file
index 3e4a3fefdee13be652758b2d26c966aa68467bdf..9a3c581a23c8b77baddabb0bc48aa15e5b1218b2 100644 (file)
@@ -34,29 +34,19 @@ pci_log_device(struct pci_device* pcidev)
     pciaddr_t loc = pcidev->loc;
     struct device_def* binddef = pcidev->binding.def;
 
-    if (!binddef) {
-        kprintf("pci.%d:%d:%d, no binding",
-                PCILOC_BUS(loc),
-                PCILOC_DEV(loc),
-                PCILOC_FN(loc));
-        return;
-    }
-
-    kprintf("pci.%d:%d:%d, dev.%xh:%xh.%d, %s",
+    kprintf("pci.%03d:%02d:%02d, class=%p, vendor:dev=%04x:%04x",
             PCILOC_BUS(loc),
             PCILOC_DEV(loc),
             PCILOC_FN(loc),
-            binddef->class.fn_grp,
-            binddef->class.device,
-            binddef->class.variant,
-            binddef->name);
+            pcidev->class_info,
+            PCI_DEV_VENDOR(pcidev->device_info),
+            PCI_DEV_DEVID(pcidev->device_info));
 }
 
 static struct pci_device*
 pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo)
 {
     pci_reg_t class = pci_read_cspace(pci_base, 0x8);
-    struct hbucket* bucket = device_definitions_byif(DEVIF_PCI);
 
     u32_t devid = PCI_DEV_DEVID(devinfo);
     u32_t vendor = PCI_DEV_VENDOR(devinfo);
@@ -77,50 +67,83 @@ pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo)
     device_register(&device->dev, &pci_def.class, "%x", loc);
     pci_def.class.variant++;
 
-    // find a suitable binding
+    return device;
+}
+
+int
+pci_bind_definition(struct pci_device_def* pcidev_def, int* 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) {
+        ERROR("pcidev %xh:%xh.%d is unbindable",
+              pcidev_def->devdef.class.fn_grp,
+              pcidev_def->devdef.class.device,
+              pcidev_def->devdef.class.variant);
+        return EINVAL;
+    }
 
-    struct pci_device_def *pos, *n;
-    hashtable_bucket_foreach(bucket, pos, n, devdef.hlist_if)
+    *more = 0;
+
+    int bind_attempted = 0;
+    int errno = 0;
+
+    struct device_def* devdef;
+    struct pci_device *pos, *n;
+    llist_for_each(pos, n, &pci_devices, dev_chain)
     {
-        if (pos->dev_class != PCI_DEV_CLASS(class)) {
+        if (binded_pcidev(pos)) {
+            continue;
+        }
+
+        if (class != PCI_DEV_CLASS(pos->class_info)) {
             continue;
         }
 
-        u32_t idm = pos->ident_mask;
-        int result = (pos->dev_ident & idm) == (devinfo & idm);
+        int matched = (pos->device_info & devid_mask) == devid;
 
-        if (result) {
-            goto found;
+        if (!matched) {
+            continue;
         }
-    }
 
-    goto done;
+        if (bind_attempted) {
+            *more = 1;
+            break;
+        }
 
-found:
-    if (!pos->devdef.bind) {
-        kprintf(KERROR "pci_loc:%x, (%xh:%xh.%d) unbindable",
-                loc,
-                pos->devdef.class.fn_grp,
-                pos->devdef.class.device,
-                pos->devdef.class.variant);
-        goto done;
-    }
+        bind_attempted = 1;
+        devdef = &pcidev_def->devdef;
+        errno = devdef->bind(devdef, &pos->dev);
+
+        if (errno) {
+            ERROR("pci_loc:%x, bind (%xh:%xh.%d) failed, e=%d",
+                  pos->loc,
+                  devdef->class.fn_grp,
+                  devdef->class.device,
+                  devdef->class.variant,
+                  errno);
+            continue;
+        }
 
-    int errno = pos->devdef.bind(&pos->devdef, &device->dev);
-    if (errno) {
-        kprintf(KERROR "pci_loc:%x, (%xh:%xh.%d) failed, e=%d",
-                loc,
-                pos->devdef.class.fn_grp,
-                pos->devdef.class.device,
-                pos->devdef.class.variant,
-                errno);
-        goto done;
+        pos->binding.def = &pcidev_def->devdef;
     }
 
-    device->binding.def = &pos->devdef;
+    return errno;
+}
 
-done:
-    return device;
+int
+pci_bind_definition_all(struct pci_device_def* pcidef)
+{
+    int more = 0, e = 0;
+    do {
+        if (!(e = pci_bind_definition(pcidef, &more))) {
+            break;
+        }
+    } while (more);
+
+    return e;
 }
 
 void
@@ -418,8 +441,8 @@ pci_bind_instance(struct pci_device* pcidev, void* devobj)
 }
 
 static struct device_def pci_def = {
-    .name = "pci3.0-hba",
+    .name = "Generic PCI",
     .class = DEVCLASS(DEVIF_SOC, DEVFN_BUSIF, DEV_PCI),
     .init = pci_load_devices
 };
-EXPORT_DEVICE(pci3hba, &pci_def, load_poststage);
+EXPORT_DEVICE(pci3hba, &pci_def, load_sysconf);
index 3035f314dc6b238ca3f56afc0c20d791667845ae..d732f2cd75eaca742d367f68bf975bf80cd90766 100644 (file)
@@ -45,4 +45,4 @@ static struct device_def devrandx86_def = {
     .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
+EXPORT_DEVICE(randdev, &devrandx86_def, load_onboot);
\ No newline at end of file
index 6b645279e9331def4ba43877f3318caeb83331ce..5083444e29bdf7523e96b4637aa35df23e7b963c 100644 (file)
@@ -195,7 +195,7 @@ rtc_init(struct device_def* devdef)
     // Make sure the rtc timer is disabled by default
     rtc_disable_timer();
 
-    struct hwrtc* rtc = hwrtc_alloc_new(devdef, "mc146818");
+    struct hwrtc* rtc = hwrtc_alloc_new("mc146818");
     struct mc146818* state = valloc(sizeof(struct mc146818));
 
     state->rtc_context = rtc;
@@ -212,6 +212,8 @@ rtc_init(struct device_def* devdef)
     rtc->get_counts = rtc_getcnt;
     rtc->chfreq = rtc_chfreq;
 
+    hwrtc_register(&devdef->class, rtc);
+
     return 0;
 }
 
@@ -220,4 +222,4 @@ static struct device_def devrtc_mc146818 = {
     .class = DEVCLASS(DEVIF_SOC, DEVFN_TIME, DEV_RTC),
     .init = rtc_init
 };
-EXPORT_DEVICE(mc146818, &devrtc_mc146818, load_earlystage);
\ No newline at end of file
+EXPORT_DEVICE(mc146818, &devrtc_mc146818, load_timedev);
\ No newline at end of file
similarity index 84%
rename from lunaix-os/hal/rtc/hwrtc.c
rename to lunaix-os/hal/rtc/rtc_device.c
index 87e7d1011942888a41d678725e0586c004982ea2..cd94a97e7aeacc3db7cde9c53a1cfa46e7f2ee7f 100644 (file)
@@ -1,27 +1,19 @@
-#include <hal/hwrtc.h>
-
 #include <lunaix/fs/twifs.h>
 #include <lunaix/fs/twimap.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/status.h>
 
-#include <usr/lunaix/ioctl_defs.h>
+#include <hal/hwrtc.h>
 
-const struct hwrtc* primary_rtc;
+const struct hwrtc* sysrtc;
 static int rtc_count = 0;
 
 DEFINE_LLIST(rtcs);
 
-// void
-// hwrtc_init()
-// {
-//     ldga_invoke_fn0(rtcdev);
-// }
-
 void
 hwrtc_walltime(datetime_t* dt)
 {
-    primary_rtc->get_walltime(primary_rtc, dt);
+    sysrtc->get_walltime(sysrtc, dt);
 }
 
 static int
@@ -69,7 +61,7 @@ hwrtc_read(struct device* dev, void* buf, size_t offset, size_t len)
 }
 
 struct hwrtc*
-hwrtc_alloc_new(struct device_def* def, char* name)
+hwrtc_alloc_new(char* name)
 {
     struct hwrtc* rtc_instance = valloc(sizeof(struct hwrtc));
 
@@ -79,10 +71,7 @@ hwrtc_alloc_new(struct device_def* def, char* name)
 
     llist_append(&rtcs, &rtc_instance->rtc_list);
 
-    if (!primary_rtc) {
-        primary_rtc = rtc_instance;
-    }
-
+    rtc_instance->id = rtc_count++;
     rtc_instance->name = name;
     struct device* rtcdev = device_allocsys(NULL, rtc_instance);
 
@@ -91,18 +80,25 @@ hwrtc_alloc_new(struct device_def* def, char* name)
 
     rtc_instance->rtc_dev = rtcdev;
 
-    device_register(rtcdev, &def->class, "rtc%d", def->class.variant);
+    return rtc_instance;
+}
 
-    def->class.variant++;
+void
+hwrtc_register(struct devclass* class, struct hwrtc* rtc)
+{
+    if (unlikely(!sysrtc)) {
+        sysrtc = rtc;
+    }
 
-    return rtc_instance;
+    class->variant = rtc->id;
+    device_register(rtc->rtc_dev, class, "rtc%d", rtc->id);
 }
 
 static void
 __hwrtc_readinfo(struct twimap* mapping)
 {
     struct hwrtc* rtc = twimap_data(mapping, struct hwrtc*);
-    twimap_printf(mapping, "device: %s\n", rtc->name);
+    twimap_printf(mapping, "name: %s\n", rtc->name);
     twimap_printf(mapping, "frequency: %dHz\n", rtc->base_freq);
     twimap_printf(mapping, "ticks count: %d\n", rtc->get_counts(rtc));
     twimap_printf(
@@ -135,4 +131,4 @@ hwrtc_twifs_export_all()
         hwrtc_twifs_export(pos);
     }
 }
-EXPORT_TWIFS_PLUGIN(rtc_fsexport, hwrtc_twifs_export_all);
\ No newline at end of file
+EXPORT_TWIFS_PLUGIN(rtc_fsexport, hwrtc_twifs_export_all);
index db3e700d004960281d8b000a6240e1e5f9b2ef2a..8ec8747982c384be5350479c3b8ebfd961acc58f 100644 (file)
@@ -1,7 +1,7 @@
 #include <hal/apic_timer.h>
-#include <hal/hwrtc.h>
 #include <hal/hwtimer.h>
 
+#include <lunaix/clock.h>
 #include <lunaix/compiler.h>
 #include <lunaix/isrm.h>
 #include <lunaix/spike.h>
@@ -109,13 +109,13 @@ apic_timer_init(struct hwtimer* timer, u32_t hertz, timer_tick_cb timer_cb)
 
 #ifdef __LUNAIXOS_DEBUG__
     if (frequency < 1000) {
-        kprintf(KWARN "Frequency too low. Millisecond timer might be dodgy.");
+        WARN("Frequency too low. Millisecond timer might be dodgy.");
     }
 #endif
 
     apic_timer_done = 0;
 
-    primary_rtc->cls_mask(primary_rtc);
+    sysrtc->cls_mask(sysrtc);
     apic_write_reg(APIC_TIMER_ICR, APIC_BASETICKS); // start APIC timer
 
     // enable interrupt, just for our RTC start ticking!
@@ -125,14 +125,14 @@ apic_timer_init(struct hwtimer* timer, u32_t hertz, timer_tick_cb timer_cb)
 
     cpu_disable_interrupt();
 
-    primary_rtc->set_mask(primary_rtc);
+    sysrtc->set_mask(sysrtc);
 
-    base_freq = primary_rtc->get_counts(primary_rtc);
-    base_freq = APIC_BASETICKS / base_freq * primary_rtc->base_freq;
+    base_freq = sysrtc->get_counts(sysrtc);
+    base_freq = APIC_BASETICKS / base_freq * sysrtc->base_freq;
 
     assert_msg(base_freq, "Fail to initialize timer (NOFREQ)");
 
-    kprintf(KINFO "hw: %u Hz; os: %u Hz", base_freq, frequency);
+    kprintf("hw: %u Hz; os: %u Hz", base_freq, frequency);
 
     // cleanup
     isrm_ivfree(iv_timer);
similarity index 71%
rename from lunaix-os/hal/timer/hwtimer.c
rename to lunaix-os/hal/timer/timer_device.c
index 91dca07459d8e9caf450ecbaab8c9cddd78d8f6d..c5341bed3886db14fe60e4e5c5f460c1ff61a4c1 100644 (file)
@@ -1,34 +1,34 @@
-#include <hal/hwtimer.h>
 #include <lunaix/spike.h>
+#include <lunaix/time.h>
 
-#include <usr/lunaix/ioctl_defs.h>
+#include <hal/hwtimer.h>
 
-struct hwtimer* current_timer;
+const struct hwtimer* systimer;
 
 ticks_t
 hwtimer_base_frequency()
 {
-    assert(current_timer);
-    return current_timer->base_freq;
+    assert(systimer);
+    return systimer->base_freq;
 }
 
 ticks_t
 hwtimer_current_systicks()
 {
-    assert(current_timer);
-    return current_timer->systicks();
+    assert(systimer);
+    return systimer->systicks();
 }
 
 ticks_t
 hwtimer_to_ticks(u32_t value, int unit)
 {
-    assert(current_timer);
+    assert(systimer);
     // in case system frequency is less than 1000Hz
     if (unit != TIME_MS) {
-        return current_timer->running_freq * unit * value;
+        return systimer->running_freq * unit * value;
     }
 
-    ticks_t freq_ms = current_timer->running_freq / 1000;
+    ticks_t freq_ms = systimer->running_freq / 1000;
 
     return freq_ms * value;
 }
@@ -56,7 +56,7 @@ hwtimer_init(u32_t hertz, void* tick_callback)
     hwt_ctx->init(hwt_ctx, hertz, tick_callback);
     hwt_ctx->running_freq = hertz;
 
-    current_timer = hwt_ctx;
+    systimer = hwt_ctx;
 
     struct device* timerdev = device_allocsys(NULL, hwt_ctx);
 
index f362b2d08a6fa16af793d6f42694223240bd45f7..f14ebcaff2d6838e3e003194178ea1a6a532ed20 100644 (file)
@@ -49,9 +49,6 @@ typedef struct
     struct acpi_mcfg_toc mcfg;
 } acpi_context;
 
-int
-acpi_init();
-
 acpi_context*
 acpi_get_context();
 
index 13312a525135ca63fc12406519ba06d0efaf5cea..d4db5c1d76f1e803d01299e049f61646636b28fd 100644 (file)
@@ -2,6 +2,7 @@
 #define __LUNAIX_AHCI_H
 
 #include "hba.h"
+#include <lunaix/isrm.h>
 
 /*
  * Macro naming rule:
@@ -21,6 +22,13 @@ struct ahci_driver
     int id;
 };
 
+struct ahci_driver_param
+{
+    ptr_t mmio_base;
+    size_t mmio_size;
+    int ahci_iv;
+};
+
 void
 ahci_parse_dev_info(struct hba_device* dev_info, u16_t* data);
 
@@ -47,4 +55,10 @@ ahci_try_send(struct hba_port* port, int slot);
 void
 ahci_post(struct hba_port* port, struct hba_cmd_state* state, int slot);
 
+struct ahci_driver*
+ahci_driver_init(struct ahci_driver_param* param);
+
+void
+ahci_hba_isr(const isr_param* param);
+
 #endif /* __LUNAIX_AHCI_H */
index a5ebb9c21e0587c3f9de6df0d2ee895fb0983aef..c0186ff7cd14b363ba3b0b66d36347e0937d00d3 100644 (file)
@@ -16,6 +16,7 @@ struct hwrtc
     struct llist_header rtc_list;
     struct device* rtc_dev;
 
+    int id;
     char* name;
     void* data;
     ticks_t base_freq;
@@ -29,15 +30,13 @@ struct hwrtc
     int (*chfreq)(struct hwrtc*, int);
 };
 
-extern const struct hwrtc* primary_rtc;
-
-void
-hwrtc_init();
-
 struct hwrtc*
-hwrtc_alloc_new(struct device_def* def, char* name);
+hwrtc_alloc_new(char* name);
 
 void
 hwrtc_walltime(datetime_t* dt);
 
+void
+hwrtc_register(struct devclass* class, struct hwrtc* rtc);
+
 #endif /* __LUNAIX_HWRTC_H */
index 22fdaacc37b71168bf624a2db00e43d95bf55d33..3a55d6d96e235aa836df1a508b2e4fee7161afd1 100644 (file)
@@ -22,8 +22,6 @@ struct hwtimer
     ticks_t running_freq;
 };
 
-extern struct hwtimer* current_timer;
-
 void
 hwtimer_init(u32_t hertz, void* tick_callback);
 
index e5bbd456285db9aa36e32a64d562074003ddc136..adc270fc06156a95755afd6335676a5d046abf72 100644 (file)
@@ -6,8 +6,8 @@
 #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 EXPORT_PCI_DEVICE(id, pci_devdef, stage)                               \
+    EXPORT_DEVICE(id, &(pci_devdef)->devdef, stage)
 
 #define PCI_MATCH_EXACT -1
 #define PCI_MATCH_ANY 0
@@ -102,6 +102,12 @@ struct pci_device
 };
 #define PCI_DEVICE(devbase) (container_of((devbase), struct pci_device, dev))
 
+struct pci_device_list
+{
+    struct llist_header peers;
+    struct pci_device* pcidev;
+};
+
 typedef void* (*pci_drv_init)(struct pci_device*);
 
 #define PCI_DEVIDENT(vendor, id)                                               \
@@ -114,6 +120,10 @@ struct pci_device_def
     u32_t ident_mask;
     struct device_def devdef;
 };
+#define pcidev_def(dev_def_ptr)                                                \
+    container_of((dev_def_ptr), struct pci_device_def, devdef)
+
+#define binded_pcidev(pcidev) ((pcidev)->binding.def)
 
 /**
  * @brief 根据类型代码(Class Code)去在拓扑中寻找一个设备
@@ -161,4 +171,10 @@ pci_probe_bar_info(struct pci_device* device);
 void
 pci_probe_msi_info(struct pci_device* device);
 
+int
+pci_bind_definition(struct pci_device_def* pcidev_def, int* more);
+
+int
+pci_bind_definition_all(struct pci_device_def* pcidef);
+
 #endif /* __LUNAIX_PCI_H */
index a189a4de8f70735273be3f15aeec889a1c184b7c..a869c8c2e1a0f759b52795b00246e60f6d428044 100644 (file)
@@ -13,6 +13,7 @@
 #define BLKIO_PENDING 0x8
 
 #define BLKIO_WAIT 0x1
+#define BLKIO_NOASYNC 0x2
 
 // Free on complete
 #define BLKIO_FOC 0x10
index 4eea312fedc7206bbee01af4c1f8e138a0ead913..58e1ead7886ab1f7993e171bfd51d1c2422d1ec3 100644 (file)
@@ -2,6 +2,16 @@
 #define __LUNAIX_CLOCK_H
 
 #include <lunaix/time.h>
+
+#include <hal/hwrtc.h>
+#include <hal/hwtimer.h>
+
+extern const struct hwrtc* sysrtc;
+extern const struct hwtimer* systimer;
+
+void
+clock_init();
+
 void
 clock_walltime(datetime_t* datetime);
 
index 314afd95e297948b6d3596f341ed6f770c32c819..f011a0b9df07cd865c81ba2c7e741ee87c5598ca 100644 (file)
 #define stringify(v) #v
 #define stringify__(v) stringify(v)
 
+inline static void noret
+spin()
+{
+    volatile int __infloop = 1;
+    while (__infloop)
+        ;
+    __builtin_unreachable();
+}
+
 #endif /* __LUNAIX_COMPILER_H */
index fac62a9b54f179c5d42d1ed598c96fe81234e330..f65082126313c81202e0b587d7ae869849c73d01 100644 (file)
 #include <usr/lunaix/device.h>
 
 /**
- * @brief Export a device definition
+ * @brief Export a device definition (i.e., device driver metadata)
  *
  */
 #define EXPORT_DEVICE(id, devdef, load_order)                                  \
     export_ldga_el(devdefs, id, ptr_t, devdef);                                \
     export_ldga_el_sfx(devdefs, id##_ldorder, ptr_t, devdef, load_order);
 
+/**
+ * @brief Mark the device definition can be loaded on demand, all other loading
+ * options are extended from this
+ */
 #define load_on_demand ld_ondemand
-#define load_pci_probe ld_ondemand
 
 /**
- * @brief Mark the device definition should be loaded automatically as earlier
- * as possible in the kernel bootstrapping stage (before initialization of file
- * systems). Load here if your driver is standalone and require no other than
- * basic memory allocation services
+ * @brief Mark the device definition to be loaded as system configuration
+ * device. These kind of devices are defined to be the devices that talk to the
+ * system firmware to do config, or collecting crucial information about the
+ * system. For instances, ACPI, SoC components, and other **interconnection**
+ * buese (not USB!). Such device driver must only rely on basic memory
+ * management service, and must not try accessing subsystems other than the mm
+ * unit, for example, timer, interrupt, file-system, must not assumed exist.
  *
  */
-#define load_earlystage ld_early
+#define load_sysconf ld_sysconf
+
+/**
+ * @brief Mark the device definition should be loaded as time device, for
+ * example a real time clock device. Such device will be loaded and managed by
+ * clock subsystem
+ */
+#define load_timedev ld_timedev
 
 /**
- * @brief Mark the device definition should be loaded automatically after timer
- * is ready. Load here if your driver require a basic timing service
+ * @brief Mark the device definition should be loaded automatically during the
+ * bootstrapping stage. Most of the driver do load there.
  *
  */
-#define load_timerstage ld_aftertimer
+#define load_onboot ld_kboot
 
 /**
  * @brief Mark the device definition should be loaded automatically in
- * the post boostrapping stage (i.e., the start up of proc0). Load here if your
- * driver involves async mechanism
+ * the post boostrapping stage (i.e., the start up of proc0), where most of
+ * kernel sub-system are became ready to use. Do your load there if your driver
+ * depends on such condition
  *
  */
-#define load_poststage ld_post
+#define load_postboot ld_post
+
+#define __foreach_exported_device_of(stage, index, pos)                        \
+    ldga_foreach(dev_##stage, struct device_def*, index, pos)
+#define foreach_exported_device_of(stage, index, pos)                          \
+    __foreach_exported_device_of(stage, index, pos)
 
 /**
  * @brief Declare a device class
@@ -115,8 +134,24 @@ struct device_def
 
     struct devclass class;
 
+    /**
+     * @brief Called when the driver is required to initialize itself.
+     *
+     */
     int (*init)(struct device_def*);
+
+    /**
+     * @brief Called when the driver is required to bind with a device. This is
+     * the case for a real-hardware-oriented driver
+     *
+     */
     int (*bind)(struct device_def*, struct device*);
+
+    /**
+     * @brief Called when a driver is requested to detach from the device and
+     * free up all it's resources
+     *
+     */
     int (*free)(struct device_def*, void* instance);
 };
 
@@ -201,13 +236,13 @@ device_scan_drivers();
 /*------ Load hooks ------*/
 
 void
-device_earlystage();
+device_onbooot_load();
 
 void
-device_poststage();
+device_postboot_load();
 
 void
-device_timerstage();
+device_sysconf_load();
 
 static inline void
 device_lock(struct device* dev)
index af1814af5b19ce69e8ba607b8b475a5ee8c4e92d..9011da3d567edd623e7cf1e37ca660cb3828cc9d 100644 (file)
@@ -26,6 +26,8 @@
 
         I2C: device connected through the IIC protocol
 
+        FMW: device is a system board firmware
+
     The function defines the functionality that the device is designated to
    serve. Lunaix identify the following values:
 
 
         TTY: a device which can be called as teletypewriter, system can use such
             device for output into external environment
+
+        CFG: device that provide configuration service to the system or other
+   devices
+
+
 */
 
 #define DEV_FNGRP(if_, function)                                               \
@@ -67,6 +74,7 @@
 #define DEVIF_USB 0x3
 #define DEVIF_SPI 0x4
 #define DEVIF_I2C 0x5
+#define DEVIF_FMW 0x6
 
 #define DEVFN_PSEUDO 0x0
 #define DEVFN_CHAR 0x1
@@ -76,6 +84,7 @@
 #define DEVFN_BUSIF 0x7
 #define DEVFN_TTY 0x8
 #define DEVFN_DISP 0x9
+#define DEVFN_CFG 0xa
 
 #define DEV_BUILTIN 0
 #define DEV_BUILTIN_NULL 0
 #define DEV_KBD 11
 #define DEV_GFXA 12
 #define DEV_VGA 13
+#define DEV_ACPI 14
 
 struct devident
 {
index d5990235253f2b06485b7f10d23d63ac2b5f84cd..1fe37f1562c4976e21f82216c5562d06fb6f26aa 100644 (file)
@@ -144,8 +144,8 @@ struct v_file_ops
     // These additional operations allow underlying fs to use more specialized
     // and optimized code.
 
-    int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
-    int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos);
+    int (*write_page)(struct v_inode* inode, void* pg, size_t fpos);
+    int (*read_page)(struct v_inode* inode, void* pg, size_t fpos);
 
     int (*readdir)(struct v_file* file, struct dir_context* dctx);
     int (*seek)(struct v_inode* inode, size_t offset); // optional
@@ -497,6 +497,12 @@ default_file_write(struct v_inode* inode,
                    size_t len,
                    size_t fpos);
 
+int
+default_file_read_page(struct v_inode* inode, void* buffer, size_t fpos);
+
+int
+default_file_write_page(struct v_inode* inode, void* buffer, size_t fpos);
+
 int
 default_file_readdir(struct v_file* file, struct dir_context* dctx);
 
index 1a6aee233b6d5858187bd177faf5f5b37a769666..6fbdbbca71ee6efff2819956094e152ac05cd2c9 100644 (file)
 #define ISO_SIGNATURE_HI 0x31
 
 // Volume Types
-#define ISO_VOLBOOT 0     // Boot Record
-#define ISO_VOLPRIM 1     // Primary
-#define ISO_VOLSUPP 2     // Supplementary
-#define ISO_VOLPART 3     // Partition
-#define ISO_VOLTERM 255   // Volume descriptor set terminator
+#define ISO_VOLBOOT 0   // Boot Record
+#define ISO_VOLPRIM 1   // Primary
+#define ISO_VOLSUPP 2   // Supplementary
+#define ISO_VOLPART 3   // Partition
+#define ISO_VOLTERM 255 // Volume descriptor set terminator
 
 #define ISO_FHIDDEN 0x1   // a hidden file
 #define ISO_FDIR 0x2      // a directory file
@@ -156,8 +156,8 @@ struct iso_drecord
     iso_bbo32_t data_size;
     struct iso_datetime2 mktime; // Time the record is made, see 9.1.5
     u8_t flags;
-    u8_t fu_sz;                  // size of file unit (FU)
-    u8_t gap_sz;                 // size of gap if FU is interleaved.
+    u8_t fu_sz;  // size of file unit (FU)
+    u8_t gap_sz; // size of gap if FU is interleaved.
     iso_bbo16_t vol_seq;
     struct iso_var_mdu name;
 } PACKED;
@@ -340,6 +340,12 @@ iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
 int
 iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
 
+int
+iso9660_read_page(struct v_inode* inode, void* buffer, size_t fpos);
+
+int
+iso9660_write_page(struct v_inode* inode, void* buffer, size_t fpos);
+
 int
 iso9660_seek(struct v_inode* inode, size_t offset);
 
index a2a0e21d5f66c1c56e33e2947306fb930d78ca2e..652fda874c821be670406d749125637431a95fab 100644 (file)
                                                       : 0)                      \
                              : (31 - __builtin_clz(x)))
 
-inline static void noret
-spin()
-{
-    volatile int __infloop = 1;
-    while (__infloop)
-        ;
-    __builtin_unreachable();
-}
-
 #ifndef __LUNAIXOS_NASSERT__
 #define assert(cond)                                                           \
     if (!(cond)) {                                                             \
index 24233159bc608de5a5ebc57db45e18e2e893d146..b372daad4ce64f18b7665fb1180bc644127ab1cc 100644 (file)
 #define KLOG_ERROR 3
 #define KLOG_FATAL 4
 
-#define _LEVEL_INFO "0"
-#define _LEVEL_WARN "1"
-#define _LEVEL_ERROR "2"
-#define _LEVEL_DEBUG "3"
-
 #define KMSG_LVLSTART '\x1b'
 #define KMSG_LOGLEVEL(c) ((c) - '0')
 
     {                                                                          \
         va_list args;                                                          \
         va_start(args, fmt);                                                   \
-        __kprintf(module, fmt, args);                                          \
+        kprintf_m(module, fmt, args);                                          \
         va_end(args);                                                          \
     }
 
+#define DEBUG(fmt, ...) kprintf(KDEBUG fmt, ##__VA_ARGS__)
+#define WARN(fmt, ...) kprintf(KWARN fmt, ##__VA_ARGS__)
+#define ERROR(fmt, ...) kprintf(KERROR fmt, ##__VA_ARGS__)
+#define FATAL(fmt, ...)                                                        \
+    ({                                                                         \
+        kprintf(KFATAL fmt, ##__VA_ARGS__);                                    \
+        spin();                                                                \
+    })
+
 void
-__kprintf(const char* component, const char* fmt, va_list args);
+kprintf_m(const char* component, const char* fmt, va_list args);
+
+// TODO need more thought on it
+
+// struct klog_chunk
+// {
+//     void* log_entry;
+//     size_t max_len;
+//     size_t len;
+// };
+
+// struct klog_chunk*
+// kprintf_lcstart_m(const char* component, size_t size);
+
+// void
+// kprintf_lcappend_m(struct klog_chunk*, const char* fmt, va_list args);
+
+// void
+// kprintf_lcdone_m(struct klog_chunk*);
 
 #endif /* __LUNAIX_SYSLOG_H */
index 9edf96165e26755e8b00603c72902a0f68a0ada9..44a2da74f8b3b35cd6193b5c9dad5e71c4b4b5f8 100644 (file)
@@ -13,6 +13,7 @@ struct ksym_entry
 struct trace_record
 {
     ptr_t pc;
+    ptr_t sym_pc;
     char* symbol;
 };
 
index 9d49bfcb98d95845449c4e69a8251570f0264cb8..033fa0abe90fa222aa11121b9748ed7002a12f3e 100644 (file)
@@ -83,7 +83,7 @@ blkpart_probegpt(struct device* master)
     u32_t crc = gpt_hdr->hdr_cksum;
     gpt_hdr->hdr_cksum = 0;
     if (crc32b((void*)gpt_hdr, sizeof(*gpt_hdr)) != crc) {
-        kprintf(KWARN "checksum failed");
+        WARN("checksum failed");
         // FUTURE check the backup header
         return EINVAL;
     }
index 3f3c1e8ab647905375a0efb1acec730a8fbdbc98..a2242adb39c43b898bba75f562ca67243f9b760a 100644 (file)
@@ -47,6 +47,21 @@ block_init()
     blk_parent_dev = device_addcat(NULL, "block");
 }
 
+static int
+__block_commit(struct blkio_context* blkio, struct blkio_req* req, int flags)
+{
+    int errno;
+    blkio_commit(blkio, req, flags);
+
+    if ((errno = req->errcode)) {
+        errno = -errno;
+    }
+
+    vbuf_free(req->vbuf);
+    blkio_free_req(req);
+    return errno;
+}
+
 int
 __block_read(struct device* dev, void* buf, size_t offset, size_t len)
 {
@@ -78,21 +93,16 @@ __block_read(struct device* dev, void* buf, size_t offset, size_t len)
     }
 
     req = blkio_vrd(vbuf, rd_block, NULL, NULL, 0);
-    blkio_commit(bdev->blkio, req, BLKIO_WAIT);
 
-    if (!(errno = req->errcode)) {
+    if (!(errno = __block_commit(bdev->blkio, req, BLKIO_WAIT))) {
         memcpy(buf, head_buf + r, rd_size);
         errno = len;
-    } else {
-        errno = -errno;
     }
 
     if (head_buf) {
         vfree(head_buf);
     }
 
-    blkio_free_req(req);
-    vbuf_free(vbuf);
     return errno;
 }
 
@@ -126,21 +136,16 @@ __block_write(struct device* dev, void* buf, size_t offset, size_t len)
     }
 
     req = blkio_vwr(vbuf, wr_block, NULL, NULL, 0);
-    blkio_commit(bdev->blkio, req, BLKIO_WAIT);
 
-    int errno = req->errcode;
-    if (!errno) {
+    int errno;
+    if (!(errno = __block_commit(bdev->blkio, req, BLKIO_WAIT))) {
         errno = len;
-    } else {
-        errno = -errno;
     }
 
     if (tmp_buf) {
         vfree(tmp_buf);
     }
 
-    blkio_free_req(req);
-    vbuf_free(vbuf);
     return errno;
 }
 
@@ -163,17 +168,11 @@ __block_read_page(struct device* dev, void* buf, size_t offset)
 
     struct blkio_req* req = blkio_vrd(vbuf, lba, NULL, NULL, 0);
 
-    blkio_commit(bdev->blkio, req, BLKIO_WAIT);
-
-    int errno = req->errcode;
-    if (!errno) {
+    int errno;
+    if (!(errno = __block_commit(bdev->blkio, req, BLKIO_WAIT))) {
         errno = rd_lba * bdev->blk_size;
-    } else {
-        errno = -errno;
     }
 
-    blkio_free_req(req);
-    vbuf_free(vbuf);
     return errno;
 }
 
@@ -184,29 +183,23 @@ __block_write_page(struct device* dev, void* buf, size_t offset)
     struct block_dev* bdev = (struct block_dev*)dev->underlay;
 
     u32_t lba = offset / bdev->blk_size + bdev->start_lba;
-    u32_t rd_lba = MIN(lba + PG_SIZE / bdev->blk_size, bdev->end_lba);
+    u32_t wr_lba = MIN(lba + PG_SIZE / bdev->blk_size, bdev->end_lba);
 
-    if (rd_lba <= lba) {
+    if (wr_lba <= lba) {
         return 0;
     }
 
-    rd_lba -= lba;
+    wr_lba -= lba;
 
-    vbuf_alloc(&vbuf, buf, rd_lba * bdev->blk_size);
+    vbuf_alloc(&vbuf, buf, wr_lba * bdev->blk_size);
 
     struct blkio_req* req = blkio_vwr(vbuf, lba, NULL, NULL, 0);
 
-    blkio_commit(bdev->blkio, req, BLKIO_WAIT);
-
-    int errno = req->errcode;
-    if (!errno) {
-        errno = rd_lba * bdev->blk_size;
-    } else {
-        errno = -errno;
+    int errno;
+    if (!(errno = __block_commit(bdev->blkio, req, BLKIO_WAIT))) {
+        errno = wr_lba * bdev->blk_size;
     }
 
-    blkio_free_req(req);
-    vbuf_free(vbuf);
     return errno;
 }
 
@@ -217,18 +210,12 @@ __block_rd_lb(struct block_dev* bdev, void* buf, u64_t start, size_t count)
     vbuf_alloc(&vbuf, buf, bdev->blk_size * count);
 
     struct blkio_req* req = blkio_vrd(vbuf, start, NULL, NULL, 0);
-    blkio_commit(bdev->blkio, req, BLKIO_WAIT);
 
-    int errno = req->errcode;
-    if (!errno) {
+    int errno;
+    if (!(errno = __block_commit(bdev->blkio, req, BLKIO_WAIT))) {
         errno = count;
-    } else {
-        errno = -errno;
     }
 
-    blkio_free_req(req);
-    vbuf_free(vbuf);
-
     return errno;
 }
 
@@ -239,18 +226,12 @@ __block_wr_lb(struct block_dev* bdev, void* buf, u64_t start, size_t count)
     vbuf_alloc(&vbuf, buf, bdev->blk_size * count);
 
     struct blkio_req* req = blkio_vwr(vbuf, start, NULL, NULL, 0);
-    blkio_commit(bdev->blkio, req, BLKIO_WAIT);
 
-    int errno = req->errcode;
-    if (!errno) {
+    int errno;
+    if (!(errno = __block_commit(bdev->blkio, req, BLKIO_WAIT))) {
         errno = count;
-    } else {
-        errno = -errno;
     }
 
-    blkio_free_req(req);
-    vbuf_free(vbuf);
-
     return errno;
 }
 
@@ -295,7 +276,7 @@ block_mount(struct block_dev* bdev, devfs_exporter fs_export)
 
     errno = blkpart_probegpt(bdev->dev);
     if (errno < 0) {
-        kprintf(KERROR "Fail to parse partition table (%d)", errno);
+        ERROR("Fail to parse partition table (%d)", errno);
     } else if (!errno) {
         // TODO try other PT parser...
     }
@@ -307,7 +288,7 @@ block_mount(struct block_dev* bdev, devfs_exporter fs_export)
     return errno;
 
 error:
-    kprintf(KERROR "Fail to mount block device: %s (%x)", bdev->name, -errno);
+    ERROR("Fail to mount block device: %s (%x)", bdev->name, -errno);
     return errno;
 }
 
index 6a7d81136785f44d5e20bafd81aea3fec1576ae4..edfeceaec54c6f44e311580b5cd57b5a98da0a15 100644 (file)
@@ -42,23 +42,23 @@ void
 sdbg_imm(const isr_param* param)
 {
     struct exec_param* execp = param->execp;
-    kprintf(KDEBUG "Quick debug mode\n");
-    kprintf(KDEBUG "cs=%p eip=%p eax=%p ebx=%p\n",
+    DEBUG("Quick debug mode\n");
+    DEBUG("cs=%p eip=%p eax=%p ebx=%p\n",
             execp->cs,
             execp->eip,
             param->registers.eax,
             param->registers.ebx);
-    kprintf(KDEBUG "ecx=%p edx=%p edi=%p esi=%p\n",
+    DEBUG("ecx=%p edx=%p edi=%p esi=%p\n",
             param->registers.ecx,
             param->registers.edx,
             param->registers.edi,
             param->registers.esi);
-    kprintf(KDEBUG "u.esp=%p k.esp=%p ebp=%p ps=%p\n",
+    DEBUG("u.esp=%p k.esp=%p ebp=%p ps=%p\n",
             param->esp,
             execp->esp,
             param->registers.ebp,
             execp->eflags);
-    kprintf(KDEBUG "ss=%p ds=%p es=%p fs=%p gs=%p\n",
+    DEBUG("ss=%p ds=%p es=%p fs=%p gs=%p\n",
             execp->ss,
             param->registers.ds,
             param->registers.es,
@@ -82,7 +82,7 @@ sdbg_init()
     struct serial_dev* sdev = serial_get_avilable();
 
     if (!sdev) {
-        kprintf(KERROR "no serial port available\n");
+        ERROR("no serial port available\n");
         return;
     }
 
index 62ceb0ef723409d46c56c62ae88a5d65e761f48e..1235884c68704417f821f36501fa8249133fd2de 100644 (file)
@@ -91,8 +91,10 @@ trace_walkback(struct trace_record* tb_buffer,
         ptr_t pc = *(frame + 1);
 
         current = trace_sym_lookup(pc);
-        tb_buffer[i] = (struct trace_record){ .pc = current ? current->pc : pc,
-                                              .symbol = ksym_getstr(current) };
+        tb_buffer[i] =
+          (struct trace_record){ .pc = pc,
+                                 .sym_pc = current ? current->pc : 0,
+                                 .symbol = ksym_getstr(current) };
 
         frame = (ptr_t*)*frame;
         i++;
@@ -105,19 +107,27 @@ trace_walkback(struct trace_record* tb_buffer,
     return i;
 }
 
+static inline void
+trace_print_code_entry(ptr_t sym_pc, ptr_t inst_pc, char* sym)
+{
+    DEBUG("%p+%p: %s", sym_pc, inst_pc - sym_pc, sym);
+}
+
 void
 trace_printstack_of(ptr_t fp)
 {
     struct trace_record tbs[NB_TRACEBACK];
 
+    // Let's get our Stackwalker does his job ;)
     int n = trace_walkback(tbs, fp, NB_TRACEBACK, &fp);
 
     if (fp) {
-        kprintf(KDEBUG "...<truncated>");
+        DEBUG("...<truncated>");
     }
 
     for (int i = 0; i < n; i++) {
-        kprintf(KDEBUG "%p: %s", tbs[i].pc, tbs[i].symbol);
+        struct trace_record* tb = &tbs[i];
+        trace_print_code_entry(tb->sym_pc, tb->pc, tb->symbol);
     }
 }
 
@@ -133,11 +143,12 @@ trace_printswctx(const isr_param* p, char* direction)
 
     struct ksym_entry* sym = trace_sym_lookup(p->execp->eip);
 
-    kprintf(KDEBUG ">> (sw:%s) iv:%d, errno:%p <<",
-            direction,
-            p->execp->vector,
-            p->execp->err_code);
-    kprintf(KDEBUG "%p:%s", p->execp->eip, ksym_getstr(sym));
+    DEBUG(">> (sw:%s) iv:%d, errno:%p <<",
+          direction,
+          p->execp->vector,
+          p->execp->err_code);
+
+    trace_print_code_entry(sym->pc, p->execp->eip, ksym_getstr(sym));
 }
 
 void
@@ -147,7 +158,7 @@ trace_printstack_isr(const isr_param* isrm)
     ptr_t fp = cpu_get_fp();
     int prev_fromusr = 0;
 
-    kprintf(KDEBUG "stack trace (pid=%d)\n", __current->pid);
+    DEBUG("stack trace (pid=%d)\n", __current->pid);
 
     trace_printstack_of(fp);
 
index 41238620b64caab78863470672d8e8b6c7fb8d73..236ac5aa33613655b17c7b361ebacd84217a5802 100644 (file)
@@ -85,32 +85,33 @@ device_definitions_byif(int if_type)
     return &dev_byif[__hashkey(dev_byif, if_type)];
 }
 
-#define device_load_on_stage(stage)                                            \
+#define __device_load_on_stage(stage)                                          \
     ({                                                                         \
         int idx = 0;                                                           \
         struct device_def* devdef;                                             \
-        ldga_foreach(dev_ld_##stage, struct device_def*, idx, devdef)          \
+        ldga_foreach(dev_##stage, struct device_def*, idx, devdef)             \
         {                                                                      \
             devdef->init(devdef);                                              \
         }                                                                      \
     })
+#define device_load_on_stage(stage) __device_load_on_stage(stage)
 
 void
-device_earlystage()
+device_onbooot_load()
 {
-    device_load_on_stage(early);
+    device_load_on_stage(load_onboot);
 }
 
 void
-device_timerstage()
+device_postboot_load()
 {
-    device_load_on_stage(aftertimer);
+    device_load_on_stage(load_postboot);
 }
 
 void
-device_poststage()
+device_sysconf_load()
 {
-    device_load_on_stage(post);
+    device_load_on_stage(load_sysconf);
 }
 
 static int
index 1a49b0519ebdca9882b67baae30cf661ec6a4762..f586addca408066d9c44ee2d0a470df02e0d4af1 100644 (file)
@@ -37,7 +37,7 @@ devfs_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 }
 
 int
-devfs_read_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
+devfs_read_page(struct v_inode* inode, void* buffer, size_t fpos)
 {
     assert(inode->data);
 
@@ -51,7 +51,7 @@ devfs_read_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 }
 
 int
-devfs_write_page(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
+devfs_write_page(struct v_inode* inode, void* buffer, size_t fpos)
 {
     assert(inode->data);
 
index 878ec024a51b143ac6eeffdcd3bf85423ed44a63..8512d8e214de5904fc75a5da18b5412a0f478b62 100644 (file)
@@ -30,6 +30,18 @@ default_file_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     return ENOTSUP;
 }
 
+int
+default_file_read_page(struct v_inode* inode, void* buffer, size_t fpos)
+{
+    return ENOTSUP;
+}
+
+int
+default_file_write_page(struct v_inode* inode, void* buffer, size_t fpos)
+{
+    return ENOTSUP;
+}
+
 int
 default_file_readdir(struct v_file* file, struct dir_context* dctx)
 {
index f07f56036258fa14568af053a78ffd458480dcdb..a48da33845d737d2bea57eb3a73fea41ac9b66cb 100644 (file)
@@ -4,6 +4,7 @@
 #include <lunaix/spike.h>
 
 #include <klibc/string.h>
+#include <sys/mm/mempart.h>
 
 int
 iso9660_open(struct v_inode* this, struct v_file* file)
@@ -79,6 +80,12 @@ done:
     return errno;
 }
 
+int
+iso9660_read_page(struct v_inode* inode, void* buffer, size_t fpos)
+{
+    return iso9660_read(inode, buffer, MEM_PAGE, fpos);
+}
+
 int
 iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
@@ -86,6 +93,13 @@ iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     return ENOTSUP;
 }
 
+int
+iso9660_write_page(struct v_inode* inode, void* buffer, size_t fpos)
+{
+    // TODO
+    return ENOTSUP;
+}
+
 int
 iso9660_seek(struct v_inode* inode, size_t offset)
 {
index ac151b32d10759697d05b06bdadcf0afc4c1dd5b..58d1b8f8c98822c0b624b1c06e390c1972aefe42 100644 (file)
@@ -14,9 +14,9 @@ static struct v_inode_ops iso_inode_ops = {
 
 static struct v_file_ops iso_file_ops = { .close = iso9660_close,
                                           .read = iso9660_read,
-                                          .read_page = iso9660_read,
+                                          .read_page = iso9660_read_page,
                                           .write = iso9660_write,
-                                          .write_page = iso9660_write,
+                                          .write_page = iso9660_write_page,
                                           .seek = iso9660_seek,
                                           .readdir = iso9660_readdir };
 
index 97ef359f40351c22acb2f8937bc27f82cd3c37b0..084a400a1993000a09f7a770fa844a3ec21f5927 100644 (file)
@@ -180,11 +180,11 @@ vfs_mount_at(const char* fs_name,
     return errno;
 
 cleanup:
-    kprintf(KERROR "mount: dev=%s, fs=%s, mode=%d, err=%d",
-            dev_name,
-            fs_name,
-            options,
-            errno);
+    ERROR("mount: dev=%s, fs=%s, mode=%d, err=%d",
+          dev_name,
+          fs_name,
+          options,
+          errno);
     mnt_point->super_block = old_sb;
     vfs_sb_free(sb);
     return errno;
@@ -234,12 +234,11 @@ __DEFINE_LXSYSCALL4(int,
                     int,
                     options)
 {
-    struct v_dnode *dev, *mnt;
+    struct v_dnode *dev = NULL, *mnt = NULL;
     int errno = 0;
 
-    if ((errno = vfs_walk(__current->cwd, source, &dev, NULL, 0))) {
-        goto done;
-    }
+    // It is fine if source is not exist, as some mounting don't require it
+    vfs_walk(__current->cwd, source, &dev, NULL, 0);
 
     if ((errno = vfs_walk(__current->cwd, target, &mnt, NULL, 0))) {
         goto done;
@@ -252,11 +251,14 @@ __DEFINE_LXSYSCALL4(int,
 
     // By our convention.
     // XXX could we do better?
-    struct device* device = (struct device*)dev->inode->data;
+    struct device* device = NULL;
 
-    if (!(dev->inode->itype & VFS_IFVOLDEV) || !device) {
-        errno = ENOTDEV;
-        goto done;
+    if (dev) {
+        if (!(dev->inode->itype & VFS_IFVOLDEV)) {
+            errno = ENOTDEV;
+            goto done;
+        }
+        device = (struct device*)dev->inode->data;
     }
 
     errno = vfs_mount_at(fstype, device, mnt, options);
index d376c798b778660328f07951257c6acfd9c537cd..e1b11578145ed1f47d1ddd12cdf7246cf8207247 100644 (file)
@@ -173,6 +173,11 @@ vfs_walk(struct v_dnode* start,
          struct hstr* component,
          int options)
 {
+    if (!path) {
+        *dentry = NULL;
+        return 0;
+    }
+
     // allocate a file name stack for path walking and recursion to resolve
     // symlink
     char* name_buffer = valloc(2048);
index 8283fd1f56d899a222ff0d779891ca2b22457361..8f6a710c6ed82000dea0f70d7e4b1158eabe4369 100644 (file)
@@ -140,8 +140,7 @@ pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
 
         if (new_page) {
             // Filling up the page
-            errno =
-              inode->default_fops->read_page(inode, pg->pg, PG_SIZE, pg->fpos);
+            errno = inode->default_fops->read_page(inode, pg->pg, pg->fpos);
 
             if (errno < 0) {
                 break;
@@ -178,8 +177,7 @@ pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
         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);
+            errno = inode->default_fops->read_page(inode, pg->pg, pg->fpos);
 
             if (errno < 0) {
                 break;
@@ -191,7 +189,7 @@ pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos)
 
             pg->len = errno;
         } else if (!pg) {
-            errno = inode->default_fops->read_page(
+            errno = inode->default_fops->read(
               inode, (data + buf_off), len - buf_off, pg->fpos);
             buf_off = len;
             break;
@@ -231,8 +229,7 @@ pcache_commit(struct v_inode* inode, struct pcache_pg* page)
         return 0;
     }
 
-    int errno =
-      inode->default_fops->write_page(inode, page->pg, PG_SIZE, page->fpos);
+    int errno = inode->default_fops->write_page(inode, page->pg, page->fpos);
 
     if (!errno) {
         page->flags &= ~PCACHE_DIRTY;
index e7ac05c7b93c991a5bceb39cb145aa040aa81255..1a6826eda70f07118caf176084bdfae1ecb33169 100644 (file)
@@ -216,7 +216,8 @@ const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir,
 const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir,
                                            .close = default_file_close,
                                            .read = default_file_read,
-                                           .read_page = default_file_read,
+                                           .read_page = default_file_read_page,
                                            .write = default_file_write,
-                                           .write_page = default_file_write,
+                                           .write_page =
+                                             default_file_write_page,
                                            .seek = default_file_seek };
\ No newline at end of file
index 704a103f270b750f130430b4035d27960b8ff3d1..9d6d9f7189be246fd0ad1c8cb70b580d2aec671f 100644 (file)
@@ -18,6 +18,8 @@
 #include <lunaix/mm/valloc.h>
 #include <lunaix/spike.h>
 
+#include <sys/mm/mempart.h>
+
 static struct twifs_node* fs_root;
 
 static struct cake_pile* twi_pile;
@@ -87,6 +89,12 @@ __twifs_fwrite(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     return twi_node->ops.write(inode, buffer, len, fpos);
 }
 
+int
+__twifs_fwrite_pg(struct v_inode* inode, void* buffer, size_t fpos)
+{
+    return __twifs_fwrite(inode, buffer, MEM_PAGE, fpos);
+}
+
 int
 __twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
 {
@@ -97,6 +105,12 @@ __twifs_fread(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
     return twi_node->ops.read(inode, buffer, len, fpos);
 }
 
+int
+__twifs_fread_pg(struct v_inode* inode, void* buffer, size_t fpos)
+{
+    return __twifs_fread(inode, buffer, MEM_PAGE, fpos);
+}
+
 struct twifs_node*
 __twifs_get_node(struct twifs_node* parent, struct hstr* name)
 {
@@ -275,9 +289,9 @@ twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...)
 
 const struct v_file_ops twifs_file_ops = { .close = default_file_close,
                                            .read = __twifs_fread,
-                                           .read_page = __twifs_fread,
+                                           .read_page = __twifs_fread_pg,
                                            .write = __twifs_fwrite,
-                                           .write_page = __twifs_fwrite,
+                                           .write_page = __twifs_fwrite_pg,
                                            .readdir = __twifs_iterate_dir };
 
 const struct v_inode_ops twifs_inode_ops = { .dir_lookup = __twifs_dirlookup,
index 1021db077e924f047cc0a203f2f48eac3bd53cb5..6b74ad33686661f0bf805cbbd03d3766e016ebc9 100644 (file)
@@ -6,7 +6,9 @@
 #include <klibc/strfmt.h>
 #include <klibc/string.h>
 
-#define TWIMAP_BUFFER_SIZE 4096
+#include <sys/mm/mempart.h>
+
+#define TWIMAP_BUFFER_SIZE MEM_PAGE
 
 void
 __twimap_default_reset(struct twimap* map)
@@ -20,13 +22,19 @@ __twimap_default_gonext(struct twimap* map)
     return 0;
 }
 
-int
+static int
 __twimap_file_read(struct v_inode* inode, void* buf, size_t len, size_t fpos)
 {
     struct twimap* map = (struct twimap*)(inode->data);
     return twimap_read(map, buf, len, fpos);
 }
 
+static int
+__twimap_file_read_page(struct v_inode* inode, void* buf, size_t fpos)
+{
+    return __twimap_file_read(inode, buf, MEM_PAGE, fpos);
+}
+
 int
 twimap_read(struct twimap* map, void* buffer, size_t len, size_t fpos)
 {
@@ -79,8 +87,7 @@ twimap_printf(struct twimap* mapping, const char* fmt, ...)
 
     char* buf = mapping->buffer + mapping->size_acc;
 
-    mapping->size_acc +=
-      ksnprintfv(buf, fmt, TWIMAP_BUFFER_SIZE, args) - 1;
+    mapping->size_acc += ksnprintfv(buf, fmt, TWIMAP_BUFFER_SIZE, args) - 1;
 
     va_end(args);
 }
@@ -117,7 +124,7 @@ twimap_create(void* data)
 
 struct v_file_ops twimap_file_ops = { .close = default_file_close,
                                       .read = __twimap_file_read,
-                                      .read_page = __twimap_file_read,
+                                      .read_page = __twimap_file_read_page,
                                       .readdir = default_file_readdir,
                                       .seek = default_file_seek,
                                       .write = default_file_write };
\ No newline at end of file
index 0510c0c53de0d7be781c04374eb4b0baa3ba3159..501c8f45a14063c34454d2d223785b18e48d7982 100644 (file)
@@ -59,12 +59,14 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
     lxconsole_init();
 
-    /* Get platform configuration */
-    acpi_init();
+    device_sysconf_load();
 
     /* Get intc online, this is the cornerstone when initing devices */
     intc_init();
 
+    clock_init();
+    timer_init();
+
     /*
         TODO autoload these init function that do not have dependency between
        them
@@ -77,18 +79,7 @@ kernel_bootstrap(struct boot_handoff* bhctx)
     block_init();
     sched_init();
 
-    device_earlystage();
-
-    /* System timing and clock support */
-    /*
-        FIXME we must get timer as earlier as possible
-
-        A decoupling between rtc and general device sub-sys is needed.
-        Otherwise we timer can only be loaded after device_earlystage.
-
-        We need a dedicated timer&clock subsystem
-    */
-    timer_init();
+    device_onbooot_load();
 
     /* the bare metal are now happy, let's get software over with */
 
@@ -97,11 +88,6 @@ kernel_bootstrap(struct boot_handoff* bhctx)
         panickf("Fail to mount root. (errno=%d)", errno);
     }
 
-    /* Mount these system-wide pseudo-fs */
-    vfs_mount("/dev", "devfs", NULL, 0);
-    vfs_mount("/sys", "twifs", NULL, MNT_RO);
-    vfs_mount("/task", "taskfs", NULL, MNT_RO);
-
     /* Finish up bootstrapping sequence, we are ready to spawn the root process
      * and start geting into uspace
      */
index d323bc1640dd909ec85a1b0b2d6928362e389727..61eb2135282a6fcbc77603f25fb8c752ece98243 100644 (file)
@@ -7,7 +7,7 @@
 #include "kp_records.h"
 
 struct kp_records*
-kp_rec_create(int max_recs)
+kprec_create(int max_recs)
 {
     struct kp_records* recs = (struct kp_records*)valloc(KP_RECS_SIZE);
 
@@ -21,18 +21,18 @@ kp_rec_create(int max_recs)
 }
 
 static inline int
-kp_recs_full(struct kp_records* recs)
+kprecs_full(struct kp_records* recs)
 {
     return recs->cur_recs >= recs->max_recs;
 }
 
-void
-kp_rec_put(struct kp_records* recs, int lvl, char* content, size_t len)
+struct kp_entry*
+kprec_put(struct kp_records* recs, int lvl, char* content, size_t len)
 {
     assert(len < 256);
 
     struct kp_entry* ent;
-    if (!kp_recs_full(recs)) {
+    if (!kprecs_full(recs)) {
         assert(recs->kp_ent_wp == &recs->kp_ents.ents);
 
         ent = (struct kp_entry*)vzalloc(KP_ENT_SIZE);
@@ -51,4 +51,6 @@ kp_rec_put(struct kp_records* recs, int lvl, char* content, size_t len)
     ent->lvl = lvl;
     ent->content = _content;
     ent->time = clock_systime();
+
+    return ent;
 }
\ No newline at end of file
index bf300f904db3518491e94fb898699a444e17eed0..1a157fe2e99d8ea3351551fcee6513eeeae3af22 100644 (file)
@@ -26,9 +26,9 @@ struct kp_records
 #define KP_RECS_SIZE sizeof(struct kp_records)
 
 struct kp_records*
-kp_rec_create(int max_recs);
+kprec_create(int max_recs);
 
-void
-kp_rec_put(struct kp_records*, int lvl, char* content, size_t len);
+struct kp_entry*
+kprec_put(struct kp_records*, int lvl, char* content, size_t len);
 
 #endif /* __LUNAIX_KP_RECORDS_H */
index c3bd04ccb0ee36890166f5353b773ceb1092300d..12c421fd6d252ff48eda3c1345adb96d64e5cab0 100644 (file)
@@ -3,6 +3,8 @@
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 
+#include <lunaix/lxconsole.h>
+
 #include <klibc/strfmt.h>
 
 #include "kp_records.h"
@@ -33,23 +35,27 @@ shift_level(const char* str, int* level)
     return str;
 }
 
-static void
-__kprintf_level(const char* component, int level, const char* fmt, va_list args)
+static inline void
+kprintf_ml(const char* component, int level, const char* fmt, va_list args)
 {
     char* buf = &tmp_buf[MAX_BUFSZ_HLF];
     ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s", component, fmt);
 
     size_t sz = ksnprintfv(tmp_buf, buf, MAX_BUFSZ_HLF, args);
-    kp_rec_put(&kprecs, level, tmp_buf, sz);
+    kprec_put(&kprecs, level, tmp_buf, sz);
+
+    // FIXME temp measure, get some output
+    console_write_str(tmp_buf);
+    console_write_char('\n');
 }
 
 void
-__kprintf(const char* component, const char* fmt, va_list args)
+kprintf_m(const char* component, const char* fmt, va_list args)
 {
     int level;
     fmt = shift_level(fmt, &level);
 
-    __kprintf_level(component, level, fmt, args);
+    kprintf_ml(component, level, fmt, args);
 }
 
 static void
@@ -64,7 +70,9 @@ __twimap_kprintf_read(struct twimap* map)
     struct kp_entry *pos, *n;
     llist_for_each(pos, n, kprecs->kp_ent_wp, ents)
     {
-        twimap_printf(map, "[%05d] %s\n", pos->time, pos->content);
+        time_t s = pos->time / 1000;
+        time_t ms = pos->time % 1000;
+        twimap_printf(map, "[%05d.%03d] %s\n", s, ms, pos->content);
     }
 }
 
@@ -77,5 +85,5 @@ EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
 
 __DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
 {
-    __kprintf_level("syslog", level, fmt, args);
+    kprintf_ml("syslog", level, fmt, args);
 }
\ No newline at end of file
index d183c63837c4caa99f8a2d631d9ef4482d64a9a0..3ca77f272ff5d174c1670aee59f9bea9fff1bac0 100644 (file)
@@ -174,8 +174,7 @@ mem_sync_pages(ptr_t mnt,
             size_t offset = mapping.va - region->start + region->foff;
             struct v_inode* inode = region->mfile->inode;
 
-            region->mfile->ops->write_page(
-              inode, (void*)mapping.va, PG_SIZE, offset);
+            region->mfile->ops->write_page(inode, (void*)mapping.va, offset);
 
             *mapping.pte &= ~PG_DIRTY;
 
index ca1b4cadf39f03b8d90b28f4c3318dca587956bb..31a100df9c33333749a12e9378e5b79b48573ea4 100644 (file)
@@ -32,12 +32,12 @@ mount_bootmedium()
     int errno = 0;
     struct device* dev = probe_boot_medium();
     if (!dev) {
-        kprintf(KERROR "fail to acquire device. (%d)", errno);
+        ERROR("fail to acquire device. (%d)", errno);
         return 0;
     }
 
     if ((errno = vfs_mount("/mnt/lunaix-os", "iso9660", dev, 0))) {
-        kprintf(KERROR "fail to mount boot medium. (%d)", errno);
+        ERROR("fail to mount boot medium. (%d)", errno);
         return 0;
     }
 
@@ -56,7 +56,7 @@ exec_initd()
     fail("should not reach");
 
 fail:
-    kprintf(KERROR "fail to load initd. (%d)", errno);
+    ERROR("fail to load initd. (%d)", errno);
     return 0;
 }
 
@@ -92,7 +92,7 @@ __proc0()
 void
 init_platform()
 {
-    device_poststage();
+    device_postboot_load();
 
     twifs_register_plugins();
 
index 70afe1349fd5cf808e5e650260ac690c91415e86..bc2992132e9382e63eca1bae20115320cad310af 100644 (file)
@@ -134,9 +134,11 @@ taskfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 
 static struct v_file_ops taskfs_file_ops = { .close = default_file_close,
                                              .read = default_file_read,
-                                             .read_page = default_file_read,
+                                             .read_page =
+                                               default_file_read_page,
                                              .write = default_file_write,
-                                             .write_page = default_file_write,
+                                             .write_page =
+                                               default_file_write_page,
                                              .readdir = taskfs_readdir,
                                              .seek = default_file_seek };
 static struct v_inode_ops taskfs_inode_ops = { .dir_lookup = taskfs_dirlookup,
index 3770dd00ce3088aa4dfff566768aa2615ff69a04..2bf61d4f48700fed442252b8a694c51c15598405 100644 (file)
@@ -1,6 +1,5 @@
-#include <hal/hwrtc.h>
-#include <hal/hwtimer.h>
 #include <lunaix/clock.h>
+#include <lunaix/device.h>
 #include <lunaix/fs/twifs.h>
 #include <lunaix/spike.h>
 
@@ -62,16 +61,32 @@ clock_unixtime()
 time_t
 clock_systime()
 {
-    if (!current_timer) {
+    if (!systimer) {
         return 0;
     }
 
     ticks_t t = hwtimer_current_systicks();
-    return t / current_timer->running_freq;
+    ticks_t tu = systimer->running_freq / 1000;
+    return t / (tu + 1);
 }
 
 void
 clock_walltime(datetime_t* datetime)
 {
-    primary_rtc->get_walltime(primary_rtc, datetime);
+    sysrtc->get_walltime(sysrtc, datetime);
+}
+
+void
+clock_init()
+{
+    int idx = 0;
+    struct device_def* pos;
+    foreach_exported_device_of(load_timedev, idx, pos)
+    {
+        if (pos->class.device != DEV_RTC) {
+            continue;
+        }
+
+        pos->init(pos);
+    }
 }
\ No newline at end of file
index 5c18cbcf62cbbf12c29c4e976c919a8dfa24022f..fa20202807432f03c6a821dfd4960f9bb16b8ee0 100644 (file)
@@ -363,4 +363,4 @@ static struct device_def lxconsole_def = {
     .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
+EXPORT_DEVICE(lxconsole, &lxconsole_def, load_onboot);
\ No newline at end of file
index 1cc64bb2901a6d3f42b6a594fc33317eebd710dd..236edcdc050722330d96eab45ec2eb4f84a94ae8 100644 (file)
@@ -80,21 +80,31 @@ SECTIONS {
 
         . = ALIGN(8);
 
-        PROVIDE(__lga_dev_ld_early_start = .);
+        PROVIDE(__lga_dev_ld_kboot_start = .);
         
-        KEEP(*(.lga.devdefs.ld_early));
+        KEEP(*(.lga.devdefs.ld_kboot));
 
-        PROVIDE(__lga_dev_ld_early_end = .);
+        PROVIDE(__lga_dev_ld_kboot_end = .);
 
         /* ---- */
 
         . = ALIGN(8);
 
-        PROVIDE(__lga_dev_ld_aftertimer_start = .);
+        PROVIDE(__lga_dev_ld_sysconf_start = .);
         
-        KEEP(*(.lga.devdefs.ld_aftertimer));
+        KEEP(*(.lga.devdefs.ld_sysconf));
 
-        PROVIDE(__lga_dev_ld_aftertimer_end = .);
+        PROVIDE(__lga_dev_ld_sysconf_end = .);
+
+        /* ---- */
+
+        . = ALIGN(8);
+
+        PROVIDE(__lga_dev_ld_timedev_start = .);
+        
+        KEEP(*(.lga.devdefs.ld_timedev));
+
+        PROVIDE(__lga_dev_ld_timedev_end = .);
 
         /* ---- */
 
index eccf605875caa3f88080fed4a840b02a31eeba10..b7c9aec4318f943c7436e9eee336c5617005ea95 100644 (file)
@@ -8,7 +8,6 @@ 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 \
index 7f7ca5e95fcc39d9b8239cde1c76f64b59d31543..1b80f495d05770b7dca832831a5b625f6f8733d5 100644 (file)
@@ -1,27 +1,45 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <lunaix/lunaix.h>
+#include <lunaix/mount.h>
 #include <stdio.h>
 #include <unistd.h>
 
+#define must_mount(src, target, fs, opts)                                      \
+    do {                                                                       \
+        int err = 0;                                                           \
+        if ((err = mount(src, target, fs, opts))) {                            \
+            syslog(2, "mount fs %s to %s failed (%d)\n", fs, target, errno);   \
+            return err;                                                        \
+        }                                                                      \
+    } while (0)
+
 int
 main(int argc, const char** argv)
 {
     int err = 0;
 
+    mkdir("/dev");
+    mkdir("/sys");
+    mkdir("/task");
+
+    must_mount(NULL, "/dev", "devfs", 0);
+    must_mount(NULL, "/sys", "twifs", MNT_RO);
+    must_mount(NULL, "/task", "taskfs", MNT_RO);
+
     if ((err = open("/dev/tty", 0)) < 0) {
         syslog(2, "fail to open tty (%d)\n", errno);
-        return 0;
+        return err;
     }
 
     if ((err = dup(err)) < 0) {
         syslog(2, "fail to setup tty i/o (%d)\n", errno);
-        return 0;
+        return err;
     }
 
     if ((err = symlink("/usr", "/mnt/lunaix-os/usr"))) {
         syslog(2, "symlink /usr:/mnt/lunaix-os/usr (%d)\n", errno);
-        return 0;
+        return err;
     }
 
     pid_t pid;
@@ -37,5 +55,5 @@ main(int argc, const char** argv)
         printf("shell exit abnormally (%d)", err);
     }
 
-    return 0;
+    return err;
 }
\ No newline at end of file