dde_linux: decouple Lx_kit::Irq and Platform::Device

The Lx_kit::Irq abstraction of DDE Linux was always using the very first
interrupt of a Platform::Device stored in it. Instead of handing over the
platform device it is much more flexible and sane to hand over the actual
interrupt capability.

Ref #3865
This commit is contained in:
Stefan Kalkowski 2020-08-21 13:57:30 +02:00 committed by Norman Feske
parent 73d3698e2f
commit e223be32ce
14 changed files with 59 additions and 379 deletions

View File

@ -1,81 +0,0 @@
/*
* \brief Platform_device implementation for ARM
* \author Sebastian Sumpf
* \date 2016-04-25
*
* Note: Throw away when there exists a plaform device implementation for ARM
* in generic code
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#define _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#include <lx_emul/extern_c_begin.h>
#include <lx_emul/printf.h>
#include <lx_emul/extern_c_end.h>
#include <lx_kit/malloc.h>
#include <platform_device/device.h>
#include <irq_session/connection.h>
#include <util/list.h>
#include <util/reconstructible.h>
namespace Platform { struct Device; }
struct Platform::Device : Platform::Abstract_device, Genode::List<Device>::Element
{
Genode::Env &env;
unsigned irq_num;
Genode::Constructible<Genode::Irq_connection> irq_connection;
Device(Genode::Env &env, unsigned irq) : env(env), irq_num(irq) { }
unsigned vendor_id() { return ~0U; }
unsigned device_id() { return ~0U; }
Genode::Irq_session_capability irq(Genode::uint8_t) override
{
irq_connection.construct(env, irq_num);
return irq_connection->cap();
}
Genode::Io_mem_session_capability io_mem(Genode::uint8_t,
Genode::Cache_attribute,
Genode::addr_t, Genode::size_t) override
{
lx_printf("%s: not implemented\n", __PRETTY_FUNCTION__);
return Genode::Io_mem_session_capability();
}
static Genode::List<Device> &list()
{
static Genode::List<Device> l;
return l;
}
static Device &create(Genode::Env &env, unsigned irq_num)
{
Device *d;
for (d = list().first(); d; d = d->next())
if (d->irq_num == irq_num)
return *d;
d = new (Lx::Malloc::mem()) Device(env, irq_num);
list().insert(d);
return *d;
}
};
#endif /* _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */

View File

@ -15,6 +15,7 @@
/* Genode includes */
#include <base/attached_io_mem_dataspace.h>
#include <irq_session/connection.h>
/* local includes */
#include <driver.h>
@ -564,8 +565,10 @@ void irq_set_chained_handler_and_data(unsigned int irq,
irqsteer_irq_desc.irq_data.chip = irqsteer_chip;
irqsteer_irq_desc.handle_irq = handle;
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq),
irq, irqsteer_irq_handler, nullptr, nullptr);
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq,
irqsteer_irq_handler, nullptr, nullptr);
}
@ -583,8 +586,9 @@ int devm_request_threaded_irq(struct device *dev, unsigned int irq,
return -1;
}
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq),
irq, handler, dev_id, thread_fn);
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id, thread_fn);
return 0;
}
@ -885,9 +889,11 @@ int devm_request_irq(struct device *dev, unsigned int irq,
irqsteer_handler[irq] = handler;
irqsteer_dev_id[irq] = dev_id;
enable_irq(irq);
} else
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq),
irq, handler, dev_id);
} else {
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id);
}
return 0;
}

View File

@ -166,7 +166,7 @@ void Framebuffer::Driver::finish_initialization()
void Framebuffer::Driver::_poll()
{
Lx::Pci_dev * pci_dev = (Lx::Pci_dev*) lx_drm_device->pdev->bus;
Lx::Irq::irq().inject_irq(pci_dev->client());
Lx::Irq::irq().inject_irq(pci_dev->irq);
}
@ -1095,7 +1095,7 @@ int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
{
struct drm_device * drm_dev = (struct drm_device*) dev;
Lx::Pci_dev * pci_dev = (Lx::Pci_dev*) drm_dev->pdev->bus;
Lx::Irq::irq().request_irq(pci_dev->client(), irq, handler, dev);
Lx::Irq::irq().request_irq(pci_dev->client().irq(0), irq, handler, dev);
return 0;
}

View File

@ -20,7 +20,7 @@
#include <base/env.h>
#include <base/snprintf.h>
#include <gpio_session/connection.h>
#include <irq_session/client.h>
#include <irq_session/connection.h>
#include <component.h>
#include <lx_emul.h>
@ -586,7 +586,9 @@ int platform_get_irq(struct platform_device * d, unsigned int i)
int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)
{
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq), irq, handler, dev_id);
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id);
return 0;
}

View File

@ -1,81 +0,0 @@
/*
* \brief Platform_device implementation for ARM
* \author Sebastian Sumpf
* \date 2016-04-25
*
* Note: Throw away when there exists a plaform device implementation for ARM
* in generic code
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#define _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#include <lx_emul/extern_c_begin.h>
#include <lx_emul/printf.h>
#include <lx_emul/extern_c_end.h>
#include <lx_kit/malloc.h>
#include <platform_device/device.h>
#include <irq_session/connection.h>
#include <util/list.h>
#include <util/reconstructible.h>
namespace Platform { struct Device; }
struct Platform::Device : Platform::Abstract_device, Genode::List<Device>::Element
{
Genode::Env &env;
unsigned irq_num;
Genode::Constructible<Genode::Irq_connection> irq_connection;
Device(Genode::Env &env, unsigned irq) : env(env), irq_num(irq) { }
unsigned vendor_id() { return ~0U; }
unsigned device_id() { return ~0U; }
Genode::Irq_session_capability irq(Genode::uint8_t) override
{
irq_connection.construct(env, irq_num);
return irq_connection->cap();
}
Genode::Io_mem_session_capability io_mem(Genode::uint8_t,
Genode::Cache_attribute,
Genode::addr_t, Genode::size_t) override
{
lx_printf("%s: not implemented\n", __PRETTY_FUNCTION__);
return Genode::Io_mem_session_capability();
}
static Genode::List<Device> &list()
{
static Genode::List<Device> l;
return l;
}
static Device &create(Genode::Env &env, unsigned irq_num)
{
Device *d;
for (d = list().first(); d; d = d->next())
if (d->irq_num == irq_num)
return *d;
d = new (Lx::Malloc::mem()) Device(env, irq_num);
list().insert(d);
return *d;
}
};
#endif /* _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */

View File

@ -1,81 +0,0 @@
/*
* \brief Platform_device implementation for ARM
* \author Sebastian Sumpf
* \date 2016-04-25
*
* Note: Throw away when there exists a plaform device implementation for ARM
* in generic code
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#define _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#include <lx_emul/extern_c_begin.h>
#include <lx_emul/printf.h>
#include <lx_emul/extern_c_end.h>
#include <lx_kit/malloc.h>
#include <platform_device/device.h>
#include <irq_session/connection.h>
#include <util/list.h>
#include <util/reconstructible.h>
namespace Platform { struct Device; }
struct Platform::Device : Platform::Abstract_device, Genode::List<Device>::Element
{
Genode::Env &env;
unsigned irq_num;
Genode::Constructible<Genode::Irq_connection> irq_connection;
Device(Genode::Env &env, unsigned irq) : env(env), irq_num(irq) { }
unsigned vendor_id() { return ~0U; }
unsigned device_id() { return ~0U; }
Genode::Irq_session_capability irq(Genode::uint8_t) override
{
irq_connection.construct(env, irq_num);
return irq_connection->cap();
}
Genode::Io_mem_session_capability io_mem(Genode::uint8_t,
Genode::Cache_attribute,
Genode::addr_t, Genode::size_t) override
{
lx_printf("%s: not implemented\n", __PRETTY_FUNCTION__);
return Genode::Io_mem_session_capability();
}
static Genode::List<Device> &list()
{
static Genode::List<Device> l;
return l;
}
static Device &create(Genode::Env &env, unsigned irq_num)
{
Device *d;
for (d = list().first(); d; d = d->next())
if (d->irq_num == irq_num)
return *d;
d = new (Lx::Malloc::mem()) Device(env, irq_num);
list().insert(d);
return *d;
}
};
#endif /* _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */

View File

@ -11,8 +11,10 @@
* version 2.
*/
#include <lx_emul/irq.h>
#include <base/env.h>
#include <irq_session/connection.h>
#include <lx_emul/irq.h>
#include <lx_kit/backend_alloc.h>
#include <lx_kit/env.h>
#include <lx_kit/irq.h>
@ -45,7 +47,9 @@ void Lx::backend_free(Genode::Ram_dataspace_capability cap) {
extern "C" int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq), irq, handler, dev);
Genode::Irq_connection * irq_con = new (Lx_kit::env().heap())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev);
return 0;
}

View File

@ -186,7 +186,7 @@ int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
{
for (Lx::Pci_dev *pci_dev = Lx::pci_dev_registry()->first(); pci_dev; pci_dev = pci_dev->next())
if (pci_dev->irq == irq) {
Lx::Irq::irq().request_irq(pci_dev->client(), irq, handler, dev);
Lx::Irq::irq().request_irq(pci_dev->client().irq(0), irq, handler, dev);
return 0;
}

View File

@ -12,6 +12,7 @@
*/
#include <base/attached_io_mem_dataspace.h>
#include <irq_session/connection.h>
#include <base/env.h>
#include <lx_emul.h>
@ -19,6 +20,7 @@
#include <lx_kit/backend_alloc.h>
#include <lx_kit/env.h>
#include <lx_kit/irq.h>
#include <lx_kit/malloc.h>
/****************************
@ -48,7 +50,10 @@ void Lx::backend_free(Genode::Ram_dataspace_capability cap) {
extern "C" int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq), irq, handler, dev);
Genode::Irq_connection * irq_con =
new(Lx::Malloc::mem())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev);
return 0;
}
@ -56,7 +61,10 @@ extern "C" int request_irq(unsigned int irq, irq_handler_t handler, unsigned lon
int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)
{
Lx::Irq::irq().request_irq(Platform::Device::create(Lx_kit::env().env(), irq), irq, handler, dev_id);
Genode::Irq_connection * irq_con =
new(Lx::Malloc::mem())
Genode::Irq_connection(Lx_kit::env().env(), irq);
Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id);
return 0;
}

View File

@ -1,81 +0,0 @@
/*
* \brief Platform_device implementation for ARM
* \author Sebastian Sumpf
* \date 2016-04-25
*
* Note: Throw away when there exists a plaform device implementation for ARM
* in generic code
*/
/*
* Copyright (C) 2016-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#define _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#include <lx_emul/extern_c_begin.h>
#include <lx_emul/printf.h>
#include <lx_emul/extern_c_end.h>
#include <lx_kit/malloc.h>
#include <platform_device/device.h>
#include <irq_session/connection.h>
#include <util/list.h>
#include <util/reconstructible.h>
namespace Platform { struct Device; }
struct Platform::Device : Platform::Abstract_device, Genode::List<Device>::Element
{
Genode::Env &env;
unsigned irq_num;
Genode::Constructible<Genode::Irq_connection> irq_connection;
Device(Genode::Env &env, unsigned irq) : env(env), irq_num(irq) { }
unsigned vendor_id() { return ~0U; }
unsigned device_id() { return ~0U; }
Genode::Irq_session_capability irq(Genode::uint8_t) override
{
irq_connection.construct(env, irq_num);
return irq_connection->cap();
}
Genode::Io_mem_session_capability io_mem(Genode::uint8_t,
Genode::Cache_attribute,
Genode::addr_t, Genode::size_t) override
{
lx_printf("%s: not implemented\n", __PRETTY_FUNCTION__);
return Genode::Io_mem_session_capability();
}
static Genode::List<Device> &list()
{
static Genode::List<Device> l;
return l;
}
static Device &create(Genode::Env &env, unsigned irq_num)
{
Device *d;
for (d = list().first(); d; d = d->next())
if (d->irq_num == irq_num)
return *d;
d = new (Lx::Malloc::mem()) Device(env, irq_num);
list().insert(d);
return *d;
}
};
#endif /* _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */

View File

@ -188,12 +188,10 @@ int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
{
for (Lx::Pci_dev *pci_dev = Lx::pci_dev_registry()->first(); pci_dev; pci_dev = pci_dev->next())
if (pci_dev->irq == irq) {
{
Genode::Irq_session_client is(pci_dev->client().irq(0));
if ((is.info().type != Genode::Irq_session::Info::MSI)
&& !flags) return 1;
}
Lx::Irq::irq().request_irq(pci_dev->client(), irq, handler, dev);
Genode::Irq_session_client is(pci_dev->client().irq(0));
if ((is.info().type != Genode::Irq_session::Info::MSI)
&& !flags) return 1;
Lx::Irq::irq().request_irq(is.rpc_cap(), irq, handler, dev);
return 0;
}

View File

@ -32,11 +32,12 @@ class Lx::Irq
/**
* Request an IRQ
*/
virtual void request_irq(Platform::Device &dev, unsigned int irq,
virtual void request_irq(Genode::Irq_session_capability cap,
unsigned int irq,
irq_handler_t handler, void *dev_id,
irq_handler_t thread_fn = 0) = 0;
virtual void inject_irq(Platform::Device &dev) = 0;
virtual void inject_irq(unsigned int irq) = 0;
/**
* Disable an IRQ

View File

@ -1333,7 +1333,7 @@ int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev)
{
Lx::Pci_dev *pci_dev = Lx::pci_dev_registry()->first();
Lx::Irq::irq().request_irq(pci_dev->client(), irq, handler, dev);
Lx::Irq::irq().request_irq(pci_dev->client().irq(0), irq, handler, dev);
return 0;
}
@ -1344,7 +1344,7 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
void *dev)
{
Lx::Pci_dev *pci_dev = Lx::pci_dev_registry()->first();
Lx::Irq::irq().request_irq(pci_dev->client(), irq, handler, dev, thread_fn);
Lx::Irq::irq().request_irq(pci_dev->client().irq(0), irq, handler, dev, thread_fn);
return 0;
}

View File

@ -41,12 +41,10 @@ class Lx_kit::Irq : public Lx::Irq
{
char name[16];
Name_composer(Platform::Device &device)
Name_composer(unsigned number)
{
Genode::snprintf(name, sizeof(name),
"irq_%02x:%02x",
device.vendor_id(),
device.device_id());
"irq_%02x", number);
}
};
@ -99,7 +97,6 @@ class Lx_kit::Irq : public Lx::Irq
private:
Name_composer _name;
Platform::Device &_dev;
unsigned int _irq;
Genode::Irq_session_client _irq_sess;
Lx_kit::List<Handler> _handler;
@ -125,13 +122,12 @@ class Lx_kit::Irq : public Lx::Irq
* Constructor
*/
Context(Genode::Entrypoint &ep,
Platform::Device &dev,
Genode::Irq_session_capability cap,
unsigned int irq)
:
_name(dev),
_dev(dev),
_name(irq),
_irq(irq),
_irq_sess(dev.irq(0)),
_irq_sess(cap),
_task(_run_irq, this, _name.name, Lx::Task::PRIORITY_3, Lx::scheduler()),
_irq_enabled(true),
_irq_ack_pending(false),
@ -184,9 +180,6 @@ class Lx_kit::Irq : public Lx::Irq
*/
void add_handler(Handler *h) { _handler.append(h); }
bool device(Platform::Device &dev) {
return (&dev == &_dev); }
bool irq(unsigned int irq) {
return (irq == _irq); }
@ -219,16 +212,6 @@ class Lx_kit::Irq : public Lx::Irq
Context_slab _context_alloc;
Handler_slab _handler_alloc;
/**
* Find context for given device
*/
Context *_find_context(Platform::Device &dev)
{
for (Context *i = _list.first(); i; i = i->next())
if (i->device(dev)) return i;
return nullptr;
}
/**
* Find context for given IRQ number
*/
@ -256,15 +239,17 @@ class Lx_kit::Irq : public Lx::Irq
** Lx::Irq interface **
***********************/
void request_irq(Platform::Device &dev, unsigned int irq,
irq_handler_t handler, void *dev_id,
irq_handler_t thread_fn = 0) override
void request_irq(Genode::Irq_session_capability cap,
unsigned int irq,
irq_handler_t handler,
void * dev_id,
irq_handler_t thread_fn = 0) override
{
Context *ctx = _find_context(dev);
Context *ctx = _find_context(irq);
/* if this IRQ is not registered */
if (!ctx) {
ctx = new (&_context_alloc) Context(_ep, dev, irq);
ctx = new (&_context_alloc) Context(_ep, cap, irq);
_list.insert(ctx);
}
@ -274,9 +259,9 @@ class Lx_kit::Irq : public Lx::Irq
ctx->add_handler(h);
}
void inject_irq(Platform::Device &dev)
void inject_irq(unsigned int irq)
{
Context *ctx = _find_context(dev);
Context *ctx = _find_context(irq);
if (ctx) ctx->unblock();
}