288 |
|
|
289 |
return nr_fpages; |
return nr_fpages; |
290 |
} |
} |
291 |
|
|
292 |
|
|
293 |
|
/* Determine the fpages covering the (page aligned) virtual address |
294 |
|
space from START to END (inclusive) under the conditions that it is |
295 |
|
going to be mapped (or granted) to the virtual address DEST. START |
296 |
|
and DEST must be page aligned, while END must be the address of the |
297 |
|
last byte in the area. MAX_FPAGES is the count of available fpages |
298 |
|
that can be stored at FPAGES. The actual number required can be |
299 |
|
very large (thousands and tens of thousands) due to bad alignment. |
300 |
|
The function returns the number of fpages returned in FPAGES. The |
301 |
|
generated fpages are fully accessible. */ |
302 |
|
static inline unsigned int |
303 |
|
l4_fpage_xspan (l4_word_t start, l4_word_t end, l4_word_t dest, |
304 |
|
l4_fpage_t *fpages, l4_word_t max_fpages) |
305 |
|
{ |
306 |
|
l4_word_t min_page_size = l4_min_page_size (); |
307 |
|
unsigned int nr_fpages = 0; |
308 |
|
|
309 |
|
if (start > end) |
310 |
|
return 0; |
311 |
|
|
312 |
|
/* Round START and DEST down to a multiple of the minimum page size. */ |
313 |
|
start &= ~(min_page_size - 1); |
314 |
|
dest &= ~(min_page_size - 1); |
315 |
|
|
316 |
|
/* Round END up to one less than a multiple of the minimum page size. */ |
317 |
|
end = (end & ~(min_page_size - 1)) + min_page_size - 1; |
318 |
|
|
319 |
|
end = ((end + min_page_size) & ~(min_page_size - 1)) - 1; |
320 |
|
|
321 |
|
/* END is now at least MIN_PAGE_SIZE - 1 larger than START. */ |
322 |
|
do |
323 |
|
{ |
324 |
|
unsigned int addr_align; |
325 |
|
unsigned int dest_align; |
326 |
|
unsigned int size_align; |
327 |
|
|
328 |
|
/* Each fpage must be self-aligned. */ |
329 |
|
addr_align = start ? l4_lsb (start) - 1 : (_L4_MAX_PAGE_SIZE_LOG2 - 1); |
330 |
|
dest_align = dest ? l4_lsb (dest) - 1 : (_L4_MAX_PAGE_SIZE_LOG2 - 1); |
331 |
|
size_align = (end + 1 - start) ? l4_msb (end + 1 - start) - 1 |
332 |
|
: (_L4_MAX_PAGE_SIZE_LOG2 - 1); |
333 |
|
|
334 |
|
if (addr_align < size_align) |
335 |
|
size_align = addr_align; |
336 |
|
if (dest_align < size_align) |
337 |
|
size_align = dest_align; |
338 |
|
|
339 |
|
fpages[nr_fpages] |
340 |
|
= l4_fpage_add_rights (l4_fpage_log2 (start, size_align), |
341 |
|
L4_FPAGE_FULLY_ACCESSIBLE); |
342 |
|
|
343 |
|
/* This may overflow and result in zero. In that case, the |
344 |
|
while loop will terminate. */ |
345 |
|
start += l4_size (fpages[nr_fpages]); |
346 |
|
dest += l4_size (fpages[nr_fpages]); |
347 |
|
nr_fpages++; |
348 |
|
} |
349 |
|
while (start && start < end && nr_fpages < max_fpages); |
350 |
|
|
351 |
|
return nr_fpages; |
352 |
|
} |