Diff markup
001 001
002 002
003 003
004 004
005 005
006 006
007 007
008 008
009 009
010 010
011 011
012 012
013 013
014 014
015 015
016 016
017 017
018 018
019 #include <hwcore/paging.h> 019 #include <hwcore/paging.h>
020 #include <hwcore/irq.h> 020 #include <hwcore/irq.h>
021 021
022 #include <sos/assert.h> 022 #include <sos/assert.h>
023 #include <sos/list.h> 023 #include <sos/list.h>
024 #include <sos/klibc.h> 024 #include <sos/klibc.h>
025 #include <sos/physmem.h> 025 #include <sos/physmem.h>
026 #include <sos/kmem_slab.h> 026 #include <sos/kmem_slab.h>
027 #include <sos/kmem_vmm.h> 027 #include <sos/kmem_vmm.h>
028 028
029 #include "mm_context.h" 029 #include "mm_context.h"
030 030
031 031
032 032
033 033
034 034
035 struct sos_mm_context 035 struct sos_mm_context
036 { 036 {
037 037
038 sos_paddr_t paddr_PD; 038 sos_paddr_t paddr_PD;
039 039
040 040
041 sos_vaddr_t vaddr_PD; 041 sos_vaddr_t vaddr_PD;
042 042
043 043
044 sos_ui32_t ref_cnt; 044 sos_ui32_t ref_cnt;
045 045
046 046
047 struct sos_mm_context *prev, *next; 047 struct sos_mm_context *prev, *next;
048 }; 048 };
049 049
050 050
051 051
052 052
053 053
054 struct sos_kslab_cache * cache_struct_mm_conte 054 struct sos_kslab_cache * cache_struct_mm_context;
055 055
056 056
057 057
058 058
059 059
060 060
061 static struct sos_mm_context *current_mm_conte 061 static struct sos_mm_context *current_mm_context = NULL;
062 062
063 063
064 064
065 065
066 066
067 static struct sos_mm_context *list_mm_context 067 static struct sos_mm_context *list_mm_context = NULL;
068 068
069 069
070 070
071 071
072 072
073 sos_ret_t sos_mm_context_subsystem_setup() 073 sos_ret_t sos_mm_context_subsystem_setup()
074 { 074 {
075 struct sos_mm_context * initial_mm_context; 075 struct sos_mm_context * initial_mm_context;
076 sos_ret_t retval; 076 sos_ret_t retval;
077 077
078 078
079 cache_struct_mm_context = sos_kmem_cache_cre 079 cache_struct_mm_context = sos_kmem_cache_create("struct mm_context",
080 080 sizeof(struct sos_mm_context),
081 081 1, 0,
082 082 SOS_KSLAB_CREATE_MAP);
083 if (NULL == cache_struct_mm_context) 083 if (NULL == cache_struct_mm_context)
084 return -SOS_ENOMEM; 084 return -SOS_ENOMEM;
085 085
086 086
087 087
088 088
089 initial_mm_context 089 initial_mm_context
090 = (struct sos_mm_context*) sos_kmem_cache_ 090 = (struct sos_mm_context*) sos_kmem_cache_alloc(cache_struct_mm_context,
091 091 SOS_KSLAB_ALLOC_ATOMIC);
092 if (NULL == initial_mm_context) 092 if (NULL == initial_mm_context)
093 return -SOS_ENOMEM; 093 return -SOS_ENOMEM;
094 094
095 095
096 initial_mm_context->paddr_PD = sos_paging_ge 096 initial_mm_context->paddr_PD = sos_paging_get_current_PD_paddr();
097 097
098 098
099 099
100 100
101 101
102 102
103 initial_mm_context->vaddr_PD = sos_kmem_vmm_ 103 initial_mm_context->vaddr_PD = sos_kmem_vmm_alloc(1, 0);
104 if (initial_mm_context->vaddr_PD == 0) 104 if (initial_mm_context->vaddr_PD == 0)
105 return -SOS_ENOMEM; 105 return -SOS_ENOMEM;
106 106
107 107
108 108
109 retval = sos_paging_map(initial_mm_context-> 109 retval = sos_paging_map(initial_mm_context->paddr_PD,
110 initial_mm_context-> 110 initial_mm_context->vaddr_PD,
111 FALSE, 111 FALSE,
112 SOS_VM_MAP_PROT_READ 112 SOS_VM_MAP_PROT_READ
113 | SOS_VM_MAP_PROT_WR 113 | SOS_VM_MAP_PROT_WRITE);
114 if (SOS_OK != retval) 114 if (SOS_OK != retval)
115 return retval; 115 return retval;
116 116
117 117
118 list_singleton(list_mm_context, initial_mm_c 118 list_singleton(list_mm_context, initial_mm_context);
119 119
120 120
121 initial_mm_context->ref_cnt ++; 121 initial_mm_context->ref_cnt ++;
122 122
123 123
124 initial_mm_context->ref_cnt ++; 124 initial_mm_context->ref_cnt ++;
125 current_mm_context = initial_mm_context; 125 current_mm_context = initial_mm_context;
126 126
127 return SOS_OK; 127 return SOS_OK;
128 } 128 }
129 129
130 130
131 struct sos_mm_context * sos_mm_context_create( 131 struct sos_mm_context * sos_mm_context_create(void)
132 { 132 {
133 sos_ui32_t flags; 133 sos_ui32_t flags;
134 struct sos_mm_context *mmctxt; 134 struct sos_mm_context *mmctxt;
135 135
136 136
137 137
138 138
139 mmctxt = (struct sos_mm_context*) sos_kmem_c 139 mmctxt = (struct sos_mm_context*) sos_kmem_cache_alloc(cache_struct_mm_context, 0);
140 if (NULL == mmctxt) 140 if (NULL == mmctxt)
141 return NULL; 141 return NULL;
142 142
143 143
144 mmctxt->vaddr_PD = sos_kmem_vmm_alloc(1, SOS 144 mmctxt->vaddr_PD = sos_kmem_vmm_alloc(1, SOS_KMEM_VMM_MAP);
145 if (mmctxt->vaddr_PD == 0) 145 if (mmctxt->vaddr_PD == 0)
146 { 146 {
147 sos_kmem_cache_free((sos_vaddr_t) mmctxt 147 sos_kmem_cache_free((sos_vaddr_t) mmctxt);
148 return NULL; 148 return NULL;
149 } 149 }
150 150
151 151
152 mmctxt->paddr_PD = sos_paging_get_paddr(mmct 152 mmctxt->paddr_PD = sos_paging_get_paddr(mmctxt->vaddr_PD);
153 if (mmctxt->paddr_PD == 0) 153 if (mmctxt->paddr_PD == 0)
154 { 154 {
155 sos_kmem_cache_free((sos_vaddr_t) mmctxt 155 sos_kmem_cache_free((sos_vaddr_t) mmctxt->vaddr_PD);
156 sos_kmem_cache_free((sos_vaddr_t) mmctxt 156 sos_kmem_cache_free((sos_vaddr_t) mmctxt);
157 return NULL; 157 return NULL;
158 } 158 }
159 159
160 160
161 if (SOS_OK != sos_paging_copy_kernel_space(m 161 if (SOS_OK != sos_paging_copy_kernel_space(mmctxt->vaddr_PD,
162 c 162 current_mm_context->vaddr_PD))
163 { 163 {
164 sos_kmem_cache_free((sos_vaddr_t) mmctxt 164 sos_kmem_cache_free((sos_vaddr_t) mmctxt->vaddr_PD);
165 sos_kmem_cache_free((sos_vaddr_t) mmctxt 165 sos_kmem_cache_free((sos_vaddr_t) mmctxt);
166 return NULL; 166 return NULL;
167 } 167 }
168 168
169 169
170 mmctxt->ref_cnt = 1; 170 mmctxt->ref_cnt = 1;
171 171
172 172
173 sos_disable_IRQs(flags); 173 sos_disable_IRQs(flags);
174 list_add_tail(list_mm_context, mmctxt); 174 list_add_tail(list_mm_context, mmctxt);
175 sos_restore_IRQs(flags); 175 sos_restore_IRQs(flags);
176 176
177 return mmctxt; 177 return mmctxt;
178 } 178 }
179 179
180 180
181 struct sos_mm_context * 181 struct sos_mm_context *
182 sos_mm_context_duplicate(const struct sos_mm_c 182 sos_mm_context_duplicate(const struct sos_mm_context *model)
183 { 183 {
184 struct sos_mm_context *mmctxt; 184 struct sos_mm_context *mmctxt;
185 185
186 186
187 mmctxt = sos_mm_context_create(); 187 mmctxt = sos_mm_context_create();
188 if (NULL == mmctxt) 188 if (NULL == mmctxt)
189 return NULL; 189 return NULL;
190 190
191 191
192 if (SOS_OK != sos_paging_copy_user_space(mmc 192 if (SOS_OK != sos_paging_copy_user_space(mmctxt->vaddr_PD,
193 mod 193 model->vaddr_PD))
194 { 194 {
195 sos_mm_context_unref(mmctxt); 195 sos_mm_context_unref(mmctxt);
196 return NULL; 196 return NULL;
197 } 197 }
198 198
199 return mmctxt; 199 return mmctxt;
200 } 200 }
201 201
202 202
203 sos_ret_t sos_mm_context_unref(struct sos_mm_c 203 sos_ret_t sos_mm_context_unref(struct sos_mm_context *mmctxt)
204 { 204 {
205 sos_ui32_t flags; 205 sos_ui32_t flags;
206 206
207 sos_disable_IRQs(flags); 207 sos_disable_IRQs(flags);
208 208
209 209
210 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0); 210 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0);
211 211
212 212
213 mmctxt->ref_cnt --; 213 mmctxt->ref_cnt --;
214 214
215 215
216 if (mmctxt->ref_cnt > 0) 216 if (mmctxt->ref_cnt > 0)
217 { 217 {
218 sos_restore_IRQs(flags); 218 sos_restore_IRQs(flags);
219 return SOS_OK; 219 return SOS_OK;
220 } 220 }
221 221
222 222
223 SOS_ASSERT_FATAL(mmctxt != current_mm_contex 223 SOS_ASSERT_FATAL(mmctxt != current_mm_context);
224 224
225 225
226 list_delete(list_mm_context, mmctxt); 226 list_delete(list_mm_context, mmctxt);
227 227
228 sos_restore_IRQs(flags); 228 sos_restore_IRQs(flags);
229 229
230 230
231 sos_paging_dispose(mmctxt->vaddr_PD); 231 sos_paging_dispose(mmctxt->vaddr_PD);
232 232
233 233
234 sos_kmem_vmm_free(mmctxt->vaddr_PD); 234 sos_kmem_vmm_free(mmctxt->vaddr_PD);
235 235
236 memset(mmctxt, 0x0, sizeof(*mmctxt)); 236 memset(mmctxt, 0x0, sizeof(*mmctxt));
237 237
238 return SOS_OK; 238 return SOS_OK;
239 } 239 }
240 240
241 241
242 sos_ret_t sos_mm_context_ref(struct sos_mm_con 242 sos_ret_t sos_mm_context_ref(struct sos_mm_context *mmctxt)
243 { 243 {
244 sos_ui32_t flags; 244 sos_ui32_t flags;
245 245
246 sos_disable_IRQs(flags); 246 sos_disable_IRQs(flags);
247 247
248 248
249 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0); 249 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0);
250 250
251 251
252 mmctxt->ref_cnt ++; 252 mmctxt->ref_cnt ++;
253 253
254 sos_restore_IRQs(flags); 254 sos_restore_IRQs(flags);
255 255
256 return SOS_OK; 256 return SOS_OK;
257 } 257 }
258 258
259 259
260 sos_ret_t sos_mm_context_switch_to(struct sos_ 260 sos_ret_t sos_mm_context_switch_to(struct sos_mm_context *mmctxt)
261 { 261 {
262 SOS_ASSERT_FATAL(NULL != mmctxt); 262 SOS_ASSERT_FATAL(NULL != mmctxt);
263 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0); 263 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0);
264 SOS_ASSERT_FATAL(current_mm_context->ref_cnt 264 SOS_ASSERT_FATAL(current_mm_context->ref_cnt > 0);
265 if (mmctxt != current_mm_context) 265 if (mmctxt != current_mm_context)
266 { 266 {
267 sos_ui32_t flags; 267 sos_ui32_t flags;
268 struct sos_mm_context * prev_mm_context 268 struct sos_mm_context * prev_mm_context = current_mm_context;
269 269
270 270
271 271
272 272
273 sos_paging_set_current_PD_paddr(mmctxt-> 273 sos_paging_set_current_PD_paddr(mmctxt->paddr_PD);
274 274
275 275
276 current_mm_context = mmctxt; 276 current_mm_context = mmctxt;
277 277
278 278
279 sos_disable_IRQs(flags); 279 sos_disable_IRQs(flags);
280 mmctxt->ref_cnt ++; 280 mmctxt->ref_cnt ++;
281 sos_mm_context_unref(prev_mm_context); 281 sos_mm_context_unref(prev_mm_context);
282 sos_restore_IRQs(flags); 282 sos_restore_IRQs(flags);
283 } 283 }
284 284
285 return SOS_OK; 285 return SOS_OK;
286 } 286 }
287 287
288 288
289 struct sos_mm_context *get_current_mm_context( !! 289 struct sos_mm_context *get_current_mm_context(void)
290 { 290 {
291 SOS_ASSERT_FATAL(current_mm_context->ref_cnt 291 SOS_ASSERT_FATAL(current_mm_context->ref_cnt > 0);
292 return current_mm_context; 292 return current_mm_context;
293 } 293 }
294 294
295 295
296 296
297 297
298 298
299 299
300 300
301 sos_ret_t sos_mm_context_synch_kernel_PDE(unsi 301 sos_ret_t sos_mm_context_synch_kernel_PDE(unsigned int index_in_pd,
302 sos_ 302 sos_ui32_t pde)
303 { 303 {
304 sos_ui32_t flags; 304 sos_ui32_t flags;
305 struct sos_mm_context * dest_mm_context; 305 struct sos_mm_context * dest_mm_context;
306 int nb_mm_contexts; 306 int nb_mm_contexts;
307 307
308 sos_disable_IRQs(flags); 308 sos_disable_IRQs(flags);
309 list_foreach_forward(list_mm_context, dest_m 309 list_foreach_forward(list_mm_context, dest_mm_context, nb_mm_contexts)
310 { 310 {
311 sos_ui32_t * dest_pd; 311 sos_ui32_t * dest_pd;
312 312
313 SOS_ASSERT_FATAL(dest_mm_context->ref_cn 313 SOS_ASSERT_FATAL(dest_mm_context->ref_cnt > 0);
314 314
315 dest_pd = (sos_ui32_t*) dest_mm_context- 315 dest_pd = (sos_ui32_t*) dest_mm_context->vaddr_PD;
316 dest_pd[index_in_pd] = pde; 316 dest_pd[index_in_pd] = pde;
317 } 317 }
318 sos_restore_IRQs(flags); 318 sos_restore_IRQs(flags);
319 319
320 return SOS_OK; 320 return SOS_OK;
321 } 321 }