From 2236410f4582ab45ae8c384dd6eeeef5d10aab15 Mon Sep 17 00:00:00 2001 From: Minep Date: Sat, 4 Nov 2023 19:27:18 +0000 Subject: [PATCH] refactor: make pci device driver loading passive, pci bus scanner will not load them automatically, 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 --- lunaix-os/arch/i386/exceptions/interrupts.c | 2 +- .../arch/i386/exceptions/intr_routines.c | 2 +- lunaix-os/arch/i386/mm/pfault.c | 38 +++--- lunaix-os/hal/acpi/acpi.c | 90 +++++++------- lunaix-os/hal/ahci/ahci.c | 43 ++----- lunaix-os/hal/ahci/ahci_pci.c | 51 ++++++++ lunaix-os/hal/ahci/io_event.c | 2 +- lunaix-os/hal/char/devnull.c | 2 +- lunaix-os/hal/char/devzero.c | 2 +- lunaix-os/hal/char/ps2kbd.c | 14 +-- lunaix-os/hal/char/uart/16550_pmio.c | 2 +- lunaix-os/hal/gfxa/vga/vga_pci.c | 13 +- lunaix-os/hal/pci.c | 117 +++++++++++------- lunaix-os/hal/rng/rngx86.c | 2 +- lunaix-os/hal/rtc/mc146818a.c | 6 +- lunaix-os/hal/rtc/{hwrtc.c => rtc_device.c} | 38 +++--- lunaix-os/hal/timer/apic_timer.c | 14 +-- .../hal/timer/{hwtimer.c => timer_device.c} | 22 ++-- lunaix-os/includes/hal/acpi/acpi.h | 3 - lunaix-os/includes/hal/ahci/ahci.h | 14 +++ lunaix-os/includes/hal/hwrtc.h | 11 +- lunaix-os/includes/hal/hwtimer.h | 2 - lunaix-os/includes/hal/pci.h | 20 ++- lunaix-os/includes/lunaix/blkio.h | 1 + lunaix-os/includes/lunaix/clock.h | 10 ++ lunaix-os/includes/lunaix/compiler.h | 9 ++ lunaix-os/includes/lunaix/device.h | 67 +++++++--- lunaix-os/includes/lunaix/device_num.h | 10 ++ lunaix-os/includes/lunaix/fs.h | 10 +- lunaix-os/includes/lunaix/fs/iso9660.h | 20 +-- lunaix-os/includes/lunaix/spike.h | 9 -- lunaix-os/includes/lunaix/syslog.h | 36 ++++-- lunaix-os/includes/lunaix/trace.h | 1 + lunaix-os/kernel/block/blkpart_gpt.c | 2 +- lunaix-os/kernel/block/block.c | 85 +++++-------- lunaix-os/kernel/debug/sdbg.c | 12 +- lunaix-os/kernel/debug/trace.c | 31 +++-- lunaix-os/kernel/device/devdb.c | 17 +-- lunaix-os/kernel/device/devfs.c | 4 +- lunaix-os/kernel/fs/defaults.c | 12 ++ lunaix-os/kernel/fs/iso9660/file.c | 14 +++ lunaix-os/kernel/fs/iso9660/inode.c | 4 +- lunaix-os/kernel/fs/mount.c | 28 +++-- lunaix-os/kernel/fs/path_walk.c | 5 + lunaix-os/kernel/fs/pcache.c | 11 +- lunaix-os/kernel/fs/ramfs/ramfs.c | 5 +- lunaix-os/kernel/fs/twifs/twifs.c | 18 ++- lunaix-os/kernel/fs/twimap.c | 17 ++- lunaix-os/kernel/kinit.c | 24 +--- lunaix-os/kernel/kprint/kp_records.c | 12 +- lunaix-os/kernel/kprint/kp_records.h | 6 +- lunaix-os/kernel/kprint/kprintf.c | 22 ++-- lunaix-os/kernel/mm/mmap.c | 3 +- lunaix-os/kernel/proc0.c | 8 +- lunaix-os/kernel/process/taskfs.c | 6 +- lunaix-os/kernel/time/clock.c | 25 +++- lunaix-os/kernel/tty/lxconsole.c | 2 +- lunaix-os/link/linker.ld | 22 +++- lunaix-os/makeinc/qemu.mkinc | 1 - lunaix-os/usr/init/init.c | 26 +++- 60 files changed, 676 insertions(+), 429 deletions(-) create mode 100644 lunaix-os/hal/ahci/ahci_pci.c rename lunaix-os/hal/rtc/{hwrtc.c => rtc_device.c} (84%) rename lunaix-os/hal/timer/{hwtimer.c => timer_device.c} (71%) diff --git a/lunaix-os/arch/i386/exceptions/interrupts.c b/lunaix-os/arch/i386/exceptions/interrupts.c index 84a29c1..a323008 100644 --- a/lunaix-os/arch/i386/exceptions/interrupts.c +++ b/lunaix-os/arch/i386/exceptions/interrupts.c @@ -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, diff --git a/lunaix-os/arch/i386/exceptions/intr_routines.c b/lunaix-os/arch/i386/exceptions/intr_routines.c index 33b33c8..77a1372 100644 --- a/lunaix-os/arch/i386/exceptions/intr_routines.c +++ b/lunaix-os/arch/i386/exceptions/intr_routines.c @@ -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); } diff --git a/lunaix-os/arch/i386/mm/pfault.c b/lunaix-os/arch/i386/mm/pfault.c index 2533d0b..165062c 100644 --- a/lunaix-os/arch/i386/mm/pfault.c +++ b/lunaix-os/arch/i386/mm/pfault.c @@ -12,6 +12,8 @@ #include +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); diff --git a/lunaix-os/hal/acpi/acpi.c b/lunaix-os/hal/acpi/acpi.c index 67915fa..5732ec8 100644 --- a/lunaix-os/hal/acpi/acpi.c +++ b/lunaix-os/hal/acpi/acpi.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -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 diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index 33dc87e..3d90845 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -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 index 0000000..0ecde58 --- /dev/null +++ b/lunaix-os/hal/ahci/ahci_pci.c @@ -0,0 +1,51 @@ +#include + +#include +#include +#include + +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(¶m); + 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 diff --git a/lunaix-os/hal/ahci/io_event.c b/lunaix-os/hal/ahci/io_event.c index 2ce49ef..2ad988a 100644 --- a/lunaix-os/hal/ahci/io_event.c +++ b/lunaix-os/hal/ahci/io_event.c @@ -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; diff --git a/lunaix-os/hal/char/devnull.c b/lunaix-os/hal/char/devnull.c index 9806dc0..7dfd0a7 100644 --- a/lunaix-os/hal/char/devnull.c +++ b/lunaix-os/hal/char/devnull.c @@ -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); diff --git a/lunaix-os/hal/char/devzero.c b/lunaix-os/hal/char/devzero.c index f579047..f976c26 100644 --- a/lunaix-os/hal/char/devzero.c +++ b/lunaix-os/hal/char/devzero.c @@ -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); diff --git a/lunaix-os/hal/char/ps2kbd.c b/lunaix-os/hal/char/ps2kbd.c index 5cbbae8..a5cc93d 100644 --- a/lunaix-os/hal/char/ps2kbd.c +++ b/lunaix-os/hal/char/ps2kbd.c @@ -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); diff --git a/lunaix-os/hal/char/uart/16550_pmio.c b/lunaix-os/hal/char/uart/16550_pmio.c index 9910051..81d0642 100644 --- a/lunaix-os/hal/char/uart/16550_pmio.c +++ b/lunaix-os/hal/char/uart/16550_pmio.c @@ -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 diff --git a/lunaix-os/hal/gfxa/vga/vga_pci.c b/lunaix-os/hal/gfxa/vga/vga_pci.c index fe77652..09476db 100644 --- a/lunaix-os/hal/gfxa/vga/vga_pci.c +++ b/lunaix-os/hal/gfxa/vga/vga_pci.c @@ -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 diff --git a/lunaix-os/hal/pci.c b/lunaix-os/hal/pci.c index 3e4a3fe..9a3c581 100644 --- a/lunaix-os/hal/pci.c +++ b/lunaix-os/hal/pci.c @@ -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); diff --git a/lunaix-os/hal/rng/rngx86.c b/lunaix-os/hal/rng/rngx86.c index 3035f31..d732f2c 100644 --- a/lunaix-os/hal/rng/rngx86.c +++ b/lunaix-os/hal/rng/rngx86.c @@ -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 diff --git a/lunaix-os/hal/rtc/mc146818a.c b/lunaix-os/hal/rtc/mc146818a.c index 6b64527..5083444 100644 --- a/lunaix-os/hal/rtc/mc146818a.c +++ b/lunaix-os/hal/rtc/mc146818a.c @@ -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 diff --git a/lunaix-os/hal/rtc/hwrtc.c b/lunaix-os/hal/rtc/rtc_device.c similarity index 84% rename from lunaix-os/hal/rtc/hwrtc.c rename to lunaix-os/hal/rtc/rtc_device.c index 87e7d10..cd94a97 100644 --- a/lunaix-os/hal/rtc/hwrtc.c +++ b/lunaix-os/hal/rtc/rtc_device.c @@ -1,27 +1,19 @@ -#include - #include #include #include #include -#include +#include -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); diff --git a/lunaix-os/hal/timer/apic_timer.c b/lunaix-os/hal/timer/apic_timer.c index db3e700..8ec8747 100644 --- a/lunaix-os/hal/timer/apic_timer.c +++ b/lunaix-os/hal/timer/apic_timer.c @@ -1,7 +1,7 @@ #include -#include #include +#include #include #include #include @@ -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); diff --git a/lunaix-os/hal/timer/hwtimer.c b/lunaix-os/hal/timer/timer_device.c similarity index 71% rename from lunaix-os/hal/timer/hwtimer.c rename to lunaix-os/hal/timer/timer_device.c index 91dca07..c5341be 100644 --- a/lunaix-os/hal/timer/hwtimer.c +++ b/lunaix-os/hal/timer/timer_device.c @@ -1,34 +1,34 @@ -#include #include +#include -#include +#include -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); diff --git a/lunaix-os/includes/hal/acpi/acpi.h b/lunaix-os/includes/hal/acpi/acpi.h index f362b2d..f14ebca 100644 --- a/lunaix-os/includes/hal/acpi/acpi.h +++ b/lunaix-os/includes/hal/acpi/acpi.h @@ -49,9 +49,6 @@ typedef struct struct acpi_mcfg_toc mcfg; } acpi_context; -int -acpi_init(); - acpi_context* acpi_get_context(); diff --git a/lunaix-os/includes/hal/ahci/ahci.h b/lunaix-os/includes/hal/ahci/ahci.h index 13312a5..d4db5c1 100644 --- a/lunaix-os/includes/hal/ahci/ahci.h +++ b/lunaix-os/includes/hal/ahci/ahci.h @@ -2,6 +2,7 @@ #define __LUNAIX_AHCI_H #include "hba.h" +#include /* * 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 */ diff --git a/lunaix-os/includes/hal/hwrtc.h b/lunaix-os/includes/hal/hwrtc.h index a5ebb9c..c0186ff 100644 --- a/lunaix-os/includes/hal/hwrtc.h +++ b/lunaix-os/includes/hal/hwrtc.h @@ -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 */ diff --git a/lunaix-os/includes/hal/hwtimer.h b/lunaix-os/includes/hal/hwtimer.h index 22fdaac..3a55d6d 100644 --- a/lunaix-os/includes/hal/hwtimer.h +++ b/lunaix-os/includes/hal/hwtimer.h @@ -22,8 +22,6 @@ struct hwtimer ticks_t running_freq; }; -extern struct hwtimer* current_timer; - void hwtimer_init(u32_t hertz, void* tick_callback); diff --git a/lunaix-os/includes/hal/pci.h b/lunaix-os/includes/hal/pci.h index e5bbd45..adc270f 100644 --- a/lunaix-os/includes/hal/pci.h +++ b/lunaix-os/includes/hal/pci.h @@ -6,8 +6,8 @@ #include #include -#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 */ diff --git a/lunaix-os/includes/lunaix/blkio.h b/lunaix-os/includes/lunaix/blkio.h index a189a4d..a869c8c 100644 --- a/lunaix-os/includes/lunaix/blkio.h +++ b/lunaix-os/includes/lunaix/blkio.h @@ -13,6 +13,7 @@ #define BLKIO_PENDING 0x8 #define BLKIO_WAIT 0x1 +#define BLKIO_NOASYNC 0x2 // Free on complete #define BLKIO_FOC 0x10 diff --git a/lunaix-os/includes/lunaix/clock.h b/lunaix-os/includes/lunaix/clock.h index 4eea312..58e1ead 100644 --- a/lunaix-os/includes/lunaix/clock.h +++ b/lunaix-os/includes/lunaix/clock.h @@ -2,6 +2,16 @@ #define __LUNAIX_CLOCK_H #include + +#include +#include + +extern const struct hwrtc* sysrtc; +extern const struct hwtimer* systimer; + +void +clock_init(); + void clock_walltime(datetime_t* datetime); diff --git a/lunaix-os/includes/lunaix/compiler.h b/lunaix-os/includes/lunaix/compiler.h index 314afd9..f011a0b 100644 --- a/lunaix-os/includes/lunaix/compiler.h +++ b/lunaix-os/includes/lunaix/compiler.h @@ -11,4 +11,13 @@ #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 */ diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index fac62a9..f650821 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -14,39 +14,58 @@ #include /** - * @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) diff --git a/lunaix-os/includes/lunaix/device_num.h b/lunaix-os/includes/lunaix/device_num.h index af1814a..9011da3 100644 --- a/lunaix-os/includes/lunaix/device_num.h +++ b/lunaix-os/includes/lunaix/device_num.h @@ -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: @@ -49,6 +51,11 @@ 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 @@ -98,6 +107,7 @@ #define DEV_KBD 11 #define DEV_GFXA 12 #define DEV_VGA 13 +#define DEV_ACPI 14 struct devident { diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index d599023..1fe37f1 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -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); diff --git a/lunaix-os/includes/lunaix/fs/iso9660.h b/lunaix-os/includes/lunaix/fs/iso9660.h index 1a6aee2..6fbdbbc 100644 --- a/lunaix-os/includes/lunaix/fs/iso9660.h +++ b/lunaix-os/includes/lunaix/fs/iso9660.h @@ -21,11 +21,11 @@ #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); diff --git a/lunaix-os/includes/lunaix/spike.h b/lunaix-os/includes/lunaix/spike.h index a2a0e21..652fda8 100644 --- a/lunaix-os/includes/lunaix/spike.h +++ b/lunaix-os/includes/lunaix/spike.h @@ -64,15 +64,6 @@ : 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)) { \ diff --git a/lunaix-os/includes/lunaix/syslog.h b/lunaix-os/includes/lunaix/syslog.h index 2423315..b372daa 100644 --- a/lunaix-os/includes/lunaix/syslog.h +++ b/lunaix-os/includes/lunaix/syslog.h @@ -10,11 +10,6 @@ #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') @@ -29,11 +24,38 @@ { \ 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 */ diff --git a/lunaix-os/includes/lunaix/trace.h b/lunaix-os/includes/lunaix/trace.h index 9edf961..44a2da7 100644 --- a/lunaix-os/includes/lunaix/trace.h +++ b/lunaix-os/includes/lunaix/trace.h @@ -13,6 +13,7 @@ struct ksym_entry struct trace_record { ptr_t pc; + ptr_t sym_pc; char* symbol; }; diff --git a/lunaix-os/kernel/block/blkpart_gpt.c b/lunaix-os/kernel/block/blkpart_gpt.c index 9d49bfc..033fa0a 100644 --- a/lunaix-os/kernel/block/blkpart_gpt.c +++ b/lunaix-os/kernel/block/blkpart_gpt.c @@ -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; } diff --git a/lunaix-os/kernel/block/block.c b/lunaix-os/kernel/block/block.c index 3f3c1e8..a2242ad 100644 --- a/lunaix-os/kernel/block/block.c +++ b/lunaix-os/kernel/block/block.c @@ -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; } diff --git a/lunaix-os/kernel/debug/sdbg.c b/lunaix-os/kernel/debug/sdbg.c index 6a7d811..edfecea 100644 --- a/lunaix-os/kernel/debug/sdbg.c +++ b/lunaix-os/kernel/debug/sdbg.c @@ -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; } diff --git a/lunaix-os/kernel/debug/trace.c b/lunaix-os/kernel/debug/trace.c index 62ceb0e..1235884 100644 --- a/lunaix-os/kernel/debug/trace.c +++ b/lunaix-os/kernel/debug/trace.c @@ -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 "..."); + DEBUG("..."); } 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); diff --git a/lunaix-os/kernel/device/devdb.c b/lunaix-os/kernel/device/devdb.c index 4123862..236ac5a 100644 --- a/lunaix-os/kernel/device/devdb.c +++ b/lunaix-os/kernel/device/devdb.c @@ -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 diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index 1a49b05..f586add 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -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); diff --git a/lunaix-os/kernel/fs/defaults.c b/lunaix-os/kernel/fs/defaults.c index 878ec02..8512d8e 100644 --- a/lunaix-os/kernel/fs/defaults.c +++ b/lunaix-os/kernel/fs/defaults.c @@ -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) { diff --git a/lunaix-os/kernel/fs/iso9660/file.c b/lunaix-os/kernel/fs/iso9660/file.c index f07f560..a48da33 100644 --- a/lunaix-os/kernel/fs/iso9660/file.c +++ b/lunaix-os/kernel/fs/iso9660/file.c @@ -4,6 +4,7 @@ #include #include +#include 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) { diff --git a/lunaix-os/kernel/fs/iso9660/inode.c b/lunaix-os/kernel/fs/iso9660/inode.c index ac151b3..58d1b8f 100644 --- a/lunaix-os/kernel/fs/iso9660/inode.c +++ b/lunaix-os/kernel/fs/iso9660/inode.c @@ -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 }; diff --git a/lunaix-os/kernel/fs/mount.c b/lunaix-os/kernel/fs/mount.c index 97ef359..084a400 100644 --- a/lunaix-os/kernel/fs/mount.c +++ b/lunaix-os/kernel/fs/mount.c @@ -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); diff --git a/lunaix-os/kernel/fs/path_walk.c b/lunaix-os/kernel/fs/path_walk.c index d376c79..e1b1157 100644 --- a/lunaix-os/kernel/fs/path_walk.c +++ b/lunaix-os/kernel/fs/path_walk.c @@ -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); diff --git a/lunaix-os/kernel/fs/pcache.c b/lunaix-os/kernel/fs/pcache.c index 8283fd1..8f6a710 100644 --- a/lunaix-os/kernel/fs/pcache.c +++ b/lunaix-os/kernel/fs/pcache.c @@ -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; diff --git a/lunaix-os/kernel/fs/ramfs/ramfs.c b/lunaix-os/kernel/fs/ramfs/ramfs.c index e7ac05c..1a6826e 100644 --- a/lunaix-os/kernel/fs/ramfs/ramfs.c +++ b/lunaix-os/kernel/fs/ramfs/ramfs.c @@ -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 diff --git a/lunaix-os/kernel/fs/twifs/twifs.c b/lunaix-os/kernel/fs/twifs/twifs.c index 704a103..9d6d9f7 100644 --- a/lunaix-os/kernel/fs/twifs/twifs.c +++ b/lunaix-os/kernel/fs/twifs/twifs.c @@ -18,6 +18,8 @@ #include #include +#include + 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, diff --git a/lunaix-os/kernel/fs/twimap.c b/lunaix-os/kernel/fs/twimap.c index 1021db0..6b74ad3 100644 --- a/lunaix-os/kernel/fs/twimap.c +++ b/lunaix-os/kernel/fs/twimap.c @@ -6,7 +6,9 @@ #include #include -#define TWIMAP_BUFFER_SIZE 4096 +#include + +#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 diff --git a/lunaix-os/kernel/kinit.c b/lunaix-os/kernel/kinit.c index 0510c0c..501c8f4 100644 --- a/lunaix-os/kernel/kinit.c +++ b/lunaix-os/kernel/kinit.c @@ -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 */ diff --git a/lunaix-os/kernel/kprint/kp_records.c b/lunaix-os/kernel/kprint/kp_records.c index d323bc1..61eb213 100644 --- a/lunaix-os/kernel/kprint/kp_records.c +++ b/lunaix-os/kernel/kprint/kp_records.c @@ -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 diff --git a/lunaix-os/kernel/kprint/kp_records.h b/lunaix-os/kernel/kprint/kp_records.h index bf300f9..1a157fe 100644 --- a/lunaix-os/kernel/kprint/kp_records.h +++ b/lunaix-os/kernel/kprint/kp_records.h @@ -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 */ diff --git a/lunaix-os/kernel/kprint/kprintf.c b/lunaix-os/kernel/kprint/kprintf.c index c3bd04c..12c421f 100644 --- a/lunaix-os/kernel/kprint/kprintf.c +++ b/lunaix-os/kernel/kprint/kprintf.c @@ -3,6 +3,8 @@ #include #include +#include + #include #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 diff --git a/lunaix-os/kernel/mm/mmap.c b/lunaix-os/kernel/mm/mmap.c index d183c63..3ca77f2 100644 --- a/lunaix-os/kernel/mm/mmap.c +++ b/lunaix-os/kernel/mm/mmap.c @@ -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; diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index ca1b4ca..31a100d 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -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(); diff --git a/lunaix-os/kernel/process/taskfs.c b/lunaix-os/kernel/process/taskfs.c index 70afe13..bc29921 100644 --- a/lunaix-os/kernel/process/taskfs.c +++ b/lunaix-os/kernel/process/taskfs.c @@ -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, diff --git a/lunaix-os/kernel/time/clock.c b/lunaix-os/kernel/time/clock.c index 3770dd0..2bf61d4 100644 --- a/lunaix-os/kernel/time/clock.c +++ b/lunaix-os/kernel/time/clock.c @@ -1,6 +1,5 @@ -#include -#include #include +#include #include #include @@ -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 diff --git a/lunaix-os/kernel/tty/lxconsole.c b/lunaix-os/kernel/tty/lxconsole.c index 5c18cbc..fa20202 100644 --- a/lunaix-os/kernel/tty/lxconsole.c +++ b/lunaix-os/kernel/tty/lxconsole.c @@ -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 diff --git a/lunaix-os/link/linker.ld b/lunaix-os/link/linker.ld index 1cc64bb..236edcd 100644 --- a/lunaix-os/link/linker.ld +++ b/lunaix-os/link/linker.ld @@ -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 = .); /* ---- */ diff --git a/lunaix-os/makeinc/qemu.mkinc b/lunaix-os/makeinc/qemu.mkinc index eccf605..b7c9aec 100644 --- a/lunaix-os/makeinc/qemu.mkinc +++ b/lunaix-os/makeinc/qemu.mkinc @@ -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 \ diff --git a/lunaix-os/usr/init/init.c b/lunaix-os/usr/init/init.c index 7f7ca5e..1b80f49 100644 --- a/lunaix-os/usr/init/init.c +++ b/lunaix-os/usr/init/init.c @@ -1,27 +1,45 @@ #include #include #include +#include #include #include +#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 -- 2.27.0