diff --git a/src/kernel/arch_i386/interrupts.c b/src/kernel/arch_i386/interrupts.c index 378ce83..1175872 100644 --- a/src/kernel/arch_i386/interrupts.c +++ b/src/kernel/arch_i386/interrupts.c @@ -3,6 +3,12 @@ #include "../drivers/cpuio.h" #include +uint8_t in_interrupt = 0; + +uint8_t get_in_interrupt(){ + return in_interrupt; +} + extern void _isr0(); extern void _isr1(); extern void _isr2(); @@ -67,6 +73,7 @@ inline void set_idt_entry(uint32_t index, void *ptr, uint8_t flags, uint16_t seg cpu_registers_t *_irq_handler(cpu_registers_t *regs){ + in_interrupt = 1; regs->esp = (uint32_t)regs; if(regs->int_no == 0x80){ regs = syscall(regs); @@ -82,6 +89,7 @@ cpu_registers_t *_irq_handler(cpu_registers_t *regs){ if(regs->int_no >= 0x28){ outb(0xa0, 0x20); } + in_interrupt = 0; return regs; } diff --git a/src/kernel/shared/interrupts.h b/src/kernel/shared/interrupts.h index 73aa3a6..77b3987 100644 --- a/src/kernel/shared/interrupts.h +++ b/src/kernel/shared/interrupts.h @@ -31,4 +31,5 @@ inline void disable_interrupts(){ } void kernel_panic(char *msg, cpu_registers_t *regs); void install_irq_handler(void (*handler)(), uint8_t irqno); -void *get_irq_handler(uint8_t irqno); \ No newline at end of file +void *get_irq_handler(uint8_t irqno); +uint8_t get_in_interrupt(); \ No newline at end of file diff --git a/src/kernel/system/modules.c b/src/kernel/system/modules.c index daa63fe..1e33138 100644 --- a/src/kernel/system/modules.c +++ b/src/kernel/system/modules.c @@ -3,6 +3,7 @@ #include "elf.h" #include "vfs.h" #include "../shared/memory.h" +#include "scheduler.h" #include #define MODULE_NAME "MLOADER" @@ -23,7 +24,7 @@ uint32_t module_api(uint32_t func, ...){ } uint32_t tmp = pm_alloc(); (structure->key) = (modules->size ^ 190507) + tmp << 12 ^ 4405648937 ^ 8592807313 >> 5; - structure->key & 0xffffff00 | modules->size; + structure->key &= 0xffffff00 | modules->size; vector_push(modules, structure); pm_free(tmp); return_value = 0; @@ -138,6 +139,20 @@ uint32_t module_api(uint32_t func, ...){ 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; diff --git a/src/kernel/system/modules.h b/src/kernel/system/modules.h index ee89489..33473b8 100644 --- a/src/kernel/system/modules.h +++ b/src/kernel/system/modules.h @@ -32,6 +32,10 @@ enum MODULE_API_FUNCS{ MODULE_API_PMALLOC64K, MODULE_API_KMALLOC_PADDR, MODULE_MESSAGE_HANDLER, + MODULE_API_BLOCK_PID, + MODULE_API_UNBLOCK_PID, + MODULE_API_GET_CPID, + MODULE_API_IS_INTERRUPT, }; typedef struct module{ diff --git a/src/kernel/system/scheduler.c b/src/kernel/system/scheduler.c index 9c2ad8e..720b04b 100644 --- a/src/kernel/system/scheduler.c +++ b/src/kernel/system/scheduler.c @@ -128,6 +128,18 @@ void kill(uint32_t pid){ processes[pid].page_dir = 0; remove_process_queue(pid); } + +void set_pid_blocked(uint32_t pid){ + processes[pid].flags.blocked = 1; + remove_process_queue(pid); +} +void set_pid_unblocked(uint32_t pid){ + processes[pid].flags.blocked = 0; + add_process_queue(pid); +} +uint32_t get_current_pid(){ + return current_pid; +} uint32_t thread_start(void (*function)()){ cpu_registers_t regs = {0}; regs.cs = 0x10; diff --git a/src/kernel/system/scheduler.h b/src/kernel/system/scheduler.h index 33ec2fd..b9713fb 100644 --- a/src/kernel/system/scheduler.h +++ b/src/kernel/system/scheduler.h @@ -27,4 +27,7 @@ cpu_registers_t* schedule(cpu_registers_t *regs); void scheduler_init(); uint32_t thread_start(void (*function)()); void thread_join(uint32_t thread_id, uint32_t *exit_code); -void thread_exit(uint32_t exit_code); \ No newline at end of file +void thread_exit(uint32_t exit_code); +void set_pid_blocked(uint32_t pid); +void set_pid_unblocked(uint32_t pid); +uint32_t get_current_pid(); \ No newline at end of file diff --git a/src/kmodules/disk_driver.c b/src/kmodules/disk_driver.c index bd3475d..3acb838 100644 --- a/src/kmodules/disk_driver.c +++ b/src/kmodules/disk_driver.c @@ -139,6 +139,7 @@ enum DRIVE_TYPE{ uint32_t volatile transferring_disk_index = -1; uint32_t expected_ints = 0; uint32_t recieved_ints = 0; +uint32_t transferring_pid = 0; typedef struct drive_desc{ uint32_t BARs[8]; @@ -162,14 +163,15 @@ int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){ static uint16_t last_bar = 0; if(last_disk != drive && last_bar != BAR){ last_disk = drive; - last_bar == BAR; + last_bar = BAR; outb(BAR + ATA_DRIVE_HEAD, drive); } for(uint32_t i = 0; i < 4; i++){ uint8_t _ = inb(BAR2 + ATA_STATUS); } uint8_t status = inb(BAR2 ATA_ALT_STATUS); - return (status >> 7) == 0; + // api(MODULE_API_PRINT, MODULE_NAME, "Status: %x", status); + return (status >> 7) == 0 && !((status >> 3) & 1); } void ata_reset(uint16_t bar1){ @@ -186,6 +188,7 @@ uint32_t find_free_drive(){ return i; } } + return -1; } int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){ @@ -267,10 +270,17 @@ int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){ // } // while (transferring_disk_index != -1); - while(ATA_BSY(status)){ - status = inb(io_base + ATA_STATUS); + //!TODO! SUPER IMPORTANT!!!! MARK CURRENT THREAD AS BLOCKED AND RE-ENTER AFTER IRQ IS FIRED + // while(ATA_BSY(status)){ + // status = inb(io_base + ATA_STATUS); + // } + uint32_t cpid = api(MODULE_API_GET_CPID); + api(MODULE_API_PRINT, MODULE_NAME, "Cpid: %x", cpid); + api(MODULE_API_BLOCK_PID, cpid); + transferring_pid = cpid; + if(!is_interrupt){ + asm("int $32\n"); } - outb(bm_base, 0x00); return 0; } @@ -355,15 +365,25 @@ int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count) { // } // while (transferring_disk_index != -1); - while(ATA_BSY(status)){ - status = inb(io_base + ATA_STATUS); + // while(ATA_BSY(status)){ + // status = inb(io_base + ATA_STATUS); + // } + // outb(bm_base, 0x00); + uint32_t cpid = api(MODULE_API_GET_CPID); + api(MODULE_API_PRINT, MODULE_NAME, "Cpid: %x", cpid); + api(MODULE_API_BLOCK_PID, cpid); + transferring_pid = cpid; + if(!is_interrupt){ + asm("int $32\n"); } - outb(bm_base, 0x00); return 0; } cpu_registers_t *int_handler(cpu_registers_t * regs){ + if(transferring_disk_index == -1){ + return regs; + } drive_t drive = drives[transferring_disk_index]; uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3); uint32_t status = inb(dmabar + 2); @@ -380,6 +400,9 @@ cpu_registers_t *int_handler(cpu_registers_t * regs){ return regs; } transferring_disk_index = -1; + outb(drives[transferring_disk_index].BARs[4] & ~3, 0x00); + api(MODULE_API_UNBLOCK_PID, transferring_pid); + transferring_pid = 0; return regs; } @@ -480,18 +503,30 @@ uint8_t ata_identify(uint32_t index, uint16_t disk){ itoa(ata_drives, fname + strlen(fname), 10); vfile_t *new_file = fcreate(api, fname, VFILE_DEVICE, ata_write, ata_read); new_file->mount_id = index; - free(api, fname); + // free(api, fname); return 1; } void ide_init(uint32_t BARS[5]){ uint32_t primary_index = find_free_drive(); + if(primary_index == -1){ + return; + } drives[primary_index].type = TYPE_TMP; uint32_t primary_slave_index = find_free_drive(); + if(primary_slave_index == -1){ + return; + } drives[primary_slave_index].type = TYPE_TMP; uint32_t secondary_index = find_free_drive(); + if(secondary_index == -1){ + return; + } drives[secondary_index].type = TYPE_TMP; uint32_t secondary_slave_index = find_free_drive(); + if(secondary_slave_index == -1){ + return; + } drives[secondary_slave_index].type = TYPE_TMP; for(int i = 0; i < 2; i++){ drives[primary_index].BARs[i] = BARS[i]; diff --git a/src/kmodules/modlib.h b/src/kmodules/modlib.h index bea5660..f21893e 100644 --- a/src/kmodules/modlib.h +++ b/src/kmodules/modlib.h @@ -21,7 +21,11 @@ enum MODULE_API_FUNCS{ MODULE_API_FREE, //free memory allocated by malloc MODULE_API_PMALLOC64K, MODULE_API_KMALLOC_PADDR, - MODULE_MESSAGE_HANDLER + MODULE_MESSAGE_HANDLER, + MODULE_API_BLOCK_PID, + MODULE_API_UNBLOCK_PID, + MODULE_API_GET_CPID, + MODULE_API_IS_INTERRUPT, }; typedef uint32_t (*KOS_MAPI_FP)(unsigned int function, ...); @@ -102,3 +106,6 @@ inline vfile_t *fcreate(KOS_MAPI_FP api, char *filename, VFILE_TYPE type, char * inline void puts(KOS_MAPI_FP api, char *mname, char *str){ api(MODULE_API_PRINT, mname, str); }; +inline uint8_t is_interrupt(KOS_MAPI_FP api){ + return api(MODULE_API_IS_INTERRUPT); +}