From a5af6c51da9281f889445137e7b2d3b2bf60cf45 Mon Sep 17 00:00:00 2001 From: notsomeidiot123 Date: Mon, 15 Sep 2025 12:50:18 -0400 Subject: [PATCH] (mostly) finished PCI implementation, will flesh it out more as needed. (100th commit\!\!\!) --- src/kernel/drivers/pci.c | 89 ++++++++++++++++++++++++++++++++++++- src/kernel/kmain.c | 4 +- src/kernel/system/modules.c | 22 +++++++-- src/kernel/system/vfs.c | 15 ++++--- src/kernel/system/vfs.h | 11 +++-- 5 files changed, 123 insertions(+), 18 deletions(-) diff --git a/src/kernel/drivers/pci.c b/src/kernel/drivers/pci.c index cb50bcb..a4234d6 100644 --- a/src/kernel/drivers/pci.c +++ b/src/kernel/drivers/pci.c @@ -1,9 +1,24 @@ #include "pci.h" #include "../shared/kstdlib.h" #include "cpuio.h" - +#include "../system/vfs.h" +#include "../shared/string.h" +#include "../shared/memory.h" #define MODULE_NAME "PCI" +char *classes[][20] = { + {}, + {"scsi", "ide", "floppy", "ipi", "raid", "ata", "sata", "sascsi", "nvm"}, + {"eth", "tring", "fddi", "atm", "isdn", "wordfip", "picmg", "infband", "fabric"}, + {"vga", "xga", "nvga3d"}, + {}, + {}, + {"host", "isa", "eisa", "mca", "pci", "pcmcia", "nubus", "cardbus"}, + {}, + {"pic", "dma", "timer", "rtc"} + +}; + uint16_t pci_read_config(uint32_t bus, uint32_t slot, uint32_t func, uint8_t offset){ uint32_t address = (uint32_t)((bus << 16) | (slot << 11) | (func << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); outl(0xcf8, address); @@ -11,13 +26,78 @@ uint16_t pci_read_config(uint32_t bus, uint32_t slot, uint32_t func, uint8_t off return tmp; } +void pci_read_file(vfile_t *file, uint32_t *buffer, uint32_t offset, uint32_t count){ + uint8_t bus = file->id >> 16; + uint8_t func = file->id>> 8 & 0xff; + uint8_t slot = file->id & 0xff; + for(uint32_t i = 0; i < count/2; i++){ + buffer[i] = pci_read_config(bus, slot, func, offset + i*2) | (pci_read_config(bus, slot, func, offset + i * 2 + 2) << 16); + } + return; +} +void pci_write_file(vfile_t *file, uint32_t *buffer, uint32_t offset, uint32_t count){ + return; +} +void pci_make_file(uint32_t class, uint8_t bus, uint8_t slot, uint8_t func){ + char *str = kmalloc(1); + memcpy("/dev/pci/", str, 9); + char *dev = classes[class >> 8][class & 0xf]; + switch(class >> 8){ + case 0x1://PCI class 0x1 is disks + strcpy("disk/", str + strlen(str)); + break; + case 0x2://PCI class 0x2 is network controllers + strcpy("net/", str + strlen(str)); + break; + case 0x3://PCI class 0x3 is video controllers + strcpy("video/", str + strlen(str)); + break; + case 0x6://PCI class 0x6 is bridge controllers + strcpy("bridge/", str + strlen(str)); + break; + } + strcpy(dev,str+strlen(str)); + // vfile_t *file = fcreate(str, VFILE_DEVICE, pci_write_file, pci_read_file); + char num[10]; + char cpy[256]; + vfile_t *file = 0; + uint8_t tries = 0; + while(file == 0){ + itoa(tries++, num, 10); + strcpy(str, cpy); + strcpy(num, cpy + strlen(cpy)); + file = fcreate(cpy, VFILE_DEVICE, pci_write_file, pci_read_file); + } + file->id = (uint32_t)slot | ((uint32_t)func << 8) | ((uint32_t)bus << 16); +} + +void pci_read_funcs(uint8_t bus, uint8_t slot){ + for(uint16_t i = 1; i < 256; i++){ + //read each function of device + uint32_t vendor = pci_read_config(bus, slot, i, 0); + if(vendor != 0xffff){ + uint16_t device = pci_read_config(bus, slot, i, 2); + uint16_t header = pci_read_config(bus, slot, i, 0xe); + uint16_t class = pci_read_config(bus, slot, i, 0xa); + mlog(MODULE_NAME, "Device found! Func: %d, Vendor: %x, Device: %x, Class: %x, Header: %x\n", MLOG_PRINT, i, vendor, device, class, header); + pci_make_file(class, bus, slot, i); + } + + } +} + uint16_t pci_get_vendor(uint8_t bus, uint8_t slot){ uint16_t vendor = 0, device = 0; vendor = pci_read_config(bus, slot, 0, 0); if(vendor != 0xffff){ device = pci_read_config(bus, slot, 0, 2); + uint16_t header = pci_read_config(bus, slot, 0, 0xe); uint16_t class = pci_read_config(bus, slot, 0, 0xa); - mlog(MODULE_NAME, "Device found! Vendor: %x, Device: %x, Class: %x\n", MLOG_PRINT, vendor, device, class); + mlog(MODULE_NAME, "Device found! Vendor: %x, Device: %x, Class: %x, Header: %x\n", MLOG_PRINT, vendor, device, class, header); + if(header & 0x80){ + pci_read_funcs(bus, slot); + } + pci_make_file(class, bus, slot, 0); } return vendor; } @@ -30,6 +110,11 @@ void pci_enumerate_bus(uint8_t bus){ void pci_init(){ mlog(MODULE_NAME, "Enumerating PCI Buses\n", MLOG_PRINT); + vfile_t *file = fcreate("dev/pci/", VFILE_DIRECTORY, kmalloc(1), 1); + fcreate("dev/pci/disk", VFILE_DIRECTORY, kmalloc(1), 1); + fcreate("dev/pci/net", VFILE_DIRECTORY, kmalloc(1), 1); + fcreate("dev/pci/video", VFILE_DIRECTORY, kmalloc(1), 1); + fcreate("dev/pci/bridge", VFILE_DIRECTORY, kmalloc(1), 1); for(uint32_t i = 0 ; i < 256; i++){ pci_enumerate_bus(i); } diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index a2ed1b9..1e7b013 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -20,6 +20,8 @@ void sysinit(){ mlog("KERNEL", "PID 1 Started\n", MLOG_PRINT); pci_init(); modules_init(boot_info); + vfile_t *file; + //fopen shell file & execute it. for(;;); } extern void kmain(kernel_info_t *kernel_info){ @@ -33,7 +35,7 @@ extern void kmain(kernel_info_t *kernel_info){ vfs_init(); fcreate("/dev", VFILE_DIRECTORY, kmalloc(1), 1); - fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1); + fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1); mlog("KERNEL", "Initializing Scheduler & starting PID 1\n", MLOG_PRINT); boot_info = kernel_info; diff --git a/src/kernel/system/modules.c b/src/kernel/system/modules.c index 13dbd3c..979eeb6 100644 --- a/src/kernel/system/modules.c +++ b/src/kernel/system/modules.c @@ -1,6 +1,7 @@ #include "modules.h" #include "../shared/kstdlib.h" #include "elf.h" +#include "vfs.h" #include "../shared/memory.h" #include @@ -46,19 +47,32 @@ uint32_t module_api(uint32_t func, ...){ vmlog(name, string, MLOG_PRINT, vars); break; case MODULE_API_READ: - return_value = -1; + vfile_t *file = va_arg(vars, vfile_t *); + char *buffer = va_arg(vars, char *); + uint32_t offset = va_arg(vars, uint32_t), count = va_arg(vars, uint32_t); + return_value = fread(file, buffer, offset, count); break; case MODULE_API_WRITE: - return_value = -1; + file = va_arg(vars, vfile_t *); + buffer = va_arg(vars, char *); + offset = va_arg(vars, uint32_t), count = va_arg(vars, uint32_t); + return_value = fwrite(file, buffer, offset, count); break; case MODULE_API_CREAT: - return_value = -1; + name = va_arg(vars, char *); + VFILE_TYPE ftype = va_arg(vars, VFILE_TYPE); + void *arg1, *arg2; + arg1 = va_arg(vars, void *); + arg2 = va_arg(vars, void *); + return_value = (uint32_t)fcreate(name, ftype, arg1, arg2); break; case MODULE_API_DELET: return_value = -1; break; case MODULE_API_OPEN: - return_value = -1; + name = va_arg(vars, char *); + file = va_arg(vars, vfile_t *); + return_value = fopen(name, file); break; case MODULE_API_MAP: return_value = -1; diff --git a/src/kernel/system/vfs.c b/src/kernel/system/vfs.c index 80f9ad2..1ca95c2 100644 --- a/src/kernel/system/vfs.c +++ b/src/kernel/system/vfs.c @@ -87,6 +87,7 @@ vfile_t *fcreate(char *name, VFILE_TYPE type, ...){ vfile->access.funcs.write = write; vfile->access.funcs.read = read; // strcpy + add_file(vfile, current_dir); break; } return vfile; //allow drivers to make last minute changes before it's sent to the user @@ -97,16 +98,16 @@ vfile_t *fcreate(char *name, VFILE_TYPE type, ...){ break; case VFILE_MOUNT: ((mount_t*)(tmpfile->access.data.ptr))->create(name + filename_offset, type == VFILE_DIRECTORY ? FS_FILE_IS_DIR : 0); - return; + return (void *)-1; default: - mlog(MODULE_NAME, "Error: Cannot create file with same name as another file! %d\n", MLOG_ERR, tmpfile->type); - return; + // mlog(MODULE_NAME, "Error: Cannot create file with same name as another file! %d\n", MLOG_ERR, tmpfile->type); + return 0; break; } filename_offset += strlen(tmp) + 1; tmp = strtok(0, '/'); } - return; + return 0; } //who needs a way to delete things? @@ -165,7 +166,7 @@ vfile_t *search_dir(char *name, vfile_t dir){ return 0; } -int fopen(char *name, vfile_t *file){ +int fopen(char *name, vfile_t **file){ char *dir = strtok(name, '/'); char *tmp = dir; uint32_t filename_offset = 0; @@ -184,12 +185,12 @@ int fopen(char *name, vfile_t *file){ case VFILE_MOUNT: return ((mount_t*)(tmpfile->access.data.ptr))->open(name + filename_offset, file); default: - *file = *tmpfile; + *file = tmpfile; return 0; } filename_offset += strlen(tmp) + 1; tmp = strtok(0, '/'); } - *file = *tmpfile; + *file = tmpfile; return 0; } \ No newline at end of file diff --git a/src/kernel/system/vfs.h b/src/kernel/system/vfs.h index 85da1ae..93595b4 100644 --- a/src/kernel/system/vfs.h +++ b/src/kernel/system/vfs.h @@ -2,12 +2,13 @@ #include typedef enum vfile_type{ - VFILE_POINTER, + VFILE_POINTER,//virtual files VFILE_DEVICE, VFILE_MOUNT,//in the pointer passed to the function, must specify a read, write, open, create, and delete function. VFILE_DIRECTORY, VFILE_PDIR,//used for directories in physical filesystems. - VFILE_FILE + VFILE_FILE,//physical files + VFILE_PIPE //yay we have pipes }VFILE_TYPE; //this code is gonna be ***really*** unsafe @@ -16,6 +17,8 @@ typedef struct virtual_file{ VFILE_TYPE type; uint32_t id;//to be assigned by driver; uint32_t mount_id; + uint8_t lock; + uint32_t size; struct virtual_file *parent;//should point to A: a virtual directory, or B: a mounted filesystem union{ struct{ @@ -40,7 +43,7 @@ typedef enum fs_flags{ typedef struct mount_funcs{ int (*write)(vfile_t *file, void *data, uint32_t offset, uint32_t count); int (*read)(vfile_t *file, void *data, uint32_t offset, uint32_t count); - int (*open)(char *filename, vfile_t *file); + int (*open)(char *filename, vfile_t **file); void (*delete)(vfile_t *file); void (*create)(char *filename, FS_FILE_FLAGS flags); }mount_t; @@ -51,4 +54,4 @@ void fdelete(); int fwrite(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count); int fread(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count); vfile_t *search_dir(char *name, vfile_t dir); -int fopen(char *name, vfile_t *file); \ No newline at end of file +int fopen(char *name, vfile_t **file); \ No newline at end of file