From 1205607e783adb9a7a8f570eb8ca20a88a478a75 Mon Sep 17 00:00:00 2001 From: Johannes Kliemann Date: Mon, 12 Jun 2017 20:29:42 +0200 Subject: [PATCH] os: add framebuffer based on platform_info of core Issue #2242 --- repos/os/src/drivers/framebuffer/boot/README | 18 ++++ .../drivers/framebuffer/boot/framebuffer.cc | 83 +++++++++++++++++++ .../framebuffer/boot/include/framebuffer.h | 62 ++++++++++++++ repos/os/src/drivers/framebuffer/boot/main.cc | 47 +++++++++++ .../os/src/drivers/framebuffer/boot/target.mk | 4 + 5 files changed, 214 insertions(+) create mode 100644 repos/os/src/drivers/framebuffer/boot/README create mode 100644 repos/os/src/drivers/framebuffer/boot/framebuffer.cc create mode 100644 repos/os/src/drivers/framebuffer/boot/include/framebuffer.h create mode 100644 repos/os/src/drivers/framebuffer/boot/main.cc create mode 100644 repos/os/src/drivers/framebuffer/boot/target.mk diff --git a/repos/os/src/drivers/framebuffer/boot/README b/repos/os/src/drivers/framebuffer/boot/README new file mode 100644 index 0000000000..ac812e5a1e --- /dev/null +++ b/repos/os/src/drivers/framebuffer/boot/README @@ -0,0 +1,18 @@ +This directory contains the implementation of a framebuffer driver which +relies on a pre-intialised graphic device, e.g. by BIOS/UEFI or bootloader. + +Behavior +-------- + +The driver looks for a ROM named 'platform_info' with the following XML +nodes and attributes: + + + + + + + +If the framebuffer node exists and all attributes, the driver opens up a +IO_MEM session with the given physical addres as framebuffer memory and +renders the framebuffer content into the given area. diff --git a/repos/os/src/drivers/framebuffer/boot/framebuffer.cc b/repos/os/src/drivers/framebuffer/boot/framebuffer.cc new file mode 100644 index 0000000000..1759ffada1 --- /dev/null +++ b/repos/os/src/drivers/framebuffer/boot/framebuffer.cc @@ -0,0 +1,83 @@ +/* + * \brief Framebuffer driver that uses a framebuffer supplied by the core rom. + * \author Johannes Kliemann + * \date 2017-06-12 + */ + +/* + * Copyright (C) 2017 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. + */ + +#include +#include + +using namespace Framebuffer; + +Session_component::Session_component(Genode::Env &env, + Genode::Xml_node pinfo) +: _env(env) +{ + try { + Genode::Xml_node fb = pinfo.sub_node("boot").sub_node("framebuffer"); + + fb.attribute("phys").value(&_core_fb.addr); + fb.attribute("width").value(&_core_fb.width); + fb.attribute("height").value(&_core_fb.height); + fb.attribute("bpp").value(&_core_fb.bpp); + } catch (...) { + Genode::error("No boot framebuffer information available."); + throw Genode::Service_denied(); + } + + Genode::log("Framebuffer with ", _core_fb.width, "x", _core_fb.height, + "x", _core_fb.bpp, " @ ", (void*)_core_fb.addr); + + _fb_mem.construct( + _env, + _core_fb.addr, + _core_fb.width * _core_fb.height * _core_fb.bpp / 4, + true); + + _fb_mode = Mode(_core_fb.width, _core_fb.height, Mode::RGB565); + + _fb_ram.construct(_env.ram(), _env.rm(), + _core_fb.width * _core_fb.height * _fb_mode.bytes_per_pixel()); +} + +Mode Session_component::mode() const { return _fb_mode; } + +void Session_component::mode_sigh(Genode::Signal_context_capability _scc) { } + +void Session_component::sync_sigh(Genode::Signal_context_capability scc) +{ + timer.sigh(scc); + timer.trigger_periodic(10*1000); +} + +void Session_component::refresh(int x, int y, int w, int h) +{ + Genode::uint32_t u_x = (Genode::uint32_t)Genode::min(_core_fb.width, (Genode::uint32_t)Genode::max(x, 0)); + Genode::uint32_t u_y = (Genode::uint32_t)Genode::min(_core_fb.height, (Genode::uint32_t)Genode::max(y, 0)); + Genode::uint32_t u_w = (Genode::uint32_t)Genode::min(_core_fb.width, (Genode::uint32_t)Genode::max(w, 0) + u_x); + Genode::uint32_t u_h = (Genode::uint32_t)Genode::min(_core_fb.height, (Genode::uint32_t)Genode::max(h, 0) + u_y); + Genode::Pixel_rgb888 *pixel_32 = _fb_mem->local_addr(); + Genode::Pixel_rgb565 *pixel_16 = _fb_ram->local_addr(); + for (Genode::uint32_t r = u_y; r < u_h; ++r){ + for (Genode::uint32_t c = u_x; c < u_w; ++c){ + Genode::uint32_t i = c + r * _core_fb.width; + pixel_32[i].rgba( + pixel_16[i].r(), + pixel_16[i].g(), + pixel_16[i].b(), + 0); + } + } +} + +Genode::Dataspace_capability Session_component::dataspace() +{ + return _fb_ram->cap(); +} diff --git a/repos/os/src/drivers/framebuffer/boot/include/framebuffer.h b/repos/os/src/drivers/framebuffer/boot/include/framebuffer.h new file mode 100644 index 0000000000..95fe71d4fd --- /dev/null +++ b/repos/os/src/drivers/framebuffer/boot/include/framebuffer.h @@ -0,0 +1,62 @@ +/* + * \brief Framebuffer driver that uses a framebuffer supplied by the core rom. + * \author Johannes Kliemann + * \date 2017-06-12 + */ + +/* + * Copyright (C) 2017 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 _FRAMEBUFFER_H_ +#define _FRAMEBUFFER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Framebuffer { + + class Session_component; +} + +class Framebuffer::Session_component : public Genode::Rpc_object +{ + private: + + Genode::Env &_env; + + struct fb_desc { + Genode::uint64_t addr; + Genode::uint32_t width; + Genode::uint32_t height; + Genode::uint32_t bpp; + } _core_fb; + + Mode _fb_mode; + + Genode::Constructible _fb_mem; + Genode::Constructible _fb_ram; + + Timer::Connection timer { _env }; + + public: + Session_component(Genode::Env &, Genode::Xml_node); + Mode mode() const override; + void mode_sigh(Genode::Signal_context_capability) override; + void sync_sigh(Genode::Signal_context_capability) override; + void refresh(int, int, int, int) override; + Genode::Dataspace_capability dataspace() override; +}; + +#endif // _FRAMEBUFFER_H_ diff --git a/repos/os/src/drivers/framebuffer/boot/main.cc b/repos/os/src/drivers/framebuffer/boot/main.cc new file mode 100644 index 0000000000..5d681fceaf --- /dev/null +++ b/repos/os/src/drivers/framebuffer/boot/main.cc @@ -0,0 +1,47 @@ +/* + * \brief Framebuffer driver that uses a framebuffer supplied by the core rom. + * \author Johannes Kliemann + * \date 2017-06-12 + */ + +/* + * Copyright (C) 2017 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. + */ + +#include +#include +#include +#include + +#include + +struct Main { + + Genode::Env &env; + + Genode::Attached_rom_dataspace pinfo { + env, + "platform_info" + }; + + Framebuffer::Session_component fb { + env, + pinfo.xml(), + }; + + Genode::Static_root fb_root {env.ep().manage(fb)}; + + Main(Genode::Env &env) : env(env) + { + env.parent().announce(env.ep().manage(fb_root)); + } +}; + +void Component::construct(Genode::Env &env) { + + static Main inst(env); + +} diff --git a/repos/os/src/drivers/framebuffer/boot/target.mk b/repos/os/src/drivers/framebuffer/boot/target.mk new file mode 100644 index 0000000000..a12eb6fea6 --- /dev/null +++ b/repos/os/src/drivers/framebuffer/boot/target.mk @@ -0,0 +1,4 @@ +TARGET = fb_boot_drv +LIBS = base +SRC_CC = main.cc framebuffer.cc +INC_DIR += $(PRG_DIR)/include