(mostly) finished PCI implementation, will flesh it out more as needed. (100th commit\!\!\!)
This commit is contained in:
parent
8a82600f5f
commit
a5af6c51da
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
Loading…
Reference in New Issue