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 {
<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>}
append drv_config {

View File

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

View File

@ -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 {
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</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
@ -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

View File

@ -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();

View File

@ -44,6 +44,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
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<Platform::Device>,
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<Platform::Device>,
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),

View File

@ -19,6 +19,7 @@
#include <base/rpc_server.h>
#include <base/tslab.h>
#include <root/component.h>
#include <timer_session/connection.h>
#include <util/mmio.h>
#include <util/retry.h>
@ -215,6 +216,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Genode::List<Device_component> _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<Session>
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<Session>
_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<Session>
* 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<Session_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<Session_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 ",