From ebb55b7e5f0b8f31328950ec383b77b208ffbb64 Mon Sep 17 00:00:00 2001 From: Lunaixsky Date: Sun, 21 Jul 2024 20:45:46 +0100 Subject: [PATCH 1/1] PCI 16x50 UART Controller, O2 Enablement (#39) * add PCI 16x50 uart controller, refactor the 16x50 structure * refactor the pci detection mechanism, allow custom compatibility check logic. * fix bug in pci device definition binding where only bind once * refactor the 16x50 controller structure, move pmio and mmio as separated component and does not need to couple with interface * fix issue where x86:isrm_ivexalloc alloc duplicated interrupt vector * change the signature of ioremap to return ptr_t instead of generic pointer * fix issue in LunaConfig header export, where non string type being joined as a string type * add config term for 16x50 controller. * rework the usr/testp, allow user to specify serial interface * usr/ls, add a slash after directory file name to distinguish * add the implementation for iounmap * refactor pci dev to use latest change in pci * remove the out-dated, mask based compatibility check scheme * rectify the issues with -O2 optimization * refactor: allow Lunaix to compile with -O2 optimization * add LConfig terms for PCI related features * add LConfig terms for AHCI related features * refactor the pci device code base with latest pci refactoring * fix: fail to read bool type config term when the value of the term is False * refactor: LConfig: allow omit the `LConfig` when doing include * remove legacy file --- lunaix-os/LConfig | 5 +- lunaix-os/arch/generic/includes/sys/pci_hba.h | 31 ----- lunaix-os/arch/x86/boot/x86_64/kremap64.c | 9 +- lunaix-os/arch/x86/exceptions/intr_routines.c | 7 + lunaix-os/arch/x86/exceptions/isrm.c | 5 + lunaix-os/arch/x86/hal/LBuild | 3 +- lunaix-os/arch/x86/hal/apic.c | 2 +- lunaix-os/arch/x86/hal/ioapic.c | 2 +- .../x86/{includes/sys/pci_hba.h => hal/pci.c} | 20 ++- lunaix-os/arch/x86/includes/sys/abi64.h | 2 +- lunaix-os/hal/LConfig | 9 ++ lunaix-os/hal/ahci/LBuild | 19 +-- lunaix-os/hal/ahci/LConfig | 18 +++ lunaix-os/hal/ahci/ahci.c | 1 - lunaix-os/hal/ahci/ahci_pci.c | 49 ++++--- lunaix-os/hal/bus/LBuild | 6 +- lunaix-os/hal/bus/LConfig | 35 +++++ lunaix-os/hal/bus/pci.c | 56 ++++---- lunaix-os/hal/char/LConfig | 7 + lunaix-os/hal/char/serial.c | 8 +- lunaix-os/hal/char/uart/16550_pmio.c | 105 --------------- lunaix-os/hal/char/uart/{16550.h => 16x50.h} | 36 ++++- .../char/uart/{16550_base.c => 16x50_base.c} | 32 ++--- lunaix-os/hal/char/uart/16x50_isa.c | 64 +++++++++ lunaix-os/hal/char/uart/16x50_mmio.c | 39 ++++++ lunaix-os/hal/char/uart/16x50_pci.c | 125 ++++++++++++++++++ lunaix-os/hal/char/uart/16x50_pmio.c | 54 ++++++++ lunaix-os/hal/char/uart/LBuild | 13 +- lunaix-os/hal/char/uart/LConfig | 25 ++++ lunaix-os/hal/gfxa/vga/vga_pci.c | 19 ++- lunaix-os/includes/hal/pci.h | 97 +++++++++++++- lunaix-os/includes/lunaix/kpreempt.h | 3 +- lunaix-os/includes/lunaix/mm/mmio.h | 2 +- lunaix-os/includes/lunaix/mm/page.h | 7 + lunaix-os/kernel/LConfig | 2 +- lunaix-os/kernel/kinit.c | 2 +- lunaix-os/kernel/mm/mmio.c | 18 +-- lunaix-os/live_debug.sh | 2 +- lunaix-os/makeinc/toolchain.mkinc | 13 +- .../build-tools/integration/config_io.py | 2 +- .../build-tools/integration/render_ishell.py | 2 +- .../scripts/build-tools/lcfg/builtins.py | 6 +- lunaix-os/scripts/qemu.py | 9 +- lunaix-os/scripts/qemus/qemu_x86_dev.json | 8 ++ lunaix-os/usr/LBuild | 2 + lunaix-os/usr/ls.c | 2 +- lunaix-os/usr/testp.c | 36 ++--- 47 files changed, 723 insertions(+), 296 deletions(-) delete mode 100644 lunaix-os/arch/generic/includes/sys/pci_hba.h rename lunaix-os/arch/x86/{includes/sys/pci_hba.h => hal/pci.c} (69%) create mode 100644 lunaix-os/hal/LConfig create mode 100644 lunaix-os/hal/ahci/LConfig create mode 100644 lunaix-os/hal/bus/LConfig create mode 100644 lunaix-os/hal/char/LConfig delete mode 100644 lunaix-os/hal/char/uart/16550_pmio.c rename lunaix-os/hal/char/uart/{16550.h => 16x50.h} (84%) rename lunaix-os/hal/char/uart/{16550_base.c => 16x50_base.c} (84%) create mode 100644 lunaix-os/hal/char/uart/16x50_isa.c create mode 100644 lunaix-os/hal/char/uart/16x50_mmio.c create mode 100644 lunaix-os/hal/char/uart/16x50_pci.c create mode 100644 lunaix-os/hal/char/uart/16x50_pmio.c create mode 100644 lunaix-os/hal/char/uart/LConfig diff --git a/lunaix-os/LConfig b/lunaix-os/LConfig index ecd4a03..fef1221 100644 --- a/lunaix-os/LConfig +++ b/lunaix-os/LConfig @@ -1,7 +1,8 @@ import time -include("kernel/LConfig") -include("arch/LConfig") +include("kernel") +include("arch") +include("hal") @Term("Version") @ReadOnly diff --git a/lunaix-os/arch/generic/includes/sys/pci_hba.h b/lunaix-os/arch/generic/includes/sys/pci_hba.h deleted file mode 100644 index f3747bf..0000000 --- a/lunaix-os/arch/generic/includes/sys/pci_hba.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __LUNAIX_ARCH_PCI_HBA_H -#define __LUNAIX_ARCH_PCI_HBA_H - -#include -#include - -#define PCI_MSI_BASE 0 - -static inline pci_reg_t -pci_read_cspace(ptr_t base, int offset) -{ - return 0; -} - -static inline void -pci_write_cspace(ptr_t base, int offset, pci_reg_t data) -{ - return; -} - -static inline u16_t -pci_config_msi_data(int vector) { - return vector; -} - -static inline ptr_t -pci_get_msi_base() { - return 0; -} - -#endif /* __LUNAIX_ARCH_PCI_HBA_H */ diff --git a/lunaix-os/arch/x86/boot/x86_64/kremap64.c b/lunaix-os/arch/x86/boot/x86_64/kremap64.c index ee9d298..bf3bb33 100644 --- a/lunaix-os/arch/x86/boot/x86_64/kremap64.c +++ b/lunaix-os/arch/x86/boot/x86_64/kremap64.c @@ -178,9 +178,12 @@ ptr_t boot_text remap_kernel() { ptr_t kmap_pa = to_kphysical(&kpt); - for (size_t i = 0; i < sizeof(kpt); i++) { - ((u8_t*)kmap_pa)[i] = 0; - } + + asm volatile("movq %1, %%rdi\n" + "rep stosb\n" ::"c"(sizeof(kpt)), + "r"(kmap_pa), + "a"(0) + : "rdi", "memory"); do_remap(); diff --git a/lunaix-os/arch/x86/exceptions/intr_routines.c b/lunaix-os/arch/x86/exceptions/intr_routines.c index 05f547e..d355927 100644 --- a/lunaix-os/arch/x86/exceptions/intr_routines.c +++ b/lunaix-os/arch/x86/exceptions/intr_routines.c @@ -39,6 +39,12 @@ intr_routine_general_protection(const struct hart_state* state) __print_panic_msg("general protection", state); } +void +intr_routine_invl_opcode(const struct hart_state* state) +{ + __print_panic_msg("invalid opcode", state); +} + void intr_routine_sys_panic(const struct hart_state* state) { @@ -89,6 +95,7 @@ intr_routine_init() isrm_bindiv(FAULT_GENERAL_PROTECTION, intr_routine_general_protection); isrm_bindiv(FAULT_PAGE_FAULT, intr_routine_page_fault); isrm_bindiv(FAULT_STACK_SEG_FAULT, intr_routine_page_fault); + isrm_bindiv(FAULT_INVALID_OPCODE, intr_routine_invl_opcode); isrm_bindiv(LUNAIX_SYS_PANIC, intr_routine_sys_panic); isrm_bindiv(LUNAIX_SCHED, intr_routine_sched); diff --git a/lunaix-os/arch/x86/exceptions/isrm.c b/lunaix-os/arch/x86/exceptions/isrm.c index 89ff616..dcd576a 100644 --- a/lunaix-os/arch/x86/exceptions/isrm.c +++ b/lunaix-os/arch/x86/exceptions/isrm.c @@ -51,6 +51,11 @@ __ivalloc_within(size_t a, size_t b, isr_cb handler) k++; } + if (j == 8) { + j = 0; + continue; + } + if (k > b) { break; } diff --git a/lunaix-os/arch/x86/hal/LBuild b/lunaix-os/arch/x86/hal/LBuild index 66fff6a..f3a3cae 100644 --- a/lunaix-os/arch/x86/hal/LBuild +++ b/lunaix-os/arch/x86/hal/LBuild @@ -5,5 +5,6 @@ sources([ "ps2kbd.c", "apic_timer.c", "ioapic.c", - "mc146818a.c" + "mc146818a.c", + "pci.c" ]) \ No newline at end of file diff --git a/lunaix-os/arch/x86/hal/apic.c b/lunaix-os/arch/x86/hal/apic.c index 4e2501f..34b243e 100644 --- a/lunaix-os/arch/x86/hal/apic.c +++ b/lunaix-os/arch/x86/hal/apic.c @@ -43,7 +43,7 @@ apic_init() // As we are going to use APIC, disable the old 8259 PIC pic_disable(); - _apic_base = (ptr_t)ioremap(__APIC_BASE_PADDR, 4096); + _apic_base = ioremap(__APIC_BASE_PADDR, 4096); // Hardware enable the APIC // By setting bit 11 of IA32_APIC_BASE register diff --git a/lunaix-os/arch/x86/hal/ioapic.c b/lunaix-os/arch/x86/hal/ioapic.c index 83ce6a0..1e0755a 100644 --- a/lunaix-os/arch/x86/hal/ioapic.c +++ b/lunaix-os/arch/x86/hal/ioapic.c @@ -38,7 +38,7 @@ ioapic_init() acpi_context* acpi_ctx = acpi_get_context(); _ioapic_base = - (ptr_t)ioremap(acpi_ctx->madt.ioapic->ioapic_addr & ~0xfff, 4096); + ioremap(acpi_ctx->madt.ioapic->ioapic_addr & ~0xfff, 4096); } void diff --git a/lunaix-os/arch/x86/includes/sys/pci_hba.h b/lunaix-os/arch/x86/hal/pci.c similarity index 69% rename from lunaix-os/arch/x86/includes/sys/pci_hba.h rename to lunaix-os/arch/x86/hal/pci.c index 74d9c03..f1321b2 100644 --- a/lunaix-os/arch/x86/includes/sys/pci_hba.h +++ b/lunaix-os/arch/x86/hal/pci.c @@ -1,37 +1,33 @@ -#ifndef __LUNAIX_PCI_HBA_H -#define __LUNAIX_PCI_HBA_H - #include -#include - -#include "port_io.h" +#include +#ifdef CONFIG_PCI_PMIO #define PCI_CONFIG_ADDR 0xcf8 #define PCI_CONFIG_DATA 0xcfc -static inline pci_reg_t +pci_reg_t pci_read_cspace(ptr_t base, int offset) { port_wrdword(PCI_CONFIG_ADDR, base | (offset & ~0x3)); return port_rddword(PCI_CONFIG_DATA); } -static inline void +void pci_write_cspace(ptr_t base, int offset, pci_reg_t data) { port_wrdword(PCI_CONFIG_ADDR, base | (offset & ~0x3)); port_wrdword(PCI_CONFIG_DATA, data); } -static inline u16_t +#endif + +u16_t pci_config_msi_data(int vector) { return vector; } -static inline ptr_t +ptr_t pci_get_msi_base() { return 0xFEE00000; } - -#endif /* __LUNAIX_PCI_HBA_H */ diff --git a/lunaix-os/arch/x86/includes/sys/abi64.h b/lunaix-os/arch/x86/includes/sys/abi64.h index 1c93cc1..1dce9b0 100644 --- a/lunaix-os/arch/x86/includes/sys/abi64.h +++ b/lunaix-os/arch/x86/includes/sys/abi64.h @@ -32,7 +32,7 @@ static inline ptr_t must_inline abi_get_callframe() { ptr_t val; - asm("movq %%rbp, %0" : "=r"(val)::); + asm volatile("movq %%rbp, %0" : "=r"(val)::"memory"); return val; } diff --git a/lunaix-os/hal/LConfig b/lunaix-os/hal/LConfig new file mode 100644 index 0000000..35385c9 --- /dev/null +++ b/lunaix-os/hal/LConfig @@ -0,0 +1,9 @@ +include("char") +include("bus") +include("ahci") + +@Collection +def hal(): + """ Lunaix hardware asbtraction layer """ + + pass \ No newline at end of file diff --git a/lunaix-os/hal/ahci/LBuild b/lunaix-os/hal/ahci/LBuild index 8c081c6..7da89ab 100644 --- a/lunaix-os/hal/ahci/LBuild +++ b/lunaix-os/hal/ahci/LBuild @@ -1,9 +1,10 @@ -sources([ - "ahci_pci.c", - "hbadev_export.c", - "ahci.c", - "utils.c", - "io_event.c", - "atapi.c", - "ata.c" -]) \ No newline at end of file +if config("ahci_enable"): + sources([ + "ahci_pci.c", + "hbadev_export.c", + "ahci.c", + "utils.c", + "io_event.c", + "atapi.c", + "ata.c" + ]) \ No newline at end of file diff --git a/lunaix-os/hal/ahci/LConfig b/lunaix-os/hal/ahci/LConfig new file mode 100644 index 0000000..b957881 --- /dev/null +++ b/lunaix-os/hal/ahci/LConfig @@ -0,0 +1,18 @@ + +@Collection +def sata_ahci(): + + add_to_collection(hal) + + @Term + def ahci_enable(): + """ Enable the support of SATA AHCI. + Must require PCI at current stage """ + + type(bool) + default(True) + + if not v(pci_enable): + set_value(False) + + \ No newline at end of file diff --git a/lunaix-os/hal/ahci/ahci.c b/lunaix-os/hal/ahci/ahci.c index bd84bf8..82375e0 100644 --- a/lunaix-os/hal/ahci/ahci.c +++ b/lunaix-os/hal/ahci/ahci.c @@ -14,7 +14,6 @@ #include #include -#include #include #include diff --git a/lunaix-os/hal/ahci/ahci_pci.c b/lunaix-os/hal/ahci/ahci_pci.c index 0ecde58..6c59cf8 100644 --- a/lunaix-os/hal/ahci/ahci_pci.c +++ b/lunaix-os/hal/ahci/ahci_pci.c @@ -2,25 +2,33 @@ #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_device* ahci_dev; + struct pci_base_addr* bar6; + struct ahci_driver* ahci_drv; - struct pci_base_addr* bar6 = &ahci_dev->bar[5]; - assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO."); + ahci_dev = PCI_DEVICE(dev); + bar6 = pci_device_bar(ahci_dev, 5); + assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO."); - pci_reg_t cmd = pci_read_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD); + pci_reg_t cmd = 0; + pci_cmd_set_bus_master(&cmd); + pci_cmd_set_mmio(&cmd); + pci_cmd_set_msi(&cmd); + pci_apply_command(ahci_dev, cmd); - // 禁用传统中断(因为我们使用MSI),启用MMIO访问,允许PCI设备间访问 - cmd |= (PCI_RCMD_MM_ACCESS | PCI_RCMD_DISABLE_INTR | PCI_RCMD_BUS_MASTER); - - pci_write_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD, cmd); - - int iv = isrm_ivexalloc(ahci_hba_isr); - pci_setup_msi(ahci_dev, iv); + int iv; + if (pci_capability_msi(ahci_dev)) { + iv = isrm_ivexalloc(ahci_hba_isr); + pci_setup_msi(ahci_dev, iv); + } + else { + iv = pci_intr_irq(ahci_dev); + iv = isrm_bindirq(iv, ahci_hba_isr); + } struct ahci_driver_param param = { .mmio_base = bar6->start, @@ -28,7 +36,7 @@ ahci_pci_bind(struct device_def* def, struct device* dev) .ahci_iv = iv, }; - struct ahci_driver* ahci_drv = ahci_driver_init(¶m); + ahci_drv = ahci_driver_init(¶m); pci_bind_instance(ahci_dev, ahci_drv); return 0; @@ -40,12 +48,19 @@ ahci_pci_init(struct device_def* def) return pci_bind_definition_all(pcidev_def(def)); } +static bool +ahci_pci_compat(struct pci_device_def* def, + struct pci_device* pcidev) +{ + return pci_device_class(pcidev) == AHCI_HBA_CLASS; +} + + static struct pci_device_def ahcidef = { - .dev_class = AHCI_HBA_CLASS, - .ident_mask = PCI_MATCH_ANY, .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA), - .name = "Generic SATA", + .name = "Generic AHCI", .init = ahci_pci_init, - .bind = ahci_pci_bind } + .bind = ahci_pci_bind }, + .test_compatibility = ahci_pci_compat }; EXPORT_PCI_DEVICE(ahci, &ahcidef, load_postboot); \ No newline at end of file diff --git a/lunaix-os/hal/bus/LBuild b/lunaix-os/hal/bus/LBuild index a485ce7..3b5ff38 100644 --- a/lunaix-os/hal/bus/LBuild +++ b/lunaix-os/hal/bus/LBuild @@ -1,3 +1,3 @@ -sources([ - "pci.c" -]) \ No newline at end of file + +if config("pci_enable"): + sources("pci.c") \ No newline at end of file diff --git a/lunaix-os/hal/bus/LConfig b/lunaix-os/hal/bus/LConfig new file mode 100644 index 0000000..74e3dbf --- /dev/null +++ b/lunaix-os/hal/bus/LConfig @@ -0,0 +1,35 @@ + +@Collection +def bus_if(): + """ System/platform bus interface """ + + add_to_collection(hal) + + @Term + def pci_enable(): + """ Peripheral Component Interconnect (PCI) Bus """ + type(bool) + default(True) + + @Term + def pcie_ext(): + """ Enable support of PCI-Express extension """ + type(bool) + default(False) + + return v(pci_enable) + + @Term + def pci_pmio(): + """ Use port-mapped I/O interface for controlling PCI """ + type(bool) + + has_pcie = v(pcie_ext) + is_x86 = v(arch) in [ "i386", "x86_64" ] + + default(not has_pcie) + + if not is_x86 or has_pcie: + set_value(False) + + return is_x86 and v(pci_enable) \ No newline at end of file diff --git a/lunaix-os/hal/bus/pci.c b/lunaix-os/hal/bus/pci.c index af7a256..6d26d09 100644 --- a/lunaix-os/hal/bus/pci.c +++ b/lunaix-os/hal/bus/pci.c @@ -9,7 +9,6 @@ * */ #include -#include #include #include @@ -71,23 +70,19 @@ pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo) } int -pci_bind_definition(struct pci_device_def* pcidev_def, int* more) +pci_bind_definition(struct pci_device_def* pcidef, bool* more) { - u32_t class = pcidev_def->dev_class; - u32_t devid_mask = pcidev_def->ident_mask; - u32_t devid = pcidev_def->dev_ident & devid_mask; - - if (!pcidev_def->devdef.bind) { + if (!pcidef->devdef.bind) { ERROR("pcidev %xh:%xh.%d is unbindable", - pcidev_def->devdef.class.fn_grp, - pcidev_def->devdef.class.device, - pcidev_def->devdef.class.variant); + pcidef->devdef.class.fn_grp, + pcidef->devdef.class.device, + pcidef->devdef.class.variant); return EINVAL; } - *more = 0; + *more = false; - int bind_attempted = 0; + bool bind_attempted = 0; int errno = 0; struct device_def* devdef; @@ -98,23 +93,22 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more) continue; } - if (class != PCI_DEV_CLASS(pos->class_info)) { - continue; - } + bool matched; - int matched = (pos->device_info & devid_mask) == devid; + assert(pcidef->test_compatibility); + matched = pcidef->test_compatibility(pcidef, pos); if (!matched) { continue; } if (bind_attempted) { - *more = 1; + *more = true; break; } - bind_attempted = 1; - devdef = &pcidev_def->devdef; + bind_attempted = true; + devdef = &pcidef->devdef; errno = devdef->bind(devdef, &pos->dev); if (errno) { @@ -127,7 +121,7 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more) continue; } - pos->binding.def = &pcidev_def->devdef; + pos->binding.def = &pcidef->devdef; } return errno; @@ -136,9 +130,10 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more) int pci_bind_definition_all(struct pci_device_def* pcidef) { - int more = 0, e = 0; + int e = 0; + bool more = false; do { - if (!(e = pci_bind_definition(pcidef, &more))) { + if ((e = pci_bind_definition(pcidef, &more))) { break; } } while (more); @@ -201,7 +196,7 @@ pci_probe_bar_info(struct pci_device* device) { u32_t bar; struct pci_base_addr* ba; - for (size_t i = 0; i < 6; i++) { + for (size_t i = 0; i < PCI_BAR_COUNT; i++) { ba = &device->bar[i]; ba->size = pci_bar_sizing(device, &bar, i + 1); if (PCI_BAR_MMIO(bar)) { @@ -327,6 +322,21 @@ pci_get_device_by_class(u32_t class) return NULL; } +void +pci_apply_command(struct pci_device* pcidev, pci_reg_t cmd) +{ + pci_reg_t rcmd; + ptr_t base; + + base = pcidev->cspace_base; + rcmd = pci_read_cspace(base, PCI_REG_STATUS_CMD); + + cmd = cmd & 0xffff; + rcmd = (rcmd & 0xffff0000) | cmd; + + pci_write_cspace(base, PCI_REG_STATUS_CMD, rcmd); +} + static void __pci_read_cspace(struct twimap* map) { diff --git a/lunaix-os/hal/char/LConfig b/lunaix-os/hal/char/LConfig new file mode 100644 index 0000000..1b5ead4 --- /dev/null +++ b/lunaix-os/hal/char/LConfig @@ -0,0 +1,7 @@ +include("uart") + +@Collection +def char_device(): + """ Controlling support of character devices """ + + add_to_collection(hal) diff --git a/lunaix-os/hal/char/serial.c b/lunaix-os/hal/char/serial.c index dea044f..15a9c9e 100644 --- a/lunaix-os/hal/char/serial.c +++ b/lunaix-os/hal/char/serial.c @@ -3,12 +3,15 @@ #include #include #include +#include #include #include #include +LOG_MODULE("serial") + #define lock_sdev(sdev) device_lock((sdev)->dev) #define unlock_sdev(sdev) device_unlock((sdev)->dev) #define unlock_and_wait(sdev, wq) \ @@ -267,10 +270,13 @@ serial_create(struct devclass* class, char* if_ident) device_grant_capability(dev, cap_meta(tp_cap)); - register_device(dev, class, "s%d", class->variant); + register_device(dev, class, "%s%d", if_ident, class->variant); term_create(dev, if_ident); + INFO("interface: %s, %xh:%xh.%d", dev->name_val, + class->fn_grp, class->device, class->variant); + class->variant++; return sdev; } diff --git a/lunaix-os/hal/char/uart/16550_pmio.c b/lunaix-os/hal/char/uart/16550_pmio.c deleted file mode 100644 index 62d403a..0000000 --- a/lunaix-os/hal/char/uart/16550_pmio.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file 16550_pmio.c - * @author Lunaixsky (lunaxisky@qq.com) - * @brief 16550 UART with port mapped IO - * @version 0.1 - * @date 2023-08-30 - * - * @copyright Copyright (c) 2023 - * - */ -#include -#include - -#include - -#include "16550.h" - -#define DELAY 50 - -static DEFINE_LLIST(com_ports); - -static u32_t -com_regread(struct uart16550* uart, ptr_t regoff) -{ - u8_t val = port_rdbyte(uart->base_addr + regoff); - port_delay(DELAY); - - return (u32_t)val; -} - -static void -com_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val) -{ - port_wrbyte(uart->base_addr + regoff, (u8_t)val); - port_delay(DELAY); -} - -static void -com_irq_handler(const struct hart_state* hstate) -{ - int vector = hart_vector_stamp(hstate); - uart_general_irq_handler(vector, &com_ports); -} - -static int -upiom_init(struct device_def* def) -{ - int irq3 = 3, irq4 = 4; - u16_t ioports[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 }; - int* irqs[] = { &irq4, &irq3, &irq4, &irq3 }; - - struct uart16550* uart = NULL; - - // COM 1...4 - for (size_t i = 0; i < 4; i++) { - if (!uart) { - uart = uart_alloc(ioports[i]); - uart->read_reg = com_regread; - uart->write_reg = com_regwrite; - } else { - uart->base_addr = ioports[i]; - } - - if (!uart_testport(uart, 0xe3)) { - continue; - } - - int irq = *irqs[i]; - if (irq) { - /* - * Since these irqs are overlapped, this particular setup is needed - * to avoid double-bind - */ - uart->iv = isrm_bindirq(irq, com_irq_handler); - *((volatile int*)irqs[i]) = 0; - } - - uart_enable_fifo(uart, UART_FIFO8); - llist_append(&com_ports, &uart->local_ports); - - struct serial_dev* sdev = serial_create(&def->class, "S"); - sdev->backend = uart; - sdev->write = uart_general_tx; - sdev->exec_cmd = uart_general_exec_cmd; - - uart->sdev = sdev; - - uart_setup(uart); - uart_setie(uart); - uart = NULL; - } - - if (uart) { - uart_free(uart); - } - - return 0; -} - -static struct device_def uart_pmio_def = { - .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_UART16550), - .name = "16550 Generic UART (I/O)", - .init = upiom_init -}; -EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_onboot); \ No newline at end of file diff --git a/lunaix-os/hal/char/uart/16550.h b/lunaix-os/hal/char/uart/16x50.h similarity index 84% rename from lunaix-os/hal/char/uart/16550.h rename to lunaix-os/hal/char/uart/16x50.h index 5b4040b..addedfa 100644 --- a/lunaix-os/hal/char/uart/16550.h +++ b/lunaix-os/hal/char/uart/16x50.h @@ -58,6 +58,12 @@ #define UART_SENT_ALL 0b0010 #define UART_MODEM_UPDATE 0b0000 +#define UART_LCR_RESET \ + (UART_rLC_STOPB | \ + UART_rLC_PAREN | \ + UART_rLC_PAREVN | \ + UART_rLC_DLAB | 0b11) + struct uart16550 { struct llist_header local_ports; @@ -220,6 +226,34 @@ int uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len); void -uart_general_irq_handler(int iv, struct llist_header* ports); +uart_handle_irq_overlap(int iv, struct llist_header* ports); + +void +uart_handle_irq(int iv, struct uart16550 *uart); + +static inline struct serial_dev* +uart_create_serial(struct uart16550* uart, struct devclass* class, + struct llist_header* ports, char* if_ident) +{ + llist_append(ports, &uart->local_ports); + + struct serial_dev* sdev = serial_create(class, if_ident); + sdev->backend = uart; + sdev->write = uart_general_tx; + sdev->exec_cmd = uart_general_exec_cmd; + + uart->sdev = sdev; + + uart_setup(uart); + uart_setie(uart); + + return sdev; +} + +struct uart16550* +uart16x50_pmio_create(ptr_t base); + +struct uart16550* +uart16x50_mmio_create(ptr_t base, ptr_t size); #endif /* __LUNAIX_16550_H */ diff --git a/lunaix-os/hal/char/uart/16550_base.c b/lunaix-os/hal/char/uart/16x50_base.c similarity index 84% rename from lunaix-os/hal/char/uart/16550_base.c rename to lunaix-os/hal/char/uart/16x50_base.c index a84e3d0..6e94b84 100644 --- a/lunaix-os/hal/char/uart/16550_base.c +++ b/lunaix-os/hal/char/uart/16x50_base.c @@ -4,7 +4,7 @@ #include #include -#include "16550.h" +#include "16x50.h" struct uart16550* uart_alloc(ptr_t base_addr) @@ -42,12 +42,6 @@ uart_general_tx(struct serial_dev* sdev, u8_t* data, size_t len) return RXTX_DONE; } -#define UART_LCR_RESET \ - (UART_rLC_STOPB | \ - UART_rLC_PAREN | \ - UART_rLC_PAREVN | \ - UART_rLC_DLAB | 0b11) - static void uart_set_control_mode(struct uart16550* uart, tcflag_t cflags) { @@ -88,9 +82,8 @@ uart_general_exec_cmd(struct serial_dev* sdev, u32_t req, va_list args) } void -uart_general_irq_handler(int iv, struct llist_header* ports) +uart_handle_irq_overlap(int iv, struct llist_header* ports) { - char tmpbuf[32]; struct uart16550 *pos, *n; llist_for_each(pos, n, ports, local_ports) { @@ -103,24 +96,31 @@ uart_general_irq_handler(int iv, struct llist_header* ports) return; done: + uart_handle_irq(iv, pos); +} + +void +uart_handle_irq(int iv, struct uart16550 *uart) +{ + char tmpbuf[32]; char recv; int i = 0; - while ((recv = uart_read_byte(pos))) { + while ((recv = uart_read_byte(uart))) { tmpbuf[i++] = recv; if (likely(i < 32)) { continue; } - if (!serial_accept_buffer(pos->sdev, tmpbuf, i)) { - uart_clear_rxfifo(pos); + if (!serial_accept_buffer(uart->sdev, tmpbuf, i)) { + uart_clear_rxfifo(uart); return; } i = 0; } - serial_accept_buffer(pos->sdev, tmpbuf, i); - serial_accept_one(pos->sdev, 0); + serial_accept_buffer(uart->sdev, tmpbuf, i); + serial_accept_one(uart->sdev, 0); - serial_end_recv(pos->sdev); -} + serial_end_recv(uart->sdev); +} \ No newline at end of file diff --git a/lunaix-os/hal/char/uart/16x50_isa.c b/lunaix-os/hal/char/uart/16x50_isa.c new file mode 100644 index 0000000..d8d2e1b --- /dev/null +++ b/lunaix-os/hal/char/uart/16x50_isa.c @@ -0,0 +1,64 @@ +#include +#include +#include + +#include + +#include "16x50.h" + +LOG_MODULE("16x50-isa"); + +static DEFINE_LLIST(com_ports); + +static void +com_irq_handler(const struct hart_state* hstate) +{ + int vector = hart_vector_stamp(hstate); + uart_handle_irq_overlap(vector, &com_ports); +} + +static int +upiom_init(struct device_def* def) +{ + int irq3 = 3, irq4 = 4; + u16_t ioports[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 }; + int* irqs[] = { &irq4, &irq3, &irq4, &irq3 }; + + struct uart16550* uart = NULL; + ptr_t base; + + // COM 1...4 + for (size_t i = 0; i < 4; i++) { + + base = ioports[i]; + uart = uart16x50_pmio_create(base); + if (!uart) { + WARN("port 0x%x not accessible", base); + continue; + } + + int irq = *irqs[i]; + if (irq) { + /* + * Since these irqs are overlapped, this particular setup is needed + * to avoid double-bind + */ + uart->iv = isrm_bindirq(irq, com_irq_handler); + *((volatile int*)irqs[i]) = 0; + } + + INFO("base: 0x%x, irq=%d", + base, irq, uart->iv); + + uart_create_serial(uart, &def->class, &com_ports, "S"); + } + + return 0; +} + +static struct device_def uart_pmio_def = { + .class = DEVCLASS(DEVIF_SOC, DEVFN_CHAR, DEV_UART16550), + .name = "16550 UART (PIO)", + .init = upiom_init +}; +EXPORT_DEVICE(uart16550_pmio, &uart_pmio_def, load_onboot); \ No newline at end of file diff --git a/lunaix-os/hal/char/uart/16x50_mmio.c b/lunaix-os/hal/char/uart/16x50_mmio.c new file mode 100644 index 0000000..2e32b75 --- /dev/null +++ b/lunaix-os/hal/char/uart/16x50_mmio.c @@ -0,0 +1,39 @@ +#include +#include +#include + +#include "16x50.h" + +static u32_t +uart_mmio_regread(struct uart16550* uart, ptr_t regoff) +{ + return (u32_t)(*(u8_t*)(uart->base_addr + regoff)); +} + +static void +uart_mmio_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val) +{ + *(u8_t*)(uart->base_addr + regoff) = (u8_t)val; +} + +struct uart16550* +uart16x50_mmio_create(ptr_t base, ptr_t size) +{ + ptr_t mmio_base; + struct uart16550* uart; + + base = ioremap(base, size); + uart = uart_alloc(base); + uart->read_reg = uart_mmio_regread; + uart->write_reg = uart_mmio_regwrite; + + if (!uart_testport(uart, 0xe3)) { + iounmap(base, size); + uart_free(uart); + return NULL; + } + + uart_enable_fifo(uart, UART_FIFO8); + + return uart; +} \ No newline at end of file diff --git a/lunaix-os/hal/char/uart/16x50_pci.c b/lunaix-os/hal/char/uart/16x50_pci.c new file mode 100644 index 0000000..880fd2d --- /dev/null +++ b/lunaix-os/hal/char/uart/16x50_pci.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include + +#include + +#include "16x50.h" + +#define PCI_DEVICE_16x50_UART 0x070000 + +LOG_MODULE("16x50-pci") + +static DEFINE_LLIST(pci_ports); + +static void +uart_msi_irq_handler(const struct hart_state* hstate) +{ + int vector; + struct uart16550* uart; + + vector = hart_vector_stamp(hstate); + uart = (struct uart16550*)isrm_get_payload(hstate); + + assert(uart); + uart_handle_irq(vector, uart); +} + +static void +uart_intx_irq_handler(const struct hart_state* hstate) +{ + int vector = hart_vector_stamp(hstate); + uart_handle_irq_overlap(vector, &pci_ports); +} + +static int +pci16550_init(struct device_def* def) +{ + return pci_bind_definition_all(pcidev_def(def)); +} + +static bool +pci16650_check_compat(struct pci_device_def* def, + struct pci_device* pcidev) +{ + unsigned int classid; + classid = pci_device_class(pcidev); + + return (classid & 0xffff00) == PCI_DEVICE_16x50_UART; +} + +static int +pci16650_binder(struct device_def* def, struct device* dev) +{ + int irq; + struct pci_base_addr* bar; + struct pci_device* pcidev; + struct uart16550* uart; + struct serial_dev* sdev; + + pcidev = PCI_DEVICE(dev); + + pci_reg_t cmd = 0; + + for (int i = 0; i < PCI_BAR_COUNT; i++) + { + cmd = 0; + pci_cmd_set_msi(&cmd); + + bar = pci_device_bar(pcidev, i); + if (bar->size == 0) { + continue; + } + + if (!pci_bar_mmio_space(bar)) { + pci_cmd_set_pmio(&cmd); + pci_apply_command(pcidev, cmd); + + uart = uart16x50_pmio_create(bar->start); + } + else { + pci_cmd_set_mmio(&cmd); + pci_apply_command(pcidev, cmd); + + uart = uart16x50_mmio_create(bar->start, bar->size); + } + + if (!uart) { + WARN("not accessible (BAR #%d)", i); + continue; + } + + if (pci_capability_msi(pcidev)) { + irq = isrm_ivexalloc(uart_msi_irq_handler); + isrm_set_payload(irq, __ptr(uart)); + pci_setup_msi(pcidev, irq); + } + else { + irq = pci_intr_irq(pcidev); + irq = isrm_bindirq(irq, uart_intx_irq_handler); + } + + INFO("base: 0x%x (%s), irq=%d (%s)", + bar->start, + pci_bar_mmio_space(bar) ? "mmio" : "pmio", + irq, + pci_capability_msi(pcidev) ? "msi" : "intx, re-routed"); + + uart->iv = irq; + + sdev = uart_create_serial(uart, &def->class, &pci_ports, "PCI"); + pci_bind_instance(pcidev, sdev); + } + + return 0; +} + +static struct pci_device_def uart_pci_def = { + .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_CHAR, DEV_UART16550), + .name = "16550 UART (PCI/MMIO)", + .init = pci16550_init, + .bind = pci16650_binder }, + .test_compatibility = pci16650_check_compat +}; +EXPORT_PCI_DEVICE(uart16550_pci, &uart_pci_def, load_onboot); \ No newline at end of file diff --git a/lunaix-os/hal/char/uart/16x50_pmio.c b/lunaix-os/hal/char/uart/16x50_pmio.c new file mode 100644 index 0000000..76ab3bc --- /dev/null +++ b/lunaix-os/hal/char/uart/16x50_pmio.c @@ -0,0 +1,54 @@ +/** + * @file 16550_pmio.c + * @author Lunaixsky (lunaxisky@qq.com) + * @brief 16550 UART with port mapped IO + * @version 0.1 + * @date 2023-08-30 + * + * @copyright Copyright (c) 2023 + * + */ +#include +#include + +#include + +#include "16x50.h" + +#define DELAY 50 + +static u32_t +com_regread(struct uart16550* uart, ptr_t regoff) +{ + u8_t val = port_rdbyte(uart->base_addr + regoff); + port_delay(DELAY); + + return (u32_t)val; +} + +static void +com_regwrite(struct uart16550* uart, ptr_t regoff, u32_t val) +{ + port_wrbyte(uart->base_addr + regoff, (u8_t)val); + port_delay(DELAY); +} + + +struct uart16550* +uart16x50_pmio_create(ptr_t base) +{ + struct uart16550* uart; + + uart = uart_alloc(base); + uart->read_reg = com_regread; + uart->write_reg = com_regwrite; + + if (!uart_testport(uart, 0xe3)) { + uart_free(uart); + return NULL; + } + + uart_enable_fifo(uart, UART_FIFO8); + + return uart; +} diff --git a/lunaix-os/hal/char/uart/LBuild b/lunaix-os/hal/char/uart/LBuild index 1fbc933..83088c6 100644 --- a/lunaix-os/hal/char/uart/LBuild +++ b/lunaix-os/hal/char/uart/LBuild @@ -1,4 +1,11 @@ sources([ - "16550_base.c", - "16550_pmio.c" -]) \ No newline at end of file + "16x50_base.c", + "16x50_pmio.c", + "16x50_mmio.c", +]) + +if config("xt_16x50"): + sources("16x50_isa.c") + +if config("pci_16x50"): + sources("16x50_pci.c") \ No newline at end of file diff --git a/lunaix-os/hal/char/uart/LConfig b/lunaix-os/hal/char/uart/LConfig new file mode 100644 index 0000000..9ed1f09 --- /dev/null +++ b/lunaix-os/hal/char/uart/LConfig @@ -0,0 +1,25 @@ + +@Collection("16x50 Serial Controller") +def uart_16x50(): + """ 16x50 serial controller """ + + # hal/char/LConfig::char_device + add_to_collection(char_device) + + @Term("16x50 XT-Compat") + def xt_16x50(): + """ Enable the 16x50 for PC-compatible platform """ + + type(bool) + + is_x86 = v(arch) in ["i386", "x86_64"] + default(is_x86) + + return is_x86 + + @Term("16x50 PCI") + def pci_16x50(): + """ Enable the support of PCI 16x50 """ + type(bool) + + default(True) \ No newline at end of file diff --git a/lunaix-os/hal/gfxa/vga/vga_pci.c b/lunaix-os/hal/gfxa/vga/vga_pci.c index 09476db..1109e5a 100644 --- a/lunaix-os/hal/gfxa/vga/vga_pci.c +++ b/lunaix-os/hal/gfxa/vga/vga_pci.c @@ -6,7 +6,6 @@ #include #include -#include #include @@ -76,8 +75,8 @@ vga_pci_bind(struct device_def* devdef, struct device* pcidev_base) pci_write_cspace(pcidev->cspace_base, PCI_REG_STATUS_CMD, cmd); - ptr_t fb_mapped = (ptr_t)ioremap(fb->start, FB256K); - ptr_t mmio_mapped = (ptr_t)ioremap(mmio->start, mmio->size); + ptr_t fb_mapped = ioremap(fb->start, FB256K); + ptr_t mmio_mapped = ioremap(mmio->start, mmio->size); struct vga* vga_state = vga_new_state(mmio_mapped + VGA_REG_OFF, fb_mapped, FB256K); @@ -105,13 +104,19 @@ vga_pci_init(struct device_def* def) #define VGA_PCI_CLASS 0x30000 +static bool +vga_pci_compat(struct pci_device_def* def, + struct pci_device* pcidev) +{ + return pci_device_class(pcidev) == VGA_PCI_CLASS; +} + + static struct pci_device_def vga_pci_devdef = { - .dev_class = VGA_PCI_CLASS, - .dev_ident = PCI_DEVIDENT(0x1234, 0x1111), - .ident_mask = PCI_MATCH_EXACT, .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_DISP, DEV_VGA), .name = "Generic VGA", .init = vga_pci_init, - .bind = vga_pci_bind } + .bind = vga_pci_bind }, + .test_compatibility = vga_pci_compat }; EXPORT_PCI_DEVICE(vga_pci, &vga_pci_devdef, load_onboot); \ No newline at end of file diff --git a/lunaix-os/includes/hal/pci.h b/lunaix-os/includes/hal/pci.h index da45090..d457a1e 100644 --- a/lunaix-os/includes/hal/pci.h +++ b/lunaix-os/includes/hal/pci.h @@ -38,6 +38,7 @@ #define PCI_BAR_TYPE(x) ((x) & 0x6) #define PCI_BAR_ADDR_MM(x) ((x) & ~0xf) #define PCI_BAR_ADDR_IO(x) ((x) & ~0x3) +#define PCI_BAR_COUNT 6 #define PCI_MSI_ADDR_LO(msi_base) ((msi_base) + 4) #define PCI_MSI_ADDR_HI(msi_base) ((msi_base) + 8) @@ -116,10 +117,9 @@ typedef void* (*pci_drv_init)(struct pci_device*); struct pci_device_def { - u32_t dev_class; - u32_t dev_ident; - u32_t ident_mask; struct device_def devdef; + + bool (*test_compatibility)(struct pci_device_def*, struct pci_device*); }; #define pcidev_def(dev_def_ptr) \ container_of((dev_def_ptr), struct pci_device_def, devdef) @@ -176,9 +176,98 @@ void pci_probe_msi_info(struct pci_device* device); int -pci_bind_definition(struct pci_device_def* pcidev_def, int* more); +pci_bind_definition(struct pci_device_def* pcidev_def, bool* more); int pci_bind_definition_all(struct pci_device_def* pcidef); +static inline unsigned int +pci_device_vendor(struct pci_device* pcidev) +{ + return PCI_DEV_VENDOR(pcidev->device_info); +} + +static inline unsigned int +pci_device_devid(struct pci_device* pcidev) +{ + return PCI_DEV_DEVID(pcidev->device_info); +} + +static inline unsigned int +pci_device_class(struct pci_device* pcidev) +{ + return PCI_DEV_CLASS(pcidev->class_info); +} + +static inline struct pci_base_addr* +pci_device_bar(struct pci_device* pcidev, int index) +{ + return &pcidev->bar[index]; +} + +static inline void +pci_cmd_set_mmio(pci_reg_t* cmd) +{ + *cmd |= PCI_RCMD_MM_ACCESS; +} + + +static inline void +pci_cmd_set_pmio(pci_reg_t* cmd) +{ + *cmd |= PCI_RCMD_IO_ACCESS; +} + +static inline void +pci_cmd_set_msi(pci_reg_t* cmd) +{ + *cmd |= PCI_RCMD_DISABLE_INTR; +} + +static inline void +pci_cmd_set_bus_master(pci_reg_t* cmd) +{ + *cmd |= PCI_RCMD_BUS_MASTER; +} + +static inline void +pci_cmd_set_fast_b2b(pci_reg_t* cmd) +{ + *cmd |= PCI_RCMD_FAST_B2B; +} + +static inline bool +pci_bar_mmio_space(struct pci_base_addr* bar) +{ + return (bar->type & BAR_TYPE_MMIO); +} + +static inline bool +pci_capability_msi(struct pci_device* pcidev) +{ + return !!pcidev->msi_loc; +} + +static inline int +pci_intr_irq(struct pci_device* pcidev) +{ + return PCI_INTR_IRQ(pcidev->intr_info); +} + +void +pci_apply_command(struct pci_device* pcidev, pci_reg_t cmd); + +pci_reg_t +pci_read_cspace(ptr_t base, int offset); + +void +pci_write_cspace(ptr_t base, int offset, pci_reg_t data); + +u16_t +pci_config_msi_data(int vector); + +ptr_t +pci_get_msi_base(); + + #endif /* __LUNAIX_PCI_H */ diff --git a/lunaix-os/includes/lunaix/kpreempt.h b/lunaix-os/includes/lunaix/kpreempt.h index d20deba..e622e05 100644 --- a/lunaix-os/includes/lunaix/kpreempt.h +++ b/lunaix-os/includes/lunaix/kpreempt.h @@ -3,7 +3,8 @@ #include -#define _preemptible __attribute__((section(".kf.preempt"))) +#define _preemptible \ + __attribute__((section(".kf.preempt"))) no_inline #define ensure_preempt_caller() \ do { \ diff --git a/lunaix-os/includes/lunaix/mm/mmio.h b/lunaix-os/includes/lunaix/mm/mmio.h index 18d1c4f..29b0786 100644 --- a/lunaix-os/includes/lunaix/mm/mmio.h +++ b/lunaix-os/includes/lunaix/mm/mmio.h @@ -3,7 +3,7 @@ #include -void* +ptr_t ioremap(ptr_t paddr, u32_t size); void diff --git a/lunaix-os/includes/lunaix/mm/page.h b/lunaix-os/includes/lunaix/mm/page.h index 23d5c64..0f9fb0c 100644 --- a/lunaix-os/includes/lunaix/mm/page.h +++ b/lunaix-os/includes/lunaix/mm/page.h @@ -284,6 +284,13 @@ vmap_range(pfn_t start, size_t npages, pte_attr_t prot) return vmap_ptes_at(_pte, LFT_SIZE, npages); } +static inline void +vunmap_range(pfn_t start, size_t npages) +{ + pte_t* ptep = mkptep_va(VMS_SELF, start); + vmm_set_ptes_contig(ptep, null_pte, LFT_SIZE, npages); +} + /** * @brief Allocate a page in kernel space. diff --git a/lunaix-os/kernel/LConfig b/lunaix-os/kernel/LConfig index c820fd0..37b9005 100644 --- a/lunaix-os/kernel/LConfig +++ b/lunaix-os/kernel/LConfig @@ -3,4 +3,4 @@ def kernel_feature(): """ Config kernel features """ pass -include("mm/LConfig") \ No newline at end of file +include("mm") \ No newline at end of file diff --git a/lunaix-os/kernel/kinit.c b/lunaix-os/kernel/kinit.c index 685c3d0..ca28001 100644 --- a/lunaix-os/kernel/kinit.c +++ b/lunaix-os/kernel/kinit.c @@ -43,7 +43,7 @@ kernel_bootstrap(struct boot_handoff* bhctx) /* Begin kernel bootstrapping sequence */ boot_begin(bhctx); - tty_init(ioremap(0xB8000, PAGE_SIZE)); + tty_init((void*)ioremap(0xB8000, PAGE_SIZE)); /* Setup kernel memory layout and services */ kmem_init(bhctx); diff --git a/lunaix-os/kernel/mm/mmio.c b/lunaix-os/kernel/mm/mmio.c index b91ab0e..dbb1870 100644 --- a/lunaix-os/kernel/mm/mmio.c +++ b/lunaix-os/kernel/mm/mmio.c @@ -2,7 +2,7 @@ #include #include -void* +ptr_t ioremap(ptr_t paddr, u32_t size) { // FIXME implement a page policy interface allow to decouple the @@ -14,21 +14,13 @@ ioremap(ptr_t paddr, u32_t size) // Ensure the range is reservable (not already in use) assert(pmm_onhold_range(start, npages)); - return (void*)vmap_range(start, npages, KERNEL_DATA); + ptr_t addr = vmap_range(start, npages, KERNEL_DATA); + return addr + va_offset(paddr); } void iounmap(ptr_t vaddr, u32_t size) { - // FIXME - fail("need fix"); - - // pte_t* ptep = mkptep_va(VMS_SELF, vaddr); - // for (size_t i = 0; i < size; i += PAGE_SIZE, ptep++) { - // pte_t pte = pte_at(ptep); - - // set_pte(ptep, null_pte); - // if (pte_isloaded(pte)) - // return_page(ppage_pa(pte_paddr(pte))); - // } + assert(vaddr >= VMAP && vaddr < VMAP_END); + vunmap_range(pfn(vaddr), leaf_count(size)); } \ No newline at end of file diff --git a/lunaix-os/live_debug.sh b/lunaix-os/live_debug.sh index e10f71c..6462f5d 100755 --- a/lunaix-os/live_debug.sh +++ b/lunaix-os/live_debug.sh @@ -4,7 +4,7 @@ hmp_port=45454 gdb_port=1234 default_cmd="console=/dev/ttyS0" -make CMDLINE=${default_cmd} ARCH=${ARCH} MODE=debug image -j5 || exit -1 +make CMDLINE=${default_cmd} ARCH=${ARCH} MODE=${MODE:-debug} image -j5 || exit -1 ./scripts/qemu.py \ scripts/qemus/qemu_x86_dev.json \ diff --git a/lunaix-os/makeinc/toolchain.mkinc b/lunaix-os/makeinc/toolchain.mkinc index a538488..486e9ce 100644 --- a/lunaix-os/makeinc/toolchain.mkinc +++ b/lunaix-os/makeinc/toolchain.mkinc @@ -14,21 +14,12 @@ W := -Wall -Wextra -Werror \ -Wno-discarded-qualifiers\ -Werror=incompatible-pointer-types -OFLAGS := -fno-gcse\ - -fno-gcse-lm\ - -fno-cse-follow-jumps\ - -fno-cse-skip-blocks\ - -fno-optimize-strlen\ - -fno-inline-functions-called-once \ - -fno-inline-small-functions \ - -fno-indirect-inlining\ - -fno-omit-frame-pointer +OFLAGS := -fno-omit-frame-pointer -CFLAGS := -std=gnu99 $(OFLAGS) $(W) +CFLAGS := -std=gnu99 $(OFLAGS) $(W) -g ifeq ($(MODE),debug) O = -Og - CFLAGS += -g endif CFLAGS += $(O) diff --git a/lunaix-os/scripts/build-tools/integration/config_io.py b/lunaix-os/scripts/build-tools/integration/config_io.py index 33079ff..15e1ba8 100644 --- a/lunaix-os/scripts/build-tools/integration/config_io.py +++ b/lunaix-os/scripts/build-tools/integration/config_io.py @@ -26,7 +26,7 @@ class CHeaderConfigProvider(ConfigIOProvider): v = self.serialize_value(v) if v is None or v is False: result.insert(0, "//") - else: + elif isinstance(v, str): result.append(v) lines.append(" ".join(result)) diff --git a/lunaix-os/scripts/build-tools/integration/render_ishell.py b/lunaix-os/scripts/build-tools/integration/render_ishell.py index 5eacf55..4fdee85 100644 --- a/lunaix-os/scripts/build-tools/integration/render_ishell.py +++ b/lunaix-os/scripts/build-tools/integration/render_ishell.py @@ -207,7 +207,7 @@ class InteractiveShell(InteractiveRenderer): def do_read(self, node_name): view, _ = self.resolve(node_name) rd_val = view.read(self.__sctx) - if not rd_val: + if rd_val is None: raise ShellException(f"config node {view.label} is not readable") print(rd_val) diff --git a/lunaix-os/scripts/build-tools/lcfg/builtins.py b/lunaix-os/scripts/build-tools/lcfg/builtins.py index f32b9b6..f072303 100644 --- a/lunaix-os/scripts/build-tools/lcfg/builtins.py +++ b/lunaix-os/scripts/build-tools/lcfg/builtins.py @@ -13,8 +13,12 @@ def v(env, caller, term): def include(env, caller, file): fobj = caller.get_fo() path = os.path.dirname(fobj.filename()) + path = join_path(path, file) + + if os.path.isdir(path): + path = join_path(path, "LConfig") - env.resolve_module(join_path(path, file)) + env.resolve_module(path) @contextual("type", caller_type=[LCTermNode]) def term_type(env, caller, type): diff --git a/lunaix-os/scripts/qemu.py b/lunaix-os/scripts/qemu.py index 5338326..ce843da 100755 --- a/lunaix-os/scripts/qemu.py +++ b/lunaix-os/scripts/qemu.py @@ -80,13 +80,14 @@ class PCISerialDevice(QEMUPeripherals): super().__init__("pci-serial", opt) def get_qemu_opts(self): - name = f"chrdev.{hex(self.__hash__())[2:]}" - cmds = [ "pci-serial", f"chardev={name}" ] + uniq = hex(self.__hash__())[2:] + name = f"chrdev.{uniq}" + cmds = [ "pci-serial", f"id=uart.{uniq}", f"chardev={name}" ] chrdev = [ "file", f"id={name}" ] logfile = get_config(self._opt, "logfile", required=True) chrdev.append(f"path={logfile}") - () + return [ "-chardev", join_attrs(chrdev), "-device", join_attrs(cmds) @@ -196,7 +197,7 @@ class QEMUExec: trace_opts = get_config(debug, "traced", []) for trace in trace_opts: - cmds += [ "-d", f"trace:{trace}"] + cmds += [ "--trace", f"{trace}"] return cmds diff --git a/lunaix-os/scripts/qemus/qemu_x86_dev.json b/lunaix-os/scripts/qemus/qemu_x86_dev.json index 474ad1a..e006691 100644 --- a/lunaix-os/scripts/qemus/qemu_x86_dev.json +++ b/lunaix-os/scripts/qemus/qemu_x86_dev.json @@ -32,6 +32,14 @@ "addr": ":12345", "logfile": "lunaix_ttyS0.log" }, + { + "class": "pci-serial", + "logfile": "ttyPCI0.log" + }, + { + "class": "pci-serial", + "logfile": "ttyPCI1.log" + }, { "class": "rtc", "base": "utc" diff --git a/lunaix-os/usr/LBuild b/lunaix-os/usr/LBuild index 03a89ee..ec56dcb 100644 --- a/lunaix-os/usr/LBuild +++ b/lunaix-os/usr/LBuild @@ -36,3 +36,5 @@ if config("arch") == "x86_64": else: compile_opts("-m32") linking_opts("-m32") + +compile_opts("-mno-sse") \ No newline at end of file diff --git a/lunaix-os/usr/ls.c b/lunaix-os/usr/ls.c index ece96e4..698d025 100644 --- a/lunaix-os/usr/ls.c +++ b/lunaix-os/usr/ls.c @@ -20,7 +20,7 @@ main(int argc, const char* argv[]) while ((dent = readdir(dir))) { if (dent->d_type == DT_DIR) { - printf(" %s\n", dent->d_name); + printf(" %s/\n", dent->d_name); } else if (dent->d_type == DT_SYMLINK) { printf(" %s@\n", dent->d_name); } else { diff --git a/lunaix-os/usr/testp.c b/lunaix-os/usr/testp.c index 8011c30..ee33fe6 100644 --- a/lunaix-os/usr/testp.c +++ b/lunaix-os/usr/testp.c @@ -6,26 +6,32 @@ #include void -test_serial() +test_serial(char* dev, int wr) { - int fd = open("/dev/ttyS0", FO_WRONLY); + int fd = open(dev, FO_WRONLY); if (fd < 0) { - printf("ttyS0 not accessable (%d)\n", errno); + printf("tty %s not accessable (%d)\n", dev, errno); return; } - char buf[32]; int sz = 0; + char buf[256]; - printf("ttyS0 input: "); + if (!wr) { + printf("tty input: "); - if ((sz = read(fd, buf, 31)) < 0) { - printf("write to ttyS0 failed (%d)\n", errno); - } + if ((sz = read(fd, buf, 31)) < 0) { + printf("read to tty failed (%d)\n", errno); + } - buf[sz] = 0; + buf[sz] = 0; - printf("%s", buf); + printf("%s", buf); + } + else { + int size = snprintf(buf, 256, "serial test: %s", dev); + write(fd, buf, size); + } close(fd); } @@ -33,18 +39,14 @@ test_serial() int main(int argc, char* argv[]) { - if (argc <= 1) { + if (argc != 2) { + printf("usage: testp path_to_dev\n"); return 1; } char* target = argv[1]; - if (!strcmp(target, "serial")) { - test_serial(); - } else { - printf("unknown test: %s\n", target); - return 1; - } + test_serial(target, 1); return 0; } \ No newline at end of file -- 2.27.0