(mostly) finished PCI implementation, will flesh it out more as needed. (100th commit\!\!\!)

This commit is contained in:
notsomeidiot123 2025-09-15 12:50:18 -04:00
parent 8a82600f5f
commit a5af6c51da
5 changed files with 123 additions and 18 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -1,6 +1,7 @@
#include "modules.h"
#include "../shared/kstdlib.h"
#include "elf.h"
#include "vfs.h"
#include "../shared/memory.h"
#include <stdarg.h>
@ -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;

View File

@ -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;
}

View File

@ -2,12 +2,13 @@
#include <stdint.h>
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);
int fopen(char *name, vfile_t **file);