Rev 1066 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
859 | serge | 1 | |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | #include |
||
6 | |||
7 | |||
1066 | serge | 8 | |
888 | serge | 9 | |
1066 | serge | 10 | #define HF_SIZE (1 << HF_WIDTH) |
11 | |||
886 | serge | 12 | |
1066 | serge | 13 | |
859 | serge | 14 | |
1066 | serge | 15 | |
886 | serge | 16 | |
1066 | serge | 17 | |
888 | serge | 18 | |
859 | serge | 19 | |
1066 | serge | 20 | (index_t)( (frame) - z_heap.frames) |
21 | |||
886 | serge | 22 | |
1066 | serge | 23 | (index_t)( (frame) - z_heap.frames) |
24 | |||
859 | serge | 25 | |
26 | |||
1066 | serge | 27 | { |
28 | frame->refcount = 1; |
||
29 | frame->buddy_order = 0; |
||
30 | } |
||
31 | |||
886 | serge | 32 | |
1066 | serge | 33 | ((frame_t*)(block))->buddy_order |
34 | |||
886 | serge | 35 | |
36 | |||
1066 | serge | 37 | ((frame_t*)(block))->buddy_order = (order) |
38 | |||
859 | serge | 39 | |
1066 | serge | 40 | ((frame_t*)(block))->refcount = 1 |
41 | |||
859 | serge | 42 | |
43 | |||
1066 | serge | 44 | { |
45 | frame_t *frame_l, *frame_r; |
||
46 | |||
859 | serge | 47 | |
1066 | serge | 48 | frame_r = (frame_l + (1 << (frame_l->buddy_order - 1))); |
49 | |||
888 | serge | 50 | |
1066 | serge | 51 | } |
52 | |||
888 | serge | 53 | |
1066 | serge | 54 | { |
859 | serge | 55 | frame_t *frame1, *frame2; |
1066 | serge | 56 | |
859 | serge | 57 | |
1066 | serge | 58 | frame2 = (frame_t*)block_2; |
59 | |||
859 | serge | 60 | |
1066 | serge | 61 | } |
62 | |||
888 | serge | 63 | |
859 | serge | 64 | |
1066 | serge | 65 | (((heap_index_abs((frame)) >> (frame)->buddy_order) & 0x1) == 0) |
66 | |||
886 | serge | 67 | |
1066 | serge | 68 | (((heap_index_abs((frame)) >> (frame)->buddy_order) & 0x1) == 1) |
69 | |||
886 | serge | 70 | |
859 | serge | 71 | |
1066 | serge | 72 | { |
73 | frame_t *frame; |
||
74 | index_t index; |
||
75 | u32_t is_left, is_right; |
||
76 | |||
859 | serge | 77 | |
1066 | serge | 78 | // ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),frame->buddy_order)); |
79 | |||
859 | serge | 80 | |
1066 | serge | 81 | is_right = IS_BUDDY_RIGHT_BLOCK_ABS( frame); |
82 | |||
859 | serge | 83 | |
1066 | serge | 84 | |
859 | serge | 85 | |
1066 | serge | 86 | index = (heap_index(frame)) + (1 << frame->buddy_order); |
87 | } |
||
88 | else { /* if (is_right) */ |
||
89 | index = (heap_index(frame)) - (1 << frame->buddy_order); |
||
90 | }; |
||
91 | |||
859 | serge | 92 | |
93 | |||
1066 | serge | 94 | { |
95 | if (z_heap.frames[index].buddy_order == frame->buddy_order && |
||
96 | z_heap.frames[index].refcount == 0) { |
||
97 | return &z_heap.frames[index].buddy_link; |
||
98 | } |
||
99 | } |
||
100 | |||
859 | serge | 101 | |
1066 | serge | 102 | } |
103 | |||
889 | serge | 104 | |
859 | serge | 105 | |
1066 | serge | 106 | { |
107 | link_t *buddy, *hlp; |
||
108 | u32_t i; |
||
109 | |||
862 | serge | 110 | |
1066 | serge | 111 | * Determine block's order. |
112 | */ |
||
113 | i = buddy_get_order(block); |
||
114 | |||
859 | serge | 115 | |
1066 | serge | 116 | |
886 | serge | 117 | |
1066 | serge | 118 | { |
889 | serge | 119 | /* |
1066 | serge | 120 | * See if there is any buddy in the list of order i. |
121 | */ |
||
122 | buddy = find_buddy( block ); |
||
123 | if (buddy) |
||
124 | { |
||
125 | |||
859 | serge | 126 | |
1066 | serge | 127 | /* |
128 | * Remove buddy from the list of order i. |
||
129 | */ |
||
130 | list_remove(buddy); |
||
131 | |||
859 | serge | 132 | |
1066 | serge | 133 | * Invalidate order of both block and buddy. |
134 | */ |
||
135 | buddy_set_order(block, BUDDY_SYSTEM_INNER_BLOCK); |
||
136 | buddy_set_order(buddy, BUDDY_SYSTEM_INNER_BLOCK); |
||
137 | |||
859 | serge | 138 | |
1066 | serge | 139 | * Coalesce block and buddy into one block. |
140 | */ |
||
141 | hlp = buddy_coalesce( block, buddy ); |
||
142 | |||
859 | serge | 143 | |
1066 | serge | 144 | * Set order of the coalesced block to i + 1. |
145 | */ |
||
146 | buddy_set_order(hlp, i + 1); |
||
147 | |||
859 | serge | 148 | |
1066 | serge | 149 | * Recursively add the coalesced block to the list of order i + 1. |
150 | */ |
||
151 | buddy_system_free( hlp ); |
||
152 | return; |
||
153 | } |
||
154 | } |
||
155 | /* |
||
156 | * Insert block into the list of order i. |
||
157 | */ |
||
158 | list_append(block, &z_heap.order[i]); |
||
159 | } |
||
160 | |||
859 | serge | 161 | |
886 | serge | 162 | |
1066 | serge | 163 | { |
859 | serge | 164 | link_t *res, *hlp; |
1066 | serge | 165 | |
859 | serge | 166 | |
1066 | serge | 167 | |
859 | serge | 168 | |
1066 | serge | 169 | * If the list of order i is not empty, |
170 | * the request can be immediatelly satisfied. |
||
171 | */ |
||
172 | if (!list_empty(&z_heap.order[i])) { |
||
173 | res = z_heap.order[i].next; |
||
174 | list_remove(res); |
||
175 | buddy_mark_busy(res); |
||
176 | return res; |
||
177 | } |
||
178 | /* |
||
179 | * If order i is already the maximal order, |
||
180 | * the request cannot be satisfied. |
||
181 | */ |
||
182 | if (i == z_heap.max_order) |
||
183 | return NULL; |
||
184 | |||
859 | serge | 185 | |
1066 | serge | 186 | * Try to recursively satisfy the request from higher order lists. |
187 | */ |
||
188 | hlp = buddy_system_alloc( i + 1 ); |
||
189 | |||
859 | serge | 190 | |
1066 | serge | 191 | * The request could not be satisfied |
192 | * from higher order lists. |
||
193 | */ |
||
194 | if (!hlp) |
||
195 | return NULL; |
||
196 | |||
859 | serge | 197 | |
1066 | serge | 198 | |
859 | serge | 199 | |
1066 | serge | 200 | * Bisect the block and set order of both of its parts to i. |
201 | */ |
||
202 | hlp = buddy_bisect( res ); |
||
203 | |||
861 | serge | 204 | |
1066 | serge | 205 | buddy_set_order(hlp, i); |
206 | |||
886 | serge | 207 | |
1066 | serge | 208 | * Return the other half to buddy system. Mark the first part |
209 | * full, so that it won't coalesce again. |
||
210 | */ |
||
211 | buddy_mark_busy(res); |
||
212 | buddy_system_free( hlp ); |
||
213 | |||
886 | serge | 214 | |
1066 | serge | 215 | } |
216 | |||
886 | serge | 217 | |
218 | |||
1066 | serge | 219 | { |
220 | count_t i; |
||
221 | count_t count; |
||
222 | |||
886 | serge | 223 | |
1066 | serge | 224 | |
886 | serge | 225 | |
1066 | serge | 226 | ASSERT( count != 0); |
227 | |||
886 | serge | 228 | |
1066 | serge | 229 | |
886 | serge | 230 | |
1066 | serge | 231 | z_heap.count = count; |
232 | z_heap.free_count = count; |
||
233 | z_heap.busy_count = 0; |
||
234 | |||
861 | serge | 235 | |
1066 | serge | 236 | |
888 | serge | 237 | |
1066 | serge | 238 | |
862 | serge | 239 | |
1066 | serge | 240 | |
862 | serge | 241 | |
1066 | serge | 242 | list_initialize(&z_heap.order[i]); |
243 | |||
862 | serge | 244 | |
859 | serge | 245 | |
1066 | serge | 246 | count, sizeof(frame_t), PAGE_SIZE); |
247 | |||
859 | serge | 248 | |
1066 | serge | 249 | |
859 | serge | 250 | |
251 | |||
1066 | serge | 252 | return 0; |
253 | |||
859 | serge | 254 | |
255 | |||
1066 | serge | 256 | z_heap.frames[i].buddy_order=0; |
257 | z_heap.frames[i].parent = NULL; |
||
258 | z_heap.frames[i].refcount=1; |
||
259 | } |
||
260 | |||
859 | serge | 261 | |
1066 | serge | 262 | { |
263 | z_heap.frames[i].refcount = 0; |
||
264 | buddy_system_free(&z_heap.frames[i].buddy_link); |
||
265 | } |
||
266 | |||
861 | serge | 267 | |
1066 | serge | 268 | |
861 | serge | 269 | |
1066 | serge | 270 | } |
859 | serge | 271 | |
272 | |||
1066 | serge | 273 | { |
886 | serge | 274 | eflags_t efl; |
1066 | serge | 275 | addr_t heap = 0; |
276 | |||
888 | serge | 277 | |
1066 | serge | 278 | frame_t *frame; |
279 | index_t v; |
||
280 | int i; |
||
281 | mmap_t *map; |
||
282 | count_t pages; |
||
283 | |||
888 | serge | 284 | |
1066 | serge | 285 | |
888 | serge | 286 | |
1066 | serge | 287 | |
888 | serge | 288 | |
1066 | serge | 289 | |
888 | serge | 290 | |
1066 | serge | 291 | // sizeof(addr_t) * pages); |
292 | |||
888 | serge | 293 | |
1066 | serge | 294 | sizeof(addr_t) * pages) >> PAGE_WIDTH)); |
295 | |||
888 | serge | 296 | |
1066 | serge | 297 | |
298 | |||
299 | { |
||
888 | serge | 300 | order = size >> HF_WIDTH; |
1066 | serge | 301 | |
888 | serge | 302 | |
1066 | serge | 303 | order = fnzb(order - 1) + 1; |
304 | |||
888 | serge | 305 | |
1066 | serge | 306 | |
888 | serge | 307 | |
1066 | serge | 308 | |
888 | serge | 309 | |
1066 | serge | 310 | |
888 | serge | 311 | |
1066 | serge | 312 | |
888 | serge | 313 | |
1066 | serge | 314 | { |
888 | serge | 315 | addr_t page = 0; |
1066 | serge | 316 | addr_t mem; |
317 | |||
888 | serge | 318 | |
1066 | serge | 319 | z_heap.busy_count += (1 << order); |
320 | |||
888 | serge | 321 | |
1066 | serge | 322 | |
888 | serge | 323 | |
1066 | serge | 324 | |
888 | serge | 325 | |
1066 | serge | 326 | |
888 | serge | 327 | |
1066 | serge | 328 | |
888 | serge | 329 | |
1066 | serge | 330 | frame[i].parent = map; |
331 | |||
888 | serge | 332 | |
1066 | serge | 333 | |
888 | serge | 334 | |
1066 | serge | 335 | |
888 | serge | 336 | |
337 | |||
1066 | serge | 338 | addr_t *mpte = &map->pte[0]; |
339 | |||
888 | serge | 340 | |
1313 | serge | 341 | |
342 | |||
1066 | serge | 343 | { |
888 | serge | 344 | |
345 | |||
1313 | serge | 346 | |
347 | |||
348 | { |
||
349 | u32_t order; |
||
350 | addr_t page_frame; |
||
351 | |||
352 | |||
353 | asm volatile ("btr %0, %1" :"=r"(tmp):"r"(order):"cc"); |
||
354 | |||
355 | |||
356 | |||
357 | |||
358 | { |
||
359 | *pte++ = 0; //page; |
||
360 | *mpte++ = page; |
||
361 | |||
362 | |||
363 | mem+= 4096; |
||
364 | }; |
||
365 | } |
||
366 | #else |
||
1066 | serge | 367 | |
888 | serge | 368 | |
1313 | serge | 369 | |
370 | |||
371 | { |
||
372 | *pte++ = 0; |
||
373 | *mpte++ = page; |
||
374 | asm volatile ( "invlpg (%0)" ::"r" (mem) ); |
||
375 | mem+= 4096; |
||
376 | }; |
||
377 | #endif |
||
378 | } |
||
379 | else |
||
380 | { |
||
1066 | serge | 381 | while(pages--) |
1313 | serge | 382 | { |
383 | *pte++ = 0; //page; |
||
384 | *mpte++ = 0; |
||
385 | |||
888 | serge | 386 | |
1313 | serge | 387 | mem+= 4096; |
388 | }; |
||
389 | } |
||
390 | |||
888 | serge | 391 | |
1066 | serge | 392 | DBG("%s %x size %d order %d\n", __FUNCTION__, heap, size, order); |
393 | |||
888 | serge | 394 | |
1066 | serge | 395 | } |
396 | |||
886 | serge | 397 | |
1066 | serge | 398 | |
888 | serge | 399 | |
1066 | serge | 400 | |
886 | serge | 401 | |
1066 | serge | 402 | }; |
403 | |||
886 | serge | 404 | |
1066 | serge | 405 | } |
406 | |||
886 | serge | 407 | |
1066 | serge | 408 | { |
409 | eflags_t efl; |
||
410 | frame_t *frame; |
||
411 | count_t idx; |
||
412 | |||
886 | serge | 413 | |
1066 | serge | 414 | |
886 | serge | 415 | |
1066 | serge | 416 | (idx >= z_heap.base+z_heap.count)) { |
417 | DBG("invalid address %x\n", addr); |
||
418 | return; |
||
419 | } |
||
420 | |||
886 | serge | 421 | |
1066 | serge | 422 | |
886 | serge | 423 | |
1066 | serge | 424 | |
886 | serge | 425 | |
1066 | serge | 426 | |
886 | serge | 427 | |
1066 | serge | 428 | |
886 | serge | 429 | |
1066 | serge | 430 | |
886 | serge | 431 | |
1066 | serge | 432 | |
886 | serge | 433 | |
1066 | serge | 434 | { |
888 | serge | 435 | mmap_t *map; |
1066 | serge | 436 | count_t i; |
437 | |||
888 | serge | 438 | |
1066 | serge | 439 | |
859 | serge | 440 | |
1066 | serge | 441 | frame[i].parent = NULL; |
442 | |||
859 | serge | 443 | |
1066 | serge | 444 | |
859 | serge | 445 | |
1066 | serge | 446 | z_heap.free_count += (1 << order); |
447 | z_heap.busy_count -= (1 << order); |
||
448 | |||
888 | serge | 449 | |
1066 | serge | 450 | safe_sti(efl); |
451 | |||
859 | serge | 452 | |
1313 | serge | 453 | { |
454 | i+= frame_free(map->pte[i]); |
||
455 | } |
||
456 | |||
859 | serge | 457 | |
1066 | serge | 458 | } |
459 | else |
||
888 | serge | 460 | { |
461 | spinlock_unlock(&z_heap.lock); |
||
1066 | serge | 462 | safe_sti(efl); |
463 | }; |
||
888 | serge | 464 | }; |
859 | serge | 465 | |
466 | |||
1066 | serge | 467 | { |
859 | serge | 468 | index_t idx; |
1066 | serge | 469 | frame_t *frame; |
470 | mmap_t *map; |
||
471 | |||
859 | serge | 472 | |
1066 | serge | 473 | |
859 | serge | 474 | |
1066 | serge | 475 | |
886 | serge | 476 | |
1066 | serge | 477 | |
886 | serge | 478 | |
1066 | serge | 479 | |
886 | serge | 480 | |
1066 | serge | 481 | { |
889 | serge | 482 | addr_t page; |
1066 | serge | 483 | |
886 | serge | 484 | |
1066 | serge | 485 | |
889 | serge | 486 | |
1066 | serge | 487 | |
889 | serge | 488 | |
1066 | serge | 489 | { |
892 | serge | 490 | if( page & PG_DEMAND) |
1066 | serge | 491 | { |
492 | page &= ~PG_DEMAND; |
||
493 | page = alloc_page() | (page & 0xFFF); |
||
494 | |||
892 | serge | 495 | |
1066 | serge | 496 | }; |
892 | serge | 497 | ((addr_t*)page_tabs)[faddr >> PAGE_WIDTH] = page; |
1066 | serge | 498 | }; |
499 | }; |
||
889 | serge | 500 | }; |
859 | serge | 501 | |
502 | |||
1066 | serge | 503 |