intel_fb_drv: componentize

Issue #1987
This commit is contained in:
Stefan Kalkowski 2016-06-01 11:32:52 +02:00 committed by Christian Helmuth
parent 1cfa14b2f2
commit 11bead1811
6 changed files with 74 additions and 86 deletions

View File

@ -23,6 +23,7 @@
#include <util/volatile_object.h>
#include <os/attached_dataspace.h>
#include <os/attached_ram_dataspace.h>
#include <os/attached_rom_dataspace.h>
#include <blit/blit.h>
struct drm_display_mode;
@ -41,14 +42,14 @@ class Framebuffer::Driver
private:
Session_component &_session;
int _height = 0;
int _width = 0;
int _height = 0;
int _width = 0;
static constexpr unsigned _bytes_per_pixel = 2;
void *_new_fb_ds_base = nullptr;
void *_cur_fb_ds_base = nullptr;
Genode::uint64_t _cur_fb_ds_size = 0;
drm_framebuffer *_new_fb = nullptr;
drm_framebuffer *_cur_fb = nullptr;
void *_new_fb_ds_base = nullptr;
void *_cur_fb_ds_base = nullptr;
Genode::uint64_t _cur_fb_ds_size = 0;
drm_framebuffer *_new_fb = nullptr;
drm_framebuffer *_cur_fb = nullptr;
drm_display_mode * _preferred_mode(drm_connector *connector);
@ -78,13 +79,17 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
template <typename T> using Lazy = Genode::Lazy_volatile_object<T>;
Driver _driver;
Genode::Attached_rom_dataspace &_config;
Genode::Signal_context_capability _mode_sigh;
Timer::Connection _timer;
bool const _buffered;
bool _buffered;
Lazy<Genode::Attached_dataspace> _fb_ds;
Lazy<Genode::Attached_ram_dataspace> _bb_ds;
bool _in_update = false;
bool _buffered_from_config() {
return _config.xml().attribute_value("buffered", false); }
void _refresh_buffered(int x, int y, int w, int h)
{
using namespace Genode;
@ -109,20 +114,27 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
public:
Session_component(bool buffered)
: _driver(*this), _buffered(buffered) {}
Session_component(Genode::Attached_rom_dataspace &config)
: _driver(*this), _config(config),
_buffered(_buffered_from_config()) {}
Driver & driver() { return _driver; }
void config_changed()
{
_config.update();
if (!_config.valid()) return;
_in_update = true;
_buffered = _buffered_from_config();
if (_driver.mode_changed() && _mode_sigh.valid())
Genode::Signal_transmitter(_mode_sigh).submit();
else
_in_update = false;
}
Genode::Xml_node config() { return _config.xml(); }
/***********************************
** Framebuffer session interface **
@ -179,10 +191,11 @@ struct Framebuffer::Root
Session_component *_create_session(const char *args) override {
return &session; }
Root(Genode::Rpc_entrypoint *ep, Genode::Allocator *alloc, bool buffered)
Root(Genode::Entrypoint &ep, Genode::Allocator &alloc,
Genode::Attached_rom_dataspace &config)
: Genode::Root_component<Session_component,
Genode::Single_client>(ep, alloc),
session(buffered) { }
session(config) { }
};
#endif /* __COMPONENT_H__ */

View File

@ -7,9 +7,8 @@
/* Genode includes */
#include <util/bit_allocator.h>
#include <base/printf.h>
#include <base/log.h>
#include <os/attached_io_mem_dataspace.h>
#include <os/config.h>
#include <os/reporter.h>
/* local includes */
@ -89,10 +88,9 @@ Framebuffer::Driver::_preferred_mode(drm_connector *connector)
/* try to read configuration for connector */
try {
config()->reload();
Xml_node node = config()->xml_node();
Xml_node xn = node.sub_node();
for (unsigned i = 0; i < node.num_sub_nodes(); xn = xn.next()) {
Xml_node config = _session.config();
Xml_node xn = config.sub_node();
for (unsigned i = 0; i < config.num_sub_nodes(); xn = xn.next()) {
if (!xn.has_type("connector"))
continue;
@ -161,7 +159,7 @@ bool Framebuffer::Driver::mode_changed()
dde_c_allocate_framebuffer(width, height, &_new_fb_ds_base,
&_cur_fb_ds_size, dde_drm_device);
if (!fb) {
PERR("failed to allocate framebuffer %dx%d", width, height);
Genode::error("failed to allocate framebuffer ", width, "x", height);
return false;
}
@ -216,8 +214,7 @@ void Framebuffer::Driver::generate_report()
static Genode::Reporter reporter("connectors");
try {
Genode::config()->reload();
reporter.enabled(Genode::config()->xml_node().sub_node("report")
reporter.enabled(_session.config().sub_node("report")
.attribute_value(reporter.name().string(), false));
} catch (...) {
reporter.enabled(false);
@ -263,32 +260,12 @@ void Framebuffer::Driver::generate_report()
}
});
} catch (...) {
PWRN("Failed to generate report");
Genode::warning("Failed to generate report");
}
}
extern "C" {
void lx_printf(char const *fmt, ...)
{
va_list va;
va_start(va, fmt);
Genode::vprintf(fmt, va);
va_end(va);
}
void lx_vprintf(char const *fmt, va_list va)
{
Genode::vprintf(fmt, va);
}
/****************************************
** Common Linux kernel infrastructure **
****************************************/
/**********************
** Global variables **
**********************/
@ -508,7 +485,7 @@ struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
client.bus_address(&dev_bus, &dev_slot, &dev_fn);
if (dev_bus == bus && PCI_SLOT(devfn) == dev_slot && PCI_FUNC(devfn) == dev_fn) {
Lx::Pci_dev *dev = new (Genode::env()->heap()) Lx::Pci_dev(cap);
Lx::Pci_dev *dev = new (Lx::Malloc::mem()) Lx::Pci_dev(cap);
Lx::pci_dev_registry()->insert(dev);
pci_dev = dev;
return true;
@ -543,7 +520,7 @@ struct pci_dev *pci_get_class(unsigned int class_code, struct pci_dev *from)
Platform::Device_client client(cap);
if (client.class_code() == class_code) {
pci_dev = new (Genode::env()->heap()) Lx::Pci_dev(cap);
pci_dev = new (Lx::Malloc::mem()) Lx::Pci_dev(cap);
return true;
}
@ -657,11 +634,11 @@ struct io_mapping *io_mapping_create_wc(resource_size_t base, unsigned long size
TRACE;
if (called++ != 0) {
PERR("io_mapping_create_wc unexpectedly called twice");
Genode::error("io_mapping_create_wc unexpectedly called twice");
return 0;
}
io_mapping *mapping = new (Genode::env()->heap()) io_mapping(base, size);
io_mapping *mapping = new (Lx::Malloc::mem()) io_mapping(base, size);
return mapping;
}
@ -847,8 +824,8 @@ void drm_ut_debug_printk(const char *function_name, const char *format, ...)
va_list list;
va_start(list, format);
printf("[drm:%s] ", function_name);
vprintf(format, list);
lx_printf("[drm:%s] ", function_name);
lx_vprintf(format, list);
va_end(list);
}
@ -859,8 +836,8 @@ void drm_err(const char *format, ...)
va_list list;
va_start(list, format);
printf("[drm:ERROR] ");
vprintf(format, list);
lx_printf("[drm:ERROR] ");
lx_vprintf(format, list);
va_end(list);
}

View File

@ -13,8 +13,9 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <os/server.h>
#include <base/log.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <os/config.h>
/* Server related local includes */
@ -33,59 +34,49 @@
extern "C" int postcore_i2c_init(); /* i2c-core.c */
extern "C" int module_i915_init(); /* i915_drv.c */
namespace Server { struct Main; }
static void run_linux(void * m);
unsigned long jiffies;
struct Server::Main
struct Main
{
Entrypoint &ep;
Genode::Entrypoint &ep;
Genode::Attached_rom_dataspace config;
Genode::Heap heap;
bool _buffered_from_config()
{
try {
config()->reload();
return Genode::config()->xml_node().attribute_value("buffered",
false);
} catch (...) { return false; }
}
Framebuffer::Root root_component { &ep.rpc_ep(), Genode::env()->heap(),
_buffered_from_config() };
Framebuffer::Root root { ep, heap, config };
/* init singleton Lx::Timer */
Lx::Timer &timer = Lx::timer(&ep, &jiffies);
/* init singleton Lx::Irq */
Lx::Irq &irq = Lx::Irq::irq(&ep, Genode::env()->heap());
Lx::Irq &irq = Lx::Irq::irq(&ep, &heap);
/* init singleton Lx::Work */
Lx::Work &work = Lx::Work::work_queue(Genode::env()->heap());
Lx::Work &work = Lx::Work::work_queue(&heap);
/* Linux task that handles the initialization */
Lx::Task linux { run_linux, reinterpret_cast<void*>(this), "linux",
Lx::Task::PRIORITY_0, Lx::scheduler() };
Main(Entrypoint &ep) : ep(ep)
Main(Genode::Env &env)
: ep(env.ep()), config(env, "config"), heap(env.ram(), env.rm())
{
Genode::printf("--- intel framebuffer driver ---\n");
Genode::log("--- intel framebuffer driver ---");
/* give all task a first kick before returning */
Lx::scheduler().schedule();
}
void announce() {
Genode::env()->parent()->announce(ep.manage(root_component)); }
Genode::env()->parent()->announce(ep.manage(root)); }
};
struct Policy_agent
{
Server::Main &main;
Main &main;
Genode::Signal_rpc_member<Policy_agent> sd;
void handle(unsigned)
@ -94,35 +85,33 @@ struct Policy_agent
Lx::scheduler().schedule();
}
Policy_agent(Server::Main &m)
Policy_agent(Main &m)
: main(m), sd(main.ep, *this, &Policy_agent::handle) {}
};
static void run_linux(void * m)
{
Server::Main * main = reinterpret_cast<Server::Main*>(m);
Main * main = reinterpret_cast<Main*>(m);
postcore_i2c_init();
module_i915_init();
main->root_component.session.driver().finish_initialization();
main->root.session.driver().finish_initialization();
main->announce();
static Policy_agent pa(*main);
Genode::config()->sigh(pa.sd);
main->config.sigh(pa.sd);
while (1) {
Lx::scheduler().current()->block_and_schedule();
main->root_component.session.config_changed();
main->root.session.config_changed();
}
}
namespace Server {
Genode::size_t Component::stack_size() {
return 8*1024*sizeof(long); }
char const *name() { return "intel_fb_ep"; }
size_t stack_size() { return 8*1024*sizeof(long); }
void construct(Entrypoint &ep) { static Main m(ep); }
}
void Component::construct(Genode::Env &env) {
static Main m(env); }

View File

@ -1,7 +1,7 @@
REQUIRES = x86
TARGET = intel_fb_drv
LIBS = base intel_fb_drv intel_fb_include libc-setjmp server config blit
LIBS = base intel_fb_drv intel_fb_include libc-setjmp blit
SRC_CC = main.cc lx_emul.cc
SRC_C = dummies.c i915_params.c lx_emul_c.c
@ -10,6 +10,7 @@ SRC_CC += irq.cc \
malloc.cc \
mapped_io_mem_range.cc \
pci.cc \
printf.cc \
scheduler.cc \
timer.cc \
work.cc

View File

@ -60,4 +60,7 @@ class Lx::Malloc
static Malloc &dma();
};
void *operator new (Genode::size_t, Lx::Malloc &);
#endif /* _LX_KIT__MALLOC_H_ */

View File

@ -381,3 +381,8 @@ Lx::Malloc &Lx::Malloc::mem() {
*/
Lx::Malloc &Lx::Malloc::dma() {
return Lx_kit::Malloc::dma(); }
/**
* Placement new for Malloc allocator
*/
void *operator new (Genode::size_t s, Lx::Malloc &a) { return a.alloc(s); }