Rev 538 | Rev 541 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 538 | Rev 539 | ||
|---|---|---|---|
| Line 41... | Line 41... | ||
| 41 | #include <align.h> |
41 | #include <align.h> |
| 42 | 42 | ||
| 43 | spinlock_t zone_head_lock; /**< this lock protects zone_head list */ |
43 | spinlock_t zone_head_lock; /**< this lock protects zone_head list */ |
| 44 | link_t zone_head; /**< list of all zones in the system */ |
44 | link_t zone_head; /**< list of all zones in the system */ |
| 45 | 45 | ||
| - | 46 | /** Blacklist containing non-available areas of memory. |
|
| - | 47 | * |
|
| - | 48 | * This blacklist is used to exclude frames that cannot be allocated |
|
| - | 49 | * (e.g. kernel memory) from available memory map. |
|
| - | 50 | */ |
|
| 46 | region_t zone_blacklist[ZONE_BLACKLIST_SIZE]; |
51 | region_t zone_blacklist[ZONE_BLACKLIST_SIZE]; |
| 47 | count_t zone_blacklist_count = 0; |
52 | count_t zone_blacklist_count = 0; |
| 48 | 53 | ||
| 49 | static struct buddy_system_operations zone_buddy_system_operations = { |
54 | static struct buddy_system_operations zone_buddy_system_operations = { |
| 50 | .find_buddy = zone_buddy_find_buddy, |
55 | .find_buddy = zone_buddy_find_buddy, |
| Line 120... | Line 125... | ||
| 120 | goto loop; |
125 | goto loop; |
| 121 | } |
126 | } |
| 122 | 127 | ||
| 123 | 128 | ||
| 124 | /* Allocate frames from zone buddy system */ |
129 | /* Allocate frames from zone buddy system */ |
| 125 | cur = buddy_system_alloc(zone->buddy_system, order); |
130 | tmp = buddy_system_alloc(zone->buddy_system, order); |
| - | 131 | ||
| - | 132 | ASSERT(tmp); |
|
| 126 | 133 | ||
| - | 134 | /* Update zone information. */ |
|
| - | 135 | zone->free_count -= (1 << order); |
|
| - | 136 | zone->busy_count += (1 << order); |
|
| - | 137 | ||
| 127 | /* frame will be actually a first frame of the block */ |
138 | /* Frame will be actually a first frame of the block. */ |
| 128 | frame = list_get_instance(cur, frame_t, buddy_link); |
139 | frame = list_get_instance(tmp, frame_t, buddy_link); |
| 129 | 140 | ||
| 130 | /* get frame address */ |
141 | /* get frame address */ |
| 131 | v = FRAME2ADDR(zone, frame); |
142 | v = FRAME2ADDR(zone, frame); |
| 132 | 143 | ||
| 133 | if (flags & FRAME_KA) |
- | |
| 134 | v = PA2KA(v); |
- | |
| 135 | - | ||
| 136 | spinlock_unlock(&zone->lock); |
144 | spinlock_unlock(&zone->lock); |
| 137 | spinlock_unlock(&zone_head_lock); |
145 | spinlock_unlock(&zone_head_lock); |
| 138 | interrupts_restore(ipl); |
146 | interrupts_restore(ipl); |
| 139 | return v; |
- | |
| 140 | 147 | ||
| - | 148 | ||
| - | 149 | if (flags & FRAME_KA) |
|
| - | 150 | v = PA2KA(v); |
|
| - | 151 | ||
| - | 152 | return v; |
|
| 141 | } |
153 | } |
| 142 | 154 | ||
| 143 | /** Free a frame. |
155 | /** Free a frame. |
| 144 | * |
156 | * |
| 145 | * Find respective frame structrue for supplied addr. |
157 | * Find respective frame structrue for supplied addr. |
| Line 188... | Line 200... | ||
| 188 | ASSERT(frame->refcount); |
200 | ASSERT(frame->refcount); |
| 189 | 201 | ||
| 190 | if (!--frame->refcount) { |
202 | if (!--frame->refcount) { |
| 191 | buddy_system_free(zone->buddy_system, &frame->buddy_link); |
203 | buddy_system_free(zone->buddy_system, &frame->buddy_link); |
| 192 | } |
204 | } |
| - | 205 | ||
| - | 206 | /* Update zone information. */ |
|
| - | 207 | zone->free_count += (1 << frame->buddy_order); |
|
| - | 208 | zone->busy_count -= (1 << frame->buddy_order); |
|
| 193 | 209 | ||
| 194 | spinlock_unlock(&zone->lock); |
210 | spinlock_unlock(&zone->lock); |
| 195 | - | ||
| 196 | spinlock_unlock(&zone_head_lock); |
211 | spinlock_unlock(&zone_head_lock); |
| 197 | interrupts_restore(ipl); |
212 | interrupts_restore(ipl); |
| 198 | } |
213 | } |
| 199 | 214 | ||
| 200 | /** Mark frame region not free. |
215 | /** Mark frame region not free. |
| Line 228... | Line 243... | ||
| 228 | { |
243 | { |
| 229 | spinlock_initialize(&zone_head_lock); |
244 | spinlock_initialize(&zone_head_lock); |
| 230 | list_initialize(&zone_head); |
245 | list_initialize(&zone_head); |
| 231 | } |
246 | } |
| 232 | 247 | ||
| - | 248 | /** Create frame zones in region of available memory. |
|
| - | 249 | * |
|
| - | 250 | * Avoid any black listed areas of non-available memory. |
|
| - | 251 | * Assume that the black listed areas cannot overlap |
|
| - | 252 | * one another or cross available memory region boundaries. |
|
| 233 | 253 | * |
|
| - | 254 | * @param base Base address of available memory region. |
|
| - | 255 | * @param size Size of the region. |
|
| - | 256 | */ |
|
| 234 | void zone_create_in_region(__address base, size_t size) { |
257 | void zone_create_in_region(__address base, size_t size) { |
| 235 | int i; |
258 | int i; |
| 236 | zone_t * z; |
259 | zone_t * z; |
| 237 | __address s; |
260 | __address s; |
| 238 | size_t sz; |
261 | size_t sz; |
| Line 266... | Line 289... | ||
| 266 | 289 | ||
| 267 | zone_attach(z); |
290 | zone_attach(z); |
| 268 | } |
291 | } |
| 269 | 292 | ||
| 270 | 293 | ||
| 271 | - | ||
| 272 | /** Create frame zone |
294 | /** Create frame zone |
| 273 | * |
295 | * |
| 274 | * Create new frame zone. |
296 | * Create new frame zone. |
| 275 | * |
297 | * |
| 276 | * @param start Physical address of the first frame within the zone. |
298 | * @param start Physical address of the first frame within the zone. |
| Line 371... | Line 393... | ||
| 371 | * @param block Block for which buddy should be found |
393 | * @param block Block for which buddy should be found |
| 372 | * |
394 | * |
| 373 | * @return Buddy for given block if found |
395 | * @return Buddy for given block if found |
| 374 | */ |
396 | */ |
| 375 | link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) { |
397 | link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) { |
| 376 | frame_t * frame, * f; |
398 | frame_t * frame; |
| 377 | zone_t * zone; |
399 | zone_t * zone; |
| 378 | link_t * cur; |
- | |
| 379 | count_t index; |
400 | count_t index; |
| 380 | bool is_left, is_right; |
401 | bool is_left, is_right; |
| 381 | 402 | ||
| 382 | frame = list_get_instance(block, frame_t, buddy_link); |
403 | frame = list_get_instance(block, frame_t, buddy_link); |
| 383 | zone = (zone_t *) b->data; |
404 | zone = (zone_t *) b->data; |
| 384 | 405 | ||
| 385 | /* |
- | |
| 386 | * (FRAME_INDEX % 2^(ORDER+1)) == 0 ===> LEFT BUDDY |
- | |
| 387 | * (FRAME_INDEX % 2^(ORDER+1)) == 2^(ORDER) ===> RIGHT BUDDY |
- | |
| 388 | */ |
- | |
| 389 | - | ||
| 390 | is_left = IS_BUDDY_LEFT_BLOCK(zone, frame); |
406 | is_left = IS_BUDDY_LEFT_BLOCK(zone, frame); |
| 391 | is_right = !is_left; |
407 | is_right = !is_left; |
| 392 | 408 | ||
| 393 | /* |
409 | /* |
| 394 | * test left buddy |
410 | * test left buddy |
| Line 404... | Line 420... | ||
| 404 | zone->frames[index].refcount == 0) { |
420 | zone->frames[index].refcount == 0) { |
| 405 | return &zone->frames[index].buddy_link; |
421 | return &zone->frames[index].buddy_link; |
| 406 | } |
422 | } |
| 407 | } |
423 | } |
| 408 | 424 | ||
| 409 | return NULL; |
425 | return NULL; |
| 410 | - | ||
| 411 | } |
426 | } |
| 412 | 427 | ||
| 413 | /** Buddy system bisect implementation |
428 | /** Buddy system bisect implementation |
| 414 | * |
429 | * |
| 415 | * @param b Buddy system. |
430 | * @param b Buddy system. |