mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
platform_drv: enhance coding practice
* more constness where possible * hide device reporter functionality in Device_reporter interface
This commit is contained in:
parent
91a569ac7f
commit
19f50a9a45
@ -15,7 +15,7 @@
|
||||
|
||||
namespace Driver { class Common; };
|
||||
|
||||
class Driver::Common
|
||||
class Driver::Common : Device_reporter
|
||||
{
|
||||
private:
|
||||
|
||||
@ -24,7 +24,7 @@ class Driver::Common
|
||||
Attached_rom_dataspace _devices_rom { _env, _rom_name.string() };
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
|
||||
Device_model _devices { _heap, _dev_reporter };
|
||||
Device_model _devices { _heap, *this };
|
||||
Signal_handler<Common> _dev_handler { _env.ep(), *this,
|
||||
&Common::_handle_devices };
|
||||
Driver::Root _root;
|
||||
@ -36,14 +36,21 @@ class Driver::Common
|
||||
|
||||
public:
|
||||
|
||||
Common(Genode::Env & env,
|
||||
Attached_rom_dataspace const & config_rom);
|
||||
|
||||
Heap & heap() { return _heap; }
|
||||
Device_model & devices() { return _devices; }
|
||||
|
||||
void handle_config(Xml_node config);
|
||||
void announce_service();
|
||||
void handle_config(Xml_node config);
|
||||
|
||||
Common(Genode::Env & env,
|
||||
Attached_rom_dataspace const & config_rom);
|
||||
|
||||
/*********************
|
||||
** Device_reporter **
|
||||
*********************/
|
||||
|
||||
void update_report() override;
|
||||
};
|
||||
|
||||
|
||||
@ -51,10 +58,19 @@ void Driver::Common::_handle_devices()
|
||||
{
|
||||
_devices_rom.update();
|
||||
_devices.update(_devices_rom.xml());
|
||||
update_report();
|
||||
_root.update_policy();
|
||||
}
|
||||
|
||||
|
||||
void Driver::Common::update_report()
|
||||
{
|
||||
if (_dev_reporter.constructed())
|
||||
_dev_reporter->generate([&] (Xml_generator & xml) {
|
||||
_devices.generate(xml); });
|
||||
}
|
||||
|
||||
|
||||
void Driver::Common::handle_config(Xml_node config)
|
||||
{
|
||||
config.for_each_sub_node("report", [&] (Xml_node const node) {
|
||||
|
@ -37,7 +37,7 @@ void Driver::Device::acquire(Session_component & sc)
|
||||
_power_domain_list.for_each([&] (Power_domain & p) {
|
||||
|
||||
bool ok = false;
|
||||
sc.devices().powers().apply(p.name, [&] (Driver::Power &power) {
|
||||
_model.powers().apply(p.name, [&] (Driver::Power &power) {
|
||||
power.on();
|
||||
ok = true;
|
||||
});
|
||||
@ -49,7 +49,7 @@ void Driver::Device::acquire(Session_component & sc)
|
||||
_reset_domain_list.for_each([&] (Reset_domain & r) {
|
||||
|
||||
bool ok = false;
|
||||
sc.devices().resets().apply(r.name, [&] (Driver::Reset &reset) {
|
||||
_model.resets().apply(r.name, [&] (Driver::Reset &reset) {
|
||||
reset.deassert();
|
||||
ok = true;
|
||||
});
|
||||
@ -61,7 +61,7 @@ void Driver::Device::acquire(Session_component & sc)
|
||||
_clock_list.for_each([&] (Clock &c) {
|
||||
|
||||
bool ok = false;
|
||||
sc.devices().clocks().apply(c.name, [&] (Driver::Clock &clock) {
|
||||
_model.clocks().apply(c.name, [&] (Driver::Clock &clock) {
|
||||
|
||||
if (c.parent.valid())
|
||||
clock.parent(c.parent);
|
||||
@ -81,7 +81,7 @@ void Driver::Device::acquire(Session_component & sc)
|
||||
|
||||
pci_enable(sc.env(), sc.device_pd(), *this);
|
||||
sc.update_devices_rom();
|
||||
sc.devices().update_report();
|
||||
_model.device_status_changed();
|
||||
}
|
||||
|
||||
|
||||
@ -94,36 +94,35 @@ void Driver::Device::release(Session_component & sc)
|
||||
|
||||
_reset_domain_list.for_each([&] (Reset_domain & r)
|
||||
{
|
||||
sc.devices().resets().apply(r.name, [&] (Driver::Reset &reset) {
|
||||
_model.resets().apply(r.name, [&] (Driver::Reset &reset) {
|
||||
reset.assert(); });
|
||||
});
|
||||
|
||||
_power_domain_list.for_each([&] (Power_domain & p)
|
||||
{
|
||||
sc.devices().powers().apply(p.name, [&] (Driver::Power &power) {
|
||||
_model.powers().apply(p.name, [&] (Driver::Power &power) {
|
||||
power.off(); });
|
||||
});
|
||||
|
||||
_clock_list.for_each([&] (Clock & c)
|
||||
{
|
||||
sc.devices().clocks().apply(c.name, [&] (Driver::Clock &clock) {
|
||||
_model.clocks().apply(c.name, [&] (Driver::Clock &clock) {
|
||||
clock.disable(); });
|
||||
});
|
||||
|
||||
_owner = Owner();
|
||||
sc.update_devices_rom();
|
||||
sc.devices().update_report();
|
||||
_model.device_status_changed();
|
||||
}
|
||||
|
||||
|
||||
void Driver::Device::report(Xml_generator & xml, Device_model & devices,
|
||||
bool info)
|
||||
void Driver::Device::generate(Xml_generator & xml, bool info) const
|
||||
{
|
||||
xml.node("device", [&] () {
|
||||
xml.attribute("name", name());
|
||||
xml.attribute("type", type());
|
||||
xml.attribute("used", _owner.valid());
|
||||
_io_mem_list.for_each([&] (Io_mem & io_mem) {
|
||||
_io_mem_list.for_each([&] (Io_mem const & io_mem) {
|
||||
xml.node("io_mem", [&] () {
|
||||
if (!info)
|
||||
return;
|
||||
@ -131,14 +130,14 @@ void Driver::Device::report(Xml_generator & xml, Device_model & devices,
|
||||
xml.attribute("size", String<16>(Hex(io_mem.range.size)));
|
||||
});
|
||||
});
|
||||
_irq_list.for_each([&] (Irq & irq) {
|
||||
_irq_list.for_each([&] (Irq const & irq) {
|
||||
xml.node("irq", [&] () {
|
||||
if (!info)
|
||||
return;
|
||||
xml.attribute("number", irq.number);
|
||||
});
|
||||
});
|
||||
_io_port_range_list.for_each([&] (Io_port_range & io_port_range) {
|
||||
_io_port_range_list.for_each([&] (Io_port_range const & io_port_range) {
|
||||
xml.node("io_port_range", [&] () {
|
||||
if (!info)
|
||||
return;
|
||||
@ -146,35 +145,33 @@ void Driver::Device::report(Xml_generator & xml, Device_model & devices,
|
||||
xml.attribute("size", String<16>(Hex(io_port_range.size)));
|
||||
});
|
||||
});
|
||||
_property_list.for_each([&] (Property & p) {
|
||||
_property_list.for_each([&] (Property const & p) {
|
||||
xml.node("property", [&] () {
|
||||
xml.attribute("name", p.name);
|
||||
xml.attribute("value", p.value);
|
||||
});
|
||||
});
|
||||
_clock_list.for_each([&] (Clock &c) {
|
||||
devices.clocks().apply(c.name, [&] (Driver::Clock &clock) {
|
||||
_clock_list.for_each([&] (Clock const & c) {
|
||||
_model.clocks().apply(c.name, [&] (Driver::Clock &clock) {
|
||||
xml.node("clock", [&] () {
|
||||
xml.attribute("rate", clock.rate().value);
|
||||
xml.attribute("name", c.driver_name);
|
||||
});
|
||||
});
|
||||
});
|
||||
_pci_config_list.for_each([&] (Pci_config &pci) {
|
||||
_pci_config_list.for_each([&] (Pci_config const & pci) {
|
||||
xml.node("pci-config", [&] () {
|
||||
xml.attribute("vendor_id", String<16>(Hex(pci.vendor_id)));
|
||||
xml.attribute("device_id", String<16>(Hex(pci.device_id)));
|
||||
xml.attribute("class", String<16>(Hex(pci.class_code)));
|
||||
});
|
||||
});
|
||||
|
||||
_report_platform_specifics(xml, devices);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Driver::Device::Device(Name name, Type type)
|
||||
: _name(name), _type(type) { }
|
||||
Driver::Device::Device(Device_model & model, Name name, Type type)
|
||||
: _model(model), _name(name), _type(type) { }
|
||||
|
||||
|
||||
Driver::Device::~Device()
|
||||
@ -184,18 +181,20 @@ Driver::Device::~Device()
|
||||
}
|
||||
|
||||
|
||||
void Driver::Device_model::update_report()
|
||||
void Driver::Device_model::device_status_changed()
|
||||
{
|
||||
if (_reporter.constructed())
|
||||
_reporter->generate([&] (Xml_generator & xml) {
|
||||
for_each([&] (Device & device) {
|
||||
device.report(xml, *this, true); });
|
||||
});
|
||||
_reporter.update_report();
|
||||
};
|
||||
|
||||
|
||||
void Driver::Device_model::generate(Xml_generator & xml) const
|
||||
{
|
||||
for_each([&] (Device const & device) {
|
||||
device.generate(xml, true); });
|
||||
}
|
||||
|
||||
|
||||
void Driver::Device_model::update(Xml_node const & node)
|
||||
{
|
||||
_model.update_from_xml(*this, node);
|
||||
update_report();
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ namespace Driver {
|
||||
using namespace Genode;
|
||||
|
||||
class Device;
|
||||
struct Device_reporter;
|
||||
struct Device_model;
|
||||
class Session_component;
|
||||
struct Irq_update_policy;
|
||||
@ -173,38 +174,38 @@ class Driver::Device : private List_model<Device>::Element
|
||||
bridge(bridge) {}
|
||||
};
|
||||
|
||||
Device(Name name, Type type);
|
||||
Device(Device_model & model, Name name, Type type);
|
||||
virtual ~Device();
|
||||
|
||||
Name name() const;
|
||||
Type type() const;
|
||||
Name name() const;
|
||||
Type type() const;
|
||||
Owner owner() const;
|
||||
|
||||
virtual void acquire(Session_component &);
|
||||
virtual void release(Session_component &);
|
||||
|
||||
template <typename FN> void for_each_irq(FN const & fn)
|
||||
template <typename FN> void for_each_irq(FN const & fn) const
|
||||
{
|
||||
unsigned idx = 0;
|
||||
_irq_list.for_each([&] (Irq const & irq) {
|
||||
fn(idx++, irq.number, irq.type, irq.polarity, irq.mode); });
|
||||
}
|
||||
|
||||
template <typename FN> void for_each_io_mem(FN const & fn)
|
||||
template <typename FN> void for_each_io_mem(FN const & fn) const
|
||||
{
|
||||
unsigned idx = 0;
|
||||
_io_mem_list.for_each([&] (Io_mem const & iomem) {
|
||||
fn(idx++, iomem.range); });
|
||||
}
|
||||
|
||||
template <typename FN> void for_each_io_port_range(FN const & fn)
|
||||
template <typename FN> void for_each_io_port_range(FN const & fn) const
|
||||
{
|
||||
unsigned idx = 0;
|
||||
_io_port_range_list.for_each([&] (Io_port_range const & ipr) {
|
||||
fn(idx++, ipr.addr, ipr.size); });
|
||||
}
|
||||
|
||||
template <typename FN> void for_pci_config(FN const & fn)
|
||||
template <typename FN> void for_pci_config(FN const & fn) const
|
||||
{
|
||||
/*
|
||||
* we allow only one PCI config per device,
|
||||
@ -221,19 +222,17 @@ class Driver::Device : private List_model<Device>::Element
|
||||
});
|
||||
}
|
||||
|
||||
void report(Xml_generator &, Device_model &, bool);
|
||||
void generate(Xml_generator &, bool) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void _report_platform_specifics(Xml_generator &,
|
||||
Device_model &) {}
|
||||
|
||||
friend class Driver::Device_model;
|
||||
friend class List_model<Device>;
|
||||
friend class List<Device>;
|
||||
|
||||
Name _name;
|
||||
Type _type;
|
||||
Device_model & _model;
|
||||
Name const _name;
|
||||
Type const _type;
|
||||
Owner _owner {};
|
||||
List_model<Io_mem> _io_mem_list {};
|
||||
List_model<Irq> _irq_list {};
|
||||
@ -252,26 +251,34 @@ class Driver::Device : private List_model<Device>::Element
|
||||
};
|
||||
|
||||
|
||||
struct Driver::Device_reporter
|
||||
{
|
||||
virtual ~Device_reporter() {}
|
||||
|
||||
virtual void update_report() = 0;
|
||||
};
|
||||
|
||||
|
||||
class Driver::Device_model :
|
||||
public List_model<Device>::Update_policy
|
||||
{
|
||||
private:
|
||||
|
||||
Heap & _heap;
|
||||
Device_reporter & _reporter;
|
||||
List_model<Device> _model { };
|
||||
Clocks _clocks { };
|
||||
Resets _resets { };
|
||||
Powers _powers { };
|
||||
|
||||
Constructible<Expanding_reporter> & _reporter;
|
||||
|
||||
public:
|
||||
|
||||
void update_report();
|
||||
void generate(Xml_generator & xml) const;
|
||||
void update(Xml_node const & node);
|
||||
void device_status_changed();
|
||||
|
||||
Device_model(Heap & heap,
|
||||
Constructible<Expanding_reporter> & reporter)
|
||||
Device_reporter & reporter)
|
||||
: _heap(heap), _reporter(reporter) { }
|
||||
|
||||
~Device_model() {
|
||||
@ -280,6 +287,9 @@ class Driver::Device_model :
|
||||
template <typename FN>
|
||||
void for_each(FN const & fn) { _model.for_each(fn); }
|
||||
|
||||
template <typename FN>
|
||||
void for_each(FN const & fn) const { _model.for_each(fn); }
|
||||
|
||||
|
||||
/***********************
|
||||
** Update_policy API **
|
||||
|
@ -66,7 +66,7 @@ Device & Device_model::create_element(Genode::Xml_node node)
|
||||
{
|
||||
Device::Name name = node.attribute_value("name", Device::Name());
|
||||
Device::Type type = node.attribute_value("type", Device::Type());
|
||||
return *(new (_heap) Device(name, type));
|
||||
return *(new (_heap) Device(*this, name, type));
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,14 +24,14 @@ using namespace Pci;
|
||||
|
||||
struct Config_helper
|
||||
{
|
||||
Driver::Device & _dev;
|
||||
Driver::Device const & _dev;
|
||||
Driver::Device::Pci_config const & _cfg;
|
||||
|
||||
Attached_io_mem_dataspace _io_mem;
|
||||
Config _config { (addr_t)_io_mem.local_addr<void>() };
|
||||
|
||||
Config_helper(Env & env,
|
||||
Driver::Device & dev,
|
||||
Driver::Device const & dev,
|
||||
Driver::Device::Pci_config const & cfg)
|
||||
: _dev(dev), _cfg(cfg), _io_mem(env, cfg.addr, 0x1000) { }
|
||||
|
||||
@ -70,21 +70,23 @@ struct Config_helper
|
||||
};
|
||||
|
||||
|
||||
void Driver::pci_enable(Env & env, Device_pd & pd, Device & dev)
|
||||
void Driver::pci_enable(Env & env, Device_pd & pd, Device const & dev)
|
||||
{
|
||||
dev.for_pci_config([&] (Device::Pci_config const & pc) {
|
||||
Config_helper(env, dev, pc).enable(pd); });
|
||||
}
|
||||
|
||||
|
||||
void Driver::pci_disable(Env & env, Device & dev)
|
||||
void Driver::pci_disable(Env & env, Device const & dev)
|
||||
{
|
||||
dev.for_pci_config([&] (Device::Pci_config const & pc) {
|
||||
Config_helper(env, dev, pc).disable(); });
|
||||
}
|
||||
|
||||
|
||||
void Driver::pci_msi_enable(Env & env, addr_t cfg_space, Irq_session::Info info)
|
||||
void Driver::pci_msi_enable(Env & env,
|
||||
addr_t cfg_space,
|
||||
Irq_session::Info const info)
|
||||
{
|
||||
Attached_io_mem_dataspace io_mem { env, cfg_space, 0x1000 };
|
||||
Config config { (addr_t)io_mem.local_addr<void>() };
|
||||
@ -140,7 +142,8 @@ pci_class_code_alias(uint32_t class_code)
|
||||
}
|
||||
|
||||
|
||||
bool Driver::pci_device_matches(Session_policy const & policy, Device & dev)
|
||||
bool Driver::pci_device_matches(Session_policy const & policy,
|
||||
Device const & dev)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@ -153,7 +156,7 @@ bool Driver::pci_device_matches(Session_policy const & policy, Device & dev)
|
||||
vendor_t vendor_id = node.attribute_value<vendor_t>("vendor_id", 0);
|
||||
device_t device_id = node.attribute_value<device_t>("device_id", 0);
|
||||
|
||||
dev.for_pci_config([&] (Device::Pci_config cfg)
|
||||
dev.for_pci_config([&] (Device::Pci_config const cfg)
|
||||
{
|
||||
if ((pci_class_code_alias(cfg.class_code) == class_code) ||
|
||||
(vendor_id == cfg.vendor_id && device_id == cfg.device_id))
|
||||
|
@ -22,12 +22,12 @@ namespace Driver {
|
||||
class Device;
|
||||
class Device_pd;
|
||||
|
||||
void pci_enable(Genode::Env & env, Device_pd & pd, Device & dev);
|
||||
void pci_disable(Genode::Env & env, Device & dev);
|
||||
void pci_enable(Genode::Env & env, Device_pd & pd, Device const & dev);
|
||||
void pci_disable(Genode::Env & env, Device const & dev);
|
||||
void pci_msi_enable(Genode::Env & env, addr_t cfg_space,
|
||||
Genode::Irq_session::Info info);
|
||||
Genode::Irq_session::Info const info);
|
||||
bool pci_device_matches(Genode::Session_policy const & policy,
|
||||
Device & dev);
|
||||
Device const & dev);
|
||||
}
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__PCI_H_ */
|
||||
|
@ -49,7 +49,7 @@ void Session_component::_free_dma_buffer(Dma_buffer & buf)
|
||||
}
|
||||
|
||||
|
||||
bool Session_component::matches(Device & dev) const
|
||||
bool Session_component::matches(Device const & dev) const
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@ -80,7 +80,7 @@ void Session_component::update_policy(bool info, Policy_version version)
|
||||
|
||||
_device_registry.for_each([&] (Device_component & dc) {
|
||||
Device_state state = AWAY;
|
||||
_devices.for_each([&] (Device & dev) {
|
||||
_devices.for_each([&] (Device const & dev) {
|
||||
if (dev.name() != dc.device())
|
||||
return;
|
||||
state = (dev.owner() == _owner_id) ? UNCHANGED : CHANGED;
|
||||
@ -107,17 +107,14 @@ void Session_component::produce_xml(Xml_generator &xml)
|
||||
if (_version.valid())
|
||||
xml.attribute("version", _version);
|
||||
|
||||
_devices.for_each([&] (Device & dev) {
|
||||
if (matches(dev)) dev.report(xml, _devices, _info); });
|
||||
_devices.for_each([&] (Device const & dev) {
|
||||
if (matches(dev)) dev.generate(xml, _info); });
|
||||
}
|
||||
|
||||
|
||||
Genode::Env & Session_component::env() { return _env; }
|
||||
|
||||
|
||||
Driver::Device_model & Session_component::devices() { return _devices; }
|
||||
|
||||
|
||||
Genode::Heap & Session_component::heap() { return _md_alloc; }
|
||||
|
||||
|
||||
@ -217,7 +214,7 @@ Genode::addr_t Session_component::dma_addr(Ram_dataspace_capability ram_cap)
|
||||
if (!ram_cap.valid())
|
||||
return ret;
|
||||
|
||||
_buffer_registry.for_each([&] (Dma_buffer & buf) {
|
||||
_buffer_registry.for_each([&] (Dma_buffer const & buf) {
|
||||
if (buf.cap.local_name() == ram_cap.local_name())
|
||||
ret = _env.pd().dma_addr(buf.cap); });
|
||||
|
||||
|
@ -56,12 +56,11 @@ class Driver::Session_component
|
||||
|
||||
~Session_component();
|
||||
|
||||
Env & env();
|
||||
Heap & heap();
|
||||
Device_model & devices();
|
||||
Device_pd & device_pd();
|
||||
Env & env();
|
||||
Heap & heap();
|
||||
Device_pd & device_pd();
|
||||
|
||||
bool matches(Device &) const;
|
||||
bool matches(Device const &) const;
|
||||
void update_devices_rom();
|
||||
|
||||
Ram_quota_guard & ram_quota_guard() { return _ram_quota_guard(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user