From 5486af56a526398455ca6fa212e7b43c72daec98 Mon Sep 17 00:00:00 2001 From: Minep Date: Mon, 27 Jun 2022 15:35:27 +0100 Subject: [PATCH] feat: PCI bus probing fix: typo in ESC perfix for ANSI color code. --- lunaix-os/hal/pci.c | 112 +++++++++++++++++++++++++++++++++++ lunaix-os/includes/hal/pci.h | 73 +++++++++++++++++++++++ lunaix-os/includes/hal/pic.h | 6 +- lunaix-os/kernel/kprintf.c | 6 +- lunaix-os/kernel/proc0.c | 10 +++- lunaix-os/kernel/tty/tty.c | 2 +- 6 files changed, 200 insertions(+), 9 deletions(-) create mode 100644 lunaix-os/hal/pci.c create mode 100644 lunaix-os/includes/hal/pci.h diff --git a/lunaix-os/hal/pci.c b/lunaix-os/hal/pci.c new file mode 100644 index 0000000..8bc35ce --- /dev/null +++ b/lunaix-os/hal/pci.c @@ -0,0 +1,112 @@ +#include +#include +#include + +LOG_MODULE("PCI") + +static struct llist_header pci_devices; + +void +pci_probe_device(int bus, int dev, int funct) +{ + pci_reg_t reg1 = pci_read_cspace(bus, dev, funct, 0); + uint32_t vendor = reg1 & 0xffff; + pci_reg_t dev_id = reg1 >> 16; + + // Vendor=0xffff则表示设备不存在 + if (vendor == PCI_VENDOR_INVLD) { + return; + } + + pci_reg_t hdr_type = pci_read_cspace(bus, dev, funct, 3); + hdr_type = (hdr_type >> 16) & 0xff; + + if ((hdr_type & 0x80)) { + hdr_type = hdr_type & ~0x80; + // 探测多用途设备(multi-function device) + for (int i = 1; i < 7; i++) { + pci_probe_device(bus, dev, i); + } + } + + if (hdr_type != 0) { + // XXX: 目前忽略所有桥接设备,比如PCI-PCI桥接器,或者是CardBus桥接器 + return; + } + + pci_reg_t intr = pci_read_cspace(bus, dev, funct, 15); + pci_reg_t class = pci_read_cspace(bus, dev, funct, 2) >> 8; + + struct pci_device* device = lxmalloc(sizeof(struct pci_device)); + *device = (struct pci_device){ .bus = bus, + .dev = dev, + .function = funct, + .class_code = class, + .vendor = vendor, + .deviceId = dev_id, + .type = hdr_type, + .intr_line = intr & 0xff, + .intr_pintype = (intr >> 8) & 0xff }; + + // 读取设备的内存映射的寄存器的基地址 + for (int i = 0; i < 6; i++) { + device->bars[i] = pci_read_cspace(bus, dev, funct, 4 + i); + } + + llist_append(&pci_devices, &device->dev_chain); +} + +void +pci_probe() +{ + // 暴力扫描所有PCI设备 + // XXX: 尽管最多会有256条PCI总线,但就目前而言,只考虑bus #0就足够了 + for (int bus = 0; bus < 1; bus++) { + for (int dev = 0; dev < 32; dev++) { + pci_probe_device(bus, dev, 0); + } + } +} + +void +pci_print_device() +{ + struct pci_device *pos, *n; + llist_for_each(pos, n, &pci_devices, dev_chain) + { + kprintf(KINFO "(B%xh:D%xh:F%xh) Dev %x:%x, Class 0x%x\n", + pos->bus, + pos->dev, + pos->function, + pos->vendor, + pos->deviceId, + pos->class_code); + + for (int i = 0; i < 6; i++) { + kprintf(KINFO "\t BAR#%d: %p\n", i, pos->bars[i]); + } + kprintf( + KINFO "\t IRQ: %d, INT#x: %d\n\n", pos->intr_line, pos->intr_pintype); + } +} + +struct pci_device* +pci_get_device(uint16_t vendorId, uint16_t deviceId) +{ + struct pci_device *pos, *n; + llist_for_each(pos, n, &pci_devices, dev_chain) + { + if (pos->vendor == vendorId && pos->deviceId == deviceId) { + return pos; + } + } + + return NULL; +} + +void +pci_init() +{ + llist_init_head(&pci_devices); + pci_probe(); +} \ No newline at end of file diff --git a/lunaix-os/includes/hal/pci.h b/lunaix-os/includes/hal/pci.h new file mode 100644 index 0000000..3e421ee --- /dev/null +++ b/lunaix-os/includes/hal/pci.h @@ -0,0 +1,73 @@ +#ifndef __LUNAIX_PCI_H +#define __LUNAIX_PCI_H + +#include +#include + +#define PCI_CONFIG_ADDR 0xcf8 +#define PCI_CONFIG_DATA 0xcfc + +#define PCI_TDEV 0x0 +#define PCI_TPCIBRIDGE 0x1 +#define PCI_TCARDBRIDGE 0x2 + +#define PCI_VENDOR_INVLD 0xffff + +#define PCI_REG_VENDER 0x0 +#define PCI_REG_DEV 0x1 +#define PCI_REG_HDRTYPE 0x7 + +#define PCI_ADDRESS(bus, dev, funct, reg) \ + (((bus)&0xff) << 16) | (((dev)&0xff) << 11) | (((funct)&0xff) << 8) | \ + (((reg)&0xff) << 2) | 0x80000000 + +typedef unsigned int pci_reg_t; + +// PCI device header format +// Ref: "PCI Local Bus Specification, Rev.3, Section 6.1" + +struct pci_device +{ + struct llist_header dev_chain; + uint16_t vendor; + uint16_t deviceId; + uint32_t class_code; + uint8_t bus; + uint8_t dev; + uint8_t function; + uint8_t type; + uint8_t intr_line; + uint8_t intr_pintype; + uint32_t bars[6]; +}; + +// PCI Configuration Space (C-Space) r/w: +// Refer to "PCI Local Bus Specification, Rev.3, Section 3.2.2.3.2" + +inline pci_reg_t +pci_read_cspace(int bus, int dev, int funct, int reg) +{ + io_outl(PCI_CONFIG_ADDR, PCI_ADDRESS(bus, dev, funct, reg)); + return io_inl(PCI_CONFIG_DATA); +} + +inline void +pci_write_cspace(int bus, int dev, int funct, int reg, pci_reg_t data) +{ + io_outl(PCI_CONFIG_ADDR, PCI_ADDRESS(bus, dev, funct, reg)); + io_outl(PCI_CONFIG_DATA, data); +} + +void +pci_probe(); + +void +pci_init(); + +void +pci_print_device(); + +struct pci_device* +pci_get_device(uint16_t vendorId, uint16_t deviceId); + +#endif /* __LUNAIX_PCI_H */ diff --git a/lunaix-os/includes/hal/pic.h b/lunaix-os/includes/hal/pic.h index 8fdcd04..b13aae5 100644 --- a/lunaix-os/includes/hal/pic.h +++ b/lunaix-os/includes/hal/pic.h @@ -6,9 +6,9 @@ static inline void pic_disable() { // ref: https://wiki.osdev.org/8259_PIC - asm volatile ("movb $0xff, %al\n" - "outb %al, $0xa1\n" - "outb %al, $0x21\n"); + asm volatile("movb $0xff, %al\n" + "outb %al, $0xa1\n" + "outb %al, $0x21\n"); } #endif /* __LUNAIX_PIC_H */ diff --git a/lunaix-os/kernel/kprintf.c b/lunaix-os/kernel/kprintf.c index 75b9fc4..af47a8a 100644 --- a/lunaix-os/kernel/kprintf.c +++ b/lunaix-os/kernel/kprintf.c @@ -33,7 +33,7 @@ __kprintf(const char* component, const char* fmt, va_list args) // tty_set_theme(VGA_COLOR_BROWN, current_theme >> 12); snprintf(expanded_fmt, MAX_XFMT_SIZE, - "\x033[6;0m[%s] (%s) %s\x033[39;49m", + "\033[6;0m[%s] (%s) %s\033[39;49m", "WARN", component, fmt); @@ -42,7 +42,7 @@ __kprintf(const char* component, const char* fmt, va_list args) // tty_set_theme(VGA_COLOR_LIGHT_RED, current_theme >> 12); snprintf(expanded_fmt, MAX_XFMT_SIZE, - "\x033[12;0m[%s] (%s) %s\x033[39;49m", + "\033[12;0m[%s] (%s) %s\033[39;49m", "EROR", component, fmt); @@ -51,7 +51,7 @@ __kprintf(const char* component, const char* fmt, va_list args) // tty_set_theme(VGA_COLOR_LIGHT_BLUE, current_theme >> 12); snprintf(expanded_fmt, MAX_XFMT_SIZE, - "\x033[9;0m[%s] (%s) %s\x033[39;49m", + "\033[9;0m[%s] (%s) %s\033[39;49m", "DEBG", component, fmt); diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 663eff2..92d3fd3 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE("PROC0") @@ -32,6 +33,7 @@ unlock_reserved_memory(); void __do_reserved_memory(int unlock); +//#define USE_DEMO #define DEMO_SIGNAL extern void @@ -52,14 +54,16 @@ __proc0_usr() } if (!(p = fork())) { -#ifdef DEMO_SIGNAL +#ifndef USE_DEMO + _exit(0); +#elif defined DEMO_SIGNAL _signal_demo_main(); #else _lxinit_main(); #endif } - // waitpid(p, 0, 0); + waitpid(p, 0, 0); while (1) { yield(); @@ -126,6 +130,8 @@ init_platform() timer_init(SYS_TIMER_FREQUENCY_HZ); clock_init(); ps2_kbd_init(); + pci_init(); + pci_print_device(); syscall_install(); diff --git a/lunaix-os/kernel/tty/tty.c b/lunaix-os/kernel/tty/tty.c index b491355..d4ac8d0 100644 --- a/lunaix-os/kernel/tty/tty.c +++ b/lunaix-os/kernel/tty/tty.c @@ -53,7 +53,7 @@ tty_flush_buffer(char* data, size_t pos, size_t limit, size_t buf_size) break; } char chr = data[pos]; - if (state == 0 && chr == '\x033') { + if (state == 0 && chr == '\033') { state = 1; } else if (state == 1 && chr == '[') { state = 2; -- 2.27.0