14Srgrimes/* 24Srgrimes * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. 34Srgrimes * Copyright 2019, Haiku, Inc. All rights reserved. 44Srgrimes * Distributed under the terms of the MIT License. 54Srgrimes */ 64Srgrimes 74Srgrimesextern "C" { 84Srgrimes#include <compat/sys/malloc.h> 94Srgrimes} 104Srgrimes 114Srgrimes#include <stdio.h> 124Srgrimes#include <string.h> 134Srgrimes 144Srgrimes#include <util/BitUtils.h> 154Srgrimes 164Srgrimes#include <kernel/heap.h> 174Srgrimes#include <kernel/vm/vm.h> 184Srgrimes 194Srgrimes 204Srgrimesvoid* 214Srgrimes_kernel_malloc(size_t size, int flags) 224Srgrimes{ 234Srgrimes // According to the FreeBSD kernel malloc man page the allocator is expected 244Srgrimes // to return power of two aligned addresses for allocations up to one page 254Srgrimes // size. While it also states that this shouldn't be relied upon, at least 264Srgrimes // bus_dmamem_alloc expects it and drivers may depend on it as well. 274Srgrimes void *ptr 284Srgrimes = memalign_etc(size >= PAGESIZE ? PAGESIZE : next_power_of_2(size), size, 294Srgrimes (flags & M_NOWAIT) ? HEAP_DONT_WAIT_FOR_MEMORY : 0); 304Srgrimes if (ptr == NULL) 314Srgrimes return NULL; 324Srgrimes 334Srgrimes if (flags & M_ZERO) 344Srgrimes memset(ptr, 0, size); 354Srgrimes 36619Srgrimes return ptr; 3710268Sbde} 384Srgrimes 394Srgrimes 403185Ssosvoid 413185Ssos_kernel_free(void *ptr) 423185Ssos{ 433185Ssos free(ptr); 443185Ssos} 452913Sache 462913Sache 474Srgrimesvoid * 484Srgrimes_kernel_contigmalloc(const char *file, int line, size_t size, int flags, 494Srgrimes vm_paddr_t low, vm_paddr_t high, unsigned long alignment, 502056Swollman unsigned long boundary) 512056Swollman{ 522056Swollman const bool zero = (flags & M_ZERO) != 0, dontWait = (flags & M_NOWAIT) != 0; 532056Swollman 544180Sbde size = ROUNDUP(size, B_PAGE_SIZE); 552056Swollman 562056Swollman uint32 creationFlags = (zero ? 0 : CREATE_AREA_DONT_CLEAR) 572056Swollman | (dontWait ? CREATE_AREA_DONT_WAIT : 0); 587090Sbde 592056Swollman char name[B_OS_NAME_LENGTH]; 602056Swollman const char* baseName = strrchr(file, '/'); 614Srgrimes baseName = baseName != NULL ? baseName + 1 : file; 622873Sbde snprintf(name, sizeof(name), "contig:%s:%d", baseName, line); 632873Sbde 642873Sbde virtual_address_restrictions virtualRestrictions = {}; 652873Sbde 662873Sbde physical_address_restrictions physicalRestrictions = {}; 672913Sache physicalRestrictions.low_address = low; 682873Sbde physicalRestrictions.high_address = high; 694Srgrimes physicalRestrictions.alignment = alignment; 704Srgrimes physicalRestrictions.boundary = boundary; 714Srgrimes 724Srgrimes void* address; 731390Ssos area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS, 744Srgrimes B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0, 754180Sbde &virtualRestrictions, &physicalRestrictions, &address); 764180Sbde if (area < 0) 774180Sbde return NULL; 784180Sbde 794180Sbde return address; 804180Sbde} 814180Sbde 824180Sbde 834180Sbdevoid 844180Sbde_kernel_contigfree(void *addr, size_t size) 854180Sbde{ 864180Sbde if (addr == NULL) 874180Sbde return; 884180Sbde 894180Sbde delete_area(area_for(addr)); 904180Sbde} 914180Sbde 924180Sbde 934180Sbdevm_paddr_t 943366Sachepmap_kextract(vm_offset_t virtualAddress) 958448Sbde{ 962017Swollman physical_entry entry; 974180Sbde status_t status = get_memory_map((void *)virtualAddress, 1, &entry, 1); 982017Swollman if (status < B_OK) { 995291Sbde panic("fbsd compat: get_memory_map failed for %p, error %08" B_PRIx32 1004180Sbde "\n", (void *)virtualAddress, status); 1014180Sbde } 1024180Sbde 1031390Ssos return (vm_paddr_t)entry.address; 1044180Sbde} 1055291Sbde