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:
parent
7b1dd26d42
commit
e8a61a299b
2 changed files with 75 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue