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 "x86_64/mem.h"
|
||||||
|
|
||||||
#include "bootboot.h"
|
#include "bootboot.h"
|
||||||
|
#include "ram.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
#include "tar.h"
|
#include "tar.h"
|
||||||
|
|
@ -84,6 +85,7 @@ struct mem_range range_ptr[10];
|
||||||
* Entry point, called by BOOTBOOT Loader *
|
* Entry point, called by BOOTBOOT Loader *
|
||||||
******************************************/
|
******************************************/
|
||||||
void _start() {
|
void _start() {
|
||||||
|
ram_init();
|
||||||
/*** NOTE: this code runs on all cores in parallel ***/
|
/*** NOTE: this code runs on all cores in parallel ***/
|
||||||
|
|
||||||
unsigned info[4];
|
unsigned info[4];
|
||||||
|
|
|
||||||
60
src/ram.c
60
src/ram.c
|
|
@ -26,7 +26,6 @@ struct free_block {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ram_layer {
|
struct ram_layer {
|
||||||
uint64_t total_blocks;
|
|
||||||
uint64_t first_free;
|
uint64_t first_free;
|
||||||
bitmap *avail_bitmap;
|
bitmap *avail_bitmap;
|
||||||
bitmap *frag_bitmap;
|
bitmap *frag_bitmap;
|
||||||
|
|
@ -230,25 +229,10 @@ ram_free_frame(frame_addr frame)
|
||||||
free_block(frame.base);
|
free_block(frame.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
// Find largest memory address available
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
ram_find_addr_limit(void)
|
ram_find_addr_limit(void)
|
||||||
{
|
{
|
||||||
// Find largest memory address available
|
|
||||||
uint64_t addrLimit = 0;
|
uint64_t addrLimit = 0;
|
||||||
MMapEnt *ment = &bootboot.mmap;
|
MMapEnt *ment = &bootboot.mmap;
|
||||||
while ((uint64_t)ment < (uint64_t)&bootboot + bootboot.size) {
|
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 length = MMapEnt_Size(ment); // in bytes
|
||||||
uint64_t end = start + length;
|
uint64_t end = start + length;
|
||||||
if (addrLimit < end) addrLimit = end;
|
if (addrLimit < end) addrLimit = end;
|
||||||
|
printf("%x %p %lu\n", MMapEnt_Type(ment), (void *)start, length);
|
||||||
ment++;
|
ment++;
|
||||||
}
|
}
|
||||||
return addrLimit;
|
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
|
void
|
||||||
ram_init(void)
|
ram_init(void)
|
||||||
{
|
{
|
||||||
|
MMapEnt *donor = ram_find_donor_range();
|
||||||
|
ASSERT(donor != NULL);
|
||||||
|
|
||||||
// Calculate how many levels we need
|
// Calculate how many levels we need
|
||||||
uint64_t addrLimit = ram_find_addr_limit();
|
uint64_t addrLimit = ram_find_addr_limit();
|
||||||
addrLimit = next_pow2(addrLimit);
|
addrLimit = next_pow2(addrLimit);
|
||||||
|
|
@ -272,8 +286,18 @@ ram_init(void)
|
||||||
}
|
}
|
||||||
ram_num_levels = __builtin_ffsl(addrLimit); // log2(addrLimit) + 1
|
ram_num_levels = __builtin_ffsl(addrLimit); // log2(addrLimit) + 1
|
||||||
ram_num_levels -= 12;
|
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
|
#if 0
|
||||||
// Mark all free memory blocks as available
|
// Mark all free memory blocks as available
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue