# HG changeset patch # User Paul Boddie # Date 1709138780 -3600 # Node ID 0ed127c41a275f2517a1743f332c7a5ac288cf86 # Parent db3da45046d67a5cf476f2999bc0c1d6d5a7336b Added support for associating regions with DMA spaces. diff -r db3da45046d6 -r 0ed127c41a27 libmem/include/mem/flexpage.h --- a/libmem/include/mem/flexpage.h Tue Feb 27 17:20:22 2024 +0100 +++ b/libmem/include/mem/flexpage.h Wed Feb 28 17:46:20 2024 +0100 @@ -68,6 +68,10 @@ offset_t base_addr, size; offset_t base_offset; + /* Physical address characteristics. */ + + l4re_dma_space_dma_addr_t base_addr_physical; + /* Transient debugging information. */ offset_t page_addr, page_offset; diff -r db3da45046d6 -r 0ed127c41a27 libmem/include/mem/memory_incremental.h --- a/libmem/include/mem/memory_incremental.h Tue Feb 27 17:20:22 2024 +0100 +++ b/libmem/include/mem/memory_incremental.h Wed Feb 28 17:46:20 2024 +0100 @@ -1,7 +1,7 @@ /* * A memory pool allocating a region at a time from the system. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -39,6 +39,7 @@ unsigned int _limit; offset_t _region_size; + l4_cap_idx_t _dma; bool _limited; Region *allocate(offset_t size); @@ -46,9 +47,11 @@ void deallocate(Region *region); public: - explicit MemoryIncremental(unsigned int limit, offset_t region_size=PAGE_SIZE); + explicit MemoryIncremental(unsigned int limit, + offset_t region_size=PAGE_SIZE, + l4_cap_idx_t dma=L4_INVALID_CAP); - explicit MemoryIncremental(); + explicit MemoryIncremental(l4_cap_idx_t dma=L4_INVALID_CAP); virtual Region *region(offset_t size); diff -r db3da45046d6 -r 0ed127c41a27 libmem/include/mem/region.h --- a/libmem/include/mem/region.h Tue Feb 27 17:20:22 2024 +0100 +++ b/libmem/include/mem/region.h Wed Feb 28 17:46:20 2024 +0100 @@ -1,7 +1,7 @@ /* * Memory region abstractions. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -21,6 +21,7 @@ #pragma once +#include #include #include "types.h" @@ -50,6 +51,7 @@ { public: offset_t start, end; + l4re_dma_space_dma_addr_t physical_start; /* Debugging information. */ @@ -57,7 +59,8 @@ /* Methods. */ - explicit Region(offset_t start, offset_t end); + explicit Region(offset_t start, offset_t end, + l4re_dma_space_dma_addr_t physical_start = 0); offset_t size(); diff -r db3da45046d6 -r 0ed127c41a27 libmem/lib/src/flexpage.cc --- a/libmem/lib/src/flexpage.cc Tue Feb 27 17:20:22 2024 +0100 +++ b/libmem/lib/src/flexpage.cc Wed Feb 28 17:46:20 2024 +0100 @@ -1,7 +1,7 @@ /* * A flexpage abstraction. * - * Copyright (C) 2021, 2022, 2023 Paul Boddie + * Copyright (C) 2021, 2022, 2023, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -70,6 +70,15 @@ page_offset = trunc(offset - base_offset, PAGE_SIZE); page_addr = base_addr + page_offset; + + /* Where a physical address is available, also provide the base address in + physical address space. Note that a physical address of zero is not + considered as indicating such an address. */ + + if (region->physical_start) + base_addr_physical = region->physical_start + (base_addr - region->start); + else + base_addr_physical = 0; } /* Set a region. */ diff -r db3da45046d6 -r 0ed127c41a27 libmem/lib/src/memory_incremental.cc --- a/libmem/lib/src/memory_incremental.cc Tue Feb 27 17:20:22 2024 +0100 +++ b/libmem/lib/src/memory_incremental.cc Wed Feb 28 17:46:20 2024 +0100 @@ -1,7 +1,7 @@ /* * A memory pool allocating a region at a time from the system. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,6 +19,8 @@ * Boston, MA 02110-1301, USA */ +#include + #include "memory_incremental.h" #include @@ -29,14 +31,15 @@ /* Initialise the memory pool with an optional 'limit' in pages. */ -MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size) -: _limit(limit), _region_size(region_size) +MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size, + l4_cap_idx_t dma) +: _limit(limit), _region_size(region_size), _dma(dma) { _limited = true; } -MemoryIncremental::MemoryIncremental() -: _region_size(PAGE_SIZE) +MemoryIncremental::MemoryIncremental(l4_cap_idx_t dma) +: _region_size(PAGE_SIZE), _dma(dma) { _limited = false; } @@ -58,10 +61,39 @@ NOTE: Here, it might be beneficial to employ an allocator that obtains dataspaces and provides multiple blocks from each dataspace. */ - if (ipc_allocate_align(size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX, page_order(size), ¤t, &ds)) + const l4_size_t attach_flags = L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX; + const l4_size_t alloc_flags = l4_is_valid_cap(_dma) ? + L4RE_MA_CONTINUOUS | L4RE_MA_PINNED : 0; + + long err = ipc_new_dataspace(size, alloc_flags, page_order(size), &ds); + + if (err) + return NULL; + + err = ipc_attach_dataspace_align(ds, size, attach_flags, page_order(size), + (void **) ¤t); + + if (err) return NULL; - return new Region((offset_t) current, (offset_t) current + size); + /* Obtain physical addresses if a DMA space capability is available. */ + + l4re_dma_space_dma_addr_t paddr = 0; + l4_size_t size_out = size; + + if (l4_is_valid_cap(_dma)) + { + long err = l4re_dma_space_map(_dma, ds | L4_CAP_FPAGE_RW, 0, &size_out, + 0, L4RE_DMA_SPACE_BIDIRECTIONAL, &paddr); + + if (err) + return NULL; + + if (size_out < size) + return NULL; + } + + return new Region((offset_t) current, (offset_t) current + size, paddr); } /* Deallocate the given region. */ diff -r db3da45046d6 -r 0ed127c41a27 libmem/lib/src/region.cc --- a/libmem/lib/src/region.cc Tue Feb 27 17:20:22 2024 +0100 +++ b/libmem/lib/src/region.cc Wed Feb 28 17:46:20 2024 +0100 @@ -1,7 +1,7 @@ /* * Memory region abstractions. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -50,8 +50,9 @@ /* Initialise a region having the given 'start' and 'end' addresses, with the 'end' being one location beyond the last address in the region. */ -Region::Region(offset_t start, offset_t end) -: start(start), end(end), state(end - start) +Region::Region(offset_t start, offset_t end, + l4re_dma_space_dma_addr_t physical_start) +: start(start), end(end), physical_start(physical_start), state(end - start) { /* Content state. */