Files
mango/vm/flat.c

76 lines
2.1 KiB
C
Raw Normal View History

2023-02-08 17:13:01 +00:00
/* ### The flat memory model ###
under this memory model, the system memory is represented by
a single contiguous array of vm_pages. this array spans from
physical address up to the last available byte, as provided by
memblock. any extra reserved regions after the last available
byte will not be included to save memory.
this memory model is good for systems with a smaller amount of
physical memory that is mostly contiguous with few holes or
reserved regions. it is simpler and has less overhead.
for systems with a large amount of memory, or with large
amounts of reserved memory (especially those whose reserved
memory outstripts free memory), the sparse memory model may
be a better choice.
*/
#include <socks/vm.h>
#include <socks/memblock.h>
#include <socks/printk.h>
/* array of pages, one for each physical page frame present in RAM */
static struct vm_page *page_array = NULL;
/* number of pages stored in page_array */
static size_t page_array_count = 0;
2023-02-08 17:13:01 +00:00
void vm_flat_init(void)
{
printk("vm: using flat memory model");
size_t pmem_size = 0;
struct memblock_iter it;
for_each_free_mem_range (&it, 0x0, UINTPTR_MAX) {
if (pmem_size < it.it_limit + 1) {
pmem_size = it.it_limit + 1;
}
}
size_t nr_pages = pmem_size / VM_PAGE_SIZE;
if (pmem_size % VM_PAGE_SIZE) {
nr_pages++;
}
page_array = memblock_alloc(sizeof(struct vm_page) * nr_pages, 8);
page_array_count = nr_pages;
size_t nr_reserved = nr_pages;
for (size_t i = 0; i < nr_pages; i++) {
page_array[i].p_flags = VM_PAGE_RESERVED;
}
for_each_free_mem_range(&it, 0x0, UINTPTR_MAX) {
for (uintptr_t i = it.it_base; i < it.it_limit; i += VM_PAGE_SIZE) {
size_t pfn = i / VM_PAGE_SIZE;
page_array[pfn].p_flags = 0;
nr_reserved--;
}
}
printk("vm: page array has %zu pages, %zu reserved", nr_pages, nr_reserved);
}
struct vm_page *vm_page_get_flat(phys_addr_t addr)
{
size_t pfn = addr / VM_PAGE_SIZE;
return pfn < page_array_count ? &page_array[pfn] : NULL;
}
size_t vm_page_get_pfn_flat(struct vm_page *pg)
{
return ((uintptr_t)pg - (uintptr_t)page_array) / sizeof *pg;
}