drivers/platform: use modern list-model interface

Issue #4317
This commit is contained in:
Norman Feske 2023-10-26 15:25:26 +02:00 committed by Christian Helmuth
parent 1895931918
commit df71cecc66
4 changed files with 370 additions and 533 deletions

View File

@ -184,6 +184,222 @@ void Driver::Device::generate(Xml_generator & xml, bool info) const
}
void Driver::Device::update(Allocator &alloc, Xml_node const &node)
{
using Bar = Device::Pci_bar;
update_list_model_from_xml(_irq_list, node,
/* create */
[&] (Xml_node const &node) -> Irq &
{
unsigned number = node.attribute_value<unsigned>("number", 0);
Irq &irq = *(new (alloc) Irq(number));
String<16> polarity = node.attribute_value("polarity", String<16>());
String<16> mode = node.attribute_value("mode", String<16>());
String<16> type = node.attribute_value("type", String<16>());
if (polarity.valid())
irq.polarity = (polarity == "high") ? Irq_session::POLARITY_HIGH
: Irq_session::POLARITY_LOW;
if (mode.valid())
irq.mode = (mode == "edge") ? Irq_session::TRIGGER_EDGE
: Irq_session::TRIGGER_LEVEL;
if (type.valid())
irq.type = (type == "msi-x") ? Irq::MSIX : Irq::MSI;
return irq;
},
/* destroy */
[&] (Irq &irq) { destroy(alloc, &irq); },
/* update */
[&] (Irq &, Xml_node const &) { }
);
update_list_model_from_xml(_io_mem_list, node,
/* create */
[&] (Xml_node const &node) -> Io_mem &
{
using Range = Io_mem::Range;
Bar bar { node.attribute_value<uint8_t>("pci_bar", Bar::INVALID) };
Range range { node.attribute_value<addr_t>("address", 0),
node.attribute_value<size_t>("size", 0) };
bool pf { node.attribute_value("prefetchable", false) };
return *new (alloc) Io_mem(bar, range, pf);
},
/* destroy */
[&] (Io_mem &io_mem) { destroy(alloc, &io_mem); },
/* update */
[&] (Io_mem &, Xml_node const &) { }
);
update_list_model_from_xml(_io_port_range_list, node,
/* create */
[&] (Xml_node const &node) -> Io_port_range &
{
using Range = Io_port_range::Range;
Bar bar { node.attribute_value<uint8_t>("pci_bar", Bar::INVALID) };
Range range { node.attribute_value<uint16_t>("address", 0),
node.attribute_value<uint16_t>("size", 0) };
return *new (alloc) Io_port_range(bar, range);
},
/* destroy */
[&] (Io_port_range &ipr) { destroy(alloc, &ipr); },
/* update */
[&] (Io_port_range &, Xml_node const &) { }
);
update_list_model_from_xml(_property_list, node,
/* create */
[&] (Xml_node const &node) -> Property &
{
return *new (alloc)
Property(node.attribute_value("name", Property::Name()),
node.attribute_value("value", Property::Value()));
},
/* destroy */
[&] (Property &property) { destroy(alloc, &property); },
/* update */
[&] (Property &, Xml_node const &) { }
);
update_list_model_from_xml(_clock_list, node,
/* create */
[&] (Xml_node const &node) -> Clock &
{
return *new (alloc)
Clock(node.attribute_value("name", Clock::Name()),
node.attribute_value("parent", Clock::Name()),
node.attribute_value("driver_name", Clock::Name()),
node.attribute_value("rate", 0UL));
},
/* destroy */
[&] (Clock &clock) { destroy(alloc, &clock); },
/* update */
[&] (Clock &, Xml_node const &) { }
);
update_list_model_from_xml(_power_domain_list, node,
/* create */
[&] (Xml_node const &node) -> Power_domain &
{
return *new (alloc)
Power_domain(node.attribute_value("name", Power_domain::Name()));
},
/* destroy */
[&] (Power_domain &power) { destroy(alloc, &power); },
/* update */
[&] (Power_domain &, Xml_node const &) { }
);
update_list_model_from_xml(_reset_domain_list, node,
/* create */
[&] (Xml_node const &node) -> Reset_domain &
{
return *new (alloc)
Reset_domain(node.attribute_value("name", Reset_domain::Name()));
},
/* destroy */
[&] (Reset_domain &reset) { destroy(alloc, &reset); },
/* update */
[&] (Reset_domain &, Xml_node const &) { }
);
update_list_model_from_xml(_pci_config_list, node,
/* create */
[&] (Xml_node const &node) -> Pci_config &
{
using namespace Pci;
addr_t addr = node.attribute_value("address", ~0UL);
bus_t bus_num = node.attribute_value<bus_t>("bus", 0);
dev_t dev_num = node.attribute_value<dev_t>("device", 0);
func_t func_num = node.attribute_value<func_t>("function", 0);
vendor_t vendor_id = node.attribute_value<vendor_t>("vendor_id",
0xffff);
device_t device_id = node.attribute_value<device_t>("device_id",
0xffff);
class_t class_code = node.attribute_value<class_t>("class", 0xff);
rev_t rev = node.attribute_value<rev_t>("revision", 0xff);
vendor_t sub_v_id = node.attribute_value<vendor_t>("sub_vendor_id",
0xffff);
device_t sub_d_id = node.attribute_value<device_t>("sub_device_id",
0xffff);
bool bridge = node.attribute_value("bridge", false);
return *(new (alloc) Pci_config(addr, bus_num, dev_num, func_num,
vendor_id, device_id, class_code,
rev, sub_v_id, sub_d_id, bridge));
},
/* destroy */
[&] (Pci_config &pci) { destroy(alloc, &pci); },
/* update */
[&] (Pci_config &, Xml_node const &) { }
);
update_list_model_from_xml(_reserved_mem_list, node,
/* create */
[&] (Xml_node const &node) -> Reserved_memory &
{
addr_t addr = node.attribute_value("address", 0UL);
size_t size = node.attribute_value("size", 0UL);
return *(new (alloc) Reserved_memory({addr, size}));
},
/* destroy */
[&] (Reserved_memory &reserved) { destroy(alloc, &reserved); },
/* update */
[&] (Reserved_memory &, Xml_node const &) { }
);
update_list_model_from_xml(_io_mmu_list, node,
/* create */
[&] (Xml_node const &node) -> Io_mmu &
{
return *new (alloc)
Io_mmu(node.attribute_value("name", Io_mmu::Name()));
},
/* destroy */
[&] (Io_mmu &io_mmu) { destroy(alloc, &io_mmu); },
/* update */
[&] (Io_mmu &, Xml_node const &) { }
);
}
Driver::Device::Device(Env & env, Device_model & model, Name name, Type type,
bool leave_operational)
:
@ -213,7 +429,31 @@ void Driver::Device_model::generate(Xml_generator & xml) const
void Driver::Device_model::update(Xml_node const & node)
{
_model.update_from_xml(*this, node);
update_list_model_from_xml(_model, node,
/* create */
[&] (Xml_node const &node) -> Device &
{
Device::Name name = node.attribute_value("name", Device::Name());
Device::Type type = node.attribute_value("type", Device::Type());
bool leave_operational = node.attribute_value("leave_operational", false);
return *(new (_heap) Device(_env, *this, name, type, leave_operational));
},
/* destroy */
[&] (Device &device)
{
device.update(_heap, Xml_node("<empty/>"));
device.release(_owner);
destroy(_heap, &device);
},
/* update */
[&] (Device &device, Xml_node const &node)
{
device.update(_heap, node);
}
);
/*
* Detect all shared interrupts

View File

@ -38,16 +38,6 @@ namespace Driver {
struct Device_reporter;
struct Device_model;
struct Device_owner;
struct Irq_update_policy;
struct Io_mem_update_policy;
struct Io_port_update_policy;
struct Property_update_policy;
struct Clock_update_policy;
struct Reset_domain_update_policy;
struct Power_domain_update_policy;
struct Pci_config_update_policy;
struct Reserved_memory_update_policy;
struct Io_mmu_update_policy;
}
@ -91,6 +81,18 @@ class Driver::Device : private List_model<Device>::Element
Io_mem(Pci_bar bar, Range range, bool pf)
: bar(bar), range(range), prefetchable(pf) {}
bool matches(Xml_node const &node) const
{
Range r { node.attribute_value<Genode::addr_t>("address", 0),
node.attribute_value<Genode::size_t>("size", 0) };
return (r.start == range.start) && (r.size == range.size);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("io_mem");
}
};
struct Irq : List_model<Irq>::Element
@ -104,6 +106,16 @@ class Driver::Device : private List_model<Device>::Element
bool shared { false };
Irq(unsigned number) : number(number) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value<unsigned>("number", 0u) == number);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("irq");
}
};
struct Io_port_range : List_model<Io_port_range>::Element
@ -115,6 +127,17 @@ class Driver::Device : private List_model<Device>::Element
Io_port_range(Pci_bar bar, Range range)
: bar(bar), range(range) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value<uint16_t>("address", 0) == range.addr)
&& (node.attribute_value<uint16_t>("size", 0) == range.size);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("io_port_range");
}
};
struct Property : List_model<Property>::Element
@ -127,6 +150,17 @@ class Driver::Device : private List_model<Device>::Element
Property(Name name, Value value)
: name(name), value(value) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value("name", Name()) == name)
&& (node.attribute_value("value", Value()) == value);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("property");
}
};
struct Clock : List_model<Clock>::Element
@ -144,6 +178,17 @@ class Driver::Device : private List_model<Device>::Element
unsigned long rate)
: name(name), parent(parent),
driver_name(driver_name), rate(rate) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value("name", Name()) == name)
&& (node.attribute_value("driver_name", Name()) == driver_name);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("clock");
}
};
struct Power_domain : List_model<Power_domain>::Element
@ -153,6 +198,16 @@ class Driver::Device : private List_model<Device>::Element
Name name;
Power_domain(Name name) : name(name) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value("name", Name()) == name);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("power-domain");
}
};
struct Reset_domain : List_model<Reset_domain>::Element
@ -162,6 +217,16 @@ class Driver::Device : private List_model<Device>::Element
Name name;
Reset_domain(Name name) : name(name) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value("name", Name()) == name);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("reset-domain");
}
};
struct Pci_config : List_model<Pci_config>::Element
@ -200,7 +265,18 @@ class Driver::Device : private List_model<Device>::Element
revision(revision),
sub_vendor_id(sub_vendor_id),
sub_device_id(sub_device_id),
bridge(bridge) {}
bridge(bridge)
{ }
bool matches(Xml_node const &node) const
{
return (node.attribute_value("address", ~0UL) == addr);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("pci-config");
}
};
struct Reserved_memory : List_model<Reserved_memory>::Element
@ -210,6 +286,17 @@ class Driver::Device : private List_model<Device>::Element
Range range;
Reserved_memory(Range range) : range(range) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value("address", 0UL) == range.start)
&& (node.attribute_value("size", 0UL) == range.size);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("reserved_memory");
}
};
struct Io_mmu : List_model<Io_mmu>::Element
@ -219,6 +306,16 @@ class Driver::Device : private List_model<Device>::Element
Name name;
Io_mmu(Name name) : name(name) {}
bool matches(Xml_node const &node) const
{
return (node.attribute_value("name", Name()) == name);
}
static bool type_matches(Xml_node const &node)
{
return node.has_type("io_mmu");
}
};
Device(Env & env, Device_model & model, Name name, Type type,
@ -294,6 +391,25 @@ class Driver::Device : private List_model<Device>::Element
void generate(Xml_generator &, bool) const;
void update(Allocator &, Xml_node const &);
/**
* List_model::Element
*/
bool matches(Xml_node const &node) const
{
return name() == node.attribute_value("name", Device::Name()) &&
type() == node.attribute_value("type", Device::Type());
}
/**
* List_model::Element
*/
static bool type_matches(Xml_node const &node)
{
return node.has_type("device");
}
protected:
friend class Driver::Device_model;
@ -333,8 +449,7 @@ struct Driver::Device_reporter
};
class Driver::Device_model :
public List_model<Device>::Update_policy
class Driver::Device_model
{
private:
@ -360,8 +475,7 @@ class Driver::Device_model :
Device_owner & owner)
: _env(env), _heap(heap), _reporter(reporter), _owner(owner) { }
~Device_model() {
_model.destroy_all_elements(*this); }
~Device_model() { update(Xml_node("<empty/>")); }
template <typename FN>
void for_each(FN const & fn) { _model.for_each(fn); }
@ -376,388 +490,9 @@ class Driver::Device_model :
if (sirq.number() == number) fn(sirq); });
}
/***********************
** Update_policy API **
***********************/
void destroy_element(Device & device);
Device & create_element(Xml_node node);
void update_element(Device & device, Xml_node node);
static bool element_matches_xml_node(Device const & dev,
Genode::Xml_node n)
{
return dev.name() == n.attribute_value("name", Device::Name()) &&
dev.type() == n.attribute_value("type", Device::Type());
}
static bool node_is_element(Genode::Xml_node node) {
return node.has_type("device"); }
Clocks & clocks() { return _clocks; };
Resets & resets() { return _resets; };
Powers & powers() { return _powers; };
};
struct Driver::Irq_update_policy : Genode::List_model<Device::Irq>::Update_policy
{
Genode::Allocator & alloc;
Irq_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & irq) {
Genode::destroy(alloc, &irq); }
Element & create_element(Genode::Xml_node node)
{
unsigned number = node.attribute_value<unsigned>("number", 0);
Element & elem = *(new (alloc) Element(number));
String<16> polarity = node.attribute_value("polarity", String<16>());
String<16> mode = node.attribute_value("mode", String<16>());
String<16> type = node.attribute_value("type", String<16>());
if (polarity.valid())
elem.polarity = (polarity == "high") ? Irq_session::POLARITY_HIGH
: Irq_session::POLARITY_LOW;
if (mode.valid())
elem.mode = (mode == "edge") ? Irq_session::TRIGGER_EDGE
: Irq_session::TRIGGER_LEVEL;
if (type.valid())
elem.type = (type == "msi-x") ? Element::MSIX : Element::MSI;
return elem;
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & irq, Genode::Xml_node node)
{
unsigned number = node.attribute_value<unsigned>("number", 0);
return number == irq.number;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("irq");
}
};
struct Driver::Io_mem_update_policy : Genode::List_model<Device::Io_mem>::Update_policy
{
using Range = Device::Io_mem::Range;
using Bar = Device::Pci_bar;
Genode::Allocator & alloc;
Io_mem_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & iomem) {
Genode::destroy(alloc, &iomem); }
Element & create_element(Genode::Xml_node node)
{
Bar bar { node.attribute_value<uint8_t>("pci_bar", Bar::INVALID) };
Range range { node.attribute_value<Genode::addr_t>("address", 0),
node.attribute_value<Genode::size_t>("size", 0) };
bool pf { node.attribute_value("prefetchable", false) };
return *(new (alloc) Element(bar, range, pf));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & iomem, Genode::Xml_node node)
{
Range range { node.attribute_value<Genode::addr_t>("address", 0),
node.attribute_value<Genode::size_t>("size", 0) };
return (range.start == iomem.range.start) && (range.size == iomem.range.size);
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("io_mem");
}
};
struct Driver::Io_port_update_policy
: Genode::List_model<Device::Io_port_range>::Update_policy
{
using Range = Device::Io_port_range::Range;
using Bar = Device::Pci_bar;
Genode::Allocator & alloc;
Io_port_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & ipr) {
Genode::destroy(alloc, &ipr); }
Element & create_element(Genode::Xml_node node)
{
Bar bar { node.attribute_value<uint8_t>("pci_bar", Bar::INVALID) };
Range range { node.attribute_value<uint16_t>("address", 0),
node.attribute_value<uint16_t>("size", 0) };
return *(new (alloc) Element(bar, range));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & ipr, Genode::Xml_node node)
{
Range range { node.attribute_value<uint16_t>("address", 0),
node.attribute_value<uint16_t>("size", 0) };
return range.addr == ipr.range.addr && range.size == ipr.range.size;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("io_port_range");
}
};
struct Driver::Property_update_policy : Genode::List_model<Device::Property>::Update_policy
{
Genode::Allocator & alloc;
Property_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & p) {
Genode::destroy(alloc, &p); }
Element & create_element(Genode::Xml_node node)
{
return *(new (alloc)
Element(node.attribute_value("name", Element::Name()),
node.attribute_value("value", Element::Value())));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & prop, Genode::Xml_node node)
{
Element::Name n = node.attribute_value("name", Element::Name());
Element::Value v = node.attribute_value("value", Element::Value());
return (n == prop.name) && (v == prop.value);
}
static bool node_is_element(Genode::Xml_node node) {
return node.has_type("property"); }
};
struct Driver::Clock_update_policy
: Genode::List_model<Device::Clock>::Update_policy
{
Genode::Allocator & alloc;
Clock_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & clock) {
Genode::destroy(alloc, &clock); }
Element & create_element(Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
Element::Name parent = node.attribute_value("parent", Element::Name());
Element::Name driver = node.attribute_value("driver_name", Element::Name());
unsigned long rate = node.attribute_value<unsigned long >("rate", 0);
return *(new (alloc) Element(name, parent, driver, rate));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & clock, Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
Element::Name driver_name = node.attribute_value("driver_name", Element::Name());
return name == clock.name && driver_name == clock.driver_name;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("clock");
}
};
struct Driver::Power_domain_update_policy
: Genode::List_model<Device::Power_domain>::Update_policy
{
Genode::Allocator & alloc;
Power_domain_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & pd) {
Genode::destroy(alloc, &pd); }
Element & create_element(Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
return *(new (alloc) Element(name));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & pd, Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
return name == pd.name;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("power-domain");
}
};
struct Driver::Reset_domain_update_policy
: Genode::List_model<Device::Reset_domain>::Update_policy
{
Genode::Allocator & alloc;
Reset_domain_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & pd) {
Genode::destroy(alloc, &pd); }
Element & create_element(Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
return *(new (alloc) Element(name));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & pd, Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
return name == pd.name;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("reset-domain");
}
};
struct Driver::Pci_config_update_policy
: Genode::List_model<Device::Pci_config>::Update_policy
{
Genode::Allocator & alloc;
Pci_config_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & pd) {
Genode::destroy(alloc, &pd); }
Element & create_element(Genode::Xml_node node)
{
using namespace Pci;
addr_t addr = node.attribute_value("address", ~0UL);
bus_t bus_num = node.attribute_value<bus_t>("bus", 0);
dev_t dev_num = node.attribute_value<dev_t>("device", 0);
func_t func_num = node.attribute_value<func_t>("function", 0);
vendor_t vendor_id = node.attribute_value<vendor_t>("vendor_id",
0xffff);
device_t device_id = node.attribute_value<device_t>("device_id",
0xffff);
class_t class_code = node.attribute_value<class_t>("class", 0xff);
rev_t rev = node.attribute_value<rev_t>("revision", 0xff);
vendor_t sub_v_id = node.attribute_value<vendor_t>("sub_vendor_id",
0xffff);
device_t sub_d_id = node.attribute_value<device_t>("sub_device_id",
0xffff);
bool bridge = node.attribute_value("bridge", false);
return *(new (alloc) Element(addr, bus_num, dev_num, func_num,
vendor_id, device_id, class_code,
rev, sub_v_id, sub_d_id, bridge));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & e, Genode::Xml_node node)
{
addr_t addr = node.attribute_value("address", ~0UL);
return addr == e.addr;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("pci-config");
}
};
struct Driver::Reserved_memory_update_policy
: Genode::List_model<Device::Reserved_memory>::Update_policy
{
Genode::Allocator & alloc;
Reserved_memory_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & pd) {
Genode::destroy(alloc, &pd); }
Element & create_element(Genode::Xml_node node)
{
using namespace Pci;
addr_t addr = node.attribute_value("address", 0UL);
size_t size = node.attribute_value("size", 0UL);
return *(new (alloc) Element({addr, size}));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & e, Genode::Xml_node node)
{
addr_t addr = node.attribute_value("address", 0UL);
size_t size = node.attribute_value("size", 0UL);
return addr == e.range.start && size == e.range.size;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("reserved_memory");
}
};
struct Driver::Io_mmu_update_policy
: Genode::List_model<Device::Io_mmu>::Update_policy
{
Genode::Allocator & alloc;
Io_mmu_update_policy(Genode::Allocator & alloc) : alloc(alloc) {}
void destroy_element(Element & pd) {
Genode::destroy(alloc, &pd); }
Element & create_element(Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
return *(new (alloc) Element(name));
}
void update_element(Element &, Genode::Xml_node) {}
static bool element_matches_xml_node(Element const & e, Genode::Xml_node node)
{
Element::Name name = node.attribute_value("name", Element::Name());
return name == e.name;
}
static bool node_is_element(Genode::Xml_node node)
{
return node.has_type("io_mmu");
}
};
#endif /* _SRC__DRIVERS__PLATFORM__DEVICE_H_ */

View File

@ -1,137 +0,0 @@
/*
* \brief Platform driver - Device model policy
* \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.
*/
#include <device.h>
using Driver::Device_model;
using Driver::Device;
void Device_model::destroy_element(Device & device)
{
{
Irq_update_policy policy(_heap);
device._irq_list.destroy_all_elements(policy);
}
{
Io_mem_update_policy policy(_heap);
device._io_mem_list.destroy_all_elements(policy);
}
{
Io_port_update_policy policy(_heap);
device._io_port_range_list.destroy_all_elements(policy);
}
{
Property_update_policy policy(_heap);
device._property_list.destroy_all_elements(policy);
}
{
Clock_update_policy policy(_heap);
device._clock_list.destroy_all_elements(policy);
}
{
Power_domain_update_policy policy(_heap);
device._power_domain_list.destroy_all_elements(policy);
}
{
Reset_domain_update_policy policy(_heap);
device._reset_domain_list.destroy_all_elements(policy);
}
{
Pci_config_update_policy policy(_heap);
device._pci_config_list.destroy_all_elements(policy);
}
{
Reserved_memory_update_policy policy(_heap);
device._reserved_mem_list.destroy_all_elements(policy);
}
{
Io_mmu_update_policy policy(_heap);
device._io_mmu_list.destroy_all_elements(policy);
}
device.release(_owner);
Genode::destroy(_heap, &device);
}
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());
bool leave_operational = node.attribute_value("leave_operational", false);
return *(new (_heap) Device(_env, *this, name, type, leave_operational));
}
void Device_model::update_element(Device & device,
Genode::Xml_node node)
{
{
Irq_update_policy policy(_heap);
device._irq_list.update_from_xml(policy, node);
}
{
Io_mem_update_policy policy(_heap);
device._io_mem_list.update_from_xml(policy, node);
}
{
Io_port_update_policy policy(_heap);
device._io_port_range_list.update_from_xml(policy, node);
}
{
Property_update_policy policy(_heap);
device._property_list.update_from_xml(policy, node);
}
{
Clock_update_policy policy(_heap);
device._clock_list.update_from_xml(policy, node);
}
{
Power_domain_update_policy policy(_heap);
device._power_domain_list.update_from_xml(policy, node);
}
{
Reset_domain_update_policy policy(_heap);
device._reset_domain_list.update_from_xml(policy, node);
}
{
Pci_config_update_policy policy(_heap);
device._pci_config_list.update_from_xml(policy, node);
}
{
Reserved_memory_update_policy policy(_heap);
device._reserved_mem_list.update_from_xml(policy, node);
}
{
Io_mmu_update_policy policy(_heap);
device._io_mmu_list.update_from_xml(policy, node);
}
}

View File

@ -1,6 +1,5 @@
SRC_CC += device.cc
SRC_CC += device_component.cc
SRC_CC += device_model_policy.cc
SRC_CC += device_pd.cc
SRC_CC += main.cc
SRC_CC += pci.cc