mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
platform_drv: attach reserved memory to device PD
Consumes the information about reserved memory region reports from the devices ROM, and adds appropriated mappings to the corresponding device PD. Ref genodelabs/genode#4578
This commit is contained in:
parent
85dc2e5b9b
commit
5e42f347d8
@ -44,6 +44,7 @@ namespace Driver {
|
||||
struct Reset_domain_update_policy;
|
||||
struct Power_domain_update_policy;
|
||||
struct Pci_config_update_policy;
|
||||
struct Reserved_memory_update_policy;
|
||||
}
|
||||
|
||||
|
||||
@ -197,6 +198,15 @@ class Driver::Device : private List_model<Device>::Element
|
||||
bridge(bridge) {}
|
||||
};
|
||||
|
||||
struct Reserved_memory : List_model<Reserved_memory>::Element
|
||||
{
|
||||
using Range = Platform::Device_interface::Range;
|
||||
|
||||
Range range;
|
||||
|
||||
Reserved_memory(Range range) : range(range) {}
|
||||
};
|
||||
|
||||
Device(Env & env, Device_model & model, Name name, Type type);
|
||||
virtual ~Device();
|
||||
|
||||
@ -245,6 +255,14 @@ class Driver::Device : private List_model<Device>::Element
|
||||
});
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void for_each_reserved_memory(FN const & fn) const
|
||||
{
|
||||
unsigned idx = 0;
|
||||
_reserved_mem_list.for_each([&] (Reserved_memory const & mem) {
|
||||
fn(idx++, mem.range); });
|
||||
}
|
||||
|
||||
void generate(Xml_generator &, bool) const;
|
||||
|
||||
protected:
|
||||
@ -253,19 +271,20 @@ class Driver::Device : private List_model<Device>::Element
|
||||
friend class List_model<Device>;
|
||||
friend class List<Device>;
|
||||
|
||||
Env & _env;
|
||||
Device_model & _model;
|
||||
Name const _name;
|
||||
Type const _type;
|
||||
Owner _owner {};
|
||||
List_model<Io_mem> _io_mem_list {};
|
||||
List_model<Irq> _irq_list {};
|
||||
List_model<Io_port_range> _io_port_range_list {};
|
||||
List_model<Property> _property_list {};
|
||||
List_model<Clock> _clock_list {};
|
||||
List_model<Power_domain> _power_domain_list {};
|
||||
List_model<Reset_domain> _reset_domain_list {};
|
||||
List_model<Pci_config> _pci_config_list {};
|
||||
Env & _env;
|
||||
Device_model & _model;
|
||||
Name const _name;
|
||||
Type const _type;
|
||||
Owner _owner {};
|
||||
List_model<Io_mem> _io_mem_list {};
|
||||
List_model<Irq> _irq_list {};
|
||||
List_model<Io_port_range> _io_port_range_list {};
|
||||
List_model<Property> _property_list {};
|
||||
List_model<Clock> _clock_list {};
|
||||
List_model<Power_domain> _power_domain_list {};
|
||||
List_model<Reset_domain> _reset_domain_list {};
|
||||
List_model<Pci_config> _pci_config_list {};
|
||||
List_model<Reserved_memory> _reserved_mem_list {};
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
@ -633,4 +652,39 @@ struct Driver::Pci_config_update_policy
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__DEVICE_H_ */
|
||||
|
@ -27,6 +27,14 @@ void Driver::Device_component::_release_resources()
|
||||
_irq_registry.for_each([&] (Irq & irq) {
|
||||
destroy(_session.heap(), &irq); });
|
||||
|
||||
_io_port_range_registry.for_each([&] (Io_port_range & iop) {
|
||||
destroy(_session.heap(), &iop); });
|
||||
|
||||
_reserved_mem_registry.for_each([&] (Io_mem & iomem) {
|
||||
destroy(_session.heap(), &iomem); });
|
||||
|
||||
if (_pci_config.constructed()) _pci_config.destruct();
|
||||
|
||||
_session.ram_quota_guard().replenish(Ram_quota{_ram_quota});
|
||||
_session.cap_quota_guard().replenish(Cap_quota{_cap_quota});
|
||||
}
|
||||
@ -177,6 +185,20 @@ Device_component::Device_component(Registry<Device_component> & registry,
|
||||
_cap_quota += Io_mem_session::CAP_QUOTA;
|
||||
_pci_config.construct(cfg.addr);
|
||||
});
|
||||
|
||||
device.for_each_reserved_memory([&] (unsigned idx, Range range)
|
||||
{
|
||||
session.ram_quota_guard().withdraw(Ram_quota{Io_mem_session::RAM_QUOTA});
|
||||
_ram_quota += Io_mem_session::RAM_QUOTA;
|
||||
session.cap_quota_guard().withdraw(Cap_quota{Io_mem_session::CAP_QUOTA});
|
||||
_cap_quota += Io_mem_session::CAP_QUOTA;
|
||||
Io_mem & iomem = *(new (session.heap())
|
||||
Io_mem(_reserved_mem_registry, idx, range));
|
||||
iomem.io_mem.construct(_env, iomem.range.start,
|
||||
iomem.range.size, false);
|
||||
session.device_pd().attach_dma_mem(iomem.io_mem->dataspace(),
|
||||
iomem.range.start);
|
||||
});
|
||||
} catch(...) {
|
||||
_release_resources();
|
||||
throw;
|
||||
|
@ -123,6 +123,7 @@ class Driver::Device_component : public Rpc_object<Platform::Device_interface,
|
||||
Registry<Irq> _irq_registry {};
|
||||
Registry<Io_mem> _io_mem_registry {};
|
||||
Registry<Io_port_range> _io_port_range_registry {};
|
||||
Registry<Io_mem> _reserved_mem_registry {};
|
||||
Constructible<Pci_config> _pci_config {};
|
||||
|
||||
void _release_resources();
|
||||
|
@ -58,6 +58,11 @@ void Device_model::destroy_element(Device & device)
|
||||
device._pci_config_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
{
|
||||
Reserved_memory_update_policy policy(_heap);
|
||||
device._reserved_mem_list.destroy_all_elements(policy);
|
||||
}
|
||||
|
||||
Genode::destroy(_heap, &device);
|
||||
}
|
||||
|
||||
@ -112,4 +117,9 @@ void Device_model::update_element(Device & device,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user