MxIP platform support package.

This commit is contained in:
Michael Mueller
2025-01-21 15:31:16 +01:00
parent 52d5a3d19e
commit 93595efd44
7 changed files with 352 additions and 0 deletions

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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

View File

@@ -0,0 +1,80 @@
#include "mxnic_netif.h"
#include <base/log.h>
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<mx::tasking::TaskInterface::channel>(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<mx::tasking::TaskInterface::channel>(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<Lwip::Link_state_task>(0, _nic, _netif, _dhcp);
if (task == nullptr) {
Genode::warning("Could not allocate link state task object.");
return;
}
task->annotate(static_cast<mx::tasking::TaskInterface::channel>(0));
mx::tasking::runtime::spawn(*task);
}

View File

@@ -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 <base/snprintf.h>
#include <base/env.h>
extern "C" {
/* LwIP includes */
#include <arch/cc.h>
/* 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);
}
}

View File

@@ -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 <trace/timestamp.h>
#include <base/fixed_stdint.h>
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));
}

View File

@@ -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 <timer_session/connection.h>
#include <util/reconstructible.h>
#include <base/sleep.h>
#include <base/log.h>
#include <lwip/genode_init.h>
/* MxTasking includes */
#include <mx/tasking/runtime.h>
#include <mx/tasking/task.h>
#include <mx/memory/dynamic_size_allocator.h>
extern "C" {
/* LwIP includes */
#include <lwip/timeouts.h>
#include <lwip/init.h>
#include <lwip/sys.h>
/* our abridged copy of string.h */
#include <cstring>
}
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<void *>(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<Timeout_task>(0);
if (task == nullptr) {
Genode::error("Failed to allocate timeout task");
return;
}
task->annotate(static_cast<mx::tasking::TaskInterface::channel>(0));
mx::tasking::runtime::spawn(*task);
}
::Timer::Connection &timer;
Timer::Periodic_timeout<Mx_timer> 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); }
}