genode/repos/os/include/platform_session/dma_buffer.h
2022-03-09 10:55:16 +01:00

91 lines
2.1 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; }
/**
* Return DMA-buffer as dataspace capability
*/
Dataspace_capability cap() { return _ds.cap(); }
};
#endif /* _INCLUDE__PLATFORM_SESSION__DMA_BUFFER_H_ */