/SPARTAN/trunk/include/mm/page.h |
---|
106,8 → 106,6 |
#define SET_PTL3_FLAGS(ptl2, i, x) SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS(ptl3, i, x) SET_FRAME_FLAGS_ARCH(ptl3, i, x) |
#include <arch/mm/page.h> |
extern void page_init(void); |
extern void map_page_to_frame(__address page, __address frame, int flags, __address root); |
extern void map_structure(__address s, size_t size); |
/SPARTAN/trunk/include/mm/vm.h |
---|
76,14 → 76,14 |
pte_t *ptl0; |
}; |
extern vm_t * vm_create(void); |
extern vm_t * vm_create(pte_t *ptl0); |
extern void vm_destroy(vm_t *m); |
extern vm_area_t *vm_area_create(vm_t *m, vm_type_t type, size_t size, __address addr); |
extern void vm_area_destroy(vm_area_t *a); |
extern void vm_area_map(vm_area_t *a); |
extern void vm_area_unmap(vm_area_t *a); |
extern void vm_area_map(vm_area_t *a, vm_t *m); |
extern void vm_area_unmap(vm_area_t *a, vm_t *m); |
extern void vm_install(vm_t *m); |
extern void vm_uninstall(vm_t *m); |
/SPARTAN/trunk/src/main/kinit.c |
---|
118,7 → 118,7 |
/* |
* Create the first user task. |
*/ |
m = vm_create(); |
m = vm_create(NULL); |
if (!m) panic("vm_create"); |
u = task_create(m); |
if (!u) panic("task_create"); |
130,6 → 130,7 |
*/ |
a = vm_area_create(m, VMA_TEXT, 1, UTEXT_ADDRESS); |
if (!a) panic("vm_area_create: vm_text"); |
vm_area_map(a, m); |
memcopy((__address) utext, PA2KA(a->mapping[0]), utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE); |
/* |
137,6 → 138,7 |
*/ |
a = vm_area_create(m, VMA_STACK, 1, USTACK_ADDRESS); |
if (!a) panic("vm_area_create: vm_stack"); |
vm_area_map(a, m); |
thread_ready(t); |
#endif /* __USERSPACE__ */ |
/SPARTAN/trunk/src/main/main.c |
---|
149,7 → 149,7 |
/* |
* Create kernel vm mapping. |
*/ |
m = vm_create(); |
m = vm_create(GET_PTL0_ADDRESS()); |
if (!m) panic("can't create kernel vm address space\n"); |
/* |
/SPARTAN/trunk/src/proc/scheduler.c |
---|
380,9 → 380,6 |
* Both tasks and vm mappings are different. |
* Replace the old one with the new one. |
*/ |
if (m1) { |
vm_uninstall(m1); |
} |
vm_install(m2); |
} |
TASK = THREAD->task; |
/SPARTAN/trunk/src/mm/vm.c |
---|
39,8 → 39,13 |
#include <list.h> |
#include <panic.h> |
#include <arch/asm.h> |
#include <debug.h> |
vm_t *vm_create(void) |
#define KAS_START_INDEX PTL0_INDEX(KERNEL_ADDRESS_SPACE_START) |
#define KAS_END_INDEX PTL0_INDEX(KERNEL_ADDRESS_SPACE_END) |
#define KAS_INDICES (1+(KAS_END_INDEX-KAS_START_INDEX)) |
vm_t *vm_create(pte_t *ptl0) |
{ |
vm_t *m; |
48,7 → 53,20 |
if (m) { |
spinlock_initialize(&m->lock); |
list_initialize(&m->vm_area_head); |
m->ptl0 = NULL; |
/* |
* Each vm_t is supposed to have its own page table. |
* It is either passed one or it has to allocate and set one up. |
*/ |
if (!(m->ptl0 = ptl0)) { |
pte_t *src_ptl0, *dst_ptl0; |
src_ptl0 = (pte_t *) PA2KA(GET_PTL0_ADDRESS()); |
dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC); |
memsetb((__address) dst_ptl0, PAGE_SIZE, 0); |
memcopy((__address) &src_ptl0[KAS_START_INDEX], (__address) &dst_ptl0[KAS_START_INDEX], KAS_INDICES*sizeof(pte_t)); |
m->ptl0 = (pte_t *) KA2PA(dst_ptl0); |
} |
} |
return m; |
109,12 → 127,13 |
{ |
} |
void vm_area_map(vm_area_t *a) |
void vm_area_map(vm_area_t *a, vm_t *m) |
{ |
int i, flags; |
pri_t pri; |
pri = cpu_priority_high(); |
spinlock_lock(&m->lock); |
spinlock_lock(&a->lock); |
switch (a->type) { |
126,28 → 145,33 |
flags = PAGE_READ | PAGE_WRITE | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE; |
break; |
default: |
panic("unexpected vm_type_t %d", a->type); |
panic("unexpected vm_type_t %d", a->type); |
} |
ASSERT(m->ptl0); |
for (i=0; i<a->size; i++) |
map_page_to_frame(a->address + i*PAGE_SIZE, a->mapping[i], flags, 0); |
map_page_to_frame(a->address + i*PAGE_SIZE, a->mapping[i], flags, (__address) m->ptl0); |
spinlock_unlock(&a->lock); |
spinlock_unlock(&m->lock); |
cpu_priority_restore(pri); |
} |
void vm_area_unmap(vm_area_t *a) |
void vm_area_unmap(vm_area_t *a, vm_t *m) |
{ |
int i; |
pri_t pri; |
pri = cpu_priority_high(); |
spinlock_lock(&m->lock); |
spinlock_lock(&a->lock); |
ASSERT(m->ptl0); |
for (i=0; i<a->size; i++) |
map_page_to_frame(a->address + i*PAGE_SIZE, 0, PAGE_NOT_PRESENT, 0); |
map_page_to_frame(a->address + i*PAGE_SIZE, 0, PAGE_NOT_PRESENT, (__address) m->ptl0); |
spinlock_unlock(&a->lock); |
spinlock_unlock(&m->lock); |
cpu_priority_restore(pri); |
} |
157,31 → 181,14 |
pri_t pri; |
pri = cpu_priority_high(); |
spinlock_lock(&m->lock); |
for(l = m->vm_area_head.next; l != &m->vm_area_head; l = l->next) |
vm_area_map(list_get_instance(l, vm_area_t, link)); |
spinlock_unlock(&m->lock); |
cpu_priority_restore(pri); |
} |
void vm_uninstall(vm_t *m) |
{ |
link_t *l; |
pri_t pri; |
pri = cpu_priority_high(); |
tlb_shootdown_start(); |
spinlock_lock(&m->lock); |
for(l = m->vm_area_head.next; l != &m->vm_area_head; l = l->next) |
vm_area_unmap(list_get_instance(l, vm_area_t, link)); |
ASSERT(m->ptl0); |
SET_PTL0_ADDRESS(m->ptl0); |
spinlock_unlock(&m->lock); |
tlb_shootdown_finalize(); |
cpu_priority_restore(pri); |
/SPARTAN/trunk/arch/ppc/src/dummy.s |
---|
28,6 → 28,7 |
.text |
.global memcopy |
.global cpu_priority_high |
.global cpu_priority_low |
.global cpu_priority_read |
50,6 → 51,7 |
.global asm_delay_loop |
.global dummy |
memcopy: |
cpu_priority_high: |
cpu_priority_low: |
cpu_priority_restore: |
/SPARTAN/trunk/arch/amd64/src/dummy.s |
---|
28,6 → 28,7 |
.text |
.global memcopy |
.global cpu_priority_high |
.global cpu_priority_low |
.global cpu_priority_read |
53,6 → 54,7 |
.global frame_arch_init |
.global dummy |
memcopy: |
cpu_priority_high: |
cpu_priority_low: |
cpu_priority_restore: |
/SPARTAN/trunk/arch/ia32/src/pm.c |
---|
34,6 → 34,7 |
#include <arch/asm.h> |
#include <arch/context.h> |
#include <panic.h> |
#include <arch/mm/page.h> |
/* |
* Early ia32 configuration functions and data structures. |
131,9 → 132,9 |
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ |
static void clean_IOPL_NT_flags(void) |
{ |
asm |
asm |
( |
"pushfl;" |
"pushfl;" |
"pop %%eax;" |
"and $0xffff8fff,%%eax;" |
"push %%eax;" |
147,9 → 148,9 |
/* Clean AM(18) flag in CR0 register */ |
static void clean_AM_flag(void) |
{ |
asm |
asm |
( |
"mov %%cr0,%%eax;" |
"mov %%cr0,%%eax;" |
"and $0xFFFBFFFF,%%eax;" |
"mov %%eax,%%cr0;" |
: |
158,10 → 159,6 |
); |
} |
void pm_init(void) |
{ |
struct descriptor *gdt_p = (struct descriptor *) PA2KA(gdtr.base); |
/SPARTAN/trunk/arch/ia32/src/proc/scheduler.c |
---|
34,5 → 34,5 |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (__address) &THREAD->kstack[THREAD_STACK_SIZE-8]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
} |
/SPARTAN/trunk/arch/ia32/src/mm/page.c |
---|
37,15 → 37,6 |
#include <synch/spinlock.h> |
#include <debug.h> |
/* |
* Note. |
* This is the preliminary code for controlling paging mechanism on ia32. It is |
* needed by other parts of the kernel for its ability to map virtual addresses |
* to physical. SMP code relies on this feature. Other than that, this code is |
* by no means meant to implement virtual memory in terms of swapping pages in |
* and out. |
*/ |
__address bootstrap_dba; |
void page_arch_init(void) |
/SPARTAN/trunk/arch/ia32/src/drivers/ega.c |
---|
29,6 → 29,7 |
#include <arch/ega.h> |
#include <putchar.h> |
#include <mm/page.h> |
#include <arch/mm/page.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <arch/asm.h> |