Rev 538 | Rev 541 | Go to most recent revision | Show entire file | Regard 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); |
|
- | 133 | ||
- | 134 | /* Update zone information. */ |
|
- | 135 | zone->free_count -= (1 << order); |
|
- | 136 | zone->busy_count += (1 << order); |
|
126 | 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 189... | Line 201... | ||
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 | } |
193 | 205 | ||
194 | spinlock_unlock(&zone->lock); |
206 | /* Update zone information. */ |
- | 207 | zone->free_count += (1 << frame->buddy_order); |
|
- | 208 | zone->busy_count -= (1 << frame->buddy_order); |
|
195 | 209 | ||
- | 210 | spinlock_unlock(&zone->lock); |
|
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 405... | Line 421... | ||
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. |