mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-20 08:03:56 +00:00
committed by
Christian Helmuth
parent
1895931918
commit
df71cecc66
@ -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,
|
Driver::Device::Device(Env & env, Device_model & model, Name name, Type type,
|
||||||
bool leave_operational)
|
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)
|
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
|
* Detect all shared interrupts
|
||||||
|
@ -38,16 +38,6 @@ namespace Driver {
|
|||||||
struct Device_reporter;
|
struct Device_reporter;
|
||||||
struct Device_model;
|
struct Device_model;
|
||||||
struct Device_owner;
|
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)
|
Io_mem(Pci_bar bar, Range range, bool pf)
|
||||||
: bar(bar), range(range), prefetchable(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
|
struct Irq : List_model<Irq>::Element
|
||||||
@ -104,6 +106,16 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
bool shared { false };
|
bool shared { false };
|
||||||
|
|
||||||
Irq(unsigned number) : number(number) {}
|
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
|
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)
|
Io_port_range(Pci_bar bar, Range range)
|
||||||
: 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
|
struct Property : List_model<Property>::Element
|
||||||
@ -127,6 +150,17 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
|
|
||||||
Property(Name name, Value value)
|
Property(Name name, Value value)
|
||||||
: 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
|
struct Clock : List_model<Clock>::Element
|
||||||
@ -144,6 +178,17 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
unsigned long rate)
|
unsigned long rate)
|
||||||
: name(name), parent(parent),
|
: name(name), parent(parent),
|
||||||
driver_name(driver_name), rate(rate) {}
|
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
|
struct Power_domain : List_model<Power_domain>::Element
|
||||||
@ -153,6 +198,16 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
Name name;
|
Name name;
|
||||||
|
|
||||||
Power_domain(Name name) : 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
|
struct Reset_domain : List_model<Reset_domain>::Element
|
||||||
@ -162,6 +217,16 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
Name name;
|
Name name;
|
||||||
|
|
||||||
Reset_domain(Name name) : 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
|
struct Pci_config : List_model<Pci_config>::Element
|
||||||
@ -200,7 +265,18 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
revision(revision),
|
revision(revision),
|
||||||
sub_vendor_id(sub_vendor_id),
|
sub_vendor_id(sub_vendor_id),
|
||||||
sub_device_id(sub_device_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
|
struct Reserved_memory : List_model<Reserved_memory>::Element
|
||||||
@ -210,6 +286,17 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
Range range;
|
Range range;
|
||||||
|
|
||||||
Reserved_memory(Range range) : 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
|
struct Io_mmu : List_model<Io_mmu>::Element
|
||||||
@ -219,6 +306,16 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
Name name;
|
Name name;
|
||||||
|
|
||||||
Io_mmu(Name name) : 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,
|
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 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:
|
protected:
|
||||||
|
|
||||||
friend class Driver::Device_model;
|
friend class Driver::Device_model;
|
||||||
@ -333,8 +449,7 @@ struct Driver::Device_reporter
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Driver::Device_model :
|
class Driver::Device_model
|
||||||
public List_model<Device>::Update_policy
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -360,8 +475,7 @@ class Driver::Device_model :
|
|||||||
Device_owner & owner)
|
Device_owner & owner)
|
||||||
: _env(env), _heap(heap), _reporter(reporter), _owner(owner) { }
|
: _env(env), _heap(heap), _reporter(reporter), _owner(owner) { }
|
||||||
|
|
||||||
~Device_model() {
|
~Device_model() { update(Xml_node("<empty/>")); }
|
||||||
_model.destroy_all_elements(*this); }
|
|
||||||
|
|
||||||
template <typename FN>
|
template <typename FN>
|
||||||
void for_each(FN const & fn) { _model.for_each(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); });
|
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; };
|
Clocks & clocks() { return _clocks; };
|
||||||
Resets & resets() { return _resets; };
|
Resets & resets() { return _resets; };
|
||||||
Powers & powers() { return _powers; };
|
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_ */
|
#endif /* _SRC__DRIVERS__PLATFORM__DEVICE_H_ */
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
SRC_CC += device.cc
|
SRC_CC += device.cc
|
||||||
SRC_CC += device_component.cc
|
SRC_CC += device_component.cc
|
||||||
SRC_CC += device_model_policy.cc
|
|
||||||
SRC_CC += device_pd.cc
|
SRC_CC += device_pd.cc
|
||||||
SRC_CC += main.cc
|
SRC_CC += main.cc
|
||||||
SRC_CC += pci.cc
|
SRC_CC += pci.cc
|
||||||
|
Reference in New Issue
Block a user