memblock region iteration can now be bounded to a certain memory range
This commit is contained in:
@@ -48,7 +48,7 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("free regions:\n");
|
printf("free regions:\n");
|
||||||
for_each_free_mem_range(&it, 0, 0x100000) {
|
for_each_free_mem_range(&it, 0, ULLONG_MAX) {
|
||||||
printf("\t%08" PRIxPTR "-%08" PRIxPTR "\n",
|
printf("\t%08" PRIxPTR "-%08" PRIxPTR "\n",
|
||||||
it.base,
|
it.base,
|
||||||
it.limit);
|
it.limit);
|
||||||
|
|||||||
@@ -11,7 +11,10 @@
|
|||||||
#define IDX_A(idx) ((idx) & 0xFFFFFFFF)
|
#define IDX_A(idx) ((idx) & 0xFFFFFFFF)
|
||||||
#define IDX_B(idx) (((idx) >> 32) & 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_memory_regions[MEMBLOCK_INIT_MEMORY_REGION_COUNT];
|
||||||
static memblock_region_t init_reserved_regions[MEMBLOCK_INIT_RESERVED_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_start = m->base;
|
||||||
uintptr_t m_end = m->limit;
|
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++) {
|
for (; idx_b < type_b->count + 1; idx_b++) {
|
||||||
memblock_region_t *r = &type_b->regions[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_start = idx_b > 0 ? r[-1].limit + 1 : 0;
|
||||||
uintptr_t r_end = idx_b < type_b->count ? r->base - 1 : ADDR_MAX;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_start < r_end) {
|
/* 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->base = MAX(m_start, r_start);
|
||||||
it->limit = MIN(m_end, r_end);
|
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) {
|
if (m_end <= r_end) {
|
||||||
idx_a++;
|
idx_a++;
|
||||||
} else {
|
} else {
|
||||||
idx_b++;
|
idx_b++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* store the position for the next iteration */
|
||||||
it->idx = ITER(idx_a, idx_b);
|
it->idx = ITER(idx_a, idx_b);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/* ULLONG_MAX signals the end of the iteration */
|
||||||
it->idx = ITER_END;
|
it->idx = ITER_END;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,17 @@
|
|||||||
|
|
||||||
typedef uint64_t memblock_index_t;
|
typedef uint64_t memblock_index_t;
|
||||||
|
|
||||||
|
typedef enum memblock_region_status {
|
||||||
|
/* Used in memblock.memory regions, indicates that the memory region exists */
|
||||||
|
MEMBLOCK_MEMORY = 0,
|
||||||
|
/* Used in memblock.reserved regions, indicates that the memory region was reserved
|
||||||
|
* by a call to memblock_alloc() */
|
||||||
|
MEMBLOCK_ALLOC,
|
||||||
|
/* Used in memblock.reserved regions, indicates that the memory region was reserved
|
||||||
|
* by a call to memblock_reserve() */
|
||||||
|
MEMBLOCK_RESERVED,
|
||||||
|
} memblock_region_status_t;
|
||||||
|
|
||||||
typedef struct memblock_region {
|
typedef struct memblock_region {
|
||||||
/* the address of the first byte that makes up the region */
|
/* the address of the first byte that makes up the region */
|
||||||
uintptr_t base;
|
uintptr_t base;
|
||||||
|
|||||||
Reference in New Issue
Block a user