WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] minios: add lwIP 1.3.0 support

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] minios: add lwIP 1.3.0 support
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Fri, 18 Jan 2008 18:23:25 +0000
Delivery-date: Fri, 18 Jan 2008 10:42:29 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
minios: add lwIP 1.3.0 support

This is to be applied on top of the POSIX-time patch

only in patch2:
unchanged:
--- a/extras/mini-os/Makefile   Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/Makefile   Fri Jan 18 18:18:12 2008 +0000
@@ -47,6 +47,13 @@ EXTRA_INC =
 # This must be before include minios.mk!
 include $(TARGET_ARCH_DIR)/arch.mk
 
+ifneq ($(LWIPDIR),)
+lwip=y
+DEF_CFLAGS += -DHAVE_LWIP
+DEF_CFLAGS += -I$(LWIPDIR)/src/include
+DEF_CFLAGS += -I$(LWIPDIR)/src/include/ipv4
+endif
+
 # Include common mini-os makerules.
 include minios.mk
 
@@ -90,6 +97,24 @@ arch_lib:
 arch_lib:
        $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
 
+ifeq ($(lwip),y)
+# lwIP library
+LWC    := $(shell find $(LWIPDIR)/ -type f -name '*.c')
+LWC    := $(filter-out %6.c %ip6_addr.c %ethernetif.c, $(LWC))
+LWC    += lwip-arch.c lwip-net.c
+LWO    := $(patsubst %.c,%.o,$(LWC))
+
+lwip.a: $(LWO)
+       $(RM) $@
+       $(AR) cqs $@ $^
+
+OBJS += lwip.a
+
+OBJS := $(filter-out $(LWO), $(OBJS))
+else
+OBJS := $(filter-out daytime.o lwip%.o, $(OBJS))
+endif
+
 $(TARGET): links $(OBJS) arch_lib
        $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o
        $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
@@ -107,6 +132,7 @@ clean:      arch_clean
        done
        rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
        find . -type l | xargs rm -f
+       $(RM) lwip.a $(LWO)
        rm -f tags TAGS
 
 
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/daytime.c  Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,64 @@
+/* 
+ * daytime.c: a simple network service based on lwIP and mini-os
+ * 
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#include <os.h>
+#include <xmalloc.h>
+#include <console.h>
+#include <netfront.h>
+#include <lwip/api.h>
+
+static char message[29];
+
+void run_server(void *p)
+{
+    struct ip_addr listenaddr = { 0 };
+    struct ip_addr ipaddr = { htonl(0x0a000001) };
+    struct ip_addr netmask = { htonl(0xff000000) };
+    struct ip_addr gw = { 0 };
+    struct netconn *listener;
+    struct netconn *session;
+    struct timeval tv;
+    err_t rc;
+
+    start_networking();
+    networking_set_addr(&ipaddr, &netmask, &gw);
+
+    tprintk("Opening connection\n");
+
+    listener = netconn_new(NETCONN_TCP);
+    tprintk("Connection at %p\n", listener);
+
+    rc = netconn_bind(listener, &listenaddr, 13);
+    if (rc != ERR_OK) {
+        tprintk("Failed to bind connection: %i\n", rc);
+        return;
+    }
+
+    rc = netconn_listen(listener);
+    if (rc != ERR_OK) {
+        tprintk("Failed to listen on connection: %i\n", rc);
+        return;
+    }
+
+    while (1) {
+        session = netconn_accept(listener);
+        if (session == NULL) 
+            continue;
+
+        gettimeofday(&tv, NULL);
+        sprintf(message, "%20lu.%6.6lu\n", tv.tv_sec, tv.tv_usec);
+        (void) netconn_write(session, message, strlen(message), NETCONN_COPY);
+        (void) netconn_disconnect(session);
+        (void) netconn_delete(session);
+    }
+}
+
+
+int app_main(start_info_t *si)
+{
+    create_thread("server", run_server, NULL);
+    return 0;
+}
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/arch/cc.h  Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,83 @@
+/* 
+ * lwip/arch/cc.h
+ *
+ * Compiler-specific types and macros for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_ARCH_CC_H__
+#define __LWIP_ARCH_CC_H__
+
+/*   Typedefs for the types used by lwip - */
+#include <os.h>
+#include <types.h>
+#include <time.h>
+typedef  u8  u8_t;
+typedef  s8  s8_t;
+typedef u16 u16_t;
+typedef s16 s16_t;
+typedef u32 u32_t;
+typedef s32 s32_t;
+typedef u64 u64_t;
+typedef s64 s64_t;
+typedef uintptr_t mem_ptr_t;
+
+typedef u16 u_short;
+
+/*   Compiler hints for packing lwip's structures - */
+#define PACK_STRUCT_FIELD(_x)  _x
+#define PACK_STRUCT_STRUCT     __attribute__ ((packed))
+#define PACK_STRUCT_BEGIN 
+#define PACK_STRUCT_END
+
+/*   Platform specific diagnostic output - */
+
+extern void lwip_printk(char *fmt, ...);
+#define LWIP_PLATFORM_DIAG(_x) do { lwip_printk _x ; } while (0)
+
+extern void lwip_die(char *fmt, ...);
+#define LWIP_PLATFORM_ASSERT(_x) do { lwip_die(_x); } while(0)
+
+/*   "lightweight" synchronization mechanisms - */
+/*     SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. */
+/*     SYS_ARCH_PROTECT(x)      - enter protection mode. */
+/*     SYS_ARCH_UNPROTECT(x)    - leave protection mode. */
+
+/*   If the compiler does not provide memset() this file must include a */
+/*   definition of it, or include a file which defines it. */
+#include <lib.h>
+
+/*   This file must either include a system-local <errno.h> which defines */
+/*   the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO */
+/*   to make lwip/arch.h define the codes which are used throughout. */
+#include <errno.h>
+
+/*   Not required by the docs, but needed for network-order calculations */
+#include <endian.h>
+
+#include <inttypes.h>
+#define S16_F PRIi16
+#define U16_F PRIu16
+#define X16_F PRIx16
+#define S32_F PRIi32
+#define U32_F PRIu32
+#define X32_F PRIx32
+
+#if 0
+#ifndef DBG_ON
+#define DBG_ON LWIP_DBG_ON
+#endif
+#define LWIP_DEBUG     DBG_ON
+//#define IP_DEBUG     DBG_ON
+#define TCP_DEBUG      DBG_ON
+#define TCP_INPUT_DEBUG        DBG_ON
+#define TCP_QLEN_DEBUG DBG_ON
+#define TCPIP_DEBUG    DBG_ON
+#define DBG_TYPES_ON   DBG_ON
+#endif
+
+/* TODO: checksum doesn't work fine?! */
+#define CHECKSUM_CHECK_TCP     0
+
+#endif /* __LWIP_ARCH_CC_H__ */
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/arch/perf.h        Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,15 @@
+/* 
+ * lwip/arch/perf.h
+ *
+ * Arch-specific performance measurement for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_ARCH_PERF_H__
+#define __LWIP_ARCH_PERF_H__
+
+#define PERF_START    do { } while(0)
+#define PERF_STOP(_x) do { (void)(_x); } while (0)
+
+#endif /* __LWIP_ARCH_PERF_H__ */
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/arch/sys_arch.h    Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,35 @@
+/* 
+ * lwip/arch/sys_arch.h
+ *
+ * Arch-specific semaphores and mailboxes for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_ARCH_SYS_ARCH_H__
+#define __LWIP_ARCH_SYS_ARCH_H__
+
+#include <os.h>
+#include <xmalloc.h>
+#include <semaphore.h>
+
+typedef struct semaphore *sys_sem_t;
+#define SYS_SEM_NULL ((sys_sem_t) NULL)
+
+struct mbox {
+    int count;
+    void **messages;
+    struct semaphore read_sem;
+    struct semaphore write_sem;
+    int writer;
+    int reader;
+};
+
+typedef struct mbox *sys_mbox_t;
+#define SYS_MBOX_NULL ((sys_mbox_t) 0)
+
+typedef struct thread *sys_thread_t;
+
+typedef unsigned long sys_prot_t;
+
+#endif /*__LWIP_ARCH_SYS_ARCH_H__ */
only in patch2:
unchanged:
--- a/extras/mini-os/include/console.h  Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/include/console.h  Fri Jan 18 18:18:12 2008 +0000
@@ -38,8 +38,11 @@
 
 #include<traps.h>
 
+void print(int direct, const char *fmt, va_list args);
 void printk(const char *fmt, ...);
 void xprintk(const char *fmt, ...);
+
+#define tprintk(_fmt, _args...) printk("[%s] " _fmt, current->name, ##_args) 
 
 void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
 void xencons_tx(void);
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/lwipopts.h Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,22 @@
+/*
+ * lwipopts.h
+ *
+ * Configuration for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_LWIPOPTS_H__
+#define __LWIP_LWIPOPTS_H__
+
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 1
+#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_DHCP 1
+#define LWIP_COMPAT_SOCKETS 0
+#define LWIP_IGMP 1
+#define MEMP_NUM_SYS_TIMEOUT 10
+#define TCP_SND_BUF 3000
+#define TCP_MSS 1500
+
+#endif /* __LWIP_LWIPOPTS_H__ */
only in patch2:
unchanged:
--- a/extras/mini-os/include/netfront.h Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/include/netfront.h Fri Jan 18 18:18:12 2008 +0000
@@ -1,7 +1,19 @@
 #include <wait.h>
+#ifdef HAVE_LWIP
+#include <lwip/netif.h>
+#endif
 struct netfront_dev;
 struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned 
char *data, int len), unsigned char rawmac[6]);
 void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
 void shutdown_netfront(struct netfront_dev *dev);
 
 extern struct wait_queue_head netfront_queue;
+
+#ifdef HAVE_LWIP
+/* Call this to bring up the netfront interface and the lwIP stack.
+ * N.B. _must_ be called from a thread; it's not safe to call this from 
+ * app_main(). */
+void start_networking(void);
+
+void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, 
struct ip_addr *gw);
+#endif
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/lwip-arch.c        Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,293 @@
+/* 
+ * lwip-arch.c
+ *
+ * Arch-specific semaphores and mailboxes for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#include <os.h>
+#include <time.h>
+#include <console.h>
+#include <xmalloc.h>
+#include <lwip/sys.h>
+#include <stdarg.h>
+
+/* Is called to initialize the sys_arch layer */
+void sys_init(void)
+{
+}
+
+/* Creates and returns a new semaphore. The "count" argument specifies
+ * the initial state of the semaphore. */
+sys_sem_t sys_sem_new(u8_t count)
+{
+    struct semaphore *sem = xmalloc(struct semaphore);
+    sem->count = count;
+    init_waitqueue_head(&sem->wait);
+    return sem;
+}
+
+/* Deallocates a semaphore. */
+void sys_sem_free(sys_sem_t sem)
+{
+    xfree(sem);
+}
+
+/* Signals a semaphore. */
+void sys_sem_signal(sys_sem_t sem)
+{
+    up(sem);
+}
+
+/* Blocks the thread while waiting for the semaphore to be
+ * signaled. If the "timeout" argument is non-zero, the thread should
+ * only be blocked for the specified time (measured in
+ * milliseconds).
+ * 
+ * If the timeout argument is non-zero, the return value is the number of
+ * milliseconds spent waiting for the semaphore to be signaled. If the
+ * semaphore wasn't signaled within the specified time, the return value is
+ * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
+ * (i.e., it was already signaled), the function may return zero. */
+u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
+{
+    /* Slightly more complicated than the normal minios semaphore:
+     * need to wake on timeout *or* signal */
+    sys_prot_t prot;
+    s64_t then = NOW();
+    s64_t deadline;
+
+    if (timeout == 0)
+       deadline = 0;
+    else
+       deadline = then + MILLISECS(timeout);
+
+    while(1) {
+        wait_event_deadline(sem->wait, (sem->count > 0), deadline);
+
+        prot = sys_arch_protect();
+       /* Atomically check that we can proceed */
+       if (sem->count > 0 || (deadline && NOW() >= deadline))
+           break;
+        sys_arch_unprotect(prot);
+    }
+
+    if (sem->count > 0) {
+        sem->count--;
+        sys_arch_unprotect(prot);
+        return NSEC_TO_MSEC(NOW() - then); 
+    }
+    
+    sys_arch_unprotect(prot);
+    return SYS_ARCH_TIMEOUT;
+}
+
+/* Creates an empty mailbox. */
+sys_mbox_t sys_mbox_new(int size)
+{
+    struct mbox *mbox = xmalloc(struct mbox);
+    if (!size)
+        size = 32;
+    else if (size == 1)
+        size = 2;
+    mbox->count = size;
+    mbox->messages = xmalloc_array(void*, size);
+    init_SEMAPHORE(&mbox->read_sem, 0);
+    mbox->reader = 0;
+    init_SEMAPHORE(&mbox->write_sem, size);
+    mbox->writer = 0;
+    return mbox;
+}
+
+/* Deallocates a mailbox. If there are messages still present in the
+ * mailbox when the mailbox is deallocated, it is an indication of a
+ * programming error in lwIP and the developer should be notified. */
+void sys_mbox_free(sys_mbox_t mbox)
+{
+    ASSERT(mbox->reader == mbox->writer);
+    xfree(mbox->messages);
+    xfree(mbox);
+}
+
+/* Posts the "msg" to the mailbox, internal version that actually does the
+ * post. */
+static void do_mbox_post(sys_mbox_t mbox, void *msg)
+{
+    /* The caller got a semaphore token, so we are now allowed to increment
+     * writer, but we still need to prevent concurrency between writers
+     * (interrupt handler vs main) */
+    sys_prot_t prot = sys_arch_protect();
+    mbox->messages[mbox->writer] = msg;
+    mbox->writer = (mbox->writer + 1) % mbox->count;
+    ASSERT(mbox->reader != mbox->writer);
+    sys_arch_unprotect(prot);
+    up(&mbox->read_sem);
+}
+
+/* Posts the "msg" to the mailbox. */
+void sys_mbox_post(sys_mbox_t mbox, void *msg)
+{
+    if (mbox == SYS_MBOX_NULL)
+        return;
+    down(&mbox->write_sem);
+    do_mbox_post(mbox, msg);
+}
+
+/* Try to post the "msg" to the mailbox. */
+err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
+{
+    if (mbox == SYS_MBOX_NULL)
+        return ERR_BUF;
+    if (!trydown(&mbox->write_sem))
+        return ERR_MEM;
+    do_mbox_post(mbox, msg);
+    return ERR_OK;
+}
+
+/*
+ * Fetch a message from a mailbox. Internal version that actually does the
+ * fetch.
+ */
+static void do_mbox_fetch(sys_mbox_t mbox, void **msg)
+{
+    sys_prot_t prot;
+    /* The caller got a semaphore token, so we are now allowed to increment
+     * reader, but we may still need to prevent concurrency between readers.
+     * FIXME: can there be concurrent readers? */
+    prot = sys_arch_protect();
+    ASSERT(mbox->reader != mbox->writer);
+    if (msg != NULL)
+        *msg = mbox->messages[mbox->reader];
+    mbox->reader = (mbox->reader + 1) % mbox->count;
+    sys_arch_unprotect(prot);
+    up(&mbox->write_sem);
+}
+
+/* Blocks the thread until a message arrives in the mailbox, but does
+ * not block the thread longer than "timeout" milliseconds (similar to
+ * the sys_arch_sem_wait() function). The "msg" argument is a result
+ * parameter that is set by the function (i.e., by doing "*msg =
+ * ptr"). The "msg" parameter maybe NULL to indicate that the message
+ * should be dropped.
+ *
+ * The return values are the same as for the sys_arch_sem_wait() function:
+ * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
+ * timeout. */
+u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
+{
+    u32 rv;
+    if (mbox == SYS_MBOX_NULL)
+        return SYS_ARCH_TIMEOUT;
+
+    rv = sys_arch_sem_wait(&mbox->read_sem, timeout);
+    if ( rv == SYS_ARCH_TIMEOUT )
+        return rv;
+
+    do_mbox_fetch(mbox, msg);
+    return 0;
+}
+
+/* This is similar to sys_arch_mbox_fetch, however if a message is not
+ * present in the mailbox, it immediately returns with the code
+ * SYS_MBOX_EMPTY. On success 0 is returned.
+ *
+ * To allow for efficient implementations, this can be defined as a
+ * function-like macro in sys_arch.h instead of a normal function. For
+ * example, a naive implementation could be:
+ *   #define sys_arch_mbox_tryfetch(mbox,msg) \
+ *     sys_arch_mbox_fetch(mbox,msg,1)
+ * although this would introduce unnecessary delays. */
+
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) {
+    if (mbox == SYS_MBOX_NULL)
+        return SYS_ARCH_TIMEOUT;
+
+    if (!trydown(&mbox->read_sem))
+       return SYS_MBOX_EMPTY;
+
+    do_mbox_fetch(mbox, msg);
+    return 0;
+}
+
+
+/* Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
+ * each thread has a list of timeouts which is repressented as a linked
+ * list of sys_timeout structures. The sys_timeouts structure holds a
+ * pointer to a linked list of timeouts. This function is called by
+ * the lwIP timeout scheduler and must not return a NULL value. 
+ *
+ * In a single threadd sys_arch implementation, this function will
+ * simply return a pointer to a global sys_timeouts variable stored in
+ * the sys_arch module. */
+struct sys_timeouts *sys_arch_timeouts(void) 
+{
+    static struct sys_timeouts timeout;
+    return &timeout;
+}
+
+
+/* Starts a new thread with priority "prio" that will begin its execution in 
the
+ * function "thread()". The "arg" argument will be passed as an argument to the
+ * thread() function. The id of the new thread is returned. Both the id and
+ * the priority are system dependent. */
+static struct thread *lwip_thread;
+sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, 
int stacksize, int prio)
+{
+    struct thread *t;
+    if (stacksize > STACK_SIZE) {
+       printk("Can't start lwIP thread: stack size %d is too large for our 
%d\n", stacksize, STACK_SIZE);
+       do_exit();
+    }
+    lwip_thread = t = create_thread(name, thread, arg);
+    return t;
+}
+
+/* This optional function does a "fast" critical region protection and returns
+ * the previous protection level. This function is only called during very 
short
+ * critical regions. An embedded system which supports ISR-based drivers might
+ * want to implement this function by disabling interrupts. Task-based systems
+ * might want to implement this by using a mutex or disabling tasking. This
+ * function should support recursive calls from the same task or interrupt. In
+ * other words, sys_arch_protect() could be called while already protected. In
+ * that case the return value indicates that it is already protected.
+ *
+ * sys_arch_protect() is only required if your port is supporting an operating
+ * system. */
+sys_prot_t sys_arch_protect(void)
+{
+    unsigned long flags;
+    local_irq_save(flags);
+    return flags;
+}
+
+/* This optional function does a "fast" set of critical region protection to 
the
+ * value specified by pval. See the documentation for sys_arch_protect() for
+ * more information. This function is only required if your port is supporting
+ * an operating system. */
+void sys_arch_unprotect(sys_prot_t pval)
+{
+    local_irq_restore(pval);
+}
+
+/* non-fatal, print a message. */
+void lwip_printk(char *fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    printk("lwIP: ");
+    print(0, fmt, args);
+    va_end(args);
+}
+
+/* fatal, print message and abandon execution. */
+void lwip_die(char *fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    printk("lwIP assertion failed: ");
+    print(0, fmt, args);
+    va_end(args);
+    printk("\n");
+    BUG();
+}
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/lwip-net.c Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,360 @@
+/* 
+ * lwip-net.c
+ *
+ * interface between lwIP's ethernet and Mini-os's netfront.
+ * For now, support only one network interface, as mini-os does.
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ * based on lwIP's ethernetif.c skeleton file, copyrights as below.
+ */
+
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without 
modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@xxxxxxx>
+ *
+ */
+
+#include <os.h>
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+
+#include <lwip/stats.h>
+#include <lwip/sys.h>
+#include <lwip/mem.h>
+#include <lwip/memp.h>
+#include <lwip/pbuf.h>
+#include <netif/etharp.h>
+#include <lwip/tcpip.h>
+#include <lwip/tcp.h>
+#include <lwip/netif.h>
+#include <lwip/dhcp.h>
+
+#include "netif/etharp.h"
+
+#include <netfront.h>
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+#define IF_IPADDR      0x00000000
+#define IF_NETMASK     0x00000000
+
+/* Only have one network interface at a time. */
+static struct netif *the_interface = NULL;
+
+static unsigned char rawmac[6];
+static struct netfront_dev *dev;
+
+/* Forward declarations. */
+static err_t netfront_output(struct netif *netif, struct pbuf *p,
+             struct ip_addr *ipaddr);
+
+/*
+ * low_level_output():
+ *
+ * Should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+#ifdef ETH_PAD_SIZE
+  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+  /* Send the data from the pbuf to the interface, one pbuf at a
+     time. The size of the data in each pbuf is kept in the ->len
+     variable. */
+  if (!p->next) {
+    /* Only one fragment, can send it directly */
+      netfront_xmit(dev, p->payload, p->len);
+  } else {
+    unsigned char data[p->tot_len], *cur;
+    struct pbuf *q;
+
+    for(q = p, cur = data; q != NULL; cur += q->len, q = q->next)
+      memcpy(cur, q->payload, q->len);
+    netfront_xmit(dev, data, p->tot_len);
+  }
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, ETH_PAD_SIZE);                        /* reclaim the padding 
word */
+#endif
+  
+  LINK_STATS_INC(link.xmit);
+
+  return ERR_OK;
+}
+
+
+
+/*
+ * netfront_output():
+ *
+ * This function is called by the TCP/IP stack when an IP packet
+ * should be sent. It calls the function called low_level_output() to
+ * do the actual transmission of the packet.
+ *
+ */
+
+static err_t
+netfront_output(struct netif *netif, struct pbuf *p,
+      struct ip_addr *ipaddr)
+{
+  
+ /* resolve hardware address, then send (or queue) packet */
+  return etharp_output(netif, p, ipaddr);
+ 
+}
+
+/*
+ * netfront_input():
+ *
+ * This function should be called when a packet is ready to be read
+ * from the interface. 
+ *
+ */
+
+static void
+netfront_input(struct netif *netif, unsigned char* data, int len)
+{
+  struct eth_hdr *ethhdr;
+  struct pbuf *p, *q;
+
+#if ETH_PAD_SIZE
+  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+  
+  /* move received packet into a new pbuf */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+  if (p == NULL) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    return;
+  }
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+  
+  /* We iterate over the pbuf chain until we have read the entire
+   * packet into the pbuf. */
+  for(q = p; q != NULL && len > 0; q = q->next) {
+    /* Read enough bytes to fill this pbuf in the chain. The
+     * available data in the pbuf is given by the q->len
+     * variable. */
+    memcpy(q->payload, data, len < q->len ? len : q->len);
+    data += q->len;
+    len -= q->len;
+  }
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+  LINK_STATS_INC(link.recv);
+
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = p->payload;
+
+  ethhdr = p->payload;
+    
+  switch (htons(ethhdr->type)) {
+  /* IP packet? */
+  case ETHTYPE_IP:
+#if 0
+/* CSi disabled ARP table update on ingress IP packets.
+   This seems to work but needs thorough testing. */
+    /* update ARP table */
+    etharp_ip_input(netif, p);
+#endif
+    /* skip Ethernet header */
+    pbuf_header(p, -(s16)sizeof(struct eth_hdr));
+    /* pass to network layer */
+    tcpip_input(p, netif);
+    break;
+      
+  case ETHTYPE_ARP:
+    /* pass p to ARP module  */
+    etharp_arp_input(netif, (struct eth_addr *) netif->hwaddr, p);
+    break;
+  default:
+    pbuf_free(p);
+    p = NULL;
+    break;
+  }
+}
+
+
+/* 
+ * netif_rx(): overrides the default netif_rx behaviour in the netfront driver.
+ * 
+ * Pull received packets into a pbuf queue for the low_level_input() 
+ * function to pass up to lwIP.
+ */
+
+void netif_rx(unsigned char* data, int len)
+{
+  if (the_interface != NULL) {
+    netfront_input(the_interface, data, len);
+    wake_up(&netfront_queue);
+  }
+  /* By returning, we ack the packet and relinquish the RX ring slot */
+}
+
+/*
+ * Set the IP, mask and gateway of the IF
+ */
+void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, 
struct ip_addr *gw)
+{
+  netif_set_ipaddr(the_interface, ipaddr);
+  netif_set_netmask(the_interface, netmask);
+  netif_set_gw(the_interface, gw);
+}
+
+
+static void
+arp_timer(void *arg)
+{
+  etharp_tmr();
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+}
+
+/*
+ * netif_netfront_init():
+ *
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ */
+
+err_t
+netif_netfront_init(struct netif *netif)
+{
+  unsigned char *mac = netif->state;
+
+#if LWIP_SNMP
+  /* ifType ethernetCsmacd(6) @see RFC1213 */
+  netif->link_type = 6;
+  /* your link speed here */
+  netif->link_speed = ;
+  netif->ts = 0;
+  netif->ifinoctets = 0;
+  netif->ifinucastpkts = 0;
+  netif->ifinnucastpkts = 0;
+  netif->ifindiscards = 0;
+  netif->ifoutoctets = 0;
+  netif->ifoutucastpkts = 0;
+  netif->ifoutnucastpkts = 0;
+  netif->ifoutdiscards = 0;
+#endif
+  
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  netif->output = netfront_output;
+  netif->linkoutput = low_level_output;
+  
+  the_interface = netif;
+  
+  /* set MAC hardware address */
+  netif->hwaddr_len = 6;
+  netif->hwaddr[0] = mac[0];
+  netif->hwaddr[1] = mac[1];
+  netif->hwaddr[2] = mac[2];
+  netif->hwaddr[3] = mac[3];
+  netif->hwaddr[4] = mac[4];
+  netif->hwaddr[5] = mac[5];
+
+  /* No interesting per-interface state */
+  netif->state = NULL;
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+  
+  /* broadcast capability */
+  netif->flags = NETIF_FLAG_BROADCAST;
+
+  etharp_init();
+
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+
+  return ERR_OK;
+}
+
+/*
+ * Thread run by netfront: bring up the IP address and fire lwIP timers.
+ */
+static __DECLARE_SEMAPHORE_GENERIC(tcpip_is_up, 0);
+static void tcpip_bringup_finished(void *p)
+{
+  tprintk("TCP/IP bringup ends.\n");
+  up(&tcpip_is_up);
+}
+
+/* 
+ * Utility function to bring the whole lot up.  Call this from app_main() 
+ * or similar -- it starts netfront and have lwIP start its thread,
+ * which calls back to tcpip_bringup_finished(), which 
+ * lets us know it's OK to continue.
+ */
+void start_networking(void)
+{
+  struct netif *netif;
+  struct ip_addr ipaddr = { htonl(IF_IPADDR) };
+  struct ip_addr netmask = { htonl(IF_NETMASK) };
+  struct ip_addr gw = { 0 };
+
+  tprintk("Waiting for network.\n");
+
+  dev = init_netfront(NULL, NULL, rawmac);
+  
+  tprintk("TCP/IP bringup begins.\n");
+  
+  netif = xmalloc(struct netif);
+  tcpip_init(tcpip_bringup_finished, netif);
+    
+  netif_add(netif, &ipaddr, &netmask, &gw, rawmac, 
+            netif_netfront_init, ip_input);
+  netif_set_default(netif);
+  netif_set_up(netif);
+
+  down(&tcpip_is_up);
+
+  tprintk("Network is ready.\n");
+}
only in patch2:
unchanged:
--- a/extras/mini-os/minios.mk  Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/minios.mk  Fri Jan 18 18:18:12 2008 +0000
@@ -6,7 +6,7 @@ debug = y
 
 # Define some default flags.
 # NB. '-Wcast-qual' is nasty, so I omitted it.
-DEF_CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
+DEF_CFLAGS += -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
 DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
 DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
 DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] minios: add lwIP 1.3.0 support, Samuel Thibault <=