/*
* \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__PLATFORM_SESSION__CONNECTION_H_
#define _INCLUDE__PLATFORM_SESSION__CONNECTION_H_
#include
#include
#include
#include
#include
#include
namespace Platform {
struct Device;
struct Dma_buffer;
struct Connection;
}
class Platform::Connection : public Genode::Connection,
public Client
{
private:
/* 'Device' and 'Dma_buffer' access the '_rm' member */
friend class Device;
friend class Dma_buffer;
Region_map &_rm;
Rom_session_client _rom {devices_rom()};
Constructible _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(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); }
Capability acquire_device(Device_name const &name) override
{
return retry_with_upgrade(Ram_quota{6*1024}, Cap_quota{6}, [&] () {
return Client::acquire_device(name); });
}
Capability acquire_device()
{
return retry_with_upgrade(Ram_quota{6*1024}, Cap_quota{6}, [&] () {
return Client::acquire_single_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
void with_xml(FN const & fn)
{
try {
if (_ds.constructed() && _ds->local_addr()) {
Xml_node xml(_ds->local_addr(), _ds->size());
fn(xml);
}
} catch (Xml_node::Invalid_syntax) {
warning("Devices rom has invalid XML syntax"); }
}
Capability device_by_type(char const * type)
{
using String = Genode::String<64>;
Capability cap;
with_xml([&] (Xml_node & xml) {
xml.for_each_sub_node("device", [&] (Xml_node node) {
/* already found a device? */
if (cap.valid())
return;
if (node.attribute_value("type", String()) != type)
return;
Device_name name = node.attribute_value("name", Device_name());
cap = acquire_device(name);
});
if (!cap.valid()) {
error(__func__, ": type=", type, " not found!");
error("device ROM content: ", xml);
}
});
return cap;
}
};
#endif /* _INCLUDE__PLATFORM_SESSION__CONNECTION_H_ */