Updated module API and disk_driver.c:ata_read()/ata_write() to be asynchronous
This commit is contained in:
parent
ece6e9c1d0
commit
b24125657c
|
|
@ -3,6 +3,12 @@
|
||||||
#include "../drivers/cpuio.h"
|
#include "../drivers/cpuio.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint8_t in_interrupt = 0;
|
||||||
|
|
||||||
|
uint8_t get_in_interrupt(){
|
||||||
|
return in_interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
extern void _isr0();
|
extern void _isr0();
|
||||||
extern void _isr1();
|
extern void _isr1();
|
||||||
extern void _isr2();
|
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){
|
cpu_registers_t *_irq_handler(cpu_registers_t *regs){
|
||||||
|
in_interrupt = 1;
|
||||||
regs->esp = (uint32_t)regs;
|
regs->esp = (uint32_t)regs;
|
||||||
if(regs->int_no == 0x80){
|
if(regs->int_no == 0x80){
|
||||||
regs = syscall(regs);
|
regs = syscall(regs);
|
||||||
|
|
@ -82,6 +89,7 @@ cpu_registers_t *_irq_handler(cpu_registers_t *regs){
|
||||||
if(regs->int_no >= 0x28){
|
if(regs->int_no >= 0x28){
|
||||||
outb(0xa0, 0x20);
|
outb(0xa0, 0x20);
|
||||||
}
|
}
|
||||||
|
in_interrupt = 0;
|
||||||
return regs;
|
return regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,4 +31,5 @@ inline void disable_interrupts(){
|
||||||
}
|
}
|
||||||
void kernel_panic(char *msg, cpu_registers_t *regs);
|
void kernel_panic(char *msg, cpu_registers_t *regs);
|
||||||
void install_irq_handler(void (*handler)(), uint8_t irqno);
|
void install_irq_handler(void (*handler)(), uint8_t irqno);
|
||||||
void *get_irq_handler(uint8_t irqno);
|
void *get_irq_handler(uint8_t irqno);
|
||||||
|
uint8_t get_in_interrupt();
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "../shared/memory.h"
|
#include "../shared/memory.h"
|
||||||
|
#include "scheduler.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define MODULE_NAME "MLOADER"
|
#define MODULE_NAME "MLOADER"
|
||||||
|
|
@ -23,7 +24,7 @@ uint32_t module_api(uint32_t func, ...){
|
||||||
}
|
}
|
||||||
uint32_t tmp = pm_alloc();
|
uint32_t tmp = pm_alloc();
|
||||||
(structure->key) = (modules->size ^ 190507) + tmp << 12 ^ 4405648937 ^ 8592807313 >> 5;
|
(structure->key) = (modules->size ^ 190507) + tmp << 12 ^ 4405648937 ^ 8592807313 >> 5;
|
||||||
structure->key & 0xffffff00 | modules->size;
|
structure->key &= 0xffffff00 | modules->size;
|
||||||
vector_push(modules, structure);
|
vector_push(modules, structure);
|
||||||
pm_free(tmp);
|
pm_free(tmp);
|
||||||
return_value = 0;
|
return_value = 0;
|
||||||
|
|
@ -138,6 +139,20 @@ uint32_t module_api(uint32_t func, ...){
|
||||||
return_value = -1;
|
return_value = -1;
|
||||||
}
|
}
|
||||||
break;
|
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);
|
va_end(vars);
|
||||||
return return_value;
|
return return_value;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ enum MODULE_API_FUNCS{
|
||||||
MODULE_API_PMALLOC64K,
|
MODULE_API_PMALLOC64K,
|
||||||
MODULE_API_KMALLOC_PADDR,
|
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 struct module{
|
typedef struct module{
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,18 @@ void kill(uint32_t pid){
|
||||||
processes[pid].page_dir = 0;
|
processes[pid].page_dir = 0;
|
||||||
remove_process_queue(pid);
|
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)()){
|
uint32_t thread_start(void (*function)()){
|
||||||
cpu_registers_t regs = {0};
|
cpu_registers_t regs = {0};
|
||||||
regs.cs = 0x10;
|
regs.cs = 0x10;
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,7 @@ cpu_registers_t* schedule(cpu_registers_t *regs);
|
||||||
void scheduler_init();
|
void scheduler_init();
|
||||||
uint32_t thread_start(void (*function)());
|
uint32_t thread_start(void (*function)());
|
||||||
void thread_join(uint32_t thread_id, uint32_t *exit_code);
|
void thread_join(uint32_t thread_id, uint32_t *exit_code);
|
||||||
void thread_exit(uint32_t exit_code);
|
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();
|
||||||
|
|
@ -139,6 +139,7 @@ enum DRIVE_TYPE{
|
||||||
uint32_t volatile transferring_disk_index = -1;
|
uint32_t volatile transferring_disk_index = -1;
|
||||||
uint32_t expected_ints = 0;
|
uint32_t expected_ints = 0;
|
||||||
uint32_t recieved_ints = 0;
|
uint32_t recieved_ints = 0;
|
||||||
|
uint32_t transferring_pid = 0;
|
||||||
|
|
||||||
typedef struct drive_desc{
|
typedef struct drive_desc{
|
||||||
uint32_t BARs[8];
|
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;
|
static uint16_t last_bar = 0;
|
||||||
if(last_disk != drive && last_bar != BAR){
|
if(last_disk != drive && last_bar != BAR){
|
||||||
last_disk = drive;
|
last_disk = drive;
|
||||||
last_bar == BAR;
|
last_bar = BAR;
|
||||||
outb(BAR + ATA_DRIVE_HEAD, drive);
|
outb(BAR + ATA_DRIVE_HEAD, drive);
|
||||||
}
|
}
|
||||||
for(uint32_t i = 0; i < 4; i++){
|
for(uint32_t i = 0; i < 4; i++){
|
||||||
uint8_t _ = inb(BAR2 + ATA_STATUS);
|
uint8_t _ = inb(BAR2 + ATA_STATUS);
|
||||||
}
|
}
|
||||||
uint8_t status = inb(BAR2 ATA_ALT_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){
|
void ata_reset(uint16_t bar1){
|
||||||
|
|
@ -186,6 +188,7 @@ uint32_t find_free_drive(){
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
|
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 (transferring_disk_index != -1);
|
||||||
while(ATA_BSY(status)){
|
//!TODO! SUPER IMPORTANT!!!! MARK CURRENT THREAD AS BLOCKED AND RE-ENTER AFTER IRQ IS FIRED
|
||||||
status = inb(io_base + ATA_STATUS);
|
// 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;
|
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 (transferring_disk_index != -1);
|
||||||
while(ATA_BSY(status)){
|
// while(ATA_BSY(status)){
|
||||||
status = inb(io_base + ATA_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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_registers_t *int_handler(cpu_registers_t * regs){
|
cpu_registers_t *int_handler(cpu_registers_t * regs){
|
||||||
|
if(transferring_disk_index == -1){
|
||||||
|
return regs;
|
||||||
|
}
|
||||||
drive_t drive = drives[transferring_disk_index];
|
drive_t drive = drives[transferring_disk_index];
|
||||||
uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3);
|
uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3);
|
||||||
uint32_t status = inb(dmabar + 2);
|
uint32_t status = inb(dmabar + 2);
|
||||||
|
|
@ -380,6 +400,9 @@ cpu_registers_t *int_handler(cpu_registers_t * regs){
|
||||||
return regs;
|
return regs;
|
||||||
}
|
}
|
||||||
transferring_disk_index = -1;
|
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;
|
return regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -480,18 +503,30 @@ uint8_t ata_identify(uint32_t index, uint16_t disk){
|
||||||
itoa(ata_drives, fname + strlen(fname), 10);
|
itoa(ata_drives, fname + strlen(fname), 10);
|
||||||
vfile_t *new_file = fcreate(api, fname, VFILE_DEVICE, ata_write, ata_read);
|
vfile_t *new_file = fcreate(api, fname, VFILE_DEVICE, ata_write, ata_read);
|
||||||
new_file->mount_id = index;
|
new_file->mount_id = index;
|
||||||
free(api, fname);
|
// free(api, fname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ide_init(uint32_t BARS[5]){
|
void ide_init(uint32_t BARS[5]){
|
||||||
uint32_t primary_index = find_free_drive();
|
uint32_t primary_index = find_free_drive();
|
||||||
|
if(primary_index == -1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
drives[primary_index].type = TYPE_TMP;
|
drives[primary_index].type = TYPE_TMP;
|
||||||
uint32_t primary_slave_index = find_free_drive();
|
uint32_t primary_slave_index = find_free_drive();
|
||||||
|
if(primary_slave_index == -1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
drives[primary_slave_index].type = TYPE_TMP;
|
drives[primary_slave_index].type = TYPE_TMP;
|
||||||
uint32_t secondary_index = find_free_drive();
|
uint32_t secondary_index = find_free_drive();
|
||||||
|
if(secondary_index == -1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
drives[secondary_index].type = TYPE_TMP;
|
drives[secondary_index].type = TYPE_TMP;
|
||||||
uint32_t secondary_slave_index = find_free_drive();
|
uint32_t secondary_slave_index = find_free_drive();
|
||||||
|
if(secondary_slave_index == -1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
drives[secondary_slave_index].type = TYPE_TMP;
|
drives[secondary_slave_index].type = TYPE_TMP;
|
||||||
for(int i = 0; i < 2; i++){
|
for(int i = 0; i < 2; i++){
|
||||||
drives[primary_index].BARs[i] = BARS[i];
|
drives[primary_index].BARs[i] = BARS[i];
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,11 @@ enum MODULE_API_FUNCS{
|
||||||
MODULE_API_FREE, //free memory allocated by malloc
|
MODULE_API_FREE, //free memory allocated by malloc
|
||||||
MODULE_API_PMALLOC64K,
|
MODULE_API_PMALLOC64K,
|
||||||
MODULE_API_KMALLOC_PADDR,
|
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, ...);
|
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){
|
inline void puts(KOS_MAPI_FP api, char *mname, char *str){
|
||||||
api(MODULE_API_PRINT, mname, str);
|
api(MODULE_API_PRINT, mname, str);
|
||||||
};
|
};
|
||||||
|
inline uint8_t is_interrupt(KOS_MAPI_FP api){
|
||||||
|
return api(MODULE_API_IS_INTERRUPT);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue