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->vaddr_PD);
155 sos_kmem_cache_free((sos_vaddr_t) mmctxt 156 sos_kmem_cache_free((sos_vaddr_t) mmctxt);
156 return NULL; 157 return NULL;
157 } 158 }
158 159
159 160
160 if (SOS_OK != sos_paging_copy_kernel_space(m 161 if (SOS_OK != sos_paging_copy_kernel_space(mmctxt->vaddr_PD,
161 c 162 current_mm_context->vaddr_PD))
162 { 163 {
>> 164 sos_kmem_cache_free((sos_vaddr_t) mmctxt->vaddr_PD);
163 sos_kmem_cache_free((sos_vaddr_t) mmctxt 165 sos_kmem_cache_free((sos_vaddr_t) mmctxt);
164 return NULL; 166 return NULL;
165 } 167 }
166 168
167 169
168 mmctxt->ref_cnt = 1; 170 mmctxt->ref_cnt = 1;
169 171
170 172
171 sos_disable_IRQs(flags); 173 sos_disable_IRQs(flags);
172 list_add_tail(list_mm_context, mmctxt); 174 list_add_tail(list_mm_context, mmctxt);
173 sos_restore_IRQs(flags); 175 sos_restore_IRQs(flags);
174 176
175 return mmctxt; 177 return mmctxt;
176 } 178 }
177 179
178 180
179 struct sos_mm_context * 181 struct sos_mm_context *
180 sos_mm_context_duplicate(const struct sos_mm_c 182 sos_mm_context_duplicate(const struct sos_mm_context *model)
181 { 183 {
182 struct sos_mm_context *mmctxt; 184 struct sos_mm_context *mmctxt;
183 185
184 186
185 mmctxt = sos_mm_context_create(); 187 mmctxt = sos_mm_context_create();
186 if (NULL == mmctxt) 188 if (NULL == mmctxt)
187 return NULL; 189 return NULL;
188 190
189 191
190 if (SOS_OK != sos_paging_copy_user_space(mmc 192 if (SOS_OK != sos_paging_copy_user_space(mmctxt->vaddr_PD,
191 mod 193 model->vaddr_PD))
192 { 194 {
193 sos_mm_context_unref(mmctxt); 195 sos_mm_context_unref(mmctxt);
194 return NULL; 196 return NULL;
195 } 197 }
196 198
197 return mmctxt; 199 return mmctxt;
198 } 200 }
199 201
200 202
201 sos_ret_t sos_mm_context_unref(struct sos_mm_c 203 sos_ret_t sos_mm_context_unref(struct sos_mm_context *mmctxt)
202 { 204 {
203 sos_ui32_t flags; 205 sos_ui32_t flags;
204 206
205 sos_disable_IRQs(flags); 207 sos_disable_IRQs(flags);
206 208
207 209
208 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0); 210 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0);
209 211
210 212
211 mmctxt->ref_cnt --; 213 mmctxt->ref_cnt --;
212 214
213 215
214 if (mmctxt->ref_cnt > 0) 216 if (mmctxt->ref_cnt > 0)
215 { 217 {
216 sos_restore_IRQs(flags); 218 sos_restore_IRQs(flags);
217 return SOS_OK; 219 return SOS_OK;
218 } 220 }
219 221
220 222
221 SOS_ASSERT_FATAL(mmctxt != current_mm_contex 223 SOS_ASSERT_FATAL(mmctxt != current_mm_context);
222 224
223 225
224 list_delete(list_mm_context, mmctxt); 226 list_delete(list_mm_context, mmctxt);
225 227
226 sos_restore_IRQs(flags); 228 sos_restore_IRQs(flags);
227 229
228 230
229 sos_paging_dispose(mmctxt->vaddr_PD); 231 sos_paging_dispose(mmctxt->vaddr_PD);
230 232
231 233
232 sos_kmem_vmm_free(mmctxt->vaddr_PD); 234 sos_kmem_vmm_free(mmctxt->vaddr_PD);
233 235
234 memset(mmctxt, 0x0, sizeof(*mmctxt)); 236 memset(mmctxt, 0x0, sizeof(*mmctxt));
235 237
236 return SOS_OK; 238 return SOS_OK;
237 } 239 }
238 240
239 241
240 sos_ret_t sos_mm_context_ref(struct sos_mm_con 242 sos_ret_t sos_mm_context_ref(struct sos_mm_context *mmctxt)
241 { 243 {
242 sos_ui32_t flags; 244 sos_ui32_t flags;
243 245
244 sos_disable_IRQs(flags); 246 sos_disable_IRQs(flags);
245 247
246 248
247 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0); 249 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0);
248 250
249 251
250 mmctxt->ref_cnt ++; 252 mmctxt->ref_cnt ++;
251 253
252 sos_restore_IRQs(flags); 254 sos_restore_IRQs(flags);
253 255
254 return SOS_OK; 256 return SOS_OK;
255 } 257 }
256 258
257 259
258 sos_ret_t sos_mm_context_switch_to(struct sos_ 260 sos_ret_t sos_mm_context_switch_to(struct sos_mm_context *mmctxt)
259 { 261 {
260 SOS_ASSERT_FATAL(NULL != mmctxt); 262 SOS_ASSERT_FATAL(NULL != mmctxt);
261 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0); 263 SOS_ASSERT_FATAL(mmctxt->ref_cnt > 0);
262 SOS_ASSERT_FATAL(current_mm_context->ref_cnt 264 SOS_ASSERT_FATAL(current_mm_context->ref_cnt > 0);
263 if (mmctxt != current_mm_context) 265 if (mmctxt != current_mm_context)
264 { 266 {
265 sos_ui32_t flags; 267 sos_ui32_t flags;
266 struct sos_mm_context * prev_mm_context 268 struct sos_mm_context * prev_mm_context = current_mm_context;
267 269
268 270
269 271
270 272
271 sos_paging_set_current_PD_paddr(mmctxt-> 273 sos_paging_set_current_PD_paddr(mmctxt->paddr_PD);
272 274
273 275
274 current_mm_context = mmctxt; 276 current_mm_context = mmctxt;
275 277
276 278
277 sos_disable_IRQs(flags); 279 sos_disable_IRQs(flags);
278 mmctxt->ref_cnt ++; 280 mmctxt->ref_cnt ++;
279 sos_mm_context_unref(prev_mm_context); 281 sos_mm_context_unref(prev_mm_context);
280 sos_restore_IRQs(flags); 282 sos_restore_IRQs(flags);
281 } 283 }
282 284
283 return SOS_OK; 285 return SOS_OK;
284 } 286 }
285 287
286 288
287 struct sos_mm_context *get_current_mm_context( 289 struct sos_mm_context *get_current_mm_context()
288 { 290 {
289 SOS_ASSERT_FATAL(current_mm_context->ref_cnt 291 SOS_ASSERT_FATAL(current_mm_context->ref_cnt > 0);
290 return current_mm_context; 292 return current_mm_context;
291 } 293 }
292 294
293 295
294 296
295 297
296 298
297 299
298 300
299 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,
300 sos_ 302 sos_ui32_t pde)
301 { 303 {
302 sos_ui32_t flags; 304 sos_ui32_t flags;
303 struct sos_mm_context * dest_mm_context; 305 struct sos_mm_context * dest_mm_context;
304 int nb_mm_contexts; 306 int nb_mm_contexts;
305 307
306 sos_disable_IRQs(flags); 308 sos_disable_IRQs(flags);
307 list_foreach_forward(list_mm_context, dest_m 309 list_foreach_forward(list_mm_context, dest_mm_context, nb_mm_contexts)
308 { 310 {
309 sos_ui32_t * dest_pd; 311 sos_ui32_t * dest_pd;
310 312
311 SOS_ASSERT_FATAL(dest_mm_context->ref_cn 313 SOS_ASSERT_FATAL(dest_mm_context->ref_cnt > 0);
312 314
313 dest_pd = (sos_ui32_t*) dest_mm_context- 315 dest_pd = (sos_ui32_t*) dest_mm_context->vaddr_PD;
314 dest_pd[index_in_pd] = pde; 316 dest_pd[index_in_pd] = pde;
315 } 317 }
316 sos_restore_IRQs(flags); 318 sos_restore_IRQs(flags);
317 319
318 return SOS_OK; 320 return SOS_OK;
319 } 321 }