diff --git a/repos/mml/src/lib/mxip/include/stdlib.h b/repos/mml/src/lib/mxip/include/stdlib.h new file mode 100644 index 0000000000..2641481f45 --- /dev/null +++ b/repos/mml/src/lib/mxip/include/stdlib.h @@ -0,0 +1,15 @@ +#ifndef _LWIP__INCLUDE__STDLIB_H_ +#define _LWIP__INCLUDE__STDLIB_H_ + +/** + * Simple atoi for LwIP purposes + */ +static inline int atoi(char const *s) +{ + int n = 0; + while ('0' <= *s && *s <= '9') + n = 10*n - (*s++ - '0'); + return n; +} + +#endif diff --git a/repos/mml/src/lib/mxip/include/string.h b/repos/mml/src/lib/mxip/include/string.h new file mode 100644 index 0000000000..0d4b83330f --- /dev/null +++ b/repos/mml/src/lib/mxip/include/string.h @@ -0,0 +1,34 @@ +/* + * \brief Memory manipulation utilities + * \author Emery Hemingway + * \date 2017-08-21 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef __LWIP__INCLUDE__STRING_H__ +#define __LWIP__INCLUDE__STRING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void *memcpy(void *dst, const void *src, size_t len); +void *memset(void *b, int c, size_t len); + +size_t strlen(const char *s); + +int memcmp(const void *b1, const void *b2, size_t len); +int strcmp(const char *s1, const char *s2); +int strncmp(const char *s1, const char *s2, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP__INCLUDE__STRING_H__ */ \ No newline at end of file diff --git a/repos/mml/src/lib/mxip/memmove.patch b/repos/mml/src/lib/mxip/memmove.patch new file mode 100644 index 0000000000..681805f15d --- /dev/null +++ b/repos/mml/src/lib/mxip/memmove.patch @@ -0,0 +1,12 @@ +diff --git a/src/core/def.c b/src/core/def.c +index 9da36fee..58edce6f 100644 +--- a/src/core/def.c ++++ b/src/core/def.c +@@ -235,6 +235,6 @@ lwip_itoa(char *result, size_t bufsize, int number) + return; + } + /* move from temporary buffer to output buffer (sign is not moved) */ +- memmove(res, tmp, (size_t)((result + bufsize) - tmp)); ++ MEMMOVE(res, tmp, (size_t)((result + bufsize) - tmp)); + } + #endif diff --git a/repos/mml/src/lib/mxip/platform/mxnic_netif.cc b/repos/mml/src/lib/mxip/platform/mxnic_netif.cc new file mode 100644 index 0000000000..b70363e46d --- /dev/null +++ b/repos/mml/src/lib/mxip/platform/mxnic_netif.cc @@ -0,0 +1,80 @@ +#include "mxnic_netif.h" +#include + +void Lwip::Nic_netif::handle_rx_packets() +{ + + Nic::Session::Rx::Sink *rx = _nic.rx(); + + bool progress = false; + + while (rx->packet_avail() && rx->ready_to_ack()) { + + try + { + Nic::Packet_descriptor packet = rx->try_get_packet(); + progress = true; + + Nic_netif_pbuf *nic_pbuf = new (this->_pbuf_alloc) Nic_netif_pbuf(*this, packet); + + if (!nic_pbuf) { + Genode::warning("Could not allocate pbuf "); + return; + } + pbuf* p = pbuf_alloced_custom( + PBUF_RAW, + packet.size(), + PBUF_REF, + &nic_pbuf->p, + rx->packet_content(packet), + packet.size()); + LINK_STATS_INC(link.recv); + + if (!p) { + Genode::warning("Initialization of pbuf failed."); + return; + } + + Lwip::Receive_task *task = new (_handler_allocator->allocate(0, 64, sizeof(Lwip::Receive_task))) Lwip::Receive_task(p, _netif, *this, nic_pbuf); + if (task == nullptr) + { + Genode::warning("Could not allocate task object."); + return; + } + task->annotate(static_cast(0)); + mx::tasking::runtime::spawn(*task); + + if (progress) + wake_up_nic_server(); + } + catch (Genode::Exception) + { + Genode::warning("Got signal without actual packet in queue"); + } + } +} + +void Lwip::Nic_netif::handle_tx_ready() +{ + Lwip::Tx_ready_task *task = new (_handler_allocator->allocate(0, 64, sizeof(Lwip::Tx_ready_task))) Lwip::Tx_ready_task(_nic, *this); + if (task == nullptr) + { + Genode::warning("Could not allocate tx_ready task object."); + return; + } + task->annotate(static_cast(0)); + mx::tasking::runtime::spawn(*task); + + +} + +void Lwip::Nic_netif::handle_link_state() +{ + Lwip::Link_state_task *task = new (_handler_allocator->allocate(0, 64, sizeof(Lwip::Link_state_task))) Lwip::Link_state_task(_nic, _netif, *this, _dhcp); // mx::tasking::runtime::new_task(0, _nic, _netif, _dhcp); + if (task == nullptr) { + Genode::warning("Could not allocate link state task object."); + return; + } + task->annotate(static_cast(0)); + mx::tasking::runtime::spawn(*task); +} \ No newline at end of file diff --git a/repos/mml/src/lib/mxip/platform/printf.cc b/repos/mml/src/lib/mxip/platform/printf.cc new file mode 100644 index 0000000000..38d93d694b --- /dev/null +++ b/repos/mml/src/lib/mxip/platform/printf.cc @@ -0,0 +1,36 @@ +/* + * \brief Print function for debugging functionality of lwIP. + * \author Stefan Kalkowski + * \date 2009-10-26 + */ + +/* + * Copyright (C) 2009-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode includes */ +#include +#include + +extern "C" { + +/* LwIP includes */ +#include + + /* Simply map to Genode's printf implementation */ + void lwip_printf(const char *format, ...) + { + va_list list; + va_start(list, format); + + char buf[128] { }; + Genode::String_console(buf, sizeof(buf)).vprintf(format, list); + Genode::log(Genode::Cstring(buf)); + + va_end(list); + } + +} diff --git a/repos/mml/src/lib/mxip/platform/rand.cc b/repos/mml/src/lib/mxip/platform/rand.cc new file mode 100644 index 0000000000..0472c619cf --- /dev/null +++ b/repos/mml/src/lib/mxip/platform/rand.cc @@ -0,0 +1,30 @@ +/* + * \brief Simple random number generator for lwIP + * \author Emery Hemingway + * \date 2016-07-30 + */ + +// *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org +// Licensed under Apache License 2.0 (NO WARRANTY, etc. see website) + +/* Genode includes */ +#include +#include + +extern "C" +genode_uint32_t genode_rand() +{ + using namespace Genode; + + static uint64_t const inc = Trace::timestamp()|1; + static uint64_t state = Trace::timestamp(); + uint64_t oldstate = state; + + // Advance internal state + state = oldstate * 6364136223846793005ULL + inc; + + // Calculate output function (XSH RR), uses old state for max ILP + uint32_t xorshifted = (uint32_t)(((oldstate >> 18u) ^ oldstate) >> 27u); + uint32_t rot = (uint32_t)(oldstate >> 59u); + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +} diff --git a/repos/mml/src/lib/mxip/platform/sys_arch.cc b/repos/mml/src/lib/mxip/platform/sys_arch.cc new file mode 100644 index 0000000000..26125d990f --- /dev/null +++ b/repos/mml/src/lib/mxip/platform/sys_arch.cc @@ -0,0 +1,145 @@ +/* + * \brief lwIP platform support + * \author Stefan Kalkowski + * \author Emery Hemingway + * \date 2016-12-01 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode includes */ +#include +#include +#include +#include + +#include + +/* MxTasking includes */ +#include +#include +#include + +extern "C" { +/* LwIP includes */ +#include +#include +#include + +/* our abridged copy of string.h */ +#include +} + +namespace Mxip { + + static mx::memory::dynamic::Allocator *_heap; + class Timeout_task : public mx::tasking::TaskInterface + { + public: + Timeout_task() {} + + mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override + { + //GENODE_LOG_TSC_NAMED(1, "sys_check_timeouts"); + sys_check_timeouts(); + _heap->free(static_cast(this)); + return mx::tasking::TaskResult::make_null(); + } + }; + + struct Mx_timer + { + void check_timeouts(Genode::Duration) + { + Timeout_task *task = new (_heap->allocate(0, 64, sizeof(Timeout_task))) Timeout_task(); // mx::tasking::runtime::new_task(0); + if (task == nullptr) { + Genode::error("Failed to allocate timeout task"); + return; + } + task->annotate(static_cast(0)); + mx::tasking::runtime::spawn(*task); + } + + ::Timer::Connection &timer; + + Timer::Periodic_timeout timeout{ + timer, *this, &Mx_timer::check_timeouts, Genode::Microseconds{250 * 1000}}; + + Mx_timer(::Timer::Connection &timer) : timer(timer) {} + }; + + static Mx_timer *sys_timer_ptr; + + void mxip_init(mx::memory::dynamic::Allocator &heap, ::Timer::Connection &timer) + { + _heap = &heap; + + static Mx_timer sys_timer(timer); + sys_timer_ptr = &sys_timer; + + lwip_init(); + } + +} + + +extern "C" { + + void lwip_platform_assert(char const* msg, char const *file, int line) + { + Genode::error("Assertion \"", msg, "\" ", file, ":", line); + Genode::sleep_forever(); + } + + void genode_free(void *ptr) + { + Mxip::_heap->free(ptr); + } + + void *genode_malloc(unsigned long size) + { + return Mxip::_heap->allocate(0, 64, size); + } + + void *genode_calloc(unsigned long number, unsigned long size) + { + size *= number; + + void * const ptr = genode_malloc(size); + if (ptr) + Genode::memset(ptr, 0x00, size); + + return ptr; + } + + u32_t sys_now(void) { + /* TODO: Use actual CPU frequency */ + //return (u32_t)Mxip::sys_timer_ptr->timer.curr_time().trunc_to_plain_ms().value; + return __builtin_ia32_rdtsc() / 2000000; + } + + void genode_memcpy(void *dst, const void *src, size_t len) + { + std::memcpy(dst, src, len); } + + void *genode_memmove(void *dst, const void *src, size_t len) { + return std::memmove(dst, src, len); } + + int memcmp(const void *b1, const void *b2, ::size_t len) { + return std::memcmp(b1, b2, len); } + + int strcmp(const char *s1, const char *s2) + { + size_t len = std::min(Genode::strlen(s1), Genode::strlen(s2)); + return std::strncmp(s1, s2, len); + } + + int strncmp(const char *s1, const char *s2, size_t len) { + return std::strncmp(s1, s2, len); } + +}