From 5f7fe7498fe5b7b1594eeb99d8a0fbb72b802cbe Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 9 Dec 2020 10:07:05 +0100 Subject: [PATCH] platform_drv: add mmio delayer support required after power on and function level reset Issue #3963 --- repos/base/run/platform_drv.inc | 2 +- .../drivers_interactive-muen/drivers.config | 1 + repos/os/run/pci.run | 11 +++++--- .../platform/spec/x86/nonpci_devices.cc | 26 ++++++++++++------- .../platform/spec/x86/pci_device_component.h | 9 +++++-- .../platform/spec/x86/pci_session_component.h | 21 ++++++++++++--- 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc index cb8a304815..51890f5691 100644 --- a/repos/base/run/platform_drv.inc +++ b/repos/base/run/platform_drv.inc @@ -262,7 +262,7 @@ proc platform_drv_config {} { append_if [expr [have_spec x86] && ![have_spec muen]] drv_config { } - append_if [have_spec rpi] drv_config { + append_if [expr [have_spec rpi] || [have_spec x86]] drv_config { } append drv_config { diff --git a/repos/os/recipes/raw/drivers_interactive-muen/drivers.config b/repos/os/recipes/raw/drivers_interactive-muen/drivers.config index 9b17944d7e..ee76eaa725 100644 --- a/repos/os/recipes/raw/drivers_interactive-muen/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-muen/drivers.config @@ -33,6 +33,7 @@ + diff --git a/repos/os/run/pci.run b/repos/os/run/pci.run index 35664f7ac4..1f436b05bb 100644 --- a/repos/os/run/pci.run +++ b/repos/os/run/pci.run @@ -2,7 +2,7 @@ assert_spec pci # # Build # -set build_components { core init test/pci } +set build_components { core init test/pci timer } set use_acpica_as_acpi_drv 0 @@ -46,7 +46,12 @@ append config { - } + + + + + + } append_platform_drv_config @@ -64,7 +69,7 @@ install_config $config # generic modules set boot_modules { - core ld.lib.so init test-pci + core ld.lib.so init test-pci timer } # platform-specific modules diff --git a/repos/os/src/drivers/platform/spec/x86/nonpci_devices.cc b/repos/os/src/drivers/platform/spec/x86/nonpci_devices.cc index 7179a20f47..f71a19049f 100644 --- a/repos/os/src/drivers/platform/spec/x86/nonpci_devices.cc +++ b/repos/os/src/drivers/platform/spec/x86/nonpci_devices.cc @@ -36,12 +36,14 @@ class Nonpci::Ps2 : public Platform::Device_component public: - Ps2(Genode::Env &env, + Ps2(Genode::Env &env, Genode::Attached_io_mem_dataspace &pciconf, - Platform::Session_component &session, - Genode::Allocator &heap_for_irq) + Platform::Session_component &session, + Genode::Allocator &heap_for_irq, + Platform::Pci::Config::Delayer &delayer) : - Platform::Device_component(env, pciconf, session, IRQ_KEYBOARD, heap_for_irq), + Platform::Device_component(env, pciconf, session, IRQ_KEYBOARD, + heap_for_irq, delayer), _ep(env.ep().rpc_ep()), _irq_mouse(IRQ_MOUSE, ~0UL, env, heap_for_irq), _data(env, REG_DATA, ACCESS_WIDTH), @@ -101,12 +103,14 @@ class Nonpci::Pit : public Platform::Device_component public: - Pit(Genode::Env &env, + Pit(Genode::Env &env, Genode::Attached_io_mem_dataspace &pciconf, - Platform::Session_component &session, - Genode::Allocator &heap_for_irq) + Platform::Session_component &session, + Genode::Allocator &heap_for_irq, + Platform::Pci::Config::Delayer &delayer) : - Platform::Device_component(env, pciconf, session, IRQ_PIT, heap_for_irq), + Platform::Device_component(env, pciconf, session, IRQ_PIT, + heap_for_irq, delayer), _ports(env, PIT_PORT, PORTS_WIDTH) { } @@ -154,10 +158,12 @@ Platform::Device_capability Platform::Session_component::device(String const &na switch(devices_i) { case 0: - dev = new (_md_alloc) Nonpci::Ps2(_env, _pciconf, *this, _global_heap); + dev = new (_md_alloc) Nonpci::Ps2(_env, _pciconf, *this, + _global_heap, _delayer); break; case 1: - dev = new (_md_alloc) Nonpci::Pit(_env, _pciconf, *this, _global_heap); + dev = new (_md_alloc) Nonpci::Pit(_env, _pciconf, *this, + _global_heap, _delayer); break; default: return Device_capability(); diff --git a/repos/os/src/drivers/platform/spec/x86/pci_device_component.h b/repos/os/src/drivers/platform/spec/x86/pci_device_component.h index 2459beae67..e524ff7056 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_device_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_device_component.h @@ -44,6 +44,7 @@ class Platform::Device_component : public Genode::Rpc_object, Device_component &operator = (Device_component const &); Genode::Env &_env; + Pci::Config::Delayer &_delayer; Device_config _device_config { }; Genode::addr_t _config_space; Config_access _config_access; @@ -289,9 +290,11 @@ class Platform::Device_component : public Genode::Rpc_object, Config_access &config_access, Platform::Session_component &session, Genode::Allocator &md_alloc, - Genode::Allocator &global_heap) + Genode::Allocator &global_heap, + Pci::Config::Delayer &delayer) : _env(env), + _delayer(delayer), _device_config(device_config), _config_space(addr), _config_access(config_access), _session(session), @@ -312,9 +315,11 @@ class Platform::Device_component : public Genode::Rpc_object, Device_component(Genode::Env &env, Genode::Attached_io_mem_dataspace &pciconf, Platform::Session_component &session, unsigned irq, - Genode::Allocator &global_heap) + Genode::Allocator &global_heap, + Pci::Config::Delayer &delayer) : _env(env), + _delayer(delayer), _config_space(~0UL), _config_access(pciconf), _session(session), diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index 127e5f8541..ecb4e83b0c 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -215,6 +216,7 @@ class Platform::Session_component : public Genode::Rpc_object Genode::List _device_list { }; Platform::Pci_buses &_pci_bus; Genode::Heap &_global_heap; + Pci::Config::Delayer &_delayer; bool _iommu; /** @@ -477,6 +479,7 @@ class Platform::Session_component : public Genode::Rpc_object Genode::Attached_io_mem_dataspace &pciconf, Platform::Pci_buses &buses, Genode::Heap &global_heap, + Pci::Config::Delayer &delayer, char const *args, bool const iommu) : @@ -487,7 +490,10 @@ class Platform::Session_component : public Genode::Rpc_object _cap_guard(Genode::cap_quota_from_args(args)), _md_alloc(_env_ram, env.rm()), _label(Genode::label_from_args(args)), - _pci_bus(buses), _global_heap(global_heap), _iommu(iommu) + _pci_bus(buses), + _global_heap(global_heap), + _delayer(delayer), + _iommu(iommu) { /* subtract the RPC session and session dataspace capabilities */ _cap_guard.withdraw(Genode::Cap_quota{2}); @@ -694,8 +700,8 @@ class Platform::Session_component : public Genode::Rpc_object * device and return its capability. */ Device_component * dev = new (_md_alloc) - Device_component(_env, config, config_space, config_access, *this, - _md_alloc, _global_heap); + Device_component(_env, config, config_space, config_access, + *this, _md_alloc, _global_heap, _delayer); _device_list.insert(dev); @@ -825,6 +831,13 @@ class Platform::Root : public Genode::Root_component bool _iommu { false }; + struct Timer_delayer : Pci::Config::Delayer, Timer::Connection + { + Timer_delayer(Env &env) : Timer::Connection(env) { } + + void usleep(uint64_t us) override { Timer::Connection::usleep(us); } + } _delayer { _env }; + void _parse_report_rom(Genode::Env &env, const char * acpi_rom, bool acpi_platform) { @@ -1011,7 +1024,7 @@ class Platform::Root : public Genode::Root_component try { return new (md_alloc()) Session_component(_env, _config, *_pci_confspace, *_buses, - _heap, args, _iommu); + _heap, _delayer, args, _iommu); } catch (Genode::Session_policy::No_policy_defined) { Genode::error("Invalid session request, no matching policy for ",