1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add the possibility to page aligned memory regions

=> usefull for device drivers (DMA transfers)
This commit is contained in:
Stefan Lankes 2016-07-27 22:30:00 +02:00
parent 7b1dd26d42
commit e8a61a299b
2 changed files with 75 additions and 0 deletions

View file

@ -96,6 +96,27 @@ int destroy_stack(void* addr, size_t sz);
*/
void kfree(void* addr);
/** @brief Kernel's more general memory allocator function.
*
* This function lets you choose flags for the newly allocated memory.
* The new region is always page aligned.
*
* @param sz Desired size of the new memory
* @param flags Flags to specify
*
* @return Pointer to the new memory range
*/
void* page_alloc(size_t sz, uint32_t flags);
/** @brief Kernel's more general release function.
*
* This function is the complement of page_allocation.
*
* @param addr Pointer to the memory range
* @param sz Desired size of the new memory
*/
void page_free(void* addr, size_t sz);
/** @brief String to long
*
* @return Long value of the parsed numerical string

View file

@ -152,6 +152,60 @@ out_err:
return -ENOMEM;
}
void* page_alloc(size_t sz, uint32_t flags)
{
size_t viraddr = 0;
size_t phyaddr;
uint32_t npages = PAGE_FLOOR(sz) >> PAGE_BITS;
size_t pflags = PG_PRESENT|PG_GLOBAL|PG_XD;
if (BUILTIN_EXPECT(!npages, 0))
goto oom;
viraddr = vma_alloc(PAGE_FLOOR(sz), flags);
if (BUILTIN_EXPECT(!viraddr, 0))
goto oom;
phyaddr = get_pages(npages);
if (BUILTIN_EXPECT(!phyaddr, 0))
{
vma_free(viraddr, viraddr+npages*PAGE_SIZE);
viraddr = 0;
goto oom;
}
if (flags & VMA_WRITE)
pflags |= PG_RW;
if (!(flags & VMA_CACHEABLE))
pflags |= PG_PCD;
int ret = page_map(viraddr, phyaddr, npages, pflags);
if (BUILTIN_EXPECT(ret, 0))
{
vma_free(viraddr, viraddr+npages*PAGE_SIZE);
put_pages(phyaddr, npages);
viraddr = 0;
}
oom:
return (void*) viraddr;
}
void page_free(void* viraddr, size_t sz)
{
size_t phyaddr;
if (BUILTIN_EXPECT(!viraddr || !sz, 0))
return;
phyaddr = virt_to_phys((size_t)viraddr);
vma_free((size_t) viraddr, (size_t) viraddr + PAGE_FLOOR(sz));
if (phyaddr)
put_pages(phyaddr, PAGE_FLOOR(sz) >> PAGE_BITS);
}
int memory_init(void)
{
size_t addr, image_size = (size_t) &kernel_end - (size_t) &kernel_start;