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

View File

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

View File

@ -13,8 +13,9 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <base/printf.h> #include <base/log.h>
#include <os/server.h> #include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <os/config.h> #include <os/config.h>
/* Server related local includes */ /* Server related local includes */
@ -33,59 +34,49 @@
extern "C" int postcore_i2c_init(); /* i2c-core.c */ extern "C" int postcore_i2c_init(); /* i2c-core.c */
extern "C" int module_i915_init(); /* i915_drv.c */ extern "C" int module_i915_init(); /* i915_drv.c */
namespace Server { struct Main; }
static void run_linux(void * m); static void run_linux(void * m);
unsigned long jiffies; 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() Framebuffer::Root root { ep, heap, 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() };
/* init singleton Lx::Timer */ /* init singleton Lx::Timer */
Lx::Timer &timer = Lx::timer(&ep, &jiffies); Lx::Timer &timer = Lx::timer(&ep, &jiffies);
/* init singleton Lx::Irq */ /* 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 */ /* 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 */ /* Linux task that handles the initialization */
Lx::Task linux { run_linux, reinterpret_cast<void*>(this), "linux", Lx::Task linux { run_linux, reinterpret_cast<void*>(this), "linux",
Lx::Task::PRIORITY_0, Lx::scheduler() }; 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 */ /* give all task a first kick before returning */
Lx::scheduler().schedule(); Lx::scheduler().schedule();
} }
void announce() { void announce() {
Genode::env()->parent()->announce(ep.manage(root_component)); } Genode::env()->parent()->announce(ep.manage(root)); }
}; };
struct Policy_agent struct Policy_agent
{ {
Server::Main &main; Main &main;
Genode::Signal_rpc_member<Policy_agent> sd; Genode::Signal_rpc_member<Policy_agent> sd;
void handle(unsigned) void handle(unsigned)
@ -94,35 +85,33 @@ struct Policy_agent
Lx::scheduler().schedule(); Lx::scheduler().schedule();
} }
Policy_agent(Server::Main &m) Policy_agent(Main &m)
: main(m), sd(main.ep, *this, &Policy_agent::handle) {} : main(m), sd(main.ep, *this, &Policy_agent::handle) {}
}; };
static void run_linux(void * m) static void run_linux(void * m)
{ {
Server::Main * main = reinterpret_cast<Server::Main*>(m); Main * main = reinterpret_cast<Main*>(m);
postcore_i2c_init(); postcore_i2c_init();
module_i915_init(); module_i915_init();
main->root_component.session.driver().finish_initialization(); main->root.session.driver().finish_initialization();
main->announce(); main->announce();
static Policy_agent pa(*main); static Policy_agent pa(*main);
Genode::config()->sigh(pa.sd); main->config.sigh(pa.sd);
while (1) { while (1) {
Lx::scheduler().current()->block_and_schedule(); 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 Component::construct(Genode::Env &env) {
static Main m(env); }
void construct(Entrypoint &ep) { static Main m(ep); }
}

View File

@ -1,7 +1,7 @@
REQUIRES = x86 REQUIRES = x86
TARGET = intel_fb_drv 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_CC = main.cc lx_emul.cc
SRC_C = dummies.c i915_params.c lx_emul_c.c SRC_C = dummies.c i915_params.c lx_emul_c.c
@ -10,6 +10,7 @@ SRC_CC += irq.cc \
malloc.cc \ malloc.cc \
mapped_io_mem_range.cc \ mapped_io_mem_range.cc \
pci.cc \ pci.cc \
printf.cc \
scheduler.cc \ scheduler.cc \
timer.cc \ timer.cc \
work.cc work.cc

View File

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

View File

@ -381,3 +381,8 @@ Lx::Malloc &Lx::Malloc::mem() {
*/ */
Lx::Malloc &Lx::Malloc::dma() { Lx::Malloc &Lx::Malloc::dma() {
return Lx_kit::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); }