memblock can now self re-allocate its internal buffers
memory allocated by memblock_alloc() can now be limited to a certain region.
This commit is contained in:
9
sandbox/base/include/socks/status.h
Normal file
9
sandbox/base/include/socks/status.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef SOCKS_STATUS_H_
|
||||
#define SOCKS_STATUS_H_
|
||||
|
||||
typedef unsigned int kern_status_t;
|
||||
|
||||
#define KERN_OK (0)
|
||||
#define KERN_ERR_UNIMPLEMENTED (1)
|
||||
|
||||
#endif
|
||||
@@ -2,11 +2,15 @@
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/mman.h>
|
||||
#include <socks/types.h>
|
||||
#include <socks/memblock.h>
|
||||
|
||||
/* we're working with 4MiB of simulated system RAM */
|
||||
#define MEMORY_SIZE_MB 128
|
||||
|
||||
#define ALLOC_START_MB 16
|
||||
#define ALLOC_END_MB 18
|
||||
|
||||
/* virtual address of where system memory is mapped */
|
||||
static void *system_memory = NULL;
|
||||
|
||||
@@ -33,6 +37,12 @@ int main(int argc, const char **argv)
|
||||
|
||||
printf("allocated %u MiB (0x%zx bytes) of memory to act as system RAM at %p\n", MEMORY_SIZE_MB, MB_TO_BYTES(MEMORY_SIZE_MB), system_memory);
|
||||
|
||||
uintptr_t voffset = (uintptr_t)system_memory;
|
||||
|
||||
memblock_init(MB_TO_BYTES(ALLOC_START_MB) + voffset, MB_TO_BYTES(ALLOC_END_MB) + voffset, voffset);
|
||||
|
||||
printf("memblock heap initialised in 0x%zx-0x%zx\n", MB_TO_BYTES(ALLOC_START_MB), MB_TO_BYTES(ALLOC_END_MB));
|
||||
|
||||
memblock_add(0, MB_TO_BYTES(MEMORY_SIZE_MB));
|
||||
|
||||
memblock_reserve(0x00000, 0x40000);
|
||||
|
||||
@@ -52,6 +52,14 @@ typedef struct memblock_type {
|
||||
} memblock_type_t;
|
||||
|
||||
typedef struct memblock {
|
||||
/* bounds of the memory region that can be used by memblock_alloc()
|
||||
both of these are virtual addresses */
|
||||
uintptr_t m_alloc_start, m_alloc_end;
|
||||
/* memblock assumes that all memory in the alloc zone is contiguously mapped
|
||||
(if paging is enabled). m_voffset is the offset that needs to be added to
|
||||
a given physical address to get the corresponding virtual address */
|
||||
uintptr_t m_voffset;
|
||||
|
||||
struct memblock_type memory;
|
||||
struct memblock_type reserved;
|
||||
} memblock_t;
|
||||
@@ -67,6 +75,8 @@ extern memblock_t memblock;
|
||||
|
||||
extern int __next_mem_range(memblock_iter_t *it);
|
||||
|
||||
extern int memblock_init(uintptr_t alloc_start, uintptr_t alloc_end, uintptr_t voffset);
|
||||
|
||||
extern int memblock_add(phys_addr_t base, size_t size);
|
||||
extern int memblock_reserve(phys_addr_t base, size_t size);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "socks/types.h"
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
@@ -20,6 +21,8 @@
|
||||
static memblock_region_t init_memory_regions[MEMBLOCK_INIT_MEMORY_REGION_COUNT];
|
||||
static memblock_region_t init_reserved_regions[MEMBLOCK_INIT_RESERVED_REGION_COUNT];
|
||||
|
||||
static phys_addr_t do_alloc(size_t size);
|
||||
|
||||
memblock_t memblock = {
|
||||
.memory.regions = init_memory_regions,
|
||||
.memory.count = 0,
|
||||
@@ -32,6 +35,19 @@ memblock_t memblock = {
|
||||
.reserved.name = "reserved",
|
||||
};
|
||||
|
||||
static void memblock_double_capacity(memblock_type_t *type)
|
||||
{
|
||||
size_t new_max = type->max * 2;
|
||||
|
||||
phys_addr_t new_regions_p = do_alloc(new_max * sizeof(memblock_region_t));
|
||||
|
||||
void *new_regions = (void *)(new_regions_p + memblock.m_voffset);
|
||||
memcpy(new_regions, type->regions, type->count * sizeof(memblock_region_t));
|
||||
|
||||
type->regions = new_regions;
|
||||
type->max = new_max;
|
||||
}
|
||||
|
||||
static int memblock_insert_region(memblock_type_t *type, memblock_region_t *to_add)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
@@ -71,6 +87,15 @@ static int memblock_remove_region(memblock_type_t *type, unsigned int i)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memblock_init(uintptr_t alloc_start, uintptr_t alloc_end, uintptr_t voffset)
|
||||
{
|
||||
memblock.m_alloc_start = alloc_start;
|
||||
memblock.m_alloc_end =alloc_end;
|
||||
memblock.m_voffset = voffset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int memblock_add_range(memblock_type_t *type, uintptr_t base, size_t size, memblock_region_status_t status)
|
||||
{
|
||||
if (size == 0) {
|
||||
@@ -163,20 +188,35 @@ int memblock_add_range(memblock_type_t *type, uintptr_t base, size_t size, membl
|
||||
|
||||
int memblock_add(uintptr_t base, size_t size)
|
||||
{
|
||||
if (memblock.memory.count >= memblock.memory.max - 2) {
|
||||
if (memblock.reserved.count >= memblock.reserved.max - 2) {
|
||||
memblock_double_capacity(&memblock.reserved);
|
||||
}
|
||||
|
||||
memblock_double_capacity(&memblock.memory);
|
||||
}
|
||||
|
||||
return memblock_add_range(&memblock.memory, base, size, MEMBLOCK_MEMORY);
|
||||
}
|
||||
|
||||
int memblock_reserve(uintptr_t base, size_t size)
|
||||
{
|
||||
if (memblock.reserved.count >= memblock.reserved.max - 2) {
|
||||
memblock_double_capacity(&memblock.reserved);
|
||||
}
|
||||
|
||||
return memblock_add_range(&memblock.reserved, base, size, MEMBLOCK_RESERVED);
|
||||
}
|
||||
|
||||
phys_addr_t memblock_alloc(size_t size)
|
||||
static phys_addr_t do_alloc(size_t size)
|
||||
{
|
||||
phys_addr_t allocated_base = ADDR_MAX;
|
||||
|
||||
phys_addr_t region_start = memblock.m_alloc_start - memblock.m_voffset;
|
||||
phys_addr_t region_end = memblock.m_alloc_end - memblock.m_voffset;
|
||||
|
||||
memblock_iter_t it;
|
||||
for_each_free_mem_range (&it, 0x0, ADDR_MAX) {
|
||||
for_each_free_mem_range (&it, region_start, region_end) {
|
||||
size_t region_size = it.it_limit - it.it_base + 1;
|
||||
if (region_size >= size) {
|
||||
allocated_base = it.it_base;
|
||||
@@ -196,6 +236,15 @@ phys_addr_t memblock_alloc(size_t size)
|
||||
return allocated_base;
|
||||
}
|
||||
|
||||
phys_addr_t memblock_alloc(size_t size)
|
||||
{
|
||||
if (memblock.reserved.count >= memblock.reserved.max - 2) {
|
||||
memblock_double_capacity(&memblock.reserved);
|
||||
}
|
||||
|
||||
return do_alloc(size);
|
||||
}
|
||||
|
||||
int memblock_free(phys_addr_t addr, size_t size)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
#ifndef SOCKS_VM_H_
|
||||
#define SOCKS_VM_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <socks/types.h>
|
||||
#include <socks/status.h>
|
||||
|
||||
/*******************************************
|
||||
* Beginning of machine-specific definitions
|
||||
*******************************************/
|
||||
typedef enum vm_zone_id {
|
||||
VM_ZONE_DMA = 0x01u,
|
||||
VM_ZONE_NORMAL = 0x02u,
|
||||
VM_ZONE_HIGHMEM = 0x03u,
|
||||
VM_ZONE_DMA = 1u,
|
||||
VM_ZONE_NORMAL = 2u,
|
||||
VM_ZONE_HIGHMEM = 3u,
|
||||
VM_ZONE_COUNT
|
||||
} vm_zone_id_t;
|
||||
/*******************************************
|
||||
* End of machine-specific definitions.
|
||||
*******************************************/
|
||||
|
||||
typedef enum vm_memory_region_status {
|
||||
VM_REGION_FREE = 0x01u,
|
||||
@@ -30,6 +27,10 @@ typedef struct vm_zone {
|
||||
unsigned z_reserved[32];
|
||||
} vm_zone_t;
|
||||
|
||||
typedef struct vm_pg_data {
|
||||
vm_zone_t pg_zones[VM_ZONE_COUNT];
|
||||
} vm_pg_data_t;
|
||||
|
||||
typedef struct vm_region {
|
||||
vm_memory_region_status_t r_status;
|
||||
phys_addr_t r_base;
|
||||
@@ -44,7 +45,7 @@ typedef struct vm_page {
|
||||
uint32_t p_flags; /* vm_page_flags_t bitfield */
|
||||
} __attribute__((packed)) vm_page_t;
|
||||
|
||||
extern void vm_bootstrap(void);
|
||||
extern kern_status_t vm_bootstrap(const vm_region_t *mem_map, size_t nr_mem_map_entries);
|
||||
|
||||
extern void vm_page_init(vm_page_t *pg);
|
||||
|
||||
34
sandbox/vm/vm_bootstrap.c
Normal file
34
sandbox/vm/vm_bootstrap.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <limits.h>
|
||||
#include <socks/vm.h>
|
||||
#include <socks/memblock.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* One vm_pg_data_t per NUMA node. Right now we're only worrying about a single node */
|
||||
static vm_pg_data_t node_data = {};
|
||||
|
||||
kern_status_t vm_bootstrap(const vm_region_t *mem_map, size_t nr_mem_map_entries)
|
||||
{
|
||||
uintptr_t pmap_min = UINTPTR_MAX, pmap_max = 0x0;
|
||||
|
||||
for (size_t i = 0; i < nr_mem_map_entries; i++) {
|
||||
if (mem_map[i].r_base < pmap_min) {
|
||||
pmap_min = mem_map[i].r_base;
|
||||
}
|
||||
|
||||
if (mem_map[i].r_limit > pmap_max) {
|
||||
pmap_max = mem_map[i].r_limit;
|
||||
}
|
||||
}
|
||||
|
||||
memblock_add(pmap_min, pmap_max);
|
||||
|
||||
|
||||
for (size_t i = 0; i < nr_mem_map_entries; i++) {
|
||||
if (mem_map[i].r_status == VM_REGION_RESERVED) {
|
||||
memblock_reserve(mem_map[i].r_base, mem_map[i].r_limit);
|
||||
}
|
||||
}
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user