diff --git a/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc b/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc
index c23a81d9cf..0cc8da5464 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc
+++ b/repos/libports/src/drivers/framebuffer/vesa/framebuffer.cc
@@ -6,23 +6,24 @@
*/
/*
- * Copyright (C) 2007-2013 Genode Labs GmbH
+ * Copyright (C) 2007-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
-#include
-#include
-#include
+/* Genode includes */
#include
-#include
#include
+#include
+/* local includes */
#include "framebuffer.h"
#include "ifx86emu.h"
+#include "hw_emul.h"
#include "vesa.h"
#include "vbe.h"
+#include "genode_env.h"
using namespace Genode;
using namespace Vesa;
@@ -47,8 +48,8 @@ static inline uint32_t to_phys(uint32_t addr)
static uint16_t get_vesa_mode(mb_vbe_ctrl_t *ctrl_info, mb_vbe_mode_t *mode_info,
- unsigned long &width, unsigned long &height,
- unsigned long depth, bool verbose)
+ unsigned &width, unsigned &height, unsigned depth,
+ bool verbose)
{
bool choose_highest_resolution_mode = ((width == 0) || (height == 0));
@@ -143,25 +144,25 @@ static uint16_t get_vesa_mode(mb_vbe_ctrl_t *ctrl_info, mb_vbe_mode_t *mode_info
** Driver API **
****************/
-Dataspace_capability Framebuffer_drv::hw_framebuffer()
+Dataspace_capability Framebuffer::hw_framebuffer()
{
return io_mem_cap;
}
-int Framebuffer_drv::map_io_mem(addr_t base, size_t size, bool write_combined,
- void **out_addr, addr_t addr,
- Dataspace_capability *out_io_ds)
+int Framebuffer::map_io_mem(addr_t base, size_t size, bool write_combined,
+ void **out_addr, addr_t addr,
+ Dataspace_capability *out_io_ds)
{
- Io_mem_connection &io_mem = *new (env()->heap())
- Io_mem_connection(base, size, write_combined);
+ Io_mem_connection &io_mem = *new (alloc())
+ Io_mem_connection(genode_env(), base, size, write_combined);
Io_mem_dataspace_capability io_ds = io_mem.dataspace();
if (!io_ds.valid())
return -2;
try {
- *out_addr = env()->rm_session()->attach(io_ds, size, 0, addr != 0, addr);
+ *out_addr = genode_env().rm().attach(io_ds, size, 0, addr != 0, addr);
} catch (Rm_session::Attach_failed) {
return -3;
}
@@ -175,8 +176,7 @@ int Framebuffer_drv::map_io_mem(addr_t base, size_t size, bool write_combined,
}
-int Framebuffer_drv::set_mode(unsigned long &width, unsigned long &height,
- unsigned long mode)
+int Framebuffer::set_mode(unsigned &width, unsigned &height, unsigned mode)
{
mb_vbe_ctrl_t *ctrl_info;
mb_vbe_mode_t *mode_info;
@@ -260,10 +260,19 @@ int Framebuffer_drv::set_mode(unsigned long &width, unsigned long &height,
** Driver startup **
********************/
-int Framebuffer_drv::init()
+void Framebuffer::init(Genode::Env &env, Genode::Allocator &heap)
{
- if (X86emu::init())
- return -1;
+ local_init_genode_env(env, heap);
- return 0;
+ {
+ /*
+ * Wait until Acpi/Pci driver initialization is done to avoid
+ * potentially concurrent access by this driver and the Acpi/Pci driver
+ * to the graphics device, i.e., to the PCI config space.
+ */
+ Platform::Connection sync(env);
+ }
+
+ hw_emul_init(env);
+ X86emu::init(env, heap);
}
diff --git a/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc b/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc
index da868cdb72..bdd25becf4 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc
+++ b/repos/libports/src/drivers/framebuffer/vesa/hw_emul.cc
@@ -11,16 +11,18 @@
*/
/*
- * Copyright (C) 2010-2013 Genode Labs GmbH
+ * Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
-#include
+/* Genode includes */
#include
#include
+/* local includes */
+#include "framebuffer.h"
#include "hw_emul.h"
using namespace Genode;
@@ -40,24 +42,22 @@ enum {
};
-/**
- * Helper for the formatted output of a (bus, device, function) triple
- */
struct Devfn
{
- unsigned short devfn;
+ unsigned char b, d, f;
- explicit Devfn(unsigned short devfn) : devfn(devfn) { }
+ Devfn(Platform::Device &device) { device.bus_address(&b, &d, &f); }
+
+ Devfn(unsigned short devfn)
+ : b((devfn >> 8) & 0xff), d((devfn >> 3) & 0x1f), f(devfn & 7) { }
+
+ unsigned short devfn() const { return b << 8 | d << 3 | f; }
void print(Genode::Output &out) const
{
- unsigned char const bus = devfn >> 8,
- dev = (devfn >> 3) & 0x1f,
- fn = devfn & 0x7;
-
- Genode::print(out, Hex(bus, Hex::OMIT_PREFIX, Hex::PAD), ":",
- Hex(dev, Hex::OMIT_PREFIX, Hex::PAD), ".",
- Hex(fn, Hex::OMIT_PREFIX));
+ Genode::print(out, Hex(b, Hex::OMIT_PREFIX, Hex::PAD), ":",
+ Hex(d, Hex::OMIT_PREFIX, Hex::PAD), ".",
+ Hex(f, Hex::OMIT_PREFIX));
}
};
@@ -68,7 +68,7 @@ class Pci_card
Platform::Connection _pci_drv;
Platform::Device_client _device;
- unsigned short _devfn;
+ Devfn _devfn;
Platform::Device_capability _first_device()
{
@@ -110,8 +110,8 @@ class Pci_card
}
if (!device_cap.valid()) {
- Genode::error("PCI VGA card not found. Sleeping...");
- sleep_forever();
+ Genode::error("PCI VGA card not found.");
+ throw Framebuffer::Fatal();
}
return device_cap;
@@ -119,27 +119,18 @@ class Pci_card
public:
- Pci_card() : _device(_find_vga_card())
+ Pci_card(Genode::Env &env)
+ : _pci_drv(env), _device(_find_vga_card()), _devfn(_device)
{
- unsigned char bus = 0, dev = 0, fn = 0;
-
- _device.bus_address(&bus, &dev, &fn);
- _devfn = bus << 8 | dev << 3 | fn;
-
- if (verbose)
- Genode::log("Found PCI VGA at ", Devfn(_devfn));
+ Genode::log("Found PCI VGA at ", _devfn);
}
- Platform::Device_client &device() { return _device; }
- unsigned short devfn() const { return _devfn; }
+ Platform::Device &device() { return _device; }
+ unsigned short devfn() const { return _devfn.devfn(); }
};
-static Pci_card *pci_card()
-{
- static Pci_card _pci_card;
- return &_pci_card;
-}
+static Constructible pci_card;
/**
@@ -166,7 +157,7 @@ static bool handle_pci_port_write(unsigned short port, T val)
}
unsigned const devfn = (val >> 8) & 0xffff;
- if (devfn != pci_card()->devfn()) {
+ if (devfn != pci_card->devfn()) {
if (verbose)
warning("accessing unknown PCI device ", Devfn(devfn));
pci_cfg_addr_valid = false;
@@ -219,13 +210,13 @@ static bool handle_pci_port_read(unsigned short port, T *val)
switch (pci_cfg_addr) {
case 0: /* vendor / device ID */
- raw_val = pci_card()->device().vendor_id() |
- (pci_card()->device().device_id() << 16);
+ raw_val = pci_card->device().vendor_id() |
+ (pci_card->device().device_id() << 16);
break;
case 4: /* status and command */
case 8: /* class code / revision ID */
- raw_val = pci_card()->device().config_read(pci_cfg_addr,
+ raw_val = pci_card->device().config_read(pci_cfg_addr,
Platform::Device::ACCESS_32BIT);
break;
@@ -237,7 +228,7 @@ static bool handle_pci_port_read(unsigned short port, T *val)
case 0x24: /* base address register 5 */
{
unsigned bar = (pci_cfg_addr - 0x10) / 4;
- Platform::Device::Resource res = pci_card()->device().resource(bar);
+ Platform::Device::Resource res = pci_card->device().resource(bar);
if (res.type() == Platform::Device::Resource::INVALID) {
warning("requested PCI resource ", bar, " invalid");
*val = 0;
@@ -349,3 +340,6 @@ bool hw_emul_handle_port_write(unsigned short port, T val)
return false;
}
+
+
+void hw_emul_init(Genode::Env &env) { pci_card.construct(env); }
diff --git a/repos/libports/src/drivers/framebuffer/vesa/ifx86emu.cc b/repos/libports/src/drivers/framebuffer/vesa/ifx86emu.cc
index 7727d5e37e..1dd6633642 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/ifx86emu.cc
+++ b/repos/libports/src/drivers/framebuffer/vesa/ifx86emu.cc
@@ -6,28 +6,29 @@
*/
/*
- * Copyright (C) 2007-2013 Genode Labs GmbH
+ * Copyright (C) 2007-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
+/* Genode includes */
#include
-#include
-#include
-#include
+#include
+#include
#include
#include
-#include
-
+#include
#include
-#include
-#include
+#include /* XXX for emulating X86emu::printk() */
+
+/* local includes */
#include "ifx86emu.h"
#include "framebuffer.h"
#include "vesa.h"
#include "hw_emul.h"
+#include "genode_env.h"
namespace X86emu {
@@ -133,163 +134,134 @@ class Region : public Avl_node
template
-class Region_database : public Avl_tree
+struct Region_database : Avl_tree
{
- public:
+ Genode::Env &env;
+ Genode::Allocator &heap;
- TYPE * match(addr_t base, size_t size)
- {
- if (!first()) return 0;
+ Region_database(Genode::Env &env, Genode::Allocator &heap)
+ : env(env), heap(heap) { }
- return static_cast(first()->match(base, size));
+ TYPE * match(addr_t base, size_t size)
+ {
+ if (!first()) return 0;
+
+ return static_cast(first()->match(base, size));
+ }
+
+ TYPE * meet(addr_t base, size_t size)
+ {
+ if (!first()) return 0;
+
+ return static_cast(first()->meet(base, size));
+ }
+
+ TYPE * get_region(addr_t base, size_t size)
+ {
+ TYPE *region;
+
+ /* look for match and return if found */
+ if ((region = match(base, size)))
+ return region;
+
+ /*
+ * We try to create a new port region, but first we look if any overlapping
+ * resp. meeting regions already exist. These are freed and merged into a
+ * new super region including the new port region.
+ */
+
+ addr_t beg = base, end = base + size;
+
+ while ((region = meet(beg, end - beg))) {
+ /* merge region into super region */
+ beg = min(beg, static_cast(region->base()));
+ end = max(end, static_cast(region->base() + region->size()));
+
+ /* destroy old region */
+ remove(region);
+ destroy(heap, region);
}
- TYPE * meet(addr_t base, size_t size)
- {
- if (!first()) return 0;
-
- return static_cast(first()->meet(base, size));
+ try {
+ region = new (heap) TYPE(env, beg, end - beg);
+ insert(region);
+ return region;
+ } catch (...) {
+ Genode::error("access to I/O region ",
+ Hex_range(beg, end - beg), " denied");
+ return 0;
}
+ }
- TYPE * get_region(addr_t base, size_t size)
- {
- TYPE *region;
+ void print_regions()
+ {
+ if (!first()) return;
- /* look for match and return if found */
- if ((region = match(base, size)))
- return region;
-
- /*
- * We try to create a new port region, but first we look if any overlapping
- * resp. meeting regions already exist. These are freed and merged into a
- * new super region including the new port region.
- */
-
- addr_t beg = base, end = base + size;
-
- while ((region = meet(beg, end - beg))) {
- /* merge region into super region */
- beg = min(beg, static_cast(region->base()));
- end = max(end, static_cast(region->base() + region->size()));
-
- /* destroy old region */
- remove(region);
- destroy(env()->heap(), region);
- }
-
- try {
- region = new (env()->heap()) TYPE(beg, end - beg);
- insert(region);
- return region;
- } catch (...) {
- Genode::error("access to I/O region ",
- Hex_range(beg, end - beg), " denied");
- return 0;
- }
- }
-
- void print_regions()
- {
- if (!first()) return;
-
- first()->print_regions();
- }
+ first()->print_regions();
+ }
};
/**
* I/O port region including corresponding IO_PORT connection
*/
-class Port_region : public Region, public Io_port_connection
+struct Port_region : Region, Io_port_connection
{
- public:
+ Port_region(Genode::Env &env, unsigned short port_base, size_t port_size)
+ :
+ Region(port_base, port_size),
+ Io_port_connection(env, port_base, port_size)
+ {
+ if (verbose) Genode::log("add port ", *this);
+ }
- void print(Genode::Output &out) const
- {
- unsigned const beg = base(), end = beg + size();
- Genode::print(out, Hex_range(beg, end - beg));
- }
+ ~Port_region()
+ {
+ if (verbose) Genode::log("del port ", *this);
+ }
- Port_region(unsigned short port_base, size_t port_size)
- : Region(port_base, port_size), Io_port_connection(port_base, port_size)
- {
- if (verbose)
- Genode::log("add port ", *this);
- }
-
- ~Port_region()
- {
- if (verbose)
- Genode::log("del port ", *this);
- }
+ void print(Genode::Output &out) const
+ {
+ unsigned const beg = base(), end = beg + size();
+ Genode::print(out, Hex_range(beg, end - beg));
+ }
};
/**
* I/O memory region including corresponding IO_MEM connection
*/
-class Mem_region : public Region
+struct Mem_region : Region, Attached_io_mem_dataspace
{
- private:
+ Mem_region(Genode::Env &env, addr_t mem_base, size_t mem_size)
+ :
+ Region(mem_base, mem_size),
+ Attached_io_mem_dataspace(env, mem_base, mem_size)
+ {
+ if (verbose) Genode::log("add mem ", *this, " @ ", local_addr());
+ }
- class Io_mem_dataspace : public Io_mem_connection
- {
- private:
+ ~Mem_region()
+ {
+ if (verbose) Genode::log("del mem ", *this);
+ }
- void *_local_addr;
+ template
+ T * virt_addr(addr_t addr)
+ {
+ return reinterpret_cast(local_addr() + (addr - base()));
+ }
- public:
-
- Io_mem_dataspace(addr_t base, size_t size)
- : Io_mem_connection(base, size)
- {
- _local_addr = env()->rm_session()->attach(dataspace());
- }
-
- ~Io_mem_dataspace()
- {
- env()->rm_session()->detach(_local_addr);
- }
-
- Io_mem_dataspace_capability cap() { return dataspace(); }
-
- template
- T * local_addr() { return static_cast(_local_addr); }
- };
-
- Io_mem_dataspace _ds;
-
- public:
-
- void print(Genode::Output &out) const
- {
- addr_t const beg = base(), end = beg + size();
- Genode::print(out, Hex_range(beg, end - beg));
- }
-
- Mem_region(addr_t mem_base, size_t mem_size)
- : Region(mem_base, mem_size), _ds(mem_base, mem_size)
- {
- if (verbose)
- Genode::log("add mem ", *this, " @ ", _ds.local_addr());
- }
-
- ~Mem_region()
- {
- if (verbose)
- Genode::log("del mem ", *this);
- }
-
- template
- T * virt_addr(addr_t addr)
- {
- return reinterpret_cast(_ds.local_addr() + (addr - base()));
- }
+ void print(Genode::Output &out) const
+ {
+ addr_t const beg = base(), end = beg + size();
+ Genode::print(out, Hex_range(beg, end - beg));
+ }
};
-static Region_database port_region_db;
-static Region_database mem_region_db;
+static Genode::Constructible> port_region_db;
+static Genode::Constructible> mem_region_db;
/**
@@ -302,7 +274,7 @@ static int map_code_area(void)
void *dummy;
/* map page0 */
- if ((err = Framebuffer_drv::map_io_mem(0x0, PAGESIZE, false, &dummy))) {
+ if ((err = Framebuffer::map_io_mem(0x0, PAGESIZE, false, &dummy))) {
Genode::error("could not map page zero");
return err;
}
@@ -310,7 +282,7 @@ static int map_code_area(void)
/* alloc code pages in RAM */
try {
- static Attached_ram_dataspace ram_ds(env()->ram_session(), CODESIZE);
+ static Attached_ram_dataspace ram_ds(genode_env().ram(), genode_env().rm(), CODESIZE);
dummy = ram_ds.local_addr();
x86_mem.data_addr(dummy);
} catch (...) {
@@ -391,7 +363,7 @@ static T X86API inx(X86emu::X86EMU_pioAddr addr)
if (hw_emul_handle_port_read(port, &ret))
return ret;
- Port_region *region = port_region_db.get_region(port, sizeof(T));
+ Port_region *region = port_region_db->get_region(port, sizeof(T));
if (!region) return 0;
@@ -423,7 +395,7 @@ static void X86API outx(X86emu::X86EMU_pioAddr addr, T val)
if (hw_emul_handle_port_write(port, val))
return;
- Port_region *region = port_region_db.get_region(port, sizeof(T));
+ Port_region *region = port_region_db->get_region(port, sizeof(T));
if (!region) return;
@@ -479,7 +451,7 @@ TYPE * X86emu::virt_addr(ADDR_TYPE addr)
local_addr += (x86_mem.data_addr() - PAGESIZE);
/* any other I/O memory allocated on demand */
- else if ((region = mem_region_db.get_region(addr & ~(PAGESIZE-1), PAGESIZE)))
+ else if ((region = mem_region_db->get_region(addr & ~(PAGESIZE-1), PAGESIZE)))
return region->virt_addr(local_addr);
else {
@@ -515,17 +487,35 @@ uint16_t X86emu::x86emu_cmd(uint16_t eax, uint16_t ebx, uint16_t ecx,
}
-int X86emu::init(void)
+void X86emu::print_regions()
{
- /*
- * Wait until Acpi/Pci driver initialization is done to avoid potentially
- * concurrently accesses by this driver and the Acpi/Pci driver to the
- * graphic device (PCI config space).
- */
- Platform::Connection conn;
+ log("I/O port regions:");
+ port_region_db->print_regions();
- if (map_code_area())
- return -1;
+ log("I/O memory regions:");
+ mem_region_db->print_regions();
+}
+
+
+void X86emu::printk(const char *format, ...)
+{
+ va_list list;
+ va_start(list, format);
+
+ Genode::vprintf(format, list);
+
+ va_end(list);
+}
+
+
+void X86emu::init(Genode::Env &env, Allocator &heap)
+{
+ local_init_genode_env(env, heap);
+
+ port_region_db.construct(env, heap);
+ mem_region_db.construct(env, heap);
+
+ if (map_code_area()) throw Framebuffer::Fatal();
if (verbose) {
log("--- x86 bios area is ",
@@ -537,25 +527,4 @@ int X86emu::init(void)
X86emu::M.x86.debug = 0;
X86emu::X86EMU_setupPioFuncs(&port_funcs);
X86emu::X86EMU_setupMemFuncs(&mem_funcs);
- return 0;
-}
-
-
-void X86emu::print_regions()
-{
- log("I/O port regions:");
- port_region_db.print_regions();
-
- log("I/O memory regions:");
- mem_region_db.print_regions();
-}
-
-void X86emu::printk(const char *format, ...)
-{
- va_list list;
- va_start(list, format);
-
- vprintf(format, list);
-
- va_end(list);
}
diff --git a/repos/libports/src/drivers/framebuffer/vesa/include/framebuffer.h b/repos/libports/src/drivers/framebuffer/vesa/include/framebuffer.h
index 3f60a12bd5..718fe59e1c 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/include/framebuffer.h
+++ b/repos/libports/src/drivers/framebuffer/vesa/include/framebuffer.h
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2006-2013 Genode Labs GmbH
+ * Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@@ -15,12 +15,19 @@
#ifndef _FRAMEBUFFER_H_
#define _FRAMEBUFFER_H_
-#include
+#include
#include
#include "vbe.h"
-namespace Framebuffer_drv {
+namespace Genode {
+ struct Env;
+ struct Allocator;
+}
+
+namespace Framebuffer {
+
+ struct Fatal { }; /* exception */
/**
* Return capability for h/w framebuffer dataspace
@@ -30,7 +37,7 @@ namespace Framebuffer_drv {
/**
* Initialize driver, x86emu lib, set up memory
*/
- int init();
+ void init(Genode::Env &, Genode::Allocator &);
/**
* Set video, initialize framebuffer dataspace
@@ -42,7 +49,7 @@ namespace Framebuffer_drv {
* \return 0 on success,
* non-zero otherwise
*/
- int set_mode(unsigned long &width, unsigned long &height, unsigned long mode);
+ int set_mode(unsigned &width, unsigned &height, unsigned mode);
/**
* Map given device memory, return out_addr (map address)
diff --git a/repos/libports/src/drivers/framebuffer/vesa/include/genode_env.h b/repos/libports/src/drivers/framebuffer/vesa/include/genode_env.h
new file mode 100644
index 0000000000..46ed0aa4d7
--- /dev/null
+++ b/repos/libports/src/drivers/framebuffer/vesa/include/genode_env.h
@@ -0,0 +1,48 @@
+/*
+ * \brief Utilities for accessing the Genode environment
+ * \author Norman Feske
+ * \date 2017-01-10
+ */
+
+/*
+ * Copyright (C) 2017 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#ifndef _GENODE_ENV_H_
+#define _GENODE_ENV_H_
+
+#include
+#include
+
+static Genode::Env *_env_ptr;
+static inline Genode::Env &genode_env()
+{
+ if (_env_ptr)
+ return *_env_ptr;
+
+ Genode::error("genode env accessed prior initialization");
+ throw 1;
+}
+
+
+static Genode::Allocator *_alloc_ptr;
+static inline Genode::Allocator &alloc()
+{
+ if (_alloc_ptr)
+ return *_alloc_ptr;
+
+ Genode::error("allocator accessed prior initialization");
+ throw 1;
+}
+
+
+static void local_init_genode_env(Genode::Env &env, Genode::Allocator &alloc)
+{
+ _env_ptr = &env;
+ _alloc_ptr = &alloc;
+}
+
+#endif /* _GENODE_ENV_H_ */
diff --git a/repos/libports/src/drivers/framebuffer/vesa/include/hw_emul.h b/repos/libports/src/drivers/framebuffer/vesa/include/hw_emul.h
index 31a31bc453..bf49afef87 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/include/hw_emul.h
+++ b/repos/libports/src/drivers/framebuffer/vesa/include/hw_emul.h
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2010-2013 Genode Labs GmbH
+ * Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@@ -15,6 +15,11 @@
#ifndef _HW_EMUL_H_
#define _HW_EMUL_H_
+
+namespace Genode { struct Env; }
+
+void hw_emul_init(Genode::Env &);
+
/**
* Handle port-read access
*
diff --git a/repos/libports/src/drivers/framebuffer/vesa/include/ifx86emu.h b/repos/libports/src/drivers/framebuffer/vesa/include/ifx86emu.h
index d19c7b6680..7c70c499e4 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/include/ifx86emu.h
+++ b/repos/libports/src/drivers/framebuffer/vesa/include/ifx86emu.h
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2007-2013 Genode Labs GmbH
+ * Copyright (C) 2007-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@@ -17,6 +17,12 @@
#include
+
+namespace Genode {
+ struct Env;
+ struct Allocator;
+}
+
namespace X86emu {
using Genode::addr_t;
@@ -35,9 +41,6 @@ namespace X86emu {
addr_t _bios_addr;
addr_t _data_addr;
- /**
- * Constructur
- */
X86emu_mem() : _bios_addr(0), _data_addr(0) { }
inline addr_t _addr(addr_t* obj_addr, void* addr = 0)
@@ -47,13 +50,8 @@ namespace X86emu {
return *obj_addr;
}
- /**
- * set/get functions
- */
- inline addr_t bios_addr(void *addr = 0) {
- return _addr(&_bios_addr, addr); }
- inline addr_t data_addr(void *addr = 0) {
- return _addr(&_data_addr, addr); }
+ inline addr_t bios_addr(void *addr = 0) { return _addr(&_bios_addr, addr); }
+ inline addr_t data_addr(void *addr = 0) { return _addr(&_data_addr, addr); }
};
/**
@@ -64,7 +62,7 @@ namespace X86emu {
/**
* Initialization
*/
- int init(void);
+ void init(Genode::Env &, Genode::Allocator &);
/**
* Execute real mode command
diff --git a/repos/libports/src/drivers/framebuffer/vesa/main.cc b/repos/libports/src/drivers/framebuffer/vesa/main.cc
index 31690bb6b3..0ef0632b33 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/main.cc
+++ b/repos/libports/src/drivers/framebuffer/vesa/main.cc
@@ -7,249 +7,240 @@
*/
/*
- * Copyright (C) 2007-2013 Genode Labs GmbH
+ * Copyright (C) 2007-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
-/* Genode */
-#include
-#include
-#include
+/* Genode includes */
+#include
+#include
+#include
+#include
#include
-#include
-#include
-#include
-#include
-#include
+#include
+#include
#include
-#include
#include
+#include
-/* Local */
+/* local includes */
#include "framebuffer.h"
-using namespace Genode;
-
-
-/***************
- ** Utilities **
- ***************/
-
-/**
- * Determine session argument value based on config file and session arguments
- *
- * \param attr_name attribute name of config node
- * \param args session argument string
- * \param arg_name argument name
- * \param default default session argument value if value is neither
- * specified in config node nor in session arguments
- */
-unsigned long session_arg(const char *attr_name, const char *args,
- const char *arg_name, unsigned long default_value)
-{
- unsigned long result = default_value;
-
- /* try to obtain value from config file */
- try { Genode::config()->xml_node().attribute(attr_name).value(&result); }
- catch (...) { }
-
- /* check session argument to override value from config file */
- result = Arg_string::find_arg(args, arg_name).ulong_value(result);
- return result;
-}
-
-
-bool config_attribute(const char *attr_name)
-{
- return Genode::config()->xml_node().attribute_value(attr_name, false);
-}
-
-
-/***********************************************
- ** Implementation of the framebuffer service **
- ***********************************************/
namespace Framebuffer {
+ struct Session_component;
+ struct Root;
+ struct Main;
- class Session_component : public Genode::Rpc_object
- {
- private:
-
- unsigned _scr_width, _scr_height, _scr_mode;
- bool _buffered;
-
- /* dataspace uses a back buffer (if '_buffered' is true) */
- Genode::Ram_dataspace_capability _bb_ds;
- void *_bb_addr;
-
- /* dataspace of physical frame buffer */
- Genode::Dataspace_capability _fb_ds;
- void *_fb_addr;
-
- Timer::Connection _timer;
-
- void _refresh_buffered(int x, int y, int w, int h)
- {
- /* clip specified coordinates against screen boundaries */
- int x2 = min(x + w - 1, (int)_scr_width - 1),
- y2 = min(y + h - 1, (int)_scr_height - 1);
- int x1 = max(x, 0),
- y1 = max(y, 0);
- if (x1 > x2 || y1 > y2) return;
-
- /* determine bytes per pixel */
- int bypp = 0;
- if (_scr_mode == 16) bypp = 2;
- if (!bypp) return;
-
- /* copy pixels from back buffer to physical frame buffer */
- char *src = (char *)_bb_addr + bypp*(_scr_width*y1 + x1),
- *dst = (char *)_fb_addr + bypp*(_scr_width*y1 + x1);
-
- blit(src, bypp*_scr_width, dst, bypp*_scr_width,
- bypp*(x2 - x1 + 1), y2 - y1 + 1);
- }
-
- public:
-
- /**
- * Constructor
- */
- Session_component(unsigned scr_width, unsigned scr_height, unsigned scr_mode,
- Genode::Dataspace_capability fb_ds, bool buffered)
- :
- _scr_width(scr_width), _scr_height(scr_height), _scr_mode(scr_mode),
- _buffered(buffered), _fb_ds(fb_ds)
- {
- if (!_buffered) return;
-
- if (scr_mode != 16) {
- Genode::warning("buffered mode not supported for mode ", (int)scr_mode);
- _buffered = false;
- }
-
- size_t buf_size = scr_width*scr_height*scr_mode/8;
- try { _bb_ds = Genode::env()->ram_session()->alloc(buf_size); }
- catch (...) {
- Genode::warning("could not allocate back buffer, disabled buffered output");
- _buffered = false;
- }
-
- if (_buffered && _bb_ds.valid()) {
- _bb_addr = Genode::env()->rm_session()->attach(_bb_ds);
- _fb_addr = Genode::env()->rm_session()->attach(_fb_ds);
- }
-
- if (_buffered)
- Genode::log("using buffered output");
- }
-
- /**
- * Destructor
- */
- ~Session_component()
- {
- if (!_buffered) return;
-
- Genode::env()->rm_session()->detach(_bb_addr);
- Genode::env()->ram_session()->free(_bb_ds);
- Genode::env()->rm_session()->detach(_fb_addr);
- }
-
-
- /***********************************
- ** Framebuffer session interface **
- ***********************************/
-
- Dataspace_capability dataspace() override {
- return _buffered ? Dataspace_capability(_bb_ds)
- : Dataspace_capability(_fb_ds); }
-
- Mode mode() const override
- {
- return Mode(_scr_width, _scr_height,
- _scr_mode == 16 ? Mode::RGB565 : Mode::INVALID);
- }
-
- void mode_sigh(Genode::Signal_context_capability) override { }
-
- void sync_sigh(Genode::Signal_context_capability sigh) override
- {
- _timer.sigh(sigh);
- _timer.trigger_periodic(10*1000);
- }
-
- void refresh(int x, int y, int w, int h) override
- {
- if (_buffered)
- _refresh_buffered(x, y, w, h);
- }
- };
-
-
- /**
- * Shortcut for single-client root component
- */
- typedef Genode::Root_component Root_component;
-
- class Root : public Root_component
- {
- protected:
-
- Session_component *_create_session(const char *args) override
- {
- unsigned long scr_width = session_arg("width", args, "fb_width", 0),
- scr_height = session_arg("height", args, "fb_height", 0),
- scr_mode = session_arg("depth", args, "fb_mode", 16);
- bool buffered = config_attribute("buffered");
-
- if (Framebuffer_drv::set_mode(scr_width, scr_height, scr_mode) != 0) {
- Genode::warning("Could not set vesa mode ",
- scr_width, "x", scr_height, "@", scr_mode);
- throw Root::Invalid_args();
- }
-
- Genode::log("using video mode: ", scr_width, "x", scr_height, "@", scr_mode);
-
- return new (md_alloc()) Session_component(scr_width, scr_height, scr_mode,
- Framebuffer_drv::hw_framebuffer(),
- buffered);
- }
-
- public:
-
- Root(Rpc_entrypoint *session_ep, Allocator *md_alloc)
- : Root_component(session_ep, md_alloc) { }
- };
+ using Genode::size_t;
+ using Genode::min;
+ using Genode::max;
+ using Genode::Dataspace_capability;
+ using Genode::Attached_rom_dataspace;
+ using Genode::Attached_ram_dataspace;
}
-int main(int argc, char **argv)
+class Framebuffer::Session_component : public Genode::Rpc_object
{
- /* We need to create capabilities for sessions. Therefore, we request the
- * CAP service. */
- static Cap_connection cap;
+ private:
- /* initialize server entry point */
- enum { STACK_SIZE = 4*1024*sizeof(long) };
- static Rpc_entrypoint ep(&cap, STACK_SIZE, "vesa_ep");
+ Genode::Env &_env;
- /* init driver back end */
- if (Framebuffer_drv::init()) {
- Genode::error("H/W driver init failed");
- return 3;
+ unsigned const _scr_width, _scr_height, _scr_depth;
+
+ Timer::Connection _timer { _env };
+
+ /* dataspace of physical frame buffer */
+ Dataspace_capability _fb_cap;
+ void *_fb_addr;
+
+ /* dataspace uses a back buffer (if '_buffered' is true) */
+ Genode::Constructible _bb;
+
+ void _refresh_buffered(int x, int y, int w, int h)
+ {
+ /* clip specified coordinates against screen boundaries */
+ int x2 = min(x + w - 1, (int)_scr_width - 1),
+ y2 = min(y + h - 1, (int)_scr_height - 1);
+ int x1 = max(x, 0),
+ y1 = max(y, 0);
+ if (x1 > x2 || y1 > y2) return;
+
+ /* determine bytes per pixel */
+ int bypp = 0;
+ if (_scr_depth == 16) bypp = 2;
+ if (!bypp) return;
+
+ /* copy pixels from back buffer to physical frame buffer */
+ char *src = _bb->local_addr() + bypp*(_scr_width*y1 + x1),
+ *dst = (char *)_fb_addr + bypp*(_scr_width*y1 + x1);
+
+ blit(src, bypp*_scr_width, dst, bypp*_scr_width,
+ bypp*(x2 - x1 + 1), y2 - y1 + 1);
+ }
+
+ bool _buffered() const { return _bb.constructed(); }
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Session_component(Genode::Env &env,
+ unsigned scr_width, unsigned scr_height, unsigned scr_depth,
+ Dataspace_capability fb_cap, bool buffered)
+ :
+ _env(env),
+ _scr_width(scr_width), _scr_height(scr_height), _scr_depth(scr_depth),
+ _fb_cap(fb_cap)
+ {
+ if (!buffered) return;
+
+ if (_scr_depth != 16) {
+ Genode::warning("buffered mode not supported for depth ", _scr_depth);
+ return;
+ }
+
+ size_t const bb_size = _scr_width*_scr_height*_scr_depth/8;
+ try { _bb.construct(env.ram(), env.rm(), bb_size); }
+ catch (...) {
+ Genode::warning("could not allocate back buffer, disabled buffered output");
+ return;
+ }
+
+ _fb_addr = env.rm().attach(_fb_cap);
+
+ Genode::log("using buffered output");
+ }
+
+ /**
+ * Destructor
+ */
+ ~Session_component()
+ {
+ if (_buffered()) {
+ _bb.destruct();
+ _env.rm().detach(_fb_addr);
+ }
+ }
+
+
+ /***********************************
+ ** Framebuffer session interface **
+ ***********************************/
+
+ Dataspace_capability dataspace() override
+ {
+ return _buffered() ? Dataspace_capability(_bb->cap())
+ : Dataspace_capability(_fb_cap);
+ }
+
+ Mode mode() const override
+ {
+ return Mode(_scr_width, _scr_height,
+ _scr_depth == 16 ? Mode::RGB565 : Mode::INVALID);
+ }
+
+ void mode_sigh(Genode::Signal_context_capability) override { }
+
+ void sync_sigh(Genode::Signal_context_capability sigh) override
+ {
+ _timer.sigh(sigh);
+ _timer.trigger_periodic(10*1000);
+ }
+
+ void refresh(int x, int y, int w, int h) override
+ {
+ if (_buffered())
+ _refresh_buffered(x, y, w, h);
+ }
+};
+
+
+/**
+ * Shortcut for single-client root component
+ */
+typedef Genode::Root_component Root_component;
+
+class Framebuffer::Root : public Root_component
+{
+ private:
+
+ Genode::Env &_env;
+
+ Attached_rom_dataspace const &_config;
+
+ unsigned _session_arg(char const *attr_name, char const *args,
+ char const *arg_name, unsigned default_value)
+ {
+ /* try to obtain value from config file */
+ unsigned result = _config.xml().attribute_value(attr_name,
+ default_value);
+
+ /* check session argument to override value from config file */
+ return Genode::Arg_string::find_arg(args, arg_name).ulong_value(result);
+ }
+
+ protected:
+
+ Session_component *_create_session(char const *args) override
+ {
+ unsigned scr_width = _session_arg("width", args, "fb_width", 0);
+ unsigned scr_height = _session_arg("height", args, "fb_height", 0);
+ unsigned const scr_depth = _session_arg("depth", args, "fb_mode", 16);
+
+ bool const buffered = _config.xml().attribute_value("buffered", false);
+
+ if (Framebuffer::set_mode(scr_width, scr_height, scr_depth) != 0) {
+ Genode::warning("Could not set vesa mode ",
+ scr_width, "x", scr_height, "@", scr_depth);
+ throw Root::Invalid_args();
+ }
+
+ Genode::log("using video mode: ",
+ scr_width, "x", scr_height, "@", scr_depth);
+
+ return new (md_alloc()) Session_component(_env,
+ scr_width, scr_height, scr_depth,
+ Framebuffer::hw_framebuffer(),
+ buffered);
+ }
+
+ public:
+
+ Root(Genode::Env &env, Genode::Allocator &alloc,
+ Attached_rom_dataspace const &config)
+ :
+ Root_component(&env.ep().rpc_ep(), &alloc),
+ _env(env), _config(config)
+ { }
+};
+
+
+struct Framebuffer::Main
+{
+ Genode::Env &env;
+
+ Genode::Heap heap { env.ram(), env.rm() };
+
+ Attached_rom_dataspace config { env, "config" };
+
+ Root root { env, heap, config };
+
+ Main(Genode::Env &env) : env(env)
+ {
+ try { Framebuffer::init(env, heap); } catch (...) {
+ Genode::error("H/W driver init failed");
+ throw;
+ }
+
+ env.parent().announce(env.ep().manage(root));
}
+};
- /* entry point serving framebuffer root interface */
- static Framebuffer::Root fb_root(&ep, env()->heap());
- /* tell parent about the service */
- env()->parent()->announce(ep.manage(&fb_root));
-
- /* main's done - go to sleep */
-
- sleep_forever();
- return 0;
-}
+void Component::construct(Genode::Env &env) { static Framebuffer::Main inst(env); }
diff --git a/repos/libports/src/drivers/framebuffer/vesa/target.mk b/repos/libports/src/drivers/framebuffer/vesa/target.mk
index cb0b71000d..d1b8298ebc 100644
--- a/repos/libports/src/drivers/framebuffer/vesa/target.mk
+++ b/repos/libports/src/drivers/framebuffer/vesa/target.mk
@@ -1,5 +1,5 @@
TARGET = fb_drv
-REQUIRES = vesa
+REQUIRES = x86
SRC_CC = main.cc framebuffer.cc ifx86emu.cc hw_emul.cc
-LIBS = base blit x86emu config
+LIBS = base blit x86emu
INC_DIR += $(PRG_DIR)/include $(REP_DIR)/include/x86emu