debuggers.hg
changeset 16804:3c49ae5641b0
minios: add lwIP 1.3.0 support
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Jan 21 11:20:52 2008 +0000 (2008-01-21) |
parents | aca8d453da59 |
children | 60ee6f97cb19 |
files | extras/mini-os/Makefile extras/mini-os/daytime.c extras/mini-os/include/arch/cc.h extras/mini-os/include/arch/perf.h extras/mini-os/include/arch/sys_arch.h extras/mini-os/include/console.h extras/mini-os/include/lwipopts.h extras/mini-os/include/netfront.h extras/mini-os/lwip-arch.c extras/mini-os/lwip-net.c extras/mini-os/minios.mk |
line diff
1.1 --- a/extras/mini-os/Makefile Mon Jan 21 11:20:27 2008 +0000 1.2 +++ b/extras/mini-os/Makefile Mon Jan 21 11:20:52 2008 +0000 1.3 @@ -47,6 +47,13 @@ EXTRA_INC = 1.4 # This must be before include minios.mk! 1.5 include $(TARGET_ARCH_DIR)/arch.mk 1.6 1.7 +ifneq ($(LWIPDIR),) 1.8 +lwip=y 1.9 +DEF_CFLAGS += -DHAVE_LWIP 1.10 +DEF_CFLAGS += -I$(LWIPDIR)/src/include 1.11 +DEF_CFLAGS += -I$(LWIPDIR)/src/include/ipv4 1.12 +endif 1.13 + 1.14 # Include common mini-os makerules. 1.15 include minios.mk 1.16 1.17 @@ -90,6 +97,24 @@ links: $(ARCH_LINKS) 1.18 arch_lib: 1.19 $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1; 1.20 1.21 +ifeq ($(lwip),y) 1.22 +# lwIP library 1.23 +LWC := $(shell find $(LWIPDIR)/ -type f -name '*.c') 1.24 +LWC := $(filter-out %6.c %ip6_addr.c %ethernetif.c, $(LWC)) 1.25 +LWC += lwip-arch.c lwip-net.c 1.26 +LWO := $(patsubst %.c,%.o,$(LWC)) 1.27 + 1.28 +lwip.a: $(LWO) 1.29 + $(RM) $@ 1.30 + $(AR) cqs $@ $^ 1.31 + 1.32 +OBJS += lwip.a 1.33 + 1.34 +OBJS := $(filter-out $(LWO), $(OBJS)) 1.35 +else 1.36 +OBJS := $(filter-out daytime.o lwip%.o, $(OBJS)) 1.37 +endif 1.38 + 1.39 $(TARGET): links $(OBJS) arch_lib 1.40 $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o 1.41 $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o 1.42 @@ -107,6 +132,7 @@ clean: arch_clean 1.43 done 1.44 rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz 1.45 find . -type l | xargs rm -f 1.46 + $(RM) lwip.a $(LWO) 1.47 rm -f tags TAGS 1.48 1.49
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/extras/mini-os/daytime.c Mon Jan 21 11:20:52 2008 +0000 2.3 @@ -0,0 +1,64 @@ 2.4 +/* 2.5 + * daytime.c: a simple network service based on lwIP and mini-os 2.6 + * 2.7 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 2.8 + */ 2.9 + 2.10 +#include <os.h> 2.11 +#include <xmalloc.h> 2.12 +#include <console.h> 2.13 +#include <netfront.h> 2.14 +#include <lwip/api.h> 2.15 + 2.16 +static char message[29]; 2.17 + 2.18 +void run_server(void *p) 2.19 +{ 2.20 + struct ip_addr listenaddr = { 0 }; 2.21 + struct ip_addr ipaddr = { htonl(0x0a000001) }; 2.22 + struct ip_addr netmask = { htonl(0xff000000) }; 2.23 + struct ip_addr gw = { 0 }; 2.24 + struct netconn *listener; 2.25 + struct netconn *session; 2.26 + struct timeval tv; 2.27 + err_t rc; 2.28 + 2.29 + start_networking(); 2.30 + networking_set_addr(&ipaddr, &netmask, &gw); 2.31 + 2.32 + tprintk("Opening connection\n"); 2.33 + 2.34 + listener = netconn_new(NETCONN_TCP); 2.35 + tprintk("Connection at %p\n", listener); 2.36 + 2.37 + rc = netconn_bind(listener, &listenaddr, 13); 2.38 + if (rc != ERR_OK) { 2.39 + tprintk("Failed to bind connection: %i\n", rc); 2.40 + return; 2.41 + } 2.42 + 2.43 + rc = netconn_listen(listener); 2.44 + if (rc != ERR_OK) { 2.45 + tprintk("Failed to listen on connection: %i\n", rc); 2.46 + return; 2.47 + } 2.48 + 2.49 + while (1) { 2.50 + session = netconn_accept(listener); 2.51 + if (session == NULL) 2.52 + continue; 2.53 + 2.54 + gettimeofday(&tv, NULL); 2.55 + sprintf(message, "%20lu.%6.6lu\n", tv.tv_sec, tv.tv_usec); 2.56 + (void) netconn_write(session, message, strlen(message), NETCONN_COPY); 2.57 + (void) netconn_disconnect(session); 2.58 + (void) netconn_delete(session); 2.59 + } 2.60 +} 2.61 + 2.62 + 2.63 +int app_main(start_info_t *si) 2.64 +{ 2.65 + create_thread("server", run_server, NULL); 2.66 + return 0; 2.67 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/extras/mini-os/include/arch/cc.h Mon Jan 21 11:20:52 2008 +0000 3.3 @@ -0,0 +1,83 @@ 3.4 +/* 3.5 + * lwip/arch/cc.h 3.6 + * 3.7 + * Compiler-specific types and macros for lwIP running on mini-os 3.8 + * 3.9 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 3.10 + */ 3.11 + 3.12 +#ifndef __LWIP_ARCH_CC_H__ 3.13 +#define __LWIP_ARCH_CC_H__ 3.14 + 3.15 +/* Typedefs for the types used by lwip - */ 3.16 +#include <os.h> 3.17 +#include <types.h> 3.18 +#include <time.h> 3.19 +typedef u8 u8_t; 3.20 +typedef s8 s8_t; 3.21 +typedef u16 u16_t; 3.22 +typedef s16 s16_t; 3.23 +typedef u32 u32_t; 3.24 +typedef s32 s32_t; 3.25 +typedef u64 u64_t; 3.26 +typedef s64 s64_t; 3.27 +typedef uintptr_t mem_ptr_t; 3.28 + 3.29 +typedef u16 u_short; 3.30 + 3.31 +/* Compiler hints for packing lwip's structures - */ 3.32 +#define PACK_STRUCT_FIELD(_x) _x 3.33 +#define PACK_STRUCT_STRUCT __attribute__ ((packed)) 3.34 +#define PACK_STRUCT_BEGIN 3.35 +#define PACK_STRUCT_END 3.36 + 3.37 +/* Platform specific diagnostic output - */ 3.38 + 3.39 +extern void lwip_printk(char *fmt, ...); 3.40 +#define LWIP_PLATFORM_DIAG(_x) do { lwip_printk _x ; } while (0) 3.41 + 3.42 +extern void lwip_die(char *fmt, ...); 3.43 +#define LWIP_PLATFORM_ASSERT(_x) do { lwip_die(_x); } while(0) 3.44 + 3.45 +/* "lightweight" synchronization mechanisms - */ 3.46 +/* SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. */ 3.47 +/* SYS_ARCH_PROTECT(x) - enter protection mode. */ 3.48 +/* SYS_ARCH_UNPROTECT(x) - leave protection mode. */ 3.49 + 3.50 +/* If the compiler does not provide memset() this file must include a */ 3.51 +/* definition of it, or include a file which defines it. */ 3.52 +#include <lib.h> 3.53 + 3.54 +/* This file must either include a system-local <errno.h> which defines */ 3.55 +/* the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO */ 3.56 +/* to make lwip/arch.h define the codes which are used throughout. */ 3.57 +#include <errno.h> 3.58 + 3.59 +/* Not required by the docs, but needed for network-order calculations */ 3.60 +#include <endian.h> 3.61 + 3.62 +#include <inttypes.h> 3.63 +#define S16_F PRIi16 3.64 +#define U16_F PRIu16 3.65 +#define X16_F PRIx16 3.66 +#define S32_F PRIi32 3.67 +#define U32_F PRIu32 3.68 +#define X32_F PRIx32 3.69 + 3.70 +#if 0 3.71 +#ifndef DBG_ON 3.72 +#define DBG_ON LWIP_DBG_ON 3.73 +#endif 3.74 +#define LWIP_DEBUG DBG_ON 3.75 +//#define IP_DEBUG DBG_ON 3.76 +#define TCP_DEBUG DBG_ON 3.77 +#define TCP_INPUT_DEBUG DBG_ON 3.78 +#define TCP_QLEN_DEBUG DBG_ON 3.79 +#define TCPIP_DEBUG DBG_ON 3.80 +#define DBG_TYPES_ON DBG_ON 3.81 +#endif 3.82 + 3.83 +/* TODO: checksum doesn't work fine?! */ 3.84 +#define CHECKSUM_CHECK_TCP 0 3.85 + 3.86 +#endif /* __LWIP_ARCH_CC_H__ */
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/extras/mini-os/include/arch/perf.h Mon Jan 21 11:20:52 2008 +0000 4.3 @@ -0,0 +1,15 @@ 4.4 +/* 4.5 + * lwip/arch/perf.h 4.6 + * 4.7 + * Arch-specific performance measurement for lwIP running on mini-os 4.8 + * 4.9 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 4.10 + */ 4.11 + 4.12 +#ifndef __LWIP_ARCH_PERF_H__ 4.13 +#define __LWIP_ARCH_PERF_H__ 4.14 + 4.15 +#define PERF_START do { } while(0) 4.16 +#define PERF_STOP(_x) do { (void)(_x); } while (0) 4.17 + 4.18 +#endif /* __LWIP_ARCH_PERF_H__ */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/extras/mini-os/include/arch/sys_arch.h Mon Jan 21 11:20:52 2008 +0000 5.3 @@ -0,0 +1,35 @@ 5.4 +/* 5.5 + * lwip/arch/sys_arch.h 5.6 + * 5.7 + * Arch-specific semaphores and mailboxes for lwIP running on mini-os 5.8 + * 5.9 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 5.10 + */ 5.11 + 5.12 +#ifndef __LWIP_ARCH_SYS_ARCH_H__ 5.13 +#define __LWIP_ARCH_SYS_ARCH_H__ 5.14 + 5.15 +#include <os.h> 5.16 +#include <xmalloc.h> 5.17 +#include <semaphore.h> 5.18 + 5.19 +typedef struct semaphore *sys_sem_t; 5.20 +#define SYS_SEM_NULL ((sys_sem_t) NULL) 5.21 + 5.22 +struct mbox { 5.23 + int count; 5.24 + void **messages; 5.25 + struct semaphore read_sem; 5.26 + struct semaphore write_sem; 5.27 + int writer; 5.28 + int reader; 5.29 +}; 5.30 + 5.31 +typedef struct mbox *sys_mbox_t; 5.32 +#define SYS_MBOX_NULL ((sys_mbox_t) 0) 5.33 + 5.34 +typedef struct thread *sys_thread_t; 5.35 + 5.36 +typedef unsigned long sys_prot_t; 5.37 + 5.38 +#endif /*__LWIP_ARCH_SYS_ARCH_H__ */
6.1 --- a/extras/mini-os/include/console.h Mon Jan 21 11:20:27 2008 +0000 6.2 +++ b/extras/mini-os/include/console.h Mon Jan 21 11:20:52 2008 +0000 6.3 @@ -38,9 +38,12 @@ 6.4 6.5 #include<traps.h> 6.6 6.7 +void print(int direct, const char *fmt, va_list args); 6.8 void printk(const char *fmt, ...); 6.9 void xprintk(const char *fmt, ...); 6.10 6.11 +#define tprintk(_fmt, _args...) printk("[%s] " _fmt, current->name, ##_args) 6.12 + 6.13 void xencons_rx(char *buf, unsigned len, struct pt_regs *regs); 6.14 void xencons_tx(void); 6.15
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/extras/mini-os/include/lwipopts.h Mon Jan 21 11:20:52 2008 +0000 7.3 @@ -0,0 +1,22 @@ 7.4 +/* 7.5 + * lwipopts.h 7.6 + * 7.7 + * Configuration for lwIP running on mini-os 7.8 + * 7.9 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 7.10 + */ 7.11 + 7.12 +#ifndef __LWIP_LWIPOPTS_H__ 7.13 +#define __LWIP_LWIPOPTS_H__ 7.14 + 7.15 +#define SYS_LIGHTWEIGHT_PROT 1 7.16 +#define MEM_LIBC_MALLOC 1 7.17 +#define LWIP_TIMEVAL_PRIVATE 0 7.18 +#define LWIP_DHCP 1 7.19 +#define LWIP_COMPAT_SOCKETS 0 7.20 +#define LWIP_IGMP 1 7.21 +#define MEMP_NUM_SYS_TIMEOUT 10 7.22 +#define TCP_SND_BUF 3000 7.23 +#define TCP_MSS 1500 7.24 + 7.25 +#endif /* __LWIP_LWIPOPTS_H__ */
8.1 --- a/extras/mini-os/include/netfront.h Mon Jan 21 11:20:27 2008 +0000 8.2 +++ b/extras/mini-os/include/netfront.h Mon Jan 21 11:20:52 2008 +0000 8.3 @@ -1,7 +1,19 @@ 8.4 #include <wait.h> 8.5 +#ifdef HAVE_LWIP 8.6 +#include <lwip/netif.h> 8.7 +#endif 8.8 struct netfront_dev; 8.9 struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned char *data, int len), unsigned char rawmac[6]); 8.10 void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len); 8.11 void shutdown_netfront(struct netfront_dev *dev); 8.12 8.13 extern struct wait_queue_head netfront_queue; 8.14 + 8.15 +#ifdef HAVE_LWIP 8.16 +/* Call this to bring up the netfront interface and the lwIP stack. 8.17 + * N.B. _must_ be called from a thread; it's not safe to call this from 8.18 + * app_main(). */ 8.19 +void start_networking(void); 8.20 + 8.21 +void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw); 8.22 +#endif
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/extras/mini-os/lwip-arch.c Mon Jan 21 11:20:52 2008 +0000 9.3 @@ -0,0 +1,293 @@ 9.4 +/* 9.5 + * lwip-arch.c 9.6 + * 9.7 + * Arch-specific semaphores and mailboxes for lwIP running on mini-os 9.8 + * 9.9 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 9.10 + */ 9.11 + 9.12 +#include <os.h> 9.13 +#include <time.h> 9.14 +#include <console.h> 9.15 +#include <xmalloc.h> 9.16 +#include <lwip/sys.h> 9.17 +#include <stdarg.h> 9.18 + 9.19 +/* Is called to initialize the sys_arch layer */ 9.20 +void sys_init(void) 9.21 +{ 9.22 +} 9.23 + 9.24 +/* Creates and returns a new semaphore. The "count" argument specifies 9.25 + * the initial state of the semaphore. */ 9.26 +sys_sem_t sys_sem_new(u8_t count) 9.27 +{ 9.28 + struct semaphore *sem = xmalloc(struct semaphore); 9.29 + sem->count = count; 9.30 + init_waitqueue_head(&sem->wait); 9.31 + return sem; 9.32 +} 9.33 + 9.34 +/* Deallocates a semaphore. */ 9.35 +void sys_sem_free(sys_sem_t sem) 9.36 +{ 9.37 + xfree(sem); 9.38 +} 9.39 + 9.40 +/* Signals a semaphore. */ 9.41 +void sys_sem_signal(sys_sem_t sem) 9.42 +{ 9.43 + up(sem); 9.44 +} 9.45 + 9.46 +/* Blocks the thread while waiting for the semaphore to be 9.47 + * signaled. If the "timeout" argument is non-zero, the thread should 9.48 + * only be blocked for the specified time (measured in 9.49 + * milliseconds). 9.50 + * 9.51 + * If the timeout argument is non-zero, the return value is the number of 9.52 + * milliseconds spent waiting for the semaphore to be signaled. If the 9.53 + * semaphore wasn't signaled within the specified time, the return value is 9.54 + * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore 9.55 + * (i.e., it was already signaled), the function may return zero. */ 9.56 +u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) 9.57 +{ 9.58 + /* Slightly more complicated than the normal minios semaphore: 9.59 + * need to wake on timeout *or* signal */ 9.60 + sys_prot_t prot; 9.61 + s64_t then = NOW(); 9.62 + s64_t deadline; 9.63 + 9.64 + if (timeout == 0) 9.65 + deadline = 0; 9.66 + else 9.67 + deadline = then + MILLISECS(timeout); 9.68 + 9.69 + while(1) { 9.70 + wait_event_deadline(sem->wait, (sem->count > 0), deadline); 9.71 + 9.72 + prot = sys_arch_protect(); 9.73 + /* Atomically check that we can proceed */ 9.74 + if (sem->count > 0 || (deadline && NOW() >= deadline)) 9.75 + break; 9.76 + sys_arch_unprotect(prot); 9.77 + } 9.78 + 9.79 + if (sem->count > 0) { 9.80 + sem->count--; 9.81 + sys_arch_unprotect(prot); 9.82 + return NSEC_TO_MSEC(NOW() - then); 9.83 + } 9.84 + 9.85 + sys_arch_unprotect(prot); 9.86 + return SYS_ARCH_TIMEOUT; 9.87 +} 9.88 + 9.89 +/* Creates an empty mailbox. */ 9.90 +sys_mbox_t sys_mbox_new(int size) 9.91 +{ 9.92 + struct mbox *mbox = xmalloc(struct mbox); 9.93 + if (!size) 9.94 + size = 32; 9.95 + else if (size == 1) 9.96 + size = 2; 9.97 + mbox->count = size; 9.98 + mbox->messages = xmalloc_array(void*, size); 9.99 + init_SEMAPHORE(&mbox->read_sem, 0); 9.100 + mbox->reader = 0; 9.101 + init_SEMAPHORE(&mbox->write_sem, size); 9.102 + mbox->writer = 0; 9.103 + return mbox; 9.104 +} 9.105 + 9.106 +/* Deallocates a mailbox. If there are messages still present in the 9.107 + * mailbox when the mailbox is deallocated, it is an indication of a 9.108 + * programming error in lwIP and the developer should be notified. */ 9.109 +void sys_mbox_free(sys_mbox_t mbox) 9.110 +{ 9.111 + ASSERT(mbox->reader == mbox->writer); 9.112 + xfree(mbox->messages); 9.113 + xfree(mbox); 9.114 +} 9.115 + 9.116 +/* Posts the "msg" to the mailbox, internal version that actually does the 9.117 + * post. */ 9.118 +static void do_mbox_post(sys_mbox_t mbox, void *msg) 9.119 +{ 9.120 + /* The caller got a semaphore token, so we are now allowed to increment 9.121 + * writer, but we still need to prevent concurrency between writers 9.122 + * (interrupt handler vs main) */ 9.123 + sys_prot_t prot = sys_arch_protect(); 9.124 + mbox->messages[mbox->writer] = msg; 9.125 + mbox->writer = (mbox->writer + 1) % mbox->count; 9.126 + ASSERT(mbox->reader != mbox->writer); 9.127 + sys_arch_unprotect(prot); 9.128 + up(&mbox->read_sem); 9.129 +} 9.130 + 9.131 +/* Posts the "msg" to the mailbox. */ 9.132 +void sys_mbox_post(sys_mbox_t mbox, void *msg) 9.133 +{ 9.134 + if (mbox == SYS_MBOX_NULL) 9.135 + return; 9.136 + down(&mbox->write_sem); 9.137 + do_mbox_post(mbox, msg); 9.138 +} 9.139 + 9.140 +/* Try to post the "msg" to the mailbox. */ 9.141 +err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) 9.142 +{ 9.143 + if (mbox == SYS_MBOX_NULL) 9.144 + return ERR_BUF; 9.145 + if (!trydown(&mbox->write_sem)) 9.146 + return ERR_MEM; 9.147 + do_mbox_post(mbox, msg); 9.148 + return ERR_OK; 9.149 +} 9.150 + 9.151 +/* 9.152 + * Fetch a message from a mailbox. Internal version that actually does the 9.153 + * fetch. 9.154 + */ 9.155 +static void do_mbox_fetch(sys_mbox_t mbox, void **msg) 9.156 +{ 9.157 + sys_prot_t prot; 9.158 + /* The caller got a semaphore token, so we are now allowed to increment 9.159 + * reader, but we may still need to prevent concurrency between readers. 9.160 + * FIXME: can there be concurrent readers? */ 9.161 + prot = sys_arch_protect(); 9.162 + ASSERT(mbox->reader != mbox->writer); 9.163 + if (msg != NULL) 9.164 + *msg = mbox->messages[mbox->reader]; 9.165 + mbox->reader = (mbox->reader + 1) % mbox->count; 9.166 + sys_arch_unprotect(prot); 9.167 + up(&mbox->write_sem); 9.168 +} 9.169 + 9.170 +/* Blocks the thread until a message arrives in the mailbox, but does 9.171 + * not block the thread longer than "timeout" milliseconds (similar to 9.172 + * the sys_arch_sem_wait() function). The "msg" argument is a result 9.173 + * parameter that is set by the function (i.e., by doing "*msg = 9.174 + * ptr"). The "msg" parameter maybe NULL to indicate that the message 9.175 + * should be dropped. 9.176 + * 9.177 + * The return values are the same as for the sys_arch_sem_wait() function: 9.178 + * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a 9.179 + * timeout. */ 9.180 +u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) 9.181 +{ 9.182 + u32 rv; 9.183 + if (mbox == SYS_MBOX_NULL) 9.184 + return SYS_ARCH_TIMEOUT; 9.185 + 9.186 + rv = sys_arch_sem_wait(&mbox->read_sem, timeout); 9.187 + if ( rv == SYS_ARCH_TIMEOUT ) 9.188 + return rv; 9.189 + 9.190 + do_mbox_fetch(mbox, msg); 9.191 + return 0; 9.192 +} 9.193 + 9.194 +/* This is similar to sys_arch_mbox_fetch, however if a message is not 9.195 + * present in the mailbox, it immediately returns with the code 9.196 + * SYS_MBOX_EMPTY. On success 0 is returned. 9.197 + * 9.198 + * To allow for efficient implementations, this can be defined as a 9.199 + * function-like macro in sys_arch.h instead of a normal function. For 9.200 + * example, a naive implementation could be: 9.201 + * #define sys_arch_mbox_tryfetch(mbox,msg) \ 9.202 + * sys_arch_mbox_fetch(mbox,msg,1) 9.203 + * although this would introduce unnecessary delays. */ 9.204 + 9.205 +u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) { 9.206 + if (mbox == SYS_MBOX_NULL) 9.207 + return SYS_ARCH_TIMEOUT; 9.208 + 9.209 + if (!trydown(&mbox->read_sem)) 9.210 + return SYS_MBOX_EMPTY; 9.211 + 9.212 + do_mbox_fetch(mbox, msg); 9.213 + return 0; 9.214 +} 9.215 + 9.216 + 9.217 +/* Returns a pointer to the per-thread sys_timeouts structure. In lwIP, 9.218 + * each thread has a list of timeouts which is repressented as a linked 9.219 + * list of sys_timeout structures. The sys_timeouts structure holds a 9.220 + * pointer to a linked list of timeouts. This function is called by 9.221 + * the lwIP timeout scheduler and must not return a NULL value. 9.222 + * 9.223 + * In a single threadd sys_arch implementation, this function will 9.224 + * simply return a pointer to a global sys_timeouts variable stored in 9.225 + * the sys_arch module. */ 9.226 +struct sys_timeouts *sys_arch_timeouts(void) 9.227 +{ 9.228 + static struct sys_timeouts timeout; 9.229 + return &timeout; 9.230 +} 9.231 + 9.232 + 9.233 +/* Starts a new thread with priority "prio" that will begin its execution in the 9.234 + * function "thread()". The "arg" argument will be passed as an argument to the 9.235 + * thread() function. The id of the new thread is returned. Both the id and 9.236 + * the priority are system dependent. */ 9.237 +static struct thread *lwip_thread; 9.238 +sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) 9.239 +{ 9.240 + struct thread *t; 9.241 + if (stacksize > STACK_SIZE) { 9.242 + printk("Can't start lwIP thread: stack size %d is too large for our %d\n", stacksize, STACK_SIZE); 9.243 + do_exit(); 9.244 + } 9.245 + lwip_thread = t = create_thread(name, thread, arg); 9.246 + return t; 9.247 +} 9.248 + 9.249 +/* This optional function does a "fast" critical region protection and returns 9.250 + * the previous protection level. This function is only called during very short 9.251 + * critical regions. An embedded system which supports ISR-based drivers might 9.252 + * want to implement this function by disabling interrupts. Task-based systems 9.253 + * might want to implement this by using a mutex or disabling tasking. This 9.254 + * function should support recursive calls from the same task or interrupt. In 9.255 + * other words, sys_arch_protect() could be called while already protected. In 9.256 + * that case the return value indicates that it is already protected. 9.257 + * 9.258 + * sys_arch_protect() is only required if your port is supporting an operating 9.259 + * system. */ 9.260 +sys_prot_t sys_arch_protect(void) 9.261 +{ 9.262 + unsigned long flags; 9.263 + local_irq_save(flags); 9.264 + return flags; 9.265 +} 9.266 + 9.267 +/* This optional function does a "fast" set of critical region protection to the 9.268 + * value specified by pval. See the documentation for sys_arch_protect() for 9.269 + * more information. This function is only required if your port is supporting 9.270 + * an operating system. */ 9.271 +void sys_arch_unprotect(sys_prot_t pval) 9.272 +{ 9.273 + local_irq_restore(pval); 9.274 +} 9.275 + 9.276 +/* non-fatal, print a message. */ 9.277 +void lwip_printk(char *fmt, ...) 9.278 +{ 9.279 + va_list args; 9.280 + va_start(args, fmt); 9.281 + printk("lwIP: "); 9.282 + print(0, fmt, args); 9.283 + va_end(args); 9.284 +} 9.285 + 9.286 +/* fatal, print message and abandon execution. */ 9.287 +void lwip_die(char *fmt, ...) 9.288 +{ 9.289 + va_list args; 9.290 + va_start(args, fmt); 9.291 + printk("lwIP assertion failed: "); 9.292 + print(0, fmt, args); 9.293 + va_end(args); 9.294 + printk("\n"); 9.295 + BUG(); 9.296 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/extras/mini-os/lwip-net.c Mon Jan 21 11:20:52 2008 +0000 10.3 @@ -0,0 +1,360 @@ 10.4 +/* 10.5 + * lwip-net.c 10.6 + * 10.7 + * interface between lwIP's ethernet and Mini-os's netfront. 10.8 + * For now, support only one network interface, as mini-os does. 10.9 + * 10.10 + * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007 10.11 + * based on lwIP's ethernetif.c skeleton file, copyrights as below. 10.12 + */ 10.13 + 10.14 + 10.15 +/* 10.16 + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 10.17 + * All rights reserved. 10.18 + * 10.19 + * Redistribution and use in source and binary forms, with or without modification, 10.20 + * are permitted provided that the following conditions are met: 10.21 + * 10.22 + * 1. Redistributions of source code must retain the above copyright notice, 10.23 + * this list of conditions and the following disclaimer. 10.24 + * 2. Redistributions in binary form must reproduce the above copyright notice, 10.25 + * this list of conditions and the following disclaimer in the documentation 10.26 + * and/or other materials provided with the distribution. 10.27 + * 3. The name of the author may not be used to endorse or promote products 10.28 + * derived from this software without specific prior written permission. 10.29 + * 10.30 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 10.31 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 10.32 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 10.33 + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 10.34 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 10.35 + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 10.36 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 10.37 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 10.38 + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 10.39 + * OF SUCH DAMAGE. 10.40 + * 10.41 + * This file is part of the lwIP TCP/IP stack. 10.42 + * 10.43 + * Author: Adam Dunkels <adam@sics.se> 10.44 + * 10.45 + */ 10.46 + 10.47 +#include <os.h> 10.48 + 10.49 +#include "lwip/opt.h" 10.50 +#include "lwip/def.h" 10.51 +#include "lwip/mem.h" 10.52 +#include "lwip/pbuf.h" 10.53 +#include "lwip/sys.h" 10.54 + 10.55 +#include <lwip/stats.h> 10.56 +#include <lwip/sys.h> 10.57 +#include <lwip/mem.h> 10.58 +#include <lwip/memp.h> 10.59 +#include <lwip/pbuf.h> 10.60 +#include <netif/etharp.h> 10.61 +#include <lwip/tcpip.h> 10.62 +#include <lwip/tcp.h> 10.63 +#include <lwip/netif.h> 10.64 +#include <lwip/dhcp.h> 10.65 + 10.66 +#include "netif/etharp.h" 10.67 + 10.68 +#include <netfront.h> 10.69 + 10.70 +/* Define those to better describe your network interface. */ 10.71 +#define IFNAME0 'e' 10.72 +#define IFNAME1 'n' 10.73 + 10.74 +#define IF_IPADDR 0x00000000 10.75 +#define IF_NETMASK 0x00000000 10.76 + 10.77 +/* Only have one network interface at a time. */ 10.78 +static struct netif *the_interface = NULL; 10.79 + 10.80 +static unsigned char rawmac[6]; 10.81 +static struct netfront_dev *dev; 10.82 + 10.83 +/* Forward declarations. */ 10.84 +static err_t netfront_output(struct netif *netif, struct pbuf *p, 10.85 + struct ip_addr *ipaddr); 10.86 + 10.87 +/* 10.88 + * low_level_output(): 10.89 + * 10.90 + * Should do the actual transmission of the packet. The packet is 10.91 + * contained in the pbuf that is passed to the function. This pbuf 10.92 + * might be chained. 10.93 + * 10.94 + */ 10.95 + 10.96 +static err_t 10.97 +low_level_output(struct netif *netif, struct pbuf *p) 10.98 +{ 10.99 +#ifdef ETH_PAD_SIZE 10.100 + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ 10.101 +#endif 10.102 + 10.103 + /* Send the data from the pbuf to the interface, one pbuf at a 10.104 + time. The size of the data in each pbuf is kept in the ->len 10.105 + variable. */ 10.106 + if (!p->next) { 10.107 + /* Only one fragment, can send it directly */ 10.108 + netfront_xmit(dev, p->payload, p->len); 10.109 + } else { 10.110 + unsigned char data[p->tot_len], *cur; 10.111 + struct pbuf *q; 10.112 + 10.113 + for(q = p, cur = data; q != NULL; cur += q->len, q = q->next) 10.114 + memcpy(cur, q->payload, q->len); 10.115 + netfront_xmit(dev, data, p->tot_len); 10.116 + } 10.117 + 10.118 +#if ETH_PAD_SIZE 10.119 + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ 10.120 +#endif 10.121 + 10.122 + LINK_STATS_INC(link.xmit); 10.123 + 10.124 + return ERR_OK; 10.125 +} 10.126 + 10.127 + 10.128 + 10.129 +/* 10.130 + * netfront_output(): 10.131 + * 10.132 + * This function is called by the TCP/IP stack when an IP packet 10.133 + * should be sent. It calls the function called low_level_output() to 10.134 + * do the actual transmission of the packet. 10.135 + * 10.136 + */ 10.137 + 10.138 +static err_t 10.139 +netfront_output(struct netif *netif, struct pbuf *p, 10.140 + struct ip_addr *ipaddr) 10.141 +{ 10.142 + 10.143 + /* resolve hardware address, then send (or queue) packet */ 10.144 + return etharp_output(netif, p, ipaddr); 10.145 + 10.146 +} 10.147 + 10.148 +/* 10.149 + * netfront_input(): 10.150 + * 10.151 + * This function should be called when a packet is ready to be read 10.152 + * from the interface. 10.153 + * 10.154 + */ 10.155 + 10.156 +static void 10.157 +netfront_input(struct netif *netif, unsigned char* data, int len) 10.158 +{ 10.159 + struct eth_hdr *ethhdr; 10.160 + struct pbuf *p, *q; 10.161 + 10.162 +#if ETH_PAD_SIZE 10.163 + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ 10.164 +#endif 10.165 + 10.166 + /* move received packet into a new pbuf */ 10.167 + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); 10.168 + if (p == NULL) { 10.169 + LINK_STATS_INC(link.memerr); 10.170 + LINK_STATS_INC(link.drop); 10.171 + return; 10.172 + } 10.173 + 10.174 +#if ETH_PAD_SIZE 10.175 + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ 10.176 +#endif 10.177 + 10.178 + /* We iterate over the pbuf chain until we have read the entire 10.179 + * packet into the pbuf. */ 10.180 + for(q = p; q != NULL && len > 0; q = q->next) { 10.181 + /* Read enough bytes to fill this pbuf in the chain. The 10.182 + * available data in the pbuf is given by the q->len 10.183 + * variable. */ 10.184 + memcpy(q->payload, data, len < q->len ? len : q->len); 10.185 + data += q->len; 10.186 + len -= q->len; 10.187 + } 10.188 + 10.189 +#if ETH_PAD_SIZE 10.190 + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ 10.191 +#endif 10.192 + 10.193 + LINK_STATS_INC(link.recv); 10.194 + 10.195 + /* points to packet payload, which starts with an Ethernet header */ 10.196 + ethhdr = p->payload; 10.197 + 10.198 + ethhdr = p->payload; 10.199 + 10.200 + switch (htons(ethhdr->type)) { 10.201 + /* IP packet? */ 10.202 + case ETHTYPE_IP: 10.203 +#if 0 10.204 +/* CSi disabled ARP table update on ingress IP packets. 10.205 + This seems to work but needs thorough testing. */ 10.206 + /* update ARP table */ 10.207 + etharp_ip_input(netif, p); 10.208 +#endif 10.209 + /* skip Ethernet header */ 10.210 + pbuf_header(p, -(s16)sizeof(struct eth_hdr)); 10.211 + /* pass to network layer */ 10.212 + tcpip_input(p, netif); 10.213 + break; 10.214 + 10.215 + case ETHTYPE_ARP: 10.216 + /* pass p to ARP module */ 10.217 + etharp_arp_input(netif, (struct eth_addr *) netif->hwaddr, p); 10.218 + break; 10.219 + default: 10.220 + pbuf_free(p); 10.221 + p = NULL; 10.222 + break; 10.223 + } 10.224 +} 10.225 + 10.226 + 10.227 +/* 10.228 + * netif_rx(): overrides the default netif_rx behaviour in the netfront driver. 10.229 + * 10.230 + * Pull received packets into a pbuf queue for the low_level_input() 10.231 + * function to pass up to lwIP. 10.232 + */ 10.233 + 10.234 +void netif_rx(unsigned char* data, int len) 10.235 +{ 10.236 + if (the_interface != NULL) { 10.237 + netfront_input(the_interface, data, len); 10.238 + wake_up(&netfront_queue); 10.239 + } 10.240 + /* By returning, we ack the packet and relinquish the RX ring slot */ 10.241 +} 10.242 + 10.243 +/* 10.244 + * Set the IP, mask and gateway of the IF 10.245 + */ 10.246 +void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw) 10.247 +{ 10.248 + netif_set_ipaddr(the_interface, ipaddr); 10.249 + netif_set_netmask(the_interface, netmask); 10.250 + netif_set_gw(the_interface, gw); 10.251 +} 10.252 + 10.253 + 10.254 +static void 10.255 +arp_timer(void *arg) 10.256 +{ 10.257 + etharp_tmr(); 10.258 + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); 10.259 +} 10.260 + 10.261 +/* 10.262 + * netif_netfront_init(): 10.263 + * 10.264 + * Should be called at the beginning of the program to set up the 10.265 + * network interface. It calls the function low_level_init() to do the 10.266 + * actual setup of the hardware. 10.267 + * 10.268 + */ 10.269 + 10.270 +err_t 10.271 +netif_netfront_init(struct netif *netif) 10.272 +{ 10.273 + unsigned char *mac = netif->state; 10.274 + 10.275 +#if LWIP_SNMP 10.276 + /* ifType ethernetCsmacd(6) @see RFC1213 */ 10.277 + netif->link_type = 6; 10.278 + /* your link speed here */ 10.279 + netif->link_speed = ; 10.280 + netif->ts = 0; 10.281 + netif->ifinoctets = 0; 10.282 + netif->ifinucastpkts = 0; 10.283 + netif->ifinnucastpkts = 0; 10.284 + netif->ifindiscards = 0; 10.285 + netif->ifoutoctets = 0; 10.286 + netif->ifoutucastpkts = 0; 10.287 + netif->ifoutnucastpkts = 0; 10.288 + netif->ifoutdiscards = 0; 10.289 +#endif 10.290 + 10.291 + netif->name[0] = IFNAME0; 10.292 + netif->name[1] = IFNAME1; 10.293 + netif->output = netfront_output; 10.294 + netif->linkoutput = low_level_output; 10.295 + 10.296 + the_interface = netif; 10.297 + 10.298 + /* set MAC hardware address */ 10.299 + netif->hwaddr_len = 6; 10.300 + netif->hwaddr[0] = mac[0]; 10.301 + netif->hwaddr[1] = mac[1]; 10.302 + netif->hwaddr[2] = mac[2]; 10.303 + netif->hwaddr[3] = mac[3]; 10.304 + netif->hwaddr[4] = mac[4]; 10.305 + netif->hwaddr[5] = mac[5]; 10.306 + 10.307 + /* No interesting per-interface state */ 10.308 + netif->state = NULL; 10.309 + 10.310 + /* maximum transfer unit */ 10.311 + netif->mtu = 1500; 10.312 + 10.313 + /* broadcast capability */ 10.314 + netif->flags = NETIF_FLAG_BROADCAST; 10.315 + 10.316 + etharp_init(); 10.317 + 10.318 + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); 10.319 + 10.320 + return ERR_OK; 10.321 +} 10.322 + 10.323 +/* 10.324 + * Thread run by netfront: bring up the IP address and fire lwIP timers. 10.325 + */ 10.326 +static __DECLARE_SEMAPHORE_GENERIC(tcpip_is_up, 0); 10.327 +static void tcpip_bringup_finished(void *p) 10.328 +{ 10.329 + tprintk("TCP/IP bringup ends.\n"); 10.330 + up(&tcpip_is_up); 10.331 +} 10.332 + 10.333 +/* 10.334 + * Utility function to bring the whole lot up. Call this from app_main() 10.335 + * or similar -- it starts netfront and have lwIP start its thread, 10.336 + * which calls back to tcpip_bringup_finished(), which 10.337 + * lets us know it's OK to continue. 10.338 + */ 10.339 +void start_networking(void) 10.340 +{ 10.341 + struct netif *netif; 10.342 + struct ip_addr ipaddr = { htonl(IF_IPADDR) }; 10.343 + struct ip_addr netmask = { htonl(IF_NETMASK) }; 10.344 + struct ip_addr gw = { 0 }; 10.345 + 10.346 + tprintk("Waiting for network.\n"); 10.347 + 10.348 + dev = init_netfront(NULL, NULL, rawmac); 10.349 + 10.350 + tprintk("TCP/IP bringup begins.\n"); 10.351 + 10.352 + netif = xmalloc(struct netif); 10.353 + tcpip_init(tcpip_bringup_finished, netif); 10.354 + 10.355 + netif_add(netif, &ipaddr, &netmask, &gw, rawmac, 10.356 + netif_netfront_init, ip_input); 10.357 + netif_set_default(netif); 10.358 + netif_set_up(netif); 10.359 + 10.360 + down(&tcpip_is_up); 10.361 + 10.362 + tprintk("Network is ready.\n"); 10.363 +}
11.1 --- a/extras/mini-os/minios.mk Mon Jan 21 11:20:27 2008 +0000 11.2 +++ b/extras/mini-os/minios.mk Mon Jan 21 11:20:52 2008 +0000 11.3 @@ -6,7 +6,7 @@ debug = y 11.4 11.5 # Define some default flags. 11.6 # NB. '-Wcast-qual' is nasty, so I omitted it. 11.7 -DEF_CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format 11.8 +DEF_CFLAGS += -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format 11.9 DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,) 11.10 DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline 11.11 DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)