diff --git a/src/README.md b/src/README.md index f4dcfc4181..1f79fbfae6 100644 --- a/src/README.md +++ b/src/README.md @@ -339,10 +339,13 @@ can be accessed directly by network cards. The important characteristic of DMA memory is being located in contiguous physical memory at a stable address. -— Function **memory.dma_alloc** *bytes* +— Function **memory.dma_alloc** *bytes*, *[alignment]* Returns a pointer to *bytes* of new DMA memory. +Optionally a specific *alignment* requirement can be provided (in +bytes). The default alignment is 128. + — Function **memory.virtual_to_physical** *pointer* Returns the physical address (`uint64_t`) the DMA memory at *pointer*. diff --git a/src/core/memory.lua b/src/core/memory.lua index ec25748211..20f07408dd 100644 --- a/src/core/memory.lua +++ b/src/core/memory.lua @@ -23,13 +23,20 @@ chunks = {} -- Allocate DMA-friendly memory. -- Return virtual memory pointer, physical address, and actual size. -function dma_alloc (bytes) +function dma_alloc (bytes, align) + align = align or 128 assert(bytes <= huge_page_size) - bytes = lib.align(bytes, 128) - if #chunks == 0 or bytes + chunks[#chunks].used > chunks[#chunks].size then + -- Get current chunk of memory to allocate from + if #chunks == 0 then allocate_next_chunk() end + local chunk = chunks[#chunks] + -- Skip allocation forward pointer to suit alignment + chunk.used = lib.align(chunk.used, align) + -- Need a new chunk to service this allocation? + if chunk.used + bytes > chunk.size then allocate_next_chunk() + chunk = chunks[#chunks] end - local chunk = chunks[#chunks] + -- Slice out the memory we need local where = chunk.used chunk.used = chunk.used + bytes return chunk.pointer + where, chunk.physical + where, bytes