1.1 --- a/libmem/lib/src/memory_incremental.cc Tue Feb 27 17:20:22 2024 +0100
1.2 +++ b/libmem/lib/src/memory_incremental.cc Wed Feb 28 17:46:20 2024 +0100
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * A memory pool allocating a region at a time from the system.
1.6 *
1.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) 2021, 2022, 2024 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License as
1.12 @@ -19,6 +19,8 @@
1.13 * Boston, MA 02110-1301, USA
1.14 */
1.15
1.16 +#include <l4/re/c/mem_alloc.h>
1.17 +
1.18 #include "memory_incremental.h"
1.19
1.20 #include <ipc/mem_ipc.h>
1.21 @@ -29,14 +31,15 @@
1.22
1.23 /* Initialise the memory pool with an optional 'limit' in pages. */
1.24
1.25 -MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size)
1.26 -: _limit(limit), _region_size(region_size)
1.27 +MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size,
1.28 + l4_cap_idx_t dma)
1.29 +: _limit(limit), _region_size(region_size), _dma(dma)
1.30 {
1.31 _limited = true;
1.32 }
1.33
1.34 -MemoryIncremental::MemoryIncremental()
1.35 -: _region_size(PAGE_SIZE)
1.36 +MemoryIncremental::MemoryIncremental(l4_cap_idx_t dma)
1.37 +: _region_size(PAGE_SIZE), _dma(dma)
1.38 {
1.39 _limited = false;
1.40 }
1.41 @@ -58,10 +61,39 @@
1.42 NOTE: Here, it might be beneficial to employ an allocator that obtains
1.43 dataspaces and provides multiple blocks from each dataspace. */
1.44
1.45 - if (ipc_allocate_align(size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX, page_order(size), ¤t, &ds))
1.46 + const l4_size_t attach_flags = L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX;
1.47 + const l4_size_t alloc_flags = l4_is_valid_cap(_dma) ?
1.48 + L4RE_MA_CONTINUOUS | L4RE_MA_PINNED : 0;
1.49 +
1.50 + long err = ipc_new_dataspace(size, alloc_flags, page_order(size), &ds);
1.51 +
1.52 + if (err)
1.53 + return NULL;
1.54 +
1.55 + err = ipc_attach_dataspace_align(ds, size, attach_flags, page_order(size),
1.56 + (void **) ¤t);
1.57 +
1.58 + if (err)
1.59 return NULL;
1.60
1.61 - return new Region((offset_t) current, (offset_t) current + size);
1.62 + /* Obtain physical addresses if a DMA space capability is available. */
1.63 +
1.64 + l4re_dma_space_dma_addr_t paddr = 0;
1.65 + l4_size_t size_out = size;
1.66 +
1.67 + if (l4_is_valid_cap(_dma))
1.68 + {
1.69 + long err = l4re_dma_space_map(_dma, ds | L4_CAP_FPAGE_RW, 0, &size_out,
1.70 + 0, L4RE_DMA_SPACE_BIDIRECTIONAL, &paddr);
1.71 +
1.72 + if (err)
1.73 + return NULL;
1.74 +
1.75 + if (size_out < size)
1.76 + return NULL;
1.77 + }
1.78 +
1.79 + return new Region((offset_t) current, (offset_t) current + size, paddr);
1.80 }
1.81
1.82 /* Deallocate the given region. */