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