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