28 pmapregion_t *r =
map->region +
map->count;
31 r->type = (int32_t)type;
41 const pmapregion_t *r1 = (
const pmapregion_t *)a;
42 const pmapregion_t *r2 = (
const pmapregion_t *)b;
43 if (r1->addr > r2->addr)
45 if (r1->addr < r2->addr)
47 if (r1->size > r2->size)
49 if (r1->size < r2->size)
60 memmove(r, r + 1, (term - r) *
sizeof(pmapregion_t));
70 memmove(r + 2, r + 1, (term - (r + 1)) *
sizeof(pmapregion_t));
76 resort(pmapregion_t *r, pmapregion_t *term)
78 while (r + 1 < term) {
81 pmapregion_t tmp = r[0];
93 pmapregion_t *curr =
map->region;
94 pmapregion_t *term =
map->region +
map->count;
96 while (curr + 1 < term) {
99 if (curr->size == 0) {
104 pmapregion_t *next = curr + 1;
106 uint64_t cl = curr->addr;
107 uint64_t cr = curr->addr + curr->size;
108 uint64_t nl = next->addr;
109 uint64_t nr = next->addr + next->size;
112 if (
min(cr, nr) <=
max(cl, nl)) {
124 if (next->type > curr->type) {
136 if (next->type > curr->type) {
144 next->size = nr - cr;
153 if (next->type > curr->type) {
156 curr->size = nl - cl;
165 if (next->type > curr->type) {
168 curr->size = nl - cl;
173 next->size = nr - cr;
179 if (next->type > curr->type) {
183 curr->size = nl - cl;
186 next[1].size = cr - nr;
187 next[1].type = curr->type;
188 next[1].flags = curr->flags;
207 pmapregion_t *curr =
map->region;
208 pmapregion_t *term =
map->region +
map->count;
210 while (curr + 1 < term) {
211 pmapregion_t *next = curr + 1;
213 uint64_t cr = curr->addr + curr->size;
214 uint64_t nl = next->addr;
223 if (curr->type == type) {
224 curr->size += nl - cr;
226 else if (next->type == type) {
227 next->size += nl - cr;
236 next->size = nl - cr;
247 pmapregion_t *curr =
map->region;
248 pmapregion_t *term =
map->region +
map->count;
250 while (curr + 1 < term) {
251 pmapregion_t *next = curr + 1;
252 if (curr->type == next->type) {
253 curr->size += next->size;
265 map->last_usable = 0;
266 for (
int i =
map->count - 1; i >= 0; i--) {
267 const pmapregion_t *r = &
map->region[i];
269 map->last_usable = r->addr + r->size;
279 qsort(
map->region,
map->count,
sizeof(pmapregion_t),
static void resort(pmapregion_t *r, pmapregion_t *term)
Re-sort all unsorted region records starting from the requested record.
const pmap_t * pmap()
Return a pointer to the current physical memory map.
Physical memory map describing usable and reserved regions of physical memory.
String and memory operations.
#define min(a, b)
Generic min/max routines.
#define KMEM_KERNEL_IMAGE_END
Kernel physical (and virtual) memory map.
static void fill_gaps(int32_t type)
Find missing memory regions in the map, and fill them with entries of the requested type...
pmemtype
The types of physical memory.
Marked as uncacheable, usually for I/O.
Reported usable by the BIOS.
void * memmove(void *dst, const void *src, size_t num)
Move bytes from one memory region to another, even if the regions overlap.
static void update_last_usable()
static int cmp_region(const void *a, const void *b)
Compare two memory region records and return a sorting integer.
void pmap_add(uint64_t addr, uint64_t size, enum pmemtype type)
Add a region of memory to the physical memory map.
static void add_region(uint64_t addr, uint64_t size, enum pmemtype type)
Add a memory region to the end of the memory map.
void qsort(void *base, size_t num, size_t size, sortcmp cmp)
Sort the elements of an array using a sort comparison function.
void pmap_init()
Initialize the physical memory map using data installed by the BIOS during boot loading.
Reported (or inferred) to be reserved.
static void collapse_overlaps()
Find all overlapping memory regions in the memory map and collapse or reorganize them.
General utilities library.
static void consolidate_neighbors()
Find adjacent memory entries of the same type and merge them.
static void collapse(pmapregion_t *r, pmapregion_t *term)
Remove a region from the memory map and shift all subsequent regions down by one. ...
static void insertafter(pmapregion_t *r, pmapregion_t *term)
Insert a new, uninitialized memory region record after an existing record in the memory map...