1.1 --- a/libmem/include/mem/flexpage.h Tue Feb 27 17:20:22 2024 +0100
1.2 +++ b/libmem/include/mem/flexpage.h Wed Feb 28 17:46:20 2024 +0100
1.3 @@ -68,6 +68,10 @@
1.4 offset_t base_addr, size;
1.5 offset_t base_offset;
1.6
1.7 + /* Physical address characteristics. */
1.8 +
1.9 + l4re_dma_space_dma_addr_t base_addr_physical;
1.10 +
1.11 /* Transient debugging information. */
1.12
1.13 offset_t page_addr, page_offset;
2.1 --- a/libmem/include/mem/memory_incremental.h Tue Feb 27 17:20:22 2024 +0100
2.2 +++ b/libmem/include/mem/memory_incremental.h Wed Feb 28 17:46:20 2024 +0100
2.3 @@ -1,7 +1,7 @@
2.4 /*
2.5 * A memory pool allocating a region at a time from the system.
2.6 *
2.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
2.8 + * Copyright (C) 2021, 2022, 2024 Paul Boddie <paul@boddie.org.uk>
2.9 *
2.10 * This program is free software; you can redistribute it and/or
2.11 * modify it under the terms of the GNU General Public License as
2.12 @@ -39,6 +39,7 @@
2.13
2.14 unsigned int _limit;
2.15 offset_t _region_size;
2.16 + l4_cap_idx_t _dma;
2.17 bool _limited;
2.18
2.19 Region *allocate(offset_t size);
2.20 @@ -46,9 +47,11 @@
2.21 void deallocate(Region *region);
2.22
2.23 public:
2.24 - explicit MemoryIncremental(unsigned int limit, offset_t region_size=PAGE_SIZE);
2.25 + explicit MemoryIncremental(unsigned int limit,
2.26 + offset_t region_size=PAGE_SIZE,
2.27 + l4_cap_idx_t dma=L4_INVALID_CAP);
2.28
2.29 - explicit MemoryIncremental();
2.30 + explicit MemoryIncremental(l4_cap_idx_t dma=L4_INVALID_CAP);
2.31
2.32 virtual Region *region(offset_t size);
2.33
3.1 --- a/libmem/include/mem/region.h Tue Feb 27 17:20:22 2024 +0100
3.2 +++ b/libmem/include/mem/region.h Wed Feb 28 17:46:20 2024 +0100
3.3 @@ -1,7 +1,7 @@
3.4 /*
3.5 * Memory region abstractions.
3.6 *
3.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
3.8 + * Copyright (C) 2021, 2022, 2024 Paul Boddie <paul@boddie.org.uk>
3.9 *
3.10 * This program is free software; you can redistribute it and/or
3.11 * modify it under the terms of the GNU General Public License as
3.12 @@ -21,6 +21,7 @@
3.13
3.14 #pragma once
3.15
3.16 +#include <l4/re/c/dma_space.h>
3.17 #include <systypes/base.h>
3.18
3.19 #include "types.h"
3.20 @@ -50,6 +51,7 @@
3.21 {
3.22 public:
3.23 offset_t start, end;
3.24 + l4re_dma_space_dma_addr_t physical_start;
3.25
3.26 /* Debugging information. */
3.27
3.28 @@ -57,7 +59,8 @@
3.29
3.30 /* Methods. */
3.31
3.32 - explicit Region(offset_t start, offset_t end);
3.33 + explicit Region(offset_t start, offset_t end,
3.34 + l4re_dma_space_dma_addr_t physical_start = 0);
3.35
3.36 offset_t size();
3.37
4.1 --- a/libmem/lib/src/flexpage.cc Tue Feb 27 17:20:22 2024 +0100
4.2 +++ b/libmem/lib/src/flexpage.cc Wed Feb 28 17:46:20 2024 +0100
4.3 @@ -1,7 +1,7 @@
4.4 /*
4.5 * A flexpage abstraction.
4.6 *
4.7 - * Copyright (C) 2021, 2022, 2023 Paul Boddie <paul@boddie.org.uk>
4.8 + * Copyright (C) 2021, 2022, 2023, 2024 Paul Boddie <paul@boddie.org.uk>
4.9 *
4.10 * This program is free software; you can redistribute it and/or
4.11 * modify it under the terms of the GNU General Public License as
4.12 @@ -70,6 +70,15 @@
4.13
4.14 page_offset = trunc(offset - base_offset, PAGE_SIZE);
4.15 page_addr = base_addr + page_offset;
4.16 +
4.17 + /* Where a physical address is available, also provide the base address in
4.18 + physical address space. Note that a physical address of zero is not
4.19 + considered as indicating such an address. */
4.20 +
4.21 + if (region->physical_start)
4.22 + base_addr_physical = region->physical_start + (base_addr - region->start);
4.23 + else
4.24 + base_addr_physical = 0;
4.25 }
4.26
4.27 /* Set a region. */
5.1 --- a/libmem/lib/src/memory_incremental.cc Tue Feb 27 17:20:22 2024 +0100
5.2 +++ b/libmem/lib/src/memory_incremental.cc Wed Feb 28 17:46:20 2024 +0100
5.3 @@ -1,7 +1,7 @@
5.4 /*
5.5 * A memory pool allocating a region at a time from the system.
5.6 *
5.7 - * Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
5.8 + * Copyright (C) 2021, 2022, 2024 Paul Boddie <paul@boddie.org.uk>
5.9 *
5.10 * This program is free software; you can redistribute it and/or
5.11 * modify it under the terms of the GNU General Public License as
5.12 @@ -19,6 +19,8 @@
5.13 * Boston, MA 02110-1301, USA
5.14 */
5.15
5.16 +#include <l4/re/c/mem_alloc.h>
5.17 +
5.18 #include "memory_incremental.h"
5.19
5.20 #include <ipc/mem_ipc.h>
5.21 @@ -29,14 +31,15 @@
5.22
5.23 /* Initialise the memory pool with an optional 'limit' in pages. */
5.24
5.25 -MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size)
5.26 -: _limit(limit), _region_size(region_size)
5.27 +MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size,
5.28 + l4_cap_idx_t dma)
5.29 +: _limit(limit), _region_size(region_size), _dma(dma)
5.30 {
5.31 _limited = true;
5.32 }
5.33
5.34 -MemoryIncremental::MemoryIncremental()
5.35 -: _region_size(PAGE_SIZE)
5.36 +MemoryIncremental::MemoryIncremental(l4_cap_idx_t dma)
5.37 +: _region_size(PAGE_SIZE), _dma(dma)
5.38 {
5.39 _limited = false;
5.40 }
5.41 @@ -58,10 +61,39 @@
5.42 NOTE: Here, it might be beneficial to employ an allocator that obtains
5.43 dataspaces and provides multiple blocks from each dataspace. */
5.44
5.45 - if (ipc_allocate_align(size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX, page_order(size), ¤t, &ds))
5.46 + const l4_size_t attach_flags = L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX;
5.47 + const l4_size_t alloc_flags = l4_is_valid_cap(_dma) ?
5.48 + L4RE_MA_CONTINUOUS | L4RE_MA_PINNED : 0;
5.49 +
5.50 + long err = ipc_new_dataspace(size, alloc_flags, page_order(size), &ds);
5.51 +
5.52 + if (err)
5.53 + return NULL;
5.54 +
5.55 + err = ipc_attach_dataspace_align(ds, size, attach_flags, page_order(size),
5.56 + (void **) ¤t);
5.57 +
5.58 + if (err)
5.59 return NULL;
5.60
5.61 - return new Region((offset_t) current, (offset_t) current + size);
5.62 + /* Obtain physical addresses if a DMA space capability is available. */
5.63 +
5.64 + l4re_dma_space_dma_addr_t paddr = 0;
5.65 + l4_size_t size_out = size;
5.66 +
5.67 + if (l4_is_valid_cap(_dma))
5.68 + {
5.69 + long err = l4re_dma_space_map(_dma, ds | L4_CAP_FPAGE_RW, 0, &size_out,
5.70 + 0, L4RE_DMA_SPACE_BIDIRECTIONAL, &paddr);
5.71 +
5.72 + if (err)
5.73 + return NULL;
5.74 +
5.75 + if (size_out < size)
5.76 + return NULL;
5.77 + }
5.78 +
5.79 + return new Region((offset_t) current, (offset_t) current + size, paddr);
5.80 }
5.81
5.82 /* Deallocate the given region. */
6.1 --- a/libmem/lib/src/region.cc Tue Feb 27 17:20:22 2024 +0100
6.2 +++ b/libmem/lib/src/region.cc Wed Feb 28 17:46:20 2024 +0100
6.3 @@ -1,7 +1,7 @@
6.4 /*
6.5 * Memory region abstractions.
6.6 *
6.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
6.8 + * Copyright (C) 2021, 2024 Paul Boddie <paul@boddie.org.uk>
6.9 *
6.10 * This program is free software; you can redistribute it and/or
6.11 * modify it under the terms of the GNU General Public License as
6.12 @@ -50,8 +50,9 @@
6.13 /* Initialise a region having the given 'start' and 'end' addresses, with the
6.14 'end' being one location beyond the last address in the region. */
6.15
6.16 -Region::Region(offset_t start, offset_t end)
6.17 -: start(start), end(end), state(end - start)
6.18 +Region::Region(offset_t start, offset_t end,
6.19 + l4re_dma_space_dma_addr_t physical_start)
6.20 +: start(start), end(end), physical_start(physical_start), state(end - start)
6.21 {
6.22 /* Content state. */
6.23