mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
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:
parent
d1cf9c86b8
commit
dc8c899c1d
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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 };
|
||||
});
|
||||
|
@ -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:
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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_ */
|
@ -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_ */
|
@ -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 {
|
||||
|
@ -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!");
|
||||
|
155
repos/os/include/spec/arm/platform_session/device.h
Normal file
155
repos/os/include/spec/arm/platform_session/device.h
Normal 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_ */
|
@ -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);
|
||||
|
@ -1 +0,0 @@
|
||||
#include <spec/arm/platform_device/client.h>
|
@ -1 +0,0 @@
|
||||
#include <spec/arm/platform_device/platform_device.h>
|
1
repos/os/include/spec/arm_64/platform_session/device.h
Normal file
1
repos/os/include/spec/arm_64/platform_session/device.h
Normal file
@ -0,0 +1 @@
|
||||
#include <spec/arm/platform_session/device.h>
|
@ -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 \
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
/* local includes */
|
||||
#include "component.h"
|
||||
#include "platform_device.h"
|
||||
|
||||
namespace Virtio_mmio_nic {
|
||||
using namespace Genode;
|
||||
|
45
repos/os/src/drivers/nic/virtio/platform_device.h
Normal file
45
repos/os/src/drivers/nic/virtio/platform_device.h
Normal 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_ */
|
@ -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,
|
||||
|
@ -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 &);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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() { }
|
||||
|
@ -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() };
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user