Rev 4263 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4263 | Rev 4581 | ||
---|---|---|---|
Line 65... | Line 65... | ||
65 | * Synchronization primitives used to sleep when there is no memory |
65 | * Synchronization primitives used to sleep when there is no memory |
66 | * available. |
66 | * available. |
67 | */ |
67 | */ |
68 | mutex_t mem_avail_mtx; |
68 | mutex_t mem_avail_mtx; |
69 | condvar_t mem_avail_cv; |
69 | condvar_t mem_avail_cv; |
70 | count_t mem_avail_req = 0; /**< Number of frames requested. */ |
70 | size_t mem_avail_req = 0; /**< Number of frames requested. */ |
71 | count_t mem_avail_gen = 0; /**< Generation counter. */ |
71 | size_t mem_avail_gen = 0; /**< Generation counter. */ |
72 | 72 | ||
73 | /********************/ |
73 | /********************/ |
74 | /* Helper functions */ |
74 | /* Helper functions */ |
75 | /********************/ |
75 | /********************/ |
76 | 76 | ||
77 | static inline index_t frame_index(zone_t *zone, frame_t *frame) |
77 | static inline size_t frame_index(zone_t *zone, frame_t *frame) |
78 | { |
78 | { |
79 | return (index_t) (frame - zone->frames); |
79 | return (size_t) (frame - zone->frames); |
80 | } |
80 | } |
81 | 81 | ||
82 | static inline index_t frame_index_abs(zone_t *zone, frame_t *frame) |
82 | static inline size_t frame_index_abs(zone_t *zone, frame_t *frame) |
83 | { |
83 | { |
84 | return (index_t) (frame - zone->frames) + zone->base; |
84 | return (size_t) (frame - zone->frames) + zone->base; |
85 | } |
85 | } |
86 | 86 | ||
87 | static inline bool frame_index_valid(zone_t *zone, index_t index) |
87 | static inline bool frame_index_valid(zone_t *zone, size_t index) |
88 | { |
88 | { |
89 | return (index < zone->count); |
89 | return (index < zone->count); |
90 | } |
90 | } |
91 | 91 | ||
92 | static inline index_t make_frame_index(zone_t *zone, frame_t *frame) |
92 | static inline size_t make_frame_index(zone_t *zone, frame_t *frame) |
93 | { |
93 | { |
94 | return (frame - zone->frames); |
94 | return (frame - zone->frames); |
95 | } |
95 | } |
96 | 96 | ||
97 | /** Initialize frame structure. |
97 | /** Initialize frame structure. |
Line 118... | Line 118... | ||
118 | * @param count Number of frames of the newly inserted zone. |
118 | * @param count Number of frames of the newly inserted zone. |
119 | * |
119 | * |
120 | * @return Zone number on success, -1 on error. |
120 | * @return Zone number on success, -1 on error. |
121 | * |
121 | * |
122 | */ |
122 | */ |
123 | static count_t zones_insert_zone(pfn_t base, count_t count) |
123 | static size_t zones_insert_zone(pfn_t base, size_t count) |
124 | { |
124 | { |
125 | if (zones.count + 1 == ZONES_MAX) { |
125 | if (zones.count + 1 == ZONES_MAX) { |
126 | printf("Maximum zone count %u exceeded!\n", ZONES_MAX); |
126 | printf("Maximum zone count %u exceeded!\n", ZONES_MAX); |
127 | return (count_t) -1; |
127 | return (size_t) -1; |
128 | } |
128 | } |
129 | 129 | ||
130 | count_t i; |
130 | size_t i; |
131 | for (i = 0; i < zones.count; i++) { |
131 | for (i = 0; i < zones.count; i++) { |
132 | /* Check for overlap */ |
132 | /* Check for overlap */ |
133 | if (overlaps(base, count, |
133 | if (overlaps(base, count, |
134 | zones.info[i].base, zones.info[i].count)) { |
134 | zones.info[i].base, zones.info[i].count)) { |
135 | printf("Zones overlap!\n"); |
135 | printf("Zones overlap!\n"); |
136 | return (count_t) -1; |
136 | return (size_t) -1; |
137 | } |
137 | } |
138 | if (base < zones.info[i].base) |
138 | if (base < zones.info[i].base) |
139 | break; |
139 | break; |
140 | } |
140 | } |
141 | 141 | ||
142 | /* Move other zones up */ |
142 | /* Move other zones up */ |
143 | count_t j; |
143 | size_t j; |
144 | for (j = zones.count; j > i; j--) { |
144 | for (j = zones.count; j > i; j--) { |
145 | zones.info[j] = zones.info[j - 1]; |
145 | zones.info[j] = zones.info[j - 1]; |
146 | zones.info[j].buddy_system->data = |
146 | zones.info[j].buddy_system->data = |
147 | (void *) &zones.info[j - 1]; |
147 | (void *) &zones.info[j - 1]; |
148 | } |
148 | } |
Line 159... | Line 159... | ||
159 | * |
159 | * |
160 | * @return Total number of available frames. |
160 | * @return Total number of available frames. |
161 | * |
161 | * |
162 | */ |
162 | */ |
163 | #ifdef CONFIG_DEBUG |
163 | #ifdef CONFIG_DEBUG |
164 | static count_t total_frames_free(void) |
164 | static size_t total_frames_free(void) |
165 | { |
165 | { |
166 | count_t total = 0; |
166 | size_t total = 0; |
167 | count_t i; |
167 | size_t i; |
168 | for (i = 0; i < zones.count; i++) |
168 | for (i = 0; i < zones.count; i++) |
169 | total += zones.info[i].free_count; |
169 | total += zones.info[i].free_count; |
170 | 170 | ||
171 | return total; |
171 | return total; |
172 | } |
172 | } |
Line 182... | Line 182... | ||
182 | * @param hint Used as zone hint. |
182 | * @param hint Used as zone hint. |
183 | * |
183 | * |
184 | * @return Zone index or -1 if not found. |
184 | * @return Zone index or -1 if not found. |
185 | * |
185 | * |
186 | */ |
186 | */ |
187 | count_t find_zone(pfn_t frame, count_t count, count_t hint) |
187 | size_t find_zone(pfn_t frame, size_t count, size_t hint) |
188 | { |
188 | { |
189 | if (hint >= zones.count) |
189 | if (hint >= zones.count) |
190 | hint = 0; |
190 | hint = 0; |
191 | 191 | ||
192 | count_t i = hint; |
192 | size_t i = hint; |
193 | do { |
193 | do { |
194 | if ((zones.info[i].base <= frame) |
194 | if ((zones.info[i].base <= frame) |
195 | && (zones.info[i].base + zones.info[i].count >= frame + count)) |
195 | && (zones.info[i].base + zones.info[i].count >= frame + count)) |
196 | return i; |
196 | return i; |
197 | 197 | ||
198 | i++; |
198 | i++; |
199 | if (i >= zones.count) |
199 | if (i >= zones.count) |
200 | i = 0; |
200 | i = 0; |
201 | } while (i != hint); |
201 | } while (i != hint); |
202 | 202 | ||
203 | return (count_t) -1; |
203 | return (size_t) -1; |
204 | } |
204 | } |
205 | 205 | ||
206 | /** @return True if zone can allocate specified order */ |
206 | /** @return True if zone can allocate specified order */ |
207 | static bool zone_can_alloc(zone_t *zone, uint8_t order) |
207 | static bool zone_can_alloc(zone_t *zone, uint8_t order) |
208 | { |
208 | { |
Line 218... | Line 218... | ||
218 | * @param order Size (2^order) of free space we are trying to find. |
218 | * @param order Size (2^order) of free space we are trying to find. |
219 | * @param flags Required flags of the target zone. |
219 | * @param flags Required flags of the target zone. |
220 | * @param hind Preferred zone. |
220 | * @param hind Preferred zone. |
221 | * |
221 | * |
222 | */ |
222 | */ |
223 | static count_t find_free_zone(uint8_t order, zone_flags_t flags, count_t hint) |
223 | static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint) |
224 | { |
224 | { |
225 | if (hint >= zones.count) |
225 | if (hint >= zones.count) |
226 | hint = 0; |
226 | hint = 0; |
227 | 227 | ||
228 | count_t i = hint; |
228 | size_t i = hint; |
229 | do { |
229 | do { |
230 | /* |
230 | /* |
231 | * Check whether the zone meets the search criteria. |
231 | * Check whether the zone meets the search criteria. |
232 | */ |
232 | */ |
233 | if ((zones.info[i].flags & flags) == flags) { |
233 | if ((zones.info[i].flags & flags) == flags) { |
Line 241... | Line 241... | ||
241 | i++; |
241 | i++; |
242 | if (i >= zones.count) |
242 | if (i >= zones.count) |
243 | i = 0; |
243 | i = 0; |
244 | } while (i != hint); |
244 | } while (i != hint); |
245 | 245 | ||
246 | return (count_t) -1; |
246 | return (size_t) -1; |
247 | } |
247 | } |
248 | 248 | ||
249 | /**************************/ |
249 | /**************************/ |
250 | /* Buddy system functions */ |
250 | /* Buddy system functions */ |
251 | /**************************/ |
251 | /**************************/ |
Line 263... | Line 263... | ||
263 | uint8_t order) |
263 | uint8_t order) |
264 | { |
264 | { |
265 | frame_t *frame = list_get_instance(child, frame_t, buddy_link); |
265 | frame_t *frame = list_get_instance(child, frame_t, buddy_link); |
266 | zone_t *zone = (zone_t *) buddy->data; |
266 | zone_t *zone = (zone_t *) buddy->data; |
267 | 267 | ||
268 | index_t index = frame_index(zone, frame); |
268 | size_t index = frame_index(zone, frame); |
269 | do { |
269 | do { |
270 | if (zone->frames[index].buddy_order != order) |
270 | if (zone->frames[index].buddy_order != order) |
271 | return &zone->frames[index].buddy_link; |
271 | return &zone->frames[index].buddy_link; |
272 | } while (index-- > 0); |
272 | } while (index-- > 0); |
273 | 273 | ||
Line 289... | Line 289... | ||
289 | ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), |
289 | ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), |
290 | frame->buddy_order)); |
290 | frame->buddy_order)); |
291 | 291 | ||
292 | bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); |
292 | bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); |
293 | 293 | ||
294 | index_t index; |
294 | size_t index; |
295 | if (is_left) { |
295 | if (is_left) { |
296 | index = (frame_index(zone, frame)) + |
296 | index = (frame_index(zone, frame)) + |
297 | (1 << frame->buddy_order); |
297 | (1 << frame->buddy_order); |
298 | } else { /* is_right */ |
298 | } else { /* is_right */ |
299 | index = (frame_index(zone, frame)) - |
299 | index = (frame_index(zone, frame)) - |
Line 444... | Line 444... | ||
444 | * |
444 | * |
445 | * @param zone Pointer to zone from which the frame is to be freed. |
445 | * @param zone Pointer to zone from which the frame is to be freed. |
446 | * @param frame_idx Frame index relative to zone. |
446 | * @param frame_idx Frame index relative to zone. |
447 | * |
447 | * |
448 | */ |
448 | */ |
449 | static void zone_frame_free(zone_t *zone, index_t frame_idx) |
449 | static void zone_frame_free(zone_t *zone, size_t frame_idx) |
450 | { |
450 | { |
451 | ASSERT(zone_flags_available(zone->flags)); |
451 | ASSERT(zone_flags_available(zone->flags)); |
452 | 452 | ||
453 | frame_t *frame = &zone->frames[frame_idx]; |
453 | frame_t *frame = &zone->frames[frame_idx]; |
454 | 454 | ||
Line 465... | Line 465... | ||
465 | zone->busy_count -= (1 << order); |
465 | zone->busy_count -= (1 << order); |
466 | } |
466 | } |
467 | } |
467 | } |
468 | 468 | ||
469 | /** Return frame from zone. */ |
469 | /** Return frame from zone. */ |
470 | static frame_t *zone_get_frame(zone_t *zone, index_t frame_idx) |
470 | static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx) |
471 | { |
471 | { |
472 | ASSERT(frame_idx < zone->count); |
472 | ASSERT(frame_idx < zone->count); |
473 | return &zone->frames[frame_idx]; |
473 | return &zone->frames[frame_idx]; |
474 | } |
474 | } |
475 | 475 | ||
476 | /** Mark frame in zone unavailable to allocation. */ |
476 | /** Mark frame in zone unavailable to allocation. */ |
477 | static void zone_mark_unavailable(zone_t *zone, index_t frame_idx) |
477 | static void zone_mark_unavailable(zone_t *zone, size_t frame_idx) |
478 | { |
478 | { |
479 | ASSERT(zone_flags_available(zone->flags)); |
479 | ASSERT(zone_flags_available(zone->flags)); |
480 | 480 | ||
481 | frame_t *frame = zone_get_frame(zone, frame_idx); |
481 | frame_t *frame = zone_get_frame(zone, frame_idx); |
482 | if (frame->refcount) |
482 | if (frame->refcount) |
Line 501... | Line 501... | ||
501 | * @param z2 Second zone to merge. |
501 | * @param z2 Second zone to merge. |
502 | * @param old_z1 Original date of the first zone. |
502 | * @param old_z1 Original date of the first zone. |
503 | * @param buddy Merged zone buddy. |
503 | * @param buddy Merged zone buddy. |
504 | * |
504 | * |
505 | */ |
505 | */ |
506 | static void zone_merge_internal(count_t z1, count_t z2, zone_t *old_z1, buddy_system_t *buddy) |
506 | static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy) |
507 | { |
507 | { |
508 | ASSERT(zone_flags_available(zones.info[z1].flags)); |
508 | ASSERT(zone_flags_available(zones.info[z1].flags)); |
509 | ASSERT(zone_flags_available(zones.info[z2].flags)); |
509 | ASSERT(zone_flags_available(zones.info[z2].flags)); |
510 | ASSERT(zones.info[z1].flags == zones.info[z2].flags); |
510 | ASSERT(zones.info[z1].flags == zones.info[z2].flags); |
511 | ASSERT(zones.info[z1].base < zones.info[z2].base); |
511 | ASSERT(zones.info[z1].base < zones.info[z2].base); |
Line 527... | Line 527... | ||
527 | zones.info[z1].frames = |
527 | zones.info[z1].frames = |
528 | (frame_t *) ((uint8_t *) zones.info[z1].buddy_system |
528 | (frame_t *) ((uint8_t *) zones.info[z1].buddy_system |
529 | + buddy_conf_size(order)); |
529 | + buddy_conf_size(order)); |
530 | 530 | ||
531 | /* This marks all frames busy */ |
531 | /* This marks all frames busy */ |
532 | count_t i; |
532 | size_t i; |
533 | for (i = 0; i < zones.info[z1].count; i++) |
533 | for (i = 0; i < zones.info[z1].count; i++) |
534 | frame_initialize(&zones.info[z1].frames[i]); |
534 | frame_initialize(&zones.info[z1].frames[i]); |
535 | 535 | ||
536 | /* Copy frames from both zones to preserve full frame orders, |
536 | /* Copy frames from both zones to preserve full frame orders, |
537 | * parents etc. Set all free frames with refcount = 0 to 1, because |
537 | * parents etc. Set all free frames with refcount = 0 to 1, because |
Line 597... | Line 597... | ||
597 | * @param znum The actual zone where freeing should occur. |
597 | * @param znum The actual zone where freeing should occur. |
598 | * @param pfn Old zone configuration frame. |
598 | * @param pfn Old zone configuration frame. |
599 | * @param count Old zone frame count. |
599 | * @param count Old zone frame count. |
600 | * |
600 | * |
601 | */ |
601 | */ |
602 | static void return_config_frames(count_t znum, pfn_t pfn, count_t count) |
602 | static void return_config_frames(size_t znum, pfn_t pfn, size_t count) |
603 | { |
603 | { |
604 | ASSERT(zone_flags_available(zones.info[znum].flags)); |
604 | ASSERT(zone_flags_available(zones.info[znum].flags)); |
605 | 605 | ||
606 | count_t cframes = SIZE2FRAMES(zone_conf_size(count)); |
606 | size_t cframes = SIZE2FRAMES(zone_conf_size(count)); |
607 | 607 | ||
608 | if ((pfn < zones.info[znum].base) |
608 | if ((pfn < zones.info[znum].base) |
609 | || (pfn >= zones.info[znum].base + zones.info[znum].count)) |
609 | || (pfn >= zones.info[znum].base + zones.info[znum].count)) |
610 | return; |
610 | return; |
611 | 611 | ||
612 | frame_t *frame __attribute__ ((unused)); |
612 | frame_t *frame __attribute__ ((unused)); |
613 | 613 | ||
614 | frame = &zones.info[znum].frames[pfn - zones.info[znum].base]; |
614 | frame = &zones.info[znum].frames[pfn - zones.info[znum].base]; |
615 | ASSERT(!frame->buddy_order); |
615 | ASSERT(!frame->buddy_order); |
616 | 616 | ||
617 | count_t i; |
617 | size_t i; |
618 | for (i = 0; i < cframes; i++) { |
618 | for (i = 0; i < cframes; i++) { |
619 | zones.info[znum].busy_count++; |
619 | zones.info[znum].busy_count++; |
620 | zone_frame_free(&zones.info[znum], |
620 | zone_frame_free(&zones.info[znum], |
621 | pfn - zones.info[znum].base + i); |
621 | pfn - zones.info[znum].base + i); |
622 | } |
622 | } |
Line 632... | Line 632... | ||
632 | * @param znum Zone. |
632 | * @param znum Zone. |
633 | * @param frame_idx Index the first frame of the block. |
633 | * @param frame_idx Index the first frame of the block. |
634 | * @param count Allocated frames in block. |
634 | * @param count Allocated frames in block. |
635 | * |
635 | * |
636 | */ |
636 | */ |
637 | static void zone_reduce_region(count_t znum, pfn_t frame_idx, count_t count) |
637 | static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count) |
638 | { |
638 | { |
639 | ASSERT(zone_flags_available(zones.info[znum].flags)); |
639 | ASSERT(zone_flags_available(zones.info[znum].flags)); |
640 | ASSERT(frame_idx + count < zones.info[znum].count); |
640 | ASSERT(frame_idx + count < zones.info[znum].count); |
641 | 641 | ||
642 | uint8_t order = zones.info[znum].frames[frame_idx].buddy_order; |
642 | uint8_t order = zones.info[znum].frames[frame_idx].buddy_order; |
643 | ASSERT((count_t) (1 << order) >= count); |
643 | ASSERT((size_t) (1 << order) >= count); |
644 | 644 | ||
645 | /* Reduce all blocks to order 0 */ |
645 | /* Reduce all blocks to order 0 */ |
646 | count_t i; |
646 | size_t i; |
647 | for (i = 0; i < (count_t) (1 << order); i++) { |
647 | for (i = 0; i < (size_t) (1 << order); i++) { |
648 | frame_t *frame = &zones.info[znum].frames[i + frame_idx]; |
648 | frame_t *frame = &zones.info[znum].frames[i + frame_idx]; |
649 | frame->buddy_order = 0; |
649 | frame->buddy_order = 0; |
650 | if (!frame->refcount) |
650 | if (!frame->refcount) |
651 | frame->refcount = 1; |
651 | frame->refcount = 1; |
652 | ASSERT(frame->refcount == 1); |
652 | ASSERT(frame->refcount == 1); |
653 | } |
653 | } |
654 | 654 | ||
655 | /* Free unneeded frames */ |
655 | /* Free unneeded frames */ |
656 | for (i = count; i < (count_t) (1 << order); i++) |
656 | for (i = count; i < (size_t) (1 << order); i++) |
657 | zone_frame_free(&zones.info[znum], i + frame_idx); |
657 | zone_frame_free(&zones.info[znum], i + frame_idx); |
658 | } |
658 | } |
659 | 659 | ||
660 | /** Merge zones z1 and z2. |
660 | /** Merge zones z1 and z2. |
661 | * |
661 | * |
Line 668... | Line 668... | ||
668 | * possible, merged configuration data occupies more space :-/ |
668 | * possible, merged configuration data occupies more space :-/ |
669 | * |
669 | * |
670 | * The function uses |
670 | * The function uses |
671 | * |
671 | * |
672 | */ |
672 | */ |
673 | bool zone_merge(count_t z1, count_t z2) |
673 | bool zone_merge(size_t z1, size_t z2) |
674 | { |
674 | { |
675 | ipl_t ipl = interrupts_disable(); |
675 | ipl_t ipl = interrupts_disable(); |
676 | spinlock_lock(&zones.lock); |
676 | spinlock_lock(&zones.lock); |
677 | 677 | ||
678 | bool ret = true; |
678 | bool ret = true; |
Line 731... | Line 731... | ||
731 | return_config_frames(z1, |
731 | return_config_frames(z1, |
732 | ADDR2PFN(KA2PA((uintptr_t) zones.info[z2].frames)), |
732 | ADDR2PFN(KA2PA((uintptr_t) zones.info[z2].frames)), |
733 | zones.info[z2].count); |
733 | zones.info[z2].count); |
734 | 734 | ||
735 | /* Move zones down */ |
735 | /* Move zones down */ |
736 | count_t i; |
736 | size_t i; |
737 | for (i = z2 + 1; i < zones.count; i++) { |
737 | for (i = z2 + 1; i < zones.count; i++) { |
738 | zones.info[i - 1] = zones.info[i]; |
738 | zones.info[i - 1] = zones.info[i]; |
739 | zones.info[i - 1].buddy_system->data = |
739 | zones.info[i - 1].buddy_system->data = |
740 | (void *) &zones.info[i - 1]; |
740 | (void *) &zones.info[i - 1]; |
741 | } |
741 | } |
Line 756... | Line 756... | ||
756 | * have 1 zone (it's faster). |
756 | * have 1 zone (it's faster). |
757 | * |
757 | * |
758 | */ |
758 | */ |
759 | void zone_merge_all(void) |
759 | void zone_merge_all(void) |
760 | { |
760 | { |
761 | count_t i = 0; |
761 | size_t i = 0; |
762 | while (i < zones.count) { |
762 | while (i < zones.count) { |
763 | if (!zone_merge(i, i + 1)) |
763 | if (!zone_merge(i, i + 1)) |
764 | i++; |
764 | i++; |
765 | } |
765 | } |
766 | } |
766 | } |
Line 774... | Line 774... | ||
774 | * @param flags Zone flags. |
774 | * @param flags Zone flags. |
775 | * |
775 | * |
776 | * @return Initialized zone. |
776 | * @return Initialized zone. |
777 | * |
777 | * |
778 | */ |
778 | */ |
779 | static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, count_t count, zone_flags_t flags) |
779 | static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags) |
780 | { |
780 | { |
781 | zone->base = start; |
781 | zone->base = start; |
782 | zone->count = count; |
782 | zone->count = count; |
783 | zone->flags = flags; |
783 | zone->flags = flags; |
784 | zone->free_count = count; |
784 | zone->free_count = count; |
Line 797... | Line 797... | ||
797 | 797 | ||
798 | /* Check sizes */ |
798 | /* Check sizes */ |
799 | zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system + |
799 | zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system + |
800 | buddy_conf_size(order)); |
800 | buddy_conf_size(order)); |
801 | 801 | ||
802 | count_t i; |
802 | size_t i; |
803 | for (i = 0; i < count; i++) |
803 | for (i = 0; i < count; i++) |
804 | frame_initialize(&zone->frames[i]); |
804 | frame_initialize(&zone->frames[i]); |
805 | 805 | ||
806 | /* Stuffing frames */ |
806 | /* Stuffing frames */ |
807 | for (i = 0; i < count; i++) { |
807 | for (i = 0; i < count; i++) { |
Line 817... | Line 817... | ||
817 | * @param count Size of zone in frames. |
817 | * @param count Size of zone in frames. |
818 | * |
818 | * |
819 | * @return Size of zone configuration info (in bytes). |
819 | * @return Size of zone configuration info (in bytes). |
820 | * |
820 | * |
821 | */ |
821 | */ |
822 | uintptr_t zone_conf_size(count_t count) |
822 | uintptr_t zone_conf_size(size_t count) |
823 | { |
823 | { |
824 | return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count))); |
824 | return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count))); |
825 | } |
825 | } |
826 | 826 | ||
827 | /** Create and add zone to system. |
827 | /** Create and add zone to system. |
Line 838... | Line 838... | ||
838 | * modified not to include it. |
838 | * modified not to include it. |
839 | * |
839 | * |
840 | * @return Zone number or -1 on error. |
840 | * @return Zone number or -1 on error. |
841 | * |
841 | * |
842 | */ |
842 | */ |
843 | count_t zone_create(pfn_t start, count_t count, pfn_t confframe, zone_flags_t flags) |
843 | size_t zone_create(pfn_t start, size_t count, pfn_t confframe, zone_flags_t flags) |
844 | { |
844 | { |
845 | ipl_t ipl = interrupts_disable(); |
845 | ipl_t ipl = interrupts_disable(); |
846 | spinlock_lock(&zones.lock); |
846 | spinlock_lock(&zones.lock); |
847 | 847 | ||
848 | if (zone_flags_available(flags)) { /* Create available zone */ |
848 | if (zone_flags_available(flags)) { /* Create available zone */ |
Line 853... | Line 853... | ||
853 | ASSERT(confframe != NULL); |
853 | ASSERT(confframe != NULL); |
854 | 854 | ||
855 | /* If confframe is supposed to be inside our zone, then make sure |
855 | /* If confframe is supposed to be inside our zone, then make sure |
856 | * it does not span kernel & init |
856 | * it does not span kernel & init |
857 | */ |
857 | */ |
858 | count_t confcount = SIZE2FRAMES(zone_conf_size(count)); |
858 | size_t confcount = SIZE2FRAMES(zone_conf_size(count)); |
859 | if ((confframe >= start) && (confframe < start + count)) { |
859 | if ((confframe >= start) && (confframe < start + count)) { |
860 | for (; confframe < start + count; confframe++) { |
860 | for (; confframe < start + count; confframe++) { |
861 | uintptr_t addr = PFN2ADDR(confframe); |
861 | uintptr_t addr = PFN2ADDR(confframe); |
862 | if (overlaps(addr, PFN2ADDR(confcount), |
862 | if (overlaps(addr, PFN2ADDR(confcount), |
863 | KA2PA(config.base), config.kernel_size)) |
863 | KA2PA(config.base), config.kernel_size)) |
Line 866... | Line 866... | ||
866 | if (overlaps(addr, PFN2ADDR(confcount), |
866 | if (overlaps(addr, PFN2ADDR(confcount), |
867 | KA2PA(config.stack_base), config.stack_size)) |
867 | KA2PA(config.stack_base), config.stack_size)) |
868 | continue; |
868 | continue; |
869 | 869 | ||
870 | bool overlap = false; |
870 | bool overlap = false; |
871 | count_t i; |
871 | size_t i; |
872 | for (i = 0; i < init.cnt; i++) |
872 | for (i = 0; i < init.cnt; i++) |
873 | if (overlaps(addr, PFN2ADDR(confcount), |
873 | if (overlaps(addr, PFN2ADDR(confcount), |
874 | KA2PA(init.tasks[i].addr), |
874 | KA2PA(init.tasks[i].addr), |
875 | init.tasks[i].size)) { |
875 | init.tasks[i].size)) { |
876 | overlap = true; |
876 | overlap = true; |
Line 884... | Line 884... | ||
884 | 884 | ||
885 | if (confframe >= start + count) |
885 | if (confframe >= start + count) |
886 | panic("Cannot find configuration data for zone."); |
886 | panic("Cannot find configuration data for zone."); |
887 | } |
887 | } |
888 | 888 | ||
889 | count_t znum = zones_insert_zone(start, count); |
889 | size_t znum = zones_insert_zone(start, count); |
890 | if (znum == (count_t) -1) { |
890 | if (znum == (size_t) -1) { |
891 | spinlock_unlock(&zones.lock); |
891 | spinlock_unlock(&zones.lock); |
892 | interrupts_restore(ipl); |
892 | interrupts_restore(ipl); |
893 | return (count_t) -1; |
893 | return (size_t) -1; |
894 | } |
894 | } |
895 | 895 | ||
896 | buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe)); |
896 | buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe)); |
897 | zone_construct(&zones.info[znum], buddy, start, count, flags); |
897 | zone_construct(&zones.info[znum], buddy, start, count, flags); |
898 | 898 | ||
899 | /* If confdata in zone, mark as unavailable */ |
899 | /* If confdata in zone, mark as unavailable */ |
900 | if ((confframe >= start) && (confframe < start + count)) { |
900 | if ((confframe >= start) && (confframe < start + count)) { |
901 | count_t i; |
901 | size_t i; |
902 | for (i = confframe; i < confframe + confcount; i++) |
902 | for (i = confframe; i < confframe + confcount; i++) |
903 | zone_mark_unavailable(&zones.info[znum], |
903 | zone_mark_unavailable(&zones.info[znum], |
904 | i - zones.info[znum].base); |
904 | i - zones.info[znum].base); |
905 | } |
905 | } |
906 | 906 | ||
Line 909... | Line 909... | ||
909 | 909 | ||
910 | return znum; |
910 | return znum; |
911 | } |
911 | } |
912 | 912 | ||
913 | /* Non-available zone */ |
913 | /* Non-available zone */ |
914 | count_t znum = zones_insert_zone(start, count); |
914 | size_t znum = zones_insert_zone(start, count); |
915 | if (znum == (count_t) -1) { |
915 | if (znum == (size_t) -1) { |
916 | spinlock_unlock(&zones.lock); |
916 | spinlock_unlock(&zones.lock); |
917 | interrupts_restore(ipl); |
917 | interrupts_restore(ipl); |
918 | return (count_t) -1; |
918 | return (size_t) -1; |
919 | } |
919 | } |
920 | zone_construct(&zones.info[znum], NULL, start, count, flags); |
920 | zone_construct(&zones.info[znum], NULL, start, count, flags); |
921 | 921 | ||
922 | spinlock_unlock(&zones.lock); |
922 | spinlock_unlock(&zones.lock); |
923 | interrupts_restore(ipl); |
923 | interrupts_restore(ipl); |
Line 928... | Line 928... | ||
928 | /*******************/ |
928 | /*******************/ |
929 | /* Frame functions */ |
929 | /* Frame functions */ |
930 | /*******************/ |
930 | /*******************/ |
931 | 931 | ||
932 | /** Set parent of frame. */ |
932 | /** Set parent of frame. */ |
933 | void frame_set_parent(pfn_t pfn, void *data, count_t hint) |
933 | void frame_set_parent(pfn_t pfn, void *data, size_t hint) |
934 | { |
934 | { |
935 | ipl_t ipl = interrupts_disable(); |
935 | ipl_t ipl = interrupts_disable(); |
936 | spinlock_lock(&zones.lock); |
936 | spinlock_lock(&zones.lock); |
937 | 937 | ||
938 | count_t znum = find_zone(pfn, 1, hint); |
938 | size_t znum = find_zone(pfn, 1, hint); |
939 | 939 | ||
940 | ASSERT(znum != (count_t) -1); |
940 | ASSERT(znum != (size_t) -1); |
941 | 941 | ||
942 | zone_get_frame(&zones.info[znum], |
942 | zone_get_frame(&zones.info[znum], |
943 | pfn - zones.info[znum].base)->parent = data; |
943 | pfn - zones.info[znum].base)->parent = data; |
944 | 944 | ||
945 | spinlock_unlock(&zones.lock); |
945 | spinlock_unlock(&zones.lock); |
946 | interrupts_restore(ipl); |
946 | interrupts_restore(ipl); |
947 | } |
947 | } |
948 | 948 | ||
949 | void *frame_get_parent(pfn_t pfn, count_t hint) |
949 | void *frame_get_parent(pfn_t pfn, size_t hint) |
950 | { |
950 | { |
951 | ipl_t ipl = interrupts_disable(); |
951 | ipl_t ipl = interrupts_disable(); |
952 | spinlock_lock(&zones.lock); |
952 | spinlock_lock(&zones.lock); |
953 | 953 | ||
954 | count_t znum = find_zone(pfn, 1, hint); |
954 | size_t znum = find_zone(pfn, 1, hint); |
955 | 955 | ||
956 | ASSERT(znum != (count_t) -1); |
956 | ASSERT(znum != (size_t) -1); |
957 | 957 | ||
958 | void *res = zone_get_frame(&zones.info[znum], |
958 | void *res = zone_get_frame(&zones.info[znum], |
959 | pfn - zones.info[znum].base)->parent; |
959 | pfn - zones.info[znum].base)->parent; |
960 | 960 | ||
961 | spinlock_unlock(&zones.lock); |
961 | spinlock_unlock(&zones.lock); |
Line 971... | Line 971... | ||
971 | * @param pzone Preferred zone. |
971 | * @param pzone Preferred zone. |
972 | * |
972 | * |
973 | * @return Physical address of the allocated frame. |
973 | * @return Physical address of the allocated frame. |
974 | * |
974 | * |
975 | */ |
975 | */ |
976 | void *frame_alloc_generic(uint8_t order, frame_flags_t flags, count_t *pzone) |
976 | void *frame_alloc_generic(uint8_t order, frame_flags_t flags, size_t *pzone) |
977 | { |
977 | { |
978 | count_t size = ((count_t) 1) << order; |
978 | size_t size = ((size_t) 1) << order; |
979 | ipl_t ipl; |
979 | ipl_t ipl; |
980 | count_t hint = pzone ? (*pzone) : 0; |
980 | size_t hint = pzone ? (*pzone) : 0; |
981 | 981 | ||
982 | loop: |
982 | loop: |
983 | ipl = interrupts_disable(); |
983 | ipl = interrupts_disable(); |
984 | spinlock_lock(&zones.lock); |
984 | spinlock_lock(&zones.lock); |
985 | 985 | ||
986 | /* |
986 | /* |
987 | * First, find suitable frame zone. |
987 | * First, find suitable frame zone. |
988 | */ |
988 | */ |
989 | count_t znum = find_free_zone(order, |
989 | size_t znum = find_free_zone(order, |
990 | FRAME_TO_ZONE_FLAGS(flags), hint); |
990 | FRAME_TO_ZONE_FLAGS(flags), hint); |
991 | 991 | ||
992 | /* If no memory, reclaim some slab memory, |
992 | /* If no memory, reclaim some slab memory, |
993 | if it does not help, reclaim all */ |
993 | if it does not help, reclaim all */ |
994 | if ((znum == (count_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { |
994 | if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { |
995 | spinlock_unlock(&zones.lock); |
995 | spinlock_unlock(&zones.lock); |
996 | interrupts_restore(ipl); |
996 | interrupts_restore(ipl); |
997 | 997 | ||
998 | count_t freed = slab_reclaim(0); |
998 | size_t freed = slab_reclaim(0); |
999 | 999 | ||
1000 | ipl = interrupts_disable(); |
1000 | ipl = interrupts_disable(); |
1001 | spinlock_lock(&zones.lock); |
1001 | spinlock_lock(&zones.lock); |
1002 | 1002 | ||
1003 | if (freed > 0) |
1003 | if (freed > 0) |
1004 | znum = find_free_zone(order, |
1004 | znum = find_free_zone(order, |
1005 | FRAME_TO_ZONE_FLAGS(flags), hint); |
1005 | FRAME_TO_ZONE_FLAGS(flags), hint); |
1006 | 1006 | ||
1007 | if (znum == (count_t) -1) { |
1007 | if (znum == (size_t) -1) { |
1008 | spinlock_unlock(&zones.lock); |
1008 | spinlock_unlock(&zones.lock); |
1009 | interrupts_restore(ipl); |
1009 | interrupts_restore(ipl); |
1010 | 1010 | ||
1011 | freed = slab_reclaim(SLAB_RECLAIM_ALL); |
1011 | freed = slab_reclaim(SLAB_RECLAIM_ALL); |
1012 | 1012 | ||
Line 1017... | Line 1017... | ||
1017 | znum = find_free_zone(order, |
1017 | znum = find_free_zone(order, |
1018 | FRAME_TO_ZONE_FLAGS(flags), hint); |
1018 | FRAME_TO_ZONE_FLAGS(flags), hint); |
1019 | } |
1019 | } |
1020 | } |
1020 | } |
1021 | 1021 | ||
1022 | if (znum == (count_t) -1) { |
1022 | if (znum == (size_t) -1) { |
1023 | if (flags & FRAME_ATOMIC) { |
1023 | if (flags & FRAME_ATOMIC) { |
1024 | spinlock_unlock(&zones.lock); |
1024 | spinlock_unlock(&zones.lock); |
1025 | interrupts_restore(ipl); |
1025 | interrupts_restore(ipl); |
1026 | return NULL; |
1026 | return NULL; |
1027 | } |
1027 | } |
1028 | 1028 | ||
1029 | #ifdef CONFIG_DEBUG |
1029 | #ifdef CONFIG_DEBUG |
1030 | count_t avail = total_frames_free(); |
1030 | size_t avail = total_frames_free(); |
1031 | #endif |
1031 | #endif |
1032 | 1032 | ||
1033 | spinlock_unlock(&zones.lock); |
1033 | spinlock_unlock(&zones.lock); |
1034 | interrupts_restore(ipl); |
1034 | interrupts_restore(ipl); |
1035 | 1035 | ||
1036 | /* |
1036 | /* |
1037 | * Sleep until some frames are available again. |
1037 | * Sleep until some frames are available again. |
1038 | */ |
1038 | */ |
1039 | 1039 | ||
1040 | #ifdef CONFIG_DEBUG |
1040 | #ifdef CONFIG_DEBUG |
1041 | printf("Thread %" PRIu64 " waiting for %" PRIc " frames, " |
1041 | printf("Thread %" PRIu64 " waiting for %" PRIs " frames, " |
1042 | "%" PRIc " available.\n", THREAD->tid, size, avail); |
1042 | "%" PRIs " available.\n", THREAD->tid, size, avail); |
1043 | #endif |
1043 | #endif |
1044 | 1044 | ||
1045 | mutex_lock(&mem_avail_mtx); |
1045 | mutex_lock(&mem_avail_mtx); |
1046 | 1046 | ||
1047 | if (mem_avail_req > 0) |
1047 | if (mem_avail_req > 0) |
1048 | mem_avail_req = min(mem_avail_req, size); |
1048 | mem_avail_req = min(mem_avail_req, size); |
1049 | else |
1049 | else |
1050 | mem_avail_req = size; |
1050 | mem_avail_req = size; |
1051 | count_t gen = mem_avail_gen; |
1051 | size_t gen = mem_avail_gen; |
1052 | 1052 | ||
1053 | while (gen == mem_avail_gen) |
1053 | while (gen == mem_avail_gen) |
1054 | condvar_wait(&mem_avail_cv, &mem_avail_mtx); |
1054 | condvar_wait(&mem_avail_cv, &mem_avail_mtx); |
1055 | 1055 | ||
1056 | mutex_unlock(&mem_avail_mtx); |
1056 | mutex_unlock(&mem_avail_mtx); |
Line 1093... | Line 1093... | ||
1093 | 1093 | ||
1094 | /* |
1094 | /* |
1095 | * First, find host frame zone for addr. |
1095 | * First, find host frame zone for addr. |
1096 | */ |
1096 | */ |
1097 | pfn_t pfn = ADDR2PFN(frame); |
1097 | pfn_t pfn = ADDR2PFN(frame); |
1098 | count_t znum = find_zone(pfn, 1, NULL); |
1098 | size_t znum = find_zone(pfn, 1, NULL); |
1099 | 1099 | ||
1100 | ASSERT(znum != (count_t) -1); |
1100 | ASSERT(znum != (size_t) -1); |
1101 | 1101 | ||
1102 | zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); |
1102 | zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); |
1103 | 1103 | ||
1104 | spinlock_unlock(&zones.lock); |
1104 | spinlock_unlock(&zones.lock); |
1105 | interrupts_restore(ipl); |
1105 | interrupts_restore(ipl); |
Line 1132... | Line 1132... | ||
1132 | spinlock_lock(&zones.lock); |
1132 | spinlock_lock(&zones.lock); |
1133 | 1133 | ||
1134 | /* |
1134 | /* |
1135 | * First, find host frame zone for addr. |
1135 | * First, find host frame zone for addr. |
1136 | */ |
1136 | */ |
1137 | count_t znum = find_zone(pfn, 1, NULL); |
1137 | size_t znum = find_zone(pfn, 1, NULL); |
1138 | 1138 | ||
1139 | ASSERT(znum != (count_t) -1); |
1139 | ASSERT(znum != (size_t) -1); |
1140 | 1140 | ||
1141 | zones.info[znum].frames[pfn - zones.info[znum].base].refcount++; |
1141 | zones.info[znum].frames[pfn - zones.info[znum].base].refcount++; |
1142 | 1142 | ||
1143 | spinlock_unlock(&zones.lock); |
1143 | spinlock_unlock(&zones.lock); |
1144 | interrupts_restore(ipl); |
1144 | interrupts_restore(ipl); |
1145 | } |
1145 | } |
1146 | 1146 | ||
1147 | /** Mark given range unavailable in frame zones. */ |
1147 | /** Mark given range unavailable in frame zones. */ |
1148 | void frame_mark_unavailable(pfn_t start, count_t count) |
1148 | void frame_mark_unavailable(pfn_t start, size_t count) |
1149 | { |
1149 | { |
1150 | ipl_t ipl = interrupts_disable(); |
1150 | ipl_t ipl = interrupts_disable(); |
1151 | spinlock_lock(&zones.lock); |
1151 | spinlock_lock(&zones.lock); |
1152 | 1152 | ||
1153 | count_t i; |
1153 | size_t i; |
1154 | for (i = 0; i < count; i++) { |
1154 | for (i = 0; i < count; i++) { |
1155 | count_t znum = find_zone(start + i, 1, 0); |
1155 | size_t znum = find_zone(start + i, 1, 0); |
1156 | if (znum == (count_t) -1) /* PFN not found */ |
1156 | if (znum == (size_t) -1) /* PFN not found */ |
1157 | continue; |
1157 | continue; |
1158 | 1158 | ||
1159 | zone_mark_unavailable(&zones.info[znum], |
1159 | zone_mark_unavailable(&zones.info[znum], |
1160 | start + i - zones.info[znum].base); |
1160 | start + i - zones.info[znum].base); |
1161 | } |
1161 | } |
Line 1180... | Line 1180... | ||
1180 | frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), |
1180 | frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), |
1181 | SIZE2FRAMES(config.kernel_size)); |
1181 | SIZE2FRAMES(config.kernel_size)); |
1182 | frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)), |
1182 | frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)), |
1183 | SIZE2FRAMES(config.stack_size)); |
1183 | SIZE2FRAMES(config.stack_size)); |
1184 | 1184 | ||
1185 | count_t i; |
1185 | size_t i; |
1186 | for (i = 0; i < init.cnt; i++) { |
1186 | for (i = 0; i < init.cnt; i++) { |
1187 | pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr)); |
1187 | pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr)); |
1188 | frame_mark_unavailable(pfn, |
1188 | frame_mark_unavailable(pfn, |
1189 | SIZE2FRAMES(init.tasks[i].size)); |
1189 | SIZE2FRAMES(init.tasks[i].size)); |
1190 | } |
1190 | } |
Line 1205... | Line 1205... | ||
1205 | { |
1205 | { |
1206 | ipl_t ipl = interrupts_disable(); |
1206 | ipl_t ipl = interrupts_disable(); |
1207 | spinlock_lock(&zones.lock); |
1207 | spinlock_lock(&zones.lock); |
1208 | 1208 | ||
1209 | uint64_t total = 0; |
1209 | uint64_t total = 0; |
1210 | count_t i; |
1210 | size_t i; |
1211 | for (i = 0; i < zones.count; i++) |
1211 | for (i = 0; i < zones.count; i++) |
1212 | total += (uint64_t) FRAMES2SIZE(zones.info[i].count); |
1212 | total += (uint64_t) FRAMES2SIZE(zones.info[i].count); |
1213 | 1213 | ||
1214 | spinlock_unlock(&zones.lock); |
1214 | spinlock_unlock(&zones.lock); |
1215 | interrupts_restore(ipl); |
1215 | interrupts_restore(ipl); |
Line 1239... | Line 1239... | ||
1239 | * When someone adds/removes zones while we are printing the statistics, |
1239 | * When someone adds/removes zones while we are printing the statistics, |
1240 | * we may end up with inaccurate output (e.g. a zone being skipped from |
1240 | * we may end up with inaccurate output (e.g. a zone being skipped from |
1241 | * the listing). |
1241 | * the listing). |
1242 | */ |
1242 | */ |
1243 | 1243 | ||
1244 | count_t i; |
1244 | size_t i; |
1245 | for (i = 0;; i++) { |
1245 | for (i = 0;; i++) { |
1246 | ipl_t ipl = interrupts_disable(); |
1246 | ipl_t ipl = interrupts_disable(); |
1247 | spinlock_lock(&zones.lock); |
1247 | spinlock_lock(&zones.lock); |
1248 | 1248 | ||
1249 | if (i >= zones.count) { |
1249 | if (i >= zones.count) { |
Line 1251... | Line 1251... | ||
1251 | interrupts_restore(ipl); |
1251 | interrupts_restore(ipl); |
1252 | break; |
1252 | break; |
1253 | } |
1253 | } |
1254 | 1254 | ||
1255 | uintptr_t base = PFN2ADDR(zones.info[i].base); |
1255 | uintptr_t base = PFN2ADDR(zones.info[i].base); |
1256 | count_t count = zones.info[i].count; |
1256 | size_t count = zones.info[i].count; |
1257 | zone_flags_t flags = zones.info[i].flags; |
1257 | zone_flags_t flags = zones.info[i].flags; |
1258 | count_t free_count = zones.info[i].free_count; |
1258 | size_t free_count = zones.info[i].free_count; |
1259 | count_t busy_count = zones.info[i].busy_count; |
1259 | size_t busy_count = zones.info[i].busy_count; |
1260 | 1260 | ||
1261 | spinlock_unlock(&zones.lock); |
1261 | spinlock_unlock(&zones.lock); |
1262 | interrupts_restore(ipl); |
1262 | interrupts_restore(ipl); |
1263 | 1263 | ||
1264 | bool available = zone_flags_available(flags); |
1264 | bool available = zone_flags_available(flags); |
1265 | 1265 | ||
1266 | printf("%-2" PRIc, i); |
1266 | printf("%-2" PRIs, i); |
1267 | 1267 | ||
1268 | #ifdef __32_BITS__ |
1268 | #ifdef __32_BITS__ |
1269 | printf(" %10p", base); |
1269 | printf(" %10p", base); |
1270 | #endif |
1270 | #endif |
1271 | 1271 | ||
1272 | #ifdef __64_BITS__ |
1272 | #ifdef __64_BITS__ |
1273 | printf(" %18p", base); |
1273 | printf(" %18p", base); |
1274 | #endif |
1274 | #endif |
1275 | 1275 | ||
1276 | printf(" %12" PRIc " %c%c%c ", count, |
1276 | printf(" %12" PRIs " %c%c%c ", count, |
1277 | available ? 'A' : ' ', |
1277 | available ? 'A' : ' ', |
1278 | (flags & ZONE_RESERVED) ? 'R' : ' ', |
1278 | (flags & ZONE_RESERVED) ? 'R' : ' ', |
1279 | (flags & ZONE_FIRMWARE) ? 'F' : ' '); |
1279 | (flags & ZONE_FIRMWARE) ? 'F' : ' '); |
1280 | 1280 | ||
1281 | if (available) |
1281 | if (available) |
1282 | printf("%12" PRIc " %12" PRIc, |
1282 | printf("%12" PRIs " %12" PRIs, |
1283 | free_count, busy_count); |
1283 | free_count, busy_count); |
1284 | 1284 | ||
1285 | printf("\n"); |
1285 | printf("\n"); |
1286 | } |
1286 | } |
1287 | } |
1287 | } |
Line 1289... | Line 1289... | ||
1289 | /** Prints zone details. |
1289 | /** Prints zone details. |
1290 | * |
1290 | * |
1291 | * @param num Zone base address or zone number. |
1291 | * @param num Zone base address or zone number. |
1292 | * |
1292 | * |
1293 | */ |
1293 | */ |
1294 | void zone_print_one(count_t num) |
1294 | void zone_print_one(size_t num) |
1295 | { |
1295 | { |
1296 | ipl_t ipl = interrupts_disable(); |
1296 | ipl_t ipl = interrupts_disable(); |
1297 | spinlock_lock(&zones.lock); |
1297 | spinlock_lock(&zones.lock); |
1298 | count_t znum = (count_t) -1; |
1298 | size_t znum = (size_t) -1; |
1299 | 1299 | ||
1300 | count_t i; |
1300 | size_t i; |
1301 | for (i = 0; i < zones.count; i++) { |
1301 | for (i = 0; i < zones.count; i++) { |
1302 | if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) { |
1302 | if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) { |
1303 | znum = i; |
1303 | znum = i; |
1304 | break; |
1304 | break; |
1305 | } |
1305 | } |
1306 | } |
1306 | } |
1307 | 1307 | ||
1308 | if (znum == (count_t) -1) { |
1308 | if (znum == (size_t) -1) { |
1309 | spinlock_unlock(&zones.lock); |
1309 | spinlock_unlock(&zones.lock); |
1310 | interrupts_restore(ipl); |
1310 | interrupts_restore(ipl); |
1311 | printf("Zone not found.\n"); |
1311 | printf("Zone not found.\n"); |
1312 | return; |
1312 | return; |
1313 | } |
1313 | } |
1314 | 1314 | ||
1315 | uintptr_t base = PFN2ADDR(zones.info[i].base); |
1315 | uintptr_t base = PFN2ADDR(zones.info[i].base); |
1316 | zone_flags_t flags = zones.info[i].flags; |
1316 | zone_flags_t flags = zones.info[i].flags; |
1317 | count_t count = zones.info[i].count; |
1317 | size_t count = zones.info[i].count; |
1318 | count_t free_count = zones.info[i].free_count; |
1318 | size_t free_count = zones.info[i].free_count; |
1319 | count_t busy_count = zones.info[i].busy_count; |
1319 | size_t busy_count = zones.info[i].busy_count; |
1320 | 1320 | ||
1321 | spinlock_unlock(&zones.lock); |
1321 | spinlock_unlock(&zones.lock); |
1322 | interrupts_restore(ipl); |
1322 | interrupts_restore(ipl); |
1323 | 1323 | ||
1324 | bool available = zone_flags_available(flags); |
1324 | bool available = zone_flags_available(flags); |
1325 | 1325 | ||
1326 | printf("Zone number: %" PRIc "\n", znum); |
1326 | printf("Zone number: %" PRIs "\n", znum); |
1327 | printf("Zone base address: %p\n", base); |
1327 | printf("Zone base address: %p\n", base); |
1328 | printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count, |
1328 | printf("Zone size: %" PRIs " frames (%" PRIs " KiB)\n", count, |
1329 | SIZE2KB(FRAMES2SIZE(count))); |
1329 | SIZE2KB(FRAMES2SIZE(count))); |
1330 | printf("Zone flags: %c%c%c\n", |
1330 | printf("Zone flags: %c%c%c\n", |
1331 | available ? 'A' : ' ', |
1331 | available ? 'A' : ' ', |
1332 | (flags & ZONE_RESERVED) ? 'R' : ' ', |
1332 | (flags & ZONE_RESERVED) ? 'R' : ' ', |
1333 | (flags & ZONE_FIRMWARE) ? 'F' : ' '); |
1333 | (flags & ZONE_FIRMWARE) ? 'F' : ' '); |
1334 | 1334 | ||
1335 | if (available) { |
1335 | if (available) { |
1336 | printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n", |
1336 | printf("Allocated space: %" PRIs " frames (%" PRIs " KiB)\n", |
1337 | busy_count, SIZE2KB(FRAMES2SIZE(busy_count))); |
1337 | busy_count, SIZE2KB(FRAMES2SIZE(busy_count))); |
1338 | printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n", |
1338 | printf("Available space: %" PRIs " frames (%" PRIs " KiB)\n", |
1339 | free_count, SIZE2KB(FRAMES2SIZE(free_count))); |
1339 | free_count, SIZE2KB(FRAMES2SIZE(free_count))); |
1340 | } |
1340 | } |
1341 | } |
1341 | } |
1342 | 1342 | ||
1343 | /** @} |
1343 | /** @} |