mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
90a6f55f88
The new 'Dma_buffer' utility simplifies the allocation of DMA-capable RAM by device drivers. Issue #4401
86 lines
2.0 KiB
C++
86 lines
2.0 KiB
C++
/*
|
|
* \brief Utility to allocate and locally attach a DMA buffer
|
|
* \author Norman Feske
|
|
* \date 2022-02-02
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2022 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
#ifndef _INCLUDE__PLATFORM_SESSION__DMA_BUFFER_H_
|
|
#define _INCLUDE__PLATFORM_SESSION__DMA_BUFFER_H_
|
|
|
|
/* Genode includes */
|
|
#include <base/attached_dataspace.h>
|
|
#include <platform_session/connection.h>
|
|
|
|
class Platform::Dma_buffer : Noncopyable
|
|
{
|
|
private:
|
|
|
|
struct Allocation
|
|
{
|
|
Platform::Connection &platform;
|
|
|
|
size_t const size;
|
|
Cache const cache;
|
|
|
|
Ram_dataspace_capability _alloc()
|
|
{
|
|
return platform.retry_with_upgrade(Ram_quota{4096}, Cap_quota{2},
|
|
[&] () { return platform.alloc_dma_buffer(size, cache); });
|
|
}
|
|
|
|
Ram_dataspace_capability cap = _alloc();
|
|
|
|
addr_t const dma_addr = platform.dma_addr(cap);
|
|
|
|
Allocation(Connection &platform, size_t size, Cache cache)
|
|
: platform(platform), size(size), cache(cache) { }
|
|
|
|
~Allocation() { platform.free_dma_buffer(cap); }
|
|
|
|
} _allocation;
|
|
|
|
Attached_dataspace _ds { _allocation.platform._rm, _allocation.cap };
|
|
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* \param platform platform session used for the buffer allocation
|
|
* \param size DMA buffer size in bytes
|
|
*
|
|
* \throw Out_of_ram
|
|
* \throw Out_of_caps
|
|
* \throw Region_map::Region_conflict
|
|
*/
|
|
Dma_buffer(Connection &platform, size_t size, Cache cache)
|
|
:
|
|
_allocation(platform, size, cache)
|
|
{ }
|
|
|
|
/**
|
|
* Return component-local base address
|
|
*/
|
|
template <typename T> T *local_addr() { return _ds.local_addr<T>(); }
|
|
template <typename T> T const *local_addr() const { return _ds.local_addr<T>(); }
|
|
|
|
/**
|
|
* Return bus address to be used for DMA operations
|
|
*/
|
|
addr_t dma_addr() const { return _allocation.dma_addr; }
|
|
|
|
/**
|
|
* Return DMA-buffer size in bytes
|
|
*/
|
|
size_t size() const { return _allocation.size; }
|
|
};
|
|
|
|
#endif /* _INCLUDE__PLATFORM_SESSION__DMA_BUFFER_H_ */
|