mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
committed by
Norman Feske
parent
a981fb864c
commit
6789ce8b83
@@ -245,6 +245,9 @@ proc platform_drv_config {} {
|
||||
append_if [have_board pc] drv_config {
|
||||
<service name="ROM" label="acpi"> <child name="acpi_report_rom"/> </service>}
|
||||
|
||||
append_if [expr [have_spec x86]] drv_config {
|
||||
<service name="Report"> <child name="acpi_report_rom"/> </service>}
|
||||
|
||||
append_if [expr [have_board rpi] || [have_board pc]] drv_config {
|
||||
<service name="Timer"> <any-child/> </service>}
|
||||
|
||||
|
||||
@@ -42,8 +42,12 @@ struct Platform::Main
|
||||
Genode::Constructible<Genode::Attached_rom_dataspace> system_state { };
|
||||
Genode::Constructible<Genode::Attached_rom_dataspace> acpi_ready { };
|
||||
|
||||
Genode::Signal_handler<Platform::Main> _acpi_report;
|
||||
Genode::Signal_handler<Platform::Main> _system_report;
|
||||
Signal_handler<Main> _acpi_report { _env.ep(), *this,
|
||||
&Main::acpi_update };
|
||||
Signal_handler<Main> _system_report { _env.ep(), *this,
|
||||
&Main::system_update };
|
||||
Signal_handler<Main> _config_handler { _env.ep(), *this,
|
||||
&Main::config_update };
|
||||
|
||||
Genode::Capability<Genode::Typed_root<Platform::Session_component> > root_cap { };
|
||||
|
||||
@@ -52,14 +56,22 @@ struct Platform::Main
|
||||
|
||||
void acpi_update()
|
||||
{
|
||||
acpi_rom->update();
|
||||
if (!root.constructed()) {
|
||||
acpi_rom->update();
|
||||
|
||||
if (!acpi_rom->valid() || root.constructed())
|
||||
if (!acpi_rom->valid())
|
||||
return;
|
||||
|
||||
root.construct(_env, sliced_heap, _config,
|
||||
acpi_rom->local_addr<const char>(), _acpi_platform);
|
||||
}
|
||||
|
||||
if (root_cap.valid())
|
||||
return;
|
||||
|
||||
const char * report_addr = acpi_rom->local_addr<const char>();
|
||||
|
||||
root.construct(_env, sliced_heap, _config, report_addr, _acpi_platform);
|
||||
/* don't announce service if no policy entry is available */
|
||||
if (!root->config_with_policy())
|
||||
return;
|
||||
|
||||
root_cap = _env.ep().manage(*root);
|
||||
|
||||
@@ -92,6 +104,23 @@ struct Platform::Main
|
||||
}
|
||||
}
|
||||
|
||||
void config_update()
|
||||
{
|
||||
_config.update();
|
||||
|
||||
if (!_config.valid())
|
||||
return;
|
||||
|
||||
if (!root_cap.valid())
|
||||
acpi_update();
|
||||
|
||||
|
||||
if (root.constructed()) {
|
||||
root->generate_pci_report();
|
||||
root->config_update();
|
||||
}
|
||||
}
|
||||
|
||||
static bool acpi_platform(Genode::Env & env)
|
||||
{
|
||||
using Name = String<32>;
|
||||
@@ -110,13 +139,12 @@ struct Platform::Main
|
||||
Main(Genode::Env &env)
|
||||
:
|
||||
_env(env),
|
||||
_acpi_report(_env.ep(), *this, &Main::acpi_update),
|
||||
_system_report(_env.ep(), *this, &Main::system_update),
|
||||
_acpi_platform(acpi_platform(env))
|
||||
{
|
||||
const Genode::Xml_node config = _config.xml();
|
||||
_config.sigh(_config_handler);
|
||||
|
||||
_acpi_ready = config.attribute_value("acpi_ready", false);
|
||||
if (_config.valid())
|
||||
_acpi_ready = _config.xml().attribute_value("acpi_ready", false);
|
||||
|
||||
if (_acpi_ready) {
|
||||
acpi_ready.construct(env, "acpi_ready");
|
||||
|
||||
@@ -86,6 +86,8 @@ class Nonpci::Ps2 : public Platform::Device_component
|
||||
{
|
||||
return Genode::Io_mem_session_capability();
|
||||
}
|
||||
|
||||
virtual String<5> name() const override { return "PS2"; }
|
||||
};
|
||||
|
||||
|
||||
@@ -123,6 +125,8 @@ class Nonpci::Pit : public Platform::Device_component
|
||||
|
||||
return Genode::Io_port_session_capability();
|
||||
}
|
||||
|
||||
virtual String<5> name() const override { return "PIT"; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -547,6 +547,17 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
||||
Device_config device_config() const { return _device_config; }
|
||||
Genode::addr_t config_space() const { return _config_space; }
|
||||
|
||||
virtual String<5> name() const { return "PCI"; }
|
||||
|
||||
template <typename FUNC>
|
||||
void for_each_device(FUNC const &fn) const
|
||||
{
|
||||
fn(*this);
|
||||
|
||||
for (auto *dev = this; dev; dev = dev->next()) {
|
||||
fn(*dev); }
|
||||
}
|
||||
|
||||
/**************************
|
||||
** PCI-device interface **
|
||||
**************************/
|
||||
|
||||
@@ -214,13 +214,13 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
_env.pd(), _ram_guard, _cap_guard };
|
||||
Genode::Heap _md_alloc;
|
||||
Genode::Session_label const _label;
|
||||
Genode::Session_policy const _policy { _label, _config.xml() };
|
||||
Genode::List<Device_component> _device_list { };
|
||||
Platform::Pci_buses &_pci_bus;
|
||||
Genode::Heap &_global_heap;
|
||||
Pci::Config::Delayer &_delayer;
|
||||
Device_bars_pool &_devices_bars;
|
||||
bool _iommu;
|
||||
bool _msi_usage { true };
|
||||
|
||||
/**
|
||||
* Registry of RAM dataspaces allocated by the session
|
||||
@@ -325,8 +325,10 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Session_policy const policy { _label, _config.xml() };
|
||||
|
||||
try {
|
||||
_policy.for_each_sub_node("device", [&] (Xml_node dev) {
|
||||
policy.for_each_sub_node("device", [&] (Xml_node dev) {
|
||||
|
||||
/* enforce restriction based on name name */
|
||||
if (dev.attribute_value("name", Genode::String<10>()) == name)
|
||||
@@ -373,7 +375,9 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
using namespace Genode;
|
||||
|
||||
try {
|
||||
_policy.for_each_sub_node("pci", [&] (Xml_node node) {
|
||||
Session_policy const policy { _label, _config.xml() };
|
||||
|
||||
policy.for_each_sub_node("pci", [&] (Xml_node node) {
|
||||
|
||||
if (_bdf_exactly_specified(node)) {
|
||||
if (_bdf_matches(node, bdf))
|
||||
@@ -488,8 +492,18 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
/* subtract the RPC session and session dataspace capabilities */
|
||||
_cap_guard.withdraw(Genode::Cap_quota{2});
|
||||
|
||||
check_for_policy();
|
||||
}
|
||||
|
||||
void check_for_policy()
|
||||
{
|
||||
Session_policy const policy { _label, _config.xml() };
|
||||
|
||||
typedef Genode::String<10> Mode;
|
||||
_msi_usage = policy.attribute_value("irq_mode", Mode()) != "nomsi";
|
||||
|
||||
/* check policy for non-pci devices */
|
||||
_policy.for_each_sub_node("device", [&] (Genode::Xml_node device_node) {
|
||||
policy.for_each_sub_node("device", [&] (Genode::Xml_node device_node) {
|
||||
|
||||
if (!device_node.has_attribute("name")) {
|
||||
Genode::error("'", _label, "' - device node "
|
||||
@@ -509,7 +523,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
});
|
||||
|
||||
/* pci devices */
|
||||
_policy.for_each_sub_node("pci", [&] (Genode::Xml_node node) {
|
||||
policy.for_each_sub_node("pci", [&] (Genode::Xml_node node) {
|
||||
|
||||
enum { INVALID_CLASS = 0x1000000U };
|
||||
|
||||
@@ -571,6 +585,40 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
});
|
||||
}
|
||||
|
||||
bool policy_valid()
|
||||
{
|
||||
try {
|
||||
/* check that policy is available */
|
||||
check_for_policy();
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check that device entries in policy are still permitted */
|
||||
if (!_device_list.first())
|
||||
return true;
|
||||
|
||||
bool result = true;
|
||||
|
||||
_device_list.first()->for_each_device([&](auto const &dev) {
|
||||
|
||||
/* Non PCI devices */
|
||||
if (!dev.device_config().valid()) {
|
||||
if (!permit_device(dev.name().string()))
|
||||
result = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* PCI devices */
|
||||
if (!permit_device(dev.device_config().bdf(),
|
||||
dev.device_config().class_code()))
|
||||
result = false;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
@@ -610,11 +658,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
/**
|
||||
* Check whether msi usage was explicitly switched off
|
||||
*/
|
||||
bool msi_usage()
|
||||
{
|
||||
typedef Genode::String<10> Mode;
|
||||
return _policy.attribute_value("irq_mode", Mode()) != "nomsi";
|
||||
}
|
||||
bool msi_usage() const { return _msi_usage; }
|
||||
|
||||
|
||||
/***************************
|
||||
@@ -821,7 +865,8 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
Device_bars_pool _devices_bars { };
|
||||
Genode::Constructible<Platform::Pci_buses> _buses { };
|
||||
|
||||
bool _iommu { false };
|
||||
bool _iommu { false };
|
||||
bool _pci_reported { false };
|
||||
|
||||
struct Timer_delayer : Pci::Config::Delayer, Timer::Connection
|
||||
{
|
||||
@@ -830,6 +875,8 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
void usleep(uint64_t us) override { Timer::Connection::usleep(us); }
|
||||
} _delayer { _env };
|
||||
|
||||
Genode::Registry<Genode::Registered<Session_component> > _sessions { };
|
||||
|
||||
void _parse_report_rom(Genode::Env &env, const char * acpi_rom,
|
||||
bool acpi_platform)
|
||||
{
|
||||
@@ -1014,10 +1061,14 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
Session_component *_create_session(const char *args) override
|
||||
{
|
||||
try {
|
||||
return new (md_alloc())
|
||||
Session_component(_env, _config, *_pci_confspace, *_buses,
|
||||
_heap, _delayer, _devices_bars, args,
|
||||
_iommu);
|
||||
return new (md_alloc())
|
||||
Genode::Registered<Session_component>(_sessions, _env,
|
||||
_config,
|
||||
*_pci_confspace,
|
||||
*_buses, _heap,
|
||||
_delayer,
|
||||
_devices_bars, args,
|
||||
_iommu);
|
||||
}
|
||||
catch (Genode::Session_policy::No_policy_defined) {
|
||||
Genode::error("Invalid session request, no matching policy for ",
|
||||
@@ -1065,8 +1116,16 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
|
||||
_construct_buses();
|
||||
|
||||
if (config.xml().has_sub_node("report")
|
||||
&& config.xml().sub_node("report").attribute_value("pci", true)) {
|
||||
generate_pci_report();
|
||||
}
|
||||
|
||||
void generate_pci_report()
|
||||
{
|
||||
if (!_pci_reported && _config.valid() &&
|
||||
_config.xml().has_sub_node("report") &&
|
||||
_config.xml().sub_node("report").attribute_value("pci", false)) {
|
||||
|
||||
_pci_reported = true;
|
||||
|
||||
_pci_reporter.construct(_env, "pci", "pci");
|
||||
|
||||
@@ -1091,7 +1150,9 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
using Genode::Hex;
|
||||
|
||||
xml.node("device", [&] () {
|
||||
xml.attribute("bdf" , String<8>(Hex(bus, Hex::Prefix::OMIT_PREFIX), ":", Hex(device, Hex::Prefix::OMIT_PREFIX), ".", function));
|
||||
xml.attribute("bus" , String<5>(Hex(bus)));
|
||||
xml.attribute("device" , String<5>(Hex(device)));
|
||||
xml.attribute("function" , String<5>(Hex(function)));
|
||||
xml.attribute("vendor_id" , String<8>(Hex(config.vendor_id())));
|
||||
xml.attribute("device_id" , String<8>(Hex(config.device_id())));
|
||||
xml.attribute("class_code", String<12>(Hex(config.class_code())));
|
||||
@@ -1118,4 +1179,15 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool config_with_policy() const {
|
||||
return _config.valid() && _config.xml().has_sub_node("policy"); }
|
||||
|
||||
void config_update()
|
||||
{
|
||||
_sessions.for_each([&](auto &session) {
|
||||
if (!session.policy_valid())
|
||||
destroy(session);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user