memblock region iteration can now be bounded to a certain memory range
This commit is contained in:
@@ -11,7 +11,10 @@
|
||||
#define IDX_A(idx) ((idx) & 0xFFFFFFFF)
|
||||
#define IDX_B(idx) (((idx) >> 32) & 0xFFFFFFFF)
|
||||
|
||||
#define ADDR_MAX 0xFFFFFFFF
|
||||
/* the maximum possible value for a pointer type.
|
||||
* Note that any pointers returned by the memblock API will still
|
||||
* be bounded by the defined memory regions, and not by this constant. */
|
||||
#define ADDR_MAX (~(uintptr_t)0)
|
||||
|
||||
static memblock_region_t init_memory_regions[MEMBLOCK_INIT_MEMORY_REGION_COUNT];
|
||||
static memblock_region_t init_reserved_regions[MEMBLOCK_INIT_RESERVED_REGION_COUNT];
|
||||
@@ -172,10 +175,22 @@ void __next_memory_region(memblock_iter_t *it, memblock_type_t *type_a, memblock
|
||||
uintptr_t m_start = m->base;
|
||||
uintptr_t m_end = m->limit;
|
||||
|
||||
if (m_end < start) {
|
||||
/* we haven't reached the requested memory range yet */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_start > end) {
|
||||
/* we have gone past the requested memory range and can now stop */
|
||||
break;
|
||||
}
|
||||
|
||||
for (; idx_b < type_b->count + 1; idx_b++) {
|
||||
memblock_region_t *r = &type_b->regions[idx_b];
|
||||
|
||||
/* r_start and r_end delimit the region of memory between the current and previous reserved regions */
|
||||
/* r_start and r_end delimit the region of memory between the current and previous reserved regions.
|
||||
* if we have gone past the last reserved region, these variables delimit the range between the end
|
||||
* of the last reserved region and the end of memory. */
|
||||
uintptr_t r_start = idx_b > 0 ? r[-1].limit + 1 : 0;
|
||||
uintptr_t r_end = idx_b < type_b->count ? r->base - 1 : ADDR_MAX;
|
||||
|
||||
@@ -184,21 +199,37 @@ void __next_memory_region(memblock_iter_t *it, memblock_type_t *type_a, memblock
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_start < r_end) {
|
||||
it->base = MAX(m_start, r_start);
|
||||
it->limit = MIN(m_end, r_end);
|
||||
|
||||
if (m_end <= r_end) {
|
||||
idx_a++;
|
||||
} else {
|
||||
idx_b++;
|
||||
}
|
||||
|
||||
it->idx = ITER(idx_a, idx_b);
|
||||
return;
|
||||
/* we've already gone past this free memory region. move to the next one */
|
||||
if (m_start >= r_end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we want the area that is overlapped by both
|
||||
* region M (m_start - m_end) : The region defined as system memory.
|
||||
* region R (r_start - r_end) : The region defined as free / outside of any reserved regions.
|
||||
*/
|
||||
it->base = MAX(m_start, r_start);
|
||||
it->limit = MIN(m_end, r_end);
|
||||
|
||||
/* further limit the region to the intersection between the region itself and the
|
||||
* specified iteration bounds */
|
||||
it->base = MAX(it->base, start);
|
||||
it->limit = MIN(it->limit, end);
|
||||
|
||||
/* whichever region is smaller, increment the pointer for that type, so we can
|
||||
* compare the larger region with the next region of the incremented type. */
|
||||
if (m_end <= r_end) {
|
||||
idx_a++;
|
||||
} else {
|
||||
idx_b++;
|
||||
}
|
||||
|
||||
/* store the position for the next iteration */
|
||||
it->idx = ITER(idx_a, idx_b);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ULLONG_MAX signals the end of the iteration */
|
||||
it->idx = ITER_END;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user