226 lines
7.7 KiB
C
226 lines
7.7 KiB
C
#include "modules.h"
|
|
#include "../shared/kstdlib.h"
|
|
#include "elf.h"
|
|
#include "vfs.h"
|
|
#include "../shared/memory.h"
|
|
#include "scheduler.h"
|
|
#include <stdarg.h>
|
|
|
|
#define MODULE_NAME "MLOADER"
|
|
|
|
vector_t *modules;
|
|
vector_t *module_deps;
|
|
|
|
uint32_t module_api(uint32_t func, ...){
|
|
va_list vars;
|
|
va_start(vars, func);
|
|
uint32_t return_value = 0;
|
|
switch(func){
|
|
case MODULE_API_REGISTER:
|
|
//do something
|
|
module_t *structure = va_arg(vars, void *);
|
|
if(structure == 0){
|
|
return_value = -1;
|
|
}
|
|
uint32_t tmp = pm_alloc();
|
|
(structure->key) = (modules->size ^ 190507) + tmp << 12 ^ 4405648937 ^ 8592807313 >> 5;
|
|
structure->key &= (0xffffff00 | modules->size);
|
|
vector_push(modules, structure);
|
|
pm_free(tmp);
|
|
return_value = 0;
|
|
break;
|
|
case MODULE_API_ADDINT:
|
|
uint32_t int_index = va_arg(vars, uint32_t);
|
|
uint32_t key = va_arg(vars, uint32_t);
|
|
void *interrupt_handler = va_arg(vars, void *);
|
|
if(int_index >= 16 || int_index < 0 /* || get_irq_handler(int_index)*/){
|
|
|
|
return_value = -1;
|
|
break;
|
|
}
|
|
install_irq_handler(interrupt_handler, int_index);
|
|
module_t *tmpmodule = vector_get(key & 0xff, modules);
|
|
tmpmodule->interrupts |= 1 << int_index;
|
|
return_value = 0;
|
|
break;
|
|
case MODULE_API_DELINT:
|
|
int_index = va_arg(vars, uint32_t);
|
|
key = va_arg(vars, uint32_t);
|
|
tmpmodule = vector_get(key & 0xff, modules);
|
|
if(key == tmpmodule->key){
|
|
install_irq_handler(0, int_index);
|
|
tmpmodule->interrupts &= ~(1 << int_index);
|
|
}
|
|
else{
|
|
return_value = -1;
|
|
break;
|
|
}
|
|
return_value = 0;
|
|
break;
|
|
case MODULE_API_PRINT:
|
|
char *name = va_arg(vars, char *);
|
|
char *string = va_arg(vars, char *);
|
|
vmlog(name, string, MLOG_PRINT, vars);
|
|
break;
|
|
case MODULE_API_READ:
|
|
vfile_t *file = va_arg(vars, vfile_t *);
|
|
char *buffer = va_arg(vars, char *);
|
|
uint32_t offset = va_arg(vars, uint32_t);
|
|
uint32_t count = va_arg(vars, uint32_t);
|
|
return_value = fread(file, buffer, offset, count);
|
|
break;
|
|
case MODULE_API_WRITE:
|
|
file = va_arg(vars, vfile_t *);
|
|
buffer = va_arg(vars, char *);
|
|
offset = va_arg(vars, uint32_t), count = va_arg(vars, uint32_t);
|
|
count = va_arg(vars, uint32_t);
|
|
return_value = fwrite(file, buffer, offset, count);
|
|
break;
|
|
case MODULE_API_CREAT:
|
|
name = va_arg(vars, char *);
|
|
FS_FILE_FLAGS ftype = va_arg(vars, FS_FILE_FLAGS);
|
|
void *arg1, *arg2;
|
|
arg1 = va_arg(vars, void *);
|
|
arg2 = va_arg(vars, void *);
|
|
return_value = (uint32_t)fcreate(name, ftype);
|
|
break;
|
|
case MODULE_API_DELET:
|
|
file = va_arg(vars, vfile_t *);
|
|
return_value = fdelete(file);
|
|
break;
|
|
case MODULE_API_OPEN:
|
|
name = va_arg(vars, char *);
|
|
return_value = (uint32_t)fopen(name);
|
|
break;
|
|
case MODULE_API_READDIR:
|
|
file = va_arg(vars, vfile_t *);
|
|
buffer = va_arg(vars, void *);
|
|
offset = va_arg(vars, uint32_t);
|
|
count = va_arg(vars, uint32_t);
|
|
// return_value = readdir(file, buffer, offset, count);
|
|
return_value = 0;
|
|
break;
|
|
case MODULE_API_MAP:
|
|
return_value = 0;
|
|
void *vaddr = va_arg(vars, void *);
|
|
void *paddr = va_arg(vars, void *);
|
|
uint32_t flags = va_arg(vars, uint32_t);
|
|
map(vaddr, paddr, flags);
|
|
break;
|
|
case MODULE_API_UNMAP:
|
|
vaddr = va_arg(vars, void *);
|
|
unmap(vaddr);
|
|
break;
|
|
case MODULE_API_PADDR:
|
|
void *addr = va_arg(vars, void *);
|
|
return_value = get_paddr(addr);
|
|
break;
|
|
case MODULE_API_MALLOC:
|
|
uint32_t sz_pgs = va_arg(vars, uint32_t);
|
|
return_value = (uint32_t)kmalloc(sz_pgs);
|
|
break;
|
|
case MODULE_API_FREE:
|
|
void *ptr = va_arg(vars, void *);
|
|
kfree(ptr);
|
|
return_value = 0;
|
|
break;
|
|
case MODULE_API_PMALLOC64K:
|
|
return_value = pm_alloc_64kaligned();
|
|
break;
|
|
case MODULE_API_KMALLOC_PADDR:
|
|
paddr = (void *)va_arg(vars, uint32_t);
|
|
uint32_t size = va_arg(vars, uint32_t);
|
|
return_value = (uint32_t)kmalloc_page_paddr((uint32_t)paddr, size);
|
|
break;
|
|
case MODULE_MESSAGE_HANDLER:
|
|
key = va_arg(vars, uint32_t);
|
|
void *handler = va_arg(vars, void (*)());
|
|
for(int i = 0; i < modules->size; i++){
|
|
module_t* module = ((module_t *)vector_get(i, modules));
|
|
if(module->key == key){
|
|
module->message_handler = handler;
|
|
return_value = 0;
|
|
break;
|
|
}
|
|
return_value = -1;
|
|
}
|
|
break;
|
|
case MODULE_API_BLOCK_PID:
|
|
uint32_t pid = va_arg(vars, uint32_t);
|
|
set_pid_blocked(pid);
|
|
break;
|
|
case MODULE_API_UNBLOCK_PID:
|
|
pid = va_arg(vars, uint32_t);
|
|
set_pid_unblocked(pid);
|
|
break;
|
|
case MODULE_API_GET_CPID:
|
|
return_value = get_current_pid();
|
|
break;
|
|
case MODULE_API_IS_INTERRUPT:
|
|
return get_in_interrupt();
|
|
break;
|
|
}
|
|
va_end(vars);
|
|
return return_value;
|
|
}
|
|
|
|
|
|
|
|
uint32_t dispatch_message(uint32_t message, ...){
|
|
va_list args;
|
|
va_start(args, message);
|
|
|
|
for(int i = 0; i < modules->size; i++){
|
|
module_t *module = vector_get(i, modules);
|
|
uint32_t key = module->key;
|
|
int32_t (*handler)(uint32_t, ...) = module->message_handler;
|
|
if(!handler) continue;
|
|
int32_t result = 0;
|
|
|
|
vfile_t *srcfile;
|
|
char *destname;
|
|
uint32_t offset;
|
|
|
|
switch(message){
|
|
case MESSAGE_MOUNT_FS:
|
|
srcfile = va_arg(args, vfile_t *);
|
|
destname = va_arg(args, char *);
|
|
offset = va_arg(args, uint32_t);
|
|
|
|
result = handler(message, srcfile, destname, offset);
|
|
break;
|
|
}
|
|
if((int32_t) message >= 0 && result){
|
|
va_end(args);
|
|
return result;
|
|
}
|
|
}
|
|
va_end(args);
|
|
return 0;
|
|
}
|
|
|
|
void module_start(void *ptr){
|
|
void (*entry)(void* api, uint32_t version) = load_elf(ptr, PT_SYS);
|
|
(*entry)(module_api, 0);
|
|
}
|
|
void modules_init(){
|
|
mlog(MODULE_NAME, "Initializing Boot-Time Modules\n", MLOG_PRINT);
|
|
// kernel_module_t *module = kernel_info->loaded_modules;
|
|
// uint32_t i = 0;
|
|
modules = init_vector(0, sizeof(module_t), 0, 0);
|
|
// while(module){
|
|
// if(!module->ptr){
|
|
// continue;
|
|
// }
|
|
// if(module->flags & MODULE_INITRC){
|
|
// fcreate("initrc", VFILE_POINTER, module->ptr, 1);
|
|
// continue;
|
|
// }
|
|
// void (*entry)(void* api, uint32_t version) = load_elf(module->ptr, PT_SYS);
|
|
// mlog(MODULE_NAME, "Loaded module with ID %x\n", MLOG_PRINT, module->id);
|
|
// // module->type |= 0x8000;//set present flag in type
|
|
// module->flags |= MODULE_PRESENT;
|
|
// module = module->link;
|
|
// (*entry)(module_api, 0);
|
|
// }
|
|
} |