diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2014-12-07 20:11:06 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2014-12-07 20:11:06 +0100 |
commit | bd1ed224590700c7568dd6a73a2dadcda238b1d5 (patch) | |
tree | 65d1204bfd1ef486529c314f3c9f942bd728e78e | |
parent | f0475a3d517b4df8eb2b73f22eaec91a72bcc51f (diff) | |
download | kogata-bd1ed224590700c7568dd6a73a2dadcda238b1d5.tar.gz kogata-bd1ed224590700c7568dd6a73a2dadcda238b1d5.zip |
Information about current PD now stored in current_task->current_pd_d
-rw-r--r-- | kernel/include/task.h | 4 | ||||
-rw-r--r-- | kernel/l0/paging.c | 13 | ||||
-rw-r--r-- | kernel/l0/task.c | 9 |
3 files changed, 18 insertions, 8 deletions
diff --git a/kernel/include/task.h b/kernel/include/task.h index 8ba50b0..2c3f6ef 100644 --- a/kernel/include/task.h +++ b/kernel/include/task.h @@ -1,6 +1,7 @@ #pragma once #include <sys.h> +#include <paging.h> #include <region.h> #define T_STATE_RUNNING 1 @@ -9,6 +10,8 @@ #define KPROC_STACK_SIZE 0x8000 // 8Kb +#define TASK_SWITCH_FREQUENCY 100 // in herz + typedef struct saved_context { uint32_t *esp; void (*eip)(); @@ -16,6 +19,7 @@ typedef struct saved_context { typedef struct task { saved_context_t ctx; + pagedir_t *current_pd_d; uint32_t state; void* result; diff --git a/kernel/l0/paging.c b/kernel/l0/paging.c index 3f38997..93cbc38 100644 --- a/kernel/l0/paging.c +++ b/kernel/l0/paging.c @@ -4,6 +4,7 @@ #include <dbglog.h> #include <region.h> #include <mutex.h> +#include <task.h> #define PAGE_OF_ADDR(x) (((size_t)x >> PAGE_SHIFT) % N_PAGES_IN_PT) #define PT_OF_ADDR(x) ((size_t)x >> (PAGE_SHIFT + PT_SHIFT)) @@ -43,7 +44,6 @@ static pagetable_t __attribute__((aligned(PAGE_SIZE))) kernel_pt0; extern char kernel_stack_protector; static pagedir_t kernel_pd_d; -static pagedir_t *current_pd_d; #define current_pt ((pagetable_t*)PD_MIRROR_ADDR) #define current_pd ((pagetable_t*)(PD_MIRROR_ADDR + (N_PAGES_IN_PT-1)*PAGE_SIZE)) @@ -85,7 +85,7 @@ void page_fault_handler(registers_t *regs) { dbg_print_region_stats(); PANIC("Unhandled kernel space page fault"); } - i->pf(current_pd_d, i, vaddr); + i->pf(get_current_pagedir(), i, vaddr); } else { if (regs->eflags & EFLAGS_IF) asm volatile("sti"); // userspace PF handlers should always be preemptible @@ -131,7 +131,6 @@ void paging_setup(void* kernel_data_end) { invlpg((void*)K_HIGHHALF_ADDR); // paging already enabled in loader, nothing to do. - switch_pagedir(&kernel_pd_d); // disable 4M pages (remove PSE bit in CR4) uint32_t cr4; @@ -143,7 +142,8 @@ void paging_setup(void* kernel_data_end) { } pagedir_t *get_current_pagedir() { - return current_pd_d; + if (current_task == 0) return &kernel_pd_d; + return current_task->current_pd_d; } pagedir_t *get_kernel_pagedir() { @@ -152,7 +152,7 @@ pagedir_t *get_kernel_pagedir() { void switch_pagedir(pagedir_t *pd) { asm volatile("movl %0, %%cr3":: "r"(pd->phys_addr)); - current_pd_d = pd; + if (current_task != 0) current_task->current_pd_d = pd; } // ============================== // @@ -176,7 +176,8 @@ int pd_map_page(void* vaddr, uint32_t frame_id, bool rw) { ASSERT((size_t)vaddr < PD_MIRROR_ADDR); - pagedir_t *pdd = ((size_t)vaddr >= K_HIGHHALF_ADDR ? &kernel_pd_d : current_pd_d); + pagedir_t *pdd = ((size_t)vaddr >= K_HIGHHALF_ADDR || current_task == 0 + ? &kernel_pd_d : current_task->current_pd_d); pagetable_t *pd = ((size_t)vaddr >= K_HIGHHALF_ADDR ? &kernel_pd : current_pd); mutex_lock(&pdd->mutex); diff --git a/kernel/l0/task.c b/kernel/l0/task.c index e02dcf6..f8750e6 100644 --- a/kernel/l0/task.c +++ b/kernel/l0/task.c @@ -84,8 +84,10 @@ static void run_task(void (*entry)(void*)) { ASSERT(current_task->state == T_STATE_RUNNING); ASSERT(current_task->has_result); - current_task->has_result = false; + switch_pagedir(get_kernel_pagedir()); + current_task->has_result = false; + asm volatile("sti"); entry(current_task->result); @@ -125,13 +127,15 @@ task_t *new_task(entry_t entry) { t->result = 0; t->has_result = false; + t->current_pd_d = get_kernel_pagedir(); + t->more_data = 0; return t; } void tasking_setup(entry_t cont, void* arg) { - set_pit_frequency(100); + set_pit_frequency(TASK_SWITCH_FREQUENCY); idt_set_irq_handler(IRQ0, yield); task_t *t = new_task(cont); @@ -146,6 +150,7 @@ void tasking_setup(entry_t cont, void* arg) { void yield() { if (current_task == 0) { // might happen before tasking is initialized + // (but should not...) dbg_printf("Warning: probable deadlock."); } else { save_context_and_enter_scheduler(¤t_task->ctx); |