memblock: add alignment parameter to alloc functions

This commit is contained in:
2023-02-06 20:38:32 +00:00
parent a72117abcd
commit 6afb3bd10d
4 changed files with 25 additions and 14 deletions

View File

@@ -251,8 +251,11 @@ extern int memblock_reserve(phys_addr_t base, size_t size);
previous calls to memblock_alloc() previous calls to memblock_alloc()
@param size the size of the buffer to allocate in bytes. @param size the size of the buffer to allocate in bytes.
@param align the alignment to use. for example, an alignment of 4096
will result in the returned pointer being a multiple
of 4096. this must be a power of 2.
*/ */
extern void *memblock_alloc(size_t size); extern void *memblock_alloc(size_t size, phys_addr_t align);
/* allocate a block of memory, returning a physical address. /* allocate a block of memory, returning a physical address.
@@ -270,8 +273,11 @@ extern void *memblock_alloc(size_t size);
previous calls to memblock_alloc() previous calls to memblock_alloc()
@param size the size of the buffer to allocate in bytes. @param size the size of the buffer to allocate in bytes.
@param align the alignment to use. for example, an alignment of 4096
will result in the returned pointer being a multiple
of 4096. this must be a power of 2.
*/ */
extern phys_addr_t memblock_alloc_phys(size_t size); extern phys_addr_t memblock_alloc_phys(size_t size, phys_addr_t align);
/* free a block of memory using its virtual address. /* free a block of memory using its virtual address.

View File

@@ -14,7 +14,7 @@ kern_status_t vm_bootstrap(const vm_zone_descriptor_t *zones, size_t nr_zones)
int numa_count = 1; int numa_count = 1;
/* we're only worrying about UMA systems for now */ /* we're only worrying about UMA systems for now */
node_data = memblock_alloc(sizeof(vm_pg_data_t) * numa_count); node_data = memblock_alloc(sizeof(vm_pg_data_t) * numa_count, 8);
vm_page_init_array(); vm_page_init_array();

View File

@@ -41,7 +41,7 @@
static memblock_region_t init_memory_regions[MEMBLOCK_INIT_MEMORY_REGION_COUNT]; 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 memblock_region_t init_reserved_regions[MEMBLOCK_INIT_RESERVED_REGION_COUNT];
static phys_addr_t do_alloc(size_t size); static phys_addr_t do_alloc(size_t size, phys_addr_t align);
memblock_t memblock = { memblock_t memblock = {
.memory.regions = init_memory_regions, .memory.regions = init_memory_regions,
@@ -59,7 +59,7 @@ static void memblock_double_capacity(memblock_type_t *type)
{ {
size_t new_max = type->max * 2; size_t new_max = type->max * 2;
phys_addr_t new_regions_p = do_alloc(new_max * sizeof(memblock_region_t)); phys_addr_t new_regions_p = do_alloc(new_max * sizeof(memblock_region_t), 8);
void *new_regions = (void *)(new_regions_p + memblock.m_voffset); void *new_regions = (void *)(new_regions_p + memblock.m_voffset);
memcpy(new_regions, type->regions, type->count * sizeof(memblock_region_t)); memcpy(new_regions, type->regions, type->count * sizeof(memblock_region_t));
@@ -228,8 +228,13 @@ int memblock_reserve(uintptr_t base, size_t size)
return memblock_add_range(&memblock.reserved, base, size, MEMBLOCK_RESERVED); return memblock_add_range(&memblock.reserved, base, size, MEMBLOCK_RESERVED);
} }
static phys_addr_t do_alloc(size_t size) static phys_addr_t do_alloc(size_t size, phys_addr_t align)
{ {
if (!align) {
/* align to 8-byte boundary by default */
align = 0x8;
}
phys_addr_t allocated_base = ADDR_MAX; phys_addr_t allocated_base = ADDR_MAX;
phys_addr_t region_start = memblock.m_alloc_start - memblock.m_voffset; phys_addr_t region_start = memblock.m_alloc_start - memblock.m_voffset;
@@ -237,9 +242,9 @@ static phys_addr_t do_alloc(size_t size)
memblock_iter_t it; memblock_iter_t it;
for_each_free_mem_range (&it, region_start, region_end) { for_each_free_mem_range (&it, region_start, region_end) {
if (it.it_base & 0xF) { if (it.it_base & (align - 1)) {
it.it_base &= ~0xF; it.it_base &= ~(align - 1);
it.it_base += 0x10; it.it_base += align;
} }
size_t region_size = it.it_limit - it.it_base + 1; size_t region_size = it.it_limit - it.it_base + 1;
@@ -261,13 +266,13 @@ static phys_addr_t do_alloc(size_t size)
return allocated_base; return allocated_base;
} }
void *memblock_alloc(size_t size) void *memblock_alloc(size_t size, phys_addr_t align)
{ {
if (memblock.reserved.count >= memblock.reserved.max - 2) { if (memblock.reserved.count >= memblock.reserved.max - 2) {
memblock_double_capacity(&memblock.reserved); memblock_double_capacity(&memblock.reserved);
} }
phys_addr_t p = do_alloc(size); phys_addr_t p = do_alloc(size, align);
if (p) { if (p) {
p += memblock.m_voffset; p += memblock.m_voffset;
} }
@@ -275,13 +280,13 @@ void *memblock_alloc(size_t size)
return (void *)p; return (void *)p;
} }
phys_addr_t memblock_alloc_phys(size_t size) phys_addr_t memblock_alloc_phys(size_t size, phys_addr_t align)
{ {
if (memblock.reserved.count >= memblock.reserved.max - 2) { if (memblock.reserved.count >= memblock.reserved.max - 2) {
memblock_double_capacity(&memblock.reserved); memblock_double_capacity(&memblock.reserved);
} }
return do_alloc(size); return do_alloc(size, align);
} }
int memblock_free(void *p, size_t size) int memblock_free(void *p, size_t size)

View File

@@ -69,7 +69,7 @@ void vm_page_init_array()
nr_pages++; nr_pages++;
} }
page_array = memblock_alloc(sizeof(vm_page_t) * nr_pages); page_array = memblock_alloc(sizeof(vm_page_t) * nr_pages, 8);
page_array_count = nr_pages; page_array_count = nr_pages;
for (size_t i = 0; i < nr_pages; i++) { for (size_t i = 0; i < nr_pages; i++) {