mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
de7fdd3e1a
Instead of returning an invalid device capability when a device is (not yet) available, e.g. a PCI device is requested before the PCI bus got parsed accordingly, we check the device capability within the Platform::Connection utilities, and register temporarily an Io_signal_handler to wait for changes of the devices ROM, and try the device aquisition again. Thereby, simple drivers so not have to take the burden to do so. To enable this feature for all drivers, we always have to export a devices ROM, but limit the information about physical resources (I/O memory addresses, IRQ numbers, I/O port ranges) to clients with 'info=yes' in their policy description. Fix genodelabs/genode#4496
91 lines
2.1 KiB
C++
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._env.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_ */
|