Rev 121 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 121 | Rev 167 | ||
---|---|---|---|
Line 37... | Line 37... | ||
37 | #include <synch/spinlock.h> |
37 | #include <synch/spinlock.h> |
38 | #include <config.h> |
38 | #include <config.h> |
39 | #include <list.h> |
39 | #include <list.h> |
40 | #include <panic.h> |
40 | #include <panic.h> |
41 | #include <arch/asm.h> |
41 | #include <arch/asm.h> |
- | 42 | #include <debug.h> |
|
42 | 43 | ||
- | 44 | #define KAS_START_INDEX PTL0_INDEX(KERNEL_ADDRESS_SPACE_START) |
|
- | 45 | #define KAS_END_INDEX PTL0_INDEX(KERNEL_ADDRESS_SPACE_END) |
|
- | 46 | #define KAS_INDICES (1+(KAS_END_INDEX-KAS_START_INDEX)) |
|
- | 47 | ||
43 | vm_t *vm_create(void) |
48 | vm_t *vm_create(pte_t *ptl0) |
44 | { |
49 | { |
45 | vm_t *m; |
50 | vm_t *m; |
46 | 51 | ||
47 | m = (vm_t *) malloc(sizeof(vm_t)); |
52 | m = (vm_t *) malloc(sizeof(vm_t)); |
48 | if (m) { |
53 | if (m) { |
49 | spinlock_initialize(&m->lock); |
54 | spinlock_initialize(&m->lock); |
50 | list_initialize(&m->vm_area_head); |
55 | list_initialize(&m->vm_area_head); |
- | 56 | ||
- | 57 | /* |
|
- | 58 | * Each vm_t is supposed to have its own page table. |
|
- | 59 | * It is either passed one or it has to allocate and set one up. |
|
- | 60 | */ |
|
51 | m->ptl0 = NULL; |
61 | if (!(m->ptl0 = ptl0)) { |
- | 62 | pte_t *src_ptl0, *dst_ptl0; |
|
- | 63 | ||
- | 64 | src_ptl0 = (pte_t *) PA2KA(GET_PTL0_ADDRESS()); |
|
- | 65 | dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC); |
|
- | 66 | memsetb((__address) dst_ptl0, PAGE_SIZE, 0); |
|
- | 67 | memcopy((__address) &src_ptl0[KAS_START_INDEX], (__address) &dst_ptl0[KAS_START_INDEX], KAS_INDICES*sizeof(pte_t)); |
|
- | 68 | m->ptl0 = (pte_t *) KA2PA(dst_ptl0); |
|
- | 69 | } |
|
52 | } |
70 | } |
53 | 71 | ||
54 | return m; |
72 | return m; |
55 | } |
73 | } |
56 | 74 | ||
Line 107... | Line 125... | ||
107 | 125 | ||
108 | void vm_area_destroy(vm_area_t *a) |
126 | void vm_area_destroy(vm_area_t *a) |
109 | { |
127 | { |
110 | } |
128 | } |
111 | 129 | ||
112 | void vm_area_map(vm_area_t *a) |
130 | void vm_area_map(vm_area_t *a, vm_t *m) |
113 | { |
131 | { |
114 | int i, flags; |
132 | int i, flags; |
115 | pri_t pri; |
133 | pri_t pri; |
116 | 134 | ||
117 | pri = cpu_priority_high(); |
135 | pri = cpu_priority_high(); |
- | 136 | spinlock_lock(&m->lock); |
|
118 | spinlock_lock(&a->lock); |
137 | spinlock_lock(&a->lock); |
119 | 138 | ||
120 | switch (a->type) { |
139 | switch (a->type) { |
121 | case VMA_TEXT: |
140 | case VMA_TEXT: |
122 | flags = PAGE_EXEC | PAGE_READ | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE; |
141 | flags = PAGE_EXEC | PAGE_READ | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE; |
Line 124... | Line 143... | ||
124 | case VMA_DATA: |
143 | case VMA_DATA: |
125 | case VMA_STACK: |
144 | case VMA_STACK: |
126 | flags = PAGE_READ | PAGE_WRITE | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE; |
145 | flags = PAGE_READ | PAGE_WRITE | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE; |
127 | break; |
146 | break; |
128 | default: |
147 | default: |
129 | panic("unexpected vm_type_t %d", a->type); |
148 | panic("unexpected vm_type_t %d", a->type); |
130 | } |
149 | } |
131 | 150 | ||
- | 151 | ASSERT(m->ptl0); |
|
132 | for (i=0; i<a->size; i++) |
152 | for (i=0; i<a->size; i++) |
133 | map_page_to_frame(a->address + i*PAGE_SIZE, a->mapping[i], flags, 0); |
153 | map_page_to_frame(a->address + i*PAGE_SIZE, a->mapping[i], flags, (__address) m->ptl0); |
134 | 154 | ||
135 | spinlock_unlock(&a->lock); |
155 | spinlock_unlock(&a->lock); |
- | 156 | spinlock_unlock(&m->lock); |
|
136 | cpu_priority_restore(pri); |
157 | cpu_priority_restore(pri); |
137 | } |
158 | } |
138 | 159 | ||
139 | void vm_area_unmap(vm_area_t *a) |
160 | void vm_area_unmap(vm_area_t *a, vm_t *m) |
140 | { |
161 | { |
141 | int i; |
162 | int i; |
142 | pri_t pri; |
163 | pri_t pri; |
143 | 164 | ||
144 | pri = cpu_priority_high(); |
165 | pri = cpu_priority_high(); |
- | 166 | spinlock_lock(&m->lock); |
|
145 | spinlock_lock(&a->lock); |
167 | spinlock_lock(&a->lock); |
146 | 168 | ||
- | 169 | ASSERT(m->ptl0); |
|
147 | for (i=0; i<a->size; i++) |
170 | for (i=0; i<a->size; i++) |
148 | map_page_to_frame(a->address + i*PAGE_SIZE, 0, PAGE_NOT_PRESENT, 0); |
171 | map_page_to_frame(a->address + i*PAGE_SIZE, 0, PAGE_NOT_PRESENT, (__address) m->ptl0); |
149 | 172 | ||
150 | spinlock_unlock(&a->lock); |
173 | spinlock_unlock(&a->lock); |
151 | cpu_priority_restore(pri); |
- | |
152 | } |
- | |
153 | - | ||
154 | void vm_install(vm_t *m) |
- | |
155 | { |
- | |
156 | link_t *l; |
- | |
157 | pri_t pri; |
- | |
158 | - | ||
159 | pri = cpu_priority_high(); |
- | |
160 | spinlock_lock(&m->lock); |
- | |
161 | - | ||
162 | for(l = m->vm_area_head.next; l != &m->vm_area_head; l = l->next) |
- | |
163 | vm_area_map(list_get_instance(l, vm_area_t, link)); |
- | |
164 | - | ||
165 | spinlock_unlock(&m->lock); |
174 | spinlock_unlock(&m->lock); |
166 | cpu_priority_restore(pri); |
175 | cpu_priority_restore(pri); |
167 | } |
176 | } |
168 | 177 | ||
169 | void vm_uninstall(vm_t *m) |
178 | void vm_install(vm_t *m) |
170 | { |
179 | { |
171 | link_t *l; |
180 | link_t *l; |
172 | pri_t pri; |
181 | pri_t pri; |
173 | 182 | ||
174 | pri = cpu_priority_high(); |
183 | pri = cpu_priority_high(); |
175 | 184 | ||
176 | tlb_shootdown_start(); |
185 | tlb_shootdown_start(); |
177 | - | ||
178 | spinlock_lock(&m->lock); |
186 | spinlock_lock(&m->lock); |
179 | 187 | ||
180 | for(l = m->vm_area_head.next; l != &m->vm_area_head; l = l->next) |
188 | ASSERT(m->ptl0); |
181 | vm_area_unmap(list_get_instance(l, vm_area_t, link)); |
189 | SET_PTL0_ADDRESS(m->ptl0); |
182 | 190 | ||
183 | spinlock_unlock(&m->lock); |
191 | spinlock_unlock(&m->lock); |
184 | - | ||
185 | tlb_shootdown_finalize(); |
192 | tlb_shootdown_finalize(); |
186 | 193 | ||
187 | cpu_priority_restore(pri); |
194 | cpu_priority_restore(pri); |
188 | } |
195 | } |