* Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2019, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
extern "C" {
#include <compat/sys/malloc.h>
}
#include <stdio.h>
#include <string.h>
#include <util/BitUtils.h>
#include <kernel/heap.h>
#include <kernel/vm/vm.h>
void*
_kernel_malloc(size_t size, int flags)
{
void *ptr
= memalign_etc(size >= PAGESIZE ? PAGESIZE : next_power_of_2(size), size,
(flags & M_NOWAIT) ? HEAP_DONT_WAIT_FOR_MEMORY : 0);
if (ptr == NULL)
return NULL;
if (flags & M_ZERO)
memset(ptr, 0, size);
return ptr;
}
void
_kernel_free(void *ptr)
{
free(ptr);
}
void *
_kernel_contigmalloc(const char *file, int line, size_t size, int flags,
vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
unsigned long boundary)
{
const bool zero = (flags & M_ZERO) != 0, dontWait = (flags & M_NOWAIT) != 0;
size = ROUNDUP(size, B_PAGE_SIZE);
uint32 creationFlags = (zero ? 0 : CREATE_AREA_DONT_CLEAR)
| (dontWait ? CREATE_AREA_DONT_WAIT : 0);
char name[B_OS_NAME_LENGTH];
const char* baseName = strrchr(file, '/');
baseName = baseName != NULL ? baseName + 1 : file;
snprintf(name, sizeof(name), "contig:%s:%d", baseName, line);
virtual_address_restrictions virtualRestrictions = {};
physical_address_restrictions physicalRestrictions = {};
physicalRestrictions.low_address = low;
physicalRestrictions.high_address = high;
physicalRestrictions.alignment = alignment;
physicalRestrictions.boundary = boundary;
void* address;
area_id area = create_area_etc(B_SYSTEM_TEAM, name, size, B_CONTIGUOUS,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, creationFlags, 0,
&virtualRestrictions, &physicalRestrictions, &address);
if (area < 0)
return NULL;
return address;
}
void
_kernel_contigfree(void *addr, size_t size)
{
if (addr == NULL)
return;
delete_area(area_for(addr));
}
vm_paddr_t
pmap_kextract(vm_offset_t virtualAddress)
{
physical_entry entry;
status_t status = get_memory_map((void *)virtualAddress, 1, &entry, 1);
if (status < B_OK) {
panic("fbsd compat: get_memory_map failed for %p, error %08" B_PRIx32
"\n", (void *)virtualAddress, status);
}
return (vm_paddr_t)entry.address;
}