AArch64 EL2 hypervisor for QEMU virt that boots at EL2
1

Configure Feed

Select the types of activity you want to include in your feed.

ariel / mm / allocator.c
1.9 kB 78 lines
1#include "hv/allocator.h" 2#include "hv/config.h" 3#include "hv/panic.h" 4#include "hv/string.h" 5#include "hv/uart.h" 6 7#define MAX_ALLOC_PAGES 1024u 8 9static paddr_t g_base; 10static uint64_t g_size; 11static uint8_t g_used[MAX_ALLOC_PAGES]; 12static uint64_t g_pages; 13 14void allocator_init(paddr_t base, uint64_t size) 15{ 16 BUG_ON(!hv_is_aligned_u64(base, CONFIG_PAGE_SIZE)); 17 BUG_ON(!hv_is_aligned_u64(size, CONFIG_PAGE_SIZE)); 18 g_base = base; 19 g_size = size; 20 g_pages = size / CONFIG_PAGE_SIZE; 21 BUG_ON(g_pages > MAX_ALLOC_PAGES); 22 hv_memset(g_used, 0, sizeof(g_used)); 23} 24 25void *alloc_page(void) 26{ 27 for (uint64_t i = 0; i < g_pages; i++) { 28 if (g_used[i] == 0u) { 29 g_used[i] = 1u; 30 return (void *)(uintptr_t)(g_base + (i * CONFIG_PAGE_SIZE)); 31 } 32 } 33 return (void *)0; 34} 35 36bool allocator_owns(paddr_t addr, uint64_t size) 37{ 38 uint64_t end; 39 uint64_t alloc_end; 40 if (hv_add_overflow_u64(addr, size, &end) || 41 hv_add_overflow_u64(g_base, g_size, &alloc_end)) { 42 return false; 43 } 44 return addr >= g_base && end <= alloc_end; 45} 46 47bool allocator_selftest(void) 48{ 49 if (!hv_is_aligned_u64(g_base, CONFIG_PAGE_SIZE) || g_pages == 0u) { 50 return false; 51 } 52 uint64_t free_count = 0; 53 for (uint64_t i = 0; i < g_pages; i++) { 54 if (g_used[i] == 0u) { 55 free_count++; 56 } 57 } 58 return free_count != 0u && allocator_owns(g_base, CONFIG_PAGE_SIZE); 59} 60 61void allocator_dump(void) 62{ 63 uint64_t used = 0; 64 for (uint64_t i = 0; i < g_pages; i++) { 65 if (g_used[i] != 0u) { 66 used++; 67 } 68 } 69 uart_puts("allocator base="); 70 uart_put_hex64(g_base); 71 uart_puts(" size="); 72 uart_put_hex64(g_size); 73 uart_puts(" pages="); 74 uart_put_dec64(g_pages); 75 uart_puts(" used="); 76 uart_put_dec64(used); 77 uart_puts("\n"); 78}