mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 15:29:57 +00:00
parent
d10a69c7bc
commit
e2a23a0ab3
@ -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 <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/stdint.h>
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <platform_session/connection.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@ -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 <base/sleep.h>
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <util/retry.h>
|
||||
|
||||
/* 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> 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); }
|
||||
|
@ -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 <base/log.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/attached_io_mem_dataspace.h>
|
||||
#include <util/avl_tree.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
|
||||
#include <util/reconstructible.h>
|
||||
#include <io_port_session/connection.h>
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <platform_session/connection.h>
|
||||
|
||||
#include <base/printf.h> /* 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<Region>
|
||||
|
||||
|
||||
template <typename TYPE>
|
||||
class Region_database : public Avl_tree<Region>
|
||||
struct Region_database : Avl_tree<Region>
|
||||
{
|
||||
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<TYPE *>(first()->match(base, size));
|
||||
TYPE * match(addr_t base, size_t size)
|
||||
{
|
||||
if (!first()) return 0;
|
||||
|
||||
return static_cast<TYPE *>(first()->match(base, size));
|
||||
}
|
||||
|
||||
TYPE * meet(addr_t base, size_t size)
|
||||
{
|
||||
if (!first()) return 0;
|
||||
|
||||
return static_cast<TYPE *>(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<addr_t>(region->base()));
|
||||
end = max(end, static_cast<addr_t>(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<TYPE *>(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<addr_t>(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<addr_t>(region->base()));
|
||||
end = max(end, static_cast<addr_t>(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<addr_t>(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<uint16_t>(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<uint16_t>(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<void>());
|
||||
}
|
||||
|
||||
class Io_mem_dataspace : public Io_mem_connection
|
||||
{
|
||||
private:
|
||||
~Mem_region()
|
||||
{
|
||||
if (verbose) Genode::log("del mem ", *this);
|
||||
}
|
||||
|
||||
void *_local_addr;
|
||||
template <typename T>
|
||||
T * virt_addr(addr_t addr)
|
||||
{
|
||||
return reinterpret_cast<T *>(local_addr<char>() + (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 <typename T>
|
||||
T * local_addr() { return static_cast<T *>(_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<addr_t>(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<void>());
|
||||
}
|
||||
|
||||
~Mem_region()
|
||||
{
|
||||
if (verbose)
|
||||
Genode::log("del mem ", *this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T * virt_addr(addr_t addr)
|
||||
{
|
||||
return reinterpret_cast<T *>(_ds.local_addr<char>() + (addr - base()));
|
||||
}
|
||||
void print(Genode::Output &out) const
|
||||
{
|
||||
addr_t const beg = base(), end = beg + size();
|
||||
Genode::print(out, Hex_range<addr_t>(beg, end - beg));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Region_database<Port_region> port_region_db;
|
||||
static Region_database<Mem_region> mem_region_db;
|
||||
static Genode::Constructible<Region_database<Port_region>> port_region_db;
|
||||
static Genode::Constructible<Region_database<Mem_region>> 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<void>();
|
||||
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<TYPE>(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);
|
||||
}
|
||||
|
@ -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 <base/capability.h>
|
||||
#include <dataspace/capability.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
#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)
|
||||
|
@ -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 <base/component.h>
|
||||
#include <base/log.h>
|
||||
|
||||
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_ */
|
@ -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
|
||||
*
|
||||
|
@ -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 <base/stdint.h>
|
||||
|
||||
|
||||
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
|
||||
|
@ -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 <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/rpc_server.h>
|
||||
/* Genode includes */
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <root/component.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <blit/blit.h>
|
||||
#include <os/config.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
|
||||
/* 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<Session>
|
||||
{
|
||||
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<Session_component, Genode::Single_client> 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<Session>
|
||||
{
|
||||
/* 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<Attached_ram_dataspace> _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<char>() + 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<Framebuffer::Session_component,
|
||||
Genode::Single_client> 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); }
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user