1 /* 2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2019, Haiku, Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 extern "C" { 8 #include <compat/sys/malloc.h> 9 } 10 11 #include <stdio.h> 12 #include <string.h> 13 14 #include <util/BitUtils.h> 15 16 #include <kernel/heap.h> 17 #include <kernel/vm/vm.h> 18 19 20 void* 21 _kernel_malloc(size_t size, int flags) 22 { 23 // According to the FreeBSD kernel malloc man page the allocator is expected 24 // to return power of two aligned addresses for allocations up to one page 25 // size. While it also states that this shouldn't be relied upon, at least 26 // bus_dmamem_alloc expects it and drivers may depend on it as well. 27 void *ptr 28 = memalign_etc(size >= PAGESIZE ? PAGESIZE : next_power_of_2(size), size, 29 (flags & M_NOWAIT) ? HEAP_DONT_WAIT_FOR_MEMORY : 0); 30 if (ptr == NULL) 31 return NULL; 32 33 if (flags & M_ZERO) 34 memset(ptr, 0, size); 35 36 return ptr; 37 } 38 39 40 void 41 _kernel_free(void *ptr) 42 { 43 free(ptr); 44 } 45 46 47 void * 48 _kernel_contigmalloc(const char *file, int line, size_t size, int flags, 49 vm_paddr_t low, vm_paddr_t high, unsigned long alignment, 50 unsigned long boundary) 51 { 52 const bool zero = (flags & M_ZERO) != 0, dontWait = (flags & M_NOWAIT) != 0; 53 54 size = ROUNDUP(size, B_PAGE_SIZE); 55 56 uint32 creationFlags = (zero ? 0 : CREATE_AREA_DONT_CLEAR) 57 | (dontWait ? CREATE_AREA_DONT_WAIT : 0); 58 59 char name[B_OS_NAME_LENGTH]; 60 const char* baseName = strrchr(file, '/'); 61 baseName = baseName != NULL ? baseName + 1 : file; 62 snprintf(name, sizeof(name), "contig:%s:%d", baseName, line); 63 64 virtual_address_restrictions virtualRestrictions = {}; 65 66 physical_address_restrictions physicalRestrictions = {}; 67 physicalRestrictions.low_address = low; 68 physicalRestrictions.high_address = high; 69 physicalRestrictions.alignment = alignment; 70 physicalRestrictions.boundary = boundary; 71 72 void* address; 73 area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS, 74 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0, 75 &virtualRestrictions, &physicalRestrictions, &address); 76 if (area < 0) 77 return NULL; 78 79 return address; 80 } 81 82 83 void 84 _kernel_contigfree(void *addr, size_t size) 85 { 86 if (addr == NULL) 87 return; 88 89 delete_area(area_for(addr)); 90 } 91 92 93 vm_paddr_t 94 pmap_kextract(vm_offset_t virtualAddress) 95 { 96 physical_entry entry; 97 status_t status = get_memory_map((void *)virtualAddress, 1, &entry, 1); 98 if (status < B_OK) { 99 panic("fbsd compat: get_memory_map failed for %p, error %08" B_PRIx32 100 "\n", (void *)virtualAddress, status); 101 } 102 103 return (vm_paddr_t)entry.address; 104 } 105