Streamline platform-device API on ARM

This API rework eases the access to memory-mapped I/O registers and
interrupts when using the platform driver. It introduces the notions of

- Platform::Device       - one device obtained from a platform session
- Platform::Device::Mmio - locally-mapped MMIO registers of a device
- Platform::Device::Irq  - interface for receiving device interrupts

The patch touches several drivers. Some drivers would require a
significant structural change to adopt the new API (e.g., net/virtio,
dde_linux drivers, imx gpio). In these cases, the patch adds
compatibility shims meant to be temporary. In other cases (e.g., imx
i2c), the adaptation was simple enough to carry through.

Fixes #4075
This commit is contained in:
Norman Feske 2021-04-14 17:19:37 +02:00
parent d1cf9c86b8
commit dc8c899c1d
40 changed files with 616 additions and 349 deletions

View File

@ -115,7 +115,7 @@
<!-- CAUTION: System reset controller access is currently required by
mipi_dsi -->
<device name="src">
<device name="src" type="fsl,imx8mq-src">
<io_mem address="0x30390000" size="0x10000"/>
</device>

View File

@ -15,7 +15,7 @@
/* Genode includes */
#include <base/attached_dataspace.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
/* local includes */
#include <driver.h>
@ -57,6 +57,33 @@
enum Device_id { DCSS, HDMI, MIPI, SRC, UNKNOWN };
namespace Platform { struct Device_client; }
struct Platform::Device_client : Rpc_client<Device_interface>
{
Device_client(Capability<Device_interface> cap)
: Rpc_client<Device_interface>(cap) { }
Irq_session_capability irq(unsigned id = 0)
{
return call<Rpc_irq>(id);
}
Io_mem_session_capability io_mem(unsigned id, Range &range, Cache cache)
{
return call<Rpc_io_mem>(id, range, cache);
}
Dataspace_capability io_mem_dataspace(unsigned id = 0)
{
Range range { };
return Io_mem_session_client(io_mem(id, range, UNCACHED)).dataspace();
}
};
namespace Lx_kit {
Platform::Connection & platform_connection();
Platform::Device_client & platform_device(Device_id);

View File

@ -21,8 +21,7 @@
#include <base/snprintf.h>
#include <gpio_session/connection.h>
#include <irq_session/client.h>
#include <platform_session/connection.h>
#include <platform_device/client.h>
#include <platform_session/device.h>
#include <component.h>
#include <lx_emul.h>
@ -108,6 +107,37 @@ struct Device : Genode::List<Device>::Element
};
namespace Platform {
struct Device_client;
using Device_capability = Genode::Capability<Platform::Device_interface>;
}
struct Platform::Device_client : Rpc_client<Device_interface>
{
Device_client(Device_capability cap)
: Rpc_client<Device_interface>(cap) { }
Irq_session_capability irq(unsigned id = 0)
{
return call<Rpc_irq>(id);
}
Io_mem_session_capability io_mem(unsigned id, Range &range, Cache cache)
{
return call<Rpc_io_mem>(id, range, cache);
}
Dataspace_capability io_mem_dataspace(unsigned id = 0)
{
Range range { };
return Io_mem_session_client(io_mem(id, range, UNCACHED)).dataspace();
}
};
class Driver : public Genode::List<Driver>::Element
{
private:

View File

@ -11,7 +11,7 @@
* version 2.
*/
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <platform.h>
#include <lx_emul.h>
@ -95,8 +95,11 @@ void lx_platform_device_init()
{
Device::Name name = node.attribute_value("name", Device::Name());
Device::Name type = node.attribute_value("type", Device::Name());
Platform::Device_client device {
resource_env().platform.acquire_device(name.string()) };
using Platform::Device_interface;
Capability<Device_interface> device_cap =
resource_env().platform.acquire_device(name);
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = (char *)kzalloc(64,0);
@ -108,13 +111,17 @@ void lx_platform_device_init()
node.for_each_sub_node("io_mem", [&] (Xml_node node)
{
if (res_count >= MAX_RESOURCES) { return; }
if (res_count >= MAX_RESOURCES)
return;
Device_interface::Range range { };
Io_mem_session_client io_mem_client {
device_cap.call<Device_interface::Rpc_io_mem>(res_count, range, UNCACHED) };
unsigned id = node.attribute_value("id", res_count);
size_t sz = node.attribute_value("size", (size_t)0);
addr_t p_off = node.attribute_value("page_offset", (addr_t)0);
Io_mem & iom = *new (Lx_kit::env().heap())
Io_mem(device.io_mem_dataspace(id), p_off, sz, resource_env().io_mem_list);
Io_mem(io_mem_client.dataspace(), range.start, range.size,
resource_env().io_mem_list);
pdev->resource[res_count++] = { iom.start, iom.start+iom.size-1,
"io_mem", IORESOURCE_MEM };
});
@ -124,11 +131,15 @@ void lx_platform_device_init()
node.for_each_sub_node("irq", [&] (Xml_node node)
{
if (res_count+pdev->num_resources >= MAX_RESOURCES) { return; }
if (res_count+pdev->num_resources >= MAX_RESOURCES)
return;
Irq_session_capability irq_cap =
device_cap.call<Device_interface::Rpc_irq>(res_count);
unsigned id = node.attribute_value("id", res_count);
Irq & irq = *new (Lx_kit::env().heap())
Irq(device.irq(id), resource_env().irq_list);
Irq(irq_cap, resource_env().irq_list);
pdev->resource[pdev->num_resources+res_count++] =
{ irq.nr, irq.nr, "irq", IORESOURCE_IRQ };
});

View File

@ -18,11 +18,11 @@
/* Genode includes */
#include <base/allocator.h>
#include <platform_device/platform_device.h>
#include <irq_session/capability.h>
namespace Lx { class Irq; }
class Lx::Irq
{
public:

View File

@ -150,7 +150,7 @@
<!-- CAUTION: System reset controller access is currently required by
mipi_dsi -->
<device name="src">
<device name="src" type="fsl,imx8mq-src">
<io_mem address="0x30390000" size="0x10000"/>
</device>

View File

@ -1,54 +0,0 @@
/*
* \brief Client-side interface for ARM device
* \author Stefan Kalkowski
* \date 2020-04-15
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__SPEC__ARM__PLATFORM_DEVICE__CLIENT_H_
#define _INCLUDE__SPEC__ARM__PLATFORM_DEVICE__CLIENT_H_
#include <platform_session/platform_session.h>
#include <platform_device/platform_device.h>
#include <base/rpc_client.h>
#include <io_mem_session/client.h>
namespace Platform { struct Device_client; }
struct Platform::Device_client : Genode::Rpc_client<Device>
{
Device_client(Device_capability device)
: Genode::Rpc_client<Device>(device) {}
Genode::Irq_session_capability irq(unsigned id = 0) override
{
return call<Rpc_irq>(id);
}
Genode::Io_mem_session_capability
io_mem(unsigned id = 0, Genode::Cache caching = Genode::Cache::UNCACHED) override
{
return call<Rpc_io_mem>(id, caching);
}
/***************************
** Convenience utilities **
***************************/
Genode::Io_mem_dataspace_capability
io_mem_dataspace(unsigned id = 0, Genode::Cache cache = Genode::Cache::UNCACHED)
{
Genode::Io_mem_session_client session(io_mem(id, cache));
return session.dataspace();
}
};
#endif /* _INCLUDE__SPEC__ARM__PLATFORM_DEVICE__CLIENT_H_ */

View File

@ -1,55 +0,0 @@
/*
* \brief ARM-device interface
* \author Stefan Kalkowski
* \date 2020-04-15
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__SPEC__ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#define _INCLUDE__SPEC__ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#include <base/rpc.h>
#include <base/exception.h>
#include <io_mem_session/capability.h>
#include <irq_session/capability.h>
#include <util/string.h>
namespace Platform { struct Device; }
struct Platform::Device : Genode::Session
{
enum { DEVICE_NAME_LEN = 64 };
using Name = Genode::String<DEVICE_NAME_LEN>;
virtual ~Device() { }
/**
* Get IRQ session capability
*/
virtual Genode::Irq_session_capability irq(unsigned id) = 0;
/**
* Get IO mem session capability of specified resource id
*/
virtual Genode::Io_mem_session_capability io_mem(unsigned id, Genode::Cache) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_irq, Genode::Irq_session_capability, irq, unsigned);
GENODE_RPC(Rpc_io_mem, Genode::Io_mem_session_capability, io_mem,
unsigned, Genode::Cache);
GENODE_RPC_INTERFACE(Rpc_irq, Rpc_io_mem);
};
#endif /* _INCLUDE__SPEC__ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */

View File

@ -15,17 +15,12 @@
#define _INCLUDE__SPEC__ARM__PLATFORM_SESSION__CLIENT_H_
#include <base/rpc_client.h>
#include <platform_device/client.h>
#include <platform_session/capability.h>
namespace Platform {
using namespace Genode;
struct Client;
}
namespace Platform { struct Client; }
struct Platform::Client : public Genode::Rpc_client<Session>
struct Platform::Client : Genode::Rpc_client<Session>
{
Client(Session_capability session)
: Rpc_client<Session>(session) { }
@ -33,10 +28,10 @@ struct Platform::Client : public Genode::Rpc_client<Session>
Rom_session_capability devices_rom() override {
return call<Rpc_devices_rom>(); }
Device_capability acquire_device(String const &device) override {
return call<Rpc_acquire_device>(device); }
Capability<Device_interface> acquire_device(Device_name const &name) override {
return call<Rpc_acquire_device>(name); }
void release_device(Device_capability device) override {
void release_device(Capability<Device_interface> device) override {
call<Rpc_release_device>(device); }
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override {

View File

@ -21,7 +21,11 @@
#include <rom_session/client.h>
#include <util/xml_node.h>
namespace Platform { struct Connection; }
namespace Platform {
struct Device;
struct Connection;
}
class Platform::Connection : public Genode::Connection<Session>,
@ -29,7 +33,9 @@ class Platform::Connection : public Genode::Connection<Session>,
{
private:
Region_map & _rm;
friend class Device; /* 'Device' accesses '_rm' */
Region_map &_rm;
Rom_session_client _rom {devices_rom()};
Constructible<Attached_dataspace> _ds {};
@ -44,24 +50,30 @@ class Platform::Connection : public Genode::Connection<Session>,
public:
Connection(Env &env)
: Genode::Connection<Session>(env, session(env.parent(),
"ram_quota=%u, cap_quota=%u",
RAM_QUOTA, CAP_QUOTA)),
Client(cap()),
_rm(env.rm()) { _try_attach(); }
:
Genode::Connection<Session>(env, session(env.parent(),
"ram_quota=%u, cap_quota=%u",
RAM_QUOTA, CAP_QUOTA)),
Client(cap()),
_rm(env.rm())
{
_try_attach();
}
void update()
{
if (_ds.constructed() && _rom.update() == true) { return; }
if (_ds.constructed() && _rom.update() == true)
return;
_try_attach();
}
void sigh(Signal_context_capability sigh) { _rom.sigh(sigh); }
Device_capability acquire_device(String const &device) override
Capability<Device_interface> acquire_device(Device_name const &name) override
{
return retry_with_upgrade(Ram_quota{6*1024}, Cap_quota{6}, [&] () {
return Client::acquire_device(device); });
return Client::acquire_device(name); });
}
Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache) override
@ -82,15 +94,15 @@ class Platform::Connection : public Genode::Connection<Session>,
warning("Devices rom has invalid XML syntax"); }
}
Device_capability device_by_index(unsigned idx)
Capability<Device_interface> device_by_index(unsigned idx)
{
Device_capability cap;
Capability<Device_interface> cap;
with_xml([&] (Xml_node & xml) {
try {
Xml_node node = xml.sub_node(idx);
Device::Name name = node.attribute_value("name",
Device::Name());
Device_name name = node.attribute_value("name",
Device_name());
cap = acquire_device(name.string());
} catch(Xml_node::Nonexistent_sub_node) {
error(__func__, ": invalid device index ", idx);
@ -101,23 +113,24 @@ class Platform::Connection : public Genode::Connection<Session>,
return cap;
}
Device_capability device_by_type(char const * type)
Capability<Device_interface> device_by_type(char const * type)
{
using String = Genode::String<64>;
Device_capability cap;
Capability<Device_interface> cap;
with_xml([&] (Xml_node & xml) {
xml.for_each_sub_node("device", [&] (Xml_node node) {
/* already found a device? */
if (cap.valid()) { return; }
if (cap.valid())
return;
if (node.attribute_value("type", String()) != type) {
return; }
if (node.attribute_value("type", String()) != type)
return;
Device::Name name = node.attribute_value("name",
Device::Name());
cap = acquire_device(name.string());
Device_name name = node.attribute_value("name", Device_name());
cap = acquire_device(name);
});
if (!cap.valid()) {
error(__func__, ": type=", type, " not found!");

View File

@ -0,0 +1,155 @@
/*
* \brief ARM-device interface
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2020-04-15
*/
/*
* Copyright (C) 2020-2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__SPEC__ARM__PLATFORM_SESSION__DEVICE_H_
#define _INCLUDE__SPEC__ARM__PLATFORM_SESSION__DEVICE_H_
#include <util/mmio.h>
#include <util/string.h>
#include <base/rpc.h>
#include <base/exception.h>
#include <io_mem_session/client.h>
#include <irq_session/client.h>
#include <platform_session/connection.h>
class Platform::Device : Interface, Noncopyable
{
public:
struct Mmio;
struct Irq;
typedef Platform::Session::Device_name Name;
private:
typedef Device_interface::Range Range;
friend class Mmio;
::Platform::Connection &_platform;
Capability<Device_interface> _cap;
Irq_session_capability _irq(unsigned index)
{
return _cap.call<Device_interface::Rpc_irq>(index);
}
Io_mem_session_capability _io_mem(unsigned index, Range &range, Cache cache)
{
return _cap.call<Device_interface::Rpc_io_mem>(index, range, cache);
}
Region_map &_rm() { return _platform._rm; }
public:
struct Index { unsigned value; };
Device(Connection &platform, Index index)
:
_platform(platform), _cap(platform.device_by_index(index.value))
{ }
struct Type { String<64> name; };
Device(Connection &platform, Type type)
:
_platform(platform), _cap(platform.device_by_type(type.name.string()))
{ }
explicit Device(Connection &platform) : Device(platform, Index { 0 }) { }
~Device() { _platform.release_device(_cap); }
};
class Platform::Device::Mmio : Range, Attached_dataspace, public Genode::Mmio
{
private:
Dataspace_capability _ds_cap(Device &device, unsigned id)
{
Io_mem_session_client io_mem(device._io_mem(id, *this, UNCACHED));
return io_mem.dataspace();
}
public:
struct Index { unsigned value; };
Mmio(Device &device, Index index)
:
Attached_dataspace(device._rm(), _ds_cap(device, index.value)),
Genode::Mmio((addr_t)(local_addr<char>() + Range::start))
{ }
explicit Mmio(Device &device) : Mmio(device, Index { 0 }) { }
size_t size() const { return Range::size; }
template <typename T>
T *local_addr()
{
void *ptr = Attached_dataspace::local_addr<char>() + Range::start;
return reinterpret_cast<T *>(ptr);
}
};
class Platform::Device::Irq : Noncopyable
{
private:
Irq_session_client _irq;
public:
struct Index { unsigned value; };
Irq(Device &device, Index index) : _irq(device._irq(index.value)) { }
explicit Irq(Device &device) : Irq(device, Index { 0 }) { }
/**
* Acknowledge interrupt
*
* This method must be called by the interrupt handler.
*/
void ack() { _irq.ack_irq(); }
/**
* Register interrupt signal handler
*
* The call of this method implies a one-time trigger of the interrupt
* handler once the driver component becomes receptive to signals. This
* artificial interrupt signal alleviates the need to place an explicit
* 'Irq::ack' respectively a manual call of the interrupt handler
* routine during the driver initialization.
*
* Furthermore, this artificial interrupt reforces drivers to be robust
* against spurious interrupts.
*/
void sigh(Signal_context_capability sigh)
{
_irq.sigh(sigh);
/* trigger initial interrupt */
if (sigh.valid())
Signal_transmitter(sigh).submit();
}
};
#endif /* _INCLUDE__SPEC__ARM__PLATFORM_SESSION__DEVICE_H_ */

View File

@ -18,19 +18,35 @@
#include <base/rpc_args.h>
#include <base/cache.h>
#include <dataspace/capability.h>
#include <platform_device/capability.h>
#include <platform_device/platform_device.h>
#include <rom_session/capability.h>
#include <irq_session/capability.h>
#include <io_mem_session/capability.h>
#include <session/session.h>
namespace Platform {
using namespace Genode;
struct Device_interface;
struct Session;
}
struct Platform::Device_interface : Interface
{
/**
* Byte-offset range of memory-mapped I/O registers within dataspace
*/
struct Range { addr_t start; size_t size; };
GENODE_RPC(Rpc_irq, Irq_session_capability, irq, unsigned);
GENODE_RPC(Rpc_io_mem, Io_mem_session_capability, io_mem,
unsigned, Range &, Cache);
GENODE_RPC_INTERFACE(Rpc_irq, Rpc_io_mem);
};
struct Platform::Session : Genode::Session
{
/**
@ -42,7 +58,7 @@ struct Platform::Session : Genode::Session
virtual ~Session() { }
using String = Rpc_in_buffer<Device::DEVICE_NAME_LEN>;
typedef String<64> Device_name;
/**
* Request ROM session containing the information about available devices.
@ -52,19 +68,19 @@ struct Platform::Session : Genode::Session
virtual Rom_session_capability devices_rom() = 0;
/**
* Acquire device known by unique 'name'.
* Acquire device known by unique 'name'
*/
virtual Device_capability acquire_device(String const &name) = 0;
virtual Capability<Device_interface> acquire_device(Device_name const &name) = 0;
/**
* Free server-internal data structures representing the device
*
* Use this method to relax the resource-allocation of the Platform session.
*/
virtual void release_device(Device_capability device) = 0;
virtual void release_device(Capability<Device_interface> device) = 0;
/**
* Allocate memory suitable for DMA.
* Allocate memory suitable for DMA
*/
virtual Ram_dataspace_capability alloc_dma_buffer(size_t, Cache) = 0;
@ -84,10 +100,10 @@ struct Platform::Session : Genode::Session
*********************/
GENODE_RPC(Rpc_devices_rom, Rom_session_capability, devices_rom);
GENODE_RPC_THROW(Rpc_acquire_device, Device_capability, acquire_device,
GENODE_RPC_THROW(Rpc_acquire_device, Capability<Device_interface>, acquire_device,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
String const &);
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
Device_name const &);
GENODE_RPC(Rpc_release_device, void, release_device, Capability<Device_interface>);
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
alloc_dma_buffer,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), size_t, Cache);

View File

@ -1 +0,0 @@
#include <spec/arm/platform_device/client.h>

View File

@ -1 +0,0 @@
#include <spec/arm/platform_device/platform_device.h>

View File

@ -0,0 +1 @@
#include <spec/arm/platform_session/device.h>

View File

@ -1,9 +1,7 @@
INCLUDE_SUB_DIRS := platform_session \
platform_device \
spec/arm_64/platform_session \
spec/arm_64/platform_device \
spec/arm/platform_session \
spec/arm/platform_device \
spec/imx53/platform_session \
spec/rpi/platform \
spec/rpi/platform_session \

View File

@ -16,8 +16,7 @@
#include <base/attached_dataspace.h>
#include <base/component.h>
#include <base/log.h>
#include <platform_session/connection.h>
#include <platform_device/client.h>
#include <platform_session/device.h>
#include <timer_session/connection.h>
#include <capture_session/connection.h>
#include <blit/painter.h>
@ -84,15 +83,17 @@ struct Pl11x_driver::Main
* Driver
*/
Platform::Connection _platform { _env };
Platform::Device_client _pl11x_dev { _platform.device_by_type("arm,pl111") };
Platform::Device_client _sp810_dev { _platform.device_by_type("arm,sp810") };
Attached_dataspace _lcd_io_mem { _env.rm(),
_pl11x_dev.io_mem_dataspace() };
Attached_dataspace _sys_mem { _env.rm(),
_sp810_dev.io_mem_dataspace() };
using Type = Platform::Device::Type;
Platform::Connection _platform { _env };
Platform::Device _pl11x_dev { _platform, Type { "arm,pl111" } };
Platform::Device _sp810_dev { _platform, Type { "arm,sp810" } };
Platform::Device::Mmio _lcd_io_mem { _pl11x_dev };
Platform::Device::Mmio _sys_mem { _sp810_dev };
Ram_dataspace_capability _fb_ds_cap {
_platform.alloc_dma_buffer(FRAMEBUFFER_SIZE, UNCACHED) };
Attached_dataspace _fb_ds { _env.rm(), _fb_ds_cap };
void _init_device();

View File

@ -20,12 +20,43 @@
/* Genode includes */
#include <gpio/driver.h>
#include <irq_session/client.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <timer_session/connection.h>
/* local includes */
#include <gpio.h>
namespace Platform { struct Device_client; }
/*
* Transitionally wrapper for accessing platform devices used until
* the migration to Platform::Device::Mmio API is completed.
*/
struct Platform::Device_client : Rpc_client<Device_interface>
{
Device_client(Capability<Device_interface> cap)
: Rpc_client<Device_interface>(cap) { }
Irq_session_capability irq(unsigned id = 0)
{
return call<Rpc_irq>(id);
}
Io_mem_session_capability io_mem(unsigned id, Range &range, Cache cache)
{
return call<Rpc_io_mem>(id, range, cache);
}
Dataspace_capability io_mem_dataspace(unsigned id = 0)
{
Range range { };
return Io_mem_session_client(io_mem(id, range, UNCACHED)).dataspace();
}
};
class Imx_driver : public Gpio::Driver
{
using Pin = Gpio::Pin;

View File

@ -104,7 +104,7 @@ void I2c::Driver::_bus_write(uint8_t data)
while (!_mmio.read<Mmio::Status::Irq>());
_mmio.write<Mmio::Status::Irq>(0);
_irq.ack_irq();
_irq.ack();
if (_mmio.read<Mmio::Status::Rcv_ack>()) {
_bus_stop();
@ -158,7 +158,7 @@ void I2c::Driver::read(uint8_t address, uint8_t *buffer_out, size_t const buffer
}
buffer_out[i] = _mmio.read<Mmio::Data>();
_irq.ack_irq();
_irq.ack();
}
_bus_stop();

View File

@ -50,15 +50,10 @@ class I2c::Driver: public I2c::Driver_base
Env &_env;
Args const _args;
Platform::Connection _platform_connection { _env };
Platform::Device_client _device { _platform_connection.device_by_index(0) };
/* iomem region for I2C control register */
Attached_dataspace _i2c_ctl_ds { _env.rm(), _device.io_mem_dataspace(0) };
I2c::Mmio _mmio { reinterpret_cast<addr_t>(_i2c_ctl_ds.local_addr<uint16_t>()) };
/* interrupt handler */
Irq_session_client _irq { _device.irq() };
Platform::Connection _platform { _env };
Platform::Device _device { _platform };
I2c::Mmio _mmio { _device };
Platform::Device::Irq _irq { _device };
Io_signal_handler<Driver> _irq_handler;
unsigned _sem_cnt = 1;
@ -82,7 +77,7 @@ class I2c::Driver: public I2c::Driver_base
{
_irq.sigh(_irq_handler);
_irq_handle();
_irq.ack_irq();
_irq.ack();
}
void write(uint8_t, uint8_t const *, size_t) override;

View File

@ -15,12 +15,12 @@
#ifndef _I2C_MMIO_H_
#define _I2C_MMIO_H_
#include <util/mmio.h>
#include <platform_session/device.h>
namespace I2c { struct Mmio; }
struct I2c::Mmio: Genode::Mmio
struct I2c::Mmio: Platform::Device::Mmio
{
struct Address : Mmio::Register<0x0, 16> {
struct Adr : Mmio::Register<0x0, 16>::Bitfield<1, 7> {};
@ -49,7 +49,7 @@ struct I2c::Mmio: Genode::Mmio
struct Data : Mmio::Register<0x10, 16> {};
Mmio(Genode::addr_t base) : Genode::Mmio { base } { }
Mmio(Platform::Device &device) : Platform::Device::Mmio { device } { }
};
#endif /* _I2C_MMIO_H_ */

View File

@ -92,11 +92,11 @@ class Lan9118_base
{ }
};
Genode::Attached_dataspace _mmio;
volatile Genode::uint32_t *_reg_base;
Timer::Connection _timer;
Nic::Mac_address _mac_addr { };
Genode::Irq_session_client _irq;
Platform::Device::Mmio &_mmio;
Platform::Device::Irq &_irq;
volatile Genode::uint32_t *_reg_base { _mmio.local_addr<Genode::uint32_t>() };
Timer::Connection _timer;
Nic::Mac_address _mac_addr { };
/**
* Read 32-bit wide MMIO register
@ -249,7 +249,7 @@ class Lan9118_base
/* acknowledge all pending irqs */
_reg_write(INT_STS, ~0);
_irq.ack_irq();
_irq.ack();
}
void _drv_rx_copy_pkt(Genode::size_t size,
@ -279,18 +279,14 @@ class Lan9118_base
*/
class Device_not_supported { };
Lan9118_base(Genode::Io_mem_dataspace_capability ds_cap,
Genode::Irq_session_capability irq_cap,
Genode::Signal_context_capability irq_handler,
Genode::Env & env)
Lan9118_base(Platform::Device::Mmio &mmio,
Platform::Device::Irq &irq,
Genode::Signal_context_capability irq_handler,
Genode::Env &env)
:
_mmio { env.rm(), ds_cap },
_reg_base { _mmio.local_addr<Genode::uint32_t>() },
_timer { env },
_irq { irq_cap }
_mmio(mmio), _irq(irq), _timer(env)
{
_irq.sigh(irq_handler);
_irq.ack_irq();
unsigned long const id_rev = _reg_read(ID_REV),
byte_order = _reg_read(BYTE_TEST);
@ -443,17 +439,17 @@ class Lan9118 : public Nic::Session_component,
*
* \throw Device_not_supported
*/
Lan9118(Genode::Io_mem_dataspace_capability ds_cap,
Genode::Irq_session_capability irq_cap,
Genode::size_t const tx_buf_size,
Genode::size_t const rx_buf_size,
Genode::Allocator & rx_block_md_alloc,
Genode::Env & env)
Lan9118(Platform::Device::Mmio &mmio,
Platform::Device::Irq &irq,
Genode::size_t const tx_buf_size,
Genode::size_t const rx_buf_size,
Genode::Allocator &rx_block_md_alloc,
Genode::Env &env)
:
Session_component { tx_buf_size, rx_buf_size, Genode::UNCACHED,
rx_block_md_alloc, env },
Genode::Signal_handler<Lan9118> { env.ep(), *this, &Lan9118::_handle_irq },
Lan9118_base { ds_cap, irq_cap, *this, env }
Lan9118_base { mmio, irq, *this, env }
{ }
/**************************************
@ -553,13 +549,13 @@ class Genode::Uplink_client : public Signal_handler<Uplink_client>,
public:
Uplink_client(Env &env,
Allocator &alloc,
Io_mem_dataspace_capability ds_cap,
Irq_session_capability irq_cap)
Uplink_client(Env &env,
Allocator &alloc,
Platform::Device::Mmio &mmio,
Platform::Device::Irq &irq)
:
Signal_handler<Uplink_client> { env.ep(), *this, &Uplink_client::_handle_irq },
Lan9118_base { ds_cap, irq_cap, *this, env },
Lan9118_base { mmio, irq, *this, env },
Uplink_client_base { env, alloc, _mac_addr }
{
_drv_handle_link_state(true);

View File

@ -21,7 +21,7 @@
#include <base/env.h>
#include <base/heap.h>
#include <nic/component.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <root/component.h>
/* NIC driver includes */
@ -36,8 +36,10 @@ class Nic_root : public Root_component<Lan9118, Single_client>
{
private:
Env &_env;
Platform::Device_client &_device;
Env &_env;
Platform::Device::Mmio &_mmio;
Platform::Device::Irq &_irq;
/********************
@ -62,19 +64,18 @@ class Nic_root : public Root_component<Lan9118, Single_client>
}
return new (md_alloc())
Lan9118(_device.io_mem_dataspace(), _device.irq(),
tx_buf_size, rx_buf_size, *md_alloc(), _env);
Lan9118(_mmio, _irq, tx_buf_size, rx_buf_size, *md_alloc(), _env);
}
public:
Nic_root(Env &env,
Allocator &md_alloc,
Platform::Device_client &device)
Nic_root(Env &env,
Allocator &md_alloc,
Platform::Device::Mmio &mmio,
Platform::Device::Irq &irq)
:
Root_component<Lan9118, Genode::Single_client> { env.ep(), md_alloc },
_env { env },
_device { device }
_env(env), _mmio(mmio), _irq(irq)
{ }
};
@ -85,7 +86,9 @@ class Main
Env &_env;
Heap _heap { _env.ram(), _env.rm() };
Platform::Connection _platform { _env };
Platform::Device_client _device { _platform.device_by_index(0) };
Platform::Device _device { _platform };
Platform::Device::Mmio _mmio { _device };
Platform::Device::Irq _irq { _device };
Constructible<Nic_root> _nic_root { };
Constructible<Uplink_client> _uplink_client { };
@ -104,14 +107,13 @@ class Main
switch (mode) {
case Nic_driver_mode::NIC_SERVER:
_nic_root.construct(_env, _heap, _device);
_nic_root.construct(_env, _heap, _mmio, _irq);
_env.parent().announce(_env.ep().manage(*_nic_root));
break;
case Nic_driver_mode::UPLINK_CLIENT:
_uplink_client.construct(
_env, _heap, _device.io_mem_dataspace(), _device.irq());
_uplink_client.construct(_env, _heap, _mmio, _irq);
break;
}

View File

@ -22,6 +22,7 @@
/* local includes */
#include "component.h"
#include "platform_device.h"
namespace Virtio_mmio_nic {
using namespace Genode;

View File

@ -0,0 +1,45 @@
/*
* \brief Client stub for Platform::Device client
* \author Norman Feske
* \date 2021-04-15
*
* The 'Device_client' is a mere compatibilty wrapper used until the
* driver has been coverted to the 'Platform::Device::Mmio' API.
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _PLATFORM_DEVICE_H_
#define _PLATFORM_DEVICE_H_
namespace Platform { struct Device_client; }
struct Platform::Device_client : Rpc_client<Device_interface>
{
Device_client(Capability<Device_interface> cap)
: Rpc_client<Device_interface>(cap) { }
Irq_session_capability irq(unsigned id = 0)
{
return call<Rpc_irq>(id);
}
Io_mem_session_capability io_mem(unsigned id, Range &range, Cache cache)
{
return call<Rpc_io_mem>(id, range, cache);
}
Io_mem_dataspace_capability io_mem_dataspace(unsigned id = 0)
{
Range range { };
return Io_mem_session_client(io_mem(id, range, UNCACHED)).dataspace();
}
};
#endif /* _PLATFORM_DEVICE_H_ */

View File

@ -96,7 +96,7 @@ Genode::Irq_session_capability Driver::Device::irq(unsigned idx,
Genode::Io_mem_session_capability
Driver::Device::io_mem(unsigned idx, Cache cache, Session_component & sc)
Driver::Device::io_mem(unsigned idx, Range &range, Cache cache, Session_component & sc)
{
Io_mem_session_capability cap;
@ -107,6 +107,9 @@ Driver::Device::io_mem(unsigned idx, Cache cache, Session_component & sc)
{
if (i++ != idx) return;
range = Range { .start = io_mem.base & 0xfff,
.size = io_mem.size };
if (!io_mem.io_mem) {
io_mem.io_mem = new (sc.heap())
Io_mem_connection(sc.env().env, io_mem.base, io_mem.size,

View File

@ -17,13 +17,14 @@
#include <base/allocator.h>
#include <io_mem_session/connection.h>
#include <irq_session/connection.h>
#include <platform_session/platform_session.h>
#include <platform_session/device.h>
#include <util/list.h>
#include <util/list_model.h>
#include <util/reconstructible.h>
#include <util/xml_generator.h>
namespace Driver {
using namespace Genode;
class Env;
@ -70,8 +71,9 @@ class Driver::Device : private List_model<Device>::Element
: name(name), value(value) {}
};
using Name = Genode::String<64>;
using Type = Genode::String<64>;
using Name = Genode::String<64>;
using Type = Genode::String<64>;
using Range = Platform::Device_interface::Range;
Device(Name name, Type type);
virtual ~Device();
@ -82,10 +84,9 @@ class Driver::Device : private List_model<Device>::Element
virtual bool acquire(Session_component &);
virtual void release(Session_component &);
Irq_session_capability irq(unsigned idx,
Session_component & session);
Io_mem_session_capability io_mem(unsigned idx, Cache,
Session_component & session);
Irq_session_capability irq(unsigned idx, Session_component &);
Io_mem_session_capability io_mem(unsigned idx, Range &, Cache,
Session_component &);
void report(Xml_generator &, Session_component &);

View File

@ -41,12 +41,12 @@ void Driver::Device_component::release()
Genode::Io_mem_session_capability
Device_component::io_mem(unsigned idx, Cache cache)
Device_component::io_mem(unsigned idx, Range &range, Cache cache)
{
Io_mem_session_capability cap;
_session.env().devices.for_each([&] (Driver::Device & device) {
if (device.name() == _device) {
cap = device.io_mem(idx, cache, _session); }});
cap = device.io_mem(idx, range, cache, _session); }});
return cap;
}

View File

@ -16,7 +16,7 @@
#include <base/rpc_server.h>
#include <platform_session/platform_session.h>
#include <platform_device/platform_device.h>
#include <platform_session/device.h>
#include <env.h>
#include <device.h>
@ -27,7 +27,8 @@ namespace Driver {
}
class Driver::Device_component : public Rpc_object<Platform::Device>
class Driver::Device_component : public Rpc_object<Platform::Device_interface,
Device_component>
{
public:
@ -44,21 +45,21 @@ class Driver::Device_component : public Rpc_object<Platform::Device>
void report(Xml_generator&);
/**************************
** Platform::Device API **
**************************/
/************************************
** Platform::Device RPC functions **
************************************/
Irq_session_capability irq(unsigned) override;
Io_mem_session_capability io_mem(unsigned, Cache) override;
Irq_session_capability irq(unsigned);
Io_mem_session_capability io_mem(unsigned, Range &, Cache);
private:
friend class Session_component;
Session_component & _session;
Driver::Device::Name const _device;
Platform::Device_capability _cap {};
List_element<Device_component> _list_elem { this };
Session_component & _session;
Driver::Device::Name const _device;
Capability<Platform::Device> _cap {};
List_element<Device_component> _list_elem { this };
/*
* Noncopyable

View File

@ -74,8 +74,8 @@ Genode::Rom_session_capability Session_component::devices_rom() {
return _rom_session.cap(); }
Platform::Device_capability
Session_component::acquire_device(Platform::Session::String const &name)
Genode::Capability<Platform::Device_interface>
Session_component::acquire_device(Platform::Session::Device_name const &name)
{
for (Device_list_element * e = _device_list.first(); e; e = e->next()) {
if (e->object()->device() != name.string()) { continue; }
@ -92,11 +92,11 @@ Session_component::acquire_device(Platform::Session::String const &name)
return _env.env.ep().rpc_ep().manage(e->object());
}
return Platform::Device_capability();
return Capability<Platform::Device_interface>();
}
void Session_component::release_device(Platform::Device_capability device_cap)
void Session_component::release_device(Capability<Platform::Device_interface> device_cap)
{
_env.env.ep().rpc_ep().apply(device_cap, [&] (Device_component * dc) {
_env.env.ep().rpc_ep().dissolve(dc);

View File

@ -31,7 +31,8 @@ namespace Driver {
}
class Driver::Session_component :
class Driver::Session_component
:
public Session_object<Platform::Session>,
private Registry<Driver::Session_component>::Element,
private Dynamic_rom_session::Xml_producer
@ -63,11 +64,11 @@ class Driver::Session_component :
** Platform Session API **
**************************/
using Device_capability = Platform::Device_capability;
using String = Platform::Session::String;
using Device_capability = Capability<Platform::Device_interface>;
using Device_name = Platform::Session::Device_name;
Rom_session_capability devices_rom() override;
Device_capability acquire_device(String const &) override;
Device_capability acquire_device(Device_name const &) override;
void release_device(Device_capability) override;
Ram_dataspace_capability alloc_dma_buffer(size_t, Cache) override;
void free_dma_buffer(Ram_dataspace_capability ram_cap) override;

View File

@ -14,42 +14,67 @@
/* Genode includes */
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <timer_session/connection.h>
#include <event_session/connection.h>
/* local includes */
#include "ps2_keyboard.h"
#include "ps2_mouse.h"
#include "irq_handler.h"
#include "pl050.h"
#include "led_state.h"
namespace Ps2 { struct Main; }
namespace Ps2 {
using namespace Genode;
struct Main;
}
struct Ps2::Main
{
using Device = Platform::Device_client;
Env & _env;
Genode::Env & _env;
Platform::Connection _platform { _env };
Device _device_0 { _platform.device_by_index(0) };
Device _device_1 { _platform.device_by_index(1) };
Pl050 _pl050 { _env, _device_0.io_mem_dataspace(),
_device_1.io_mem_dataspace() };
using Device = Platform::Device;
Event::Connection _event { _env };
Timer::Connection _timer { _env };
Genode::Attached_rom_dataspace _config { _env, "config" };
Genode::Reconstructible<Verbose> _verbose { _config.xml() };
Device _device_keyboard { _platform, Device::Index { 0 } };
Device _device_mouse { _platform, Device::Index { 1 } };
Device::Mmio _mmio_keyboard { _device_keyboard };
Device::Mmio _mmio_mouse { _device_mouse };
Device::Irq _irq_keyboard { _device_keyboard };
Device::Irq _irq_mouse { _device_mouse };
Pl050 _pl050 { _mmio_keyboard, _mmio_mouse };
Event::Connection _event { _env };
Timer::Connection _timer { _env };
Attached_rom_dataspace _config { _env, "config" };
Reconstructible<Verbose> _verbose { _config.xml() };
Mouse _mouse { _pl050.aux_interface(), _timer, *_verbose };
Keyboard _keyboard { _pl050.kbd_interface(), false, *_verbose };
Irq_handler _mouse_irq { _env.ep(), _mouse, _event, _device_1.irq() };
Irq_handler _keyboard_irq { _env.ep(), _keyboard, _event, _device_0.irq() };
void _handle_irq_common()
{
_event.with_batch([&] (Event::Session_client::Batch &batch) {
while (_mouse .event_pending()) _mouse .handle_event(batch);
while (_keyboard.event_pending()) _keyboard.handle_event(batch);
});
}
void _handle_irq_keyboard() { _irq_keyboard.ack(); _handle_irq_common(); }
void _handle_irq_mouse() { _irq_mouse .ack(); _handle_irq_common(); }
Signal_handler<Main> _keyboard_irq_handler {
_env.ep(), *this, &Main::_handle_irq_keyboard };
Signal_handler<Main> _mouse_irq_handler {
_env.ep(), *this, &Main::_handle_irq_mouse };
Led_state _capslock { _env, "capslock" },
_numlock { _env, "numlock" },
@ -59,7 +84,7 @@ struct Ps2::Main
{
_config.update();
Genode::Xml_node config = _config.xml();
Xml_node config = _config.xml();
_verbose.construct(config);
@ -72,13 +97,16 @@ struct Ps2::Main
_keyboard.led_enabled(Keyboard::SCRLOCK_LED, _scrlock .enabled());
}
Genode::Signal_handler<Main> _config_handler {
Signal_handler<Main> _config_handler {
_env.ep(), *this, &Main::_handle_config };
Main(Genode::Env &env) : _env(env)
Main(Env &env) : _env(env)
{
_config.sigh(_config_handler);
_handle_config();
_irq_keyboard.sigh(_keyboard_irq_handler);
_irq_mouse .sigh(_mouse_irq_handler);
}
};

View File

@ -67,9 +67,7 @@ class Pl050
_Channel(_Channel const &);
_Channel &operator = (_Channel const &);
Genode::Mutex _mutex { };
Genode::Attached_dataspace _io_mem_ds;
volatile Genode::uint32_t * _reg_base;
volatile Genode::uint32_t * _reg_base;
/**
* Return true if input is available
@ -79,11 +77,9 @@ class Pl050
public:
_Channel(Genode::Env & env,
Genode::Io_mem_dataspace_capability cap)
_Channel(Platform::Device::Mmio &mmio)
:
_io_mem_ds(env.rm(), cap),
_reg_base(_io_mem_ds.local_addr<Genode::uint32_t>())
_reg_base(mmio.local_addr<Genode::uint32_t>())
{ }
/**
@ -91,8 +87,6 @@ class Pl050
*/
unsigned char read() override
{
Genode::Mutex::Guard guard(_mutex);
while (empty())
if (_input_pending())
add(_reg_base[PL050_REG_DATA]);
@ -103,6 +97,7 @@ class Pl050
void write(unsigned char value) override
{
while (!(_reg_base[PL050_REG_STATUS] & PL050_STATUS_TX_EMPTY));
_reg_base[PL050_REG_DATA] = value;
}
@ -124,11 +119,10 @@ class Pl050
public:
Pl050(Genode::Env & env,
Genode::Io_mem_dataspace_capability keyb_cap,
Genode::Io_mem_dataspace_capability mouse_cap) :
_kbd(env, keyb_cap),
_aux(env, mouse_cap)
Pl050(Platform::Device::Mmio &keyboard_mmio,
Platform::Device::Mmio &mouse_mmio)
:
_kbd(keyboard_mmio), _aux(mouse_mmio)
{
_kbd.enable_irq();
_aux.enable_irq();

View File

@ -92,7 +92,7 @@ int Driver::_stop_transmission()
void Driver::_handle_irq()
{
_irq.ack_irq();
_irq.ack();
/* the handler is only for block transfers, on other commands we poll */
if (!_block_transfer.pending) {
@ -284,7 +284,6 @@ Card_info Driver::_init()
{
/* install IRQ signal */
_irq.sigh(_irq_handler);
_irq.ack_irq();
/* configure host for initialization stage */
if (_reset()) {
@ -522,17 +521,16 @@ void Driver::_clock(Clock clock)
Driver::Driver(Env & env, Platform::Connection & platform)
: Driver_base(env.ram()),
Platform::Device_client(platform.device_by_index(0)),
Attached_dataspace(env.rm(), Device_client::io_mem_dataspace()),
Mmio((addr_t)local_addr<void>()),
_env(env),
_platform(platform),
_irq(Device_client::irq())
:
Driver_base(env.ram()),
Platform::Device(platform),
Platform::Device::Mmio(*static_cast<Platform::Device *>(this)),
_env(env),
_platform(platform)
{
log("SD card detected");
log("capacity: ", card_info().capacity_mb(), " MiB");
}
Driver::~Driver() { _platform.release_device(rpc_cap()); }
Driver::~Driver() { }

View File

@ -15,11 +15,8 @@
#define _SRC__DRIVERS__SD_CARD__SPEC__IMX__DRIVER_H_
/* Genode includes */
#include <base/attached_dataspace.h>
#include <irq_session/client.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <timer_session/connection.h>
#include <util/mmio.h>
/* local includes */
#include <driver_base.h>
@ -29,9 +26,8 @@ namespace Sd_card { class Driver; }
class Sd_card::Driver : public Driver_base,
private Platform::Device_client,
private Attached_dataspace,
private Mmio
private Platform::Device,
private Platform::Device::Mmio
{
private:
@ -222,7 +218,7 @@ class Sd_card::Driver : public Driver_base,
Timer_delayer _delayer { _env };
Signal_handler<Driver> _irq_handler { _env.ep(), *this,
&Driver::_handle_irq };
Irq_session_client _irq;
Platform::Device::Irq _irq { *this };
Card_info _card_info { _init() };
Adma2::Table _adma2_table { _env.ram(), _env.rm() };

View File

@ -139,12 +139,12 @@ void Driver::_write_data(unsigned length,
Driver::Driver(Env &env, Platform::Connection & platform)
: Block::Driver(env.ram()),
Platform::Device_client(platform.device_by_index(0)),
Attached_dataspace(env.rm(), Device_client::io_mem_dataspace()),
Mmio((addr_t)local_addr<void>()),
_platform(platform),
_timer(env)
:
Block::Driver(env.ram()),
Platform::Device(platform, Platform::Device::Index { 0 }),
Platform::Device::Mmio(*this, Platform::Device::Mmio::Index { 0 }),
_platform(platform),
_timer(env)
{
enum { POWER_UP = 2, POWER_ON = 3 };
@ -190,8 +190,7 @@ Driver::Driver(Env &env, Platform::Connection & platform)
}
Driver::~Driver() {
_platform.release_device(Platform::Device_client::rpc_cap()); }
Driver::~Driver() { }
void Driver::read(Block::sector_t block_number,

View File

@ -16,11 +16,9 @@
#define _DRIVER_H_
/* local includes */
#include <base/attached_dataspace.h>
#include <block/driver.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <timer_session/connection.h>
#include <util/mmio.h>
namespace Sd_card {
@ -31,9 +29,8 @@ namespace Sd_card {
class Sd_card::Driver : public Block::Driver,
private Platform::Device_client,
private Attached_dataspace,
private Mmio
private Platform::Device,
private Platform::Device::Mmio
{
private:
@ -121,6 +118,19 @@ class Sd_card::Driver : public Block::Driver,
size_t const _block_size = 512;
Block::sector_t const _block_count = 0x20000000 / _block_size;
Dataspace_capability _io_mem_ds(Platform::Connection &platform)
{
using Device = Platform::Device_interface;
Capability<Device> device_cap = platform.device_by_index(0);
Device::Range range { };
Io_mem_session_client io_mem {
device_cap.call<Device::Rpc_io_mem>(1, range, UNCACHED) };
return io_mem.dataspace();
}
public:
Driver(Env &env, Platform::Connection & platform);

View File

@ -22,20 +22,19 @@ using namespace Sd_card;
Driver::Driver(Env & env, Platform::Connection & platform)
: Driver_base(env.ram()),
Platform::Device_client(platform.device_by_index(0)),
Attached_dataspace(env.rm(), Device_client::io_mem_dataspace()),
Mmio((addr_t)local_addr<void>()),
_env(env),
_platform(platform),
_irq(Device_client::irq())
:
Driver_base(env.ram()),
Platform::Device(platform),
Platform::Device::Mmio(*static_cast<Platform::Device *>(this)),
_env(env),
_platform(platform)
{
log("SD card detected");
log("capacity: ", _card_info.capacity_mb(), " MiB");
}
Driver::~Driver() { _platform.release_device(rpc_cap()); }
Driver::~Driver() { }
void Driver::_set_and_enable_clock(unsigned divider)

View File

@ -17,11 +17,8 @@
#define _DRIVER_H_
/* Genode includes */
#include <base/attached_dataspace.h>
#include <irq_session/client.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <timer_session/connection.h>
#include <util/mmio.h>
/* local includes */
#include <driver_base.h>
@ -30,9 +27,8 @@ namespace Sd_card { class Driver; }
class Sd_card::Driver : public Driver_base,
private Platform::Device_client,
private Attached_dataspace,
private Mmio
private Platform::Device,
private Platform::Device::Mmio
{
private:
@ -161,7 +157,7 @@ class Sd_card::Driver : public Driver_base,
Env & _env;
Platform::Connection & _platform;
Timer_delayer _delayer { _env };
Irq_session_client _irq;
Platform::Device::Irq _irq { *this };
Card_info _card_info { _init() };
template <typename REG>

View File

@ -18,12 +18,47 @@
#include <event_session/connection.h>
#include <gpio_session/connection.h>
#include <platform_session/connection.h>
#include <platform_session/device.h>
#include <i2c.h>
using namespace Genode;
namespace Platform {
using Device_capability = Capability<Device_interface>;
struct Device_client;
}
/*
* Transitionally wrapper for accessing platform devices used until
* the migration to Platform::Device::Mmio API is completed.
*/
struct Platform::Device_client : Rpc_client<Device_interface>
{
Device_client(Capability<Device_interface> cap)
: Rpc_client<Device_interface>(cap) { }
Irq_session_capability irq(unsigned id = 0)
{
return call<Rpc_irq>(id);
}
Io_mem_session_capability io_mem(unsigned id, Range &range, Cache cache)
{
return call<Rpc_io_mem>(id, range, cache);
}
Dataspace_capability io_mem_dataspace(unsigned id = 0)
{
Range range { };
return Io_mem_session_client(io_mem(id, range, UNCACHED)).dataspace();
}
};
struct Finger_data
{
uint8_t status;