From 6266a24cd2f71a0bad0e55c1eedd480790868c0f Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 2 Mar 2010 17:21:32 +0100 Subject: old uncommited changes commited --- src/kernel/task/idt.c | 25 +++++++++++++++++++------ src/kernel/task/idt.h | 3 ++- src/kernel/task/syscall.c | 2 ++ src/kernel/task/task.c | 18 +++++++++++++++--- src/kernel/task/task.h | 5 ++++- 5 files changed, 42 insertions(+), 11 deletions(-) (limited to 'src/kernel/task') diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.c index 72a3d54..cff4ae9 100644 --- a/src/kernel/task/idt.c +++ b/src/kernel/task/idt.c @@ -65,6 +65,7 @@ struct idt_entry idt_entries[256]; struct idt_ptr idt_ptr; static int_callback irq_handlers[16] = {0}; +static struct thread* irq_wakeup[16] = {0}; void idt_isrHandler(struct registers regs) { if ((regs.int_no == 14 && paging_fault(®s) != 0) || regs.int_no != 14) { @@ -80,16 +81,18 @@ void idt_isrHandler(struct registers regs) { } void idt_irqHandler(struct registers regs) { - uint32_t doSwitch = 0; - doSwitch |= (regs.int_no == 32); //IRQ0 = timer + uint32_t doSwitch = (regs.err_code == 0); //IRQ0 = timer if (regs.err_code > 7) { outb(0xA0, 0x20); } outb(0x20, 0x20); + if (irq_wakeup[regs.err_code] != 0) { + irq_wakeup[regs.err_code]->state = TS_RUNNING; + irq_wakeup[regs.err_code] = 0; + doSwitch = 1; + } if (irq_handlers[regs.err_code] != 0) { irq_handlers[regs.err_code](®s); - } else { - monitor_write("Unhandled IRQ "); monitor_writeHex(regs.int_no - 32); monitor_write("\n"); } if (doSwitch) tasking_switch(); } @@ -98,7 +101,7 @@ void idt_syscallHandler(struct registers regs) { if (syscalls[regs.eax] != 0) { syscalls[regs.eax](®s); } else { - PANIC("unhandled syscall"); + monitor_write("Unhandled syscall...\n"); } } @@ -187,5 +190,15 @@ void idt_init() { } void idt_handleIrq(int number, int_callback func) { - irq_handlers[number] = func; + if (number < 16 && number >= 0) { + irq_handlers[number] = func; + } +} + +void idt_waitIrq(int number) { + if (number < 16 && number >= 0 && proc_priv() <= PL_DRIVER) { + irq_wakeup[number] = current_thread; + current_thread->state = TS_WAKEWAIT; + tasking_schedule(); + } } diff --git a/src/kernel/task/idt.h b/src/kernel/task/idt.h index bb89013..ed37eb0 100644 --- a/src/kernel/task/idt.h +++ b/src/kernel/task/idt.h @@ -27,7 +27,8 @@ struct registers { typedef void (*int_callback)(struct registers*); void idt_init(); -void idt_handleIrq(int number, int_callback func); +void idt_handleIrq(int number, int_callback func); //Set IRQ handler +void idt_waitIrq(int number); //ask current thread to wait for IRQ #endif diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index 8195dd0..752864c 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -14,6 +14,7 @@ CALL0V(tasking_switch, schedule_sc); CALL1V(thread_sleep, thread_sleep_sc); CALL1V(process_exit, process_exit_sc); CALL1(monitor_write, printk_sc); +CALL1V(idt_waitIrq, irq_wait_sc); static void thread_new_sc(struct registers* r) { thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx); @@ -26,4 +27,5 @@ int_callback syscalls[] = { process_exit_sc, printk_sc, thread_new_sc, + irq_wait_sc, 0 }; diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 8cdf7b3..622eaa1 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -88,6 +88,10 @@ void tasking_switch() { : : "r"(current_thread->ebp), "r"(current_thread->esp), "r"(current_thread->eip)); } +void tasking_schedule() { + asm volatile("int $64" : : "a"(1)); +} + void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablephysical) { if (idx < 896) return; struct process* it = processes; @@ -121,7 +125,12 @@ void thread_sleep(uint32_t msecs) { if (current_thread == 0) return; current_thread->state = TS_SLEEPING; current_thread->timeWait = timer_time() + msecs; - asm volatile("int $64" : : "a"(1)); + tasking_schedule(); +} + +int proc_priv() { + if (current_thread == 0) return PL_UNKNOWN; + return current_thread->process->privilege; } void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h @@ -167,7 +176,10 @@ void process_exit(uint32_t retval) { static uint32_t thread_runnable(struct thread *t) { if (t->state == TS_RUNNING) return 1; - if (t->state == TS_SLEEPING && timer_time() >= t->timeWait) return 1; + if (t->state == TS_SLEEPING && timer_time() >= t->timeWait) { + t->state = TS_RUNNING; + return 1; + } return 0; } @@ -220,7 +232,7 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void * if (proc->privilege >= PL_SERVICE) { //We are running in user mode proc->stacksBottom -= USER_STACK_SIZE; - t->userStack_seg = seg_map(simpleseg_make(proc->stacksBottom, USER_STACK_SIZE, 1), proc->pagedir); + t->userStack_seg = seg_map(simpleseg_make(proc->stacksBottom, USER_STACK_SIZE, 1), proc->pagedir, 0); } t->kernelStack_addr = kmalloc(KSTACKSIZE); diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index d363333..dd5461e 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -7,8 +7,9 @@ #define TS_RUNNING 0 #define TS_SLEEPING 1 //Sleeping for a defined amount of time -#define TS_WAIKWAIT 2 //Waiting to be waked up by something precise (thread currently blocked) +#define TS_WAKEWAIT 2 //Waiting to be waked up by something precise (thread currently blocked) +#define PL_UNKNOWN 4 #define PL_USER 3 #define PL_SERVICE 2 #define PL_DRIVER 1 @@ -47,10 +48,12 @@ extern struct thread *current_thread; void tasking_init(); void tasking_switch(); +void tasking_schedule(); void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablePhysical); uint32_t tasking_handleException(struct registers *regs); void thread_sleep(uint32_t msecs); +int proc_priv(); //Returns current privilege level void thread_exit(); void process_exit(uint32_t retval); struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data); -- cgit v1.2.3