From 98ac3ec1ffca226ad49b81b417f1fbe183d3d9da Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 29 Sep 2011 23:36:37 +0200 Subject: [PATCH 01/23] create new directory for demo applications --- apps/Makefile | 4 ++++ {kernel => apps}/echo.c | 0 {kernel => apps}/netio.c | 0 {kernel => apps}/tests.c | 0 4 files changed, 4 insertions(+) create mode 100644 apps/Makefile rename {kernel => apps}/echo.c (100%) rename {kernel => apps}/netio.c (100%) rename {kernel => apps}/tests.c (100%) diff --git a/apps/Makefile b/apps/Makefile new file mode 100644 index 00000000..94912228 --- /dev/null +++ b/apps/Makefile @@ -0,0 +1,4 @@ +C_source := tests.c echo.c netio.c +MODULE := apps + +include $(TOPDIR)/Makefile.inc diff --git a/kernel/echo.c b/apps/echo.c similarity index 100% rename from kernel/echo.c rename to apps/echo.c diff --git a/kernel/netio.c b/apps/netio.c similarity index 100% rename from kernel/netio.c rename to apps/netio.c diff --git a/kernel/tests.c b/apps/tests.c similarity index 100% rename from kernel/tests.c rename to apps/tests.c From bff21fdcad76dfd85ccd14215d64a085b69e3add Mon Sep 17 00:00:00 2001 From: Marian Ohligs Date: Fri, 30 Sep 2011 11:48:13 +0200 Subject: [PATCH 02/23] tidy up syscall.c, add comments, add missing checks, fix bug in open --- kernel/syscall.c | 245 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 183 insertions(+), 62 deletions(-) diff --git a/kernel/syscall.c b/kernel/syscall.c index f5329367..28b660ca 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -47,6 +47,11 @@ static int get_fildes(void) task_t* curr_task = per_core(current_task); int fd; + /* + * Seach the process specific file descriptor table for a free + * descriptor. The new descriptor returned by the call is the lowest + * numbered descriptor currently not in use by the process. + */ for (fd = 0; fd < NR_OPEN; fd++) { if (curr_task->fildes_table[fd] == NULL) { /* Init Filedescriptor */ @@ -60,32 +65,55 @@ static int get_fildes(void) return -EMFILE; } +static int sys_write(int fd, const char* buf, size_t len) +{ + task_t* curr_task = per_core(current_task); + + /* fd is negative or greater than the maximum allowable number */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return -EBADF; + /* fd is not an active, valid file descriptor. */ + if (curr_task->fildes_table[fd] == NULL) + return -EBADF; + + return write_fs(curr_task->fildes_table[fd], (uint8_t*)buf, len); +} + static int sys_open(const char* name, int flags, int mode) { int fd, check; - fildes_t* file = NULL; + task_t* curr_task = per_core(current_task); + /* no name is given */ + if (name == NULL) + return -EINVAL; + + /* Get a free file descriptor */ fd = get_fildes(); - /* validate the fd */ - if (fd < 0) - return fd; - file = per_core(current_task)->fildes_table[fd]; - file->mode = mode; - file->flags = flags; - file->count = 1; - check = open_fs(file, (char*) name); + /* fd is negative or greater than the maximum allowable number */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return fd; /* in this case fd = errno */ + + /* init the whole file descriptor structure */ + curr_task->fildes_table[fd]->mode = mode; + curr_task->fildes_table[fd]->flags = flags; + curr_task->fildes_table[fd]->count = 1; + check = open_fs(curr_task->fildes_table[fd], (char*) name); + + /* file doesn't exist! */ if (check < 0) { - /* file doesn't exist! */ - kfree(file, sizeof(fildes_t)); - file = NULL; + /* tidy up the fildescriptor */ + kfree(curr_task->fildes_table[fd], sizeof(fildes_t)); + curr_task->fildes_table[fd] = NULL; return check; } return fd; } -static int sys_stat(const char* name, struct stat* st) { +static int sys_stat(const char* name, struct stat* st) +{ vfs_node_t* node; node = findnode_fs(name); @@ -112,43 +140,102 @@ static int sys_stat(const char* name, struct stat* st) { return 0; } +static int sys_read(int fd, const char* buf, size_t len) +{ + task_t* curr_task = per_core(current_task); + + /* fd is negative or greater than the maximum allowable number */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return -EBADF; + /* fd is not an active, valid file descriptor. */ + if (curr_task->fildes_table[fd] == NULL) + return -EBADF; + + return read_fs(curr_task->fildes_table[fd], (uint8_t*)buf, len); +} + + #if defined(CONFIG_LWIP) && LWIP_SOCKET static int sys_socket(int domain, int type, int protocol) { - int fd; - fildes_t* file = NULL; + int fd, sock; + task_t* curr_task = per_core(current_task); + /* Get a free file descriptor */ fd = get_fildes(); - /* validate the fd */ - if (fd < 0) - return fd; - file = per_core(current_task)->fildes_table[fd]; - file->offset = lwip_socket(domain, type, protocol); - file->node = findnode_fs("/dev/socket"); - file->count = 1; + /* validate the file descriptor */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return fd; /* in this case fd = errno */ + + /* Get a valid lwip descriptor */ + sock = lwip_socket(domain, type, protocol); + + /* validate the file descriptor */ + if (BUILTIN_EXPECT(sock < 0, 0)) + return sock; /* in this case sock = errno */ + + /* + * init the whole file descriptor structure. + * We use the offset to save the lwip descriptor + * TODO: find another solution or change the name 'offset' + */ + curr_task->fildes_table[fd]->offset = sock; + curr_task->fildes_table[fd]->count = 1; + curr_task->fildes_table[fd]->node = findnode_fs("/dev/socket"); + + /* file doesn't exist! */ + if (curr_task->fildes_table[fd]->node == NULL) { + /* tidy up the fildescriptor */ + kfree(curr_task->fildes_table[fd], sizeof(fildes_t)); + curr_task->fildes_table[fd] = NULL; + return -ENOENT; + } return fd; } static int sys_accept(int s, struct sockaddr* addr, socklen_t* addrlen) { - int fd; - fildes_t* file = NULL; + int fd, sock2; + task_t* curr_task = per_core(current_task); - if (BUILTIN_EXPECT(s >= NR_OPEN, 0)) - return -EINVAL; + /* validate the 'socket'-filedescriptor */ + if (BUILTIN_EXPECT((s >= NR_OPEN) || (s < 0), 0)) + return -EBADF; + /* validate the 'socket'-file descriptor object */ + if (curr_task->fildes_table[s] == NULL) + return -EBADF; + /* Get a free file descriptor */ fd = get_fildes(); - /* validate the fd */ - if (fd < 0) - return fd; - file = per_core(current_task)->fildes_table[fd]; - file->offset = lwip_accept(s, addr, addrlen); - file->node = findnode_fs("/dev/socket"); - file->count = 1; + /* validate the file descriptor */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return fd; /* in this case fd = errno */ + /* Get a valid lwip descriptor */ + sock2 = lwip_accept(s, addr, addrlen); + /* validate the file descriptor */ + if (BUILTIN_EXPECT(sock2 < 0, 0)) + return sock2; /* in this case sock = errno */ + + /* + * init the whole file descriptor structure. + * We use the offset to save the lwip descriptor + * TODO: find another solution or change the name 'offset' + */ + curr_task->fildes_table[fd]->offset = sock2; + curr_task->fildes_table[fd]->count = 1; + curr_task->fildes_table[fd]->node = findnode_fs("/dev/socket"); + /* file doesn't exist! */ + if (curr_task->fildes_table[fd]->node == NULL) { + /* tidy up the fildescriptor */ + kfree(curr_task->fildes_table[fd], sizeof(fildes_t)); + curr_task->fildes_table[fd] = NULL; + return -ENOENT; + } + return fd; } @@ -157,13 +244,26 @@ static int sys_accept(int s, struct sockaddr* addr, socklen_t* addrlen) static int sys_close(int fd) { + int check; task_t* curr_task = per_core(current_task); - - if (BUILTIN_EXPECT(fd >= NR_OPEN, 0)) - return -EINVAL; + /* fd is negative or greater than the maximum allowable number */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return -EBADF; + /* fd is not an active, valid file descriptor. */ + if (curr_task->fildes_table[fd] == NULL) + return -EBADF; + + /* + * The close() call deletes a descriptor from the per-process object + * reference table. If this is the last reference to the underlying + * object, the object will be deactivated. + */ if (curr_task->fildes_table[fd]->count == 1) { - close_fs(curr_task->fildes_table[fd]); + check = close_fs(curr_task->fildes_table[fd]); + /* close command failed -> return check = errno */ + if (BUILTIN_EXPECT(check < 0, 0)) + return check; kfree(curr_task->fildes_table[fd], sizeof(fildes_t)); curr_task->fildes_table[fd] = NULL; } else { @@ -178,30 +278,42 @@ static int sys_close(int fd) static int sys_lseek(int fd, off_t pos, int origin) { int ret = -EINVAL; - fildes_t* file; + task_t* curr_task = per_core(current_task); - if (BUILTIN_EXPECT(fd >= NR_OPEN, 0)) - return -EINVAL; + /* fd is negative or greater than the maximum allowable number */ + if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) + return -EBADF; + /* fd is not an active, valid file descriptor. */ + if (curr_task->fildes_table[fd] == NULL) + return -EBADF; - file = per_core(current_task)->fildes_table[fd]; - - if (BUILTIN_EXPECT(!((file->node->type == FS_FILE) - || (file->node->type == FS_CHARDEVICE)), 0)) - return -EINVAL; + /* TODO: in case of Fildes is associated with a pipe, socket, or FIFO. return ESPIPE */ + /* TODO: The seek location is too large to be stored in an object of type off_t. return EOVERFLOW*/ switch(origin) - { + { case SEEK_SET: { /* set file offset to offset */ - file->offset = pos; + ret = pos; + /* The seek location is negative. */ + if (ret < 0) + return -EINVAL; + curr_task->fildes_table[fd]->offset = ret; ret = 0; break; } case SEEK_CUR: { /* set file offset to current plus offset */ - ret = pos + file->offset; + ret = pos + curr_task->fildes_table[fd]->offset; + /* The seek location is negative. */ + if (ret < 0) + return -EINVAL; break; } case SEEK_END: { /* set file offset to EOF plus offset */ - file->offset = pos + file->node->block_size; + ret = pos + curr_task->fildes_table[fd]->node->block_size; + /* The seek location is negative. */ + if (ret < 0) + return -EINVAL; + curr_task->fildes_table[fd]->offset = ret; ret = 0; break; } @@ -209,6 +321,7 @@ static int sys_lseek(int fd, off_t pos, int origin) ret = -EINVAL; break; } + return ret; } @@ -217,12 +330,19 @@ static int sys_dup(int fd) task_t* curr_task = per_core(current_task); int new_fd; + /* fd is negative or greater than the maximum allowable number */ if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) return -EBADF; + /* fd is not an active, valid file descriptor. */ if (curr_task->fildes_table[fd] == NULL) return -EBADF; + /* Get a free file descriptor */ new_fd = get_fildes(); + /* validate the file descriptor */ + if (BUILTIN_EXPECT((new_fd >= NR_OPEN) || (fd < 0), 0)) + return new_fd; /* in this case fd = errno */ + curr_task->fildes_table[new_fd] = curr_task->fildes_table[fd]; curr_task->fildes_table[fd]->count++; @@ -233,18 +353,26 @@ static int sys_dup2(int fd, int fd2) { task_t* curr_task = per_core(current_task); + /* fd and fd2 is negative or greater than the maximum allowable number */ if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0)) return -EBADF; if (BUILTIN_EXPECT((fd2 >= NR_OPEN) || (fd2 < 0), 0)) return -EBADF; + /* fd is not an active, valid file descriptor. */ if (curr_task->fildes_table[fd] == NULL) return -EBADF; - if (fd == fd2) + /* If fd and fd2 are equal, then dup2() just returns fd2 */ + if (fd == fd2) return fd2; + + /* + * if descriptor fd2 is already in use, it is first deallocated + * as if a close(2) call had been done first + */ if (curr_task->fildes_table[fd2] != NULL) sys_close(fd2); - + curr_task->fildes_table[fd2] = curr_task->fildes_table[fd]; curr_task->fildes_table[fd]->count++; @@ -296,9 +424,7 @@ int syscall_handler(uint32_t sys_nr, ...) int fd = va_arg(vl, int); const char* buf = va_arg(vl, const char*); size_t len = va_arg(vl, size_t); - if (fd >= 0) - ret = write_fs(per_core(current_task)->fildes_table[fd], - (uint8_t*)buf, len); + ret = sys_write(fd, buf, len); break; } case __NR_open: { @@ -310,8 +436,7 @@ int syscall_handler(uint32_t sys_nr, ...) } case __NR_close: { int fd = va_arg(vl, int); - if (fd >= 0) - ret = sys_close(fd); + ret = sys_close(fd); break; } case __NR_dup: { @@ -328,7 +453,6 @@ int syscall_handler(uint32_t sys_nr, ...) case __NR_stat: { const char* name = va_arg(vl, const char*); struct stat* st = va_arg(vl, struct stat*); - ret = sys_stat(name, st); break; } @@ -336,17 +460,14 @@ int syscall_handler(uint32_t sys_nr, ...) int fd = va_arg(vl, int); const char* buf = va_arg(vl, const char*); size_t len = va_arg(vl, size_t); - if (fd >= 0) - ret = read_fs(per_core(current_task)->fildes_table[fd], - (uint8_t*)buf, len); + ret = sys_read(fd, buf, len); break; } case __NR_lseek: { int fd = va_arg(vl, int); off_t pos = va_arg(vl, off_t); int origin = va_arg(vl, int); - if (fd >= 0) - ret = sys_lseek(fd, pos, origin); + ret = sys_lseek(fd, pos, origin); break; } case __NR_sbrk: { From 84d9058d7a707b126bf065805905a76a61f35c85 Mon Sep 17 00:00:00 2001 From: Marian Ohligs Date: Fri, 30 Sep 2011 11:55:26 +0200 Subject: [PATCH 03/23] fix makefile --- Makefile.example | 2 +- kernel/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.example b/Makefile.example index a4b633f7..fd93ee09 100644 --- a/Makefile.example +++ b/Makefile.example @@ -3,7 +3,7 @@ ARCH = x86 NAME = metalsvm LWIPDIRS = lwip/src/arch lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/netif DRIVERDIRS = drivers/net drivers/char -KERNDIRS = libkern kernel mm fs arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS) +KERNDIRS = libkern kernel mm fs apps arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS) SUBDIRS = $(KERNDIRS) CC_FOR_TARGET=gcc diff --git a/kernel/Makefile b/kernel/Makefile index fabfe28e..0e498e06 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c netio.c init.c +C_source := main.c tasks.c syscall.c init.c MODULE := kernel include $(TOPDIR)/Makefile.inc From aecd3b1c8cce419c39bb2c59d561d6b552ecdf30 Mon Sep 17 00:00:00 2001 From: Marian Ohligs Date: Fri, 30 Sep 2011 11:59:45 +0200 Subject: [PATCH 04/23] remove compiler warnings in drivers/char/stdio --- arch/x86/include/asm/kb.h | 4 +++- arch/x86/kernel/kb.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kb.h b/arch/x86/include/asm/kb.h index 1b2dfb40..fcb55196 100644 --- a/arch/x86/include/asm/kb.h +++ b/arch/x86/include/asm/kb.h @@ -53,7 +53,9 @@ typedef struct extern kb_buffer_t kb_buffer; -void kb_flush(); +void kb_init(size_t size, tid_t tid); + +void kb_finish(void); #endif diff --git a/arch/x86/kernel/kb.c b/arch/x86/kernel/kb.c index aabf040c..18a65ee7 100644 --- a/arch/x86/kernel/kb.c +++ b/arch/x86/kernel/kb.c @@ -36,7 +36,7 @@ void kb_init(size_t size, tid_t tid) { return; } -void kb_finish() { +void kb_finish(void) { kfree(kb_buffer.buffer, (kb_buffer.maxsize * sizeof(char))); kb_buffer.buffer = NULL; kb_buffer.size = 0; From 789ffcb0115df5b8737ec7f84c4b9c07a9f09f3f Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 2 Oct 2011 14:44:05 +0200 Subject: [PATCH 05/23] minor changes --- Makefile.example | 2 +- kernel/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.example b/Makefile.example index a4b633f7..fd93ee09 100644 --- a/Makefile.example +++ b/Makefile.example @@ -3,7 +3,7 @@ ARCH = x86 NAME = metalsvm LWIPDIRS = lwip/src/arch lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/netif DRIVERDIRS = drivers/net drivers/char -KERNDIRS = libkern kernel mm fs arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS) +KERNDIRS = libkern kernel mm fs apps arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/scc $(LWIPDIRS) $(DRIVERDIRS) SUBDIRS = $(KERNDIRS) CC_FOR_TARGET=gcc diff --git a/kernel/Makefile b/kernel/Makefile index fabfe28e..0e498e06 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c netio.c init.c +C_source := main.c tasks.c syscall.c init.c MODULE := kernel include $(TOPDIR)/Makefile.inc From aa6eb4da1ba0e17d27876fa1d5bf45f460b77f0e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 2 Oct 2011 07:11:01 -0700 Subject: [PATCH 06/23] change coding style --- drivers/net/util.c | 104 +++++++++++++++++++++------------------------ drivers/net/util.h | 52 +++++++++++------------ 2 files changed, 75 insertions(+), 81 deletions(-) diff --git a/drivers/net/util.c b/drivers/net/util.c index 415d5fd0..8ab43537 100644 --- a/drivers/net/util.c +++ b/drivers/net/util.c @@ -1,55 +1,49 @@ -/* - * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, - * RWTH Aachen University - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of MetalSVM. - */ - -#include -#include "util.h" - -inline int isprint(unsigned char e) -{ - if ((e < 0x30) || (e > 0x80)) - return 0; - return 1; -} - -// hex_dumb display network packets in a good way -void hex_dump(unsigned n, const unsigned char* buf) -{ - int on_this_line = 0; - - while (n-- > 0) - { - kprintf("%02X ", *buf++); - on_this_line += 1; - if (on_this_line == 16 || n == 0) - { - int i; - - kputs(" "); - - for (i = on_this_line; i < 16; i++) - kputs(" "); - - for (i = on_this_line; i > 0; i--) - kputchar(isprint(buf[-i]) ? buf[-i] : '.'); - - kputs("\n"); - on_this_line = 0; - } - } -} +/* + * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + */ + +#include +#include "util.h" +inline int isprint(unsigned char e) +{ + if ((e < 0x30) || (e > 0x80)) + return 0; + return 1; +} + +// hex_dumb display network packets in a good way +void hex_dump(unsigned n, const unsigned char *buf) +{ + int on_this_line = 0; + while (n-- > 0) + { + kprintf("%02X ", *buf++); + on_this_line += 1; + if (on_this_line == 16 || n == 0) + { + int i; + kputs(" "); + for (i = on_this_line; i < 16; i++) + kputs(" "); + for (i = on_this_line; i > 0; i--) + kputchar(isprint(buf[-i]) ? buf[-i] : '.'); + kputs("\n"); + on_this_line = 0; + } + } +} diff --git a/drivers/net/util.h b/drivers/net/util.h index f35b7428..c2c75c1d 100644 --- a/drivers/net/util.h +++ b/drivers/net/util.h @@ -1,26 +1,26 @@ -/* - * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, - * RWTH Aachen University - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of MetalSVM. - */ - -#ifndef __UTIL__ -#define __UTIL__ - -// hex_dumb display network packets in a good way -void hex_dump(unsigned n, const unsigned char* buf); - -#endif +/* + * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + */ + +#ifndef __UTIL__ +#define __UTIL__ + +// hex_dumb display network packets in a good way +void hex_dump(unsigned n, const unsigned char *buf); + +#endif From 49a793736c67064a975b9ab9f0a28df2f651889e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 2 Oct 2011 08:54:53 -0700 Subject: [PATCH 07/23] merge driver from Benedikt's bachelor thesis, remove compiler warning --- drivers/net/mmnif.c | 3220 ++++++++++++++++++++++++++++--------------- drivers/net/mmnif.h | 99 +- 2 files changed, 2129 insertions(+), 1190 deletions(-) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index 3b1679be..80acc0e3 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -1,1139 +1,2081 @@ -/* - * mmnif.c --- memmory mapped interface - * - * Virutal IP Interface for the concept processor SCC - * - * virutally tested under Windows 7 - * - * Carl-Benedikt Krüger 2011 - * - * - * EXPERIMENTAL VERSION - */ - - -#include "mmnif.h" /* definitions */ - -#include /* lwip netif */ -#include /* inteface stats */ -#include /* ethernet arp packets */ -#include /* struct iphdr*/ -#include /* tcpip_input()*/ -#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) - -#ifdef WIN32 - -#define kmalloc malloc -#define kfree(x,y) free(x) -#define RCCE_shfree(x) VirtualFree(x,NULL,NULL); -#define RCCE_shmalloc(x) VirtualAlloc((char*)0x41000000,x,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE); -#include "mailbox.h" /* mailbox_ptr_t */ -#define WIN32_LEAN_AND_MEAN -#include -#include -typedef bthread_sem_t sem_t; -typedef bthread_t tid_t; -/* "interrupt" of the other virutal network card*/ -extern HANDLE remote_process_event; -extern HANDLE remote_process_mutex; -extern HANDLE own_process_mutex; -/* HANDLE to the other Process (for WPM and RPM)*/ -extern HANDLE hProc; -#define DEBUGPRINTF(x,...) printf(x,__VA_ARGS__) - -#else - -#include /* mailbox_ptr_t */ - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#define DEBUGPRINTF(x,...) kprintf(x,##__VA_ARGS__) - -#endif - - - -#define DEBUG_MMNIF -//#define DEBUG_MMNIF_PACKET - -#ifdef DEBUG_MMNIF -#include "util.h" /* hex dump */ -#endif - -/* define constants - * regarding the driver & its configuration - */ - -#define MMNIF_TX_BUFFERLEN 1792 -#define MMNIF_TX_QUEUELEN 4 - -#define MMNIF_RX_BUFFERLEN 8192 -#define MMNIF_MAX_DESCRIPTORS 32 - -#define MMNIF_CORES 48 - -#define MMNIF_POLL_BUDGET 0x100000 - -#define MMNIF_STATUS_FREE 0x00 -#define MMNIF_STATUS_PENDING 0x01 -#define MMNIF_STATUS_RDY 0x02 -#define MMNIF_STATUS_INPROC 0x03 -#define MMNIF_STATUS_PROC 0x04 - - -/* decide whether it's polling mode or not - */ -static int no_irq = 0; - -/* this will be set by open() and close() and shows wether the driver is running or not -*/ -static int active = 0; - -/* decide wheter it's uses locking or not - */ -static int disable_locking = 0; - -/* decide whether deliver work to a worker thread or instantly process all packets - */ -static int instant_process = 1; - -/* IP address of the local core and the router core to get packets forwarded - */ -static unsigned int own_ip_address = 0xC0A80000; /* 192.168.0.0 */ - -static unsigned int router_ip_address = 0xC0A80001; /* 192.168.0.1 */ - -/* "message passing buffer" specific constants: - * - start address - * - size - */ -char* mpb_start_address = NULL; -unsigned int mpb_size = NULL; - -/* - * the memory mapped network device - */ -static struct netif* mmnif_dev = NULL; - -/* thread variables */ -static tid_t worker_thread; -static tid_t polling_thread; - -typedef struct mmnif_device_stats -{ - /* device stats (granularity in packets): - * - recieve errors - * - recieve successes - * - recieved bytes - * - transmit errors - * - transmit successes - * - transmitted bytes - */ - unsigned int rx_err; - unsigned int rx; - - unsigned int rx_bytes; - - unsigned int tx_err; - unsigned int tx; - - unsigned int tx_bytes; - - /* Heuristics : - * - how many times an budget overflow occured - * - how many times the polling thread polled without recieving a new message - * - how many messages are recieved via interrupt - * - how many messages are recieved via the polling thread - */ - unsigned int bdg_overflow; - unsigned int pll_empty; - unsigned int rx_intr; - unsigned int rx_poll; - -} mmnif_device_stats_t; - -/* receive descror structure */ -typedef struct rx_desc -{ - uint8_t stat; - uint16_t len; - uint32_t addr; - -} rx_desc_t; - -/* receive ring buffer structure */ -typedef struct mm_rx_buffer -{ - /* iv_intr: inform via interrupt - * states whether the interface wants to recieve an interrupt for - * incoming packet - */ - uint16_t iv_intr; - /* memory "pseudo-ring/heap" - * packets are always in one single chunk of memory - * head : head of allocated memory region - * tail : tail of allocated memory region - */ - uint16_t head; - uint16_t tail; - spinlock_t rlock; - /* descritpor queue - * desc_table : descriptor table - * dcount : descriptor's free in queue - * dread : next descriptor to read - * dwrite : next descriptor to write - * dlock : lock to protect these members - */ - rx_desc_t desc_table[MMNIF_MAX_DESCRIPTORS]; - uint8_t dcount; - uint8_t dread; - uint8_t dwrite; - spinlock_t dlock; -} mm_rx_buffer_t; - -typedef struct mmnif -{ - struct mmnif_device_stats stats; - - /* Interface constants: - * - ehternet address - * - local ip address - */ - struct eth_addr* ethaddr; - uint32_t ipaddr; - - /* memory interaction variables: - * - transmit queue - * - pointer to transmit buffer - * - pointer to recive buffer - */ - uint8_t tx_queue; - uint8_t* tx_buff[MMNIF_TX_QUEUELEN]; - mm_rx_buffer_t* rx_buff; - - /* lock to protect members - */ - spinlock_t lock; - - /* - */ - sem_t com_poll; - -}mmnif_t; - - -#ifdef WIN32 -__inline int RCCE_ue(void){ -#ifndef RECV - return 1; -#else - return 0; -#endif -} -#endif - -/* - * memory maped interface helper functions - */ -#ifdef WIN32 -#define __MEMCPY(x,y,z) memcpy(x,y,z) -#else -#define __MEMCPY(x,y,z) memcpy(x,y,z) -#endif - -/* mmnif_device_schedule() : - * if there is no interupt used to indicate new packets - * this creates a polling thread which looks for data - * itself - */ -__inline int mmnif_device_schedule() -{ -#ifdef WIN32 - bthread_create(&polling_thread,NULL,mmnif_poll,NULL); - return NULL; -#else - create_kernel_task(&polling_thread,mmnif_poll,NULL, NORMAL_PRIO); - return NULL; -#endif -} - -/* trigger an interrupt on the remote processor - * so he knows there is a packet to read - */ -__inline int mmnif_trigger_irq(dest_ip) -{ -#ifdef WIN32 - return SetEvent(remote_process_event); -#else - int tmp, x, y, z, addr; - - int ue = dest_ip -1; - - z = Z_PID(RC_COREID[ue]); - x = X_PID(RC_COREID[ue]); - y = Y_PID(RC_COREID[ue]); - addr = CRB_ADDR(x,y) + (z==0 ? GLCFG0 : GLCFG1); - - // send interrupt to ue - do { - NOP1; - tmp=ReadConfigReg(addr); - } while(tmp & 2); - tmp |= 2; - SetConfigReg(addr, tmp); - - return 0; -#endif -} - -/* mmnif_get_device_stats(): Returns a copy of the - * current device - */ -mmnif_device_stats_t mmnif_get_device_stats(void) -{ - mmnif_device_stats_t stats = {0}; - - if(!mmnif_dev) - DEBUGPRINTF("mmnif_get_device_stats(): the device is not initialized yet.\n"); - else - stats = ((mmnif_t*)mmnif_dev->state)->stats; - - return stats; -} - -/* mmnif_print_stats(): Print the devices stats of the - * current device - */ -void mmnif_print_stats(void) -{ - mmnif_t* mmnif; - - if (!mmnif_dev) - { - DEBUGPRINTF("mmnif_print_stats(): the device is not initialized yet.\n"); - return; - } - - mmnif = (mmnif_t*)mmnif_dev->state; - - DEBUGPRINTF("/dev/mmnif - stats:\n"); - DEBUGPRINTF("Received: %d packets successfull\n",mmnif->stats.rx); - DEBUGPRINTF("Received: %d bytes\n",mmnif->stats.rx_bytes); - DEBUGPRINTF("interrupts: %d\n",mmnif->stats.rx_intr); - DEBUGPRINTF("polling: %d\n",mmnif->stats.rx_poll); - DEBUGPRINTF("Received: %d packets containuing errors\n",mmnif->stats.rx_err); - DEBUGPRINTF("Transmitted: %d packests successfull\n",mmnif->stats.tx); - DEBUGPRINTF("Transmitted: %d bytes\n",mmnif->stats.tx_bytes); - DEBUGPRINTF("Transmitted: %d packests were dropped due to errors\n",mmnif->stats.tx_err); - -} - - -/* - * memory maped interface main functions - */ - -/* mmnif_get_destination(): low level transmid helper function - * this function deals with some HW details, it checks to wich core this packet - * should be routed and returns the destination - */ - -uint8_t mmnif_get_destination(struct netif* netif, struct pbuf* p) -{ - struct ip_hdr* iphdr; - uint8_t core; - uint8_t* ip4addr; - uint8_t addr[4]; - uint32_t netmask = 0xFFFFFF00; - - /* grab the destination ip address out of the ip header - * for internal routing the last ocet is interpreted as core ID. - */ - - iphdr = (struct ip_hdr*)(p->payload); - ip4addr = &iphdr->dest.addr; - - /* revert the address to host format */ - addr[3] = ip4addr[0]; addr[2] = ip4addr[1]; - addr[1] = ip4addr[2]; addr[0] = ip4addr[3]; - - /* check if the ip address is in the Local Area Network of the 48 cores */ - - /* if it's not the same network the router core is addressed - * Note: the router core is core 1 - */ - - if (!((netmask & *(uint32_t*)addr) == (netmask & own_ip_address) )) - return 1; - - core = addr[0]; - - /* check if the address is legitimata else return router core again */ - if ((core) < 1 || (core > MMNIF_CORES)) - core = 1; - - return core; -} - -/* mmnif_rxbuff_alloc(): - * this function allocates a continues chunk of memory - * right inside of the buffer which is used for communication - * with the remote end - */ -uint32_t mmnif_rxbuff_alloc(uint8_t dest,uint16_t len) -{ - mm_rx_buffer_t* rb = (mm_rx_buffer_t*)((char*)mpb_start_address + ( dest -1 ) * mpb_size); - char* memblock = (char*)rb + sizeof(mm_rx_buffer_t); - - uint32_t ret; - - spinlock_lock(&rb->dlock); - - if (rb->dcount) - { - if (rb->tail > rb->head) - { - if (MMNIF_RX_BUFFERLEN - rb->tail > len) - { - rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; - ret = memblock + rb->tail; - rb->desc_table[rb->dwrite].addr = ret; - rb->desc_table[rb->dwrite].len = len; - rb->dcount--; - rb->dwrite = (++rb->dwrite)%MMNIF_MAX_DESCRIPTORS; - - rb->tail = (rb->tail + len); - spinlock_unlock(&rb->dlock); - return ret; - } - else if (rb->head > len) - { - rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; - ret = memblock; - rb->desc_table[rb->dwrite].addr = ret; - rb->desc_table[rb->dwrite].len = len; - rb->dcount--; - rb->dwrite = (++rb->dwrite)%MMNIF_MAX_DESCRIPTORS; - - rb->tail = len; - spinlock_unlock(&rb->dlock); - return ret; - } - else - { - spinlock_unlock(&rb->dlock); - return NULL; - } - } - else - { - if (rb->head - rb->tail > len) - { - rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; - ret = memblock + rb->tail; - rb->desc_table[rb->dwrite].addr = ret; - rb->desc_table[rb->dwrite].len = len; - rb->dcount--; - rb->dwrite = (++rb->dwrite)%MMNIF_MAX_DESCRIPTORS; - - rb->tail = (rb->tail + len); - spinlock_unlock(&rb->dlock); - return ret; - } - else if (rb->tail == rb->head) - { - if (MMNIF_RX_BUFFERLEN - rb->tail < len) - { - rb->tail = 0; - if (rb->dread == rb->dwrite) - rb->head = 0; - } - - rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; - ret = memblock + rb->tail; - rb->desc_table[rb->dwrite].addr = ret; - rb->desc_table[rb->dwrite].len = len; - rb->dcount--; - rb->dwrite = (++rb->dwrite)%MMNIF_MAX_DESCRIPTORS; - - rb->tail = (rb->tail + len); - spinlock_unlock(&rb->dlock); - return ret; - } - else - { - spinlock_unlock(&rb->dlock); - return NULL; - } - } - } - else - { - spinlock_unlock(&rb->dlock); - return NULL; - } -} - -/* mmnif_commit_packet: this function set the state of the (in advance) - * allocated packet to RDY so the recieve queue knows that it can be - * processed further - */ -int mmnif_commit_packet(uint8_t dest,uint32_t addr) -{ - mm_rx_buffer_t* rb = (mm_rx_buffer_t*)((char*)mpb_start_address + ( dest -1 ) * mpb_size); - uint32_t i; - - for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) - { - if (rb->desc_table[i].addr == addr && rb->desc_table[i].stat == MMNIF_STATUS_PENDING) - { - rb->desc_table[i].stat = MMNIF_STATUS_RDY; - return 0; - } - } - return -1; -} - -/* mmnif_rxbuff_free() : the opposite to mmnif_rxbuff_alloc() a from the receiver - * already processed chunk of memory is freed so that it can be allocated again - */ -void mmnif_rxbuff_free(void) -{ - mmnif_t* mmnif = mmnif_dev->state; - mm_rx_buffer_t* b = mmnif->rx_buff; - uint32_t i,j; - uint32_t rpos; - - spinlock_lock(&b->dlock); - - rpos = b->dread; - - for (i = 0, j = rpos; i < MMNIF_MAX_DESCRIPTORS; i++) - { - j = (j+i)%MMNIF_MAX_DESCRIPTORS; - - if (b->desc_table[j].stat == MMNIF_STATUS_PROC) - { - b->dcount++; - b->dread = (b->dread +1)%MMNIF_MAX_DESCRIPTORS; - b->desc_table[j].stat = MMNIF_STATUS_FREE; - - if (b->tail > b->head) - { - b->head += b->desc_table[j].len; - } - else - { - if ( (b->desc_table[(j+1)%MMNIF_MAX_DESCRIPTORS].stat != MMNIF_STATUS_FREE ) - && ( b->desc_table[j].addr > b->desc_table[(j+1)%MMNIF_MAX_DESCRIPTORS].addr)) - { - b->head = 0; - - } - else - { - b->head += b->desc_table[j].len; - } - } - } - else - break; - } - - spinlock_unlock(&b->dlock); -} -/* - * Transmid a packet (called by the lwip) - */ -err_t mmnif_tx(struct netif* netif, struct pbuf* p) -{ - mmnif_t* mmnif = netif->state; - uint8_t slot = mmnif->tx_queue; - - uint32_t write_address; - uint32_t i; - struct pbuf* q; /* interator */ - - uint8_t build_buff = TRUE; - uint32_t dest_ip = mmnif_get_destination(netif,p); - - mm_rx_buffer_t* rb = (mm_rx_buffer_t*)((char*)mpb_start_address + ( dest_ip -1 ) * mpb_size); - -#ifdef WIN32 - ReadProcessMemory(hProc, (char*)mpb_start_address + ( dest_ip -1 ) * mpb_size, (char*)mpb_start_address + ( dest_ip -1 ) * mpb_size,mpb_size,NULL); - WaitForSingleObject(remote_process_mutex,INFINITE); -#endif - - spinlock_lock(&mmnif->lock); - mmnif->tx_queue++; - spinlock_unlock(&mmnif->lock); - - - /* Perform serveral sanity checks on the packet and the buffers: - * - is the queue full? - * - is the output packet to big? - */ - - if (mmnif->tx_queue > MMNIF_TX_QUEUELEN) - { - DEBUGPRINTF("mmnif_tx(): too many packets at once for tx_queue\n"); - goto drop_packet; - } - - if (p->tot_len > MMNIF_TX_BUFFERLEN) - { - DEBUGPRINTF("mmnif_tx(): packet is longer than %d bytes\n",MMNIF_TX_BUFFERLEN); - goto drop_packet; - } - - /* check if the pbuf consists only of one element - * if that is the case it would be much overhead - * copying that packet again - */ - if (!p->next) - build_buff = FALSE; - - if (build_buff) - { - /* build the payload out of the p's - * ensure that the packet is in one memory chunk stored in the transmid buffer - */ - for (q = p, i = 0; q != 0; q = q->next) - { - memcpy(mmnif->tx_buff[slot] + i, q->payload, q->len); - i += q->len; - } - } - - /* allocate memory for the packet in the remote buffer */ - - write_address = mmnif_rxbuff_alloc(dest_ip,p->tot_len); - - if (!write_address) - goto drop_packet; - - /* write buffer to buffer & increment the queued packet count - * this can be safely done without locking because this place is - * reserved for us because it has the status "pending" - */ - if (build_buff) - memcpy(write_address,mmnif->tx_buff[slot],p->tot_len); - else - memcpy(write_address,p->payload,p->tot_len); - - - if (mmnif_commit_packet(dest_ip,write_address)) - { - DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); - } - -#ifdef DEBUG_MMNIF_PACKET - DEBUGPRINTF("\n SEND 0x%.8X with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); - hex_dump(p->tot_len, p->payload); -#endif - - /* release the tx_queue because it's finished */ - spinlock_lock(&mmnif->lock); - mmnif->tx_queue--; - spinlock_unlock(&mmnif->lock); - - /* just gather some stats */ - LINK_STATS_INC(link.xmit); - - mmnif->stats.tx++; - mmnif->stats.tx_bytes += p->tot_len; - -#ifdef WIN32 - WriteProcessMemory(hProc, (char*)mpb_start_address + ( dest_ip -1 ) * mpb_size, (char*)mpb_start_address + ( dest_ip -1 ) * mpb_size,mpb_size,NULL); - SetEvent(remote_process_event); - ReleaseMutex(remote_process_mutex); -#endif - - if (rb->iv_intr) - mmnif_trigger_irq(dest_ip); - - return ERR_OK; - -drop_packet: - /* drop packet for one or another reason - */ - spinlock_lock(&mmnif->lock); - mmnif->tx_queue--; - spinlock_unlock(&mmnif->lock); - - LINK_STATS_INC(link.drop); - mmnif->stats.tx_err++; - -#ifdef WIN32 - WriteProcessMemory(hProc, (char*)mpb_start_address + ( dest_ip -1 ) * mpb_size,(char*)mpb_start_address + ( dest_ip -1 ) * mpb_size,mpb_size,NULL); -#endif - - return ERR_IF; -} - -/* mmnif_link_layer(): wrapper function called by ip_output() - * adding all needed headers for the link layer - * because we have no link layer and everything is reliable we don't need - * to add anything so we just pass it to our tx function - */ -static void mmnif_link_layer(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) -{ - netif->linkoutput(netif,q); -} - -/* - * Init the device (called from lwip) - * It's invoked in netif_add - */ -err_t mmnif_init(struct netif* netif) -{ - mmnif_t* mmnif; - uint32_t i; - int num = 0; - - /* Alloc and clear memory for the device struct - */ - mmnif = kmalloc(sizeof(mmnif_t)); - - if (!mmnif) - { - DEBUGPRINTF("mmnif init():out of memory\n"); - return ERR_MEM; - } - memset(mmnif, 0, sizeof(mmnif_t)); - - /* Alloc and clear shared memory for rx_buff - */ - mpb_size = (sizeof(mm_rx_buffer_t) + MMNIF_RX_BUFFERLEN); - // align mpb size to the granularity of a page size - mpb_size = (mpb_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - mpb_start_address = RCCE_shmalloc(mpb_size*MMNIF_CORES); - // map physical address in the virtual address space - mpb_start_address = map_region(0, mpb_start_address, mpb_size >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); - - mmnif->rx_buff = mpb_start_address + (mpb_size) * (own_ip_address - router_ip_address); - if (!(mpb_start_address)) - { - DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); - return ERR_MEM; - } - memset(mmnif->rx_buff, 0, mpb_size); - - /* set initial values - */ - mmnif->rx_buff->dcount = MMNIF_MAX_DESCRIPTORS; - - /* init the lock's for the hdr - */ - - spinlock_init(&mmnif->rx_buff->rlock); - spinlock_init(&mmnif->rx_buff->dlock); - - spinlock_init(&mmnif->lock); - - /* init the sems for communication art - */ - sem_init(&mmnif->com_poll,1); - - /* since there is no possibilty to create a full semaphore we just block it manually - */ - sem_wait(&mmnif->com_poll,0); - - /* inform via interrupt should be the dafault - */ - if (!no_irq) - mmnif->rx_buff->iv_intr = TRUE; - - /* Alloc and clear internal memory for tx_buff - */ - mmnif->tx_buff[0] = kmalloc(MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); - - if (!(mmnif->tx_buff[0])) - { - DEBUGPRINTF("mmnif init: out of memory tx\n"); - return ERR_MEM; - } - mmnif->tx_queue = 0; - memset(mmnif->tx_buff[0], 0, MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); - - for (i = 0; i < MMNIF_TX_QUEUELEN -1 ; i++) - mmnif->tx_buff[i+1] = mmnif->tx_buff[i] + MMNIF_TX_BUFFERLEN; - - /* pass the device state to lwip */ - netif->state = mmnif; - mmnif_dev = netif; - - /* administrative details */ - netif->name[0] = 'e'; - netif->name[1] = 'n'; - netif->num = num; - num++; - /* downward functions */ - netif->output = mmnif_link_layer; - /* there is no special link layer just the ip layer */ - netif->linkoutput = mmnif_tx; - /* maximum transfer unit */ - netif->mtu = 1500; - /* broadcast capability, keep all default flags*/ - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP; - /* hardware address length */ - netif->hwaddr_len = 6; - - active = TRUE; - -#ifdef MMNIF_DEBUG - DEBUGPRINTF("mmnif init complete\n"); -#endif - - return NULL; -} - -/* - * Receive a packet : recieve, pack it up and pass over to higher levels - */ -static void mmnif_rx(struct netif* netif) -{ - mmnif_t* mmnif = netif->state; - mm_rx_buffer_t* b = mmnif->rx_buff; - - uint16_t length; - struct pbuf* p = NULL; - struct pbuf* q; - char* packet; - - uint32_t i,j; - uint8_t rdesc = 0xFF; - - err_t err = NULL; - -#ifdef WIN32 - ReadProcessMemory(hProc, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size,mpb_size,NULL); - WaitForSingleObject(own_process_mutex,INFINITE); -#endif - - spinlock_lock(&b->rlock); - - /* check if this call to mmnif_rx makes any sense - */ - if (b->desc_table[b->dread].stat == MMNIF_STATUS_FREE) - { - spinlock_unlock(&b->rlock); -#ifdef WIN32 - WriteProcessMemory(hProc, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size,mpb_size,NULL); -#endif - return; - } - - /* search the packet whose transmission is finished - */ - for (i = 0,j = b->dread; i < MMNIF_MAX_DESCRIPTORS; i++) - { - if (b->desc_table[(j + i)% MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_RDY) - { - rdesc = (j + i)% MMNIF_MAX_DESCRIPTORS; - b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; - packet = (char*)b->desc_table[rdesc].addr; - length = b->desc_table[rdesc].len; - break; - } - } - - spinlock_unlock(&b->rlock); - - /* if there is no packet finished we encountered a random error - */ - if (rdesc == 0xFF) - { -#ifdef WIN32 - WriteProcessMemory(hProc, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size,mpb_size,NULL); -#endif - return; - } - - /* If length is zero return silently - */ - if (length == 0) - { - DEBUGPRINTF("mmnif_rx(): empty packet error\n"); - return; - } - if (length < sizeof(struct ip_hdr) ||length > netif->mtu) - { - DEBUGPRINTF("mmnif_rx(): illegal packet length %d => drop the packet\n",length); - goto drop_packet; - } - - /* From now on there is a real packet and it - * has to be worked on - */ - - #ifdef DEBUG_MMNIF_PACKET - DEBUGPRINTF("\n RECIEVED - 0x%.8X with legth: %d\n",packet,length); - hex_dump(length,packet); - #endif - - /* Build the pbuf for the packet so the lwip - * and other higher layer can handle it - */ - p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); - if (!p) - { - DEBUGPRINTF("mmnif_rx(): low on mem - packet dropped\n"); - goto drop_packet; - } - - /* copy packet to pbuf structure going through linked list */ - for (q=p, i = 0; q!=NULL; q=q->next) - { - memcpy((uint8_t*)q->payload,&packet[i],q->len); - i +=q->len; - } - - /* indicate that the copy process is done and the packet can be freed - * note that we did not lock here because we are the only one editing this value - */ - mmnif->rx_buff->desc_table[rdesc].stat = MMNIF_STATUS_PROC; - - /* everything is copied to a new buffer so it's save to release - * the old one for new incoming packets - */ - - mmnif_rxbuff_free(); - - /* full packet send to tcpip_thread to process */ - if ((err = mmnif_dev->input(p, mmnif_dev)) != ERR_OK) - { - DEBUGPRINTF("mmnif_rx: IP input error\n"); - pbuf_free(p); - } - - /* gather some stats and leave the rx handler */ - LINK_STATS_INC(link.xmit); - mmnif->stats.rx++; - - mmnif->stats.rx_bytes += p->tot_len; - - if (mmnif->rx_buff->iv_intr) - mmnif->stats.rx_intr++; - else - mmnif->stats.rx_poll++; - -#ifdef WIN32 - WriteProcessMemory(hProc, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size,mpb_size,NULL); - ReleaseMutex(own_process_mutex); -#endif - - return; - -drop_packet: - - spinlock_lock(&mmnif->rx_buff->rlock); - /*error handling*/ - spinlock_unlock(&mmnif->rx_buff->rlock); - - LINK_STATS_INC(link.drop); - mmnif->stats.rx_err++; - -#ifdef WIN32 - WriteProcessMemory(hProc, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size, (char*)mpb_start_address + ( !((own_ip_address && 0xFF)-1) ) * mpb_size,mpb_size,NULL); -#endif - return; -} -/* mmnif_irqhandler(): - * handles the incomint interrupts - */ -void mmnif_irqhandler(void) -{ - mmnif_t* mmnif; - - /* return if mmnif_dev is not yet initialized*/ - if (!mmnif_dev) - { - DEBUGPRINTF("mmnif_irqhandler(): the driver is not initialized yet\n"); - return; - } - - mmnif = (mmnif_t*) mmnif_dev->state; - - while (mmnif->rx_buff->dcount < MMNIF_MAX_DESCRIPTORS) - { - mmnif_rx(mmnif_dev); - -// if (instant_process) -// mmnif_wait(mmnif_dev,1,MMNIF_WORKER_BUDGET); - } -} -/* - * the poll function wich is used if no interrupt wake up our mmnif_rx functions - */ -int mmnif_poll(void* e) -{ - mmnif_t* mmnif; - - if (!mmnif_dev) - { - DEBUGPRINTF("mmnif_poll(): the driver is not initialized yet\n"); - return -1; - } - - mmnif = (mmnif_t*) mmnif_dev->state; - -#ifdef DEBUG_MMNIF - DEBUGPRINTF("mmnif_poll(): polling thread launched",mmnif->rx_buff); -#endif - - if (!no_irq) - { - sem_wait(&mmnif->com_poll,0); - } - - /*run while driver is up*/ - while (active) - { - while (!mmnif->rx_buff->dcount == MMNIF_MAX_DESCRIPTORS) - { - mmnif->stats.pll_empty++; - if (mmnif->stats.pll_empty >= MMNIF_POLL_BUDGET) - { - /* enable interrupts and suspend polling - * - */ - mmnif->rx_buff->iv_intr = TRUE; - mmnif->stats.pll_empty = 0; -#ifdef DEBUG_MMNIF - DEBUGPRINTF("mmnif_poll(): heuristical interrupts enabled\n"); -#endif - sem_wait(&mmnif->com_poll,0); - } - /* uncomment this to test only polling - */ - // mmnif->stats.pll_empty = 0; - } - - mmnif->stats.pll_empty=0; - mmnif_rx(mmnif_dev); - - } - - return NULL; -} -/* - * Open the interface should be called by kernel to use this network interface - */ -int mmnif_open(void) -{ - struct ip_addr ipaddr; - struct ip_addr netmask; - struct ip_addr gw; - - /* calculate my own ip address from core number - * Note: core 1 is the router core - */ - IP4_ADDR(&gw, 0,0,0,0); - IP4_ADDR(&ipaddr, 192,168,0,RCCE_ue() +1); - IP4_ADDR(&netmask, 255,255,255,0); - - own_ip_address+= RCCE_ue() +1; - - mmnif_dev = kmalloc(sizeof(struct netif)); - - /* register our Memory Mapped Virtual IP interface in the lwip stack - * and tell him how to use the interface: - * - mmnif_dev : the device data storage - * - ipaddr : the ip address wich should be used - * - gw : the gateway wicht should be used - * - mmnif_init : the initialization which has to be done in order to use our interface - * - ethernet_input : tells him that he should get ethernet input (inclusice ARP) - * - * Note: Ethernet Input will be removed because its NOT needed and will - * be replaced with ip_input - */ - if (!netif_add(mmnif_dev, &ipaddr, &netmask, &gw, NULL,(netif_init_fn)mmnif_init, tcpip_input)) - { - DEBUGPRINTF("mmnif_open() : unable to add network interface\n"); - return -1; - } - - /* set our network interface to the default interface for lwip*/ - //netif_set_default(mmnif_dev); - /* tell lwip all initialization is done and we want to set it ab*/ - netif_set_up(mmnif_dev); - - /* test if interface is really up */ - if (!netif_is_up(mmnif_dev)) - { - DEBUGPRINTF("mmnif_open(): network interface is not up\n"); - return -2; - } - - /* indicate that the driver is active now*/ - active = TRUE; - - /* If interrupts are not used we immediately add the polling function - * to the queue which would otherwise be done through the IRQ handler. - */ - mmnif_device_schedule(); - - /* Start the device worker thread wich actually processes the incoming - * packet's this is not done in the "interrupt handler" to shorten them up - */ -// if (!instant_process) -// mmnif_worker_schedule(); - - - // mmnif_retrigger_schedule(); - -#ifdef DEBUG_MMNIF - DEBUGPRINTF("mmnif_dev is open\n"); -#endif - - return 0; - -} - -/* - * close the interface should be called by kernel to close this interface and release resources - * Note: it's temporarly empty. Support will be added. - */ -int mmnif_close(void) -{ - size_t phyaddr; - - mmnif_t* mmnif; - - if (!mmnif_dev) - { - DEBUGPRINTF("mmnif_close(): you closed the device before it was properly opened -.-* \n"); - } - - mmnif = (mmnif_t*)mmnif_dev->state; - /* indicate that the driver is not active anymore - * - this will stop the polling thread i.e. - */ - - active = FALSE; - - kfree(mmnif->tx_buff[0],MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); - kfree(mmnif_dev,sizeof(mmnif_t)); - - // determine physical address - phyaddr = virt_to_phys(mpb_start_address); - // unmap shared memory regeion - unmap_region(mpb_start_address, mpb_size >> PAGE_SHIFT); - RCCE_shfree(phyaddr); - - return NULL; -} - -#endif +/* + * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + * + * mmnif.c --- memmory mapped interface + * + * Virutal IP Interface for the concept processor SCC + * + */ + +#include "mmnif.h" /* definitions */ + +#include /* lwip netif */ +#include /* inteface stats */ +#include /* ethernet arp packets */ +#include /* struct iphdr */ +#include /* tcpip_input() */ +#include + +//#include + +#include /* mailbox_ptr_t */ +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#define TRUE 1 +#define FALSE 0 + +#define DEBUGPRINTF(x,...) kprintf(x,##__VA_ARGS__) + +#define DEBUG_MMNIF +//#define DEBUG_MMNIF_PACKET + +// set to 1 if you want to enable the L1 cache for the receive buffers +#define USE_CACHE 0 + +// set to 1 if you want to use the message passing buffer +#define MMNIF_USE_MPB 0 + +/* Cache line wrappers */ +#define CLINE_SHIFT 5 +#define CLINE_SIZE (1UL << CLINE_SHIFT) +#define CLINE_MASK (~(CLINE_SIZE - 1)) +#define CLINE_ALIGN(_x) (((_x) + CLINE_SIZE - 1) & CLINE_MASK) +//#define CLINE_ALIGN(_x) (_x) + +#define MMNIF_AUTO_SOCKET_TIMEOUT 500 + +#define MMNIF_FAST_SOCKET_BLOCK 0 + +#ifdef DEBUG_MMNIF +#include "util.h" /* hex dump */ +#endif + +/* define constants + * regarding the driver & its configuration + */ + +#define MMNIF_TX_BUFFERLEN 2048 +#define MMNIF_TX_QUEUELEN 4 + +#define MMNIF_RX_BUFFERLEN 7*1024 +#define MMNIF_MAX_DESCRIPTORS 64 + +#define MMNIF_CORES 2 + +#define MMNIF_POLL_BUDGET 0x100000 +#define MMNIF_INTR_BUDGET 0x10 + +#define MMNIF_STATUS_FREE 0x00 +#define MMNIF_STATUS_PENDING 0x01 +#define MMNIF_STATUS_RDY 0x02 +#define MMNIF_STATUS_INPROC 0x03 +#define MMNIF_STATUS_INPROC_BYPASS 0x04 +#define MMNIF_STATUS_PROC 0x05 + +#define MMNIF_MAX_ACCEPTORS 0x20 +#define MMNIF_ACC_STAT_CLOSED 0x00 +#define MMNIF_ACC_STAT_ACCEPTING 0x01 +#define MMNIF_ACC_STAT_ACCEPT_ME 0x02 +#define MMNIF_ACC_STAT_ACCEPTED 0x03 + +#define MMNIF_HASHTABLE_SIZE 0x20 + +#define MMNIF_PSEUDO_SOCKET_START 0x31337 + +static int npseudosocket = MMNIF_PSEUDO_SOCKET_START; +static spinlock_t pseudolock; + +/* decide whether it's polling mode or not + */ +static int reduce_irq = 0; + +/* this will be set by open() and close() and shows wether the driver is running or not +*/ +static int active = 0; + +/* IP address of the local core and the router core to get packets forwarded + */ +static unsigned int own_ip_address = 0xC0A80000; /* 192.168.0.0 */ +static unsigned int router_ip_address = 0xC0A80001; /* 192.168.0.1 */ +//static unsigned int budget_overflow_count = 0; + +/* "message passing buffer" specific constants: + * - start address + * - size + */ +static char* header_start_address = NULL; +static unsigned int header_size = 0; +static char* heap_start_address = NULL; +static unsigned int heap_size = 0; + +/* + * the memory mapped network device + */ +static struct netif* mmnif_dev = NULL; + +/* thread variables */ +static tid_t polling_thread; + +/* accept struct + */ +typedef struct acceptor { + + /* stat: status of the acceptor + * src_ip: where did the connect request came from + * port: port on which the acceptor is listening + * alock : acceptor lock + * nsock : next pseudo socket which is used in further connection + * rsock : remote socket which has to be assosicated with the nsock + */ + uint8_t stat; + uint8_t src_ip; + uint16_t port; + spinlock_t alock; + int nsock; + int rsock; +} acceptor_t; + +/* bypass descriptor struct + */ +typedef struct bypass_rxdesc { + + /* socket : hashtarget + * remote_socket: socket on the remote end + * cnt : atomic counter for the recv function + * dest_ip : associated destination ip/core + */ + int socket; + int remote_socket; + sem_t sem; + atomic_int32_t cnt; + uint8_t dest_ip; +} bypass_rxdesc_t; + +/* + */ +static bypass_rxdesc_t mmnif_hashtable[MMNIF_HASHTABLE_SIZE]; +typedef struct mmnif_device_stats { + + /* device stats (granularity in packets): + * - recieve errors + * - recieve successes + * - recieved bytes + * - transmit errors + * - transmit successes + * - transmitted bytes + */ + unsigned int rx_err; + unsigned int rx; + unsigned int rx_bytes; + unsigned int tx_err; + unsigned int tx; + unsigned int tx_bytes; + + /* Heuristics : + * - how many times an budget overflow occured + * - how many times the polling thread polled without recieving a new message + * - how many messages are recieved via interrupt + * - how many messages are recieved via the polling thread + */ + unsigned int bdg_overflow; + unsigned int pll_empty; + unsigned int rx_intr; + unsigned int rx_poll; +} mmnif_device_stats_t; + +/* receive descror structure */ +typedef struct rx_desc { + + /* stat : status of the descriptor + * len : length of the packet + * addr : memory address of the packet + * fast_sock: (-1) if no socket is associated + * else the socket n of the fast socket + */ + uint8_t stat; + uint16_t len; + uint32_t addr; + uint32_t fast_sock; +} rx_desc_t; + +/* receive ring buffer structure */ +typedef struct mm_rx_buffer { + + /* iv_intr: inform via interrupt + * states whether the interface wants to recieve an interrupt for + * incoming packet + */ + uint16_t iv_intr; + + /* memory "pseudo-ring/heap" + * packets are always in one single chunk of memory + * head : head of allocated memory region + * tail : tail of allocated memory region + */ + uint16_t head; + uint16_t tail; + spinlock_t rlock; + + /* descritpor queue + * desc_table : descriptor table + * dcount : descriptor's free in queue + * dread : next descriptor to read + * dwrite : next descriptor to write + * dlock : lock to protect these members + */ + rx_desc_t desc_table[MMNIF_MAX_DESCRIPTORS]; + uint8_t dcount; + uint8_t dread; + uint8_t dwrite; + spinlock_t dlock; + + /* acceptors + * shared memory "hashtable" to realize + * fast socket accept/connect + */ + acceptor_t acceptors[MMNIF_MAX_ACCEPTORS]; +} mm_rx_buffer_t; + +typedef struct mmnif { + struct mmnif_device_stats stats; + + /* Interface constants: + * - ehternet address + * - local ip address + */ + struct eth_addr *ethaddr; + uint32_t ipaddr; + + /* memory interaction variables: + * - transmit queue + * - pointer to transmit buffer + * - pointer to recive buffer + */ + uint8_t tx_queue; + uint8_t *tx_buff[MMNIF_TX_QUEUELEN]; + mm_rx_buffer_t *rx_buff; + uint8_t *rx_heap; + + /* lock to protect members + */ + spinlock_t lock; + + /* semaphore to regulate polling vs. interrupts + */ + sem_t com_poll; +} mmnif_t; + +/* + * A write access, which cache line is not present, doesn't perform (on the + * current SCC architecture) a cache line fill. Therefore, the core writes + * in this case directly to the memory. + * + * The following function copies from the on-die memory (MPB) to the off-die + * memory and prefetchs its destintation. Therefore, the function avoids the + * bad behavior of a "write miss". + */ +inline static void *memcpy_get(void *dest, const void *src, size_t count) +{ + int h, i, j, k, l, m; + asm volatile ("cld;\n\t" + "1: cmpl $0, %%eax ; je 2f\n\t" + "movl (%%edi), %%edx\n\t" + "movl 0(%%esi), %%ecx\n\t" + "movl 4(%%esi), %%edx\n\t" + "movl %%ecx, 0(%%edi)\n\t" + "movl %%edx, 4(%%edi)\n\t" + "movl 8(%%esi), %%ecx\n\t" + "movl 12(%%esi), %%edx\n\t" + "movl %%ecx, 8(%%edi)\n\t" + "movl %%edx, 12(%%edi)\n\t" + "movl 16(%%esi), %%ecx\n\t" + "movl 20(%%esi), %%edx\n\t" + "movl %%ecx, 16(%%edi)\n\t" + "movl %%edx, 20(%%edi)\n\t" + "movl 24(%%esi), %%ecx\n\t" + "movl 28(%%esi), %%edx\n\t" + "movl %%ecx, 24(%%edi)\n\t" + "movl %%edx, 28(%%edi)\n\t" + "addl $32, %%esi\n\t" + "addl $32, %%edi\n\t" + "dec %%eax ; jmp 1b\n\t" + "2: movl %%ebx, %%ecx\n\t" + "movl (%%edi), %%edx\n\t" + "andl $31, %%ecx\n\t" + "rep ; movsb\n\t":"=&a" (h), "=&D"(i), "=&S"(j), + "=&b"(k), "=&c"(l), "=&d"(m):"0"(count / 32), + "1"(dest), "2"(src), "3"(count):"memory", "cc"); + return dest; +} + +/* + * In our kernel, we didn't want to use FPU registers. + * Therefore, we use standard memcpy routine + */ +inline static void *memcpy_put(void *dest, const void *src, size_t count) +{ + int32_t i, j, k; + if (BUILTIN_EXPECT(!dest || !src, 0)) + return dest; + asm volatile ("cld; rep movsl\n\t" + "movl %4, %%ecx\n\t" + "andl $3, %%ecx\n\t" + "rep movsb\n\t":"=&c" (i), "=&D"(j), + "=&S"(k):"0"(count / 4), "g"(count), "1"(dest), + "2"(src):"memory", "cc"); + return dest; +} + +/* + * memory maped interface helper functions + */ + +/* mmnif_device_schedule() : + * if there is no interupt used to indicate new packets + * this creates a polling thread which looks for data + * itself + */ +inline int mmnif_device_schedule() +{ + return create_kernel_task(&polling_thread, mmnif_poll, NULL, NORMAL_PRIO); +} + +/* trigger an interrupt on the remote processor + * so he knows there is a packet to read + */ +inline int mmnif_trigger_irq(dest_ip) +{ + int tmp, x, y, z, addr; + int ue = dest_ip - 1; + z = Z_PID(RC_COREID[ue]); + x = X_PID(RC_COREID[ue]); + y = Y_PID(RC_COREID[ue]); + addr = CRB_ADDR(x, y) + (z == 0 ? GLCFG0 : GLCFG1); + + // send interrupt to ue + do { + NOP1; + tmp = ReadConfigReg(addr); + } + while (tmp & 2); + tmp |= 2; + SetConfigReg(addr, tmp); + return 0; +} + +/* mmnif_get_device_stats(): Returns a copy of the + * current device + */ +mmnif_device_stats_t mmnif_get_device_stats() +{ + mmnif_device_stats_t stats = { + 0 + }; + if (!mmnif_dev) + DEBUGPRINTF + ("mmnif_get_device_stats(): the device is not initialized yet.\n"); + + else + stats = ((mmnif_t *) mmnif_dev->state)->stats; + return stats; +} + +/* mmnif_print_stats(): Print the devices stats of the + * current device + */ +void mmnif_print_stats() +{ + mmnif_t *mmnif; + if (!mmnif_dev) + { + DEBUGPRINTF + ("mmnif_print_stats(): the device is not initialized yet.\n"); + return; + } + mmnif = (mmnif_t *) mmnif_dev->state; + DEBUGPRINTF("/dev/mmnif - stats:\n"); + DEBUGPRINTF("Received: %d packets successfull\n", mmnif->stats.rx); + DEBUGPRINTF("Received: %d bytes\n", mmnif->stats.rx_bytes); + DEBUGPRINTF("interrupts: %d\n", mmnif->stats.rx_intr); + DEBUGPRINTF("polling: %d\n", mmnif->stats.rx_poll); + DEBUGPRINTF("Received: %d packets containuing errors\n", + mmnif->stats.rx_err); + DEBUGPRINTF("Transmitted: %d packests successfull\n", mmnif->stats.tx); + DEBUGPRINTF("Transmitted: %d bytes\n", mmnif->stats.tx_bytes); + DEBUGPRINTF("Transmitted: %d packests were dropped due to errors\n", + mmnif->stats.tx_err); +} + +/* mmnif_print_driver_status + * + */ +void mmnif_print_driver_status() +{ + mmnif_t *mmnif; + int i; + if (!mmnif_dev) + { + DEBUGPRINTF + ("mmnif_print_driver_status(): the device is not initialized yet.\n"); + return; + } + mmnif = (mmnif_t *) mmnif_dev->state; + DEBUGPRINTF("/dev/mmnif driver status: \n\n"); + DEBUGPRINTF("rx_buf: 0x%.8X\n", mmnif->rx_buff); + DEBUGPRINTF("free descriptors : %d\n\n", mmnif->rx_buff->dcount); + DEBUGPRINTF("descriptor table: (only print descriptors in use)\n"); + DEBUGPRINTF("status\taddr\tsize\n"); + for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) + { + if (mmnif->rx_buff->desc_table[i].stat != 0) + DEBUGPRINTF("0x%.2X\t0x%.8X\t%X\t\n", + mmnif->rx_buff->desc_table[i].stat, + mmnif->rx_buff->desc_table[i].addr, + mmnif->rx_buff->desc_table[i].len); + } + DEBUGPRINTF("\n\nretrive via interrupt : %d\n", + mmnif->rx_buff->iv_intr); + DEBUGPRINTF("ring heap start addr: 0x%.8X\n", + mmnif->rx_buff + sizeof(mm_rx_buffer_t)); + DEBUGPRINTF("head: 0x%X\ttail: 0x%X\n", mmnif->rx_buff->head, + mmnif->rx_buff->tail); + mmnif_print_stats(); +} + +/* + * memory maped interface main functions + */ + +/* mmnif_get_destination(): low level transmid helper function + * this function deals with some HW details, it checks to wich core this packet + * should be routed and returns the destination + */ +uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p) +{ + struct ip_hdr *iphdr; + uint8_t core; + uint8_t *ip4addr; + uint8_t addr[4]; + uint32_t netmask = 0xFFFFFF00; + + /* grab the destination ip address out of the ip header + * for internal routing the last ocet is interpreted as core ID. + */ + iphdr = (struct ip_hdr *)(p->payload); + ip4addr = (uint8_t*) &iphdr->dest.addr; + + /* revert the address to host format */ + addr[3] = ip4addr[0]; + addr[2] = ip4addr[1]; + addr[1] = ip4addr[2]; + addr[0] = ip4addr[3]; + + /* check if the ip address is in the Local Area Network of the 48 cores */ + + /* if it's not the same network the router core is addressed + * Note: the router core is core 1 + */ + if (!((netmask & *(uint32_t *) addr) == (netmask & own_ip_address))) + return 1; + core = addr[0]; + + /* check if the address is legitimata else return router core again */ + if ((core) < 1 || (core > MMNIF_CORES)) + core = 1; + return core; +} + +/* mmnif_rxbuff_alloc(): + * this function allocates a continues chunk of memory + * right inside of the buffer which is used for communication + * with the remote end + */ +uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len) +{ + mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size); + +#if MMNIF_USE_MPB + char *memblock = (char *)heap_start_address + (dest - 1) * 0x2000; +#else + char *memblock = (char *)heap_start_address + (dest - 1) * heap_size; +#endif + +// memblock = 0xC0000000 + ( dest -1 ) * heap_size; + uint32_t ret; + +// if (rb->tail > rb->head) +// if ((MMNIF_RX_BUFFERLEN - rb->tail < len)&&(rb->head < len)) +// return NULL; +// else +// if ((rb->head - rb->tail < len)&&(rb->tail != rb->head)) +// return NULL; + spinlock_lock(&rb->dlock); + if (rb->dcount) + { + if (rb->tail > rb->head) + { + if (MMNIF_RX_BUFFERLEN - rb->tail > len) + { + rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; + ret = (uint32_t) (memblock + rb->tail); + rb->desc_table[rb->dwrite].addr = ret; + rb->desc_table[rb->dwrite].len = len; + rb->dcount--; + rb->dwrite = (rb->dwrite + 1) % MMNIF_MAX_DESCRIPTORS; + rb->tail = (rb->tail + len); + spinlock_unlock(&rb->dlock); + return ret; + } else if (rb->head > len) { + rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; + ret = (uint32_t) memblock; + rb->desc_table[rb->dwrite].addr = ret; + rb->desc_table[rb->dwrite].len = len; + rb->dcount--; + rb->dwrite = (rb->dwrite + 1) % MMNIF_MAX_DESCRIPTORS; + rb->tail = len; + spinlock_unlock(&rb->dlock); + return ret; + } else { + spinlock_unlock(&rb->dlock); + return 0; + } + } else { + if (rb->head - rb->tail > len) + { + rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; + ret = (uint32_t) (memblock + rb->tail); + rb->desc_table[rb->dwrite].addr = ret; + rb->desc_table[rb->dwrite].len = len; + rb->dcount--; + rb->dwrite = (rb->dwrite + 1) % MMNIF_MAX_DESCRIPTORS; + rb->tail = (rb->tail + len); + spinlock_unlock(&rb->dlock); + return ret; + } else if (rb->tail == rb->head) { + if (MMNIF_RX_BUFFERLEN - rb->tail < len) + { + rb->tail = 0; + if (rb->dread == rb->dwrite) + rb->head = 0; + } + rb->desc_table[rb->dwrite].stat = MMNIF_STATUS_PENDING; + ret = (uint32_t) (memblock + rb->tail); + rb->desc_table[rb->dwrite].addr = ret; + rb->desc_table[rb->dwrite].len = len; + rb->dcount--; + rb->dwrite = (rb->dwrite + 1) % MMNIF_MAX_DESCRIPTORS; + rb->tail = (rb->tail + len); + spinlock_unlock(&rb->dlock); + return ret; + } else { + spinlock_unlock(&rb->dlock); + return 0; + } + } + } else { + spinlock_unlock(&rb->dlock); + return 0; + } +} + +/* mmnif_commit_packet: this function set the state of the (in advance) + * allocated packet to RDY so the recieve queue knows that it can be + * processed further + */ +int mmnif_commit_packet(uint8_t dest, uint32_t addr) +{ + mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size); + uint32_t i; + + for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) + { + if (rb->desc_table[i].addr == addr + && rb->desc_table[i].stat == MMNIF_STATUS_PENDING) + { + rb->desc_table[i].stat = MMNIF_STATUS_RDY; + rb->desc_table[i].fast_sock = -1; + return 0; + } + } + + return -1; +} + +/* mmnif_commit_packet: this function set the state of the (in advance) + * allocated packet to RDY so the recieve queue knows that it can be + * processed further + */ +int mmnif_commit_packet_bypass(uint8_t dest, uint32_t addr, int dest_socket) +{ + mm_rx_buffer_t *rb = + (mm_rx_buffer_t *) ((char *)header_start_address + + (dest - 1) * header_size); + uint32_t i; + for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) + { + if (rb->desc_table[i].addr == addr + && rb->desc_table[i].stat == MMNIF_STATUS_PENDING) + { + rb->desc_table[i].stat = MMNIF_STATUS_RDY; + rb->desc_table[i].fast_sock = dest_socket; + return 0; + } + } + return -1; +} + +/* mmnif_rxbuff_free() : the opposite to mmnif_rxbuff_alloc() a from the receiver + * already processed chunk of memory is freed so that it can be allocated again + */ +void mmnif_rxbuff_free() +{ + mmnif_t *mmnif = mmnif_dev->state; + mm_rx_buffer_t *b = mmnif->rx_buff; + uint32_t i, j; + uint32_t rpos; + spinlock_lock(&b->dlock); + rpos = b->dread; + for (i = 0, j = rpos; i < MMNIF_MAX_DESCRIPTORS; i++) + { + j = (j + i) % MMNIF_MAX_DESCRIPTORS; + if (b->desc_table[j].stat == MMNIF_STATUS_PROC) + { + b->dcount++; + b->dread = (b->dread + 1) % MMNIF_MAX_DESCRIPTORS; + b->desc_table[j].stat = MMNIF_STATUS_FREE; + if (b->tail > b->head) + { + b->head += b->desc_table[j].len; + } + + else + { + if ((b-> + desc_table[(j + + 1) % + MMNIF_MAX_DESCRIPTORS].stat != + MMNIF_STATUS_FREE) + && (b->desc_table[j].addr > + b->desc_table[(j + 1) % + MMNIF_MAX_DESCRIPTORS]. + addr)) + { + b->head = 0; + } + + else + { + b->head += b->desc_table[j].len; + } + } + } + + else + break; + } + spinlock_unlock(&b->dlock); +} + +/* + * Transmid a packet (called by the lwip) + */ +err_t mmnif_tx(struct netif *netif, struct pbuf *p) +{ + mmnif_t *mmnif = netif->state; + uint8_t slot = mmnif->tx_queue; + uint32_t write_address; + uint32_t i; + struct pbuf *q; /* interator */ + uint8_t build_buff = TRUE; + uint32_t dest_ip = mmnif_get_destination(netif, p); + //uint8_t chances = 20; + mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest_ip - 1) * header_size); + + spinlock_lock(&mmnif->lock); + mmnif->tx_queue++; + spinlock_unlock(&mmnif->lock); + + /* Perform serveral sanity checks on the packet and the buffers: + * - is the queue full? + * - is the output packet to big? + */ + if (mmnif->tx_queue > MMNIF_TX_QUEUELEN) + { + DEBUGPRINTF("mmnif_tx(): too many packets at once for tx_queue\n"); + goto drop_packet; + } + if (p->tot_len > MMNIF_TX_BUFFERLEN) + { + DEBUGPRINTF("mmnif_tx(): packet is longer than %d bytes\n",MMNIF_TX_BUFFERLEN); + goto drop_packet; + } + + /* check if the pbuf consists only of one element + * if that is the case it would be much overhead + * copying that packet again + */ + if (!p->next) + build_buff = FALSE; + + if (build_buff) + { + + /* build the payload out of the p's + * ensure that the packet is in one memory chunk stored in the transmid buffer + */ + for (q = p, i = 0; q != 0; q = q->next) + { + memcpy(mmnif->tx_buff[slot] + i, q->payload, q->len); + i += q->len; + } + } + + /* allocate memory for the packet in the remote buffer */ +realloc: + write_address = mmnif_rxbuff_alloc(dest_ip, CLINE_ALIGN(p->tot_len)); + if (!write_address) + { + +// DEBUGPRINTF("mmnif_tx(): concurrency"); + +// if (!chances) +// goto drop_packet; + +// chances--; +// // udelay(exp_delay); +// // exp_delay << 1; +// // reschedule(); +// // NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8; +// udelay(20000); +// mmnif_trigger_irq(dest_ip); + goto realloc; + } + if (!write_address) + goto drop_packet; + + /* write buffer to buffer & increment the queued packet count + * this can be safely done without locking because this place is + * reserved for us because it has the status "pending" + */ + +#if MMNIF_USE_MPB + asm volatile (".byte 0x0f; .byte 0x0a;\n"); + +#endif + if (build_buff) +#if MMNIF_USE_MPB + memcpy_put(write_address, mmnif->tx_buff[slot], CLINE_ALIGN(p->tot_len)); +#else + memcpy((void*)write_address, mmnif->tx_buff[slot], CLINE_ALIGN(p->tot_len)); + +#endif + else +#if MMNIF_USE_MPB + memcpy_put(write_address, p->payload, CLINE_ALIGN(p->tot_len)); + +#else + memcpy((void*)write_address, p->payload, CLINE_ALIGN(p->tot_len)); + +#endif + + *((int *)RCCE_fool_write_combine_buffer) = 1; +#if USE_CACHE +#if MMNIF_USE_MPB + asm volatile (".byte 0x0f; .byte 0x0a;\n"); + +#endif +#endif + if (mmnif_commit_packet(dest_ip, write_address)) + { + DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); + } +#ifdef DEBUG_MMNIF_PACKET +// DEBUGPRINTF("\n SEND 0x%.8X with length: %d\n",(char*)heap_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); +// hex_dump(p->tot_len, p->payload); +#endif + + /* release the tx_queue because it's finished */ + spinlock_lock(&mmnif->lock); + mmnif->tx_queue--; + spinlock_unlock(&mmnif->lock); + + /* just gather some stats */ + LINK_STATS_INC(link.xmit); + mmnif->stats.tx++; + mmnif->stats.tx_bytes += p->tot_len; + if (rb->iv_intr) + mmnif_trigger_irq(dest_ip); + return ERR_OK; + +drop_packet: + /* drop packet for one or another reason + */ +#ifdef DEBUG_MMNIF + DEBUGPRINTF("mmnif_tx(): packet dropped"); + +#endif /* */ + spinlock_lock(&mmnif->lock); + mmnif->tx_queue--; + spinlock_unlock(&mmnif->lock); + LINK_STATS_INC(link.drop); + mmnif->stats.tx_err++; + return ERR_IF; +} + +/* mmnif_hashlookup(): looks up a bypass descriptor by + * the associated socket + */ +bypass_rxdesc_t *mmnif_hashlookup(int s) +{ + int i; + bypass_rxdesc_t *p; + + for (i=0, p = &mmnif_hashtable[s % MMNIF_HASHTABLE_SIZE]; isocket == s) + return p; + p = &mmnif_hashtable[(s + i + 1) % MMNIF_HASHTABLE_SIZE]; + } + return 0; +} + +/* mmnif_hashadd(): adds a entry to the hashtable + * by the socket + */ +int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip) +{ + bypass_rxdesc_t *p; + int i; + p = mmnif_hashlookup(sock); + if (p != 0) + return -1; + for (i = 0; i < MMNIF_HASHTABLE_SIZE; i++) + { + p = &mmnif_hashtable[(sock + i) % MMNIF_HASHTABLE_SIZE]; + if (p->socket == -1) + { + p->socket = sock; + p->remote_socket = rsock; + p->dest_ip = dest_ip; + return 0; + } + } + return -1; +} + +/* mmnif_hashdelete(): deletes an entry from the + * hashtable + */ +int mmnif_hashdelete(int sock) +{ + bypass_rxdesc_t *p; + int i; + p = mmnif_hashlookup(sock); + if (p != 0) + return -1; + for (i = 0; i < MMNIF_HASHTABLE_SIZE; i++) + { + p = &mmnif_hashtable[(sock + i) % MMNIF_HASHTABLE_SIZE]; + if (p->socket == sock) + { + p->socket = -1; + p->remote_socket = 0; + p->dest_ip = 0; + return 0; + } + } + return -1; +} + +/* + * Transmid a packet (with insane speed) + */ +err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, int s) +{ + mmnif_t *mmnif = netif->state; + uint32_t write_address; + bypass_rxdesc_t *dest = mmnif_hashlookup(s); + //uint32_t exp_delay = 2; + mm_rx_buffer_t *rb = + (mm_rx_buffer_t *) ((char *)header_start_address + + (dest->dest_ip - 1) * header_size); + + /* Perform serveral sanity checks on the packet and the buffers: + * - is the output packet to big? + */ + +// if (size > MMNIF_TX_BUFFERLEN) +// { +// DEBUGPRINTF("mmnif_tx(): packet is longer than %d bytes\n",MMNIF_TX_BUFFERLEN); +// goto drop_packet; +// } + + /* allocate memory for the packet in the remote buffer */ + realloc:write_address = + mmnif_rxbuff_alloc(dest->dest_ip, CLINE_ALIGN(size)); + if (!write_address) + { + + // DEBUGPRINTF("mmnif_tx_bypass(): concurrency"); + // udelay(exp_delay); + // exp_delay << 1; + // reschedule(); + NOP8; + NOP8; + NOP8; + NOP8; + NOP8; + NOP8; + NOP8; + NOP8; + goto realloc; + } + + /* write buffer to buffer & increment the queued packet count + * this can be safely done without locking because this place is + * reserved for us because it has the status "pending" + */ + +#if MMNIF_USE_MPB + asm volatile (".byte 0x0f; .byte 0x0a;\n"); +#endif + +#if MMNIF_USE_MPB + memcpy_put(write_address, pbuff, CLINE_ALIGN(size)); +#else + memcpy((void*) write_address, pbuff, CLINE_ALIGN(size)); +#endif + *((int *)RCCE_fool_write_combine_buffer) = 1; + +#if USE_CACHE +#if MMNIF_USE_MPB + asm volatile (".byte 0x0f; .byte 0x0a;\n"); + +#endif +#endif + if (mmnif_commit_packet_bypass(dest->dest_ip, write_address, dest->remote_socket)) + { + DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); + } +#ifdef DEBUG_MMNIF_PACKET + // DEBUGPRINTF("\n SEND 0x%.8X with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); + // hex_dump(p->tot_len, p->payload); +#endif + + /* just gather some stats */ + LINK_STATS_INC(link.xmit); + mmnif->stats.tx++; + mmnif->stats.tx_bytes += size; + if (rb->iv_intr) + mmnif_trigger_irq(dest->dest_ip); + return ERR_OK; +//drop_packet: + /* drop packet for one or another reason + */ + LINK_STATS_INC(link.drop); + mmnif->stats.tx_err++; + return ERR_IF; +} + +/* mmnif_send(): is going to be used as replacement of + * lwip_send with fast_sockets + */ +int mmnif_send(int s, void *data, size_t size, int flags) +{ + bypass_rxdesc_t *p = mmnif_hashlookup(s); + uint32_t i, j, k, ret; + if (p != 0) + { + if (size < ((MMNIF_RX_BUFFERLEN / 2) - 1)) + return mmnif_tx_bypass(mmnif_dev, data, size, s); + + else + { + j = size / (((MMNIF_RX_BUFFERLEN / 2) - 1)); + k = size - (j * (((MMNIF_RX_BUFFERLEN / 2) - 1))); + for (i = 0; i < j; i++) + { + ret = + mmnif_tx_bypass(mmnif_dev, + data + + i * + ((MMNIF_RX_BUFFERLEN / 2) - + 1), + ((MMNIF_RX_BUFFERLEN / 2) - + 1), s); + if (ret < 0) + return ret; + } + ret = + mmnif_tx_bypass(mmnif_dev, + data + (j - + 1) * ((MMNIF_RX_BUFFERLEN / + 2) - 1), k, s); + return ret; + } + } + return lwip_send(s, data, size, flags); +} + +/* mmnif_link_layer(): wrapper function called by ip_output() + * adding all needed headers for the link layer + * because we have no link layer and everything is reliable we don't need + * to add anything so we just pass it to our tx function + */ +static err_t +mmnif_link_layer(struct netif *netif, struct pbuf *q, ip_addr_t * ipaddr) +{ + return netif->linkoutput(netif, q); +} + +/* + * Init the device (called from lwip) + * It's invoked in netif_add + */ +err_t mmnif_init(struct netif *netif) +{ + mmnif_t *mmnif; + uint32_t i; + int num = 0; + int tmp1, tmp2, n; + +#ifdef DEBUG_MMNIF + DEBUGPRINTF("mmnif init attempt\n"); + +#endif /* */ + + /* Alloc and clear memory for the device struct + */ + mmnif = kmalloc(sizeof(mmnif_t)); + if (!mmnif) + { + DEBUGPRINTF("mmnif init():out of memory\n"); + return ERR_MEM; + } + memset(mmnif, 0, sizeof(mmnif_t)); + + /* Alloc and clear shared memory for rx_buff + */ + header_size = (sizeof(mm_rx_buffer_t)); + DEBUGPRINTF("mmnif_init() : size of mm_rx_buffer_t : %d", + sizeof(mm_rx_buffer_t)); + + // align mpb size to the granularity of a page size + header_size = (header_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + header_start_address = (void*) RCCE_shmalloc(header_size * MMNIF_CORES); + DEBUGPRINTF("RCCE_shmalloc : 0x%.8X", header_start_address); + + // map physical address in the virtual address space + header_start_address = (void*) map_region(0, (size_t) header_start_address, (MMNIF_CORES * header_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE); + DEBUGPRINTF("map_region : 0x%.8X", header_start_address); + mmnif->rx_buff = (mm_rx_buffer_t *) (header_start_address + (header_size) * (own_ip_address - router_ip_address)); + + /* Alloc and clear shared memory for rx_buff + */ + heap_size = (MMNIF_RX_BUFFERLEN); + + // align mpb size to the granularity of a page size + heap_size = (heap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + +#if MMNIF_USE_MPB + heap_start_address = RCCE_malloc(RCCE_LINE_SIZE); + DEBUGPRINTF("MessagePassingBuffer allocated @ : 0x%.8X\n", heap_start_address); + for (i = heap_size / RCCE_LINE_SIZE; i > 0; i--) + { + if (!RCCE_malloc(RCCE_LINE_SIZE)) ; + + { + + // DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); + // return ERR_MEM; + } + } + +#else /* */ + heap_start_address = (void*) RCCE_shmalloc(heap_size * MMNIF_CORES); + n = (int) heap_start_address; + DEBUGPRINTF("RCCE_shmalloc : 0x%.8X", header_start_address); + + // map physical address in the virtual address space +#if USE_CACHE + //heap_start_address = map_region(0, heap_start_address, (MMNIF_CORES*heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE); + heap_start_address = map_region(0, heap_start_address, (MMNIF_CORES * heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE | MAP_MPE); + remap_region(heap_start_address + + (heap_size) * (own_ip_address - router_ip_address), + n + (heap_size) * (own_ip_address - router_ip_address), 1, + MAP_KERNEL_SPACE | MAP_MPE); + +#else + heap_start_address = (void*) map_region(0, (size_t) heap_start_address, (MMNIF_CORES * heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE | MAP_MPE); + +#endif // USE_CAHCE +#endif // MMNIF_USE_MPB + DEBUGPRINTF("map_region : 0x%.8X", header_start_address); + +#if MMNIF_USE_MPB + mmnif->rx_heap = heap_start_address; + heap_start_address = + heap_start_address - (own_ip_address - router_ip_address) * 0x2000; + DEBUGPRINTF("heap_start_address : 0x%.8X", heap_start_address); + +// heap_start_address = 0xC0000000; +// mmnif->rx_heap = heap_start_address + (heap_size) * (own_ip_address - router_ip_address); +#else /* */ + mmnif->rx_heap = + heap_start_address + (heap_size) * (own_ip_address - + router_ip_address); + +#endif /* */ + if (!(heap_start_address)) + { + DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); + return ERR_MEM; + } + memset(mmnif->rx_buff, 0, header_size); + memset(mmnif->rx_heap, 0, heap_size); + +#if USE_CACHE + *((int *)RCCE_fool_write_combine_buffer) = 1; + +#endif /* */ + if (own_ip_address == router_ip_address) + { + kprintf("Test0: MEMCPY 2048B"); + tmp1 = get_clock_tick(); + for (n = 0; n < 4096; n++) + { + memcpy(mmnif->rx_heap + heap_size, mmnif->rx_heap, + 2048); + +#if USE_CACHE + *((int *)RCCE_fool_write_combine_buffer) = 1; + flush_cache(); + +#endif /* */ + memcpy(mmnif->rx_heap, mmnif->rx_heap, 2048); + } tmp2 = get_clock_tick(); + kprintf("memcpy'd' %d bytes in %d ticks", n * 2048, + (tmp2 - tmp1)); + } + + /* set initial values + */ + mmnif->rx_buff->dcount = MMNIF_MAX_DESCRIPTORS; + + /* init the lock's for the hdr + */ + spinlock_init(&mmnif->rx_buff->rlock); + spinlock_init(&mmnif->rx_buff->dlock); + spinlock_init(&pseudolock); + spinlock_init(&mmnif->lock); + + /* init the sems for communication art + */ + sem_init(&mmnif->com_poll, 0); + + /* inform via interrupt should be the dafault + */ + if (!reduce_irq) + mmnif->rx_buff->iv_intr = TRUE; + + /* Alloc and clear internal memory for tx_buff + */ + mmnif->tx_buff[0] = kmalloc(MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); + if (!(mmnif->tx_buff[0])) + { + DEBUGPRINTF("mmnif init: out of memory tx\n"); + return ERR_MEM; + } + mmnif->tx_queue = 0; + memset(mmnif->tx_buff[0], 0, MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); + for (i = 0; i < MMNIF_TX_QUEUELEN - 1; i++) + mmnif->tx_buff[i + 1] = mmnif->tx_buff[i] + MMNIF_TX_BUFFERLEN; + for (i = 0; i < MMNIF_HASHTABLE_SIZE; i++) + { + mmnif_hashtable[i].socket = -1; + mmnif_hashtable[i].remote_socket = -1; + mmnif_hashtable[i].dest_ip = 0; + +#if MMNIF_FAST_SOCKET_BLOCK + sem_init(&mmnif_hashtable[i].sem, 0); + +#endif /* */ + } + for (i = 0; i < MMNIF_MAX_ACCEPTORS; i++) + { + mmnif->rx_buff->acceptors[i].stat = MMNIF_ACC_STAT_CLOSED; + mmnif->rx_buff->acceptors[i].nsock = -1; + mmnif->rx_buff->acceptors[i].rsock = -1; + mmnif->rx_buff->acceptors[i].src_ip = 0; + mmnif->rx_buff->acceptors[i].port = 0; + spinlock_init(&mmnif->rx_buff->acceptors[i].alock); + spinlock_lock(&mmnif->rx_buff->acceptors[i].alock); + spinlock_unlock(&mmnif->rx_buff->acceptors[i].alock); + } + + /* pass the device state to lwip */ + netif->state = mmnif; + mmnif_dev = netif; + + /* administrative details */ + netif->name[0] = 'e'; + netif->name[1] = 'n'; + netif->num = num; + num++; + + /* downward functions */ + netif->output = mmnif_link_layer; + + /* there is no special link layer just the ip layer */ + netif->linkoutput = mmnif_tx; + + /* maximum transfer unit */ + netif->mtu = MMNIF_TX_BUFFERLEN; + + /* broadcast capability, keep all default flags */ + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP; + + /* hardware address length */ + netif->hwaddr_len = 0; + active = TRUE; + +#ifdef DEBUG_MMNIF + DEBUGPRINTF("mmnif init complete\n"); +#endif + return ERR_OK; +} + +/* + * Receive a packet : recieve, pack it up and pass over to higher levels + */ +static void mmnif_rx(struct netif *netif) +{ + mmnif_t *mmnif = netif->state; + mm_rx_buffer_t *b = mmnif->rx_buff; + uint16_t length = 0; + struct pbuf *p = NULL; + struct pbuf *q; + char *packet = NULL; + uint32_t i, j; + uint8_t rdesc = 0xFF; + err_t err = ERR_OK; + bypass_rxdesc_t *bp; + +anotherpacket: + spinlock_lock(&b->rlock); + + /* check if this call to mmnif_rx makes any sense + */ + if (b->desc_table[b->dread].stat == MMNIF_STATUS_FREE) + { + spinlock_unlock(&b->rlock); + return; + } + + /* search the packet whose transmission is finished + */ + for (i = 0, j = b->dread; i < MMNIF_MAX_DESCRIPTORS; i++) + { + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == + MMNIF_STATUS_RDY) + { + rdesc = (j + i) % MMNIF_MAX_DESCRIPTORS; + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS]. + fast_sock == -1) + { + b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; + packet = (char *)b->desc_table[rdesc].addr; + length = b->desc_table[rdesc].len; + break; + } + + else + { + bp = mmnif_hashlookup(b->desc_table[rdesc]. + fast_sock); + if (!bp) + { + DEBUGPRINTF + ("mmnif_rx(): no fast socket associated with %d", + b->desc_table[rdesc].fast_sock); + mmnif->rx_buff->desc_table[rdesc].stat = MMNIF_STATUS_PROC; + mmnif_rxbuff_free(); + } + + else + { + b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; + +#if MMNIF_FAST_SOCKET_BLOCK + sem_post(&bp->sem); + +#else + atomic_int32_inc(&bp->cnt); + +#endif + } + spinlock_unlock(&b->rlock); + return; + } + } + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_FREE) + { + spinlock_unlock(&b->rlock); + return; + } + } + spinlock_unlock(&b->rlock); + + /* if there is no packet finished we encountered a random error + */ + if (rdesc == 0xFF) + return; + + /* If length is zero return silently + */ + if (length == 0) + { + DEBUGPRINTF("mmnif_rx(): empty packet error\n"); + return; + } + if (length < sizeof(struct ip_hdr) || length > netif->mtu) + { + DEBUGPRINTF("mmnif_rx(): illegal packet length %d => drop the packet\n", length); + goto drop_packet; + } + + /* From now on there is a real packet and it + * has to be worked on + */ + +#ifdef DEBUG_MMNIF_PACKET + DEBUGPRINTF("\n RECIEVED - 0x%.8X with legth: %d\n", packet, length); + hex_dump(length, packet); + +#endif + + /* Build the pbuf for the packet so the lwip + * and other higher layer can handle it + */ + p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); + if (!p) + { + DEBUGPRINTF("mmnif_rx(): low on mem - packet dropped\n"); + goto drop_packet; + } +#if USE_CACHE + asm volatile (".byte 0x0f; .byte 0x0a;\n"); + +#endif /* */ + + /* copy packet to pbuf structure going through linked list */ + for (q = p, i = 0; q != NULL; q = q->next) + { + +#if MMNIF_USE_MPB + memcpy_get((uint8_t *) q->payload, &packet[i], q->len); + +#else /* */ + memcpy((uint8_t *) q->payload, &packet[i], q->len); + +#endif /* */ + i += q->len; + } + + /* indicate that the copy process is done and the packet can be freed + * note that we did not lock here because we are the only one editing this value + */ + mmnif->rx_buff->desc_table[rdesc].stat = MMNIF_STATUS_PROC; + + /* everything is copied to a new buffer so it's save to release + * the old one for new incoming packets + */ + mmnif_rxbuff_free(); + + /* full packet send to tcpip_thread to process */ + if ((err = mmnif_dev->input(p, mmnif_dev)) != ERR_OK) + { + DEBUGPRINTF("mmnif_rx: IP input error\n"); + pbuf_free(p); + } + + /* gather some stats and leave the rx handler */ + LINK_STATS_INC(link.xmit); + mmnif->stats.rx++; + mmnif->stats.rx_bytes += p->tot_len; + if (mmnif->rx_buff->iv_intr) + mmnif->stats.rx_intr++; + + else + mmnif->stats.rx_poll++; + goto anotherpacket; + return; + drop_packet:spinlock_lock(&mmnif->rx_buff->rlock); + + /*error handling */ + spinlock_unlock(&mmnif->rx_buff->rlock); + LINK_STATS_INC(link.drop); + mmnif->stats.rx_err++; + return; +} + +/* mmnif_rx_bypass(): recieve packets + * with insane speed ;) + */ +int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) +{ + mmnif_t *mmnif = netif->state; + mm_rx_buffer_t *b = mmnif->rx_buff; + uint16_t length; + char *packet; + uint32_t i, j; + uint8_t rdesc = 0xFF; + + // spinlock_lock(&b->rlock); + + /* check if this call to mmnif_rx makes any sense + */ + if (b->desc_table[b->dread].stat == MMNIF_STATUS_FREE) + { + + // spinlock_unlock(&b->rlock); + return -1; + } + + /* search the packet whose transmission is finished + */ + for (i = 0, j = b->dread; i < MMNIF_MAX_DESCRIPTORS; i++) + { + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == + MMNIF_STATUS_INPROC + && b->desc_table[(j + i) % + MMNIF_MAX_DESCRIPTORS].fast_sock != -1) + { + rdesc = (j + i) % MMNIF_MAX_DESCRIPTORS; + packet = (char *)b->desc_table[rdesc].addr; + length = b->desc_table[rdesc].len; + b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC_BYPASS; + break; + } + } + + // spinlock_unlock(&b->rlock); + + /* if there is no packet finished we encountered a random error + */ + if (rdesc == 0xFF) + { + return -1; + } + + /* If length is zero return silently + */ + if (length == 0) + { + DEBUGPRINTF("mmnif_rx(): empty packet error\n"); + return -1; + } + + /* From now on there is a real packet and it + * has to be worked on + */ + +#ifdef DEBUG_MMNIF_PACKET + DEBUGPRINTF("\n RECIEVED - 0x%.8X with legth: %d\n", packet, length); + hex_dump(length, packet); + +#endif /* */ + if (len >= length) + memcpy(data, (void*) mmnif->rx_buff->desc_table[rdesc].addr, mmnif->rx_buff->desc_table[rdesc].len); + + else + goto drop_packet; + + /* indicate that the copy process is done and the packet can be freed + * note that we did not lock here because we are the only one editing this value + */ + b->desc_table[rdesc].stat = MMNIF_STATUS_PROC; + + /* everything is copied to a new buffer so it's save to release + * the old one for new incoming packets + */ + mmnif_rxbuff_free(); + + /* gather some stats and leave the rx handler */ + LINK_STATS_INC(link.xmit); + mmnif->stats.rx++; + mmnif->stats.rx_bytes += length; + if (mmnif->rx_buff->iv_intr) + mmnif->stats.rx_intr++; + + else + mmnif->stats.rx_poll++; + return length; + drop_packet:spinlock_lock(&mmnif->rx_buff->rlock); + + /*error handling */ + spinlock_unlock(&mmnif->rx_buff->rlock); + LINK_STATS_INC(link.drop); + mmnif->stats.rx_err++; + return -1; +} + +/* mmnif_recv(): replacement of lwip_recv + * for fast sockets + */ +int mmnif_recv(int s, void *data, uint32_t len, int flags) +{ + bypass_rxdesc_t *p = mmnif_hashlookup(s); + int ret; + if (p == 0) + return lwip_recv(s, data, len, flags); + +#if MMNIF_FAST_SOCKET_BLOCK + sem_wait(&p->sem, 0); + +#else /* */ + while (!atomic_int32_read(&p->cnt)) + { + + //reschedule(); + NOP8; + } + +#endif /* */ + ret = mmnif_rx_bypass(mmnif_dev, s, data, len); + atomic_int32_dec(&p->cnt); + return ret; +} + +/* mmnif_socket(): replacement of lwip_socket for + * fast sockets + */ +int mmnif_socket(int domain, int type, int protocol) +{ + int ret = 0; + if (domain == AF_MMNIF_NET) + { + spinlock_lock(&pseudolock); + ret = npseudosocket++; + spinlock_unlock(&pseudolock); + return ret; + } + return lwip_socket(domain, type, protocol); +} + +/* mmnif_accept(): replacement of lwip_accept for + * fast sockets + */ +int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) +{ + struct sockaddr_in *bp = (struct sockaddr_in*)addr; + uint16_t port = bp->sin_port; + mm_rx_buffer_t *b = ((mmnif_t *) mmnif_dev->state)->rx_buff; + int i; + bypass_rxdesc_t *p; + int tmp1 = get_clock_tick(); + int tmp2 = 0; + if ((unsigned int)s >= MMNIF_PSEUDO_SOCKET_START) + { + for (i = 0; i < MMNIF_MAX_ACCEPTORS; i++) + { + if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS]. + stat == MMNIF_ACC_STAT_CLOSED) + { + spinlock_lock(&b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].port = port; + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].stat = + MMNIF_ACC_STAT_ACCEPTING; + spinlock_lock(&pseudolock); + mmnif_hashadd(npseudosocket, -1, 0); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].nsock = + npseudosocket++; + spinlock_unlock(&pseudolock); + spinlock_unlock(&b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + while (b-> + acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].stat != + MMNIF_ACC_STAT_ACCEPT_ME) + NOP8; + p = mmnif_hashlookup(b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + nsock); + p->dest_ip = + b->acceptors[(i + port) % + MMNIF_MAX_ACCEPTORS].src_ip; + p->remote_socket = + b->acceptors[(i + port) % + MMNIF_MAX_ACCEPTORS].rsock; + spinlock_lock(&b-> + acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].stat = + MMNIF_ACC_STAT_ACCEPTED; + i = b->acceptors[(i + port) % + MMNIF_MAX_ACCEPTORS].nsock; + spinlock_unlock(&b-> + acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + return i; + } + } + return -1; + } + + else + { + for (i = 0; i < MMNIF_MAX_ACCEPTORS; i++) + { + if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS]. + stat == MMNIF_ACC_STAT_CLOSED) + { + spinlock_lock(&b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].port = port; + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].stat = + MMNIF_ACC_STAT_ACCEPTING; + spinlock_lock(&pseudolock); + mmnif_hashadd(npseudosocket, -1, 0); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].nsock = + npseudosocket++; + spinlock_unlock(&pseudolock); + spinlock_unlock(&b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + while (b-> + acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].stat != + MMNIF_ACC_STAT_ACCEPT_ME) + { + tmp2 = get_clock_tick(); + if (tmp2 - tmp1 > + MMNIF_AUTO_SOCKET_TIMEOUT) + { + spinlock_lock(&b->acceptors[(i + + port) + % + MMNIF_MAX_ACCEPTORS].alock); + if (b->acceptors + [(i + + port) % + MMNIF_MAX_ACCEPTORS]. + stat == + MMNIF_ACC_STAT_ACCEPT_ME) + { + spinlock_unlock(&b-> + acceptors + [(i + + port) + % + MMNIF_MAX_ACCEPTORS]. + alock); + break; + } +#ifdef DEBUG_MMNIF + DEBUGPRINTF + ("mmnif_accept(): Timout occoured, switching to normal accept()"); + +#endif /* */ + mmnif_hashdelete(b-> + acceptors[(i + + port) + % + MMNIF_MAX_ACCEPTORS]. + nsock); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + stat = + MMNIF_ACC_STAT_CLOSED; + spinlock_unlock(&b-> + acceptors[(i + + port) + % + MMNIF_MAX_ACCEPTORS].alock); + goto normalaccept; + } + NOP8; + } + p = mmnif_hashlookup(b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + nsock); + p->dest_ip = + b->acceptors[(i + port) % + MMNIF_MAX_ACCEPTORS].src_ip; + p->remote_socket = + b->acceptors[(i + port) % + MMNIF_MAX_ACCEPTORS].rsock; + spinlock_lock(&b-> + acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + b->acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS].stat = + MMNIF_ACC_STAT_ACCEPTED; + i = b->acceptors[(i + port) % + MMNIF_MAX_ACCEPTORS].nsock; + spinlock_unlock(&b-> + acceptors[(i + + port) % + MMNIF_MAX_ACCEPTORS]. + alock); + return i; + } + } + return -1; + } + normalaccept:return lwip_accept(s, addr, addrlen); +} + +/* mmnif_connect(): replacement of lwip_connect for + * fast sockets + */ +int mmnif_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct sockaddr_in *p = (struct sockaddr_in*) name; + uint16_t port = p->sin_port; + mm_rx_buffer_t *b; + int i; + //int tmp1 = get_clock_tick(); + //int tmp2 = 0; + uint8_t core; + uint8_t *ip4addr; + uint8_t addr[4]; + //uint32_t netmask = 0xFFFFFF00; + + /* grab the destination ip address out of the ip header + * for internal routing the last ocet is interpreted as core ID. + */ + ip4addr = (uint8_t*) &p->sin_addr.s_addr; + + /* revert the address to host format */ + addr[3] = ip4addr[0]; + addr[2] = ip4addr[1]; + addr[1] = ip4addr[2]; + addr[0] = ip4addr[3]; + + /* check if the ip address is in the Local Area Network of the 48 cores */ + // if (!((netmask & *(uint32_t*)addr) == (netmask & own_ip_address) )) + // return -1; + + core = addr[0]; + if ((core) < 1 || (core > MMNIF_CORES)) + return lwip_connect(s, name, namelen); + + b = (mm_rx_buffer_t *) ((char *)header_start_address + + (core - 1) * header_size); + for (i = 0; i < MMNIF_MAX_ACCEPTORS; i++) + { + if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat == MMNIF_ACC_STAT_ACCEPTING + && b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].port == port) + { + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPT_ME; + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].rsock = s; + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].src_ip = own_ip_address & 0xFF; + mmnif_hashadd(s, + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock, core); + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPTED) + { + +// tmp2 = get_clock_tick(); +// if (tmp2 - tmp1 > MMNIF_AUTO_SOCKET_TIMEOUT) +// { +//#ifdef DEBUG_MMNIF +// DEBUGPRINTF("mmnif_connect(): Timout occoured, switching to normal connect()"); +//#endif +// mmnif_hashdelete(s); +// goto normalsend; +// } + NOP8; + } + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_CLOSED; + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + return 0; + } + } + +#ifdef DEBUG_MMNIF + DEBUGPRINTF("mmnif_connect(): no acceptor found"); + +#endif + + return -1; +} + +int mmnif_listen(int s, int backlog) +{ + if ((unsigned int)s < MMNIF_PSEUDO_SOCKET_START) + return lwip_listen(s, backlog); + return 0; +} + +int mmnif_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + if ((unsigned int)s < MMNIF_PSEUDO_SOCKET_START) + return lwip_bind(s, name, namelen); + return 0; +} + +/* mmnif_closesocket(): replacement if lwip_close for + * fast_sockets + */ +int mmnif_closesocket(int s) +{ + bypass_rxdesc_t *p = mmnif_hashlookup(s); + + if (p == 0) + return -1; + mmnif_hashdelete(s); + if ((unsigned int)s < MMNIF_PSEUDO_SOCKET_START) + return lwip_close(s); + return 0; +} + +/* mmnif_irqhandler(): + * handles the incomint interrupts + */ +void mmnif_irqhandler() +{ + mmnif_t *mmnif; + + /* return if mmnif_dev is not yet initialized */ + if (!mmnif_dev) + { + DEBUGPRINTF + ("mmnif_irqhandler(): the driver is not initialized yet\n"); + return; + } + mmnif = (mmnif_t *) mmnif_dev->state; + mmnif_rx(mmnif_dev); + +// while (mmnif->rx_buff->dcount < MMNIF_MAX_DESCRIPTORS) +// { +// mmnif_rx(mmnif_dev); + +// if (mmnif->rx_buff->dcount < MMNIF_MAX_DESCRIPTORS/2) +// { +// budget_overflow_count++; +// if (budget_overflow_count >= MMNIF_INTR_BUDGET) +// { +// mmnif->rx_buff->iv_intr = FALSE; +// budget_overflow_count = 0; +// sem_post(&mmnif->com_poll); +// break; +// } +// } +// else +// budget_overflow_count = 0; + +// } +} + +/* + * the poll function wich is used if no interrupt wake up our mmnif_rx functions + */ +int mmnif_poll(void *e) +{ + mmnif_t *mmnif; + if (!mmnif_dev) + { + DEBUGPRINTF + ("mmnif_poll(): the driver is not initialized yet\n"); + return -1; + } + mmnif = (mmnif_t *) mmnif_dev->state; + if (!reduce_irq) + { + sem_wait(&mmnif->com_poll, 0); + } +#ifdef DEBUG_MMNIF + DEBUGPRINTF("mmnif_poll(): polling thread launched", mmnif->rx_buff); + +#endif /* */ + + /*run while driver is up */ + while (active) + { + while (mmnif->rx_buff->desc_table[mmnif->rx_buff->dread].stat != + MMNIF_STATUS_RDY) + { + mmnif->stats.pll_empty++; + if (mmnif->stats.pll_empty >= MMNIF_POLL_BUDGET) + { + + /* enable interrupts and suspend polling + * + */ + mmnif->rx_buff->iv_intr = TRUE; + mmnif->stats.pll_empty = 0; + +#ifdef DEBUG_MMNIF + DEBUGPRINTF + ("mmnif_poll(): heuristical interrupts enabled\n"); + +#endif /* */ + sem_wait(&mmnif->com_poll, 0); + } + + /* uncomment this to test only polling + */ + // mmnif->stats.pll_empty = 0; + } + mmnif->stats.pll_empty = 0; + mmnif_rx(mmnif_dev); + } + + return 0; +} + +/* + * Open the interface should be called by kernel to use this network interface + */ +int mmnif_open() +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + /* calculate my own ip address from core number + * Note: core 1 is the router core + */ + IP4_ADDR(&gw, 0, 0, 0, 0); + IP4_ADDR(&ipaddr, 192, 168, 0, RCCE_ue() + 1); + IP4_ADDR(&netmask, 255, 255, 255, 0); + own_ip_address += RCCE_ue() + 1; + mmnif_dev = kmalloc(sizeof(struct netif)); + + /* register our Memory Mapped Virtual IP interface in the lwip stack + * and tell him how to use the interface: + * - mmnif_dev : the device data storage + * - ipaddr : the ip address wich should be used + * - gw : the gateway wicht should be used + * - mmnif_init : the initialization which has to be done in order to use our interface + * - ethernet_input : tells him that he should get ethernet input (inclusice ARP) + * + * Note: Ethernet Input will be removed because its NOT needed and will + * be replaced with ip_input + */ + if (!netif_add + (mmnif_dev, &ipaddr, &netmask, &gw, NULL, + (netif_init_fn) mmnif_init, tcpip_input)) + { + DEBUGPRINTF("mmnif_open() : unable to add network interface\n"); + return -1; + } + + /* set our network interface to the default interface for lwip */ + netif_set_default(mmnif_dev); + + /* tell lwip all initialization is done and we want to set it ab */ + netif_set_up(mmnif_dev); + + /* test if interface is really up */ + if (!netif_is_up(mmnif_dev)) + { + DEBUGPRINTF("mmnif_open(): network interface is not up\n"); + +// return -2; + } + + /* indicate that the driver is active now */ + active = TRUE; + + /* If interrupts are not used we immediately add the polling function + * to the queue which would otherwise be done through the IRQ handler. + */ + if (reduce_irq) + mmnif_device_schedule(); + +#ifdef DEBUG_MMNIF + DEBUGPRINTF("mmnif_dev is open\n"); + +#endif /* */ + return 0; +} + +/* + * close the interface should be called by kernel to close this interface and release resources + * Note: it's temporarly empty. Support will be added. + */ +int mmnif_close() +{ + mmnif_t *mmnif; + if (!mmnif_dev) + { + DEBUGPRINTF + ("mmnif_close(): you closed the device before it was properly opened -.-* \n"); + } + mmnif = (mmnif_t *) mmnif_dev->state; + + /* indicate that the driver is not active anymore + * - this will stop the polling thread i.e. + */ + active = FALSE; + kfree(mmnif->tx_buff[0], MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); + kfree(mmnif_dev, sizeof(mmnif_t)); + + //RCCE_shfree(mpb_start_address); + return 0; +} diff --git a/drivers/net/mmnif.h b/drivers/net/mmnif.h index 012e8109..97305344 100644 --- a/drivers/net/mmnif.h +++ b/drivers/net/mmnif.h @@ -1,51 +1,48 @@ -/* - * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, - * RWTH Aachen University - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of MetalSVM. - */ - -#ifndef __MMNIF_H__ -#define __MMNIF_H__ - -#ifdef WIN32 - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; - -#else - -#define TRUE 1 -#define FALSE 0 - -#endif - -/* - * Initialize the network driver for mmn - */ -int mmnif_open(void); -int mmnif_close(void); - -int mmnif_poll(void* e); -int mmnif_worker(void* e); - -void mmnif_irqhandler(void); - -#endif +/* + * Copyright 2011 Carl-Benedikt Krueger, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + */ + +#ifndef __MMNIF_H__ +#define __MMNIF_H__ + +#define AF_MMNIF_NET 0x1337 + +#define MMNIF_AUTOACTIVATE_FAST_SOCKETS 0 + +#if MMNIF_AUTOACTIVATE_FAST_SOCKETS +#define accept(a,b,c) mmnif_accept(a,b,c) +#define closesocket(s) mmnif_closesocket(s) +#define connect(a,b,c) mmnif_connect(a,b,c) +#define recv(a,b,c,d) mmnif_recv(a,b,c,d) +#define send(a,b,c,d) mmnif_send(a,b,c,d) +#define socket(a,b,c) mmnif_socket(a,b,c) +#define bind(a,b,c) mmnif_bind(a,b,c) +#define listen(a,b) mmnif_listen(a,b) +#endif + +/* + * Initialize the network driver for mmn + */ +int mmnif_open(void); +int mmnif_close(void); +int mmnif_poll(void *e); +int mmnif_worker(void *e); +void mmnif_irqhandler(void); +void mmnif_print_driver_status(); + +#endif From 0fa695f3de3c9c0f01c3dde05a25635b340b8a4d Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 2 Oct 2011 13:55:41 -0700 Subject: [PATCH 08/23] cosmetic changes --- drivers/net/util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/util.c b/drivers/net/util.c index 8ab43537..449fa499 100644 --- a/drivers/net/util.c +++ b/drivers/net/util.c @@ -30,13 +30,16 @@ inline int isprint(unsigned char e) void hex_dump(unsigned n, const unsigned char *buf) { int on_this_line = 0; + while (n-- > 0) { kprintf("%02X ", *buf++); on_this_line += 1; + if (on_this_line == 16 || n == 0) { int i; + kputs(" "); for (i = on_this_line; i < 16; i++) kputs(" "); From 747d8a278cef5b7433403855133ee561c002bfa1 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 2 Oct 2011 13:56:54 -0700 Subject: [PATCH 09/23] changes coding style, redesign of the startup code --- drivers/net/mmnif.c | 500 ++++++++++++++------------------------------ drivers/net/mmnif.h | 14 +- 2 files changed, 170 insertions(+), 344 deletions(-) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index 80acc0e3..42450e1d 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -361,7 +361,7 @@ inline static void *memcpy_put(void *dest, const void *src, size_t count) * this creates a polling thread which looks for data * itself */ -inline int mmnif_device_schedule() +inline static int mmnif_device_schedule(void) { return create_kernel_task(&polling_thread, mmnif_poll, NULL, NORMAL_PRIO); } @@ -369,7 +369,7 @@ inline int mmnif_device_schedule() /* trigger an interrupt on the remote processor * so he knows there is a packet to read */ -inline int mmnif_trigger_irq(dest_ip) +inline static int mmnif_trigger_irq(dest_ip) { int tmp, x, y, z, addr; int ue = dest_ip - 1; @@ -392,24 +392,22 @@ inline int mmnif_trigger_irq(dest_ip) /* mmnif_get_device_stats(): Returns a copy of the * current device */ -mmnif_device_stats_t mmnif_get_device_stats() +static mmnif_device_stats_t mmnif_get_device_stats(void) { - mmnif_device_stats_t stats = { - 0 - }; - if (!mmnif_dev) - DEBUGPRINTF - ("mmnif_get_device_stats(): the device is not initialized yet.\n"); + mmnif_device_stats_t stats = { 0 }; + if (!mmnif_dev) + DEBUGPRINTF("mmnif_get_device_stats(): the device is not initialized yet.\n"); else stats = ((mmnif_t *) mmnif_dev->state)->stats; + return stats; } /* mmnif_print_stats(): Print the devices stats of the * current device */ -void mmnif_print_stats() +static void mmnif_print_stats(void) { mmnif_t *mmnif; if (!mmnif_dev) @@ -424,47 +422,41 @@ void mmnif_print_stats() DEBUGPRINTF("Received: %d bytes\n", mmnif->stats.rx_bytes); DEBUGPRINTF("interrupts: %d\n", mmnif->stats.rx_intr); DEBUGPRINTF("polling: %d\n", mmnif->stats.rx_poll); - DEBUGPRINTF("Received: %d packets containuing errors\n", - mmnif->stats.rx_err); + DEBUGPRINTF("Received: %d packets containuing errors\n", mmnif->stats.rx_err); DEBUGPRINTF("Transmitted: %d packests successfull\n", mmnif->stats.tx); DEBUGPRINTF("Transmitted: %d bytes\n", mmnif->stats.tx_bytes); - DEBUGPRINTF("Transmitted: %d packests were dropped due to errors\n", - mmnif->stats.tx_err); + DEBUGPRINTF("Transmitted: %d packests were dropped due to errors\n", mmnif->stats.tx_err); } /* mmnif_print_driver_status * */ -void mmnif_print_driver_status() +void mmnif_print_driver_status(void) { mmnif_t *mmnif; int i; if (!mmnif_dev) { - DEBUGPRINTF - ("mmnif_print_driver_status(): the device is not initialized yet.\n"); + DEBUGPRINTF("mmnif_print_driver_status(): the device is not initialized yet.\n"); return; } mmnif = (mmnif_t *) mmnif_dev->state; DEBUGPRINTF("/dev/mmnif driver status: \n\n"); - DEBUGPRINTF("rx_buf: 0x%.8X\n", mmnif->rx_buff); + DEBUGPRINTF("rx_buf: 0xp\n", mmnif->rx_buff); DEBUGPRINTF("free descriptors : %d\n\n", mmnif->rx_buff->dcount); DEBUGPRINTF("descriptor table: (only print descriptors in use)\n"); DEBUGPRINTF("status\taddr\tsize\n"); for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) { if (mmnif->rx_buff->desc_table[i].stat != 0) - DEBUGPRINTF("0x%.2X\t0x%.8X\t%X\t\n", + DEBUGPRINTF("0x%.2X\t0x%p\t%X\t\n", mmnif->rx_buff->desc_table[i].stat, mmnif->rx_buff->desc_table[i].addr, mmnif->rx_buff->desc_table[i].len); } - DEBUGPRINTF("\n\nretrive via interrupt : %d\n", - mmnif->rx_buff->iv_intr); - DEBUGPRINTF("ring heap start addr: 0x%.8X\n", - mmnif->rx_buff + sizeof(mm_rx_buffer_t)); - DEBUGPRINTF("head: 0x%X\ttail: 0x%X\n", mmnif->rx_buff->head, - mmnif->rx_buff->tail); + DEBUGPRINTF("\n\nretrive via interrupt : %d\n", mmnif->rx_buff->iv_intr); + DEBUGPRINTF("ring heap start addr: 0x%p\n", mmnif->rx_buff + sizeof(mm_rx_buffer_t)); + DEBUGPRINTF("head: 0x%X\ttail: 0x%X\n", mmnif->rx_buff->head, mmnif->rx_buff->tail); mmnif_print_stats(); } @@ -476,7 +468,7 @@ void mmnif_print_driver_status() * this function deals with some HW details, it checks to wich core this packet * should be routed and returns the destination */ -uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p) +static uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p) { struct ip_hdr *iphdr; uint8_t core; @@ -516,8 +508,9 @@ uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p) * right inside of the buffer which is used for communication * with the remote end */ -uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len) +static uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len) { + uint32_t ret; mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size); #if MMNIF_USE_MPB @@ -526,15 +519,13 @@ uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len) char *memblock = (char *)heap_start_address + (dest - 1) * heap_size; #endif -// memblock = 0xC0000000 + ( dest -1 ) * heap_size; - uint32_t ret; - // if (rb->tail > rb->head) // if ((MMNIF_RX_BUFFERLEN - rb->tail < len)&&(rb->head < len)) // return NULL; // else // if ((rb->head - rb->tail < len)&&(rb->tail != rb->head)) // return NULL; + spinlock_lock(&rb->dlock); if (rb->dcount) { @@ -608,7 +599,7 @@ uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len) * allocated packet to RDY so the recieve queue knows that it can be * processed further */ -int mmnif_commit_packet(uint8_t dest, uint32_t addr) +static int mmnif_commit_packet(uint8_t dest, uint32_t addr) { mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size); uint32_t i; @@ -631,12 +622,11 @@ int mmnif_commit_packet(uint8_t dest, uint32_t addr) * allocated packet to RDY so the recieve queue knows that it can be * processed further */ -int mmnif_commit_packet_bypass(uint8_t dest, uint32_t addr, int dest_socket) +static int mmnif_commit_packet_bypass(uint8_t dest, uint32_t addr, int dest_socket) { - mm_rx_buffer_t *rb = - (mm_rx_buffer_t *) ((char *)header_start_address + - (dest - 1) * header_size); + mm_rx_buffer_t* rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size); uint32_t i; + for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) { if (rb->desc_table[i].addr == addr @@ -647,20 +637,23 @@ int mmnif_commit_packet_bypass(uint8_t dest, uint32_t addr, int dest_socket) return 0; } } + return -1; } /* mmnif_rxbuff_free() : the opposite to mmnif_rxbuff_alloc() a from the receiver * already processed chunk of memory is freed so that it can be allocated again */ -void mmnif_rxbuff_free() +static void mmnif_rxbuff_free(void) { mmnif_t *mmnif = mmnif_dev->state; mm_rx_buffer_t *b = mmnif->rx_buff; uint32_t i, j; uint32_t rpos; + spinlock_lock(&b->dlock); rpos = b->dread; + for (i = 0, j = rpos; i < MMNIF_MAX_DESCRIPTORS; i++) { j = (j + i) % MMNIF_MAX_DESCRIPTORS; @@ -672,31 +665,16 @@ void mmnif_rxbuff_free() if (b->tail > b->head) { b->head += b->desc_table[j].len; - } - - else - { - if ((b-> - desc_table[(j + - 1) % - MMNIF_MAX_DESCRIPTORS].stat != - MMNIF_STATUS_FREE) - && (b->desc_table[j].addr > - b->desc_table[(j + 1) % - MMNIF_MAX_DESCRIPTORS]. - addr)) + } else { + if ((b->desc_table[(j + 1) % MMNIF_MAX_DESCRIPTORS].stat != MMNIF_STATUS_FREE) + && (b->desc_table[j].addr > b->desc_table[(j + 1) % MMNIF_MAX_DESCRIPTORS].addr)) { b->head = 0; - } - - else - { + } else { b->head += b->desc_table[j].len; } } - } - - else + } else break; } spinlock_unlock(&b->dlock); @@ -705,7 +683,7 @@ void mmnif_rxbuff_free() /* * Transmid a packet (called by the lwip) */ -err_t mmnif_tx(struct netif *netif, struct pbuf *p) +static err_t mmnif_tx(struct netif *netif, struct pbuf *p) { mmnif_t *mmnif = netif->state; uint8_t slot = mmnif->tx_queue; @@ -730,6 +708,7 @@ err_t mmnif_tx(struct netif *netif, struct pbuf *p) DEBUGPRINTF("mmnif_tx(): too many packets at once for tx_queue\n"); goto drop_packet; } + if (p->tot_len > MMNIF_TX_BUFFERLEN) { DEBUGPRINTF("mmnif_tx(): packet is longer than %d bytes\n",MMNIF_TX_BUFFERLEN); @@ -776,6 +755,7 @@ realloc: // mmnif_trigger_irq(dest_ip); goto realloc; } + if (!write_address) goto drop_packet; @@ -816,7 +796,7 @@ realloc: DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); } #ifdef DEBUG_MMNIF_PACKET -// DEBUGPRINTF("\n SEND 0x%.8X with length: %d\n",(char*)heap_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); +// DEBUGPRINTF("\n SEND 0x%p with length: %d\n",(char*)heap_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); // hex_dump(p->tot_len, p->payload); #endif @@ -831,6 +811,7 @@ realloc: mmnif->stats.tx_bytes += p->tot_len; if (rb->iv_intr) mmnif_trigger_irq(dest_ip); + return ERR_OK; drop_packet: @@ -845,13 +826,14 @@ drop_packet: spinlock_unlock(&mmnif->lock); LINK_STATS_INC(link.drop); mmnif->stats.tx_err++; + return ERR_IF; } /* mmnif_hashlookup(): looks up a bypass descriptor by * the associated socket */ -bypass_rxdesc_t *mmnif_hashlookup(int s) +static bypass_rxdesc_t *mmnif_hashlookup(int s) { int i; bypass_rxdesc_t *p; @@ -868,7 +850,7 @@ bypass_rxdesc_t *mmnif_hashlookup(int s) /* mmnif_hashadd(): adds a entry to the hashtable * by the socket */ -int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip) +static int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip) { bypass_rxdesc_t *p; int i; @@ -892,13 +874,15 @@ int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip) /* mmnif_hashdelete(): deletes an entry from the * hashtable */ -int mmnif_hashdelete(int sock) +static int mmnif_hashdelete(int sock) { bypass_rxdesc_t *p; int i; + p = mmnif_hashlookup(sock); if (p != 0) return -1; + for (i = 0; i < MMNIF_HASHTABLE_SIZE; i++) { p = &mmnif_hashtable[(sock + i) % MMNIF_HASHTABLE_SIZE]; @@ -916,15 +900,13 @@ int mmnif_hashdelete(int sock) /* * Transmid a packet (with insane speed) */ -err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, int s) +static err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, int s) { mmnif_t *mmnif = netif->state; uint32_t write_address; bypass_rxdesc_t *dest = mmnif_hashlookup(s); //uint32_t exp_delay = 2; - mm_rx_buffer_t *rb = - (mm_rx_buffer_t *) ((char *)header_start_address + - (dest->dest_ip - 1) * header_size); + mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest->dest_ip - 1) * header_size); /* Perform serveral sanity checks on the packet and the buffers: * - is the output packet to big? @@ -937,8 +919,8 @@ err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, int s) // } /* allocate memory for the packet in the remote buffer */ - realloc:write_address = - mmnif_rxbuff_alloc(dest->dest_ip, CLINE_ALIGN(size)); +realloc: + write_address = mmnif_rxbuff_alloc(dest->dest_ip, CLINE_ALIGN(size)); if (!write_address) { @@ -984,7 +966,7 @@ err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, int s) DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); } #ifdef DEBUG_MMNIF_PACKET - // DEBUGPRINTF("\n SEND 0x%.8X with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); + // DEBUGPRINTF("\n SEND 0x%p with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); // hex_dump(p->tot_len, p->payload); #endif @@ -1010,6 +992,7 @@ int mmnif_send(int s, void *data, size_t size, int flags) { bypass_rxdesc_t *p = mmnif_hashlookup(s); uint32_t i, j, k, ret; + if (p != 0) { if (size < ((MMNIF_RX_BUFFERLEN / 2) - 1)) @@ -1019,27 +1002,19 @@ int mmnif_send(int s, void *data, size_t size, int flags) { j = size / (((MMNIF_RX_BUFFERLEN / 2) - 1)); k = size - (j * (((MMNIF_RX_BUFFERLEN / 2) - 1))); + for (i = 0; i < j; i++) { - ret = - mmnif_tx_bypass(mmnif_dev, - data + - i * - ((MMNIF_RX_BUFFERLEN / 2) - - 1), - ((MMNIF_RX_BUFFERLEN / 2) - - 1), s); + ret = mmnif_tx_bypass(mmnif_dev, data + i * ((MMNIF_RX_BUFFERLEN / 2) - 1), ((MMNIF_RX_BUFFERLEN / 2) - 1), s); + if (ret < 0) return ret; } - ret = - mmnif_tx_bypass(mmnif_dev, - data + (j - - 1) * ((MMNIF_RX_BUFFERLEN / - 2) - 1), k, s); + ret = mmnif_tx_bypass(mmnif_dev, data + (j - 1) * ((MMNIF_RX_BUFFERLEN / 2) - 1), k, s); return ret; } } + return lwip_send(s, data, size, flags); } @@ -1068,7 +1043,10 @@ err_t mmnif_init(struct netif *netif) #ifdef DEBUG_MMNIF DEBUGPRINTF("mmnif init attempt\n"); -#endif /* */ +#endif + + mmnif_dev = netif; + own_ip_address += RCCE_ue() + 1; /* Alloc and clear memory for the device struct */ @@ -1083,17 +1061,16 @@ err_t mmnif_init(struct netif *netif) /* Alloc and clear shared memory for rx_buff */ header_size = (sizeof(mm_rx_buffer_t)); - DEBUGPRINTF("mmnif_init() : size of mm_rx_buffer_t : %d", - sizeof(mm_rx_buffer_t)); + DEBUGPRINTF("mmnif_init() : size of mm_rx_buffer_t : %d", sizeof(mm_rx_buffer_t)); // align mpb size to the granularity of a page size header_size = (header_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); header_start_address = (void*) RCCE_shmalloc(header_size * MMNIF_CORES); - DEBUGPRINTF("RCCE_shmalloc : 0x%.8X", header_start_address); + DEBUGPRINTF("RCCE_shmalloc : 0x%p", header_start_address); // map physical address in the virtual address space header_start_address = (void*) map_region(0, (size_t) header_start_address, (MMNIF_CORES * header_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE); - DEBUGPRINTF("map_region : 0x%.8X", header_start_address); + DEBUGPRINTF("map_region : 0x%p", header_start_address); mmnif->rx_buff = (mm_rx_buffer_t *) (header_start_address + (header_size) * (own_ip_address - router_ip_address)); /* Alloc and clear shared memory for rx_buff @@ -1105,7 +1082,7 @@ err_t mmnif_init(struct netif *netif) #if MMNIF_USE_MPB heap_start_address = RCCE_malloc(RCCE_LINE_SIZE); - DEBUGPRINTF("MessagePassingBuffer allocated @ : 0x%.8X\n", heap_start_address); + DEBUGPRINTF("MessagePassingBuffer allocated @ : 0x%p\n", heap_start_address); for (i = heap_size / RCCE_LINE_SIZE; i > 0; i--) { if (!RCCE_malloc(RCCE_LINE_SIZE)) ; @@ -1117,41 +1094,34 @@ err_t mmnif_init(struct netif *netif) } } -#else /* */ +#else heap_start_address = (void*) RCCE_shmalloc(heap_size * MMNIF_CORES); n = (int) heap_start_address; - DEBUGPRINTF("RCCE_shmalloc : 0x%.8X", header_start_address); + DEBUGPRINTF("RCCE_shmalloc : 0x%p", header_start_address); // map physical address in the virtual address space #if USE_CACHE //heap_start_address = map_region(0, heap_start_address, (MMNIF_CORES*heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE); heap_start_address = map_region(0, heap_start_address, (MMNIF_CORES * heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE | MAP_MPE); - remap_region(heap_start_address + - (heap_size) * (own_ip_address - router_ip_address), - n + (heap_size) * (own_ip_address - router_ip_address), 1, - MAP_KERNEL_SPACE | MAP_MPE); - + remap_region(heap_start_address + (heap_size) * (own_ip_address - router_ip_address), n + (heap_size) * (own_ip_address - router_ip_address), 1, MAP_KERNEL_SPACE | MAP_MPE); #else heap_start_address = (void*) map_region(0, (size_t) heap_start_address, (MMNIF_CORES * heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE | MAP_MPE); - #endif // USE_CAHCE #endif // MMNIF_USE_MPB - DEBUGPRINTF("map_region : 0x%.8X", header_start_address); + DEBUGPRINTF("map_region : 0x%p", header_start_address); #if MMNIF_USE_MPB mmnif->rx_heap = heap_start_address; heap_start_address = heap_start_address - (own_ip_address - router_ip_address) * 0x2000; - DEBUGPRINTF("heap_start_address : 0x%.8X", heap_start_address); + DEBUGPRINTF("heap_start_address : 0x%p", heap_start_address); // heap_start_address = 0xC0000000; // mmnif->rx_heap = heap_start_address + (heap_size) * (own_ip_address - router_ip_address); -#else /* */ - mmnif->rx_heap = - heap_start_address + (heap_size) * (own_ip_address - - router_ip_address); +#else + mmnif->rx_heap = heap_start_address + (heap_size) * (own_ip_address - router_ip_address); +#endif -#endif /* */ if (!(heap_start_address)) { DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); @@ -1163,25 +1133,23 @@ err_t mmnif_init(struct netif *netif) #if USE_CACHE *((int *)RCCE_fool_write_combine_buffer) = 1; -#endif /* */ +#endif if (own_ip_address == router_ip_address) { kprintf("Test0: MEMCPY 2048B"); tmp1 = get_clock_tick(); for (n = 0; n < 4096; n++) { - memcpy(mmnif->rx_heap + heap_size, mmnif->rx_heap, - 2048); + memcpy(mmnif->rx_heap + heap_size, mmnif->rx_heap, 2048); #if USE_CACHE *((int *)RCCE_fool_write_combine_buffer) = 1; flush_cache(); -#endif /* */ +#endif memcpy(mmnif->rx_heap, mmnif->rx_heap, 2048); } tmp2 = get_clock_tick(); - kprintf("memcpy'd' %d bytes in %d ticks", n * 2048, - (tmp2 - tmp1)); + kprintf("memcpy'd' %d bytes in %d ticks", n * 2048, (tmp2 - tmp1)); } /* set initial values @@ -1214,9 +1182,11 @@ err_t mmnif_init(struct netif *netif) } mmnif->tx_queue = 0; memset(mmnif->tx_buff[0], 0, MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); - for (i = 0; i < MMNIF_TX_QUEUELEN - 1; i++) + + for (i=0; itx_buff[i + 1] = mmnif->tx_buff[i] + MMNIF_TX_BUFFERLEN; - for (i = 0; i < MMNIF_HASHTABLE_SIZE; i++) + + for (i=0; irx_buff->acceptors[i].stat = MMNIF_ACC_STAT_CLOSED; mmnif->rx_buff->acceptors[i].nsock = -1; @@ -1244,8 +1215,8 @@ err_t mmnif_init(struct netif *netif) mmnif_dev = netif; /* administrative details */ - netif->name[0] = 'e'; - netif->name[1] = 'n'; + netif->name[0] = 'm'; + netif->name[1] = 'm'; netif->num = num; num++; @@ -1259,15 +1230,24 @@ err_t mmnif_init(struct netif *netif) netif->mtu = MMNIF_TX_BUFFERLEN; /* broadcast capability, keep all default flags */ - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_LINK_UP; + netif->flags |= NETIF_FLAG_BROADCAST; /* hardware address length */ netif->hwaddr_len = 0; + + /* indicate that the driver is active now */ active = TRUE; + /* If interrupts are not used we immediately add the polling function + * to the queue which would otherwise be done through the IRQ handler. + */ + if (reduce_irq) + mmnif_device_schedule(); + #ifdef DEBUG_MMNIF DEBUGPRINTF("mmnif init complete\n"); #endif + return ERR_OK; } @@ -1375,7 +1355,7 @@ anotherpacket: */ #ifdef DEBUG_MMNIF_PACKET - DEBUGPRINTF("\n RECIEVED - 0x%.8X with legth: %d\n", packet, length); + DEBUGPRINTF("\n RECIEVED - 0x%p with legth: %d\n", packet, length); hex_dump(length, packet); #endif @@ -1436,19 +1416,22 @@ anotherpacket: mmnif->stats.rx_poll++; goto anotherpacket; return; - drop_packet:spinlock_lock(&mmnif->rx_buff->rlock); + +drop_packet: + spinlock_lock(&mmnif->rx_buff->rlock); /*error handling */ spinlock_unlock(&mmnif->rx_buff->rlock); LINK_STATS_INC(link.drop); mmnif->stats.rx_err++; + return; } /* mmnif_rx_bypass(): recieve packets * with insane speed ;) */ -int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) +static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) { mmnif_t *mmnif = netif->state; mm_rx_buffer_t *b = mmnif->rx_buff; @@ -1507,7 +1490,7 @@ int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) */ #ifdef DEBUG_MMNIF_PACKET - DEBUGPRINTF("\n RECIEVED - 0x%.8X with legth: %d\n", packet, length); + DEBUGPRINTF("\n RECIEVED - 0x%p with legth: %d\n", packet, length); hex_dump(length, packet); #endif /* */ @@ -1537,12 +1520,15 @@ int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) else mmnif->stats.rx_poll++; return length; - drop_packet:spinlock_lock(&mmnif->rx_buff->rlock); + +drop_packet: + spinlock_lock(&mmnif->rx_buff->rlock); /*error handling */ spinlock_unlock(&mmnif->rx_buff->rlock); LINK_STATS_INC(link.drop); mmnif->stats.rx_err++; + return -1; } @@ -1559,7 +1545,7 @@ int mmnif_recv(int s, void *data, uint32_t len, int flags) #if MMNIF_FAST_SOCKET_BLOCK sem_wait(&p->sem, 0); -#else /* */ +#else while (!atomic_int32_read(&p->cnt)) { @@ -1570,6 +1556,7 @@ int mmnif_recv(int s, void *data, uint32_t len, int flags) #endif /* */ ret = mmnif_rx_bypass(mmnif_dev, s, data, len); atomic_int32_dec(&p->cnt); + return ret; } @@ -1579,6 +1566,7 @@ int mmnif_recv(int s, void *data, uint32_t len, int flags) int mmnif_socket(int domain, int type, int protocol) { int ret = 0; + if (domain == AF_MMNIF_NET) { spinlock_lock(&pseudolock); @@ -1586,6 +1574,7 @@ int mmnif_socket(int domain, int type, int protocol) spinlock_unlock(&pseudolock); return ret; } + return lwip_socket(domain, type, protocol); } @@ -1608,60 +1597,23 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS]. stat == MMNIF_ACC_STAT_CLOSED) { - spinlock_lock(&b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].port = port; - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].stat = - MMNIF_ACC_STAT_ACCEPTING; + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].port = port; + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPTING; spinlock_lock(&pseudolock); mmnif_hashadd(npseudosocket, -1, 0); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].nsock = - npseudosocket++; + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock = npseudosocket++; spinlock_unlock(&pseudolock); - spinlock_unlock(&b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); - while (b-> - acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].stat != - MMNIF_ACC_STAT_ACCEPT_ME) + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPT_ME) NOP8; - p = mmnif_hashlookup(b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - nsock); - p->dest_ip = - b->acceptors[(i + port) % - MMNIF_MAX_ACCEPTORS].src_ip; - p->remote_socket = - b->acceptors[(i + port) % - MMNIF_MAX_ACCEPTORS].rsock; - spinlock_lock(&b-> - acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].stat = - MMNIF_ACC_STAT_ACCEPTED; - i = b->acceptors[(i + port) % - MMNIF_MAX_ACCEPTORS].nsock; - spinlock_unlock(&b-> - acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); + p = mmnif_hashlookup(b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock); + p->dest_ip = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].src_ip; + p->remote_socket = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].rsock; + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPTED; + i = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock; + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); return i; } } @@ -1672,118 +1624,53 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) { for (i = 0; i < MMNIF_MAX_ACCEPTORS; i++) { - if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS]. - stat == MMNIF_ACC_STAT_CLOSED) + if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat == MMNIF_ACC_STAT_CLOSED) { - spinlock_lock(&b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].port = port; - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].stat = - MMNIF_ACC_STAT_ACCEPTING; + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].port = port; + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPTING; spinlock_lock(&pseudolock); mmnif_hashadd(npseudosocket, -1, 0); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].nsock = - npseudosocket++; + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock = npseudosocket++; spinlock_unlock(&pseudolock); - spinlock_unlock(&b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); - while (b-> - acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].stat != - MMNIF_ACC_STAT_ACCEPT_ME) + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPT_ME) { tmp2 = get_clock_tick(); - if (tmp2 - tmp1 > - MMNIF_AUTO_SOCKET_TIMEOUT) + if (tmp2 - tmp1 > MMNIF_AUTO_SOCKET_TIMEOUT) { - spinlock_lock(&b->acceptors[(i + - port) - % - MMNIF_MAX_ACCEPTORS].alock); - if (b->acceptors - [(i + - port) % - MMNIF_MAX_ACCEPTORS]. - stat == - MMNIF_ACC_STAT_ACCEPT_ME) + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat == MMNIF_ACC_STAT_ACCEPT_ME) { - spinlock_unlock(&b-> - acceptors - [(i + - port) - % - MMNIF_MAX_ACCEPTORS]. - alock); + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); break; } #ifdef DEBUG_MMNIF - DEBUGPRINTF - ("mmnif_accept(): Timout occoured, switching to normal accept()"); + DEBUGPRINTF("mmnif_accept(): Timout occoured, switching to normal accept()"); -#endif /* */ - mmnif_hashdelete(b-> - acceptors[(i + - port) - % - MMNIF_MAX_ACCEPTORS]. - nsock); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - stat = - MMNIF_ACC_STAT_CLOSED; - spinlock_unlock(&b-> - acceptors[(i + - port) - % - MMNIF_MAX_ACCEPTORS].alock); +#endif + mmnif_hashdelete(b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_CLOSED; + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); goto normalaccept; } NOP8; } - p = mmnif_hashlookup(b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - nsock); - p->dest_ip = - b->acceptors[(i + port) % - MMNIF_MAX_ACCEPTORS].src_ip; - p->remote_socket = - b->acceptors[(i + port) % - MMNIF_MAX_ACCEPTORS].rsock; - spinlock_lock(&b-> - acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); - b->acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS].stat = - MMNIF_ACC_STAT_ACCEPTED; - i = b->acceptors[(i + port) % - MMNIF_MAX_ACCEPTORS].nsock; - spinlock_unlock(&b-> - acceptors[(i + - port) % - MMNIF_MAX_ACCEPTORS]. - alock); + p = mmnif_hashlookup(b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock); + p->dest_ip = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].src_ip; + p->remote_socket = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].rsock; + spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPTED; + i = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock; + spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); return i; } } return -1; } - normalaccept:return lwip_accept(s, addr, addrlen); + +normalaccept: + return lwip_accept(s, addr, addrlen); } /* mmnif_connect(): replacement of lwip_connect for @@ -1939,8 +1826,7 @@ int mmnif_poll(void *e) mmnif_t *mmnif; if (!mmnif_dev) { - DEBUGPRINTF - ("mmnif_poll(): the driver is not initialized yet\n"); + DEBUGPRINTF("mmnif_poll(): the driver is not initialized yet\n"); return -1; } mmnif = (mmnif_t *) mmnif_dev->state; @@ -1988,94 +1874,30 @@ int mmnif_poll(void *e) return 0; } -/* - * Open the interface should be called by kernel to use this network interface - */ -int mmnif_open() -{ - struct ip_addr ipaddr; - struct ip_addr netmask; - struct ip_addr gw; - - /* calculate my own ip address from core number - * Note: core 1 is the router core - */ - IP4_ADDR(&gw, 0, 0, 0, 0); - IP4_ADDR(&ipaddr, 192, 168, 0, RCCE_ue() + 1); - IP4_ADDR(&netmask, 255, 255, 255, 0); - own_ip_address += RCCE_ue() + 1; - mmnif_dev = kmalloc(sizeof(struct netif)); - - /* register our Memory Mapped Virtual IP interface in the lwip stack - * and tell him how to use the interface: - * - mmnif_dev : the device data storage - * - ipaddr : the ip address wich should be used - * - gw : the gateway wicht should be used - * - mmnif_init : the initialization which has to be done in order to use our interface - * - ethernet_input : tells him that he should get ethernet input (inclusice ARP) - * - * Note: Ethernet Input will be removed because its NOT needed and will - * be replaced with ip_input - */ - if (!netif_add - (mmnif_dev, &ipaddr, &netmask, &gw, NULL, - (netif_init_fn) mmnif_init, tcpip_input)) - { - DEBUGPRINTF("mmnif_open() : unable to add network interface\n"); - return -1; - } - - /* set our network interface to the default interface for lwip */ - netif_set_default(mmnif_dev); - - /* tell lwip all initialization is done and we want to set it ab */ - netif_set_up(mmnif_dev); - - /* test if interface is really up */ - if (!netif_is_up(mmnif_dev)) - { - DEBUGPRINTF("mmnif_open(): network interface is not up\n"); - -// return -2; - } - - /* indicate that the driver is active now */ - active = TRUE; - - /* If interrupts are not used we immediately add the polling function - * to the queue which would otherwise be done through the IRQ handler. - */ - if (reduce_irq) - mmnif_device_schedule(); - -#ifdef DEBUG_MMNIF - DEBUGPRINTF("mmnif_dev is open\n"); - -#endif /* */ - return 0; -} - /* * close the interface should be called by kernel to close this interface and release resources * Note: it's temporarly empty. Support will be added. */ -int mmnif_close() +err_t mmnif_shutdown(void) { - mmnif_t *mmnif; - if (!mmnif_dev) - { - DEBUGPRINTF - ("mmnif_close(): you closed the device before it was properly opened -.-* \n"); + err_t err; + mmnif_t* mmnif; + + if (!mmnif_dev) { + DEBUGPRINTF("mmnif_shutdown(): you closed the device before it was properly initialized -.-* \n"); + return ERR_MEM; } mmnif = (mmnif_t *) mmnif_dev->state; + err = netifapi_netif_set_down(mmnif_dev); + /* indicate that the driver is not active anymore * - this will stop the polling thread i.e. */ active = FALSE; kfree(mmnif->tx_buff[0], MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); - kfree(mmnif_dev, sizeof(mmnif_t)); //RCCE_shfree(mpb_start_address); - return 0; + + return err; } diff --git a/drivers/net/mmnif.h b/drivers/net/mmnif.h index 97305344..d5d88579 100644 --- a/drivers/net/mmnif.h +++ b/drivers/net/mmnif.h @@ -20,6 +20,11 @@ #ifndef __MMNIF_H__ #define __MMNIF_H__ +#include +#ifdef CONFIG_LWIP +#include +#include /* lwip netif */ + #define AF_MMNIF_NET 0x1337 #define MMNIF_AUTOACTIVATE_FAST_SOCKETS 0 @@ -35,14 +40,13 @@ #define listen(a,b) mmnif_listen(a,b) #endif -/* - * Initialize the network driver for mmn - */ -int mmnif_open(void); -int mmnif_close(void); +err_t mmnif_init(struct netif*); +err_t mmnif_shutdown(void); int mmnif_poll(void *e); int mmnif_worker(void *e); void mmnif_irqhandler(void); void mmnif_print_driver_status(); #endif + +#endif From 498654447cac380f30cf520a7d164a77a291f8f6 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 2 Oct 2011 14:07:13 -0700 Subject: [PATCH 10/23] move scc_memcpy.h to arch/x86/include/asm --- arch/x86/{scc => include/asm}/scc_memcpy.h | 0 arch/x86/scc/RCCE_get.c | 2 +- arch/x86/scc/RCCE_put.c | 2 +- arch/x86/scc/RCCE_recv.c | 2 +- arch/x86/scc/RCCE_send.c | 2 +- arch/x86/scc/iRCCE_get.c | 2 +- arch/x86/scc/iRCCE_put.c | 2 +- drivers/net/mmnif.c | 62 +--------------------- 8 files changed, 7 insertions(+), 67 deletions(-) rename arch/x86/{scc => include/asm}/scc_memcpy.h (100%) diff --git a/arch/x86/scc/scc_memcpy.h b/arch/x86/include/asm/scc_memcpy.h similarity index 100% rename from arch/x86/scc/scc_memcpy.h rename to arch/x86/include/asm/scc_memcpy.h diff --git a/arch/x86/scc/RCCE_get.c b/arch/x86/scc/RCCE_get.c index 5e0ed7c0..d7abb19f 100644 --- a/arch/x86/scc/RCCE_get.c +++ b/arch/x86/scc/RCCE_get.c @@ -26,7 +26,7 @@ #ifdef CONFIG_ROCKCREEK -#include "scc_memcpy.h" +#include //-------------------------------------------------------------------------------------- // FUNCTION: RCCE_get diff --git a/arch/x86/scc/RCCE_put.c b/arch/x86/scc/RCCE_put.c index 44893895..289ec00e 100644 --- a/arch/x86/scc/RCCE_put.c +++ b/arch/x86/scc/RCCE_put.c @@ -26,7 +26,7 @@ #ifdef CONFIG_ROCKCREEK -#include "scc_memcpy.h" +#include //-------------------------------------------------------------------------------------- // FUNCTION: RCCE_put diff --git a/arch/x86/scc/RCCE_recv.c b/arch/x86/scc/RCCE_recv.c index 31aeac96..30331a5b 100644 --- a/arch/x86/scc/RCCE_recv.c +++ b/arch/x86/scc/RCCE_recv.c @@ -28,7 +28,7 @@ #ifdef CONFIG_ROCKCREEK #include -#include "scc_memcpy.h" +#include //-------------------------------------------------------------------------------------- // FUNCTION: RCCE_recv_general diff --git a/arch/x86/scc/RCCE_send.c b/arch/x86/scc/RCCE_send.c index 5c7c61e0..efbca6c3 100644 --- a/arch/x86/scc/RCCE_send.c +++ b/arch/x86/scc/RCCE_send.c @@ -28,7 +28,7 @@ #ifdef CONFIG_ROCKCREEK #include -#include "scc_memcpy.h" +#include //-------------------------------------------------------------------------------------- // FUNCTION: RCCE_send_general diff --git a/arch/x86/scc/iRCCE_get.c b/arch/x86/scc/iRCCE_get.c index 8859bfed..c03a6d37 100644 --- a/arch/x86/scc/iRCCE_get.c +++ b/arch/x86/scc/iRCCE_get.c @@ -36,7 +36,7 @@ #include #if defined(COPPERRIDGE) || defined(SCC) -#include "scc_memcpy.h" +#include #endif void* iRCCE_memcpy_get(void *dest, const void *src, size_t count) diff --git a/arch/x86/scc/iRCCE_put.c b/arch/x86/scc/iRCCE_put.c index 96060cae..f16204b0 100644 --- a/arch/x86/scc/iRCCE_put.c +++ b/arch/x86/scc/iRCCE_put.c @@ -36,7 +36,7 @@ #include #if defined(COPPERRIDGE) || defined(SCC) -#include "scc_memcpy.h" +#include #endif void* iRCCE_memcpy_put(void *dest, const void *src, size_t count) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index 42450e1d..e086a397 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -44,6 +44,7 @@ #include #include +#include #include @@ -291,67 +292,6 @@ typedef struct mmnif { sem_t com_poll; } mmnif_t; -/* - * A write access, which cache line is not present, doesn't perform (on the - * current SCC architecture) a cache line fill. Therefore, the core writes - * in this case directly to the memory. - * - * The following function copies from the on-die memory (MPB) to the off-die - * memory and prefetchs its destintation. Therefore, the function avoids the - * bad behavior of a "write miss". - */ -inline static void *memcpy_get(void *dest, const void *src, size_t count) -{ - int h, i, j, k, l, m; - asm volatile ("cld;\n\t" - "1: cmpl $0, %%eax ; je 2f\n\t" - "movl (%%edi), %%edx\n\t" - "movl 0(%%esi), %%ecx\n\t" - "movl 4(%%esi), %%edx\n\t" - "movl %%ecx, 0(%%edi)\n\t" - "movl %%edx, 4(%%edi)\n\t" - "movl 8(%%esi), %%ecx\n\t" - "movl 12(%%esi), %%edx\n\t" - "movl %%ecx, 8(%%edi)\n\t" - "movl %%edx, 12(%%edi)\n\t" - "movl 16(%%esi), %%ecx\n\t" - "movl 20(%%esi), %%edx\n\t" - "movl %%ecx, 16(%%edi)\n\t" - "movl %%edx, 20(%%edi)\n\t" - "movl 24(%%esi), %%ecx\n\t" - "movl 28(%%esi), %%edx\n\t" - "movl %%ecx, 24(%%edi)\n\t" - "movl %%edx, 28(%%edi)\n\t" - "addl $32, %%esi\n\t" - "addl $32, %%edi\n\t" - "dec %%eax ; jmp 1b\n\t" - "2: movl %%ebx, %%ecx\n\t" - "movl (%%edi), %%edx\n\t" - "andl $31, %%ecx\n\t" - "rep ; movsb\n\t":"=&a" (h), "=&D"(i), "=&S"(j), - "=&b"(k), "=&c"(l), "=&d"(m):"0"(count / 32), - "1"(dest), "2"(src), "3"(count):"memory", "cc"); - return dest; -} - -/* - * In our kernel, we didn't want to use FPU registers. - * Therefore, we use standard memcpy routine - */ -inline static void *memcpy_put(void *dest, const void *src, size_t count) -{ - int32_t i, j, k; - if (BUILTIN_EXPECT(!dest || !src, 0)) - return dest; - asm volatile ("cld; rep movsl\n\t" - "movl %4, %%ecx\n\t" - "andl $3, %%ecx\n\t" - "rep movsb\n\t":"=&c" (i), "=&D"(j), - "=&S"(k):"0"(count / 4), "g"(count), "1"(dest), - "2"(src):"memory", "cc"); - return dest; -} - /* * memory maped interface helper functions */ From 4285fd528791ba53882bebee0fa5ef52a9c4999c Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 3 Oct 2011 03:52:14 -0700 Subject: [PATCH 11/23] some code clean ups --- drivers/net/mmnif.c | 74 ++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index e086a397..f9cede90 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -389,13 +389,13 @@ void mmnif_print_driver_status(void) for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) { if (mmnif->rx_buff->desc_table[i].stat != 0) - DEBUGPRINTF("0x%.2X\t0x%p\t%X\t\n", + DEBUGPRINTF("0x%.2X\t%p\t%X\t\n", mmnif->rx_buff->desc_table[i].stat, mmnif->rx_buff->desc_table[i].addr, mmnif->rx_buff->desc_table[i].len); } DEBUGPRINTF("\n\nretrive via interrupt : %d\n", mmnif->rx_buff->iv_intr); - DEBUGPRINTF("ring heap start addr: 0x%p\n", mmnif->rx_buff + sizeof(mm_rx_buffer_t)); + DEBUGPRINTF("ring heap start addr: %p\n", mmnif->rx_buff + sizeof(mm_rx_buffer_t)); DEBUGPRINTF("head: 0x%X\ttail: 0x%X\n", mmnif->rx_buff->head, mmnif->rx_buff->tail); mmnif_print_stats(); } @@ -728,7 +728,6 @@ realloc: #if USE_CACHE #if MMNIF_USE_MPB asm volatile (".byte 0x0f; .byte 0x0a;\n"); - #endif #endif if (mmnif_commit_packet(dest_ip, write_address)) @@ -736,7 +735,7 @@ realloc: DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); } #ifdef DEBUG_MMNIF_PACKET -// DEBUGPRINTF("\n SEND 0x%p with length: %d\n",(char*)heap_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); +// DEBUGPRINTF("\n SEND %p with length: %d\n",(char*)heap_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); // hex_dump(p->tot_len, p->payload); #endif @@ -898,7 +897,6 @@ realloc: #if USE_CACHE #if MMNIF_USE_MPB asm volatile (".byte 0x0f; .byte 0x0a;\n"); - #endif #endif if (mmnif_commit_packet_bypass(dest->dest_ip, write_address, dest->remote_socket)) @@ -906,7 +904,7 @@ realloc: DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); } #ifdef DEBUG_MMNIF_PACKET - // DEBUGPRINTF("\n SEND 0x%p with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); + // DEBUGPRINTF("\n SEND %p with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); // hex_dump(p->tot_len, p->payload); #endif @@ -1001,16 +999,16 @@ err_t mmnif_init(struct netif *netif) /* Alloc and clear shared memory for rx_buff */ header_size = (sizeof(mm_rx_buffer_t)); - DEBUGPRINTF("mmnif_init() : size of mm_rx_buffer_t : %d", sizeof(mm_rx_buffer_t)); + DEBUGPRINTF("mmnif_init() : size of mm_rx_buffer_t : %d\n", sizeof(mm_rx_buffer_t)); // align mpb size to the granularity of a page size header_size = (header_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); header_start_address = (void*) RCCE_shmalloc(header_size * MMNIF_CORES); - DEBUGPRINTF("RCCE_shmalloc : 0x%p", header_start_address); + DEBUGPRINTF("RCCE_shmalloc : %p\n", header_start_address); // map physical address in the virtual address space header_start_address = (void*) map_region(0, (size_t) header_start_address, (MMNIF_CORES * header_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE); - DEBUGPRINTF("map_region : 0x%p", header_start_address); + DEBUGPRINTF("map_region : %p\n", header_start_address); mmnif->rx_buff = (mm_rx_buffer_t *) (header_start_address + (header_size) * (own_ip_address - router_ip_address)); /* Alloc and clear shared memory for rx_buff @@ -1022,22 +1020,20 @@ err_t mmnif_init(struct netif *netif) #if MMNIF_USE_MPB heap_start_address = RCCE_malloc(RCCE_LINE_SIZE); - DEBUGPRINTF("MessagePassingBuffer allocated @ : 0x%p\n", heap_start_address); + DEBUGPRINTF("MessagePassingBuffer allocated @ : %p\n", heap_start_address); for (i = heap_size / RCCE_LINE_SIZE; i > 0; i--) { - if (!RCCE_malloc(RCCE_LINE_SIZE)) ; - + if (!RCCE_malloc(RCCE_LINE_SIZE)) { - - // DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); - // return ERR_MEM; + //DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); + //return ERR_MEM; } } #else heap_start_address = (void*) RCCE_shmalloc(heap_size * MMNIF_CORES); n = (int) heap_start_address; - DEBUGPRINTF("RCCE_shmalloc : 0x%p", header_start_address); + DEBUGPRINTF("RCCE_shmalloc : %p\n", header_start_address); // map physical address in the virtual address space #if USE_CACHE @@ -1048,13 +1044,13 @@ err_t mmnif_init(struct netif *netif) heap_start_address = (void*) map_region(0, (size_t) heap_start_address, (MMNIF_CORES * heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE | MAP_MPE); #endif // USE_CAHCE #endif // MMNIF_USE_MPB - DEBUGPRINTF("map_region : 0x%p", header_start_address); + DEBUGPRINTF("map_region : %p\n", header_start_address); #if MMNIF_USE_MPB mmnif->rx_heap = heap_start_address; heap_start_address = heap_start_address - (own_ip_address - router_ip_address) * 0x2000; - DEBUGPRINTF("heap_start_address : 0x%p", heap_start_address); + DEBUGPRINTF("heap_start_address : %p\n", heap_start_address); // heap_start_address = 0xC0000000; // mmnif->rx_heap = heap_start_address + (heap_size) * (own_ip_address - router_ip_address); @@ -1070,10 +1066,11 @@ err_t mmnif_init(struct netif *netif) memset(mmnif->rx_buff, 0, header_size); memset(mmnif->rx_heap, 0, heap_size); -#if USE_CACHE *((int *)RCCE_fool_write_combine_buffer) = 1; - +#if USE_CACHE + asm volatile (".byte 0x0f; .byte 0x0a;\n"); #endif + if (own_ip_address == router_ip_address) { kprintf("Test0: MEMCPY 2048B"); @@ -1082,14 +1079,13 @@ err_t mmnif_init(struct netif *netif) { memcpy(mmnif->rx_heap + heap_size, mmnif->rx_heap, 2048); -#if USE_CACHE *((int *)RCCE_fool_write_combine_buffer) = 1; - flush_cache(); - +#if USE_CACHE + asm volatile (".byte 0x0f; .byte 0x0a;\n"); #endif memcpy(mmnif->rx_heap, mmnif->rx_heap, 2048); } tmp2 = get_clock_tick(); - kprintf("memcpy'd' %d bytes in %d ticks", n * 2048, (tmp2 - tmp1)); + kprintf("memcpy'd' %d bytes in %d ticks\n", n * 2048, (tmp2 - tmp1)); } /* set initial values @@ -1233,10 +1229,7 @@ anotherpacket: packet = (char *)b->desc_table[rdesc].addr; length = b->desc_table[rdesc].len; break; - } - - else - { + } else { bp = mmnif_hashlookup(b->desc_table[rdesc]. fast_sock); if (!bp) @@ -1246,10 +1239,7 @@ anotherpacket: b->desc_table[rdesc].fast_sock); mmnif->rx_buff->desc_table[rdesc].stat = MMNIF_STATUS_PROC; mmnif_rxbuff_free(); - } - - else - { + } else { b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; #if MMNIF_FAST_SOCKET_BLOCK @@ -1295,7 +1285,7 @@ anotherpacket: */ #ifdef DEBUG_MMNIF_PACKET - DEBUGPRINTF("\n RECIEVED - 0x%p with legth: %d\n", packet, length); + DEBUGPRINTF("\n RECIEVED - %p with legth: %d\n", packet, length); hex_dump(length, packet); #endif @@ -1311,8 +1301,7 @@ anotherpacket: } #if USE_CACHE asm volatile (".byte 0x0f; .byte 0x0a;\n"); - -#endif /* */ +#endif /* copy packet to pbuf structure going through linked list */ for (q = p, i = 0; q != NULL; q = q->next) @@ -1320,11 +1309,9 @@ anotherpacket: #if MMNIF_USE_MPB memcpy_get((uint8_t *) q->payload, &packet[i], q->len); - -#else /* */ +#else memcpy((uint8_t *) q->payload, &packet[i], q->len); - -#endif /* */ +#endif i += q->len; } @@ -1430,7 +1417,7 @@ static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) */ #ifdef DEBUG_MMNIF_PACKET - DEBUGPRINTF("\n RECIEVED - 0x%p with legth: %d\n", packet, length); + DEBUGPRINTF("\n RECIEVED - %p with legth: %d\n", packet, length); hex_dump(length, packet); #endif /* */ @@ -1725,16 +1712,15 @@ int mmnif_closesocket(int s) */ void mmnif_irqhandler() { - mmnif_t *mmnif; + //mmnif_t *mmnif; /* return if mmnif_dev is not yet initialized */ if (!mmnif_dev) { - DEBUGPRINTF - ("mmnif_irqhandler(): the driver is not initialized yet\n"); + DEBUGPRINTF("mmnif_irqhandler(): the driver is not initialized yet\n"); return; } - mmnif = (mmnif_t *) mmnif_dev->state; + //mmnif = (mmnif_t *) mmnif_dev->state; mmnif_rx(mmnif_dev); // while (mmnif->rx_buff->dcount < MMNIF_MAX_DESCRIPTORS) From ea4af96cdec1f3d9ece79b3997b4af3a8bb13e23 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 3 Oct 2011 03:52:50 -0700 Subject: [PATCH 12/23] add client version of the netio benchmark --- apps/netio.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 4 deletions(-) diff --git a/apps/netio.c b/apps/netio.c index 4df88f8f..66f875c5 100644 --- a/apps/netio.c +++ b/apps/netio.c @@ -24,8 +24,14 @@ #include #include +#ifdef CONFIG_ROCKCREEK +#include +#include +#include +#endif + /* - * This implements a netio server. + * This implements a netio server and client (only TCP version). * The client sends a command word (4 bytes) then a data length word (4 bytes). * If the command is "receive", the server is to consume "data length" bytes into * a circular buffer until the first byte is non-zero, then it is to consume @@ -56,9 +62,12 @@ typedef struct #define DEFAULTPORT 0x494F /* "IO" */ #define TMAXSIZE 65536 +static int tSizes[] = {1024, 2048, 4096, 8192, 16384, 32767}; +static size_t ntSizes = sizeof(tSizes) / sizeof(int); static int nPort = DEFAULTPORT; static const int sobufsize = 131072; static struct in_addr addr_local; +static struct in_addr addr_server; static int send_data(int socket, void *buffer, size_t size, int flags) { @@ -131,7 +140,7 @@ static int TCPServer(void* arg) if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) { kprintf("Netio: Not enough memory\n"); - return -EINVAL; + return -1; } if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) { @@ -280,10 +289,170 @@ static int TCPServer(void* arg) return 0; } +int TCP_Bench(void) +{ + char *cBuffer; + CONTROL ctl; + long long nData; + int i; + struct sockaddr_in sa_server; + int server; + int rc, err; + int nByte; + uint64_t start, end; + uint32_t freq = get_cpu_frequency(); /* in MHz */ + + if ((cBuffer = InitBuffer(TMAXSIZE)) == NULL) + { + kprintf("Netio: Not enough memory\n"); + return -1; + } + + if ((server = socket(PF_INET, SOCK_STREAM, 0)) < 0) + { + kprintf("socket failed: %d\n", server); + kfree(cBuffer, TMAXSIZE); + return -2; + } + + setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize)); + setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize)); + + sa_server.sin_family = AF_INET; + sa_server.sin_port = htons(nPort); + sa_server.sin_addr = addr_server; + + if ((err = connect(server, (struct sockaddr *) &sa_server, sizeof(sa_server))) < 0) + { + kprintf("connect failed: %d\n", err); + closesocket(server); + kfree(cBuffer, TMAXSIZE); + return -2; + } + + kprintf("\nTCP connection established.\n"); + + for (i = 0; i < ntSizes; i++) + { + kprintf("Packet size %s bytes: ", PacketSize(tSizes[i])); + + /* tell the server we will send it data now */ + + ctl.cmd = htonl(CMD_C2S); + ctl.data = htonl(tSizes[i]); + + if (send_data(server, (void *) &ctl, CTLSIZE, 0)) + break; + + /* 1 - Tx test */ + + start = rdtsc(); + nData = 0; + cBuffer[0] = 0; + + do + { + //GenerateRandomData(cBuffer, tSizes[i]); + + for (nByte = 0; nByte < tSizes[i]; ) + { + rc = send(server, cBuffer + nByte, tSizes[i] - nByte, 0); + + if (rc < 0) + { + kprintf("send failed: %d\n", rc); + break; + } + + if (rc > 0) + nByte += rc; + } + + nData += tSizes[i]; + end = rdtsc(); + } while((end-start)/freq < 6000000ULL /* = 6s */); + + kprintf("%llu KBytes/s\n", (nData/1024ULL)/((end-start)/(1000000ULL*freq))); + + kprintf(" Tx, "); + + cBuffer[0] = 1; + + if (send_data(server, cBuffer, tSizes[i], 0)) + break; + + /* tell the server we expect him to send us data now */ + + ctl.cmd = htonl(CMD_S2C); + ctl.data = htonl(tSizes[i]); + + if (send_data(server, (void *) &ctl, CTLSIZE, 0)) + break; + + /* 2 - Rx test */ + + start = rdtsc(); + nData = 0; + cBuffer[0] = 0; + rc = 0; + + do + { + for (nByte = 0; nByte < tSizes[i]; ) + { + rc = recv(server, cBuffer + nByte, tSizes[i] - nByte, 0); + + if (rc < 0) + { + kprintf("recv failed: %d\n", rc); + break; + } + + if (rc > 0) + nByte += rc; + } + + nData += tSizes[i]; + } while (cBuffer[0] == 0 && rc > 0); + + end = rdtsc(); + kprintf("%llu KBytes/s\n", (nData/1024ULL)/((end-start)/(1000000ULL*freq))); + + kprintf(" Rx.\n"); + } + + ctl.cmd = htonl(CMD_QUIT); + ctl.data = 0; + + send_data(server, (void *) &ctl, CTLSIZE, 0); + + kprintf("Done.\n"); + + closesocket(server); + kfree(cBuffer, TMAXSIZE); + + return 0; +} + int netio_init(void) { - addr_local.s_addr = INADDR_ANY; + int err = 0; - return create_kernel_task(NULL, TCPServer, NULL, NORMAL_PRIO); + addr_local.s_addr = INADDR_ANY; + //addr_server.s_addr = inet_addr("192.168.28.254"); + addr_server.s_addr = inet_addr("192.168.0.2"); + +#ifdef CONFIG_ROCKCREEK + if (RCCE_ue() == 1) { + err = create_kernel_task(NULL, TCPServer, NULL, NORMAL_PRIO); + } else if (RCCE_ue() == 0) { + sleep(3); + err = TCP_Bench(); + } +#else + err = create_kernel_task(NULL, TCPServer, NULL, NORMAL_PRIO); +#endif + + return err; } #endif From fbb0b9237b2aef766afdc6f35e201e72527c4b3c Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 3 Oct 2011 03:53:15 -0700 Subject: [PATCH 13/23] add mmnif_irqhandler in the default handler --- arch/x86/scc/icc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 065c086f..b5ef9002 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -90,7 +90,7 @@ static void intr_handler(struct state *s) int tmp, z; #ifdef CONFIG_LWIP - //mmnif_irqhandler(); + mmnif_irqhandler(); #endif z = Z_PID(RC_COREID[my_ue]); From f2a393004666e02fc59ab2e9d9bb0a0412614861 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 3 Oct 2011 23:59:52 -0700 Subject: [PATCH 14/23] cosmetic changes --- drivers/net/mmnif.c | 275 +++++++++++++------------------------------- drivers/net/mmnif.h | 1 - 2 files changed, 77 insertions(+), 199 deletions(-) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index f9cede90..707ffe99 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -51,7 +51,7 @@ #define TRUE 1 #define FALSE 0 -#define DEBUGPRINTF(x,...) kprintf(x,##__VA_ARGS__) +#define DEBUGPRINTF(x,...) LWIP_DEBUGF(NETIF_DEBUG, (x, ##__VA_ARGS__)) #define DEBUG_MMNIF //#define DEBUG_MMNIF_PACKET @@ -71,7 +71,7 @@ #define MMNIF_AUTO_SOCKET_TIMEOUT 500 -#define MMNIF_FAST_SOCKET_BLOCK 0 +#define MMNIF_FAST_SOCKET_BLOCK 1 #ifdef DEBUG_MMNIF #include "util.h" /* hex dump */ @@ -112,14 +112,6 @@ static int npseudosocket = MMNIF_PSEUDO_SOCKET_START; static spinlock_t pseudolock; -/* decide whether it's polling mode or not - */ -static int reduce_irq = 0; - -/* this will be set by open() and close() and shows wether the driver is running or not -*/ -static int active = 0; - /* IP address of the local core and the router core to get packets forwarded */ static unsigned int own_ip_address = 0xC0A80000; /* 192.168.0.0 */ @@ -140,13 +132,9 @@ static unsigned int heap_size = 0; */ static struct netif* mmnif_dev = NULL; -/* thread variables */ -static tid_t polling_thread; - /* accept struct */ typedef struct acceptor { - /* stat: status of the acceptor * src_ip: where did the connect request came from * port: port on which the acceptor is listening @@ -165,7 +153,6 @@ typedef struct acceptor { /* bypass descriptor struct */ typedef struct bypass_rxdesc { - /* socket : hashtarget * remote_socket: socket on the remote end * cnt : atomic counter for the recv function @@ -182,7 +169,6 @@ typedef struct bypass_rxdesc { */ static bypass_rxdesc_t mmnif_hashtable[MMNIF_HASHTABLE_SIZE]; typedef struct mmnif_device_stats { - /* device stats (granularity in packets): * - recieve errors * - recieve successes @@ -201,18 +187,13 @@ typedef struct mmnif_device_stats { /* Heuristics : * - how many times an budget overflow occured * - how many times the polling thread polled without recieving a new message - * - how many messages are recieved via interrupt - * - how many messages are recieved via the polling thread */ unsigned int bdg_overflow; unsigned int pll_empty; - unsigned int rx_intr; - unsigned int rx_poll; } mmnif_device_stats_t; /* receive descror structure */ typedef struct rx_desc { - /* stat : status of the descriptor * len : length of the packet * addr : memory address of the packet @@ -227,13 +208,6 @@ typedef struct rx_desc { /* receive ring buffer structure */ typedef struct mm_rx_buffer { - - /* iv_intr: inform via interrupt - * states whether the interface wants to recieve an interrupt for - * incoming packet - */ - uint16_t iv_intr; - /* memory "pseudo-ring/heap" * packets are always in one single chunk of memory * head : head of allocated memory region @@ -273,6 +247,9 @@ typedef struct mmnif { struct eth_addr *ethaddr; uint32_t ipaddr; + // checks the TCPIP thread already the rx buffers? + uint8_t check_in_progress; + /* memory interaction variables: * - transmit queue * - pointer to transmit buffer @@ -296,16 +273,6 @@ typedef struct mmnif { * memory maped interface helper functions */ -/* mmnif_device_schedule() : - * if there is no interupt used to indicate new packets - * this creates a polling thread which looks for data - * itself - */ -inline static int mmnif_device_schedule(void) -{ - return create_kernel_task(&polling_thread, mmnif_poll, NULL, NORMAL_PRIO); -} - /* trigger an interrupt on the remote processor * so he knows there is a packet to read */ @@ -350,18 +317,18 @@ static mmnif_device_stats_t mmnif_get_device_stats(void) static void mmnif_print_stats(void) { mmnif_t *mmnif; + if (!mmnif_dev) { DEBUGPRINTF ("mmnif_print_stats(): the device is not initialized yet.\n"); return; } + mmnif = (mmnif_t *) mmnif_dev->state; DEBUGPRINTF("/dev/mmnif - stats:\n"); DEBUGPRINTF("Received: %d packets successfull\n", mmnif->stats.rx); DEBUGPRINTF("Received: %d bytes\n", mmnif->stats.rx_bytes); - DEBUGPRINTF("interrupts: %d\n", mmnif->stats.rx_intr); - DEBUGPRINTF("polling: %d\n", mmnif->stats.rx_poll); DEBUGPRINTF("Received: %d packets containuing errors\n", mmnif->stats.rx_err); DEBUGPRINTF("Transmitted: %d packests successfull\n", mmnif->stats.tx); DEBUGPRINTF("Transmitted: %d bytes\n", mmnif->stats.tx_bytes); @@ -375,17 +342,20 @@ void mmnif_print_driver_status(void) { mmnif_t *mmnif; int i; + if (!mmnif_dev) { DEBUGPRINTF("mmnif_print_driver_status(): the device is not initialized yet.\n"); return; } + mmnif = (mmnif_t *) mmnif_dev->state; DEBUGPRINTF("/dev/mmnif driver status: \n\n"); DEBUGPRINTF("rx_buf: 0xp\n", mmnif->rx_buff); DEBUGPRINTF("free descriptors : %d\n\n", mmnif->rx_buff->dcount); DEBUGPRINTF("descriptor table: (only print descriptors in use)\n"); DEBUGPRINTF("status\taddr\tsize\n"); + for (i = 0; i < MMNIF_MAX_DESCRIPTORS; i++) { if (mmnif->rx_buff->desc_table[i].stat != 0) @@ -394,7 +364,7 @@ void mmnif_print_driver_status(void) mmnif->rx_buff->desc_table[i].addr, mmnif->rx_buff->desc_table[i].len); } - DEBUGPRINTF("\n\nretrive via interrupt : %d\n", mmnif->rx_buff->iv_intr); + DEBUGPRINTF("ring heap start addr: %p\n", mmnif->rx_buff + sizeof(mm_rx_buffer_t)); DEBUGPRINTF("head: 0x%X\ttail: 0x%X\n", mmnif->rx_buff->head, mmnif->rx_buff->tail); mmnif_print_stats(); @@ -633,7 +603,7 @@ static err_t mmnif_tx(struct netif *netif, struct pbuf *p) uint8_t build_buff = TRUE; uint32_t dest_ip = mmnif_get_destination(netif, p); //uint8_t chances = 20; - mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest_ip - 1) * header_size); + //mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest_ip - 1) * header_size); spinlock_lock(&mmnif->lock); mmnif->tx_queue++; @@ -651,7 +621,7 @@ static err_t mmnif_tx(struct netif *netif, struct pbuf *p) if (p->tot_len > MMNIF_TX_BUFFERLEN) { - DEBUGPRINTF("mmnif_tx(): packet is longer than %d bytes\n",MMNIF_TX_BUFFERLEN); + DEBUGPRINTF("mmnif_tx(): packet is longer than %d bytes\n", MMNIF_TX_BUFFERLEN); goto drop_packet; } @@ -713,15 +683,12 @@ realloc: memcpy_put(write_address, mmnif->tx_buff[slot], CLINE_ALIGN(p->tot_len)); #else memcpy((void*)write_address, mmnif->tx_buff[slot], CLINE_ALIGN(p->tot_len)); - #endif else #if MMNIF_USE_MPB memcpy_put(write_address, p->payload, CLINE_ALIGN(p->tot_len)); - #else memcpy((void*)write_address, p->payload, CLINE_ALIGN(p->tot_len)); - #endif *((int *)RCCE_fool_write_combine_buffer) = 1; @@ -734,6 +701,7 @@ realloc: { DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n"); } + #ifdef DEBUG_MMNIF_PACKET // DEBUGPRINTF("\n SEND %p with length: %d\n",(char*)heap_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2); // hex_dump(p->tot_len, p->payload); @@ -748,8 +716,7 @@ realloc: LINK_STATS_INC(link.xmit); mmnif->stats.tx++; mmnif->stats.tx_bytes += p->tot_len; - if (rb->iv_intr) - mmnif_trigger_irq(dest_ip); + mmnif_trigger_irq(dest_ip); return ERR_OK; @@ -758,8 +725,8 @@ drop_packet: */ #ifdef DEBUG_MMNIF DEBUGPRINTF("mmnif_tx(): packet dropped"); +#endif -#endif /* */ spinlock_lock(&mmnif->lock); mmnif->tx_queue--; spinlock_unlock(&mmnif->lock); @@ -783,6 +750,7 @@ static bypass_rxdesc_t *mmnif_hashlookup(int s) return p; p = &mmnif_hashtable[(s + i + 1) % MMNIF_HASHTABLE_SIZE]; } + return 0; } @@ -793,9 +761,11 @@ static int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip) { bypass_rxdesc_t *p; int i; + p = mmnif_hashlookup(sock); if (p != 0) return -1; + for (i = 0; i < MMNIF_HASHTABLE_SIZE; i++) { p = &mmnif_hashtable[(sock + i) % MMNIF_HASHTABLE_SIZE]; @@ -807,6 +777,7 @@ static int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip) return 0; } } + return -1; } @@ -833,6 +804,7 @@ static int mmnif_hashdelete(int sock) return 0; } } + return -1; } @@ -845,7 +817,7 @@ static err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, i uint32_t write_address; bypass_rxdesc_t *dest = mmnif_hashlookup(s); //uint32_t exp_delay = 2; - mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest->dest_ip - 1) * header_size); + //mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest->dest_ip - 1) * header_size); /* Perform serveral sanity checks on the packet and the buffers: * - is the output packet to big? @@ -912,10 +884,10 @@ realloc: LINK_STATS_INC(link.xmit); mmnif->stats.tx++; mmnif->stats.tx_bytes += size; - if (rb->iv_intr) - mmnif_trigger_irq(dest->dest_ip); + mmnif_trigger_irq(dest->dest_ip); return ERR_OK; -//drop_packet: + +drop_packet: /* drop packet for one or another reason */ LINK_STATS_INC(link.drop); @@ -976,11 +948,10 @@ err_t mmnif_init(struct netif *netif) mmnif_t *mmnif; uint32_t i; int num = 0; - int tmp1, tmp2, n; + //int tmp1, tmp2, n; #ifdef DEBUG_MMNIF DEBUGPRINTF("mmnif init attempt\n"); - #endif mmnif_dev = netif; @@ -994,7 +965,7 @@ err_t mmnif_init(struct netif *netif) DEBUGPRINTF("mmnif init():out of memory\n"); return ERR_MEM; } - memset(mmnif, 0, sizeof(mmnif_t)); + memset(mmnif, 0x00, sizeof(mmnif_t)); /* Alloc and clear shared memory for rx_buff */ @@ -1032,7 +1003,6 @@ err_t mmnif_init(struct netif *netif) #else heap_start_address = (void*) RCCE_shmalloc(heap_size * MMNIF_CORES); - n = (int) heap_start_address; DEBUGPRINTF("RCCE_shmalloc : %p\n", header_start_address); // map physical address in the virtual address space @@ -1048,8 +1018,7 @@ err_t mmnif_init(struct netif *netif) #if MMNIF_USE_MPB mmnif->rx_heap = heap_start_address; - heap_start_address = - heap_start_address - (own_ip_address - router_ip_address) * 0x2000; + heap_start_address = heap_start_address - (own_ip_address - router_ip_address) * 0x2000; DEBUGPRINTF("heap_start_address : %p\n", heap_start_address); // heap_start_address = 0xC0000000; @@ -1063,14 +1032,15 @@ err_t mmnif_init(struct netif *netif) DEBUGPRINTF("mmnif init(): allocating shared memory failed\n"); return ERR_MEM; } - memset(mmnif->rx_buff, 0, header_size); - memset(mmnif->rx_heap, 0, heap_size); + memset(mmnif->rx_buff, 0x00, header_size); + memset(mmnif->rx_heap, 0x00, heap_size); *((int *)RCCE_fool_write_combine_buffer) = 1; #if USE_CACHE asm volatile (".byte 0x0f; .byte 0x0a;\n"); #endif +#if 0 if (own_ip_address == router_ip_address) { kprintf("Test0: MEMCPY 2048B"); @@ -1087,6 +1057,7 @@ err_t mmnif_init(struct netif *netif) } tmp2 = get_clock_tick(); kprintf("memcpy'd' %d bytes in %d ticks\n", n * 2048, (tmp2 - tmp1)); } +#endif /* set initial values */ @@ -1103,11 +1074,6 @@ err_t mmnif_init(struct netif *netif) */ sem_init(&mmnif->com_poll, 0); - /* inform via interrupt should be the dafault - */ - if (!reduce_irq) - mmnif->rx_buff->iv_intr = TRUE; - /* Alloc and clear internal memory for tx_buff */ mmnif->tx_buff[0] = kmalloc(MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); @@ -1117,7 +1083,7 @@ err_t mmnif_init(struct netif *netif) return ERR_MEM; } mmnif->tx_queue = 0; - memset(mmnif->tx_buff[0], 0, MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); + memset(mmnif->tx_buff[0], 0x00, MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); for (i=0; itx_buff[i + 1] = mmnif->tx_buff[i] + MMNIF_TX_BUFFERLEN; @@ -1171,15 +1137,6 @@ err_t mmnif_init(struct netif *netif) /* hardware address length */ netif->hwaddr_len = 0; - /* indicate that the driver is active now */ - active = TRUE; - - /* If interrupts are not used we immediately add the polling function - * to the queue which would otherwise be done through the IRQ handler. - */ - if (reduce_irq) - mmnif_device_schedule(); - #ifdef DEBUG_MMNIF DEBUGPRINTF("mmnif init complete\n"); #endif @@ -1195,15 +1152,16 @@ static void mmnif_rx(struct netif *netif) mmnif_t *mmnif = netif->state; mm_rx_buffer_t *b = mmnif->rx_buff; uint16_t length = 0; - struct pbuf *p = NULL; + struct pbuf *p; struct pbuf *q; char *packet = NULL; uint32_t i, j; - uint8_t rdesc = 0xFF; + uint8_t rdesc; err_t err = ERR_OK; bypass_rxdesc_t *bp; anotherpacket: + rdesc = 0xFF; spinlock_lock(&b->rlock); /* check if this call to mmnif_rx makes any sense @@ -1211,53 +1169,46 @@ anotherpacket: if (b->desc_table[b->dread].stat == MMNIF_STATUS_FREE) { spinlock_unlock(&b->rlock); - return; + goto out; } /* search the packet whose transmission is finished */ for (i = 0, j = b->dread; i < MMNIF_MAX_DESCRIPTORS; i++) { - if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == - MMNIF_STATUS_RDY) + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_RDY) { rdesc = (j + i) % MMNIF_MAX_DESCRIPTORS; - if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS]. - fast_sock == -1) + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].fast_sock == -1) { b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; packet = (char *)b->desc_table[rdesc].addr; length = b->desc_table[rdesc].len; break; } else { - bp = mmnif_hashlookup(b->desc_table[rdesc]. - fast_sock); + bp = mmnif_hashlookup(b->desc_table[rdesc].fast_sock); if (!bp) { - DEBUGPRINTF - ("mmnif_rx(): no fast socket associated with %d", - b->desc_table[rdesc].fast_sock); + DEBUGPRINTF("mmnif_rx(): no fast socket associated with %d", b->desc_table[rdesc].fast_sock); mmnif->rx_buff->desc_table[rdesc].stat = MMNIF_STATUS_PROC; mmnif_rxbuff_free(); } else { b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC; - #if MMNIF_FAST_SOCKET_BLOCK sem_post(&bp->sem); - #else atomic_int32_inc(&bp->cnt); - #endif } spinlock_unlock(&b->rlock); - return; + goto out; } } + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_FREE) { spinlock_unlock(&b->rlock); - return; + goto out; } } spinlock_unlock(&b->rlock); @@ -1265,15 +1216,16 @@ anotherpacket: /* if there is no packet finished we encountered a random error */ if (rdesc == 0xFF) - return; + goto out; /* If length is zero return silently */ if (length == 0) { DEBUGPRINTF("mmnif_rx(): empty packet error\n"); - return; + goto out; } + if (length < sizeof(struct ip_hdr) || length > netif->mtu) { DEBUGPRINTF("mmnif_rx(): illegal packet length %d => drop the packet\n", length); @@ -1283,11 +1235,9 @@ anotherpacket: /* From now on there is a real packet and it * has to be worked on */ - #ifdef DEBUG_MMNIF_PACKET DEBUGPRINTF("\n RECIEVED - %p with legth: %d\n", packet, length); hex_dump(length, packet); - #endif /* Build the pbuf for the packet so the lwip @@ -1299,6 +1249,7 @@ anotherpacket: DEBUGPRINTF("mmnif_rx(): low on mem - packet dropped\n"); goto drop_packet; } + #if USE_CACHE asm volatile (".byte 0x0f; .byte 0x0a;\n"); #endif @@ -1306,7 +1257,6 @@ anotherpacket: /* copy packet to pbuf structure going through linked list */ for (q = p, i = 0; q != NULL; q = q->next) { - #if MMNIF_USE_MPB memcpy_get((uint8_t *) q->payload, &packet[i], q->len); #else @@ -1325,8 +1275,11 @@ anotherpacket: */ mmnif_rxbuff_free(); - /* full packet send to tcpip_thread to process */ - if ((err = mmnif_dev->input(p, mmnif_dev)) != ERR_OK) + /* + * This function is called in the context of the tcpip thread. + * Therefore, we are able to call directly the input functions. + */ + if ((err = ip_input(p, mmnif_dev)) != ERR_OK) { DEBUGPRINTF("mmnif_rx: IP input error\n"); pbuf_free(p); @@ -1336,13 +1289,7 @@ anotherpacket: LINK_STATS_INC(link.xmit); mmnif->stats.rx++; mmnif->stats.rx_bytes += p->tot_len; - if (mmnif->rx_buff->iv_intr) - mmnif->stats.rx_intr++; - - else - mmnif->stats.rx_poll++; goto anotherpacket; - return; drop_packet: spinlock_lock(&mmnif->rx_buff->rlock); @@ -1352,6 +1299,8 @@ drop_packet: LINK_STATS_INC(link.drop); mmnif->stats.rx_err++; +out: + mmnif->check_in_progress = 0; return; } @@ -1382,10 +1331,8 @@ static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) */ for (i = 0, j = b->dread; i < MMNIF_MAX_DESCRIPTORS; i++) { - if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == - MMNIF_STATUS_INPROC - && b->desc_table[(j + i) % - MMNIF_MAX_DESCRIPTORS].fast_sock != -1) + if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_INPROC + && b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].fast_sock != -1) { rdesc = (j + i) % MMNIF_MAX_DESCRIPTORS; packet = (char *)b->desc_table[rdesc].addr; @@ -1441,11 +1388,7 @@ static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len) LINK_STATS_INC(link.xmit); mmnif->stats.rx++; mmnif->stats.rx_bytes += length; - if (mmnif->rx_buff->iv_intr) - mmnif->stats.rx_intr++; - else - mmnif->stats.rx_poll++; return length; drop_packet: @@ -1466,12 +1409,12 @@ int mmnif_recv(int s, void *data, uint32_t len, int flags) { bypass_rxdesc_t *p = mmnif_hashlookup(s); int ret; + if (p == 0) return lwip_recv(s, data, len, flags); #if MMNIF_FAST_SOCKET_BLOCK sem_wait(&p->sem, 0); - #else while (!atomic_int32_read(&p->cnt)) { @@ -1480,7 +1423,8 @@ int mmnif_recv(int s, void *data, uint32_t len, int flags) NOP8; } -#endif /* */ +#endif + ret = mmnif_rx_bypass(mmnif_dev, s, data, len); atomic_int32_dec(&p->cnt); @@ -1521,8 +1465,7 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) { for (i = 0; i < MMNIF_MAX_ACCEPTORS; i++) { - if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS]. - stat == MMNIF_ACC_STAT_CLOSED) + if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat == MMNIF_ACC_STAT_CLOSED) { spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].port = port; @@ -1532,8 +1475,10 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock = npseudosocket++; spinlock_unlock(&pseudolock); spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPT_ME) NOP8; + p = mmnif_hashlookup(b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock); p->dest_ip = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].src_ip; p->remote_socket = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].rsock; @@ -1541,6 +1486,7 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPTED; i = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock; spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + return i; } } @@ -1561,6 +1507,7 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock = npseudosocket++; spinlock_unlock(&pseudolock); spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPT_ME) { tmp2 = get_clock_tick(); @@ -1583,6 +1530,7 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) } NOP8; } + p = mmnif_hashlookup(b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock); p->dest_ip = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].src_ip; p->remote_socket = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].rsock; @@ -1590,6 +1538,7 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen) b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_ACCEPTED; i = b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock; spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock); + return i; } } @@ -1701,18 +1650,20 @@ int mmnif_closesocket(int s) if (p == 0) return -1; + mmnif_hashdelete(s); if ((unsigned int)s < MMNIF_PSEUDO_SOCKET_START) return lwip_close(s); + return 0; } /* mmnif_irqhandler(): * handles the incomint interrupts */ -void mmnif_irqhandler() +void mmnif_irqhandler(void) { - //mmnif_t *mmnif; + mmnif_t *mmnif; /* return if mmnif_dev is not yet initialized */ if (!mmnif_dev) @@ -1720,84 +1671,16 @@ void mmnif_irqhandler() DEBUGPRINTF("mmnif_irqhandler(): the driver is not initialized yet\n"); return; } - //mmnif = (mmnif_t *) mmnif_dev->state; - mmnif_rx(mmnif_dev); -// while (mmnif->rx_buff->dcount < MMNIF_MAX_DESCRIPTORS) -// { -// mmnif_rx(mmnif_dev); - -// if (mmnif->rx_buff->dcount < MMNIF_MAX_DESCRIPTORS/2) -// { -// budget_overflow_count++; -// if (budget_overflow_count >= MMNIF_INTR_BUDGET) -// { -// mmnif->rx_buff->iv_intr = FALSE; -// budget_overflow_count = 0; -// sem_post(&mmnif->com_poll); -// break; -// } -// } -// else -// budget_overflow_count = 0; - -// } -} - -/* - * the poll function wich is used if no interrupt wake up our mmnif_rx functions - */ -int mmnif_poll(void *e) -{ - mmnif_t *mmnif; - if (!mmnif_dev) - { - DEBUGPRINTF("mmnif_poll(): the driver is not initialized yet\n"); - return -1; - } mmnif = (mmnif_t *) mmnif_dev->state; - if (!reduce_irq) - { - sem_wait(&mmnif->com_poll, 0); - } -#ifdef DEBUG_MMNIF - DEBUGPRINTF("mmnif_poll(): polling thread launched", mmnif->rx_buff); -#endif /* */ - - /*run while driver is up */ - while (active) - { - while (mmnif->rx_buff->desc_table[mmnif->rx_buff->dread].stat != - MMNIF_STATUS_RDY) - { - mmnif->stats.pll_empty++; - if (mmnif->stats.pll_empty >= MMNIF_POLL_BUDGET) - { - - /* enable interrupts and suspend polling - * - */ - mmnif->rx_buff->iv_intr = TRUE; - mmnif->stats.pll_empty = 0; - -#ifdef DEBUG_MMNIF - DEBUGPRINTF - ("mmnif_poll(): heuristical interrupts enabled\n"); - -#endif /* */ - sem_wait(&mmnif->com_poll, 0); - } - - /* uncomment this to test only polling - */ - // mmnif->stats.pll_empty = 0; + if (!mmnif->check_in_progress) { + if (tcpip_callback_with_block(mmnif_rx, (void*) mmnif_dev, 0) == ERR_OK) { + mmnif->check_in_progress = 1; + } else { + DEBUGPRINTF("rckemacif_handler: unable to send a poll request to the tcpip thread\n"); } - mmnif->stats.pll_empty = 0; - mmnif_rx(mmnif_dev); } - - return 0; } /* @@ -1817,13 +1700,9 @@ err_t mmnif_shutdown(void) err = netifapi_netif_set_down(mmnif_dev); - /* indicate that the driver is not active anymore - * - this will stop the polling thread i.e. - */ - active = FALSE; kfree(mmnif->tx_buff[0], MMNIF_TX_QUEUELEN * MMNIF_TX_BUFFERLEN); - //RCCE_shfree(mpb_start_address); + mmnif_dev = NULL; return err; } diff --git a/drivers/net/mmnif.h b/drivers/net/mmnif.h index d5d88579..36e0ee8e 100644 --- a/drivers/net/mmnif.h +++ b/drivers/net/mmnif.h @@ -42,7 +42,6 @@ err_t mmnif_init(struct netif*); err_t mmnif_shutdown(void); -int mmnif_poll(void *e); int mmnif_worker(void *e); void mmnif_irqhandler(void); void mmnif_print_driver_status(); From 824540f31369b775e296958606013f400c4565c5 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:00:32 -0700 Subject: [PATCH 15/23] use correct data types --- apps/netio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/netio.c b/apps/netio.c index 66f875c5..39f24ef1 100644 --- a/apps/netio.c +++ b/apps/netio.c @@ -293,7 +293,7 @@ int TCP_Bench(void) { char *cBuffer; CONTROL ctl; - long long nData; + uint64_t nData; int i; struct sockaddr_in sa_server; int server; From 3735a23fd673bd1fc631a1ffc5f202c098ce189c Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:02:33 -0700 Subject: [PATCH 16/23] =?UTF-8?q?insert=20init=20code=20f=C3=BCr=20the=20m?= =?UTF-8?q?mnif=20device?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/init.c | 47 +++++++++++++++++++++++++++++++++++++++-------- kernel/main.c | 5 ++++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index 4d54b4d4..ff83c477 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -71,6 +71,9 @@ int lowlevel_init(void) #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) static struct netif default_netif; +#ifdef CONFIG_ROCKCREEK +static struct netif mmnif_netif; +#endif static int init_netifs(void) { @@ -83,8 +86,9 @@ static int init_netifs(void) // Set up the lwIP network interface memset(&default_netif, 0x00, sizeof(struct netif)); - #ifdef CONFIG_ROCKCREEK + memset(&mmnif_netif, 0x00, sizeof(struct netif)); + /* Set network address variables */ IP4_ADDR(&gw, 192,168,28,254); IP4_ADDR(&ipaddr, 192,168,28,RCCE_ue()+1); @@ -92,12 +96,38 @@ static int init_netifs(void) /* Bring up the network interface */ if ((err = netifapi_netif_add(&default_netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, tcpip_input)) != ERR_OK) { - kprintf("Unable to add network interface: err = %d\n", err); + kprintf("Unable to add the network interface: err = %d\n", err); return -ENODEV; } netifapi_netif_set_default(&default_netif); netifapi_netif_set_up(&default_netif); + + /* Bring up the intra network interface */ + struct ip_addr intra_ipaddr; + struct ip_addr intra_netmask; + struct ip_addr intra_gw; + + IP4_ADDR(&intra_gw, 0,0,0,0); + IP4_ADDR(&intra_ipaddr, 192,168,0,RCCE_ue()+1); + IP4_ADDR(&intra_netmask, 255,255,255,0); + + /* register our Memory Mapped Virtual IP interface in the lwip stack + * and tell him how to use the interface: + * - mmnif_dev : the device data storage + * - ipaddr : the ip address wich should be used + * - gw : the gateway wicht should be used + * - mmnif_init : the initialization which has to be done in order to use our interface + * - ethernet_input : tells him that he should get ethernet input (inclusice ARP) + */ + if ((err = netifapi_netif_add(&mmnif_netif, &intra_ipaddr, &intra_netmask, &intra_gw, NULL, mmnif_init, tcpip_input)) != ERR_OK) + { + kprintf("Unable to add the intra network interface: err = %d\n", err); + return -ENODEV; + } + + /* tell lwip all initialization is done and we want to set it ab */ + netifapi_netif_set_up(&mmnif_netif); #else /* Clear network address because we use DHCP to get an ip address */ IP4_ADDR(&gw, 0,0,0,0); @@ -106,7 +136,7 @@ static int init_netifs(void) /* Bring up the network interface */ if ((err = netifapi_netif_add(&default_netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, tcpip_input)) != ERR_OK) { - kprintf("Unable to add network interface: err = %d\n", err); + kprintf("Unable to add the network interface: err = %d\n", err); return -ENODEV; } @@ -144,11 +174,10 @@ static void tcpip_init_done(void* arg) static int network_shutdown(void) { #if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) + mmnif_shutdown(); netifapi_netif_set_down(&default_netif); - memset(&default_netif, 0x00, sizeof(struct netif)); #elif defined(CONFIG_LWIP) && defined(CONFIG_PCI) netifapi_dhcp_stop(&default_netif); - memset(&default_netif, 0x00, sizeof(struct netif)); #endif return 0; @@ -209,6 +238,7 @@ int initd(void* arg) { #ifdef CONFIG_LWIP sys_sem_t sem; + tid_t id; char* argv[] = {"/bin/rlogind ", NULL}; // Initialize lwIP modules @@ -230,9 +260,10 @@ int initd(void* arg) #endif // start echo, netio and rlogind - echo_init(); - netio_init(); - create_user_task(NULL, "/bin/rlogind", argv); + //echo_init(); + //create_user_task(&id, "/bin/rlogind", argv); + //kprintf("Create rlogind with id %u\n", id); + //netio_init(); #endif list_root(); diff --git a/kernel/main.c b/kernel/main.c index c458c3aa..62753e41 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -60,6 +60,8 @@ int smp_main(void) int main(void) { + tid_t id; + lowlevel_init(); pushbg(COL_BLUE); @@ -91,7 +93,8 @@ int main(void) kprintf("Current available memory: %u MBytes\n", atomic_int32_read(&total_available_pages)/((1024*1024)/PAGE_SIZE)); sleep(5); - create_kernel_task(NULL, initd, NULL, NORMAL_PRIO); + create_kernel_task(&id, initd, NULL, NORMAL_PRIO); + kprintf("Create initd with id %u\n", id); reschedule(); while(1) { From 4099bc471db50722c7831ed288e2c72f486e6ba0 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:03:11 -0700 Subject: [PATCH 17/23] extend test cases --- apps/tests.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/tests.c b/apps/tests.c index c01d806b..0ef511d2 100644 --- a/apps/tests.c +++ b/apps/tests.c @@ -279,7 +279,7 @@ int test_init(void) // char* argv[] = {"/bin/mshell", NULL}; char* argv[] = {"/bin/tests", NULL}; char* server_argv[] = {"/bin/server", "6789", NULL}; -// char* client_argv[] = {"/bin/client", "127.0.0.1", "6789", NULL}; + char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL}; sem_init(&producing, 1); sem_init(&consuming, 0); @@ -297,9 +297,11 @@ int test_init(void) //create_user_task(NULL, "/bin/jacobi", argv); //create_user_task(NULL, "/bin/mshell", argv); //create_user_task(NULL, "/bin/jacobi", argv); - //create_user_task(NULL, "/bin/server", server_argv); - //sleep(5); - //create_user_task(NULL, "/bin/client", client_argv); + /*create_user_task(NULL, "/bin/server", server_argv); + if (RCCE_ue() != 0) { + sleep(5); + create_user_task(NULL, "/bin/client", client_argv); + }*/ return 0; } From 2b129977d0dcada69bd716fc13bbf6c7d867de2b Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 09:14:03 +0200 Subject: [PATCH 18/23] remove compiler errors --- drivers/net/mmnif.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index 707ffe99..540b4a07 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -22,6 +22,10 @@ * */ +#include + +#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) + #include "mmnif.h" /* definitions */ #include /* lwip netif */ @@ -1706,3 +1710,5 @@ err_t mmnif_shutdown(void) return err; } + +#endif From 3e0a285882ccf411cdc57f32e2ac830b1827eec5 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:14:25 -0700 Subject: [PATCH 19/23] enable rlogind --- kernel/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index ff83c477..eea20644 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -261,8 +261,8 @@ int initd(void* arg) // start echo, netio and rlogind //echo_init(); - //create_user_task(&id, "/bin/rlogind", argv); - //kprintf("Create rlogind with id %u\n", id); + create_user_task(&id, "/bin/rlogind", argv); + kprintf("Create rlogind with id %u\n", id); //netio_init(); #endif From 42602df6b0c84d10180d8f1e50b6eb29802bfd9e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:02:33 -0700 Subject: [PATCH 20/23] insert init code for the mmnif device --- kernel/init.c | 47 +++++++++++++++++++++++++++++++++++++++-------- kernel/main.c | 5 ++++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index 4d54b4d4..ff83c477 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -71,6 +71,9 @@ int lowlevel_init(void) #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) static struct netif default_netif; +#ifdef CONFIG_ROCKCREEK +static struct netif mmnif_netif; +#endif static int init_netifs(void) { @@ -83,8 +86,9 @@ static int init_netifs(void) // Set up the lwIP network interface memset(&default_netif, 0x00, sizeof(struct netif)); - #ifdef CONFIG_ROCKCREEK + memset(&mmnif_netif, 0x00, sizeof(struct netif)); + /* Set network address variables */ IP4_ADDR(&gw, 192,168,28,254); IP4_ADDR(&ipaddr, 192,168,28,RCCE_ue()+1); @@ -92,12 +96,38 @@ static int init_netifs(void) /* Bring up the network interface */ if ((err = netifapi_netif_add(&default_netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, tcpip_input)) != ERR_OK) { - kprintf("Unable to add network interface: err = %d\n", err); + kprintf("Unable to add the network interface: err = %d\n", err); return -ENODEV; } netifapi_netif_set_default(&default_netif); netifapi_netif_set_up(&default_netif); + + /* Bring up the intra network interface */ + struct ip_addr intra_ipaddr; + struct ip_addr intra_netmask; + struct ip_addr intra_gw; + + IP4_ADDR(&intra_gw, 0,0,0,0); + IP4_ADDR(&intra_ipaddr, 192,168,0,RCCE_ue()+1); + IP4_ADDR(&intra_netmask, 255,255,255,0); + + /* register our Memory Mapped Virtual IP interface in the lwip stack + * and tell him how to use the interface: + * - mmnif_dev : the device data storage + * - ipaddr : the ip address wich should be used + * - gw : the gateway wicht should be used + * - mmnif_init : the initialization which has to be done in order to use our interface + * - ethernet_input : tells him that he should get ethernet input (inclusice ARP) + */ + if ((err = netifapi_netif_add(&mmnif_netif, &intra_ipaddr, &intra_netmask, &intra_gw, NULL, mmnif_init, tcpip_input)) != ERR_OK) + { + kprintf("Unable to add the intra network interface: err = %d\n", err); + return -ENODEV; + } + + /* tell lwip all initialization is done and we want to set it ab */ + netifapi_netif_set_up(&mmnif_netif); #else /* Clear network address because we use DHCP to get an ip address */ IP4_ADDR(&gw, 0,0,0,0); @@ -106,7 +136,7 @@ static int init_netifs(void) /* Bring up the network interface */ if ((err = netifapi_netif_add(&default_netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, tcpip_input)) != ERR_OK) { - kprintf("Unable to add network interface: err = %d\n", err); + kprintf("Unable to add the network interface: err = %d\n", err); return -ENODEV; } @@ -144,11 +174,10 @@ static void tcpip_init_done(void* arg) static int network_shutdown(void) { #if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) + mmnif_shutdown(); netifapi_netif_set_down(&default_netif); - memset(&default_netif, 0x00, sizeof(struct netif)); #elif defined(CONFIG_LWIP) && defined(CONFIG_PCI) netifapi_dhcp_stop(&default_netif); - memset(&default_netif, 0x00, sizeof(struct netif)); #endif return 0; @@ -209,6 +238,7 @@ int initd(void* arg) { #ifdef CONFIG_LWIP sys_sem_t sem; + tid_t id; char* argv[] = {"/bin/rlogind ", NULL}; // Initialize lwIP modules @@ -230,9 +260,10 @@ int initd(void* arg) #endif // start echo, netio and rlogind - echo_init(); - netio_init(); - create_user_task(NULL, "/bin/rlogind", argv); + //echo_init(); + //create_user_task(&id, "/bin/rlogind", argv); + //kprintf("Create rlogind with id %u\n", id); + //netio_init(); #endif list_root(); diff --git a/kernel/main.c b/kernel/main.c index c458c3aa..62753e41 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -60,6 +60,8 @@ int smp_main(void) int main(void) { + tid_t id; + lowlevel_init(); pushbg(COL_BLUE); @@ -91,7 +93,8 @@ int main(void) kprintf("Current available memory: %u MBytes\n", atomic_int32_read(&total_available_pages)/((1024*1024)/PAGE_SIZE)); sleep(5); - create_kernel_task(NULL, initd, NULL, NORMAL_PRIO); + create_kernel_task(&id, initd, NULL, NORMAL_PRIO); + kprintf("Create initd with id %u\n", id); reschedule(); while(1) { From 04a67b27f5296a8161660f618f903c7eb533cd3b Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:03:11 -0700 Subject: [PATCH 21/23] extend test cases --- apps/tests.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/tests.c b/apps/tests.c index c01d806b..0ef511d2 100644 --- a/apps/tests.c +++ b/apps/tests.c @@ -279,7 +279,7 @@ int test_init(void) // char* argv[] = {"/bin/mshell", NULL}; char* argv[] = {"/bin/tests", NULL}; char* server_argv[] = {"/bin/server", "6789", NULL}; -// char* client_argv[] = {"/bin/client", "127.0.0.1", "6789", NULL}; + char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL}; sem_init(&producing, 1); sem_init(&consuming, 0); @@ -297,9 +297,11 @@ int test_init(void) //create_user_task(NULL, "/bin/jacobi", argv); //create_user_task(NULL, "/bin/mshell", argv); //create_user_task(NULL, "/bin/jacobi", argv); - //create_user_task(NULL, "/bin/server", server_argv); - //sleep(5); - //create_user_task(NULL, "/bin/client", client_argv); + /*create_user_task(NULL, "/bin/server", server_argv); + if (RCCE_ue() != 0) { + sleep(5); + create_user_task(NULL, "/bin/client", client_argv); + }*/ return 0; } From 99ade4c06499741cd1c67dc71657a39f52e9f2e9 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 09:14:03 +0200 Subject: [PATCH 22/23] remove compiler errors --- drivers/net/mmnif.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/mmnif.c b/drivers/net/mmnif.c index 707ffe99..540b4a07 100644 --- a/drivers/net/mmnif.c +++ b/drivers/net/mmnif.c @@ -22,6 +22,10 @@ * */ +#include + +#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) + #include "mmnif.h" /* definitions */ #include /* lwip netif */ @@ -1706,3 +1710,5 @@ err_t mmnif_shutdown(void) return err; } + +#endif From ee075fabf0aae839734246300e4538d4c085c764 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 4 Oct 2011 00:14:25 -0700 Subject: [PATCH 23/23] enable rlogind --- kernel/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index ff83c477..eea20644 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -261,8 +261,8 @@ int initd(void* arg) // start echo, netio and rlogind //echo_init(); - //create_user_task(&id, "/bin/rlogind", argv); - //kprintf("Create rlogind with id %u\n", id); + create_user_task(&id, "/bin/rlogind", argv); + kprintf("Create rlogind with id %u\n", id); //netio_init(); #endif