From: Lei Xia Date: Mon, 6 Oct 2008 17:11:11 +0000 (-0500) Subject: Merge branch 'lwip_dev' into devel X-Git-Tag: 1.0~3^2~11 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a1073097716c800734e117267ce7aa92aa0d9a17;hp=819c31aa7157ed1e3e17b9f05bf74de38179233d Merge branch 'lwip_dev' into devel Conflicts: palacios/build/Makefile palacios/include/geekos/socket.h palacios/src/geekos/net.c --- diff --git a/geekos/build/Makefile b/geekos/build/Makefile index 29c05b9..d41af2e 100644 --- a/geekos/build/Makefile +++ b/geekos/build/Makefile @@ -56,7 +56,15 @@ VPATH := $(PROJECT_ROOT)/src # TCPSTACK=UIP +# +#TCPSTACK, uIP is used currently +# +UIP=OFF +# +#LWIP, ON -- used, OFF -- not used +# +LWIP=ON # @@ -142,13 +150,26 @@ V3_LIBS := ./palacios/libxed.a ./palacios/libv3vee.a ./palacios/libxed.a ./palac -TCPSTACK_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c -TCPSTACK_C_OBJS := $(TCPSTACK_C_SRCS:%.c=net/%.o) -TCPSTACK_OBJS := $(TCPSTACK_C_OBJS) +ifeq ($(UIP),ON) + UIP_C_SRCS := psock.c timer.c uip_arp.c uip.c uip-fw.c uiplib.c uip-neighbor.c uip-split.c resolv.c + UIP_C_OBJS := $(UIP_C_SRCS:%.c=net/%.o) +else + UIP_C_SRCS := + UIP_C_OBJS := +endif + +ifeq ($(LWIP),ON) + LWIP_OBJS := lwip/*.o + CC_LWIP_OPTS := -I$(PROJECT_ROOT)/include/lwip -I$(PROJECT_ROOT)/include/lwip/ipv4 -I$(PROJECT_ROOT)/include/libc -DLWIP_DEBUG +else + LWIP_OBJS := + CC_LWIP_OPTS := +endif +TCPSTACK_OBJS := $(UIP_C_OBJS) $(LWIP_OBJS) # ---------------------------------------------------------------------- @@ -241,7 +262,7 @@ OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment # Compilation of kernel C source files geekos/%.o : geekos/%.c - $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $< -o geekos/$*.o + $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_KERNEL_OPTS) $(CC_LWIP_OPTS) $< -o geekos/$*.o # Compilation of kernel assembly source files diff --git a/geekos/include/geekos/int.h b/geekos/include/geekos/int.h index a80d142..0097777 100644 --- a/geekos/include/geekos/int.h +++ b/geekos/include/geekos/int.h @@ -20,6 +20,11 @@ #include #include + +// to stop the compilation warnings +extern void Print(const char* fmt, ...); +extern void Set_Current_Attr(uchar_t attrib); + /* * This struct reflects the contents of the stack when * a C interrupt handler function is called. diff --git a/geekos/include/geekos/ne2k.h b/geekos/include/geekos/ne2k.h index e691939..4b9e184 100644 --- a/geekos/include/geekos/ne2k.h +++ b/geekos/include/geekos/ne2k.h @@ -81,6 +81,16 @@ #define NE2K_IRQ 11 /* Interrupt channel */ + +/* Physical Address of Network Card */ +#define PHY_ADDR1 0x52 +#define PHY_ADDR2 0x54 +#define PHY_ADDR3 0x00 +#define PHY_ADDR4 0x12 +#define PHY_ADDR5 0x34 +#define PHY_ADDR6 0x58 + + struct NE2K_REGS { uchar_t cr; uchar_t isr; diff --git a/geekos/include/geekos/timer.h b/geekos/include/geekos/timer.h index f6add16..f5ae13f 100644 --- a/geekos/include/geekos/timer.h +++ b/geekos/include/geekos/timer.h @@ -14,7 +14,7 @@ #define TIMER_IRQ 0 -extern volatile ulong_t g_numTicks; +extern volatile unsigned long g_numTicks; typedef void (*timerCallback)(int, void*); @@ -44,4 +44,6 @@ int Cancel_Timer(int id); void Micro_Delay(int us); +unsigned long clock_time(void); //return elipsed millisecs + #endif /* GEEKOS_TIMER_H */ diff --git a/geekos/include/libc/string.h b/geekos/include/libc/string.h index 5a81cb8..5bf42df 100644 --- a/geekos/include/libc/string.h +++ b/geekos/include/libc/string.h @@ -44,7 +44,8 @@ char *strrchr(const char *s, int c); char *strpbrk(const char *s, const char *accept); char *strncat(char *s1, const char *s2, size_t limit); int fprintf(FILE *file, char *fmt, ...); -//int fflush(FILE *file); +int fflush(FILE *file); +int printf(char *fmt, ...); diff --git a/geekos/include/lwip/apps/ping.h b/geekos/include/lwip/apps/ping.h new file mode 100644 index 0000000..6093563 --- /dev/null +++ b/geekos/include/lwip/apps/ping.h @@ -0,0 +1,6 @@ +#ifndef __PING_H__ +#define __PING_H__ + +void ping_init(void); + +#endif /* __PING_H__ */ diff --git a/geekos/include/lwip/arch/cc.h b/geekos/include/lwip/arch/cc.h index 73eb7d3..75b51bd 100644 --- a/geekos/include/lwip/arch/cc.h +++ b/geekos/include/lwip/arch/cc.h @@ -35,11 +35,7 @@ /* Include some files for defining library routines */ #include - -extern int fflush(FILE *file); -extern int printf(char *fmt, ...); -extern void abort (void); - +#include /* Define platform endianness */ #ifndef BYTE_ORDER @@ -74,7 +70,7 @@ typedef u32_t mem_ptr_t; //#include //#include /* Plaform specific diagnostic output */ -#define LWIP_PLATFORM_DIAG(x) //do {printf x;} while(0) +#define LWIP_PLATFORM_DIAG(x) do {PrintBoth x;} while(0)//do {printf x;} while(0) #define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \ x, __LINE__, __FILE__); fflush(NULL); abort();} while(0) diff --git a/geekos/include/lwip/arch/perf.h b/geekos/include/lwip/arch/perf.h index 1daebac..ea09f70 100644 --- a/geekos/include/lwip/arch/perf.h +++ b/geekos/include/lwip/arch/perf.h @@ -52,6 +52,8 @@ #define PERF_STOP(x) /* null definition */ #endif /* PERF */ +#if 0 + void perf_print(unsigned long c1l, unsigned long c1h, unsigned long c2l, unsigned long c2h, char *key); @@ -60,4 +62,6 @@ void perf_print_times(struct tms *start, struct tms *end, char *key); void perf_init(char *fname); +#endif + #endif /* __ARCH_PERF_H__ */ diff --git a/geekos/include/lwip/ipv4/lwip/ip_addr.h b/geekos/include/lwip/ipv4/lwip/ip_addr.h index 7f24336..9c184af 100644 --- a/geekos/include/lwip/ipv4/lwip/ip_addr.h +++ b/geekos/include/lwip/ipv4/lwip/ip_addr.h @@ -32,7 +32,7 @@ #ifndef __LWIP_IP_ADDR_H__ #define __LWIP_IP_ADDR_H__ -#include "lwip/opt.h" +#include #ifdef __cplusplus extern "C" { diff --git a/geekos/include/lwip/lwip/opt.h b/geekos/include/lwip/lwip/opt.h index c980e44..8128d34 100644 --- a/geekos/include/lwip/lwip/opt.h +++ b/geekos/include/lwip/lwip/opt.h @@ -42,7 +42,7 @@ * Include user defined options first. Anything not defined in these files * will be set to standard values. Override anything you dont like! */ -#include "lwipopts.h" +#include #include "lwip/debug.h" /* @@ -640,7 +640,7 @@ * TCP_WND: The size of a TCP window. */ #ifndef TCP_WND -#define TCP_WND 2048 +#define TCP_WND 1024 //2048 #endif /** @@ -785,7 +785,7 @@ * LWIP_NETIF_API==1: Support netif api (in netifapi.c) */ #ifndef LWIP_NETIF_API -#define LWIP_NETIF_API 0 +#define LWIP_NETIF_API 1 #endif /** diff --git a/geekos/include/lwip/netif/ne2kif.h b/geekos/include/lwip/netif/ne2kif.h new file mode 100644 index 0000000..7ab596b --- /dev/null +++ b/geekos/include/lwip/netif/ne2kif.h @@ -0,0 +1,22 @@ +/* ne2k network interface for lwip + * + * Lei Xia (lxia@northwestern.edu) + */ + +#ifndef __NETIF_NE2KIF_H__ +#define __NETIF_NE2KIF_H__ + +#include +#include +#include +#include + +extern struct netif ne2kif; + +err_t ne2kif_init(struct netif *netif); + +void ne2kif_input(struct NE2K_Packet_Info * info, uchar_t * pkt); + +err_t ne2kif_output(struct netif * netif, struct pbuf * p); + +#endif /*__NETIF_NE2KIF_H__*/ diff --git a/geekos/include/uip/uip-conf.h b/geekos/include/uip/uip-conf.h index 17a5d5e..6f23e05 100644 --- a/geekos/include/uip/uip-conf.h +++ b/geekos/include/uip/uip-conf.h @@ -69,7 +69,8 @@ extern int appcall(void); * * \hideinitializer */ -typedef unsigned char u8_t; +//conflict with lwip +//typedef unsigned char u8_t; /** * 16 bit datatype @@ -78,7 +79,8 @@ typedef unsigned char u8_t; * * \hideinitializer */ -typedef unsigned short int u16_t; +//confict with lwip +//typedef unsigned short int u16_t; /** * Statistics datatype diff --git a/geekos/src/geekos/ne2k.c b/geekos/src/geekos/ne2k.c index 0b8039b..aa11b62 100644 --- a/geekos/src/geekos/ne2k.c +++ b/geekos/src/geekos/ne2k.c @@ -25,8 +25,11 @@ #include #include #include + +#ifdef UIP #include #include +#endif #define DEBUG 1 #define TX_START_BUFF 0x40 @@ -148,13 +151,13 @@ int Init_Ne2k(int (*rcvd_fn)(struct NE2K_Packet_Info *info, uchar_t *packet)) cr->ps = 0x01; /* Switch to reg page 1 */ Out_Byte(NE2K_CR, regs->cr); - /* Set the physical address of the card to 52:54:00:12:34:58 */ - Out_Byte(NE2K_CR+0x01, 0x52); - Out_Byte(NE2K_CR+0x02, 0x54); - Out_Byte(NE2K_CR+0x03, 0x00); - Out_Byte(NE2K_CR+0x04, 0x12); - Out_Byte(NE2K_CR+0x05, 0x34); - Out_Byte(NE2K_CR+0x06, 0x58); + /* Set the physical address of the card */ + Out_Byte(NE2K_CR+0x01, PHY_ADDR1); + Out_Byte(NE2K_CR+0x02, PHY_ADDR2); + Out_Byte(NE2K_CR+0x03, PHY_ADDR3); + Out_Byte(NE2K_CR+0x04, PHY_ADDR4); + Out_Byte(NE2K_CR+0x05, PHY_ADDR5); + Out_Byte(NE2K_CR+0x06, PHY_ADDR6); /* Set the multicast address register to all 1s; accepts all multicast packets */ uint_t i; @@ -228,6 +231,8 @@ int Init_Ne2k(int (*rcvd_fn)(struct NE2K_Packet_Info *info, uchar_t *packet)) * an ARP packet, which is sent out instead. The original packet will need to be * retransmitted at some point in the future. */ +#ifdef UIP + int NE2K_Transmit(uint_t size) { uip_arp_out(); @@ -257,6 +262,8 @@ int NE2K_Transmit(uint_t size) return 0; } +#endif + int NE2K_Send_Packet(uchar_t *packet, uint_t size) { struct _CR * cr = (struct _CR*)&(regs->cr); diff --git a/geekos/src/geekos/net.c b/geekos/src/geekos/net.c index 8fc76bc..7067a38 100644 --- a/geekos/src/geekos/net.c +++ b/geekos/src/geekos/net.c @@ -1,33 +1,74 @@ -/* - * This file is part of the Palacios Virtual Machine Monitor developed - * by the V3VEE Project with funding from the United States National - * Science Foundation and the Department of Energy. - * - * The V3VEE Project is a joint project between Northwestern University - * and the University of New Mexico. You can find out more at - * http://www.v3vee.org - * - * Copyright (c) 2008, Jack Lange - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ +/* (c) 2008, Jack Lange */ +/* (c) 2008, The V3VEE Project */ + #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include -void Init_Network() { - init_socket_layer(); + +static void +tcpip_init_done(void *arg) +{ + sys_sem_t *sem; + sem = arg; + sys_sem_signal(*sem); } +void Init_Network() { + + //temporay now we are using lwip sockets + // init_socket_layer(); + + struct ip_addr ipaddr, netmask, gateway; + sys_sem_t sem; + err_t err; + + sem = sys_sem_new(0); + +#ifdef LWIP_DEBUG + PrintBoth("lwIP: before tcpip_init\n"); +#endif + tcpip_init(tcpip_init_done, &sem); //initial the whole lwip module +#ifdef LWIP_DEBUG + PrintBoth("lwIP: After tcpip_init\n"); +#endif + sys_sem_wait(sem); + sys_sem_free(sem); + + IP4_ADDR(&gateway, 192,168,1,1); + IP4_ADDR(&ipaddr, 192,168,1,2); + IP4_ADDR(&netmask, 255,255,255,0); + + + err = netifapi_netif_add(&ne2kif, &ipaddr, &netmask, &gateway, + NULL, ne2kif_init, ethernet_input); + + if (err != ERR_OK){ + PrintBoth("lwip: initial network failed! add netif error %d/n", err); + return; + } + + netifapi_netif_set_default(&ne2kif); + + //initial a network application + ping_init(); +} + + +#if 0 void test_network() { uchar_t local_addr[4]; @@ -38,7 +79,7 @@ void test_network() { local_addr[2] = 2; local_addr[3] = 21; - set_ip_addr(local_addr); +// set_ip_addr(local_addr); remote_addr[0] = 10; remote_addr[1] = 0; @@ -46,6 +87,8 @@ void test_network() { remote_addr[3] = 20; - connect(remote_addr, 4301); + // connect(remote_addr, 4301); } + +#endif diff --git a/geekos/src/geekos/socket.c b/geekos/src/geekos/socket.c index f042064..e67040b 100644 --- a/geekos/src/geekos/socket.c +++ b/geekos/src/geekos/socket.c @@ -22,13 +22,16 @@ #include #include #include + +#ifdef UIP + #include #include + #include #include #include - #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) #define MAX_SOCKS 1024 @@ -42,12 +45,11 @@ void socket_appcall(void); #endif /* UIP_APPCALL */ - - static int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt); static void periodic_caller(int timer_id, void * arg); void init_socket_layer() { + int i = 0; bool iflag; @@ -59,31 +61,24 @@ void init_socket_layer() { sockets[i].state = CLOSED; } - - //initiate uIP uip_init(); uip_arp_init(); - //setup device driver - Init_Ne2k(&Packet_Received); + //setup device driver + Init_Ne2k(&Packet_Received); iflag = Begin_Int_Atomic(); Start_Timer(2, periodic_caller, NULL); End_Int_Atomic(iflag); - } - - - void set_ip_addr(uchar_t addr[4]) { uip_ipaddr_t ipaddr; uip_ipaddr(ipaddr, addr[0], addr[1], addr[2], addr[3]); /* Local IP address */ uip_sethostaddr(ipaddr); } - static int allocate_socket_fd() { int i = 0; @@ -124,7 +119,6 @@ struct socket * get_socket_from_fd(int fd) { } - static void periodic_caller(int timer_id, void * arg) { int i; //handle the periodic calls of uIP @@ -379,3 +373,6 @@ static int Packet_Received(struct NE2K_Packet_Info * info, uchar_t * pkt) { return 0; } + + +#endif /* UIP */ diff --git a/geekos/src/geekos/synch.c b/geekos/src/geekos/synch.c index fdc1f34..5c5a75b 100644 --- a/geekos/src/geekos/synch.c +++ b/geekos/src/geekos/synch.c @@ -14,6 +14,8 @@ #include #include +#include + /* * NOTES: * - The GeekOS mutex and condition variable APIs are based on those @@ -134,6 +136,24 @@ void Mutex_Unlock(struct Mutex* mutex) } /* + * Destroy Mutex + */ +void Mutex_Destroy(struct Mutex* mutex) +{ + + +} + +/* + * Condition Destroy + */ +void Cond_Destroy(struct Condition* cond) +{ + + +} + +/* * Initialize given condition. */ void Cond_Init(struct Condition* cond) diff --git a/geekos/src/geekos/timer.c b/geekos/src/geekos/timer.c index e287b6e..964f50b 100644 --- a/geekos/src/geekos/timer.c +++ b/geekos/src/geekos/timer.c @@ -133,11 +133,6 @@ timerEvent pendingTimerEvents[MAX_TIMER_EVENTS]; */ volatile ulong_t g_numTicks; -ulong_t clock_time(void){ - return g_numTicks; -} - - /* * Number of times the spin loop can execute during one timer tick */ @@ -173,6 +168,10 @@ int g_Quantum = DEFAULT_MAX_TICKS; # define Debug(args...) #endif +ulong_t clock_time(void){//in millisec + return g_numTicks * (1000/HZ); +} + /* ---------------------------------------------------------------------- * Private functions * ---------------------------------------------------------------------- */ @@ -359,6 +358,8 @@ int Start_Timer(int ticks, timerCallback cb, void * arg) KASSERT(!Interrupts_Enabled()); + PrintBoth ("there\n"); + if (timeEventCount == MAX_TIMER_EVENTS) { return -1; } else { diff --git a/geekos/src/lwip/api/tcpip.c b/geekos/src/lwip/api/tcpip.c index 97ae41d..2dae2e5 100644 --- a/geekos/src/lwip/api/tcpip.c +++ b/geekos/src/lwip/api/tcpip.c @@ -261,7 +261,11 @@ tcpip_thread(void *arg) LOCK_TCPIP_CORE(); while (1) { /* MAIN Loop */ + + PrintBoth("In tcp_thread: main loop\n"); + sys_mbox_fetch(mbox, (void *)&msg); + switch (msg->type) { #if LWIP_NETCONN case TCPIP_MSG_API: diff --git a/geekos/src/lwip/apps/ping.c b/geekos/src/lwip/apps/ping.c new file mode 100644 index 0000000..895b4ff --- /dev/null +++ b/geekos/src/lwip/apps/ping.c @@ -0,0 +1,321 @@ +/** + * @file + * Ping sender module + * + */ + +/* + * 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. + * + */ + +/** + * This is an example of a "ping" sender (with raw API and socket API). + * It can be used as a start point to maintain opened a network connection, or + * like a network "watchdog" for your device. + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/raw.h" +#include "lwip/icmp.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/sockets.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" + +#include "apps/ping.h" + +#include +#include + +/** + * PING_DEBUG: Enable debugging for PING. + */ +#ifndef PING_DEBUG +#define PING_DEBUG LWIP_DBG_ON +#endif + +/** ping target - should be a "struct ip_addr" */ +#ifndef PING_TARGET +#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any) +#endif + +/** ping receive timeout - in milliseconds */ +#ifndef PING_RCV_TIMEO +#define PING_RCV_TIMEO 1000 +#endif + +/** ping delay - in milliseconds */ +#ifndef PING_DELAY +#define PING_DELAY 1000 +#endif + +/** ping identifier - must fit on a u16_t */ +#ifndef PING_ID +#define PING_ID 0xAFAF +#endif + +/** ping additional data size to include in the packet */ +#ifndef PING_DATA_SIZE +#define PING_DATA_SIZE 32 +#endif + +/** ping result action - no default action */ +#ifndef PING_RESULT +#define PING_RESULT(ping_ok) +#endif + +/* ping variables */ +static u16_t ping_seq_num; +static u32_t ping_time; + +#if NO_SYS +/* port-defined functions used for timer execution */ +void sys_msleep(u32_t ms); +u32_t sys_now(); +#endif /* NO_SYS */ + +/** Prepare a echo ICMP request */ +static void +ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) +{ + int i; + + ICMPH_TYPE_SET(iecho,ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = PING_ID; + iecho->seqno = htons(++ping_seq_num); + iecho->chksum = inet_chksum(iecho, len); + + /* fill the additional data buffer with some data */ + for(i = 0; i < PING_DATA_SIZE; i++) { + ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = i; + } +} + +#if LWIP_SOCKET + +/* Ping using the socket ip */ +static err_t +ping_send(int s, struct ip_addr *addr) +{ + int err; + struct icmp_echo_hdr *iecho; + struct sockaddr_in to; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + + if (!(iecho = mem_malloc(ping_size))) { + return ERR_MEM; + } + + ping_prepare_echo(iecho, ping_size); + + to.sin_len = sizeof(to); + to.sin_family = AF_INET; + to.sin_addr.s_addr = addr->addr; + + err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)); + + mem_free(iecho); + + return (err ? ERR_OK : ERR_VAL); +} + +static void +ping_recv(int s) +{ + char buf[64]; + int fromlen, len; + struct sockaddr_in from; + struct ip_hdr *iphdr; + struct icmp_echo_hdr *iecho; + + while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) { + if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) { + LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, (struct ip_addr *)&(from.sin_addr)); + LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time))); + + iphdr = (struct ip_hdr *)buf; + iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4)); + if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) { + /* do some ping result processing */ + PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); + return; + } else { + LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n")); + } + } + } + + if (len == 0) { + LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %lu ms - timeout\n", (sys_now()-ping_time))); + } + + /* do some ping result processing */ + PING_RESULT(0); +} + +static void +ping_thread(void *arg) +{ + int s; + int timeout = PING_RCV_TIMEO; + struct ip_addr ping_target; + + LWIP_UNUSED_ARG(arg); + + if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { + return; + } + + lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + + while (1) { + ping_target = PING_TARGET; + + if (ping_send(s, &ping_target) == ERR_OK) { + LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF( PING_DEBUG, ("\n")); + + ping_time = sys_now(); + ping_recv(s); + } else { + LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF( PING_DEBUG, (" - error\n")); + } + sys_msleep(PING_DELAY); + } +} + +#else /* LWIP_SOCKET */ + +/* Ping using the raw ip */ +static u8_t +ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *addr) +{ + struct icmp_echo_hdr *iecho; + + if (pbuf_header( p, -PBUF_IP_HLEN)==0) { + iecho = p->payload; + + if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) { + LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF( PING_DEBUG, (" %lu ms\n", (sys_now()-ping_time))); + + /* do some ping result processing */ + PING_RESULT(1); + } + } + + return 1; /* eat the event */ +} + +static void +ping_send(struct raw_pcb *raw, struct ip_addr *addr) +{ + struct pbuf *p; + struct icmp_echo_hdr *iecho; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + + if (!(p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM))) { + return; + } + if ((p->len == p->tot_len) && (p->next == NULL)) { + iecho = p->payload; + + ping_prepare_echo(iecho, ping_size); + + raw_sendto(raw, p, addr); + ping_time = sys_now(); + } + pbuf_free(p); +} + +static void +ping_timeout(void *arg) +{ + struct raw_pcb *pcb = (struct raw_pcb*)arg; + struct ip_addr ping_target = PING_TARGET; + + LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); + + LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF( PING_DEBUG, ("\n")); + + ping_send(pcb, &ping_target); + + sys_timeout(PING_DELAY, ping_timeout, pcb); +} + +static void +ping_raw_init(void) +{ + struct raw_pcb *pcb; + + if (!(pcb = raw_new(IP_PROTO_ICMP))) { + return; + } + + raw_recv(pcb, ping_recv, NULL); + raw_bind(pcb, IP_ADDR_ANY); + sys_timeout(PING_DELAY, ping_timeout, pcb); +} + +#endif /* LWIP_SOCKET */ + +void +ping_init(void) +{ +#if LWIP_SOCKET + sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +#else /* LWIP_SOCKET */ + ping_raw_init(); +#endif /* LWIP_SOCKET */ +} + + +u32_t +sys_now() +{ + ulong_t msec; + + msec = clock_time(); + + return msec; +} + +#endif /* LWIP_RAW && LWIP_ICMP */ diff --git a/geekos/src/lwip/arch/sys_arch.c b/geekos/src/lwip/arch/sys_arch.c index 289ed70..e390d98 100644 --- a/geekos/src/lwip/arch/sys_arch.c +++ b/geekos/src/lwip/arch/sys_arch.c @@ -44,18 +44,18 @@ * will block until there is more room instead of just * leaking messages. */ +/* + * Modified by Lei Xia (lxia@northwestern.edu) to fit to Palacios, 9/29/2008 + */ #include "lwip/debug.h" #include -#include -#include -#include -#include -#include +#include #include #include #include +#include #include #include "lwip/sys.h" @@ -103,15 +103,15 @@ struct sys_thread { }; -static struct timeval starttime; +//static struct timeval starttime; //static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER; static struct Mutex lwprot_mutex; // !!!! need to be initiated, void Mutex_Init(struct Mutex* mutex); //static pthread_t lwprot_thread = (pthread_t) 0xDEAD; -static struct Kernel_Thread lwprot_thread = (struct Kernel_Thread) 0xDEAD; //!!!!! how to set it to a NULL thread? +//static struct Kernel_Thread lwprot_thread = (struct Kernel_Thread) 0xDEAD; //!!!!! how to set it to a NULL thread? -static int lwprot_count = 0; +//static int lwprot_count = 0; static struct sys_sem *sys_sem_new_(u8_t count); static void sys_sem_free_(struct sys_sem *sem); @@ -188,12 +188,11 @@ current_thread(void) } -//!!!!!!!!!!!!backto this function later /*-----------------------------------------------------------------------------------*/ sys_thread_t sys_thread_new(char *name, void (* function)(void *arg), void *arg, int stacksize, int prio) { - int code; + //int code; //pthread_t tmp; struct Kernel_Thread *tmp; struct sys_thread *st = NULL; @@ -610,6 +609,8 @@ sys_arch_timeouts(void) thread = current_thread(); return &thread->timeouts; } + + /*-----------------------------------------------------------------------------------*/ /** sys_prot_t sys_arch_protect(void) @@ -625,6 +626,8 @@ 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. */ + +#if 0 sys_prot_t sys_arch_protect(void) { @@ -659,11 +662,12 @@ sys_arch_unprotect(sys_prot_t pval) { if (--lwprot_count == 0) { - lwprot_thread = (Kernel_Thread) 0xDEAD; + lwprot_thread = (struc Kernel_Thread) 0xDEAD; Mutex_Unlock(&lwprot_mutex); } } } +#endif /*-----------------------------------------------------------------------------------*/ @@ -675,6 +679,7 @@ sys_arch_unprotect(sys_prot_t pval) #define HZ 100 #endif +#if 0 unsigned long sys_jiffies(void) { @@ -690,6 +695,7 @@ sys_jiffies(void) usec /= 1000000L / HZ; return HZ * sec + usec; } +#endif #if PPP_DEBUG @@ -703,7 +709,7 @@ void ppp_trace(int level, const char *format, ...) va_start(args, format); //vprintf(format, args); - SerialPrintList(format, args); + PrintDebug(format, args); va_end(args); } diff --git a/geekos/src/lwip/build/Makefile b/geekos/src/lwip/build/Makefile index ce16551..db76718 100644 --- a/geekos/src/lwip/build/Makefile +++ b/geekos/src/lwip/build/Makefile @@ -47,48 +47,50 @@ CFLAGS:=$(CFLAGS) \ # COREFILES, CORE4FILES: The minimum set of files needed for lwIP. COREFILES=$(LWIPDIR)/core/mem.c $(LWIPDIR)/core/memp.c $(LWIPDIR)/core/netif.c \ $(LWIPDIR)/core/pbuf.c $(LWIPDIR)/core/stats.c $(LWIPDIR)/core/sys.c \ - $(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_in.c \ + $(LWIPDIR)/core/tcp.c $(LWIPDIR)/core/tcp_in.c $(LWIPDIR)/core/raw.c\ $(LWIPDIR)/core/tcp_out.c $(LWIPDIR)/core/udp.c $(LWIPDIR)/core/init.c CORE4FILES=$(LWIPDIR)/core/ipv4/icmp.c $(LWIPDIR)/core/ipv4/ip.c \ $(LWIPDIR)/core/ipv4/inet.c $(LWIPDIR)/core/ipv4/ip_addr.c \ - $(LWIPDIR)/core/ipv4/inet_chksum.c + $(LWIPDIR)/core/ipv4/inet_chksum.c $(LWIPDIR)/core/ipv4/ip_frag.c # APIFILES: The files which implement the sequential and socket APIs. APIFILES=$(LWIPDIR)/api/api_lib.c $(LWIPDIR)/api/api_msg.c $(LWIPDIR)/api/tcpip.c \ - $(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c $(LWIPDIR)/api/netbuf.c $(LWIPDIR)/api/netdb.c + $(LWIPDIR)/api/err.c $(LWIPDIR)/api/sockets.c $(LWIPDIR)/api/netbuf.c $(LWIPDIR)/api/netdb.c $(LWIPDIR)/api/netifapi.c # NETIFFILES: Files implementing various generic network interface functions.' -NETIFFILES=$(LWIPDIR)/netif/loopif.c \ - $(LWIPDIR)/netif/etharp.c +NETIFFILES=$(LWIPDIR)/netif/loopif.c $(LWIPDIR)/netif/ne2kif.c $(LWIPDIR)/netif/etharp.c # ARCHFILES: Architecture specific files. ARCHFILES=$(LWIPDIR)/arch/sys_arch.c +# APPFILES: Application files +APPFILES=$(LWIPDIR)/apps/ping.c + # LWIPFILES: All the above. -LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES) +LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES) $(APPFILES) LWIPFILESW=$(wildcard $(LWIPFILES)) LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o)) -#LWIPLIB=lwip.o +# LWIPLIB=lwip.o %.o: $(CC) $(CFLAGS) -c $(LWIPFILES) -all: $(LWIPOBJS) +all: $(LWIPOBJS) cp *.o $(PROJECT_ROOT)build/lwip/ .PHONY: all clean: - rm -f *.o $(LWIPLIB) *.s .depend* *.core + rm -f *.o .depend* depend dep: .depend include .depend -##$(LWIPLIB): $(LWIPOBJS) -## $(CC) -g -nostartfiles -shared -static $^ -o $@ +# $(LWIPLIB): $(LWIPOBJS) +# $(CC) -g -nostartfiles -shared -static $^ -o $@ .depend: $(LWIPFILES) $(CC) $(CFLAGS) -MM $^ > .depend || rm -f .depend diff --git a/geekos/src/lwip/core/init.c b/geekos/src/lwip/core/init.c index 5e0b522..5a29538 100644 --- a/geekos/src/lwip/core/init.c +++ b/geekos/src/lwip/core/init.c @@ -200,7 +200,7 @@ lwip_sanity_check(void) if (TCP_SNDLOWAT > TCP_SND_BUF) LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n")); if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE)) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n")); + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE: %d\n", (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE))); if (TCP_WND < TCP_MSS) LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n")); #endif /* LWIP_TCP */ diff --git a/geekos/src/lwip/netif/ne2kif.c b/geekos/src/lwip/netif/ne2kif.c new file mode 100644 index 0000000..939ba66 --- /dev/null +++ b/geekos/src/lwip/netif/ne2kif.c @@ -0,0 +1,232 @@ +/** + * @file + * Ethernet Interface for ne2k device + * + * Lei Xia (lxia@northwestern.edu + */ + +#include "lwip/opt.h" + + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include +#include +#include "netif/etharp.h" +#include "netif/ppp_oe.h" +#include "lwip/netifapi.h" +#include "netif/ne2kif.h" + + +#include +#include +#include + + +struct netif ne2kif; + +/** + * This function 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. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +err_t +ne2kif_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q; + int size, offset, remlen; + uchar_t *packet; + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + size = p->tot_len; + offset = 0; + remlen = size; + + packet = (uchar_t *)Malloc (remlen); + + for(q = p; q != NULL && remlen >0; q = q->next) { + /* 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. */ + + memcpy(packet+offset, q->payload, q->len < remlen? q->len:remlen); + remlen -= q->len; + offset += q->len; + + } + NE2K_Send_Packet(packet, size); + + //signal that packet should be sent(); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void +ne2kif_input(struct NE2K_Packet_Info * info, uchar_t * pkt) +{ + struct pbuf *p, *q; + uint_t offset; + uint_t len, rlen; + + len = info->size; + + PrintBoth("Ne2k: Packet REceived\n"); + +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; // allow room for Ethernet padding +#endif + + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) { + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); // drop the padding word +#endif + + // iterate over the pbuf chain until it has read the entire packet into the pbuf. + for(offset = 0, q = p; q != NULL && rlen > 0; q = q->next) { + memcpy(q->payload, pkt+offset, rlen > q->len? q->len: rlen); + rlen -= q->len; + offset += q->len; + } + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } else { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + } + + Free(pkt); + + if (p == NULL) return; + /* points to packet payload, which starts with an Ethernet header */ + //ethhdr = p->payload; + + /* full packet send to tcpip_thread to process */ + if (ne2kif.input(p, &ne2kif)!=ERR_OK) + { LWIP_DEBUGF(NETIF_DEBUG, ("ne2kif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + +#if 0 + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + + break; + + default: + pbuf_free(p); + p = NULL; + break; + } +#endif + +} + +/** + * 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. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t +ne2kif_init(struct netif *netif) +{ + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000); + + netif->state = NULL; + netif->name[0] = 'n'; + netif->name[1] = 'e'; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = ne2kif_output; + + + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = PHY_ADDR1; + netif->hwaddr[1] = PHY_ADDR2; + netif->hwaddr[2] = PHY_ADDR3; + netif->hwaddr[3] = PHY_ADDR4; + netif->hwaddr[4] = PHY_ADDR5; + netif->hwaddr[5] = PHY_ADDR6; + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + //initate ne2k hardware + Init_Ne2k(&ne2kif_input); + + return ERR_OK; +} diff --git a/geekos/src/net/uip.c b/geekos/src/net/uip.c index 059ef9b..0b9fa75 100644 --- a/geekos/src/net/uip.c +++ b/geekos/src/net/uip.c @@ -1877,12 +1877,16 @@ uip_process(u8_t flag) uip_flags = 0; return; } + /*---------------------------------------------------------------------------*/ +/* replicate defined in lwip.c, u16_t htons(u16_t val) { return HTONS(val); } +*/ + /*---------------------------------------------------------------------------*/ void uip_send(const void *data, int len) diff --git a/palacios/build/Makefile b/palacios/build/Makefile index 551d9c3..d16d32e 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -252,6 +252,7 @@ XED_GAS_OBJS := $(XED_GAS_SRCS:%.s=xed/%.o) XED_OBJS := $(XED_C_OBJS) $(XED_GAS_OBJS) + DEVICE_C_SRCS := generic.c keyboard.c nvram.c timer.c simple_pic.c 8259a.c 8254.c serial.c ramdisk.c cdrom.c DEVICE_C_OBJS := $(DEVICE_C_SRCS:%.c=devices/%.o) @@ -263,6 +264,7 @@ V3LIBS := $(DECODER_LIBS) + # ---------------------------------------------------------------------- # Tools - # This section defines programs that are used to build GeekOS. @@ -346,7 +348,6 @@ OBJCOPY_FLAGS := -R .dynamic -R .note -R .comment - palacios/%.o : palacios/%.c $(TARGET_CC) -c $(CC_GENERAL_OPTS) $(CC_VMM_OPTS) $< -o palacios/$*.o @@ -395,6 +396,9 @@ rombios_link: vgabios_link: ln -s -f ../src/vmboot/vgabios/VGABIOS-lgpl-latest.bin vgabios +force_lwip: + (cd ../src/lwip/build; make clean; make) + force_rombios: rombios_link (cd ../src/vmboot/rombios; make clean; make) @@ -404,7 +408,7 @@ force_vgabios: vgabios_link force_payload: force_rombios force_vgabios ../scripts/make_payload.pl payload_layout.txt vm_kernel -inter1: force_payload +inter1: force_payload force_lwip -make clean world: inter1 vmm diff --git a/palacios/include/geekos/socket.h b/palacios/include/geekos/socket.h new file mode 100644 index 0000000..fbc47ed --- /dev/null +++ b/palacios/include/geekos/socket.h @@ -0,0 +1,40 @@ +/* (c) 2008, Jack Lange */ +/* (c) 2008, The V3VEE Project */ + +#ifndef GEEKOS_SOCKET_H +#define GEEKOS_SOCKET_H + +#include +#include + +#ifdef UIP +#include + + +typedef enum {WAITING, CLOSED, LISTEN, ESTABLISHED} sock_state_t; + +struct socket { + int in_use; + struct Thread_Queue recv_wait_queue; + struct ring_buffer *send_buf; + struct ring_buffer *recv_buf; + struct uip_conn *con; + + sock_state_t state; + +}; + + +void init_socket_layer(); + +int connect(const uchar_t ip_addr[4], ushort_t port); +int close(const int sockfd); +int recv(int sockfd, void * buf, uint_t len); +int send(int sockfd, void * buf, uint_t len); + +void set_ip_addr(uchar_t addr[4]); + +#endif /* UIP */ + + +#endif