mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
parent
54865fdd0f
commit
251aa95d96
@ -84,11 +84,9 @@ extern int dde_ipxe_nic_link_state(unsigned if_index);
|
||||
/**
|
||||
* Initialize network sub-system
|
||||
*
|
||||
* \param ep pointer to Server::Entrypoint
|
||||
*
|
||||
* \return number of network devices
|
||||
*/
|
||||
extern int dde_ipxe_nic_init(void *ep);
|
||||
extern int dde_ipxe_nic_init();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
30
repos/dde_ipxe/include/dde_ipxe/support.h
Normal file
30
repos/dde_ipxe/include/dde_ipxe/support.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief DDE iPXE SUPPORT API
|
||||
* \author Josef Soentgen
|
||||
* \date 2017-02-08
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _DDE_IPXE__SUPPORT_H_
|
||||
#define _DDE_IPXE__SUPPORT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/**
|
||||
* Initialize DDE support
|
||||
*
|
||||
* This function needs to be called before any dde_ipxe_* function
|
||||
* is used.
|
||||
*/
|
||||
void dde_support_init(Genode::Env &, Genode::Allocator &alloc);
|
||||
|
||||
#endif /* _DDE_IPXE__SUPPORT_H_ */
|
@ -16,11 +16,11 @@
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/log.h>
|
||||
#include <nic/component.h>
|
||||
#include <nic/root.h>
|
||||
|
||||
#include <dde_ipxe/support.h>
|
||||
#include <dde_ipxe/nic.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -103,7 +103,7 @@ class Ipxe_session_component : public Nic::Session_component
|
||||
Genode::Allocator &rx_block_md_alloc,
|
||||
Genode::Ram_session &ram_session,
|
||||
Genode::Region_map ®ion_map,
|
||||
Server::Entrypoint &ep)
|
||||
Genode::Entrypoint &ep)
|
||||
: Session_component(tx_buf_size, rx_buf_size, rx_block_md_alloc,
|
||||
ram_session, region_map, ep)
|
||||
{
|
||||
@ -151,12 +151,16 @@ struct Main
|
||||
Genode::log("--- iPXE NIC driver started ---");
|
||||
|
||||
Genode::log("-- init iPXE NIC");
|
||||
int cnt = dde_ipxe_nic_init(&_env.ep());
|
||||
Genode::log(" number of devices: ", cnt);
|
||||
|
||||
/* pass Env to backend */
|
||||
dde_support_init(_env, _heap);
|
||||
|
||||
if (!dde_ipxe_nic_init()) {
|
||||
Genode::error("could not find usable NIC device");
|
||||
}
|
||||
|
||||
_env.parent().announce(_env.ep().manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
void Component::construct(Genode::Env &env) { static Main main(env); }
|
||||
|
||||
|
@ -25,12 +25,10 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/log.h>
|
||||
#include <base/slab.h>
|
||||
#include <base/sleep.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <io_port_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <os/server.h>
|
||||
#include <platform_device/client.h>
|
||||
#include <platform_session/connection.h>
|
||||
#include <rm_session/connection.h>
|
||||
@ -38,20 +36,35 @@
|
||||
#include <timer_session/connection.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <util/retry.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
/* local includes */
|
||||
#include <dde_support.h>
|
||||
|
||||
/* DDE support includes */
|
||||
#include <dde_ipxe/support.h>
|
||||
|
||||
/****************
|
||||
** Migriation **
|
||||
****************/
|
||||
|
||||
static Server::Entrypoint *_ep;
|
||||
static Genode::Entrypoint *_global_ep;
|
||||
static Genode::Env *_global_env;
|
||||
static Genode::Allocator *_global_alloc;
|
||||
|
||||
extern "C" void dde_init(void *ep)
|
||||
|
||||
void dde_support_init(Genode::Env &env, Genode::Allocator &alloc)
|
||||
{
|
||||
_ep = (Server::Entrypoint*)ep;
|
||||
_global_env = &env;
|
||||
_global_ep = &env.ep();
|
||||
_global_alloc = &alloc;
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** Initialization check **
|
||||
**************************/
|
||||
|
||||
extern "C" int dde_support_initialized(void)
|
||||
{
|
||||
return !!_global_env;
|
||||
}
|
||||
|
||||
|
||||
@ -76,14 +89,20 @@ extern "C" void dde_printf(const char *fmt, ...)
|
||||
** Timer **
|
||||
***********/
|
||||
|
||||
static Genode::Constructible<Timer::Connection> _timer;
|
||||
|
||||
|
||||
extern "C" void dde_udelay(unsigned long usecs)
|
||||
{
|
||||
if (!_timer.constructed()) {
|
||||
_timer.construct(*_global_env);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called only once during rdtsc calibration (usecs will be
|
||||
* 10000, see dde.c 'udelay'.
|
||||
*/
|
||||
static Timer::Connection timer;
|
||||
timer.usleep(usecs);
|
||||
_timer->usleep(usecs);
|
||||
}
|
||||
|
||||
|
||||
@ -102,13 +121,15 @@ extern "C" void dde_lock_leave(void) { _ipxe_lock.unlock(); }
|
||||
|
||||
extern "C" void dde_mdelay(unsigned long msecs)
|
||||
{
|
||||
if (!_timer.constructed()) {
|
||||
_timer.construct(*_global_env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Using one static timer connection here is safe because
|
||||
* this function is only called while initializing the device
|
||||
* This function is only called while initializing the device
|
||||
* and only be the same thread.
|
||||
*/
|
||||
static Timer::Connection timer;
|
||||
timer.msleep(msecs);
|
||||
_timer->msleep(msecs);
|
||||
}
|
||||
|
||||
|
||||
@ -124,6 +145,8 @@ struct Pci_driver
|
||||
CLASS_NETWORK = PCI_BASE_CLASS_NETWORK << 16
|
||||
};
|
||||
|
||||
Genode::Region_map &_rm;
|
||||
|
||||
Platform::Connection _pci;
|
||||
Platform::Device_capability _cap;
|
||||
Platform::Device_capability _last_cap;
|
||||
@ -138,12 +161,9 @@ struct Pci_driver
|
||||
Platform::Device::Access_size _access_size(T t)
|
||||
{
|
||||
switch (sizeof(T)) {
|
||||
case 1:
|
||||
return Platform::Device::ACCESS_8BIT;
|
||||
case 2:
|
||||
return Platform::Device::ACCESS_16BIT;
|
||||
default:
|
||||
return Platform::Device::ACCESS_32BIT;
|
||||
case 1: return Platform::Device::ACCESS_8BIT;
|
||||
case 2: return Platform::Device::ACCESS_16BIT;
|
||||
default: return Platform::Device::ACCESS_32BIT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +179,8 @@ struct Pci_driver
|
||||
}
|
||||
|
||||
|
||||
Pci_driver() { }
|
||||
Pci_driver(Genode::Env &env, Genode::Region_map &rm)
|
||||
: _rm(rm), _pci(env) { }
|
||||
|
||||
template <typename T>
|
||||
void config_read(unsigned int devfn, T *val)
|
||||
@ -229,7 +250,7 @@ struct Pci_driver
|
||||
donate = donate * 2 > size ? 4096 : donate * 2;
|
||||
});
|
||||
|
||||
_region.mapped_base = (Genode::addr_t)env()->rm_session()->attach(ram_cap);
|
||||
_region.mapped_base = _rm.attach(ram_cap);
|
||||
_region.base = Dataspace_client(ram_cap).phys_addr();
|
||||
|
||||
return _region.mapped_base;
|
||||
@ -246,7 +267,7 @@ struct Pci_driver
|
||||
|
||||
static Pci_driver& pci_drv()
|
||||
{
|
||||
static Pci_driver _pci_drv;
|
||||
static Pci_driver _pci_drv { *_global_env , _global_env->rm() };
|
||||
return _pci_drv;
|
||||
}
|
||||
|
||||
@ -289,25 +310,24 @@ extern "C" void dde_pci_writel(int pos, dde_uint32_t val) {
|
||||
|
||||
struct Irq_handler
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Genode::Irq_session_client irq;
|
||||
Genode::Signal_rpc_member<Irq_handler> dispatcher;
|
||||
Genode::Irq_session_client irq;
|
||||
Genode::Signal_handler<Irq_handler> dispatcher;
|
||||
|
||||
typedef void (*irq_handler)(void*);
|
||||
|
||||
irq_handler handler;
|
||||
void *priv;
|
||||
|
||||
void handle(unsigned)
|
||||
void handle()
|
||||
{
|
||||
handler(priv);
|
||||
irq.ack_irq();
|
||||
}
|
||||
|
||||
Irq_handler(Server::Entrypoint &ep, Genode::Irq_session_capability cap,
|
||||
Irq_handler(Genode::Entrypoint &ep, Genode::Irq_session_capability cap,
|
||||
irq_handler handler, void *priv)
|
||||
:
|
||||
ep(ep), irq(cap), dispatcher(ep, *this, &Irq_handler::handle),
|
||||
irq(cap), dispatcher(ep, *this, &Irq_handler::handle),
|
||||
handler(handler), priv(priv)
|
||||
{
|
||||
irq.sigh(dispatcher);
|
||||
@ -317,19 +337,20 @@ struct Irq_handler
|
||||
}
|
||||
};
|
||||
|
||||
static Irq_handler *_irq_handler;
|
||||
|
||||
static Genode::Constructible<Irq_handler> _irq_handler;
|
||||
|
||||
|
||||
extern "C" int dde_interrupt_attach(void(*handler)(void *), void *priv)
|
||||
{
|
||||
if (_irq_handler) {
|
||||
if (_irq_handler.constructed()) {
|
||||
Genode::error("Irq_handler already registered");
|
||||
Genode::sleep_forever();
|
||||
return -1;
|
||||
}
|
||||
|
||||
try {
|
||||
Platform::Device_client device(pci_drv()._cap);
|
||||
_irq_handler = new (Genode::env()->heap())
|
||||
Irq_handler(*_ep, device.irq(0), handler, priv);
|
||||
_irq_handler.construct(*_global_ep, device.irq(0), handler, priv);
|
||||
} catch (...) { return -1; }
|
||||
|
||||
return 0;
|
||||
@ -344,8 +365,10 @@ enum { BACKING_STORE_SIZE = 1024 * 1024 };
|
||||
|
||||
struct Backing_store
|
||||
{
|
||||
Genode::Allocator_avl _avl{Genode::env()->heap()};
|
||||
Backing_store(){
|
||||
Genode::Allocator_avl _avl;
|
||||
|
||||
Backing_store (Genode::Allocator &alloc) : _avl(&alloc)
|
||||
{
|
||||
Genode::addr_t base = pci_drv().alloc_dma_memory(BACKING_STORE_SIZE);
|
||||
/* add to allocator */
|
||||
_avl.add_range(base, BACKING_STORE_SIZE);
|
||||
@ -355,7 +378,7 @@ struct Backing_store
|
||||
|
||||
static Genode::Allocator_avl& allocator()
|
||||
{
|
||||
static Backing_store _instance;
|
||||
static Backing_store _instance { *_global_alloc };
|
||||
return _instance._avl;
|
||||
|
||||
}
|
||||
@ -388,18 +411,19 @@ extern "C" dde_addr_t dde_dma_get_physaddr(void *virt) {
|
||||
** I/O port **
|
||||
**************/
|
||||
|
||||
static Genode::Io_port_session_client *_io_port;
|
||||
static Genode::Constructible<Genode::Io_port_session_client> _io_port;
|
||||
|
||||
|
||||
extern "C" void dde_request_io(dde_uint8_t virt_bar_ioport)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (_io_port) destroy(env()->heap(), _io_port);
|
||||
if (_io_port.constructed()) { _io_port.destruct(); }
|
||||
|
||||
Platform::Device_client device(pci_drv()._cap);
|
||||
Io_port_session_capability cap = device.io_port(virt_bar_ioport);
|
||||
|
||||
_io_port = new (env()->heap()) Io_port_session_client(cap);
|
||||
_io_port.construct(cap);
|
||||
}
|
||||
|
||||
|
||||
@ -469,13 +493,16 @@ struct Slab_backend_alloc : public Genode::Allocator,
|
||||
return true;
|
||||
}
|
||||
|
||||
Slab_backend_alloc(Genode::Ram_session &ram)
|
||||
Slab_backend_alloc(Genode::Env &env, Genode::Region_map &rm,
|
||||
Genode::Ram_session &ram,
|
||||
Genode::Allocator &md_alloc)
|
||||
:
|
||||
Rm_connection(env),
|
||||
Region_map_client(Rm_connection::create(VM_SIZE)),
|
||||
_index(0), _range(Genode::env()->heap()), _ram(ram)
|
||||
_index(0), _range(&md_alloc), _ram(ram)
|
||||
{
|
||||
/* reserver attach us, anywere */
|
||||
_base = Genode::env()->rm_session()->attach(dataspace());
|
||||
_base = rm.attach(dataspace());
|
||||
}
|
||||
|
||||
Genode::addr_t start() const { return _base; }
|
||||
@ -545,16 +572,17 @@ struct Slab
|
||||
NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1,
|
||||
};
|
||||
|
||||
Slab_alloc *_allocator[NUM_SLABS];
|
||||
Genode::addr_t _start;
|
||||
Genode::addr_t _end;
|
||||
Genode::Constructible<Slab_alloc> _allocator[NUM_SLABS];
|
||||
|
||||
Genode::addr_t _start;
|
||||
Genode::addr_t _end;
|
||||
|
||||
Slab(Slab_backend_alloc &alloc)
|
||||
: _start(alloc.start()), _end(alloc.end())
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_SLABS; i++)
|
||||
_allocator[i] = new (Genode::env()->heap())
|
||||
Slab_alloc(1U << (SLAB_START_LOG2 + i), alloc);
|
||||
for (unsigned i = 0; i < NUM_SLABS; i++) {
|
||||
_allocator[i].construct(1U << (SLAB_START_LOG2 + i), alloc);
|
||||
}
|
||||
}
|
||||
|
||||
void *alloc(Genode::size_t size)
|
||||
@ -585,7 +613,6 @@ struct Slab
|
||||
|
||||
void free(void *p)
|
||||
{
|
||||
using namespace Genode;
|
||||
Genode::addr_t *addr = ((Genode::addr_t *)p)-1;
|
||||
unsigned index = *(unsigned*)(addr);
|
||||
_allocator[index]->free((void*)(addr));
|
||||
@ -595,7 +622,8 @@ struct Slab
|
||||
|
||||
static ::Slab& slab()
|
||||
{
|
||||
static ::Slab_backend_alloc sb(*Genode::env()->ram_session());
|
||||
static ::Slab_backend_alloc sb(*_global_env, _global_env->rm(),
|
||||
_global_env->ram(), *_global_alloc);
|
||||
static ::Slab s(sb);
|
||||
return s;
|
||||
}
|
||||
@ -620,7 +648,8 @@ struct Io_memory
|
||||
|
||||
Genode::addr_t _vaddr;
|
||||
|
||||
Io_memory(Genode::addr_t base, Genode::Io_mem_session_capability cap)
|
||||
Io_memory(Genode::Region_map &rm,
|
||||
Genode::addr_t base, Genode::Io_mem_session_capability cap)
|
||||
:
|
||||
_mem(cap),
|
||||
_mem_ds(_mem.dataspace())
|
||||
@ -628,7 +657,7 @@ struct Io_memory
|
||||
if (!_mem_ds.valid())
|
||||
throw Genode::Exception();
|
||||
|
||||
_vaddr = Genode::env()->rm_session()->attach(_mem_ds);
|
||||
_vaddr = rm.attach(_mem_ds);
|
||||
_vaddr |= base & 0xfff;
|
||||
}
|
||||
|
||||
@ -636,14 +665,14 @@ struct Io_memory
|
||||
};
|
||||
|
||||
|
||||
static Io_memory *_io_mem;
|
||||
static Genode::Constructible<Io_memory> _io_mem;
|
||||
|
||||
|
||||
extern "C" int dde_request_iomem(dde_addr_t start, dde_addr_t *vaddr)
|
||||
{
|
||||
if (_io_mem) {
|
||||
if (_io_mem.constructed()) {
|
||||
Genode::error("Io_memory already requested");
|
||||
Genode::sleep_forever();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Platform::Device_client device(pci_drv()._cap);
|
||||
@ -660,11 +689,11 @@ extern "C" int dde_request_iomem(dde_addr_t start, dde_addr_t *vaddr)
|
||||
virt_iomem_bar ++;
|
||||
}
|
||||
}
|
||||
if (!cap.valid())
|
||||
return -1;
|
||||
|
||||
if (!cap.valid()) { return -1; }
|
||||
|
||||
try {
|
||||
_io_mem = new (Genode::env()->heap()) Io_memory(start, cap);
|
||||
_io_mem.construct(_global_env->rm(), start, cap);
|
||||
} catch (...) { return -1; }
|
||||
|
||||
*vaddr = _io_mem->vaddr();
|
||||
@ -675,8 +704,7 @@ extern "C" int dde_request_iomem(dde_addr_t start, dde_addr_t *vaddr)
|
||||
extern "C" int dde_release_iomem(dde_addr_t start, dde_size_t size)
|
||||
{
|
||||
try {
|
||||
destroy(Genode::env()->heap(), _io_mem);
|
||||
_io_mem = 0;
|
||||
_io_mem.destruct();
|
||||
return 0;
|
||||
} catch (...) { return -1; }
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ typedef unsigned int dde_uint32_t;
|
||||
/*****************
|
||||
** Initialization
|
||||
*****************/
|
||||
void dde_init(void *ep);
|
||||
|
||||
int dde_support_initialized(void);
|
||||
|
||||
|
||||
/***********
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <ipxe/iobuf.h>
|
||||
|
||||
#include <dde_ipxe/nic.h>
|
||||
|
||||
/* local includes */
|
||||
#include "local.h"
|
||||
#include <dde_support.h>
|
||||
@ -290,9 +291,11 @@ int dde_ipxe_nic_get_mac_addr(unsigned if_index, unsigned char *out_mac_addr)
|
||||
}
|
||||
|
||||
|
||||
int dde_ipxe_nic_init(void *ep)
|
||||
int dde_ipxe_nic_init()
|
||||
{
|
||||
dde_init(ep);
|
||||
if (!dde_support_initialized()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dde_lock_enter();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user