diff --git a/repos/dde_ipxe/include/dde_ipxe/nic.h b/repos/dde_ipxe/include/dde_ipxe/nic.h index 3ae0a57ea1..cecffe785c 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 a5c595df2e..545a102a85 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 51b3ed9bf3..0000000000 --- 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 2260034d86..6ec9c38b1d 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 b6a43faab7..7e85e365d7 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 b533c3882f..ec1526069f 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 c9e78f17de..b1089115ca 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 a0750d7f1b..059edb1171 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 6e5b405f47..77251cfb3c 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 b78cb88539..b1c0f9dda2 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 2a4d2d19c4..adc4d6711f 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 7061248cfe..0000000000 --- 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 a22ea5df68..38cbc0e833 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 0000000000..7ad98fa13a --- /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 09cfc40369..2017df016e 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 fa9be715c4..aee374ec9b 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 ef64773e8c..965d6111fe 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;