platform_drv: add mmio delayer support

required after power on and function level reset

Issue #3963
This commit is contained in:
Alexander Boettcher 2020-12-09 10:07:05 +01:00 committed by Norman Feske
parent c89864c830
commit 5f7fe7498f
6 changed files with 50 additions and 20 deletions

View File

@ -262,7 +262,7 @@ proc platform_drv_config {} {
append_if [expr [have_spec x86] && ![have_spec muen]] drv_config { append_if [expr [have_spec x86] && ![have_spec muen]] drv_config {
<service name="ROM" label="acpi"> <child name="acpi_report_rom"/> </service>} <service name="ROM" label="acpi"> <child name="acpi_report_rom"/> </service>}
append_if [have_spec rpi] drv_config { append_if [expr [have_spec rpi] || [have_spec x86]] drv_config {
<service name="Timer"> <any-child/> </service>} <service name="Timer"> <any-child/> </service>}
append drv_config { append drv_config {

View File

@ -33,6 +33,7 @@
<service name="PD"> <parent/> </service> <service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service> <service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service> <service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
</route> </route>
<config> <config>
<policy label_prefix="ps2_drv"> <device name="PS2"/> </policy> <policy label_prefix="ps2_drv"> <device name="PS2"/> </policy>

View File

@ -2,7 +2,7 @@ assert_spec pci
# #
# Build # Build
# #
set build_components { core init test/pci } set build_components { core init test/pci timer }
set use_acpica_as_acpi_drv 0 set use_acpica_as_acpi_drv 0
@ -46,7 +46,12 @@ append config {
<default-route> <default-route>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
</default-route> </default-route>
<default caps="100"/>} <default caps="100"/>
<start name="timer">
<resource name="RAM" quantum="10M"/>
<provides><service name="Timer"/></provides>
</start>}
append_platform_drv_config append_platform_drv_config
@ -64,7 +69,7 @@ install_config $config
# generic modules # generic modules
set boot_modules { set boot_modules {
core ld.lib.so init test-pci core ld.lib.so init test-pci timer
} }
# platform-specific modules # platform-specific modules

View File

@ -36,12 +36,14 @@ class Nonpci::Ps2 : public Platform::Device_component
public: public:
Ps2(Genode::Env &env, Ps2(Genode::Env &env,
Genode::Attached_io_mem_dataspace &pciconf, Genode::Attached_io_mem_dataspace &pciconf,
Platform::Session_component &session, Platform::Session_component &session,
Genode::Allocator &heap_for_irq) 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()), _ep(env.ep().rpc_ep()),
_irq_mouse(IRQ_MOUSE, ~0UL, env, heap_for_irq), _irq_mouse(IRQ_MOUSE, ~0UL, env, heap_for_irq),
_data(env, REG_DATA, ACCESS_WIDTH), _data(env, REG_DATA, ACCESS_WIDTH),
@ -101,12 +103,14 @@ class Nonpci::Pit : public Platform::Device_component
public: public:
Pit(Genode::Env &env, Pit(Genode::Env &env,
Genode::Attached_io_mem_dataspace &pciconf, Genode::Attached_io_mem_dataspace &pciconf,
Platform::Session_component &session, Platform::Session_component &session,
Genode::Allocator &heap_for_irq) 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) _ports(env, PIT_PORT, PORTS_WIDTH)
{ } { }
@ -154,10 +158,12 @@ Platform::Device_capability Platform::Session_component::device(String const &na
switch(devices_i) { switch(devices_i) {
case 0: 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; break;
case 1: 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; break;
default: default:
return Device_capability(); return Device_capability();

View File

@ -44,6 +44,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
Device_component &operator = (Device_component const &); Device_component &operator = (Device_component const &);
Genode::Env &_env; Genode::Env &_env;
Pci::Config::Delayer &_delayer;
Device_config _device_config { }; Device_config _device_config { };
Genode::addr_t _config_space; Genode::addr_t _config_space;
Config_access _config_access; Config_access _config_access;
@ -289,9 +290,11 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
Config_access &config_access, Config_access &config_access,
Platform::Session_component &session, Platform::Session_component &session,
Genode::Allocator &md_alloc, Genode::Allocator &md_alloc,
Genode::Allocator &global_heap) Genode::Allocator &global_heap,
Pci::Config::Delayer &delayer)
: :
_env(env), _env(env),
_delayer(delayer),
_device_config(device_config), _config_space(addr), _device_config(device_config), _config_space(addr),
_config_access(config_access), _config_access(config_access),
_session(session), _session(session),
@ -312,9 +315,11 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
Device_component(Genode::Env &env, Device_component(Genode::Env &env,
Genode::Attached_io_mem_dataspace &pciconf, Genode::Attached_io_mem_dataspace &pciconf,
Platform::Session_component &session, unsigned irq, Platform::Session_component &session, unsigned irq,
Genode::Allocator &global_heap) Genode::Allocator &global_heap,
Pci::Config::Delayer &delayer)
: :
_env(env), _env(env),
_delayer(delayer),
_config_space(~0UL), _config_space(~0UL),
_config_access(pciconf), _config_access(pciconf),
_session(session), _session(session),

View File

@ -19,6 +19,7 @@
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/tslab.h> #include <base/tslab.h>
#include <root/component.h> #include <root/component.h>
#include <timer_session/connection.h>
#include <util/mmio.h> #include <util/mmio.h>
#include <util/retry.h> #include <util/retry.h>
@ -215,6 +216,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Genode::List<Device_component> _device_list { }; Genode::List<Device_component> _device_list { };
Platform::Pci_buses &_pci_bus; Platform::Pci_buses &_pci_bus;
Genode::Heap &_global_heap; Genode::Heap &_global_heap;
Pci::Config::Delayer &_delayer;
bool _iommu; bool _iommu;
/** /**
@ -477,6 +479,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Genode::Attached_io_mem_dataspace &pciconf, Genode::Attached_io_mem_dataspace &pciconf,
Platform::Pci_buses &buses, Platform::Pci_buses &buses,
Genode::Heap &global_heap, Genode::Heap &global_heap,
Pci::Config::Delayer &delayer,
char const *args, char const *args,
bool const iommu) bool const iommu)
: :
@ -487,7 +490,10 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_cap_guard(Genode::cap_quota_from_args(args)), _cap_guard(Genode::cap_quota_from_args(args)),
_md_alloc(_env_ram, env.rm()), _md_alloc(_env_ram, env.rm()),
_label(Genode::label_from_args(args)), _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 */ /* subtract the RPC session and session dataspace capabilities */
_cap_guard.withdraw(Genode::Cap_quota{2}); _cap_guard.withdraw(Genode::Cap_quota{2});
@ -694,8 +700,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
* device and return its capability. * device and return its capability.
*/ */
Device_component * dev = new (_md_alloc) Device_component * dev = new (_md_alloc)
Device_component(_env, config, config_space, config_access, *this, Device_component(_env, config, config_space, config_access,
_md_alloc, _global_heap); *this, _md_alloc, _global_heap, _delayer);
_device_list.insert(dev); _device_list.insert(dev);
@ -825,6 +831,13 @@ class Platform::Root : public Genode::Root_component<Session_component>
bool _iommu { false }; 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, void _parse_report_rom(Genode::Env &env, const char * acpi_rom,
bool acpi_platform) bool acpi_platform)
{ {
@ -1011,7 +1024,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
try { try {
return new (md_alloc()) return new (md_alloc())
Session_component(_env, _config, *_pci_confspace, *_buses, Session_component(_env, _config, *_pci_confspace, *_buses,
_heap, args, _iommu); _heap, _delayer, args, _iommu);
} }
catch (Genode::Session_policy::No_policy_defined) { catch (Genode::Session_policy::No_policy_defined) {
Genode::error("Invalid session request, no matching policy for ", Genode::error("Invalid session request, no matching policy for ",