Stealing memory from the mmap to init phys alloc
This commit is contained in:
parent
4556fd1eed
commit
a250490e69
2 changed files with 44 additions and 18 deletions
|
|
@ -36,6 +36,7 @@
|
|||
#include "x86_64/mem.h"
|
||||
|
||||
#include "bootboot.h"
|
||||
#include "ram.h"
|
||||
#include "pci.h"
|
||||
#include "std.h"
|
||||
#include "tar.h"
|
||||
|
|
@ -84,6 +85,7 @@ struct mem_range range_ptr[10];
|
|||
* Entry point, called by BOOTBOOT Loader *
|
||||
******************************************/
|
||||
void _start() {
|
||||
ram_init();
|
||||
/*** NOTE: this code runs on all cores in parallel ***/
|
||||
|
||||
unsigned info[4];
|
||||
|
|
|
|||
60
src/ram.c
60
src/ram.c
|
|
@ -26,7 +26,6 @@ struct free_block {
|
|||
};
|
||||
|
||||
struct ram_layer {
|
||||
uint64_t total_blocks;
|
||||
uint64_t first_free;
|
||||
bitmap *avail_bitmap;
|
||||
bitmap *frag_bitmap;
|
||||
|
|
@ -230,25 +229,10 @@ ram_free_frame(frame_addr frame)
|
|||
free_block(frame.base);
|
||||
}
|
||||
|
||||
static void
|
||||
ram_alloc_datastructures()
|
||||
{
|
||||
#if 0
|
||||
uint64_t neededBytes = 0;
|
||||
|
||||
for (unsigned level = 0; level < ram_num_levels; level++) {
|
||||
neededBytes += 2 * BITMAP_SIZE();
|
||||
}
|
||||
|
||||
for (unsigned level = 0; level < ram_num_levels; level++) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Find largest memory address available
|
||||
static uint64_t
|
||||
ram_find_addr_limit(void)
|
||||
{
|
||||
// Find largest memory address available
|
||||
uint64_t addrLimit = 0;
|
||||
MMapEnt *ment = &bootboot.mmap;
|
||||
while ((uint64_t)ment < (uint64_t)&bootboot + bootboot.size) {
|
||||
|
|
@ -256,14 +240,44 @@ ram_find_addr_limit(void)
|
|||
uint64_t length = MMapEnt_Size(ment); // in bytes
|
||||
uint64_t end = start + length;
|
||||
if (addrLimit < end) addrLimit = end;
|
||||
printf("%x %p %lu\n", MMapEnt_Type(ment), (void *)start, length);
|
||||
ment++;
|
||||
}
|
||||
return addrLimit;
|
||||
}
|
||||
|
||||
// Find largest contiguous free range
|
||||
static MMapEnt *
|
||||
ram_find_donor_range(void)
|
||||
{
|
||||
MMapEnt *donor = NULL;
|
||||
MMapEnt *ment = &bootboot.mmap;
|
||||
for (; (uint64_t)ment < (uint64_t)&bootboot + bootboot.size; ment++) {
|
||||
if (!MMapEnt_IsFree(ment)) continue;
|
||||
if (!donor || MMapEnt_Size(donor) < MMapEnt_Size(ment)) {
|
||||
donor = ment;
|
||||
}
|
||||
}
|
||||
return donor;
|
||||
}
|
||||
|
||||
static void *
|
||||
ram_steal_memory(MMapEnt *donor, size_t nbytes)
|
||||
{
|
||||
nbytes = (nbytes + 15) & 0xFFFFFFFFFFFFFFF0ul;
|
||||
printf("ram_steal_memory: donor size = %lu, nbytes = %lu\n", MMapEnt_Size(donor), nbytes);
|
||||
ASSERT(MMapEnt_Size(donor) >= nbytes);
|
||||
donor->size -= nbytes;
|
||||
uint64_t addr = donor->ptr + donor->size;
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
void
|
||||
ram_init(void)
|
||||
{
|
||||
MMapEnt *donor = ram_find_donor_range();
|
||||
ASSERT(donor != NULL);
|
||||
|
||||
// Calculate how many levels we need
|
||||
uint64_t addrLimit = ram_find_addr_limit();
|
||||
addrLimit = next_pow2(addrLimit);
|
||||
|
|
@ -272,8 +286,18 @@ ram_init(void)
|
|||
}
|
||||
ram_num_levels = __builtin_ffsl(addrLimit); // log2(addrLimit) + 1
|
||||
ram_num_levels -= 12;
|
||||
printf("addrLimit = %lu\n", addrLimit);
|
||||
printf("ram_num_levels = %u\n", ram_num_levels);
|
||||
|
||||
ram_alloc_datastructures();
|
||||
for (unsigned level = 0; level < ram_num_levels; level++) {
|
||||
ram_layers[level].first_free = INVALID_FRAME_ADDR;
|
||||
size_t bitmapSize = BITMAP_SIZE(1ul << (ram_num_levels - level - 1));
|
||||
ram_layers[level].avail_bitmap = ram_steal_memory(donor, bitmapSize);
|
||||
ram_layers[level].frag_bitmap = ram_steal_memory(donor, bitmapSize);
|
||||
}
|
||||
|
||||
// Realign donor range to page boundaries
|
||||
donor->size &= UINT64_C(0xFFFFFFFFFFFFF00F);
|
||||
|
||||
#if 0
|
||||
// Mark all free memory blocks as available
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue