108 |
static struct block *zone[ZONES] = { 0, }; |
static struct block *zone[ZONES] = { 0, }; |
109 |
|
|
110 |
|
|
|
/* Find the first bit set. The least significant bit is 1. If no bit |
|
|
is set, return 0. FIXME: This can be optimized a lot, in an |
|
|
archtecture dependent way. Add to libl4, like __l4_msb(). */ |
|
|
static inline unsigned int |
|
|
wffs (l4_word_t nr) |
|
|
{ |
|
|
unsigned int bit = 0; |
|
|
|
|
|
while (bit < sizeof (l4_word_t) * 8) |
|
|
{ |
|
|
if ((1ULL << bit) & nr) |
|
|
{ |
|
|
return bit + 1; |
|
|
} |
|
|
bit++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
111 |
/* Add the block BLOCK to the zone ZONE_NR. The block has the |
/* Add the block BLOCK to the zone ZONE_NR. The block has the |
112 |
right size and alignment. Buddy up if possible. */ |
right size and alignment. Buddy up if possible. */ |
113 |
static inline |
static inline |
141 |
block = left; |
block = left; |
142 |
zone_nr++; |
zone_nr++; |
143 |
} |
} |
144 |
else if (right && ((l4_word_t) right) ^ ((l4_word_t) block) |
else if (right && (((l4_word_t) right) ^ ((l4_word_t) block)) |
145 |
== ZONE_SIZE (zone_nr)) |
== ZONE_SIZE (zone_nr)) |
146 |
{ |
{ |
147 |
/* Buddy on the right. */ |
/* Buddy on the right. */ |
199 |
do |
do |
200 |
{ |
{ |
201 |
/* All blocks must be stored aligned to their size. */ |
/* All blocks must be stored aligned to their size. */ |
202 |
unsigned int zone_nr = wffs (block | size) - 1 - L4_MIN_PAGE_SHIFT; |
unsigned int block_align = l4_lsb (block) - 1; |
203 |
|
unsigned int size_align = l4_msb (size) - 1; |
204 |
|
unsigned int zone_nr = (block_align < size_align |
205 |
|
? block_align : size_align) |
206 |
|
- L4_MIN_PAGE_SHIFT; |
207 |
|
|
208 |
|
printf ("block align: %u size_align: %u zone_nr: %u\n", |
209 |
|
block_align, size_align, zone_nr); |
210 |
add_block ((struct block *) block, zone_nr); |
add_block ((struct block *) block, zone_nr); |
211 |
|
|
212 |
block += ZONE_SIZE (zone_nr); |
block += ZONE_SIZE (zone_nr); |
232 |
panic ("%s: requested size 0x%x is not a multiple of " |
panic ("%s: requested size 0x%x is not a multiple of " |
233 |
"minimum page size", __func__, size); |
"minimum page size", __func__, size); |
234 |
|
|
235 |
/* Calculate the logarithm to base two of SIZE rounded to the |
/* Calculate the logarithm to base two of SIZE rounded up to the |
236 |
nearest power of two (actually, the MSB function returns one more |
nearest power of two (actually, the MSB function returns one more |
237 |
than the logarithm to base two of its argument, rounded down to |
than the logarithm to base two of its argument, rounded down to |
238 |
the nearest power of two - this is the same except for the border |
the nearest power of two - this is the same except for the border |
239 |
case where only one bit is set. To adjust for this border case, |
case where only one bit is set. To adjust for this border case, |
240 |
we subtract one from the argument to the MSB function). Calculate |
we subtract one from the argument to the MSB function). Calculate |
241 |
the zone number by subtracting page shift. */ |
the zone number by subtracting page shift. */ |
242 |
zone_nr = __l4_msb (size - 1) - L4_MIN_PAGE_SHIFT; |
zone_nr = l4_msb (size - 1) - L4_MIN_PAGE_SHIFT; |
243 |
|
|
244 |
/* Find the smallest zone which fits the request and has memory |
/* Find the smallest zone which fits the request and has memory |
245 |
available. */ |
available. */ |