From 9606abc14629cc4b9c05a10dcff3701a97229958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 26 Mar 2015 13:47:14 +0100 Subject: [PATCH] dde_ipxe: remove dde_kit A long long time ago, in a galaxy^W^W^W we used DDE kit to ease the porting of purely C based drivers. By now it became clear, that we do not gain that much by following this approach. DDE kit contains much generic functionality, which is not used or rather not needed by most ported drivers. Hence, we implement a slim C wrapper on top of Genode's C++ APIs, that is especially tailored to the driver. In addition to removing the dependency on DDE kit, the iPXE driver now uses the server framework and the newly introduced signal based IRQ handling. Issue #1456. --- repos/dde_ipxe/include/dde_ipxe/nic.h | 12 +- repos/dde_ipxe/lib/mk/dde_ipxe_nic.inc | 16 +- repos/dde_ipxe/lib/mk/dde_ipxe_support.mk | 5 - repos/dde_ipxe/patches/dde_ipxe.patch | 26 - repos/dde_ipxe/ports/dde_ipxe.hash | 2 +- repos/dde_ipxe/src/drivers/nic/main.cc | 86 ++- repos/dde_ipxe/src/drivers/nic/target.mk | 2 +- repos/dde_ipxe/src/drivers/nic_stat/main.cc | 92 +-- repos/dde_ipxe/src/drivers/nic_stat/target.mk | 2 +- repos/dde_ipxe/src/lib/dde_ipxe/dde.c | 175 ++--- .../dde_ipxe/src/lib/dde_ipxe/dde_support.cc | 643 ++++++++++++++++-- repos/dde_ipxe/src/lib/dde_ipxe/dde_support.h | 26 - repos/dde_ipxe/src/lib/dde_ipxe/dummies.c | 4 +- .../src/lib/dde_ipxe/include/dde_support.h | 128 ++++ .../src/lib/dde_ipxe/include/env_dde_kit.h | 14 +- repos/dde_ipxe/src/lib/dde_ipxe/local.h | 15 +- repos/dde_ipxe/src/lib/dde_ipxe/nic.c | 168 ++--- 17 files changed, 956 insertions(+), 460 deletions(-) delete mode 100644 repos/dde_ipxe/lib/mk/dde_ipxe_support.mk delete mode 100644 repos/dde_ipxe/src/lib/dde_ipxe/dde_support.h create mode 100644 repos/dde_ipxe/src/lib/dde_ipxe/include/dde_support.h diff --git a/repos/dde_ipxe/include/dde_ipxe/nic.h b/repos/dde_ipxe/include/dde_ipxe/nic.h index 3ae0a57ea..cecffe785 100644 --- a/repos/dde_ipxe/include/dde_ipxe/nic.h +++ b/repos/dde_ipxe/include/dde_ipxe/nic.h @@ -15,6 +15,10 @@ #ifndef _DDE_IPXE__NIC_H_ #define _DDE_IPXE__NIC_H_ +#ifdef __cplusplus +extern "C" { +#endif + /** * Link-state change callback */ @@ -74,8 +78,14 @@ 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); +extern int dde_ipxe_nic_init(void *ep); + +#ifdef __cplusplus +} /* extern "C" */ +#endif #endif /* _DDE_IPXE__NIC_H_ */ diff --git a/repos/dde_ipxe/lib/mk/dde_ipxe_nic.inc b/repos/dde_ipxe/lib/mk/dde_ipxe_nic.inc index a5c595df2..545a102a8 100644 --- a/repos/dde_ipxe/lib/mk/dde_ipxe_nic.inc +++ b/repos/dde_ipxe/lib/mk/dde_ipxe_nic.inc @@ -1,9 +1,8 @@ LIB_DIR := $(REP_DIR)/src/lib/dde_ipxe IPXE_CONTRIB_DIR := $(call select_from_ports,dde_ipxe)/src/lib/dde_ipxe/src -LIBS = dde_kit dde_ipxe_support - -SRC_C = nic.c dde.c dummies.c +SRC_CC = dde_support.cc +SRC_C = nic.c dde.c dummies.c SRC_C += $(addprefix core/, iobuf.c string.c bitops.c list.c random.c) SRC_C += $(addprefix arch/x86/core/, x86_string.c) @@ -21,7 +20,7 @@ INC_DIR += $(IPXE_CONTRIB_DIR)/include $(IPXE_CONTRIB_DIR) \ CC_WARN = -Wall -Wno-address CC_OPT += $(addprefix -fno-builtin-, putchar toupper tolower) -CC_OPT += -DARCH=i386 -DPLATFORM=pcbios -include compiler.h -DOBJECT=$(notdir $(*:.o=)) +CC_C_OPT += -DARCH=i386 -DPLATFORM=pcbios -include compiler.h -DOBJECT=$(notdir $(*:.o=)) # # Enable debugging of any iPXE object here via '-Ddebug_='. @@ -32,10 +31,11 @@ CC_OPT += -Ddebug_lib=7 #CC_OPT += -Ddebug_netdevice=7 -vpath nic.c $(LIB_DIR) -vpath dde.c $(LIB_DIR) -vpath dummies.c $(LIB_DIR) +vpath nic.c $(LIB_DIR) +vpath dde.c $(LIB_DIR) +vpath dummies.c $(LIB_DIR) +vpath dde_support.cc $(LIB_DIR) -vpath %.c $(IPXE_CONTRIB_DIR) +vpath %.c $(IPXE_CONTRIB_DIR) # vi: set ft=make : diff --git a/repos/dde_ipxe/lib/mk/dde_ipxe_support.mk b/repos/dde_ipxe/lib/mk/dde_ipxe_support.mk deleted file mode 100644 index 51b3ed9bf..000000000 --- a/repos/dde_ipxe/lib/mk/dde_ipxe_support.mk +++ /dev/null @@ -1,5 +0,0 @@ -LIB_DIR := $(REP_DIR)/src/lib/dde_ipxe - -SRC_CC = dde_support.cc - -vpath dde_support.cc $(LIB_DIR) diff --git a/repos/dde_ipxe/patches/dde_ipxe.patch b/repos/dde_ipxe/patches/dde_ipxe.patch index 2260034d8..6ec9c38b1 100644 --- a/repos/dde_ipxe/patches/dde_ipxe.patch +++ b/repos/dde_ipxe/patches/dde_ipxe.patch @@ -14,29 +14,3 @@ index 472e140..d5095a7 100644 "shrdl %1, %%edx, %%eax\n\t" : "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" ); return ticks; -diff --git a/src/include/assert.h b/src/include/assert.h -index 655cbdc..a8016c8 100644 ---- a/src/include/assert.h -+++ b/src/include/assert.h -@@ -31,7 +31,7 @@ extern unsigned int assertion_failures; - * to the printf symbol. - */ - extern int __attribute__ (( format ( printf, 1, 2 ) )) --assert_printf ( const char *fmt, ... ) asm ( "printf" ); -+assert_printf ( const char *fmt, ... ) asm ( "ipxe_printf" ); - - /** - * Assert a condition at run-time. -diff --git a/src/include/compiler.h b/src/include/compiler.h -index e555924..b430e37 100644 ---- a/src/include/compiler.h -+++ b/src/include/compiler.h -@@ -263,7 +263,7 @@ REQUEST_EXPANDED ( CONFIG_SYMBOL ); - - /** printf() for debugging */ - extern void __attribute__ (( format ( printf, 1, 2 ) )) --dbg_printf ( const char *fmt, ... ); -+dbg_printf ( const char *fmt, ... ) asm ( "ipxe_printf" ); - extern void dbg_autocolourise ( unsigned long id ); - extern void dbg_decolourise ( void ); - extern void dbg_hex_dump_da ( unsigned long dispaddr, diff --git a/repos/dde_ipxe/ports/dde_ipxe.hash b/repos/dde_ipxe/ports/dde_ipxe.hash index b6a43faab..7e85e365d 100644 --- a/repos/dde_ipxe/ports/dde_ipxe.hash +++ b/repos/dde_ipxe/ports/dde_ipxe.hash @@ -1 +1 @@ -7f8c6baa921f6939d49c2804b5b8c4b16981f261 +dd11e6a750e68271c2e7d293e9c1d272f7bc78e0 diff --git a/repos/dde_ipxe/src/drivers/nic/main.cc b/repos/dde_ipxe/src/drivers/nic/main.cc index b533c3882..ec1526069 100644 --- a/repos/dde_ipxe/src/drivers/nic/main.cc +++ b/repos/dde_ipxe/src/drivers/nic/main.cc @@ -17,11 +17,9 @@ #include #include #include +#include -/* DDE */ -extern "C" { #include -} namespace Ipxe { @@ -34,6 +32,8 @@ namespace Ipxe { private: + Server::Entrypoint &_ep; + Nic::Mac_address _mac_addr; Nic::Rx_buffer_alloc &_alloc; Nic::Driver_notification &_notify; @@ -49,11 +49,12 @@ namespace Ipxe { public: - Driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify) - : _alloc(alloc), _notify(notify) + Driver(Server::Entrypoint &ep, Nic::Rx_buffer_alloc &alloc, + Nic::Driver_notification ¬ify) + : _ep(ep), _alloc(alloc), _notify(notify) { PINF("--- init iPXE NIC"); - int cnt = dde_ipxe_nic_init(); + int cnt = dde_ipxe_nic_init(&ep); PINF(" number of devices: %d", cnt); PINF("--- init callbacks"); @@ -104,47 +105,58 @@ namespace Ipxe { void handle_irq(int) { /* not used */ } }; - class Driver_factory : public Nic::Driver_factory - { - Nic::Driver *create(Nic::Rx_buffer_alloc &alloc, - Nic::Driver_notification ¬ify) - { - Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc, notify); - return Driver::instance; - } - - void destroy(Nic::Driver *) - { - Genode::destroy(Genode::env()->heap(), Driver::instance); - Driver::instance = 0; - } - }; - } /* namespace Ipxe */ Ipxe::Driver * Ipxe::Driver::instance = 0; -int main(int, char **) +struct Main { - using namespace Genode; + Server::Entrypoint &ep; + Genode::Sliced_heap sliced_heap; - printf("--- iPXE NIC driver started ---\n"); + struct Factory : public Nic::Driver_factory + { + Server::Entrypoint &ep; - /** - * Factory used by 'Nic::Root' at session creation/destruction time - */ - static Ipxe::Driver_factory driver_factory; + Factory(Server::Entrypoint &ep) : ep(ep) { } - enum { STACK_SIZE = 2*sizeof(addr_t)*1024 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "nic_ep"); + Nic::Driver *create(Nic::Rx_buffer_alloc &alloc, + Nic::Driver_notification ¬ify) + { + Ipxe::Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(ep, alloc, notify); + return Ipxe::Driver::instance; + } - static Nic::Root nic_root(&ep, env()->heap(), driver_factory); - env()->parent()->announce(ep.manage(&nic_root)); + void destroy(Nic::Driver *) + { + Genode::destroy(Genode::env()->heap(), Ipxe::Driver::instance); + Ipxe::Driver::instance = 0; + } + } factory; - sleep_forever(); - return 0; + Nic::Root root; + + Main(Server::Entrypoint &ep) + : + ep(ep), + sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()), + factory(ep), + root(&ep.rpc_ep(), &sliced_heap, factory) + { + PINF("--- iPXE NIC driver started ---\n"); + Genode::env()->parent()->announce(ep.manage(root)); + } +}; + + +/************ + ** Server ** + ************/ + +namespace Server { + char const *name() { return "nic_drv_ep"; } + size_t stack_size() { return 2*1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/dde_ipxe/src/drivers/nic/target.mk b/repos/dde_ipxe/src/drivers/nic/target.mk index c9e78f17d..b1089115c 100644 --- a/repos/dde_ipxe/src/drivers/nic/target.mk +++ b/repos/dde_ipxe/src/drivers/nic/target.mk @@ -1,3 +1,3 @@ TARGET = nic_drv -LIBS = dde_ipxe_nic +LIBS = base server dde_ipxe_nic SRC_CC = main.cc diff --git a/repos/dde_ipxe/src/drivers/nic_stat/main.cc b/repos/dde_ipxe/src/drivers/nic_stat/main.cc index a0750d7f1..059edb117 100644 --- a/repos/dde_ipxe/src/drivers/nic_stat/main.cc +++ b/repos/dde_ipxe/src/drivers/nic_stat/main.cc @@ -11,12 +11,13 @@ * under the terms of the GNU General Public License version 2. */ -/* Genode */ +/* Genode include */ #include #include #include #include #include +#include #include #include @@ -56,11 +57,12 @@ namespace Ipxe { public: - Driver(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify) + Driver(Server::Entrypoint &ep, Nic::Rx_buffer_alloc &alloc, + Nic::Driver_notification ¬ify) : _alloc(alloc), _notify(notify), _stat(_timer) { PINF("--- init iPXE NIC"); - int cnt = dde_ipxe_nic_init(); + int cnt = dde_ipxe_nic_init(&ep); PINF(" number of devices: %d", cnt); PINF("--- init callbacks"); @@ -119,57 +121,61 @@ namespace Ipxe { void handle_irq(int) { /* not used */ } }; - - class Driver_factory : public Nic::Driver_factory - { - Nic::Driver *create(Nic::Rx_buffer_alloc &alloc, Nic::Driver_notification ¬ify) - { - Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(alloc, notify); - return Driver::instance; - } - - void destroy(Nic::Driver *) - { - Genode::destroy(Genode::env()->heap(), Driver::instance); - Driver::instance = 0; - } - }; - } /* namespace Ipxe */ Ipxe::Driver * Ipxe::Driver::instance = 0; -int main(int, char **) +struct Main { - using namespace Genode; + Server::Entrypoint &ep; + Genode::Sliced_heap sliced_heap; - printf("--- iPXE NIC driver started ---\n"); + struct Factory : public Nic::Driver_factory + { + Server::Entrypoint &ep; - /** - * Factory used by 'Nic::Root' at session creation/destruction time - */ - static Ipxe::Driver_factory driver_factory; + Factory(Server::Entrypoint &ep) : ep(ep) { } - enum { STACK_SIZE = 2*sizeof(addr_t)*1024 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "nic_ep"); + Nic::Driver *create(Nic::Rx_buffer_alloc &alloc, + Nic::Driver_notification ¬ify) + { + Ipxe::Driver::instance = new (Genode::env()->heap()) Ipxe::Driver(ep, alloc, notify); + return Ipxe::Driver::instance; + } - static Nic::Root nic_root(&ep, env()->heap(), driver_factory); - env()->parent()->announce(ep.manage(&nic_root)); + void destroy(Nic::Driver *) + { + Genode::destroy(Genode::env()->heap(), Ipxe::Driver::instance); + Ipxe::Driver::instance = 0; + } + } factory; -/* - Genode::size_t tx_buf_size = 64*1024; - Genode::size_t rx_buf_size = 64*1024; - session("ram_quota=%zd, tx_buf_size=%zd, rx_buf_size=%zd", - 6*4096 + tx_buf_size + rx_buf_size, - tx_buf_size, rx_buf_size)) -*/ - nic_root.session("ram_quota=155648, tx_buf_size=65536, rx_buf_size=65536", - Affinity()); + Nic::Root root; - sleep_forever(); - return 0; + Main(Server::Entrypoint &ep) + : + ep(ep), + sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()), + factory(ep), + root(&ep.rpc_ep(), &sliced_heap, factory) + { + PINF("--- iPXE NIC driver started ---\n"); + Genode::env()->parent()->announce(ep.manage(root)); + + root.session("ram_quota=155648, tx_buf_size=65536, rx_buf_size=65536", + Genode::Affinity()); + } +}; + + +/************ + ** Server ** + ************/ + +namespace Server { + char const *name() { return "nic_drv_stat_ep"; } + size_t stack_size() { return 2*1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/dde_ipxe/src/drivers/nic_stat/target.mk b/repos/dde_ipxe/src/drivers/nic_stat/target.mk index 6e5b405f4..77251cfb3 100644 --- a/repos/dde_ipxe/src/drivers/nic_stat/target.mk +++ b/repos/dde_ipxe/src/drivers/nic_stat/target.mk @@ -1,3 +1,3 @@ TARGET = nic_drv_stat -LIBS = dde_ipxe_nic net-stat +LIBS = base server dde_ipxe_nic net-stat SRC_CC = main.cc diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dde.c b/repos/dde_ipxe/src/lib/dde_ipxe/dde.c index b78cb8853..b1c0f9dda 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dde.c +++ b/repos/dde_ipxe/src/lib/dde_ipxe/dde.c @@ -1,24 +1,17 @@ /* * \brief DDE iPXE emulation implementation * \author Christian Helmuth + * \author Josef Soentgen * \date 2010-09-13 */ /* - * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2010-2015 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. */ -/* DDE kit */ -#include -#include -#include -#include -#include -#include - /* iPXE */ #include #include @@ -28,92 +21,35 @@ #include #include #include - +/* local includes */ +#include #include "local.h" - -/*********************************** - ** Wrapper to DDE support in C++ ** - ***********************************/ - -#include "dde_support.h" - -void *alloc_memblock(size_t size, size_t align, size_t offset) { return dde_alloc_memblock(size, align, offset); } -void free_memblock(void *p, size_t size) { dde_free_memblock(p, size); } -void timer2_udelay(unsigned long usecs) { dde_timer2_udelay(usecs); } - -/********************************** - ** Memory pool in DDE kit slabs ** - **********************************/ - -enum { SLAB_128, SLAB_256, SLAB_512, SLAB_1024, SLAB_2048, SLAB_4096, SLAB_20480, NUM_SLABS }; - -static struct dde_kit_slab *slabs[NUM_SLABS]; - -static inline void *alloc_from_slab(size_t size) -{ - size_t *p = 0; - size_t alloc_size = size + sizeof(size_t); - - if (alloc_size <= 128) - p = dde_kit_slab_alloc(slabs[SLAB_128]); - else if (alloc_size <= 256) - p = dde_kit_slab_alloc(slabs[SLAB_256]); - else if (alloc_size <= 512) - p = dde_kit_slab_alloc(slabs[SLAB_512]); - else if (alloc_size <= 1024) - p = dde_kit_slab_alloc(slabs[SLAB_1024]); - else if (alloc_size <= 2048) - p = dde_kit_slab_alloc(slabs[SLAB_2048]); - else if (alloc_size <= 4096) - p = dde_kit_slab_alloc(slabs[SLAB_4096]); - else if (alloc_size <= 20480) - p = dde_kit_slab_alloc(slabs[SLAB_20480]); - else - LOG("allocation of size %zd too big", size); - - if (p) { - *p = alloc_size; - p++; - } - - return p; -} +#define PDBG(fmt, ...) dde_printf(fmt "\n", ##__VA_ARGS__) -static inline void free_in_slab(void *p0) -{ - size_t *p = (size_t *)p0 - 1; +/*************************** + ** DMA memory allocation ** + ***************************/ - if (*p <= 128) - dde_kit_slab_free(slabs[SLAB_128], p); - else if (*p <= 256) - dde_kit_slab_free(slabs[SLAB_256], p); - else if (*p <= 512) - dde_kit_slab_free(slabs[SLAB_512], p); - else if (*p <= 1024) - dde_kit_slab_free(slabs[SLAB_1024], p); - else if (*p <= 2048) - dde_kit_slab_free(slabs[SLAB_2048], p); - else if (*p <= 4096) - dde_kit_slab_free(slabs[SLAB_4096], p); - else if (*p <= 20480) - dde_kit_slab_free(slabs[SLAB_20480], p); - else - LOG("deallocation at %p not possible", p0); -} +void *alloc_memblock(size_t size, size_t align, size_t offset) { + return dde_dma_alloc(size, align, offset); } -void slab_init(void) -{ - slabs[SLAB_128] = dde_kit_slab_init(128); - slabs[SLAB_256] = dde_kit_slab_init(256); - slabs[SLAB_512] = dde_kit_slab_init(512); - slabs[SLAB_1024] = dde_kit_slab_init(1024); - slabs[SLAB_2048] = dde_kit_slab_init(2048); - slabs[SLAB_4096] = dde_kit_slab_init(4096); - slabs[SLAB_20480] = dde_kit_slab_init(20480); -} +void free_memblock(void *p, size_t size) { + dde_dma_free(p, size); } + + +/********************** + ** Slab memory pool ** + **********************/ + +static inline void *alloc_from_slab(size_t size) { + return dde_slab_alloc(size); } + + +static inline void free_in_slab(void *p) { + dde_slab_free(p); } /************ @@ -131,23 +67,23 @@ void *zalloc(size_t size) } -void * malloc(size_t size) -{ - return alloc_from_slab(size); -} +void *malloc(size_t size) { + return alloc_from_slab(size); } -void free(void *p) -{ - free_in_slab(p); -} +void free(void *p) { + free_in_slab(p); } /********************* ** Time and Timers ** *********************/ -void udelay (unsigned long usecs) +void timer2_udelay(unsigned long usecs) { + dde_udelay(usecs); } + + +void udelay(unsigned long usecs) { static int init = 0; @@ -166,13 +102,11 @@ void udelay (unsigned long usecs) } -void mdelay (unsigned long msecs) -{ - dde_kit_thread_msleep(msecs); -} +void mdelay(unsigned long msecs) { + dde_mdelay(msecs); } -int ipxe_printf(const char *format, ...) +int printf(const char *format, ...) { /* replace unsupported '%#' with 'x%' in format string */ char *new_format = (char *)malloc(strlen(format) + 1); @@ -192,7 +126,7 @@ int ipxe_printf(const char *format, ...) va_list va; va_start(va, format); - dde_kit_vprintf(new_format, va); + dde_vprintf(new_format, va); va_end(va); free(new_format); @@ -207,17 +141,16 @@ int ipxe_printf(const char *format, ...) void iounmap(volatile const void *io_addr) { LOG("io_addr = %p", io_addr); - /* XXX DDE kit always releases the whole region */ - dde_kit_release_mem((dde_kit_addr_t) io_addr, 1); + dde_release_iomem((dde_addr_t) io_addr, 1); } -void * ioremap(unsigned long bus_addr, size_t len) +void *ioremap(unsigned long bus_addr, size_t len) { LOG("bus_addr = %p len = %zx", (void *)bus_addr, len); - dde_kit_addr_t vaddr; + dde_addr_t vaddr; - int ret = dde_kit_request_mem(bus_addr, len, 0, &vaddr); + int ret = dde_request_iomem(bus_addr, len, 0, &vaddr); return ret ? 0 : (void *)vaddr; } @@ -225,7 +158,7 @@ void * ioremap(unsigned long bus_addr, size_t len) unsigned long user_to_phys(userptr_t userptr, off_t offset) { - return dde_kit_pgtab_get_physaddr((void *)userptr) + offset; + return dde_dma_get_physaddr((void *)userptr) + offset; } @@ -247,54 +180,42 @@ unsigned long phys_to_bus(unsigned long phys_addr) int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value) { - dde_kit_pci_readb(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), - where, value); - + dde_pci_readb(where, value); return 0; } int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value) { - dde_kit_pci_readw(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), - where, value); - + dde_pci_readw( where, value); return 0; } int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value) { - dde_kit_pci_readl(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), - where, value); - + dde_pci_readl(where, value); return 0; } int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value) { - dde_kit_pci_writeb(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), - where, value); - + dde_pci_writeb(where, value); return 0; } int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value) { - dde_kit_pci_writew(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), - where, value); - + dde_pci_writew(where, value); return 0; } int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value) { - dde_kit_pci_writel(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), - where, value); - + dde_pci_writel( where, value); return 0; } diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc index 2a4d2d19c..adc4d6711 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc +++ b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.cc @@ -1,72 +1,73 @@ /* - * \brief Functions not offered by Genode's DDE-kit + * \brief DDE iPXE wrappers to C++ backend * \author Sebastian Sumpf + * \author Josef Soentgen * \date 2010-10-21 */ /* - * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2010-2015 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. */ +/* + * The build system picks up stdarg.h from iPXE instead of the one + * provided by GCC. This header contains the FILE_LICENCE macro which + * is defined by iPXE's compiler.h. + */ +#define FILE_LICENCE(x) + +/* Genode includes */ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include - -extern "C" { -#include -#include "dde_support.h" -} - -using namespace Genode; - -/*************************************************** - ** Support for aligned and DMA memory allocation ** - ***************************************************/ - -enum { BACKING_STORE_SIZE = 1024 * 1024 }; +/* local includes */ +#include -static Allocator_avl& allocator() +//using namespace Genode; + + +/**************** + ** Migriation ** + ****************/ + +static Server::Entrypoint *_ep; + +extern "C" void dde_init(void *ep) { - static Allocator_avl _avl(env()->heap()); - return _avl; -} - -extern "C" int dde_mem_init(int bus, int dev, int func) -{ - try { - addr_t base = dde_kit_pci_alloc_dma_buffer(bus, dev, func, - BACKING_STORE_SIZE); - /* add to allocator */ - allocator().add_range(base, BACKING_STORE_SIZE); - } catch (...) { - return false; - } - - return true; -} - -extern "C" void *dde_alloc_memblock(dde_kit_size_t size, dde_kit_size_t align, - dde_kit_size_t offset) -{ - void *ptr; - if (allocator().alloc_aligned(size, &ptr, log2(align)).is_error()) { - PERR("memory allocation failed in alloc_memblock (size=%zd, align=%zx," - " offset=%zx)", size, align, offset); - return 0; - } - return ptr; + _ep = (Server::Entrypoint*)ep; } -extern "C" void dde_free_memblock(void *p, dde_kit_size_t size) +/************ + ** printf ** + ************/ + +extern "C" void dde_vprintf(const char *fmt, va_list va) { + Genode::vprintf(fmt, va); } + + +extern "C" void dde_printf(const char *fmt, ...) { - allocator().free(p, size); + va_list args; + va_start(args, fmt); + dde_vprintf(fmt, args); + va_end(args); } @@ -74,7 +75,7 @@ extern "C" void dde_free_memblock(void *p, dde_kit_size_t size) ** Timer ** ***********/ -extern "C" void dde_timer2_udelay(unsigned long usecs) +extern "C" void dde_udelay(unsigned long usecs) { /* * This function is called only once during rdtsc calibration (usecs will be @@ -84,3 +85,551 @@ extern "C" void dde_timer2_udelay(unsigned long usecs) Timer::Connection timer; timer.usleep(usecs); } + + +/*************************** + ** locking/synchronizing ** + ***************************/ + +/** + * DDE iPXE mutual exclusion lock + */ +static Genode::Lock _ipxe_lock; + +extern "C" void dde_lock_enter(void) { _ipxe_lock.lock(); } +extern "C" void dde_lock_leave(void) { _ipxe_lock.unlock(); } + + +extern "C" void dde_mdelay(unsigned long msecs) +{ + /* + * Using one static timer connection here is safe because + * this function is only called while initializing the device + * and only be the same thread. + */ + static Timer::Connection timer; + timer.msleep(msecs); +} + + +/****************** + ** PCI handling ** + ******************/ + +struct Pci_driver +{ + enum { + PCI_BASE_CLASS_NETWORK = 0x02, + CLASS_MASK = 0xff0000, + CLASS_NETWORK = PCI_BASE_CLASS_NETWORK << 16 + }; + + Pci::Connection _pci; + Pci::Device_capability _cap; + Pci::Device_capability _last_cap; + + struct Region + { + Genode::addr_t base; + Genode::addr_t mapped_base; + } _region; + + template + Pci::Device::Access_size _access_size(T t) + { + switch (sizeof(T)) { + case 1: + return Pci::Device::ACCESS_8BIT; + case 2: + return Pci::Device::ACCESS_16BIT; + default: + return Pci::Device::ACCESS_32BIT; + } + } + + void _bus_address(int *bus, int *dev, int *fun) + { + Pci::Device_client client(_cap); + unsigned char b, d, f; + client.bus_address(&b, &d, &f); + + *bus = b; + *dev = d; + *fun = f; + } + + + Pci_driver() { } + + template + void config_read(unsigned int devfn, T *val) + { + Pci::Device_client client(_cap); + *val = client.config_read(devfn, _access_size(*val)); + } + + template + void config_write(unsigned int devfn, T val) + { + Pci::Device_client client(_cap); + client.config_write(devfn, val, _access_size(val)); + } + + int first_device(int *bus, int *dev, int *fun) + { + _cap = _pci.first_device(CLASS_NETWORK, CLASS_MASK); + _bus_address(bus, dev, fun); + return 0; + } + + int next_device(int *bus, int *dev, int *fun) + { + _last_cap = _cap; + + _cap = _pci.next_device(_cap, CLASS_NETWORK, CLASS_MASK); + _bus_address(bus, dev, fun); + + if (_last_cap.valid()) + _pci.release_device(_last_cap); + + return 0; + } + + Genode::addr_t alloc_dma_memory(Genode::size_t size) + { + try { + using namespace Genode; + + /* trigger that the device gets assigned to this driver */ + _pci.config_extended(_cap); + Ram_dataspace_capability ram_cap; + ram_cap = _pci.alloc_dma_buffer(_cap, size); + _region.mapped_base = (Genode::addr_t)env()->rm_session()->attach(ram_cap); + _region.base = Dataspace_client(ram_cap).phys_addr(); + + return _region.mapped_base; + } catch (...) { return 0; } + } + + Genode::addr_t virt_to_phys(Genode::addr_t virt) { + return virt - _region.mapped_base + _region.base; } +}; + + +static Pci_driver& pci_drv() +{ + static Pci_driver _pci_drv; + return _pci_drv; +} + + +extern "C" int dde_pci_first_device(int *bus, int *dev, int *fun) { + return pci_drv().first_device(bus, dev, fun); } + + +extern "C" int dde_pci_next_device(int *bus, int *dev, int *fun) { + return pci_drv().next_device(bus, dev, fun); } + + +extern "C" void dde_pci_readb(int pos, dde_uint8_t *val) { + pci_drv().config_read(pos, val); } + + +extern "C" void dde_pci_readw(int pos, dde_uint16_t *val) { + pci_drv().config_read(pos, val); } + + +extern "C" void dde_pci_readl(int pos, dde_uint32_t *val) { + pci_drv().config_read(pos, val); } + + +extern "C" void dde_pci_writeb(int pos, dde_uint8_t val) { + pci_drv().config_write(pos, val); } + + +extern "C" void dde_pci_writew(int pos, dde_uint16_t val) { + pci_drv().config_write(pos, val); } + + +extern "C" void dde_pci_writel(int pos, dde_uint32_t val) { + pci_drv().config_write(pos, val); } + + +/************************ + ** Interrupt handling ** + ************************/ + +struct Irq_handler +{ + Server::Entrypoint &ep; + Genode::Irq_connection irq; + Genode::Signal_rpc_member dispatcher; + + typedef void (*irq_handler)(void*); + + irq_handler handler; + void *priv; + + void handle(unsigned) + { + handler(priv); + irq.ack_irq(); + } + + Irq_handler(Server::Entrypoint &ep, int irqnr, + irq_handler handler, void *priv) + : + ep(ep), irq(irqnr), dispatcher(ep, *this, &Irq_handler::handle), + handler(handler), priv(priv) + { + irq.sigh(dispatcher); + + /* intial ack so that we will receive IRQ signals */ + irq.ack_irq(); + } +}; + +static Irq_handler *_irq_handler; + +extern "C" int dde_interrupt_attach(int irq, void(*handler)(void *), void *priv) +{ + if (_irq_handler) { + PERR("Irq_handler already registered"); + Genode::sleep_forever(); + } + + try { + _irq_handler = new (Genode::env()->heap()) + Irq_handler(*_ep, irq, handler, priv); + } catch (...) { return -1; } + + return 0; +} + + + + +/*************************************************** + ** Support for aligned and DMA memory allocation ** + ***************************************************/ + +enum { BACKING_STORE_SIZE = 1024 * 1024 }; + + +static Genode::Allocator_avl& allocator() +{ + static Genode::Allocator_avl _avl(Genode::env()->heap()); + return _avl; +} + + +extern "C" int dde_dma_mem_init() +{ + try { + Genode::addr_t base = pci_drv().alloc_dma_memory(BACKING_STORE_SIZE); + /* add to allocator */ + allocator().add_range(base, BACKING_STORE_SIZE); + } catch (...) { return false; } + + return true; +} + + +extern "C" void *dde_dma_alloc(dde_size_t size, dde_size_t align, + dde_size_t offset) +{ + void *ptr; + if (allocator().alloc_aligned(size, &ptr, Genode::log2(align)).is_error()) { + PERR("memory allocation failed in alloc_memblock (size=%zu, align=%zx," + " offset=%zx)", (Genode::size_t)size, (Genode::size_t)align, (Genode::size_t)offset); + return 0; + } + return ptr; +} + + +extern "C" void dde_dma_free(void *p, dde_size_t size) { + allocator().free(p, size); } + + +extern "C" dde_addr_t dde_dma_get_physaddr(void *virt) { + return pci_drv().virt_to_phys((Genode::addr_t)virt); } + + +/************** + ** I/O port ** + **************/ + +static Genode::Io_port_connection *_io_port; + +extern "C" void dde_request_io(dde_addr_t base, dde_size_t size) +{ + using namespace Genode; + + if (_io_port) { + PERR("Io_port_connection already open"); + sleep_forever(); + } + + _io_port = new (env()->heap()) Io_port_connection(base, size); +} + + +extern "C" dde_uint8_t dde_inb(dde_addr_t port) { + return _io_port->inb(port); } + + +extern "C" dde_uint16_t dde_inw(dde_addr_t port) { + return _io_port->inw(port); } + + +extern "C" dde_uint32_t dde_inl(dde_addr_t port) { + return _io_port->inl(port); } + + +extern "C" void dde_outb(dde_addr_t port, dde_uint8_t data) { + _io_port->outb(port, data); } + + +extern "C" void dde_outw(dde_addr_t port, dde_uint16_t data) { + _io_port->outw(port, data); } + + +extern "C" void dde_outl(dde_addr_t port, dde_uint32_t data) { + _io_port->outl(port, data); } + + +/********************** + ** Slab memory pool ** + **********************/ + +struct Slab_backend_alloc : public Genode::Allocator, + public Genode::Rm_connection +{ + enum { + VM_SIZE = 512 * 1024, + BLOCK_SIZE = 64 * 1024, + ELEMENTS = VM_SIZE / BLOCK_SIZE, + }; + + Genode::addr_t _base; + Genode::Ram_dataspace_capability _ds_cap[ELEMENTS]; + int _index; + Genode::Allocator_avl _range; + Genode::Ram_session &_ram; + + bool _alloc_block() + { + using namespace Genode; + + if (_index == ELEMENTS) { + PERR("Slab-backend exhausted!"); + return false; + } + + try { + _ds_cap[_index] = _ram.alloc(BLOCK_SIZE); + Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + } catch (...) { return false; } + + /* return base + offset in VM area */ + Genode::addr_t block_base = _base + (_index * BLOCK_SIZE); + ++_index; + + _range.add_range(block_base, BLOCK_SIZE); + return true; + } + + Slab_backend_alloc(Genode::Ram_session &ram) + : + Rm_connection(0, VM_SIZE), + _index(0), _range(Genode::env()->heap()), _ram(ram) + { + /* reserver attach us, anywere */ + _base = Genode::env()->rm_session()->attach(dataspace()); + } + + Genode::addr_t start() const { return _base; } + Genode::addr_t end() const { return _base + VM_SIZE - 1; } + + /************************* + ** Allocator interface ** + *************************/ + + bool alloc(Genode::size_t size, void **out_addr) + { + bool done = _range.alloc(size, out_addr); + + if (done) + return done; + + done = _alloc_block(); + if (!done) { + PERR("Backend allocator exhausted\n"); + return false; + } + + return _range.alloc(size, out_addr); + } + + void free(void *addr, Genode::size_t size) { } + Genode::size_t overhead(Genode::size_t size) const { return 0; } + bool need_size_for_free() const { return false; } +}; + + +struct Slab_alloc : public Genode::Slab +{ + /* + * Each slab block in the slab contains about 8 objects (slab entries) + * as proposed in the paper by Bonwick and block sizes are multiples of + * page size. + */ + static Genode::size_t _calculate_block_size(Genode::size_t object_size) + { + Genode::size_t block_size = 8 * (object_size + sizeof(Genode::Slab_entry)) + + sizeof(Genode::Slab_block); + return Genode::align_addr(block_size, 12); + } + + Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator) + : Slab(object_size, _calculate_block_size(object_size), 0, &allocator) { } + + /** + * Convenience slabe-entry allocation + */ + Genode::addr_t alloc() + { + Genode::addr_t result; + return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); + } +}; + +struct Slab +{ + enum { + SLAB_START_LOG2 = 5, /* 32 B */ + SLAB_STOP_LOG2 = 10, /* 1 KiB */ + NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1, + }; + + Slab_backend_alloc &_back_alloc; + Slab_alloc *_allocator[NUM_SLABS]; + Genode::addr_t _start; + Genode::addr_t _end; + + Slab(Slab_backend_alloc &alloc) + : _back_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); + } + + void *alloc(Genode::size_t size) + { + using namespace Genode; + size += sizeof(Genode::addr_t); + + int msb = Genode::log2(size); + + if (size > (1U << msb)) + msb++; + + if (size < (1U << SLAB_START_LOG2)) + msb = SLAB_STOP_LOG2; + + if (msb > SLAB_STOP_LOG2) + return 0; + + Genode::addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc(); + if (!addr) + return 0; + + *(Genode::addr_t*)addr = msb - SLAB_START_LOG2; + addr += sizeof(Genode::addr_t); + + return (void*)addr; + } + + 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)); + } +}; + + +static ::Slab& slab() +{ + static ::Slab_backend_alloc sb(*Genode::env()->ram_session()); + static ::Slab s(sb); + return s; +} + + +extern "C" void *dde_slab_alloc(dde_size_t size) { + return slab().alloc(size); } + + +extern "C" void dde_slab_free(void *p) { + slab().free(p); } + + +/**************** + ** I/O memory ** + ****************/ + +struct Io_memory +{ + Genode::Io_mem_connection _mem; + Genode::Io_mem_dataspace_capability _mem_ds; + + Genode::addr_t _vaddr; + + Io_memory(Genode::addr_t base, Genode::size_t size, bool wc) + : + _mem(base, size, wc), + _mem_ds(_mem.dataspace()) + { + if (!_mem_ds.valid()) + throw Genode::Exception(); + + _vaddr = Genode::env()->rm_session()->attach(_mem_ds); + _vaddr |= base & 0xfff; + } + + Genode::addr_t vaddr() const { return _vaddr; } +}; + + +static Io_memory *_io_mem; + + +extern "C" int dde_request_iomem(dde_addr_t start, dde_size_t size, int wc, + dde_addr_t *vaddr) +{ + if (_io_mem) { + PERR("Io_memory already requested"); + Genode::sleep_forever(); + } + + try { + _io_mem = new (Genode::env()->heap()) Io_memory(start, size, !!wc); + } catch (...) { return -1; } + + *vaddr = _io_mem->vaddr(); + return 0; +} + + +extern "C" int dde_release_iomem(dde_addr_t start, dde_size_t size) +{ + try { + destroy(Genode::env()->heap(), _io_mem); + _io_mem = 0; + return 0; + } catch (...) { return -1; } +} diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.h b/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.h deleted file mode 100644 index 7061248cf..000000000 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dde_support.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * \brief DDE iPXE wrappers to C++ backend - * \author Christian Helmuth - * \date 2013-01-07 - */ - -/* - * Copyright (C) 2010-2013 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_SUPPORT_H_ -#define _DDE_SUPPORT_H_ - -#include - - -void *dde_alloc_memblock(dde_kit_size_t size, dde_kit_size_t align, - dde_kit_size_t offset); -void dde_free_memblock(void *p, dde_kit_size_t size); -void dde_timer2_udelay(unsigned long usecs); -int dde_mem_init(int bus, int dev, int func); - -#endif /* _DDE_SUPPORT_H_ */ diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/dummies.c b/repos/dde_ipxe/src/lib/dde_ipxe/dummies.c index a22ea5df6..38cbc0e83 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/dummies.c +++ b/repos/dde_ipxe/src/lib/dde_ipxe/dummies.c @@ -11,7 +11,9 @@ * under the terms of the GNU General Public License version 2. */ -#include "local.h" +#include + +#define TRACE dde_printf("\033[35m%s not implemented\033[0m\n", __func__) int snprintf(char *buf, __SIZE_TYPE__ size, const char *fmt, ...) { TRACE; return 0; } diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/include/dde_support.h b/repos/dde_ipxe/src/lib/dde_ipxe/include/dde_support.h new file mode 100644 index 000000000..7ad98fa13 --- /dev/null +++ b/repos/dde_ipxe/src/lib/dde_ipxe/include/dde_support.h @@ -0,0 +1,128 @@ +/* + * \brief DDE iPXE wrappers to C++ backend + * \author Christian Helmuth + * \author Josef Soentgen + * \date 2013-01-07 + */ + +/* + * Copyright (C) 2010-2015 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_SUPPORT_H_ +#define _DDE_SUPPORT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long dde_addr_t; +typedef unsigned long dde_size_t; +typedef unsigned char dde_uint8_t; +typedef unsigned short dde_uint16_t; +typedef unsigned int dde_uint32_t; + + +/***************** + ** Initialization + *****************/ +void dde_init(void *ep); + + +/*********** + ** Timer ** + ***********/ + +void dde_udelay(unsigned long usecs); +void dde_mdelay(unsigned long msecs); + + +/************ + ** printf ** + ************/ + +typedef __builtin_va_list va_list; +void dde_vprintf(const char *fmt, va_list va) __attribute__ ((format (printf, 1, 0))); +void dde_printf(const char *fmt, ...); + + +/*************************************************** + ** Support for aligned and DMA memory allocation ** + ***************************************************/ + +int dde_dma_mem_init(); + +void *dde_dma_alloc(dde_size_t size, dde_size_t align, dde_size_t offset); +void dde_dma_free(void *p, dde_size_t size); + +dde_addr_t dde_dma_get_physaddr(void *virt); + + +/*************************** + ** locking/synchronizing ** + ***************************/ + +void dde_lock_enter(void); +void dde_lock_leave(void); + + +/************************ + ** Interrupt handling ** + ************************/ + +int dde_interrupt_attach(int irq, void (*handler)(void *), void *priv); + + +/****************** + ** PCI handling ** + ******************/ + +int dde_pci_first_device(int *, int *, int *); +int dde_pci_next_device(int *, int *, int *); + +void dde_pci_readb(int, dde_uint8_t *); +void dde_pci_readw(int, dde_uint16_t *); +void dde_pci_readl(int, dde_uint32_t *); +void dde_pci_writeb(int, dde_uint8_t); +void dde_pci_writew(int, dde_uint16_t); +void dde_pci_writel(int, dde_uint32_t); + + +/************** + ** I/O port ** + **************/ + +void dde_request_io(dde_addr_t, dde_size_t); + +dde_uint8_t dde_inb(dde_addr_t); +dde_uint16_t dde_inw(dde_addr_t); +dde_uint32_t dde_inl(dde_addr_t); + +void dde_outb(dde_addr_t, dde_uint8_t); +void dde_outw(dde_addr_t, dde_uint16_t); +void dde_outl(dde_addr_t, dde_uint32_t); + + +/********************** + ** Slab memory pool ** + **********************/ + +void *dde_slab_alloc(dde_size_t); +void dde_slab_free(void *); + + +/**************** + ** I/O memory ** + ****************/ + +int dde_request_iomem(dde_addr_t, dde_size_t, int, dde_addr_t *); +int dde_release_iomem(dde_addr_t, dde_size_t); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* _DDE_SUPPORT_H_ */ diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/include/env_dde_kit.h b/repos/dde_ipxe/src/lib/dde_ipxe/include/env_dde_kit.h index 09cfc4036..2017df016 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/include/env_dde_kit.h +++ b/repos/dde_ipxe/src/lib/dde_ipxe/include/env_dde_kit.h @@ -3,36 +3,36 @@ /* bits/io.h */ -#include +#include static inline uint8_t inb(volatile uint8_t *io_addr) { - return dde_kit_inb((dde_kit_addr_t) io_addr); + return dde_inb((dde_addr_t) io_addr); } static inline uint16_t inw(volatile uint16_t *io_addr) { - return dde_kit_inw((dde_kit_addr_t) io_addr); + return dde_inw((dde_addr_t) io_addr); } static inline uint32_t inl(volatile uint32_t *io_addr) { - return dde_kit_inl((dde_kit_addr_t) io_addr); + return dde_inl((dde_addr_t) io_addr); } static inline void outb(uint8_t data, volatile uint8_t *io_addr) { - dde_kit_outb((dde_kit_addr_t) io_addr, data); + dde_outb((dde_addr_t) io_addr, data); } static inline void outw(uint16_t data, volatile uint16_t *io_addr) { - dde_kit_outw((dde_kit_addr_t) io_addr, data); + dde_outw((dde_addr_t) io_addr, data); } static inline void outl(uint32_t data, volatile uint32_t *io_addr) { - dde_kit_outl((dde_kit_addr_t) io_addr, data); + dde_outl((dde_addr_t) io_addr, data); } diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/local.h b/repos/dde_ipxe/src/lib/dde_ipxe/local.h index fa9be715c..aee374ec9 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/local.h +++ b/repos/dde_ipxe/src/lib/dde_ipxe/local.h @@ -11,18 +11,9 @@ * under the terms of the GNU General Public License version 2. */ -#include -#include - #define FMT_BUSDEVFN "%02x:%02x.%x" -#define LOG(fmt, ...) \ - do { \ - dde_kit_log(1, "\033[36m" fmt "\033[0m", ##__VA_ARGS__ ); \ +#define LOG(fmt, ...) \ + do { \ + dde_printf("\033[36m" fmt "\033[0m\n", ##__VA_ARGS__ ); \ } while (0) - -#define TRACE dde_kit_printf("\033[35m%s not implemented\033[0m\n", __func__) - -#define ASSERT(x) dde_kit_assert(x) - -extern void slab_init(void); diff --git a/repos/dde_ipxe/src/lib/dde_ipxe/nic.c b/repos/dde_ipxe/src/lib/dde_ipxe/nic.c index ef64773e8..965d6111f 100644 --- a/repos/dde_ipxe/src/lib/dde_ipxe/nic.c +++ b/repos/dde_ipxe/src/lib/dde_ipxe/nic.c @@ -5,20 +5,12 @@ */ /* - * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2010-2015 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. */ -/* DDE kit */ -#include -#include -#include -#include -#include -#include - /* iPXE */ #include #include @@ -26,32 +18,15 @@ #include #include +/* local includes */ #include "local.h" -#include "dde_support.h" - -/** - * DDE iPXE mutual exclusion lock - */ -static struct dde_kit_lock *ipxe_lock; - -#define ENTER dde_kit_lock_lock(ipxe_lock) -#define LEAVE dde_kit_lock_unlock(ipxe_lock) - -/** - * Bottom-half activation semaphore - */ -static struct dde_kit_sem *bh_sema; +#include /** * Network device driven by iPXE */ static struct net_device *net_dev; -/** - * Link-state change detected - */ -static int link_state_changed; - /** * Callback function pointers */ @@ -68,7 +43,7 @@ extern struct pci_driver pcnet32_driver; /** - * Driver database (used for probing) + * Driver database (used for probing)PCI_BASE_CLASS_NETWORK */ static struct pci_driver *pci_drivers[] = { &realtek_driver, @@ -91,9 +66,9 @@ static void pci_read_bases(struct pci_device *pci_dev) if (!pci_dev->ioaddr) { pci_dev->ioaddr = bar & PCI_BASE_ADDRESS_IO_MASK; - dde_kit_addr_t base = bar & PCI_BASE_ADDRESS_IO_MASK; - dde_kit_size_t size = pci_bar_size(pci_dev, reg); - dde_kit_request_io(base, size); + dde_addr_t base = bar & PCI_BASE_ADDRESS_IO_MASK; + dde_size_t size = pci_bar_size(pci_dev, reg); + dde_request_io(base, size); } } else { if (!pci_dev->membase) @@ -149,27 +124,26 @@ enum { NO_DEVICE_FOUND = ~0U }; static unsigned scan_pci(void) { int ret, bus = 0, dev = 0, fun = 0; - for (ret = dde_kit_pci_first_device(&bus, &dev, &fun); + for (ret = dde_pci_first_device(&bus, &dev, &fun); ret == 0; - ret = dde_kit_pci_next_device(&bus, &dev, &fun)) { + ret = dde_pci_next_device(&bus, &dev, &fun)) { - dde_kit_uint32_t class_code; - dde_kit_pci_readl(bus, dev, fun, PCI_CLASS_REVISION, &class_code); + dde_uint32_t class_code; + dde_pci_readl(PCI_CLASS_REVISION, &class_code); class_code >>= 8; if (PCI_BASE_CLASS(class_code) != PCI_BASE_CLASS_NETWORK) continue; - dde_kit_uint16_t vendor, device; - dde_kit_pci_readw(bus, dev, fun, PCI_VENDOR_ID, &vendor); - dde_kit_pci_readw(bus, dev, fun, PCI_DEVICE_ID, &device); - dde_kit_uint8_t rev, irq; - dde_kit_pci_readb(bus, dev, fun, PCI_REVISION_ID, &rev); - dde_kit_pci_readb(bus, dev, fun, PCI_INTERRUPT_LINE, &irq); + dde_uint16_t vendor, device; + dde_pci_readw(PCI_VENDOR_ID, &vendor); + dde_pci_readw(PCI_DEVICE_ID, &device); + dde_uint8_t rev, irq; + dde_pci_readb(PCI_REVISION_ID, &rev); + dde_pci_readb(PCI_INTERRUPT_LINE, &irq); LOG("Found: " FMT_BUSDEVFN " %04x:%04x (rev %02x) IRQ %02x", bus, dev, fun, vendor, device, rev, irq); struct pci_device *pci_dev = zalloc(sizeof(*pci_dev)); - ASSERT(pci_dev != 0); pci_dev->busdevfn = PCI_BUSDEVFN(bus, dev, fun); pci_dev->vendor = vendor; @@ -200,57 +174,33 @@ static unsigned scan_pci(void) /** - * IRQ handler registered at DDE kit + * IRQ handler registered at DDE */ static void irq_handler(void *p) { - ENTER; + dde_lock_enter(); /* check for the link-state to change on each interrupt */ int link_ok = netdev_link_ok(net_dev); /* poll the device for packets and also link-state changes */ netdev_poll(net_dev); - dde_kit_sem_up(bh_sema); - link_state_changed = (link_ok != netdev_link_ok(net_dev)); - - LEAVE; -} - - -/** - * Bottom-half handler executed in separate thread - * - * Calls RX callback if appropriate. - */ -static void bh_handler(void *p) -{ - while (1) { - dde_kit_sem_down(bh_sema); - - ENTER; - - /* report link-state changes */ - if (link_state_changed) { - LEAVE; - if (link_callback) - link_callback(); - ENTER; - link_state_changed = 0; - } - - struct io_buffer *iobuf; - while ((iobuf = netdev_rx_dequeue(net_dev))) { - LEAVE; - if (rx_callback) - rx_callback(1, iobuf->data, iob_len(iobuf)); - ENTER; - free_iob(iobuf); - } - - LEAVE; + struct io_buffer *iobuf; + while ((iobuf = netdev_rx_dequeue(net_dev))) { + dde_lock_leave(); + if (rx_callback) + rx_callback(1, iobuf->data, iob_len(iobuf)); + dde_lock_enter(); + free_iob(iobuf); } + + dde_lock_leave(); + + if (link_ok != netdev_link_ok(net_dev)) + /* report link-state changes */ + if (link_callback) + link_callback(); } @@ -261,12 +211,12 @@ static void bh_handler(void *p) void dde_ipxe_nic_register_callbacks(dde_ipxe_nic_rx_cb rx_cb, dde_ipxe_nic_link_cb link_cb) { - ENTER; + dde_lock_enter(); rx_callback = rx_cb; link_callback = link_cb; - LEAVE; + dde_lock_leave(); } @@ -275,12 +225,11 @@ int dde_ipxe_nic_link_state(unsigned if_index) if (if_index != 1) return -1; - ENTER; + dde_lock_enter(); int link_state = netdev_link_ok(net_dev); - LEAVE; - + dde_lock_leave(); return link_state; } @@ -290,22 +239,22 @@ int dde_ipxe_nic_tx(unsigned if_index, const char *packet, unsigned packet_len) if (if_index != 1) return -1; - ENTER; + dde_lock_enter(); struct io_buffer *iobuf = alloc_iob(packet_len); - LEAVE; + dde_lock_leave(); if (!iobuf) return -1; memcpy(iob_put(iobuf, packet_len), packet, packet_len); - ENTER; + dde_lock_enter(); netdev_poll(net_dev); netdev_tx(net_dev, iob_disown(iobuf)); - LEAVE; + dde_lock_leave(); return 0; } @@ -315,7 +264,7 @@ int dde_ipxe_nic_get_mac_addr(unsigned if_index, char *out_mac_addr) if (if_index != 1) return -1; - ENTER; + dde_lock_enter(); out_mac_addr[0] = net_dev->hw_addr[0]; out_mac_addr[1] = net_dev->hw_addr[1]; @@ -324,26 +273,16 @@ int dde_ipxe_nic_get_mac_addr(unsigned if_index, char *out_mac_addr) out_mac_addr[4] = net_dev->hw_addr[4]; out_mac_addr[5] = net_dev->hw_addr[5]; - LEAVE; + dde_lock_leave(); return 0; } -int dde_ipxe_nic_init(void) +int dde_ipxe_nic_init(void *ep) { - dde_kit_init(); - dde_kit_timer_init(0, 0); - enum { - CLASS_MASK = 0xff0000, - CLASS_NETWORK = PCI_BASE_CLASS_NETWORK << 16 - }; - dde_kit_pci_init(CLASS_NETWORK, CLASS_MASK); + dde_init(ep); - dde_kit_lock_init(&ipxe_lock); - - slab_init(); - - ENTER; + dde_lock_enter(); /* scan all pci devices and drivers */ unsigned location = scan_pci(); @@ -353,10 +292,8 @@ int dde_ipxe_nic_init(void) /* find iPXE NIC device */ net_dev = find_netdev_by_location(BUS_TYPE_PCI, location); - /* initialize memory backend allocator for nic driver */ - if (!dde_mem_init(PCI_BUS(net_dev->dev->desc.location), - PCI_SLOT(net_dev->dev->desc.location), - PCI_FUNC(net_dev->dev->desc.location))) { + /* initialize DMA memory backend allocator for nic driver */ + if (!dde_dma_mem_init()) { LOG("initialization of block memory failed!"); return 0; } @@ -370,18 +307,15 @@ int dde_ipxe_nic_init(void) return 0; } - /* initialize IRQ handler and enable interrupt/bottom-half handling */ - bh_sema = dde_kit_sem_init(0); - dde_kit_thread_create(bh_handler, 0, "bh_handler"); - int err = dde_kit_interrupt_attach(net_dev->dev->desc.irq, 0, - 0, irq_handler, 0); + /* initialize IRQ handler */ + int err = dde_interrupt_attach(net_dev->dev->desc.irq, irq_handler, 0); if (err) { LOG("attaching to IRQ %02x failed", net_dev->dev->desc.irq); return 0; } netdev_irq(net_dev, 1); - LEAVE; + dde_lock_leave(); /* always report 1 device was found */ return 1;