diff --git a/repos/os/src/drivers/nic/spec/lan9118/lan9118.h b/repos/os/src/drivers/nic/spec/lan9118/lan9118.h index 22c6575ca..aee02cc6c 100644 --- a/repos/os/src/drivers/nic/spec/lan9118/lan9118.h +++ b/repos/os/src/drivers/nic/spec/lan9118/lan9118.h @@ -1,11 +1,12 @@ /* * \brief LAN9118 NIC driver * \author Norman Feske + * \author Stefan Kalkowski * \date 2011-05-21 */ /* - * Copyright (C) 2011-2013 Genode Labs GmbH + * Copyright (C) 2011-2016 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. @@ -14,15 +15,14 @@ #ifndef _DRIVERS__NIC__SPEC__LAN9118__LAN9118_H_ #define _DRIVERS__NIC__SPEC__LAN9118__LAN9118_H_ +#include #include #include -#include -#include +#include #include #include -class Lan9118 : public Nic::Session_component, - public Genode::Irq_handler +class Lan9118 : public Nic::Session_component { private: @@ -72,9 +72,8 @@ class Lan9118 : public Nic::Session_component, volatile Genode::uint32_t *_reg_base; Timer::Connection _timer; Nic::Mac_address _mac_addr; - - enum { IRQ_STACK_SIZE = 4096 }; - Genode::Irq_activation _irq_activation; + Genode::Irq_connection _irq; + Genode::Signal_handler _irq_handler; /** * Information about a received packet, used internally @@ -249,6 +248,43 @@ class Lan9118 : public Nic::Session_component, while (_send()) ; } + void _handle_irq() + { + using namespace Genode; + + _handle_packet_stream(); + + while (_rx_packet_avail() && _rx.source()->ready_to_submit()) { + + /* read packet from NIC, copy to client buffer */ + Rx_packet_info packet = _rx_packet_info(); + + /* align size to 32-bit boundary */ + size_t const size = align_addr(packet.size, 2); + + /* allocate rx packet buffer */ + Nic::Packet_descriptor p; + try { + p = _rx.source()->alloc_packet(size); + } catch (Session::Rx::Source::Packet_alloc_failed) { return; } + + uint32_t *dst = (uint32_t *)_rx.source()->packet_content(p); + + /* calculate number of words to be read from rx fifo */ + size_t count = min(size, _rx_data_pending()) >> 2; + + /* copy payload from rx fifo to client buffer */ + for (; count--; ) + *dst++ = _reg_read(RX_DATA_FIFO); + + _rx.source()->submit_packet(p); + } + + /* acknowledge all pending irqs */ + _reg_write(INT_STS, ~0); + + _irq.ack_irq(); + } public: @@ -266,13 +302,17 @@ class Lan9118 : public Nic::Session_component, Genode::size_t const tx_buf_size, Genode::size_t const rx_buf_size, Genode::Allocator &rx_block_md_alloc, - Genode::Ram_session &ram_session, - Server::Entrypoint &ep) - : Session_component(tx_buf_size, rx_buf_size, rx_block_md_alloc, ram_session, ep), - _mmio(mmio_base, mmio_size), - _reg_base(_mmio.local_addr()), - _irq_activation(irq, *this, IRQ_STACK_SIZE) + Genode::Env &env) + : Session_component(tx_buf_size, rx_buf_size, rx_block_md_alloc, + env.ram(), env.ep()), + _mmio(env, mmio_base, mmio_size), + _reg_base(_mmio.local_addr()), + _irq(env, irq), + _irq_handler(env.ep(), *this, &Lan9118::_handle_irq) { + _irq.sigh(_irq_handler); + _irq.ack_irq(); + unsigned long const id_rev = _reg_read(ID_REV), byte_order = _reg_read(BYTE_TEST); @@ -367,47 +407,6 @@ class Lan9118 : public Nic::Session_component, /* XXX always return true for now */ return true; } - - - /****************************** - ** Irq_activation interface ** - ******************************/ - - void handle_irq(int) - { - using namespace Genode; - - _handle_packet_stream(); - - while (_rx_packet_avail() && _rx.source()->ready_to_submit()) { - - /* read packet from NIC, copy to client buffer */ - Rx_packet_info packet = _rx_packet_info(); - - /* align size to 32-bit boundary */ - size_t const size = align_addr(packet.size, 2); - - /* allocate rx packet buffer */ - Nic::Packet_descriptor p; - try { - p = _rx.source()->alloc_packet(size); - } catch (Session::Rx::Source::Packet_alloc_failed) { return; } - - uint32_t *dst = (uint32_t *)_rx.source()->packet_content(p); - - /* calculate number of words to be read from rx fifo */ - size_t count = min(size, _rx_data_pending()) >> 2; - - /* copy payload from rx fifo to client buffer */ - for (; count--; ) - *dst++ = _reg_read(RX_DATA_FIFO); - - _rx.source()->submit_packet(p); - } - - /* acknowledge all pending irqs */ - _reg_write(INT_STS, ~0); - } }; #endif /* _DRIVERS__NIC__SPEC__LAN9118__LAN9118_H_ */ diff --git a/repos/os/src/drivers/nic/spec/lan9118/main.cc b/repos/os/src/drivers/nic/spec/lan9118/main.cc index 0e653d05b..68655cc18 100644 --- a/repos/os/src/drivers/nic/spec/lan9118/main.cc +++ b/repos/os/src/drivers/nic/spec/lan9118/main.cc @@ -1,6 +1,7 @@ /* * \brief LAN9118 NIC driver * \author Norman Feske + * \author Stefan Kalkowski * \date 2011-05-19 * * Note, this driver is only tested on Qemu. At the current stage, it is not @@ -8,17 +9,17 @@ */ /* - * Copyright (C) 2011-2013 Genode Labs GmbH + * Copyright (C) 2011-2016 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 /* device definitions */ @@ -27,13 +28,11 @@ /* driver code */ #include -namespace Server { struct Main; } - class Root : public Genode::Root_component { private: - Server::Entrypoint &_ep; + Genode::Env &_env; protected: @@ -63,42 +62,26 @@ class Root : public Genode::Root_component return new (Root::md_alloc()) Lan9118(LAN9118_PHYS, LAN9118_SIZE, LAN9118_IRQ, - tx_buf_size, rx_buf_size, - *env()->heap(), - *env()->ram_session(), - _ep); + tx_buf_size, rx_buf_size, *md_alloc(), _env); } public: - Root(Server::Entrypoint &ep, Genode::Allocator &md_alloc) - : Genode::Root_component(&ep.rpc_ep(), &md_alloc), - _ep(ep) - { } + Root(Genode::Env &env, Genode::Allocator &md_alloc) + : Genode::Root_component(env.ep(), md_alloc), + _env(env) { } }; -struct Server::Main + +Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); } + + +void Component::construct(Genode::Env &env) { - Entrypoint &ep; - ::Root nic_root{ ep, *Genode::env()->heap() }; - - Main(Entrypoint &ep) : ep(ep) - { - log("--- LAN9118 NIC driver started ---"); - Genode::env()->parent()->announce(ep.manage(nic_root)); - } -}; - - -namespace Server { - - char const *name() { return "nic_ep"; } - - size_t stack_size() { return 2*1024*sizeof(long); } - - void construct(Entrypoint &ep) - { - static Main main(ep); - } + static Genode::Heap heap(env.ram(), env.rm()); + static Root nic_root(env, heap); + Genode::log("--- LAN9118 NIC driver started ---"); + env.parent().announce(env.ep().manage(nic_root)); } diff --git a/repos/os/src/drivers/nic/spec/lan9118/target.mk b/repos/os/src/drivers/nic/spec/lan9118/target.mk index 34d51e6ea..5e8635fe9 100644 --- a/repos/os/src/drivers/nic/spec/lan9118/target.mk +++ b/repos/os/src/drivers/nic/spec/lan9118/target.mk @@ -1,5 +1,5 @@ REQUIRES = lan9118 TARGET = nic_drv SRC_CC = main.cc -LIBS = base server +LIBS = base INC_DIR += $(PRG_DIR)