Merge remote-tracking branch 'stv0g/stage5' into stage5
This commit is contained in:
commit
4f6792e3c2
3 changed files with 28 additions and 20 deletions
|
@ -33,6 +33,8 @@
|
|||
* This file contains the several functions to manage the page tables
|
||||
*/
|
||||
|
||||
#include <eduos/tasks_types.h>
|
||||
|
||||
#ifndef __PAGE_H__
|
||||
#define __PAGE_H__
|
||||
|
||||
|
@ -135,7 +137,7 @@ int page_unmap(size_t viraddr, size_t npages);
|
|||
* @retval 0 Success. Everything went fine.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int page_map_copy(size_t dest);
|
||||
int page_map_copy(task_t *dest);
|
||||
|
||||
/** @brief Free a whole page map tree */
|
||||
int page_map_drop();
|
||||
|
|
|
@ -104,9 +104,12 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
|
|||
size_t phyaddr = get_pages(1);
|
||||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
||||
goto out;
|
||||
|
||||
if (bits & PG_USER)
|
||||
atomic_int32_inc(¤t_task->user_usage);
|
||||
|
||||
/* Reference the new table within its parent */
|
||||
self[lvl][vpn] = phyaddr | bits;
|
||||
self[lvl][vpn] = phyaddr | bits | PG_PRESENT;
|
||||
|
||||
/* Fill new table with zeros */
|
||||
memset(&self[lvl-1][vpn<<PAGE_MAP_BITS], 0, PAGE_SIZE);
|
||||
|
@ -118,7 +121,7 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
|
|||
* We have to flush a single TLB entry. */
|
||||
tlb_flush_one_page(vpn << PAGE_BITS);
|
||||
|
||||
self[lvl][vpn] = phyaddr | bits;
|
||||
self[lvl][vpn] = phyaddr | bits | PG_PRESENT;
|
||||
phyaddr += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
@ -158,12 +161,13 @@ int page_map_drop()
|
|||
void traverse(int lvl, long vpn) {
|
||||
long stop;
|
||||
for (stop=vpn+PAGE_MAP_ENTRIES; vpn<stop; vpn++) {
|
||||
if (self[lvl][vpn] & PG_PRESENT && self[lvl][vpn] & PG_USER) {
|
||||
if ((self[lvl][vpn] & PG_PRESENT) && (self[lvl][vpn] & PG_USER)) {
|
||||
/* Post-order traversal */
|
||||
if (lvl)
|
||||
traverse(lvl-1, vpn<<PAGE_MAP_BITS);
|
||||
|
||||
put_pages(self[lvl][vpn] & PAGE_MASK, 1);
|
||||
atomic_int32_dec(¤t_task->user_usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +181,7 @@ int page_map_drop()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int page_map_copy(size_t dest)
|
||||
int page_map_copy(task_t *dest)
|
||||
{
|
||||
int traverse(int lvl, long vpn) {
|
||||
long stop;
|
||||
|
@ -187,12 +191,14 @@ int page_map_copy(size_t dest)
|
|||
size_t phyaddr = get_pages(1);
|
||||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
||||
return -ENOMEM;
|
||||
|
||||
atomic_int32_inc(&dest->user_usage);
|
||||
|
||||
other[lvl][vpn] = phyaddr | (self[lvl][vpn] & ~PAGE_MASK);
|
||||
if (lvl) /* PML4, PDPT, PGD */
|
||||
traverse(lvl-1, vpn<<PAGE_MAP_BITS); /* Pre-order traversal */
|
||||
else { /* PGT */
|
||||
page_map(PAGE_TMP, phyaddr, 1, PG_PRESENT | PG_RW);
|
||||
page_map(PAGE_TMP, phyaddr, 1, PG_RW);
|
||||
memcpy((void*) PAGE_TMP, (void*) (vpn<<PAGE_BITS), PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
@ -208,11 +214,11 @@ int page_map_copy(size_t dest)
|
|||
}
|
||||
|
||||
spinlock_irqsave_lock(¤t_task->page_lock);
|
||||
self[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-2] = dest | PG_PRESENT | PG_SELF | PG_RW;
|
||||
self[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-2] = dest->page_map | PG_PRESENT | PG_SELF | PG_RW;
|
||||
|
||||
int ret = traverse(PAGE_LEVELS-1, 0);
|
||||
|
||||
other[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-1] = dest | PG_PRESENT | PG_SELF | PG_RW;
|
||||
other[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-1] = dest->page_map | PG_PRESENT | PG_SELF | PG_RW;
|
||||
self [PAGE_LEVELS-1][PAGE_MAP_ENTRIES-2] = 0;
|
||||
spinlock_irqsave_unlock(¤t_task->page_lock);
|
||||
|
||||
|
@ -248,29 +254,29 @@ int page_init()
|
|||
/* Map kernel */
|
||||
addr = (size_t) &kernel_start;
|
||||
npages = PAGE_FLOOR((size_t) &kernel_end - (size_t) &kernel_start) >> PAGE_BITS;
|
||||
page_map(addr, addr, npages, PG_PRESENT | PG_RW | /* PG_USER | */ PG_GLOBAL);
|
||||
page_map(addr, addr, npages, PG_RW | /* PG_USER | */ PG_GLOBAL);
|
||||
|
||||
#ifdef CONFIG_VGA
|
||||
/* Map video memory */
|
||||
page_map(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR, 1, PG_PRESENT | PG_RW | PG_PCD);
|
||||
page_map(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR, 1, PG_RW | PG_PCD);
|
||||
#endif
|
||||
|
||||
/* Map multiboot information and modules */
|
||||
if (mb_info) {
|
||||
addr = (size_t) mb_info & PAGE_MASK;
|
||||
npages = PAGE_FLOOR(sizeof(*mb_info)) >> PAGE_BITS;
|
||||
page_map(addr, addr, npages, PG_PRESENT | PG_GLOBAL);
|
||||
page_map(addr, addr, npages, PG_GLOBAL);
|
||||
|
||||
if (mb_info->flags & MULTIBOOT_INFO_MODS) {
|
||||
addr = mb_info->mods_addr;
|
||||
npages = PAGE_FLOOR(mb_info->mods_count*sizeof(multiboot_module_t)) >> PAGE_BITS;
|
||||
page_map(addr, addr, npages, PG_PRESENT | PG_GLOBAL);
|
||||
page_map(addr, addr, npages, PG_GLOBAL);
|
||||
|
||||
multiboot_module_t* mmodule = (multiboot_module_t*) ((size_t) mb_info->mods_addr);
|
||||
for(i=0; i<mb_info->mods_count; i++) {
|
||||
addr = mmodule[i].mod_start;
|
||||
npages = PAGE_FLOOR(mmodule[i].mod_end - mmodule[i].mod_start) >> PAGE_BITS;
|
||||
page_map(addr, addr, npages, PG_PRESENT | PG_USER | PG_GLOBAL);
|
||||
page_map(addr, addr, npages, PG_USER | PG_GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ static void NORETURN do_exit(int arg)
|
|||
|
||||
kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg);
|
||||
|
||||
page_map_drop();
|
||||
page_map_drop();
|
||||
|
||||
curr_task->status = TASK_FINISHED;
|
||||
reschedule();
|
||||
|
@ -204,13 +204,13 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
|
|||
spinlock_irqsave_init(&task_table[i].page_lock);
|
||||
atomic_int32_set(&task_table[i].user_usage, 0);
|
||||
|
||||
/* Allocated new PGD or PML4 and copy page table */
|
||||
size_t map = get_pages(1);
|
||||
if (BUILTIN_EXPECT(!map, 0))
|
||||
goto out;
|
||||
/* Allocated new PGD or PML4 and copy page table */
|
||||
task_table[i].page_map = get_pages(1);
|
||||
if (BUILTIN_EXPECT(!task_table[i].page_map, 0))
|
||||
goto out;
|
||||
|
||||
page_map_copy(map);
|
||||
task_table[i].page_map = map;
|
||||
/* Copy page tables & user frames of current task to new one */
|
||||
page_map_copy(&task_table[i]);
|
||||
|
||||
if (id)
|
||||
*id = i;
|
||||
|
|
Loading…
Add table
Reference in a new issue