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