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