diff --git a/ports-foc/Makefile b/ports-foc/Makefile index 3362a6e08..f8cddfea7 100644 --- a/ports-foc/Makefile +++ b/ports-foc/Makefile @@ -8,7 +8,7 @@ VERBOSE ?= @ ECHO = @echo TARGET ?= l4linux -PATCH-l4linux = patches/l4lx_genode.patch patches/icmp_align.patch +PATCH-l4linux = $(addprefix patches/,l4lx_genode.patch icmp_align.patch tcp_mem.patch) REV-l4linux = 23 REPO-l4linux = http://svn.tudos.org/repos/oc/l4linux/trunk @@ -16,6 +16,8 @@ PATCH-l4android = patches/l4android_genode.patch REV-l4android = 90ca43bd629452ffd38d85fe8c976f069b5bb3d9 REPO-l4android = git://git.l4android.org/kernel.git +UPDATE_PATCH = $(word 1, $(PATCH-$(TARGET))) + # # Utility to check if a tool is installed # @@ -30,11 +32,14 @@ UPDATE = cd $(REAL_CONTRIB_DIR)/l4android; git fetch; git reset --hard $(REV-l4a PATCH = patch -p1 else $(call check_tool,svn) -DIFF = svn diff -UPDATE = svn up -r $(REV-l4linux) $(REAL_CONTRIB_DIR)/l4linux -PATCH = patch -p0 +FILTER_DIR = net +DIFF_PATH = $(filter-out $(FILTER_DIR),$(shell ls $(REAL_CONTRIB_DIR)/l4linux)) +DIFF = svn diff $(DIFF_PATH) +UPDATE = svn up -r $(REV-l4linux) +PATCH = patch -p0 endif + # realpath is there to follow symlink; if contrib dir does not exists yet, # create new directory REAL_CONTRIB_DIR := $(realpath $(CONTRIB_DIR)) @@ -81,8 +86,8 @@ $(REAL_CONTRIB_DIR)/l4android: $(VERBOSE)git clone $(REPO-l4android) $@ update-patch: - $(ECHO) "Save changes to original code in $(PATCH-$(TARGET))" - $(VERBOSE)(cd $(REAL_CONTRIB_DIR)/$(TARGET); LC_COLLATE=C $(DIFF)) > $(PATCH-$(TARGET)) || true + $(ECHO) "Save changes to original code in $(UPDATE_PATCH)" + $(VERBOSE)(cd $(REAL_CONTRIB_DIR)/$(TARGET); LC_COLLATE=C $(DIFF)) > $(UPDATE_PATCH) || true clean: clean-$(TARGET) $(VERBOSE)rm -f $(CONTRIB_DIR)/$(TARGET)/arch/l4/drivers diff --git a/ports-foc/include/genode/net.h b/ports-foc/include/genode/net.h index 7a5ce2c74..5116b90ea 100644 --- a/ports-foc/include/genode/net.h +++ b/ports-foc/include/genode/net.h @@ -28,10 +28,11 @@ L4_CV int genode_net_ready (void); L4_CV void genode_net_start (void *dev, FASTCALL void (*func)(void*, void*, unsigned long)); L4_CV void genode_net_stop (void); L4_CV void genode_net_mac (void* mac_addr, unsigned long size); -L4_CV int genode_net_tx (void* addr, unsigned long len, void *skb); +L4_CV int genode_net_tx (void* addr, unsigned long len); L4_CV int genode_net_tx_ack_avail(void); -L4_CV void* genode_net_tx_ack (void); +L4_CV void genode_net_tx_ack (void); L4_CV void genode_net_rx_receive (void); +L4_CV void *genode_net_memcpy (void *dst, void const *src, unsigned long size); #ifdef __cplusplus } diff --git a/ports-foc/patches/l4lx_genode.patch b/ports-foc/patches/l4lx_genode.patch index 3144eea2f..d1a413db3 100644 --- a/ports-foc/patches/l4lx_genode.patch +++ b/ports-foc/patches/l4lx_genode.patch @@ -1,3 +1,27 @@ +Index: arch/l4/Kconfig +=================================================================== +--- arch/l4/Kconfig (revision 23) ++++ arch/l4/Kconfig (working copy) +@@ -394,7 +394,19 @@ + config L4_USE_L4SHMC + bool + ++config SCREEN_GENODE ++ bool ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ default y + ++config SERIAL_GENODE ++ bool ++ default y ++ select SERIAL_CORE ++ select SERIAL_CORE_CONSOLE ++ + # some delimiter (for .config) + comment "" + source "arch/l4/Kconfig.arch" Index: arch/l4/kernel/dispatch.c =================================================================== --- arch/l4/kernel/dispatch.c (revision 23) @@ -20,6 +44,181 @@ Index: arch/l4/kernel/dispatch.c } } } +Index: arch/l4/kernel/arch-x86/vmlinux.lds.S +=================================================================== +--- arch/l4/kernel/arch-x86/vmlinux.lds.S (revision 23) ++++ arch/l4/kernel/arch-x86/vmlinux.lds.S (working copy) +@@ -33,7 +33,7 @@ + + #ifdef CONFIG_X86_32 + OUTPUT_ARCH(i386) +-ENTRY(phys_startup_32) ++ENTRY(_start) + jiffies = jiffies_64; + #else + OUTPUT_ARCH(i386:x86-64) +@@ -67,17 +67,10 @@ + + #endif + +-PHDRS { +- text PT_LOAD FLAGS(5); /* R_E */ +- data PT_LOAD FLAGS(6); /* RW_ */ +-#ifdef CONFIG_X86_64 +- user PT_LOAD FLAGS(5); /* R_E */ +-#ifdef CONFIG_SMP +- percpu PT_LOAD FLAGS(6); /* RW_ */ +-#endif +- init PT_LOAD FLAGS(7); /* RWE */ +-#endif +- note PT_NOTE FLAGS(0); /* ___ */ ++PHDRS ++{ ++ ro PT_LOAD; ++ rw PT_LOAD; + } + + SECTIONS +@@ -97,6 +90,29 @@ + /*_stext = .;*/ + .text : AT(ADDR(.text) - LOAD_OFFSET) { + _text = .; ++ _prog_img_beg = .; ++ ++ /* ++ * Leave space for parent capability parameters at start of data ++ * section. The protection domain creator is reponsible for storing ++ * sane values here. ++ */ ++ _parent_cap = .; ++ _parent_cap_thread_id = .; ++ LONG(0xffffffff); ++ _parent_cap_local_name = .; ++ LONG(0xffffffff); ++ ++ /* ++ * Platform-specific entry for Fiasco.OC. ++ * ++ * PIC-code compiled for Fiasco.OC, needs some PIC-compatible ++ * way to enter the kernel, the fixed address of the kernel ++ * entry code address needs to be found here. ++ */ ++ __l4sys_invoke_indirect = .; ++ LONG(0xeacff000); ++ + /* bootstrapping code */ + HEAD_TEXT + #ifdef CONFIG_X86_32 +@@ -112,14 +128,28 @@ + ENTRY_TEXT + IRQENTRY_TEXT + *(.fixup) ++ *(.text.*) /* put all Genode .text entries in here */ + *(.gnu.warning) ++ ++ . = ALIGN(0x08); ++ ++ _ctors_start = .; ++ KEEP (*(.ctors)) ++ KEEP (*(SORT(.ctors.*))) ++ KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */ ++ _ctors_end = .; ++ _dtors_start = .; ++ KEEP (*(SORT(.dtors.*))) ++ KEEP (*(.dtors)) ++ _dtors_end = .; ++ + /* End of text section */ + _etext = .; +- } :text = 0x9090 ++ } : rw + +- NOTES :text :note ++ NOTES :rw + +- EXCEPTION_TABLE(16) :text = 0x9090 ++ .eh_frame_hdr : { *(.eh_frame_hdr) } + + #if defined(CONFIG_DEBUG_RODATA) + /* .text should occupy whole number of pages */ +@@ -152,10 +182,34 @@ + /* rarely changed data like cpu maps */ + READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES) + ++ *(.data.*) /* put all Genode .data entries in here */ ++ ++ + /* End of data section */ + _edata = .; +- } :data ++ } : rw + ++ EXCEPTION_TABLE(16) : rw ++ ++ /* exception frames for C++ */ ++ .eh_frame : { ++ __eh_frame_start__ = .; ++ KEEP (*(.eh_frame)) ++ LONG(0) ++ } : rw ++ ++ .init_array : { ++ __init_array_start = .; ++ KEEP (*(SORT(.init_array.*))) ++ KEEP (*(.init_array)) ++ __init_array_end = .; ++ } ++ ++ .gcc_except_table : { ++ KEEP(*(.gcc_except_table)) ++ KEEP(*(.gcc_except_table.*)) ++ } ++ + #ifdef CONFIG_X86_64 + + #ifdef CONFIG_L4 +@@ -366,6 +420,7 @@ + __bss_start = .; + *(.bss..page_aligned) + *(.bss) ++ *(.bss.*) /* put all Genode .bss entries in here */ + . = ALIGN(PAGE_SIZE); + __bss_stop = .; + } +@@ -378,6 +433,7 @@ + __brk_limit = .; + } + ++ _prog_img_end = .; + _end = .; + + STABS_DEBUG +Index: arch/l4/kernel/arch-x86/x86_init.c +=================================================================== +--- arch/l4/kernel/arch-x86/x86_init.c (revision 23) ++++ arch/l4/kernel/arch-x86/x86_init.c (working copy) +@@ -38,7 +38,7 @@ + struct x86_init_ops x86_init __initdata = { + + .resources = { +- .probe_roms = probe_roms, ++ .probe_roms = x86_init_noop, + .reserve_resources = reserve_standard_io_resources, + .memory_setup = l4x_memory_setup, + }, +Index: arch/l4/kernel/arch-arm/dispatch.c +=================================================================== +--- arch/l4/kernel/arch-arm/dispatch.c (revision 23) ++++ arch/l4/kernel/arch-arm/dispatch.c (working copy) +@@ -66,7 +66,7 @@ + }; + + +-#if 1 ++#if 0 + #define TBUF_LOG_IDLE(x) TBUF_DO_IT(x) + #define TBUF_LOG_WAKEUP_IDLE(x) TBUF_DO_IT(x) + #define TBUF_LOG_USER_PF(x) TBUF_DO_IT(x) Index: arch/l4/kernel/arch-arm/vmlinux.lds.S =================================================================== --- arch/l4/kernel/arch-arm/vmlinux.lds.S (revision 23) @@ -198,168 +397,6 @@ Index: arch/l4/kernel/arch-arm/traps.c } #endif -Index: arch/l4/kernel/arch-x86/x86_init.c -=================================================================== ---- arch/l4/kernel/arch-x86/x86_init.c (revision 23) -+++ arch/l4/kernel/arch-x86/x86_init.c (working copy) -@@ -38,7 +38,7 @@ - struct x86_init_ops x86_init __initdata = { - - .resources = { -- .probe_roms = probe_roms, -+ .probe_roms = x86_init_noop, - .reserve_resources = reserve_standard_io_resources, - .memory_setup = l4x_memory_setup, - }, -Index: arch/l4/kernel/arch-x86/vmlinux.lds.S -=================================================================== ---- arch/l4/kernel/arch-x86/vmlinux.lds.S (revision 23) -+++ arch/l4/kernel/arch-x86/vmlinux.lds.S (working copy) -@@ -33,7 +33,7 @@ - - #ifdef CONFIG_X86_32 - OUTPUT_ARCH(i386) --ENTRY(phys_startup_32) -+ENTRY(_start) - jiffies = jiffies_64; - #else - OUTPUT_ARCH(i386:x86-64) -@@ -67,17 +67,10 @@ - - #endif - --PHDRS { -- text PT_LOAD FLAGS(5); /* R_E */ -- data PT_LOAD FLAGS(6); /* RW_ */ --#ifdef CONFIG_X86_64 -- user PT_LOAD FLAGS(5); /* R_E */ --#ifdef CONFIG_SMP -- percpu PT_LOAD FLAGS(6); /* RW_ */ --#endif -- init PT_LOAD FLAGS(7); /* RWE */ --#endif -- note PT_NOTE FLAGS(0); /* ___ */ -+PHDRS -+{ -+ ro PT_LOAD; -+ rw PT_LOAD; - } - - SECTIONS -@@ -97,6 +90,29 @@ - /*_stext = .;*/ - .text : AT(ADDR(.text) - LOAD_OFFSET) { - _text = .; -+ _prog_img_beg = .; -+ -+ /* -+ * Leave space for parent capability parameters at start of data -+ * section. The protection domain creator is reponsible for storing -+ * sane values here. -+ */ -+ _parent_cap = .; -+ _parent_cap_thread_id = .; -+ LONG(0xffffffff); -+ _parent_cap_local_name = .; -+ LONG(0xffffffff); -+ -+ /* -+ * Platform-specific entry for Fiasco.OC. -+ * -+ * PIC-code compiled for Fiasco.OC, needs some PIC-compatible -+ * way to enter the kernel, the fixed address of the kernel -+ * entry code address needs to be found here. -+ */ -+ __l4sys_invoke_indirect = .; -+ LONG(0xeacff000); -+ - /* bootstrapping code */ - HEAD_TEXT - #ifdef CONFIG_X86_32 -@@ -112,14 +128,28 @@ - ENTRY_TEXT - IRQENTRY_TEXT - *(.fixup) -+ *(.text.*) /* put all Genode .text entries in here */ - *(.gnu.warning) -+ -+ . = ALIGN(0x08); -+ -+ _ctors_start = .; -+ KEEP (*(.ctors)) -+ KEEP (*(SORT(.ctors.*))) -+ KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */ -+ _ctors_end = .; -+ _dtors_start = .; -+ KEEP (*(SORT(.dtors.*))) -+ KEEP (*(.dtors)) -+ _dtors_end = .; -+ - /* End of text section */ - _etext = .; -- } :text = 0x9090 -+ } : rw - -- NOTES :text :note -+ NOTES :rw - -- EXCEPTION_TABLE(16) :text = 0x9090 -+ .eh_frame_hdr : { *(.eh_frame_hdr) } - - #if defined(CONFIG_DEBUG_RODATA) - /* .text should occupy whole number of pages */ -@@ -152,10 +182,34 @@ - /* rarely changed data like cpu maps */ - READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES) - -+ *(.data.*) /* put all Genode .data entries in here */ -+ -+ - /* End of data section */ - _edata = .; -- } :data -+ } : rw - -+ EXCEPTION_TABLE(16) : rw -+ -+ /* exception frames for C++ */ -+ .eh_frame : { -+ __eh_frame_start__ = .; -+ KEEP (*(.eh_frame)) -+ LONG(0) -+ } : rw -+ -+ .init_array : { -+ __init_array_start = .; -+ KEEP (*(SORT(.init_array.*))) -+ KEEP (*(.init_array)) -+ __init_array_end = .; -+ } -+ -+ .gcc_except_table : { -+ KEEP(*(.gcc_except_table)) -+ KEEP(*(.gcc_except_table.*)) -+ } -+ - #ifdef CONFIG_X86_64 - - #ifdef CONFIG_L4 -@@ -366,6 +420,7 @@ - __bss_start = .; - *(.bss..page_aligned) - *(.bss) -+ *(.bss.*) /* put all Genode .bss entries in here */ - . = ALIGN(PAGE_SIZE); - __bss_stop = .; - } -@@ -378,6 +433,7 @@ - __brk_limit = .; - } - -+ _prog_img_end = .; - _end = .; - - STABS_DEBUG Index: arch/l4/kernel/head.S =================================================================== --- arch/l4/kernel/head.S (revision 23) @@ -623,51 +660,6 @@ Index: arch/l4/kernel/main.c LOG_printf("Still alive, going zombie???\n"); l4_sleep_forever(); } -Index: arch/l4/Kconfig -=================================================================== ---- arch/l4/Kconfig (revision 23) -+++ arch/l4/Kconfig (working copy) -@@ -394,7 +394,19 @@ - config L4_USE_L4SHMC - bool - -+config SCREEN_GENODE -+ bool -+ select FB_CFB_FILLRECT -+ select FB_CFB_COPYAREA -+ select FB_CFB_IMAGEBLIT -+ default y - -+config SERIAL_GENODE -+ bool -+ default y -+ select SERIAL_CORE -+ select SERIAL_CORE_CONSOLE -+ - # some delimiter (for .config) - comment "" - source "arch/l4/Kconfig.arch" -Index: arch/l4/include/asm/generic/l4lib.h -=================================================================== ---- arch/l4/include/asm/generic/l4lib.h (revision 23) -+++ arch/l4/include/asm/generic/l4lib.h (working copy) -@@ -3,6 +3,7 @@ - - #include - -+#if 0 - #ifdef ARCH_arm - #define L4_EXTERNAL_FUNC(func) \ - asm(".section \".data.l4externals.str\" \n" \ -@@ -58,5 +59,8 @@ - ".previous \n" \ - ) - #endif -+#endif - -+#define L4_EXTERNAL_FUNC(func) ; -+ - #endif /* __INCLUDE__ASM_L4__GENERIC__L4LIB_H__ */ Index: arch/l4/boot/Makefile =================================================================== --- arch/l4/boot/Makefile (revision 23) @@ -834,18 +826,27 @@ Index: arch/l4/Makefile server: $(Q)$(MAKE) $(build)=arch/l4/server -Index: include/asm-generic/vmlinux.lds.h +Index: arch/l4/include/asm/generic/l4lib.h =================================================================== ---- include/asm-generic/vmlinux.lds.h (revision 23) -+++ include/asm-generic/vmlinux.lds.h (working copy) -@@ -371,6 +371,7 @@ - VMLINUX_SYMBOL(__start___modver) = .; \ - *(__modver) \ - VMLINUX_SYMBOL(__stop___modver) = .; \ -+ LONG(0) /* enforce non-zero section size */ \ - . = ALIGN((align)); \ - VMLINUX_SYMBOL(__end_rodata) = .; \ - } \ +--- arch/l4/include/asm/generic/l4lib.h (revision 23) ++++ arch/l4/include/asm/generic/l4lib.h (working copy) +@@ -3,6 +3,7 @@ + + #include + ++#if 0 + #ifdef ARCH_arm + #define L4_EXTERNAL_FUNC(func) \ + asm(".section \".data.l4externals.str\" \n" \ +@@ -58,5 +59,8 @@ + ".previous \n" \ + ) + #endif ++#endif + ++#define L4_EXTERNAL_FUNC(func) ; ++ + #endif /* __INCLUDE__ASM_L4__GENERIC__L4LIB_H__ */ Index: drivers/tty/serial/l4ser.c =================================================================== --- drivers/tty/serial/l4ser.c (revision 23) @@ -936,3 +937,15 @@ Index: drivers/tty/serial/l4ser.c if (l4ser_init_port(0, PORT0_NAME)) return -ENODEV; +Index: include/asm-generic/vmlinux.lds.h +=================================================================== +--- include/asm-generic/vmlinux.lds.h (revision 23) ++++ include/asm-generic/vmlinux.lds.h (working copy) +@@ -371,6 +371,7 @@ + VMLINUX_SYMBOL(__start___modver) = .; \ + *(__modver) \ + VMLINUX_SYMBOL(__stop___modver) = .; \ ++ LONG(0) /* enforce non-zero section size */ \ + . = ALIGN((align)); \ + VMLINUX_SYMBOL(__end_rodata) = .; \ + } \ diff --git a/ports-foc/patches/tcp_mem.patch b/ports-foc/patches/tcp_mem.patch new file mode 100644 index 000000000..f17e48d99 --- /dev/null +++ b/ports-foc/patches/tcp_mem.patch @@ -0,0 +1,19 @@ +Index: net/ipv4/tcp.c +=================================================================== +--- net/ipv4/tcp.c (revision 23) ++++ net/ipv4/tcp.c (working copy) +@@ -3285,8 +3285,13 @@ + + /* Set per-socket limits to no more than 1/128 the pressure threshold */ + limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); +- max_share = min(4UL*1024*1024, limit); + ++ /* ++ * Adjust limit so it performs well on systems with little memory. If ++ * this causes errors increase L4Linux main memory ++ */ ++ max_share = min(4UL*1024*1024, limit < 768U * 1024 ? 768U * 1024 : limit); ++ + sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; + sysctl_tcp_wmem[1] = 16*1024; + sysctl_tcp_wmem[2] = max(64*1024, max_share); diff --git a/ports-foc/src/drivers/genode_net.c b/ports-foc/src/drivers/genode_net.c index c25621760..c319d6291 100644 --- a/ports-foc/src/drivers/genode_net.c +++ b/ports-foc/src/drivers/genode_net.c @@ -35,7 +35,7 @@ static void genode_net_receive_packet(void* dev_addr, void *addr, struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev); /* allocate skb */ - struct sk_buff *skb = dev_alloc_skb(size + 2); + struct sk_buff *skb = dev_alloc_skb(size + 4); if (!skb) { if (printk_ratelimit()) printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n"); @@ -44,11 +44,12 @@ static void genode_net_receive_packet(void* dev_addr, void *addr, } /* copy packet */ - memcpy(skb_put(skb, size), addr, size); + genode_net_memcpy(skb_put(skb, size), addr, size); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_NONE; + netif_rx(skb); stats->rx_packets++; @@ -84,20 +85,21 @@ int genode_net_xmit_frame(struct sk_buff *skb, struct net_device *dev) /* collect acknowledgements of old packets */ while (genode_net_tx_ack_avail()) - dev_kfree_skb((struct sk_buff *)genode_net_tx_ack()); + genode_net_tx_ack(); /* transmit to nic-session */ - if (genode_net_tx(addr, len, skb)) { - /* tx queue is full, could not enqueue packet */ - netif_stop_queue(dev); - return 1; + while (genode_net_tx(addr, len)) { + /* tx queue is full, could not enqueue packet */ + genode_net_tx_ack(); } + dev_kfree_skb(skb); /* save timestamp */ dev->trans_start = jiffies; stats->tx_packets++; stats->tx_bytes += len; + return 0; } diff --git a/ports-foc/src/lib/l4lx/genode_net.cc b/ports-foc/src/lib/l4lx/genode_net.cc index 4c09ab576..70e259a23 100644 --- a/ports-foc/src/lib/l4lx/genode_net.cc +++ b/ports-foc/src/lib/l4lx/genode_net.cc @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include #include #include @@ -27,87 +29,77 @@ namespace Fiasco { #include #include #include +#include } -static Nic::Connection *nic() { - static Nic::Connection *n = 0; - static bool initialized = false; +#define TX_BENCH 0 +#define RX_BENCH 0 - if (!initialized) { - try { - static Genode::Allocator_avl tx_block_alloc(Genode::env()->heap()); - static Nic::Connection nic(&tx_block_alloc); - n = &nic; - } catch(...) { } - initialized = true; + +/** + * Debugging/Tracing + */ +#if TX_BENCH | RX_BENCH +struct Counter : public Genode::Thread<8192> +{ + int cnt; + Genode::size_t size; + + void entry() + { + Timer::Connection _timer; + int interval = 5; + while(1) { + _timer.msleep(interval * 1000); + PDBG("LX Packets %d/s bytes/s: %d", cnt / interval, size / interval); + cnt = 0; + size = 0; + } } + + void inc(Genode::size_t s) { cnt++; size += s; } + + Counter() : cnt(0), size(0) { start(); } +}; +#else +struct Counter { inline void inc(Genode::size_t s) { } }; +#endif + + +static Nic::Connection *nic() { + + enum { + PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE, + RX_BUF_SIZE = Nic::Session::RX_QUEUE_SIZE * PACKET_SIZE, + TX_BUF_SIZE = Nic::Session::TX_QUEUE_SIZE * PACKET_SIZE, + }; + + static Nic::Connection *n = 0; + static bool initialized = false; + + if (initialized) + return n; + + try { + Linux::Irq_guard guard; + static Nic::Packet_allocator tx_block_alloc(Genode::env()->heap()); + static Nic::Connection nic(&tx_block_alloc, TX_BUF_SIZE, RX_BUF_SIZE); + n = &nic; + } catch(...) { } + initialized = true; + return n; } + namespace { - class Packet_pool - { - private: - - class Entry - { - public: - - Packet_descriptor packet; - void *addr; - - Entry() : addr(0) {} - }; - - - enum { MAX_ENTRIES = 100 }; - - Entry _entries[MAX_ENTRIES]; - - public: - - class Pool_full : Genode::Exception {}; - - - void add(Packet_descriptor p, void* addr) - { - for (unsigned i=0; i < MAX_ENTRIES; i++) { - if (!_entries[i].addr) { - _entries[i].addr = addr; - _entries[i].packet = p; - return; - } - } - throw Pool_full(); - } - - void* get(Packet_descriptor _packet) - { - for (unsigned i=0; i < MAX_ENTRIES; i++) - if (nic()->tx()->packet_content(_packet) - == nic()->tx()->packet_content(_entries[i].packet)) { - void *ret = _entries[i].addr; - _entries[i].addr = 0; - return ret; - } - return 0; - } - }; - - - static Packet_pool *packet_pool() - { - static Packet_pool pool; - return &pool; - } - - class Signal_thread : public Genode::Thread<8192> { private: Fiasco::l4_cap_idx_t _cap; + Genode::Lock *_sync; protected: @@ -122,8 +114,11 @@ namespace { nic()->rx_channel()->sigh_ready_to_ack(cap); nic()->rx_channel()->sigh_packet_avail(cap); + _sync->unlock(); + while (true) { receiver.wait_for_signal(); + if (l4_error(l4_irq_trigger(_cap)) != -1) PWRN("IRQ net trigger failed\n"); } @@ -131,8 +126,9 @@ namespace { public: - Signal_thread(Fiasco::l4_cap_idx_t cap) - : Genode::Thread<8192>("net-signal-thread"), _cap(cap) { start(); } + Signal_thread(Fiasco::l4_cap_idx_t cap, Genode::Lock *sync) + : Genode::Thread<8192>("net-signal-thread"), _cap(cap), _sync(sync) { + start(); } }; } @@ -141,7 +137,7 @@ using namespace Fiasco; extern "C" { static FASTCALL void (*receive_packet)(void*, void*, unsigned long) = 0; - static void *net_device = 0; + static void *net_device = 0; void genode_net_start(void *dev, FASTCALL void (*func)(void*, void*, unsigned long)) @@ -153,8 +149,11 @@ extern "C" { l4_cap_idx_t genode_net_irq_cap() { + Linux::Irq_guard guard; static Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq(); - static Signal_thread th(cap.dst()); + static Genode::Lock lock(Genode::Lock::LOCKED); + static Signal_thread th(cap.dst(), &lock); + lock.lock(); return cap.dst(); } @@ -168,6 +167,7 @@ extern "C" { void genode_net_mac(void* mac, unsigned long size) { + Linux::Irq_guard guard; using namespace Genode; Nic::Mac_address m = nic()->mac_address(); @@ -175,21 +175,25 @@ extern "C" { } - int genode_net_tx(void* addr, unsigned long len, void *skb) + int genode_net_tx(void* addr, unsigned long len) { + Linux::Irq_guard guard; + static Counter counter; + try { Packet_descriptor packet = nic()->tx()->alloc_packet(len); void* content = nic()->tx()->packet_content(packet); - packet_pool()->add(packet, skb); - Genode::memcpy(content, addr, len); + + Genode::memcpy((char *)content, addr, len); nic()->tx()->submit_packet(packet); + + counter.inc(len); + return 0; - } catch(Packet_pool::Pool_full) { - PWRN("skb_buff/packet pool full!"); + /* 'Packet_alloc_failed' */ } catch(...) { - PWRN("Send failed!"); + return 1; } - return 1; } @@ -197,22 +201,28 @@ extern "C" { return nic()->tx()->ack_avail(); } - void* genode_net_tx_ack() + void genode_net_tx_ack() { + Linux::Irq_guard guard; + Packet_descriptor packet = nic()->tx()->get_acked_packet(); - void *skb = packet_pool()->get(packet); nic()->tx()->release_packet(packet); - return skb; } void genode_net_rx_receive() { + Linux::Irq_guard guard; + static Counter counter; + if (nic()) { while(nic()->rx()->packet_avail()) { Packet_descriptor p = nic()->rx()->get_packet(); + if (receive_packet && net_device) receive_packet(net_device, nic()->rx()->packet_content(p), p.size()); + + counter.inc(p.size()); nic()->rx()->acknowledge_packet(p); } } @@ -223,4 +233,8 @@ extern "C" { { return nic() ? 1 : 0; } + + + void *genode_net_memcpy(void *dst, void const *src, unsigned long size) { + return Genode::memcpy(dst, src, size); } }