mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
This patch extends the 'Platform_session::alloc_dma_buffer' interface with a 'Cache' argument that corresponds to the argument accepted by 'Ram_allocator::alloc', which is used by the platform driver under the hood. Since the x86 platform driver used to be hardwired to allocate DMA buffers as UNCACHED, I adjusted all drivers by specifying the UNCACHED argument. Right now, this is needed as a hint for core to steer the allocation of I/O page tables. Once we eliminate the need for such hints (by introducing an explicit 'Region_map::attach_dma' operation), we can revisit the drivers individually because cached DMA buffers should generally be fine on the x86 architecture. Issue #2243
142 lines
3.8 KiB
C++
142 lines
3.8 KiB
C++
/*
|
|
* \brief Connection to Platform service
|
|
* \author Stefan Kalkowski
|
|
* \date 2020-05-13
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2020 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__SPEC__ARM__PLATFORM_SESSION__CONNECTION_H_
|
|
#define _INCLUDE__SPEC__ARM__PLATFORM_SESSION__CONNECTION_H_
|
|
|
|
#include <base/attached_dataspace.h>
|
|
#include <base/connection.h>
|
|
#include <base/env.h>
|
|
#include <platform_session/client.h>
|
|
#include <rom_session/client.h>
|
|
#include <util/xml_node.h>
|
|
|
|
namespace Platform { struct Connection; }
|
|
|
|
|
|
class Platform::Connection : public Genode::Connection<Session>,
|
|
public Client
|
|
{
|
|
private:
|
|
|
|
Region_map & _rm;
|
|
Rom_session_client _rom {devices_rom()};
|
|
Constructible<Attached_dataspace> _ds {};
|
|
|
|
void _try_attach()
|
|
{
|
|
_ds.destruct();
|
|
try { _ds.construct(_rm, _rom.dataspace()); }
|
|
catch (Attached_dataspace::Invalid_dataspace) {
|
|
warning("Invalid devices rom dataspace returned!");}
|
|
}
|
|
|
|
public:
|
|
|
|
Connection(Env &env)
|
|
: Genode::Connection<Session>(env, session(env.parent(),
|
|
"ram_quota=%u, cap_quota=%u",
|
|
RAM_QUOTA, CAP_QUOTA)),
|
|
Client(cap()),
|
|
_rm(env.rm()) { _try_attach(); }
|
|
|
|
void update()
|
|
{
|
|
if (_ds.constructed() && _rom.update() == true) { return; }
|
|
_try_attach();
|
|
}
|
|
|
|
void sigh(Signal_context_capability sigh) { _rom.sigh(sigh); }
|
|
|
|
Device_capability acquire_device(String const &device) override
|
|
{
|
|
return retry_with_upgrade(Ram_quota{6*1024}, Cap_quota{6}, [&] () {
|
|
return Client::acquire_device(device); });
|
|
}
|
|
|
|
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override
|
|
{
|
|
return retry_with_upgrade(Ram_quota{size}, Cap_quota{2}, [&] () {
|
|
return Client::alloc_dma_buffer(size, cache); });
|
|
}
|
|
|
|
template <typename FN>
|
|
void with_xml(FN const & fn)
|
|
{
|
|
try {
|
|
if (_ds.constructed() && _ds->local_addr<void const>()) {
|
|
Xml_node xml(_ds->local_addr<char>(), _ds->size());
|
|
fn(xml);
|
|
}
|
|
} catch (Xml_node::Invalid_syntax) {
|
|
warning("Devices rom has invalid XML syntax"); }
|
|
}
|
|
|
|
Device_capability device_by_index(unsigned idx)
|
|
{
|
|
Device_capability cap;
|
|
|
|
with_xml([&] (Xml_node & xml) {
|
|
try {
|
|
Xml_node node = xml.sub_node(idx);
|
|
Device::Name name = node.attribute_value("name",
|
|
Device::Name());
|
|
cap = acquire_device(name.string());
|
|
} catch(Xml_node::Nonexistent_sub_node) {
|
|
error(__func__, ": invalid device index ", idx);
|
|
error("device ROM content: ", xml);
|
|
}
|
|
});
|
|
|
|
return cap;
|
|
}
|
|
|
|
Device_capability device_by_property(char const * property,
|
|
char const * value)
|
|
{
|
|
using String = Genode::String<64>;
|
|
|
|
Device_capability cap;
|
|
|
|
with_xml([&] (Xml_node & xml) {
|
|
xml.for_each_sub_node("device", [&] (Xml_node node) {
|
|
/* already found a device? */
|
|
if (cap.valid()) { return; }
|
|
|
|
bool found = false;
|
|
node.for_each_sub_node("property", [&] (Xml_node node) {
|
|
if ((node.attribute_value("name", String()) == property) &&
|
|
(node.attribute_value("value", String()) == value)) {
|
|
found = true;
|
|
}
|
|
});
|
|
|
|
if (found) {
|
|
Device::Name name = node.attribute_value("name",
|
|
Device::Name());
|
|
cap = acquire_device(name.string());
|
|
}
|
|
});
|
|
if (!cap.valid()) {
|
|
error(__func__, ": property=", property, " value=",
|
|
value, " not found!");
|
|
error("device ROM content: ", xml);
|
|
}
|
|
});
|
|
|
|
return cap;
|
|
}
|
|
};
|
|
|
|
#endif /* _INCLUDE__SPEC__ARM__PLATFORM_SESSION__CONNECTION_H_ */
|