vm: refactor page_array and functions into a separate source file
This commit is contained in:
@@ -30,6 +30,11 @@ typedef struct vm_object {
|
|||||||
unsigned int reserved;
|
unsigned int reserved;
|
||||||
} vm_object_t;
|
} vm_object_t;
|
||||||
|
|
||||||
|
typedef enum vm_model {
|
||||||
|
VM_MODEL_FLAT = 1,
|
||||||
|
VM_MODEL_SPARSE,
|
||||||
|
} vm_model_t;
|
||||||
|
|
||||||
typedef enum vm_prot {
|
typedef enum vm_prot {
|
||||||
VM_PROT_READ = 0x01u,
|
VM_PROT_READ = 0x01u,
|
||||||
VM_PROT_WRITE = 0x02u,
|
VM_PROT_WRITE = 0x02u,
|
||||||
@@ -207,6 +212,8 @@ typedef struct vm_page {
|
|||||||
} __attribute__((aligned(2 * sizeof(unsigned long)))) vm_page_t;
|
} __attribute__((aligned(2 * sizeof(unsigned long)))) vm_page_t;
|
||||||
|
|
||||||
extern kern_status_t vm_bootstrap(const vm_zone_descriptor_t *zones, size_t nr_zones);
|
extern kern_status_t vm_bootstrap(const vm_zone_descriptor_t *zones, size_t nr_zones);
|
||||||
|
extern vm_model_t vm_memory_model(void);
|
||||||
|
extern void vm_set_memory_model(vm_model_t model);
|
||||||
|
|
||||||
extern vm_pg_data_t *vm_pg_data_get(vm_node_id_t node);
|
extern vm_pg_data_t *vm_pg_data_get(vm_node_id_t node);
|
||||||
|
|
||||||
@@ -247,4 +254,9 @@ extern void *kmalloc(size_t count, vm_flags_t flags);
|
|||||||
extern void *kzalloc(size_t count, vm_flags_t flags);
|
extern void *kzalloc(size_t count, vm_flags_t flags);
|
||||||
extern void kfree(void *p);
|
extern void kfree(void *p);
|
||||||
|
|
||||||
|
/* Flat memory model functions */
|
||||||
|
extern void vm_flat_init(void);
|
||||||
|
extern vm_page_t *vm_page_get_flat(phys_addr_t addr);
|
||||||
|
extern size_t vm_page_get_pfn_flat(vm_page_t *pg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ kern_status_t vm_bootstrap(const vm_zone_descriptor_t *zones, size_t nr_zones)
|
|||||||
node_data = memblock_alloc(sizeof(vm_pg_data_t) * numa_count, 8);
|
node_data = memblock_alloc(sizeof(vm_pg_data_t) * numa_count, 8);
|
||||||
printk("vm: initialising %u node%s", numa_count, numa_count > 1 ? "s" : "");
|
printk("vm: initialising %u node%s", numa_count, numa_count > 1 ? "s" : "");
|
||||||
|
|
||||||
vm_page_init_array();
|
vm_set_memory_model(VM_MODEL_FLAT);
|
||||||
|
vm_flat_init();
|
||||||
|
|
||||||
for (size_t i = 0; i < nr_zones; i++) {
|
for (size_t i = 0; i < nr_zones; i++) {
|
||||||
vm_zone_init(&node_data->pg_zones[zones[i].zd_id], &zones[i]);
|
vm_zone_init(&node_data->pg_zones[zones[i].zd_id], &zones[i]);
|
||||||
|
|||||||
58
vm/flat.c
Normal file
58
vm/flat.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#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 vm_page_t *page_array = NULL;
|
||||||
|
|
||||||
|
/* number of pages stored in page_array */
|
||||||
|
static size_t page_array_count = 0;
|
||||||
|
|
||||||
|
void vm_flat_init()
|
||||||
|
{
|
||||||
|
printk("vm: using flat memory model");
|
||||||
|
size_t pmem_size = 0;
|
||||||
|
|
||||||
|
memblock_iter_t 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(vm_page_t) * 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_page_t *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(vm_page_t *pg)
|
||||||
|
{
|
||||||
|
return ((uintptr_t)pg - (uintptr_t)page_array) / sizeof *pg;
|
||||||
|
}
|
||||||
13
vm/model.c
Normal file
13
vm/model.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include <socks/vm.h>
|
||||||
|
|
||||||
|
static vm_model_t model;
|
||||||
|
|
||||||
|
vm_model_t vm_memory_model(void)
|
||||||
|
{
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vm_set_memory_model(vm_model_t m)
|
||||||
|
{
|
||||||
|
model = m;
|
||||||
|
}
|
||||||
58
vm/page.c
58
vm/page.c
@@ -4,12 +4,6 @@
|
|||||||
#include <socks/vm.h>
|
#include <socks/vm.h>
|
||||||
#include <socks/libc/string.h>
|
#include <socks/libc/string.h>
|
||||||
|
|
||||||
/* array of pages, one for each physical page frame present in RAM */
|
|
||||||
static vm_page_t *page_array = NULL;
|
|
||||||
|
|
||||||
/* number of pages stored in page_array */
|
|
||||||
static size_t page_array_count = 0;
|
|
||||||
|
|
||||||
/* Pre-calculated page order -> size conversion table */
|
/* Pre-calculated page order -> size conversion table */
|
||||||
static size_t page_order_bytes[] = {
|
static size_t page_order_bytes[] = {
|
||||||
[VM_PAGE_4K] = 0x1000,
|
[VM_PAGE_4K] = 0x1000,
|
||||||
@@ -64,47 +58,14 @@ void *vm_phys_to_virt(phys_addr_t p)
|
|||||||
return (void *)(VM_PAGEMAP_BASE + p);
|
return (void *)(VM_PAGEMAP_BASE + p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_page_init_array()
|
|
||||||
{
|
|
||||||
size_t pmem_size = 0;
|
|
||||||
|
|
||||||
memblock_iter_t 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(vm_page_t) * 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
vm_page_t *vm_page_get(phys_addr_t addr)
|
vm_page_t *vm_page_get(phys_addr_t addr)
|
||||||
{
|
{
|
||||||
size_t pfn = addr / VM_PAGE_SIZE;
|
switch (vm_memory_model()) {
|
||||||
return pfn < page_array_count ? &page_array[pfn] : NULL;
|
case VM_MODEL_FLAT:
|
||||||
|
return vm_page_get_flat(addr);
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
phys_addr_t vm_page_get_paddr(vm_page_t *pg)
|
phys_addr_t vm_page_get_paddr(vm_page_t *pg)
|
||||||
@@ -119,7 +80,12 @@ void *vm_page_get_vaddr(vm_page_t *pg)
|
|||||||
|
|
||||||
size_t vm_page_get_pfn(vm_page_t *pg)
|
size_t vm_page_get_pfn(vm_page_t *pg)
|
||||||
{
|
{
|
||||||
return ((uintptr_t)pg - (uintptr_t)page_array) / sizeof *pg;
|
switch (vm_memory_model()) {
|
||||||
|
case VM_MODEL_FLAT:
|
||||||
|
return vm_page_get_pfn_flat(pg);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t vm_page_order_to_bytes(vm_page_order_t order)
|
size_t vm_page_order_to_bytes(vm_page_order_t order)
|
||||||
|
|||||||
Reference in New Issue
Block a user