Loading arch/sh/exception.c +34 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <sys/memory.h> #include <utils/log.h> #include <sys/kdebug.h> #include <sys/mem_area.h> //void exception_handler() __attribute__ ((interrupt_handler, section(".handler.exception"))); Loading Loading @@ -156,6 +157,39 @@ void tlbmiss_handler() page = mem_find_page(curpr->dir_list, (void*)(vpn << PM_PAGE_ORDER) ); // if page is not in dir list (or is invalid), maybe it exists in memory // area (allocate it) // FIXME not working for shared pages if(page == NULL || !(page->private.flags & MEM_PAGE_VALID)) { struct mem_area *area; void *virtaddr; virtaddr = PM_PHYSICAL_ADDR(vpn); area = mem_area_find(curpr, virtaddr); if(area != NULL) { union pm_page pmpage; void *pmaddr; // 'major' page fault, create and fill it // FIXME UNCACHED due to temporary hack to be sure nothing is retained in cache pmaddr = arch_pm_get_free_page(MEM_PM_UNCACHED); if(pmaddr != NULL) { pmpage.private.ppn = PM_PHYSICAL_PAGE(pmaddr); pmpage.private.flags = MEM_PAGE_PRIVATE | MEM_PAGE_VALID; // | MEM_PAGE_CACHED; mem_insert_page(& curpr->dir_list, &pmpage, virtaddr); // FIXME get min(PM_PAGE_BYTES, max allowed) bytes mem_area_copy_raw(area, (virtaddr - area->address), pmaddr, PM_PAGE_BYTES); // not optimized, but ensure page points to a valid page struct page = mem_find_page(curpr->dir_list, virtaddr); printk(LOG_DEBUG, "tlb major fault: page inserted (virt %p -> phy %p)\n", virtaddr, PM_PHYSICAL_ADDR(page->private.ppn)); } } } if(page != NULL) { unsigned int flags; uint32 ppn = 0; Loading init.c +6 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include "sys/console.h" #include "sys/sysctl.h" #include "sys/mem_area.h" extern char cmdargs_begin; extern char cmdargs_end; Loading Loading @@ -131,6 +132,7 @@ void init() { //DBG_WAIT; // Initializing VFS and device sub-sytems, mount platform filesystems, // register platform devices... Loading Loading @@ -215,6 +217,10 @@ void init() { test_vfs(); */ // memory area subsystem mem_area_init(); process_init(); sched_init(); test_process(); Loading sys/mem_area.c +22 −2 Original line number Diff line number Diff line Loading @@ -87,16 +87,36 @@ int mem_area_copy_raw(struct mem_area *area, size_t offset, void *dest, size_t s if(area->flags & MEM_AREA_TYPE_ANON) { // anonymous area, the current implementation do nothing... if(offset + size > area->max_size) { printk(LOG_ERR, "mem_area: attempt to copy extra bytes (anon)\n"); } else { if(offset + size > area->anon.size && (area->flags & MEM_AREA_MAYGROW)) { printk(LOG_DEBUG, "mem_area: extends area (%d->%d)\n", area->anon.size, offset + size); } ret = 0; } } else if(area->flags & MEM_AREA_TYPE_FILE) { // file mapped to memory, for now use a generic way to handle them // TODO improve this with map_area_ops struct to allow "override" size_t nbread; vfs_lseek(area->file.filep, SEEK_SET, offset); vfs_lseek(area->file.filep, area->file.origin + offset, SEEK_SET); nbread = vfs_read(area->file.filep, dest, size); ret = nbread == size ? 0 : -1; if(ret) { printk(LOG_ERR, "mem_area: failed loading %d bytes from offset 0x%x" " [absolute 0x%x] (read returns %d)\n", size, offset, area->file.origin + offset, nbread); } else { printk(LOG_DEBUG, "mem_area: loaded %d bytes @%p from file\n", size, dest); } //print_memory(LOG_DEBUG, dest, nbread); } return ret; Loading sys/process.c +42 −0 Original line number Diff line number Diff line Loading @@ -196,6 +196,20 @@ void process_terminate(struct process *proc, int status) { // FIXME controlling terminal is process was session leader // remove all memory areas struct list_head *cur_area; cur_area = proc->mem_areas.next; while(cur_area != & proc->mem_areas) { struct list_head *next_area = cur_area->next; struct mem_area *area = container_of(cur_area, struct mem_area, list); mem_area_free(area); cur_area = next_area; } INIT_LIST_HEAD(& proc->mem_areas); // release the used address space, and free each allocated physical pages arch_adrsp_release(& proc->addr_space); for(curdir = proc->dir_list; curdir != NULL; curdir = nextdir) { Loading Loading @@ -263,6 +277,20 @@ pid_t sys_fork() { newproc->ctty = cur->ctty; // copy each memory area struct list_head *area_list; list_for_each(area_list, & cur->mem_areas) { // duplicate it // FIXME file should be duplicated? Or a counter need to be used? struct mem_area *old_area = container_of(area_list, struct mem_area, list); struct mem_area *new_area; new_area = mem_area_alloc(); *new_area = *old_area; mem_area_insert(newproc, new_area); } // copy each memory page with same virtual addresses // TODO copy-on-write system! for(dir = cur->dir_list; dir != NULL; dir = dir->next) { Loading Loading @@ -427,6 +455,20 @@ int sys_execve(const char *filename, char *const argv[], char *const envp[]) { cur->sig_array[i].sa_handler = SIG_DFL; } // remove all memory areas struct list_head *cur_area; cur_area = cur->mem_areas.next; while(cur_area != & cur->mem_areas) { struct list_head *next_area = cur_area->next; struct mem_area *area = container_of(cur_area, struct mem_area, list); mem_area_free(area); cur_area = next_area; } INIT_LIST_HEAD(& cur->mem_areas); // use a new address space to avoid to use old TLB records arch_adrsp_release(& cur->addr_space); Loading Loading
arch/sh/exception.c +34 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <sys/memory.h> #include <utils/log.h> #include <sys/kdebug.h> #include <sys/mem_area.h> //void exception_handler() __attribute__ ((interrupt_handler, section(".handler.exception"))); Loading Loading @@ -156,6 +157,39 @@ void tlbmiss_handler() page = mem_find_page(curpr->dir_list, (void*)(vpn << PM_PAGE_ORDER) ); // if page is not in dir list (or is invalid), maybe it exists in memory // area (allocate it) // FIXME not working for shared pages if(page == NULL || !(page->private.flags & MEM_PAGE_VALID)) { struct mem_area *area; void *virtaddr; virtaddr = PM_PHYSICAL_ADDR(vpn); area = mem_area_find(curpr, virtaddr); if(area != NULL) { union pm_page pmpage; void *pmaddr; // 'major' page fault, create and fill it // FIXME UNCACHED due to temporary hack to be sure nothing is retained in cache pmaddr = arch_pm_get_free_page(MEM_PM_UNCACHED); if(pmaddr != NULL) { pmpage.private.ppn = PM_PHYSICAL_PAGE(pmaddr); pmpage.private.flags = MEM_PAGE_PRIVATE | MEM_PAGE_VALID; // | MEM_PAGE_CACHED; mem_insert_page(& curpr->dir_list, &pmpage, virtaddr); // FIXME get min(PM_PAGE_BYTES, max allowed) bytes mem_area_copy_raw(area, (virtaddr - area->address), pmaddr, PM_PAGE_BYTES); // not optimized, but ensure page points to a valid page struct page = mem_find_page(curpr->dir_list, virtaddr); printk(LOG_DEBUG, "tlb major fault: page inserted (virt %p -> phy %p)\n", virtaddr, PM_PHYSICAL_ADDR(page->private.ppn)); } } } if(page != NULL) { unsigned int flags; uint32 ppn = 0; Loading
init.c +6 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include "sys/console.h" #include "sys/sysctl.h" #include "sys/mem_area.h" extern char cmdargs_begin; extern char cmdargs_end; Loading Loading @@ -131,6 +132,7 @@ void init() { //DBG_WAIT; // Initializing VFS and device sub-sytems, mount platform filesystems, // register platform devices... Loading Loading @@ -215,6 +217,10 @@ void init() { test_vfs(); */ // memory area subsystem mem_area_init(); process_init(); sched_init(); test_process(); Loading
sys/mem_area.c +22 −2 Original line number Diff line number Diff line Loading @@ -87,16 +87,36 @@ int mem_area_copy_raw(struct mem_area *area, size_t offset, void *dest, size_t s if(area->flags & MEM_AREA_TYPE_ANON) { // anonymous area, the current implementation do nothing... if(offset + size > area->max_size) { printk(LOG_ERR, "mem_area: attempt to copy extra bytes (anon)\n"); } else { if(offset + size > area->anon.size && (area->flags & MEM_AREA_MAYGROW)) { printk(LOG_DEBUG, "mem_area: extends area (%d->%d)\n", area->anon.size, offset + size); } ret = 0; } } else if(area->flags & MEM_AREA_TYPE_FILE) { // file mapped to memory, for now use a generic way to handle them // TODO improve this with map_area_ops struct to allow "override" size_t nbread; vfs_lseek(area->file.filep, SEEK_SET, offset); vfs_lseek(area->file.filep, area->file.origin + offset, SEEK_SET); nbread = vfs_read(area->file.filep, dest, size); ret = nbread == size ? 0 : -1; if(ret) { printk(LOG_ERR, "mem_area: failed loading %d bytes from offset 0x%x" " [absolute 0x%x] (read returns %d)\n", size, offset, area->file.origin + offset, nbread); } else { printk(LOG_DEBUG, "mem_area: loaded %d bytes @%p from file\n", size, dest); } //print_memory(LOG_DEBUG, dest, nbread); } return ret; Loading
sys/process.c +42 −0 Original line number Diff line number Diff line Loading @@ -196,6 +196,20 @@ void process_terminate(struct process *proc, int status) { // FIXME controlling terminal is process was session leader // remove all memory areas struct list_head *cur_area; cur_area = proc->mem_areas.next; while(cur_area != & proc->mem_areas) { struct list_head *next_area = cur_area->next; struct mem_area *area = container_of(cur_area, struct mem_area, list); mem_area_free(area); cur_area = next_area; } INIT_LIST_HEAD(& proc->mem_areas); // release the used address space, and free each allocated physical pages arch_adrsp_release(& proc->addr_space); for(curdir = proc->dir_list; curdir != NULL; curdir = nextdir) { Loading Loading @@ -263,6 +277,20 @@ pid_t sys_fork() { newproc->ctty = cur->ctty; // copy each memory area struct list_head *area_list; list_for_each(area_list, & cur->mem_areas) { // duplicate it // FIXME file should be duplicated? Or a counter need to be used? struct mem_area *old_area = container_of(area_list, struct mem_area, list); struct mem_area *new_area; new_area = mem_area_alloc(); *new_area = *old_area; mem_area_insert(newproc, new_area); } // copy each memory page with same virtual addresses // TODO copy-on-write system! for(dir = cur->dir_list; dir != NULL; dir = dir->next) { Loading Loading @@ -427,6 +455,20 @@ int sys_execve(const char *filename, char *const argv[], char *const envp[]) { cur->sig_array[i].sa_handler = SIG_DFL; } // remove all memory areas struct list_head *cur_area; cur_area = cur->mem_areas.next; while(cur_area != & cur->mem_areas) { struct list_head *next_area = cur_area->next; struct mem_area *area = container_of(cur_area, struct mem_area, list); mem_area_free(area); cur_area = next_area; } INIT_LIST_HEAD(& cur->mem_areas); // use a new address space to avoid to use old TLB records arch_adrsp_release(& cur->addr_space); Loading