Merge branch 'master' of git.lfbs.rwth-aachen.de:metalsvm

This commit is contained in:
Jacek Galowicz 2011-10-24 19:27:12 +02:00
commit 098f3c48e1
18 changed files with 1069 additions and 293 deletions

View file

@ -1,4 +1,4 @@
C_source := tests.c echo.c netio.c
C_source := tests.c echo.c netio.c laplace.c gfx_client.c gfx_generic.c
MODULE := apps
include $(TOPDIR)/Makefile.inc

146
apps/gfx_client.c Normal file
View file

@ -0,0 +1,146 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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 <metalsvm/stdlib.h>
#ifdef CONFIG_LWIP
#include "gfx_client.h"
#include <lwip/sockets.h>
static int myrank;
static int sockfd;
#ifndef SINGLE_CONNECT
#define SINGLE_CONNECT 1
#endif
#define SINGLE_CONNECT_RANK 0
#define USE_GETHOSTBYNAME 0
//int gfx_init(int* pargc, char*** pargv, int rank){
int gfx_init(char* ip_str, char* port_str, int rank) {
char* hostname;
int port;
struct sockaddr_in serveraddr;
struct hostent *server;
//*pargc -=2;
myrank = rank;
#if SINGLE_CONNECT
// currently only rank 0 will connect to the gfx-server
if (rank != SINGLE_CONNECT_RANK) {
return 0;
}
#endif
/* hostname und port aus den parametern ermitteln) */
//kprintf("pargc: %d\n", *pargc);
hostname = ip_str; //(*pargv)[(*pargc)];
port = atoi(port_str); //atoi((*pargv)[(*pargc)+1]);
kprintf("gfx-client connecting to host: %s, port: %d\n", hostname, port);
/* socket erzeugen */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
return -1;
#if 1
/* Disable the Nagle (TCP No Delay) algorithm */
int flag = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)) < 0) {
kprintf("Couldn't setsockopt(TCP_NODELAY)\n");
return -1;
}
#endif
#if USE_GETHOSTBYNAME
/* dns eintrag vom server ermitteln */
serveraddr = gethostbyname(hostname);
if (server == NULL){
fprintf(stderr, "%s: no such host\n", hostname);
return -2;
}
#endif
/* adresse vom server ermitteln */
memset((char *) &serveraddr, 0x00, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
#if USE_GETHOSTBYNAME
bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length);
#else
serveraddr.sin_addr.s_addr = inet_addr(hostname);
#endif
serveraddr.sin_port = htons(port);
/* verbindung herstellen */
if (connect(sockfd, (const struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
return -3;
return 0;
}
int gfx_send(char* buf, int size, int tag){
int ret, pos = 0;
uint32_t u32size, u32tag;
#if SINGLE_CONNECT
if (myrank != SINGLE_CONNECT_RANK)
return 0;
#endif
u32size = size;
u32tag = tag;
// printf("sending stuff....");
// printf("tag: %d, size: %d\n", tag, size);
// fflush(stdout);
ret = write(sockfd, &u32tag, sizeof(u32tag));
if (ret != sizeof(tag))
return -1;
ret = write(sockfd, &u32size, sizeof(u32size));
if (ret != sizeof(size))
return -2;
do{
ret = write(sockfd, &buf[pos], size-pos);
pos += ret;
} while (pos < size);
return 0;
}
int gfx_finalize(){
// uint32_t u32tag = (uint32_t)(-1);
uint32_t u32tag = 1111;
#if SINGLE_CONNECT
if (myrank == SINGLE_CONNECT_RANK) {
write(sockfd, &u32tag, sizeof(u32tag));
close(sockfd);
}
#endif
return 0;
}
#endif

50
apps/gfx_client.h Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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 __GFX_CLIENT_H__
#define __GFX_CLIENT_H__
#include <metalsvm/stdio.h>
#include <metalsvm/stdlib.h>
#include <metalsvm/string.h>
#ifdef CONFIG_LWIP
#define BUFSIZE 1024
/*
* grafik initialisieren, letzte beide argumente, ip und port, werden entfernt
* verbindung zu server aufbauen, kollektiver aufruf, erstmal nur rank 0 connecten
*/
//int gfx_init(int* pargc, char*** pargv, int rank);
int gfx_init(char* ip_str, char* port_str, int rank);
/*
* paket mit der geg. laenge wird an den server gesehendet, das tag soll auch uebertragen werden
*/
int gfx_send(char* buf, int size, int tag);
/*
* kollektiver aufruf, vorhandene verbindungen kontrolliert beenden
*/
int gfx_finalize();
#endif
#endif

138
apps/gfx_generic.c Normal file
View file

@ -0,0 +1,138 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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 "gfx_client.h"
#include "gfx_generic.h"
#ifdef CONFIG_LWIP
int GFX_init(int* pargc, char*** pargv, int rank)
{
return gfx_init(pargc, pargv, rank);
}
int GFX_send(char* buf, int size, int tag)
{
return gfx_send(buf, size, tag);
}
int GFX_finalize()
{
return gfx_finalize();
}
int GFX_update()
{
return gfx_send(NULL, 0, GFX_UPDATE);
}
int GFX_usleep(int sleep_time)
{
int buf[1];
buf[0] = sleep_time;
return gfx_send((char*)buf, sizeof(int), GFX_USLEEP);
}
int GFX_set_rgb(int index, int r, int g, int b)
{
int buf[4];
buf[0] = index;
buf[1] = r;
buf[2] = g;
buf[3] = b;
return gfx_send((char*)buf, 4*sizeof(int), GFX_SET_RGB);
}
int GFX_set_xy(int x, int y)
{
int buf[2];
buf[0] = x;
buf[1] = y;
return gfx_send((char*)buf, 2*sizeof(int), GFX_SET_XY);
}
int GFX_set_hd(int height, int direction)
{
int buf[2];
buf[0] = height;
buf[1] = direction;
return gfx_send((char*)buf, 2*sizeof(int), GFX_SET_HD);
}
int GFX_draw_data(char *buf, int len)
{
return gfx_send(buf, len, GFX_DRAW_DATA);
}
int GFX_draw_pixel(int x, int y, int color)
{
int buf[3];
buf[0] = x;
buf[1] = y;
buf[2] = color;
return gfx_send((char*)buf, 3*sizeof(int), GFX_DRAW_PIXEL);
}
int GFX_draw_line(int x1, int y1, int x2, int y2, int color)
{
int buf[5];
buf[0] = x1;
buf[1] = y1;
buf[2] = x2;
buf[3] = y2;
buf[4] = color;
return gfx_send((char*)buf, 5*sizeof(int), GFX_DRAW_LINE);
}
int GFX_draw_box(int x, int y, int height, int width, int color)
{
int buf[5];
buf[0] = x;
buf[1] = y;
buf[2] = height;
buf[3] = width;
buf[4] = color;
return gfx_send((char*)buf, 5*sizeof(int), GFX_DRAW_BOX);
}
int GFX_draw_text(int x, int y, int color, char *text)
{
int buf[32];
buf[0] = x;
buf[1] = y;
buf[2] = color;
strcpy((char*)&(buf[3]), text);
return gfx_send((char*)buf, 32*sizeof(int), GFX_DRAW_TEXT);
}
int GFX_draw_points(int* points, int num)
{
return gfx_send((char*)points, num*3*sizeof(int), GFX_DRAW_POINTS);
}
int GFX_draw_poly(int* points, int num, int color)
{
int i;
for(i=0; i<num; i++) points[i*3+2] = color;
return gfx_send((char*)points, num*3*sizeof(int), GFX_DRAW_POLY);
}
#endif

84
apps/gfx_generic.h Normal file
View file

@ -0,0 +1,84 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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 _GFX_GENERIC_H_
#define _GFX_GENERIC_H_
#include "gfx_client.h"
#ifdef CONFIG_LWIP
int GFX_init(int* pargc, char*** pargv, int rank);
int GFX_send(char* buf, int size, int tag);
int GFX_finalize();
int GFX_update();
int GFX_set_rgb(int index, int r, int g, int b);
int GFX_set_xy(int x, int y);
int GFX_set_hd(int height, int direction);
int GFX_draw_data(char *buf, int len);
int GFX_draw_pixel(int x, int y, int color);
int GFX_draw_line(int x1, int y1, int x2, int y2, int color);
int GFX_draw_box(int x, int y, int height, int width, int color);
int GFX_draw_text(int x, int y, int color, char *text);
int GFX_draw_points(int* points, int num);
int GFX_draw_poly(int *points, int num, int color);
typedef enum _GFX_colors
{
GFX_WHITE = -1,
GFX_BLACK = -2,
GFX_RED = -3,
GFX_DRED = -4,
GFX_GREEN = -5,
GFX_DGREEN = -6,
GFX_BLUE = -7,
GFX_DBLUE = -8,
GFX_CYAN = -9,
GFX_DCYAN = -10,
GFX_MAGENTA = -11,
GFX_DMAGENTA = -12,
GFX_YELLOW = -13,
GFX_DYELLOW = -14,
GFX_GRAY = -15,
GFX_DGRAY = -16
} GFX_colors;
typedef enum GFX_commands
{
GFX_UPDATE = 0,
GFX_USLEEP = 1,
GFX_SET_RGB = 2,
GFX_SET_XY = 3,
GFX_SET_HD = 4,
GFX_DRAW_DATA = 5,
GFX_DRAW_PIXEL = 6,
GFX_DRAW_POINTS = 7,
GFX_DRAW_LINE = 8,
GFX_DRAW_BOX = 9,
GFX_DRAW_POLY = 10,
GFX_DRAW_TEXT = 11
} GFX_commands;
#endif
#endif

298
apps/laplace.c Normal file
View file

@ -0,0 +1,298 @@
/*
* Copyright 2010 Carsten Clauss, Pablo Reble, Stefan Lankes
* 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 <metalsvm/stdlib.h>
#include <metalsvm/stdio.h>
#include <asm/irqflags.h>
#include <asm/svm.h>
#ifdef CONFIG_ROCKCREEK
#include <asm/RCCE.h>
#include <asm/iRCCE.h>
#define _LAPLACE_SHMEM_
//#define _USE_GFX
#ifdef _LAPLACE_SHMEM_
#define SINGLE_CONNECT 1
#else
#define SINGLE_CONNECT 0
#endif
#ifdef _USE_GFX
#include "gfx_generic.h"
#include "gfx_client.h"
#endif
#define ABS(a) (((a) < 0) ? -(a) : (a))
#define MAX(a,b) (((a) < (b)) ? (b) : (a))
#define N 1022
#define M 510
#define TMAX (100*50)
//#define DATA unsigned int
#define DATA double
//#define FIX 1024
#define FIX 1
#define USE_STRONG 1
#define USE_LAZYRELEASE 0
#if USE_STRONG && USE_LAZYRELEASE
#error Please, use only one memory model
#endif
static inline double pow(double a, int b)
{
double base = a;
int i;
for (i = 1; i < b; ++i)
a *= base;
return a;
}
int laplace(void *arg)
{
//char* argv[] = {"/bin/laplace", "192.168.4.254", "12301", NULL};
//int argc = 3;
uint32_t flags;
#ifdef _USE_GFX
uint32_t ret;
#endif
int t;
int i, I, j, J;
int my_rank;
int num_ranks;
int n;
int m;
volatile DATA **NewValues;
volatile DATA **OldValues;
volatile DATA **tmp;
volatile char **BufValues;
uint64_t start, end;
flags = irq_nested_disable();
my_rank = RCCE_ue();
num_ranks = RCCE_num_ues();
irq_nested_enable(flags);
#ifdef _USE_GFX
kprintf("Laplace calls gfx_init\n");
ret = gfx_init("192.168.4.254" /*&argc */ , "5000" /*&argv */ , my_rank);
kprintf("gfx_init: %d\n", ret);
#endif
m = M;
J = 0;
n = N / num_ranks;
I = n * my_rank;
if (my_rank == num_ranks - 1)
n += N % num_ranks;
kprintf("(%d) %d x %d / offsets: %d, %d / (%d x %d)\n", my_rank, N, M, I, J, n, m);
#ifdef _USE_GFX
if (my_rank == 0) {
for (i = 0; i < 256; i++) {
//set color index, r, g, b
if (i < 64)
GFX_set_rgb(i, 0, i * 256 / 64, 255);
else if (i < 128)
GFX_set_rgb(i, 0, 255, 255 - ((i - 64) * 256 / 64));
else if (i < 192)
GFX_set_rgb(i, (i - 128) * 256 / 64, 255, 0);
else if (i < 256)
GFX_set_rgb(i, 255, 255 - ((i - 192) * 256 / 64), 0);
}
// TODO: move draw area to center
//GFX_set_xy(150, 150);
GFX_set_hd(N, 0);
}
#endif
NewValues = (volatile DATA **)kmalloc((N + 2) * sizeof(DATA *));
#if USE_STRONG
NewValues[0] = (DATA *) svmmalloc((N + 2) * (M + 2) * sizeof(DATA), SVM_STRONG);
#elif USE_LATYRELEASE
NewValues[0] = (DATA *) svmmalloc((N + 2) * (M + 2) * sizeof(DATA), SVM_LAZYRELEASE);
#else
NewValues[0] = (DATA *) kmalloc((N + 2) * (M + 2) * sizeof(DATA));
#endif
OldValues = (volatile DATA **)kmalloc((N + 2) * sizeof(DATA *));
#if USE_STRONG
OldValues[0] = (DATA *) svmmalloc((N + 2) * (M + 2) * sizeof(DATA), SVM_STRONG);
#elif USE_LATYRELEASE
OldValues[0] = (DATA *) svmmalloc((N + 2) * (M + 2) * sizeof(DATA), SVM_LAZYRELEASE);
#else
OldValues[0] = (DATA *) kmalloc((N + 2) * (M + 2) * sizeof(DATA));
#endif
for (i = 1; i < N + 2; i++) {
NewValues[i] = NewValues[i - 1] + (M + 2);
OldValues[i] = OldValues[i - 1] + (M + 2);
}
BufValues = (volatile char **)kmalloc((N) * sizeof(char *));
BufValues[0] = (char *)kmalloc((N) * (M) * sizeof(char));
for (i = 1; i < N; i++) {
BufValues[i] = BufValues[i - 1] + (M);
}
RCCE_barrier(&RCCE_COMM_WORLD);
kprintf("(%d) Memory allocated!\n", my_rank);
//while (1)
{
int height = N + 2;
int width = M + 2;
/*if (my_rank == 0) {
for (i = 0; i < N + 2; i++) {
for (j = 0; j < M + 2; j++) {*/
{
for (i = I; i < I + n + 2; i++) {
for (j = 0; j < M + 2; j++) {
double X = (((double)j / (double)width) * 5.0) - 2.5;
double Y = (((double)i / (double)height) * 5.0) - 2.5;
double Z = 0.0;
Z = pow((4 - (X + 1) * (X + 1) - 4 * Y * Y), 2) + pow(1.2 * (1 - X), 3) - 10;
if (Z < 0.0)
Z = 1.0;
else if (Z > 0.0)
Z = 0.0;
OldValues[i][j] = NewValues[i][j] = (DATA) ((Z) * 255.0) * FIX;
//if(NewValues[i][j] < 0) NewValues[i][j] = 0;
}
}
}
#if USE_LAZYRELEASE
svm_flush();
svm_invalidate();
#endif
RCCE_barrier(&RCCE_COMM_WORLD);
kprintf("(%d) Arrays initialized!\n", my_rank);
start = rdtsc();
start = rdtsc();
// START ITERATIONS LOOP
for (t = 0; t < TMAX; t++) {
//kprintf("(%d): o:%u n:%u \n",my_rank,(unsigned int)(OldValues[I+1][J+1]), (unsigned int)(NewValues[I+1][J+1]) );
// over all collumns
for (i = 1; i < n + 1; i++) {
// over all rows
for (j = 1; j < m + 1; j++) {
#if 1
NewValues[I + i][J + j] =
(OldValues[I + i - 1][J + j] +
OldValues[I + i + 1][J + j] +
OldValues[I + i][J + j - 1] +
OldValues[I + i][J + j + 1]) / 4;
//if ( NewValues[I+i][J+j] < 0.0 ) NewValues[I+i][J+j] = 0.0 * FIX;
//else if ( NewValues[I+i][J+j] > 255.0 ) NewValues[I+i][J+j] = 255.0 * FIX;
#else
NewValues[I + i][J + j] = 25 * (DATA) (my_rank + 1);
#endif
}
}
#if USE_LAZYRELEASE
svm_flush();
svm_invalidate();
#endif
tmp = NewValues;
NewValues = OldValues;
OldValues = tmp;
//RCCE_TNS_barrier(&RCCE_COMM_WORLD);
RCCE_barrier(&RCCE_COMM_WORLD);
#ifdef _USE_GFX
if ((my_rank == 0) && (t % 50 == 0)) {
int diff, res = 0;
for (i = 1; i < N + 1; i++) {
for (j = 1; j < M + 1; j++) {
diff = ABS(NewValues[i][j] - OldValues[i][j]);
if (diff > res)
res = diff;
BufValues[i - 1][j - 1] = (unsigned char)(NewValues[i][j] / FIX);
//GFX_draw_pixel(150+j, 150+my_rank*n+i, (unsigned char)NewValues[i+1][j+1]);
//GFX_update();
}
}
kprintf("Graphic UPDATE! (t=%d) residual:%u \n", t, res);
GFX_draw_data((char *)(BufValues[0]), (N) * (M));
GFX_update();
}
#endif
// END ITERATIONS LOOP
}
RCCE_barrier(&RCCE_COMM_WORLD);
end = rdtsc();
kprintf("Calculation time: %llu ms (%llu ticks)\n", (end-start)/(1000ULL*get_cpu_frequency()), end-start);
#if USE_STRONG || USE_LAZYRELEASE
svm_statistics();
#endif
}
kprintf("(%d) Algorithm completed!\n", my_rank);
// TODO: Freeing memory regions
#ifdef _USE_GFX
gfx_finalize();
#endif
return 0;
}
#endif

View file

@ -30,6 +30,8 @@
#include <asm/SCC_API.h>
#endif
#define USE_SOCKET_BYPASSING 1
/*
* 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).
@ -45,8 +47,24 @@
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
#ifdef CONFIG_LWIP
#ifdef CONFIG_ROCKCREEK
#if USE_SOCKET_BYPASSING // for socket bypassing
#include <lwip/opt.h>
#undef LWIP_COMPAT_SOCKETS
#endif
#endif
#include <lwip/sockets.h>
#include <lwip/err.h>
#include <lwip/stats.h>
#ifdef CONFIG_ROCKCREEK
#if USE_SOCKET_BYPASSING // for socket bypassing
#include <net/mmnif.h>
#undef AF_INET
#define AF_INET AF_MMNIF_NET
#endif
#endif
typedef struct
{
@ -60,7 +78,7 @@ typedef struct
#define CMD_RES 3
#define CTLSIZE sizeof(CONTROL)
#define DEFAULTPORT 0x494F /* "IO" */
#define DEFAULTPORT 0x494F
#define TMAXSIZE 65536
static int tSizes[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32767};
@ -153,6 +171,7 @@ static int TCPServer(void* arg)
setsockopt(server, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
setsockopt(server, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
memset((char *) &sa_server, 0x00, sizeof(sa_server));
sa_server.sin_family = AF_INET;
sa_server.sin_port = htons(nPort);
sa_server.sin_addr = addr_local;
@ -177,6 +196,7 @@ static int TCPServer(void* arg)
{
kprintf("TCP server listening.\n");
#if !USE_SOCKET_BYPASSING
FD_ZERO(&fds);
FD_SET(server, &fds);
tv.tv_sec = 3600;
@ -190,10 +210,16 @@ static int TCPServer(void* arg)
if (rc == 0 || FD_ISSET(server, &fds) == 0)
continue;
#endif
length = sizeof(sa_client);
if ((client = accept(server, (struct sockaddr *) &sa_client, &length)) == -1)
#if USE_SOCKET_BYPASSING
// TODO: Bug, not compatible with BSD sockets
memcpy(&sa_client, &sa_server, length);
#endif
if ((client = accept(server, (struct sockaddr *) &sa_client, &length)) < 0) {
kprintf("accept faild: %d\n", errno);
continue;
}
setsockopt(client, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
setsockopt(client, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
@ -215,7 +241,7 @@ static int TCPServer(void* arg)
kprintf("\nReceiving from client, packet size %s ... \n", PacketSize(ctl.data));
cBuffer[0] = 0;
nData = 0;
do {
for (nByte = 0; nByte < ctl.data; )
{

0
apps/scc_bootinfo.asm Normal file
View file

View file

@ -40,6 +40,8 @@ static sem_t consuming, producing;
static mailbox_int32_t mbox;
static int val = 0;
int laplace(void* arg);
static int consumer(void* arg)
{
int i, m = 0;
@ -318,6 +320,7 @@ int test_init(void)
//create_kernel_task(NULL, mail_noise, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, pi, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO);
//create_user_task(NULL, "/bin/hello", argv);
create_user_task(NULL, "/bin/tests", argv);
//create_user_task(NULL, "/bin/jacobi", argv);

View file

@ -190,6 +190,7 @@ int RCCE_comm_size(RCCE_COMM, int *);
int RCCE_comm_rank(RCCE_COMM, int *);
void RCCE_fence(void);
int RCCE_barrier(RCCE_COMM *);
int RCCE_TNS_barrier(RCCE_COMM* comm);
int RCCE_error_string(int, char *, int *);
int RCCE_debug_set(int);
int RCCE_debug_unset(int);

View file

@ -49,7 +49,6 @@ static volatile uint8_t* page_owner = NULL;
// helper array to convert a physical to a virtual address
static size_t phys2virt[SHARED_PAGES] = {[0 ... SHARED_PAGES-1] = 0};
static size_t shmbegin = 0;
static int my_ue = 0;
static uint32_t emit[RCCE_MAXNP] = {[0 ... RCCE_MAXNP-1] = 0};
static uint32_t request[RCCE_MAXNP] = {[0 ... RCCE_MAXNP-1] = 0};
static uint32_t forward[RCCE_MAXNP] = {[0 ... RCCE_MAXNP-1] = 0};
@ -61,7 +60,6 @@ int svm_init(void)
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
my_ue = RCCE_ue();
shmbegin = (size_t)RC_SHM_BUFFER_START();
phyaddr = (size_t) RCCE_shmalloc(OWNER_SIZE);
irq_nested_enable(flags);
@ -84,7 +82,7 @@ int svm_init(void)
}
// per default is core 0 owner
if (!my_ue)
if (!RCCE_IAM)
memset((void*)page_owner, 0x00, OWNER_SIZE);
// iRCCE is not thread save => disable interrupts
@ -112,32 +110,29 @@ int svm_access_request(size_t addr)
return -EINVAL;
pageid = (phyaddr-shmbegin) >> PAGE_SHIFT;
//svm_flush();
if (page_owner[pageid] == my_ue)
if (page_owner[pageid] == RCCE_IAM)
return 0;
remote_rank = page_owner[pageid];
((size_t*) payload)[0] = my_ue;
((size_t*) payload)[0] = RCCE_IAM;
((size_t*) payload)[1] = phyaddr;
//kprintf("send access request to %d of 0x%x\n", remote_rank, phyaddr);
/* send ping request */
iRCCE_mail_send(2*sizeof(size_t), SVM_REQUEST, 0, payload, remote_rank);
request[remote_rank]++;
NOP8;
icc_send_gic_irq(remote_rank);
/* check for incoming messages */
icc_mail_check();
while (page_owner[pageid] != my_ue) {
check_workqueues();
while (page_owner[pageid] != RCCE_IAM) {
icc_mail_check();
NOP8;
}
return change_page_permissions(addr, addr+PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
}
static atomic_int32_t size_counter = ATOMIC_INIT(0);
void* svmmalloc(size_t size, uint32_t consistency)
{
size_t phyaddr, viraddr, i;
@ -153,11 +148,61 @@ void* svmmalloc(size_t size, uint32_t consistency)
// currently, we allocate memory in page size granulation
size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
#if 0 // Workaround for our MARC paper
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
kprintf("Entering shmmalloc: size 0x%x, owner_size 0x%x\n", size, OWNER_SIZE);
if (RCCE_IAM && (consistency & SVM_STRONG))
map_flags |= MAP_NO_ACCESS;
viraddr = vm_alloc(size >> PAGE_SHIFT, map_flags);
kprintf("vm_alloc returns 0x%x\n", viraddr);
static uint32_t last = 0;
// get memory on MC0
if (last)
phyaddr = last + size/4;
else
last = phyaddr = (size_t) RCCE_shmalloc(size/4);
map_region(viraddr, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP);
for(i=0; i<size/4; i+=PAGE_SIZE)
phys2virt[(phyaddr + i - shmbegin) >> PAGE_SHIFT] = viraddr + i;
kprintf("svmmalloc on MC0: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size);
// get memory on MC1
phyaddr = shmbegin + 0x1000000 + atomic_int32_read(&size_counter);
map_region(viraddr + size/4, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP);
for(i=0; i<size/4; i+=PAGE_SIZE)
phys2virt[(phyaddr + i - shmbegin) >> PAGE_SHIFT] = viraddr + size/4 + i;
kprintf("svmmalloc on MC1: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr+size/4, size);
// get memory on MC2
phyaddr = shmbegin + 0x2000000 + atomic_int32_read(&size_counter);
map_region(viraddr + 2 * size/4, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP);
for(i=0; i<size/4; i+=PAGE_SIZE)
phys2virt[(phyaddr + i - shmbegin) >> PAGE_SHIFT] = viraddr + 2 * size/4 + i;
kprintf("svmmalloc on MC2: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr+2*size/4, size);
// get memory on MC3
phyaddr = shmbegin + 0x3000000 + atomic_int32_read(&size_counter);
map_region(viraddr + 3 * size/4, phyaddr, (size/4) >> PAGE_SHIFT, map_flags|MAP_REMAP);
for(i=0; i<size/4; i+=PAGE_SIZE)
phys2virt[(phyaddr + i - shmbegin) >> PAGE_SHIFT] = viraddr + 3 * size/4 + i;
kprintf("svmmalloc on MC3: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr+3*size/4, size);
atomic_int32_add(&size_counter, size/4);
irq_nested_enable(flags);
kprintf("shmmalloc returns 0x%x\n", viraddr);
return (void*) viraddr;
#else
// iRCCE is not thread save => disable interrupts
flags = irq_nested_disable();
phyaddr = (size_t) RCCE_shmalloc(size);
if (RCCE_ue() && (consistency & SVM_STRONG))
if (RCCE_IAM && (consistency & SVM_STRONG))
map_flags |= MAP_NO_ACCESS;
irq_nested_enable(flags);
@ -175,6 +220,7 @@ void* svmmalloc(size_t size, uint32_t consistency)
kprintf("svmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size);
return (void*) viraddr;
#endif
}
void svmfree(void* addr, size_t size)
@ -218,12 +264,12 @@ int svm_emit_page(size_t phyaddr, int ue)
return -EINVAL;
pageid = (phyaddr-shmbegin) >> PAGE_SHIFT;
if (page_owner[pageid] != my_ue) {
if (page_owner[pageid] != RCCE_IAM) {
// Core is nor owner => forward request to new owner
int remote_rank;
uint8_t payload[iRCCE_MAIL_HEADER_PAYLOAD];
kprintf("Ups, core %d is not owner of page 0x%x\n", my_ue, phyaddr);
kprintf("Ups, core %d is not owner of page 0x%x\n", RCCE_IAM, phyaddr);
remote_rank = page_owner[pageid];
((size_t*) payload)[0] = ue;
@ -258,6 +304,7 @@ void svm_flush(void)
*(int *)RCCE_fool_write_combine_buffer = 1;
flush_cache();
#error Currently not supported
#if 0
// try to flush L2 cache
z = Z_PID(RC_COREID[my_ue]);

View file

@ -48,6 +48,8 @@
// En-/ or disable debug prints...
#define DEBUG 0
#define Test_and_Set(a) ((*(virtual_lockaddress[a])) & 0x01)
//......................................................................................
// GLOBAL VARIABLES USED BY THE LIBRARY
//......................................................................................
@ -105,6 +107,38 @@ void RC_cache_invalidate() {
return;
}
int RCCE_TNS_barrier(RCCE_COMM* comm) {
// two roundtrips to realize a barrier using a T&S Register for each core.
// 1. search first free T&S Register to spin
// 2. last waiter wakes up first waiter and continues local wait
// 3. first waiter wakes up second waiter by releasing its lock ...
// At least every used T&S Register is 0 and no UE can overtake a barrier.
int num = comm->size;
int step = 0;
//fprintf(stderr,"%d:\t enter barrier \n",id);
while( !Test_and_Set(step) ) ++step;
// only one UE runs until T&S # num-1
//fprintf(stderr,"%d:\t step %d\n",id,step);
if(step == num-1) {
//fprintf(stderr,"%d:\t I am the last one\n",id);
*(virtual_lockaddress[0]) = 0x0;
while(!Test_and_Set(step)) ;
*(virtual_lockaddress[step]) = 0x0;
} else {
while(!Test_and_Set(step)) ;
*(virtual_lockaddress[step]) = 0x0;
*(virtual_lockaddress[step+1]) = 0x0;
}
//fprintf(stderr,"released barrier! step: %d\n", step);
return RCCE_SUCCESS;
}
//--------------------------------------------------------------------------------------
// FUNCTION: RC_COMM_BUFFER_SIZE
//--------------------------------------------------------------------------------------

View file

@ -162,7 +162,7 @@ static int iRCCE_mail_fetch(
iRCCE_MAIL_HEADER dummy_header = {0, 0, 0, NULL, 0, 0, 0, {[0 ... iRCCE_MAIL_HEADER_PAYLOAD-1] = 0} };
static int iRCCE_mailbox_check() {
static int iRCCE_mailbox_check(void) {
int i,j;
uint32_t flags;

View file

@ -161,7 +161,7 @@ static void icc_handler(struct state *s)
/* empty mail queue */
while( iRCCE_mail_recv(&header) == iRCCE_SUCCESS ) {
icc_mail_check_tag(header);
iRCCE_mail_release( &header );
iRCCE_mail_release(&header);
NOP8;
NOP8;
NOP8;
@ -331,7 +331,7 @@ int icc_mail_ping(void)
/* leave function if not participating in pingpong */
if( (RCCE_IAM != CORE_A) && (RCCE_IAM != CORE_B) ) return -1;
kprintf( "my_ue = %d\n", RCCE_IAM);
kprintf( "my rank = %d\n", RCCE_IAM);
kprintf( "Hello from mail_ping ... \n" );
kprintf( "rounds = %d\n", ROUNDS );
@ -401,7 +401,7 @@ int icc_mail_ping_irq(void)
int res;
iRCCE_MAIL_HEADER* recv_header = NULL;
kprintf( "my_rank = %d\n", RCCE_IAM );
kprintf( "my rank = %d\n", RCCE_IAM );
kprintf( "rem_rank = %d\n", CORE_B );
kprintf( "rounds = %d\n", ROUNDS );
@ -503,9 +503,6 @@ void icc_mail_check(void)
iRCCE_mail_check(iRCCE_MAILBOX_ALL);
/* enable interrupts */
irq_nested_enable(flags);
/* empty mail queue */
while( iRCCE_mail_recv(&header) == iRCCE_SUCCESS ) {
icc_mail_check_tag(header);
@ -514,6 +511,9 @@ void icc_mail_check(void)
NOP8;
NOP8;
}
/* enable interrupts */
irq_nested_enable(flags);
}
#endif

View file

@ -18,29 +18,34 @@
*
* mmnif.c --- memmory mapped interface
*
* Virutal IP Interface for the concept processor SCC
* Virtual IP Interface for the concept processor SCC
*
*/
/*
* 15th October 2011:
* - Redesign of the interrupt handling (by Stefan Lankes)
* - Add iRCCE support (by Stefan Lankes)
* - Extending the BSD socket interface
*/
#include <metalsvm/stddef.h>
#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK)
#include "mmnif.h" /* definitions */
#include <lwip/netif.h> /* lwip netif */
#include <lwip/stats.h> /* inteface stats */
#include <netif/etharp.h> /* ethernet arp packets */
#include <lwip/ip.h> /* struct iphdr */
#include <lwip/tcpip.h> /* tcpip_input() */
#include <lwip/sockets.h>
//#include <asm/page.h>
#include <lwip/ip_addr.h>
#include <metalsvm/mailbox.h> /* mailbox_ptr_t */
#include <metalsvm/semaphore.h>
#include <metalsvm/spinlock.h>
#include <metalsvm/page.h>
#include <metalsvm/time.h>
#include <asm/irq.h>
#include <asm/RCCE.h>
@ -51,7 +56,7 @@
#include <asm/SCC_API.h>
#include <asm/scc_memcpy.h>
#include <metalsvm/time.h>
#include <net/mmnif.h>
#define TRUE 1
#define FALSE 0
@ -80,10 +85,8 @@
#define MMNIF_AUTO_SOCKET_TIMEOUT 500
#define MMNIF_FAST_SOCKET_BLOCK 1
#ifdef DEBUG_MMNIF
#include "util.h" /* hex dump */
#include <net/util.h> /* hex dump */
#endif
/* define constants
@ -120,11 +123,6 @@
static int npseudosocket = MMNIF_PSEUDO_SOCKET_START;
static spinlock_t pseudolock;
/* 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
@ -145,14 +143,12 @@ 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;
@ -162,13 +158,13 @@ typedef struct acceptor {
typedef struct bypass_rxdesc {
/* socket : hashtarget
* remote_socket: socket on the remote end
* cnt : atomic counter for the recv function
* counter : packet counter
* last_id : last packet id
* 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;
@ -206,6 +202,7 @@ typedef struct rx_desc {
* addr : memory address of the packet
* fast_sock: (-1) if no socket is associated
* else the socket n of the fast socket
* id : packet id
*/
uint8_t stat;
uint16_t len;
@ -222,7 +219,6 @@ typedef struct mm_rx_buffer {
*/
uint16_t head;
uint16_t tail;
spinlock_t rlock;
/* descritpor queue
* desc_table : descriptor table
@ -253,18 +249,14 @@ typedef struct mmnif {
uint32_t ipaddr;
// checks the TCPIP thread already the rx buffers?
uint8_t check_in_progress;
volatile uint8_t check_in_progress;
/* memory interaction variables:
* - pointer to recive buffer
*/
mm_rx_buffer_t *rx_buff;
volatile 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;
@ -332,7 +324,7 @@ inline static void* memcpy_to_nc(void* dest, const void *src, size_t count)
/* trigger an interrupt on the remote processor
* so he knows there is a packet to read
*/
inline static int mmnif_trigger_irq(dest_ip)
inline static int mmnif_trigger_irq(int dest_ip)
{
int tmp, x, y, z, addr;
int ue = dest_ip - 1;
@ -344,7 +336,7 @@ inline static int mmnif_trigger_irq(dest_ip)
// send interrupt to ue
do {
NOP1;
NOP8;
tmp = ReadConfigReg(addr);
} while (tmp & 1);
tmp |= 1;
@ -353,21 +345,6 @@ inline static int mmnif_trigger_irq(dest_ip)
return 0;
}
/* mmnif_get_device_stats(): Returns a copy of the
* current device
*/
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");
else
stats = ((mmnif_t *) mmnif_dev->state)->stats;
return stats;
}
/* mmnif_print_stats(): Print the devices stats of the
* current device
*/
@ -437,36 +414,15 @@ void mmnif_print_driver_status(void)
static 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;
ip_addr_p_t ip;
/* 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;
ip = iphdr->dest;
/* 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;
return ip4_addr4(&ip);
}
/* mmnif_rxbuff_alloc():
@ -477,7 +433,7 @@ static uint8_t mmnif_get_destination(struct netif *netif, struct pbuf *p)
static uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len)
{
uint32_t ret = 0;
mm_rx_buffer_t *rb = (mm_rx_buffer_t *) ((char *)header_start_address + (dest - 1) * header_size);
volatile 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)/2*16*1024*1024 + (dest-1)%2 * 0x2000;
@ -492,7 +448,7 @@ static uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len)
// if ((rb->head - rb->tail < len)&&(rb->tail != rb->head))
// return NULL;
RCCE_acquire_lock(dest-1);
RCCE_acquire_lock(RC_COREID[dest-1]);
if (rb->dcount)
{
if (rb->tail > rb->head)
@ -542,9 +498,8 @@ static uint32_t mmnif_rxbuff_alloc(uint8_t dest, uint16_t len)
}
}
}
RCCE_release_lock(RC_COREID[dest-1]);
out:
RCCE_release_lock(dest-1);
return ret;
}
@ -554,7 +509,7 @@ out:
*/
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);
volatile 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++)
@ -564,6 +519,7 @@ static int mmnif_commit_packet(uint8_t dest, uint32_t addr)
{
rb->desc_table[i].stat = MMNIF_STATUS_RDY;
rb->desc_table[i].fast_sock = -1;
return 0;
}
}
@ -577,7 +533,7 @@ static int mmnif_commit_packet(uint8_t dest, uint32_t addr)
*/
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);
volatile 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++)
@ -600,11 +556,11 @@ static int mmnif_commit_packet_bypass(uint8_t dest, uint32_t addr, int dest_sock
static void mmnif_rxbuff_free(void)
{
mmnif_t *mmnif = mmnif_dev->state;
mm_rx_buffer_t *b = mmnif->rx_buff;
volatile mm_rx_buffer_t *b = mmnif->rx_buff;
uint32_t i, j;
uint32_t rpos;
RCCE_acquire_lock(RCCE_IAM);
RCCE_acquire_lock(RC_MY_COREID);
rpos = b->dread;
for (i = 0, j = rpos; i < MMNIF_MAX_DESCRIPTORS; i++)
@ -631,7 +587,7 @@ static void mmnif_rxbuff_free(void)
break;
}
RCCE_release_lock(RCCE_IAM);
RCCE_release_lock(RC_MY_COREID);
}
/*
@ -644,7 +600,6 @@ static err_t mmnif_tx(struct netif *netif, struct pbuf *p)
uint32_t i;
struct pbuf *q; /* interator */
uint32_t dest_ip = mmnif_get_destination(netif, p);
//int32_t chances = 4000;
/* check for over/underflow */
if (BUILTIN_EXPECT((p->tot_len < 20 /* IP header size */) || (p->tot_len > 1536), 0)) {
@ -652,6 +607,12 @@ static err_t mmnif_tx(struct netif *netif, struct pbuf *p)
goto drop_packet;
}
/* check destination ip */
if (BUILTIN_EXPECT((dest_ip < 1) || (dest_ip > MMNIF_CORES), 0)) {
DEBUGPRINTF("mmnif_tx: invalid destination IP %d => drop\n", dest_ip);
goto drop_packet;
}
/* allocate memory for the packet in the remote buffer */
realloc:
write_address = mmnif_rxbuff_alloc(dest_ip, p->tot_len);
@ -659,14 +620,7 @@ realloc:
{
//DEBUGPRINTF("mmnif_tx(): concurrency");
//chances--;
//if (chances <= 0)
// goto drop_packet;
//if (chances % 17 == 0)
// mmnif_trigger_irq(dest_ip);
NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;
//udelay(10);
goto realloc;
}
@ -703,6 +657,7 @@ realloc:
LINK_STATS_INC(link.xmit);
mmnif->stats.tx++;
mmnif->stats.tx_bytes += p->tot_len;
mmnif_trigger_irq(dest_ip);
return ERR_OK;
@ -756,6 +711,7 @@ static int mmnif_hashadd(int sock, int rsock, uint8_t dest_ip)
p->socket = sock;
p->remote_socket = rsock;
p->dest_ip = dest_ip;
return 0;
}
}
@ -783,6 +739,7 @@ static int mmnif_hashdelete(int sock)
p->socket = -1;
p->remote_socket = 0;
p->dest_ip = 0;
return 0;
}
}
@ -797,38 +754,16 @@ static err_t mmnif_tx_bypass(struct netif * netif, void *pbuff, uint16_t size, i
{
mmnif_t *mmnif = netif->state;
uint32_t write_address;
//uint32_t id;
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));
write_address = mmnif_rxbuff_alloc(dest->dest_ip, size);
if (!write_address)
{
// DEBUGPRINTF("mmnif_tx_bypass(): concurrency");
// udelay(exp_delay);
// exp_delay << 1;
// reschedule();
NOP8;
NOP8;
NOP8;
NOP8;
NOP8;
NOP8;
NOP8;
NOP8;
NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;NOP8;
goto realloc;
}
@ -844,7 +779,7 @@ realloc:
#if !MMNIF_USE_MPB
memcpy_to_nc((void*) write_address, pbuff, size);
#else
memcpy_put(write_address, pbuff, size);
memcpy_put((void*) write_address, pbuff, size);
#endif
*((int *)RCCE_fool_write_combine_buffer) = 1;
@ -854,7 +789,7 @@ realloc:
if (mmnif_commit_packet_bypass(dest->dest_ip, write_address, dest->remote_socket))
{
DEBUGPRINTF("mmnif_tx(): packet somehow lost during commit\n");
DEBUGPRINTF("mmnif_tx_bypass(): packet somehow lost during commit\n");
}
#ifdef DEBUG_MMNIF_PACKET
// DEBUGPRINTF("\n SEND %p with length: %d\n",(char*)mpb_start_address + (dest_ip -1)*mpb_size + pos * 1792,p->tot_len +2);
@ -865,15 +800,10 @@ realloc:
LINK_STATS_INC(link.xmit);
mmnif->stats.tx++;
mmnif->stats.tx_bytes += size;
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_trigger_irq(dest->dest_ip);
return ERR_OK;
}
/* mmnif_send(): is going to be used as replacement of
@ -882,28 +812,30 @@ drop_packet:
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;
uint32_t i, j, k;
int total_size = 0;
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)));
if (size < ((MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE)) {
if (mmnif_tx_bypass(mmnif_dev, data, size, s) == ERR_OK)
return size;
} else {
j = size / (((MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE));
k = size - (j * (((MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE)));
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;
if (mmnif_tx_bypass(mmnif_dev, (char*) data + i * ((MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE), ((MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE), s) != ERR_OK)
return total_size;
total_size += (MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE;
}
ret = mmnif_tx_bypass(mmnif_dev, data + (j - 1) * ((MMNIF_RX_BUFFERLEN / 2) - 1), k, s);
return ret;
if (mmnif_tx_bypass(mmnif_dev, data + (j - 1) * ((MMNIF_RX_BUFFERLEN / 2) - CLINE_SIZE), k, s) == ERR_OK)
total_size += k;
}
return total_size;
}
return lwip_send(s, data, size, flags);
@ -914,8 +846,7 @@ int mmnif_send(int s, void *data, size_t size, int flags)
* 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)
static err_t mmnif_link_layer(struct netif *netif, struct pbuf *q, ip_addr_t * ipaddr)
{
return netif->linkoutput(netif, q);
}
@ -934,7 +865,6 @@ err_t mmnif_init(struct netif *netif)
DEBUGPRINTF("mmnif init attempt\n");
mmnif_dev = netif;
own_ip_address += RCCE_ue() + 1;
/* Alloc and clear memory for the device struct
*/
@ -959,7 +889,7 @@ err_t mmnif_init(struct netif *netif)
// 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_WT | MAP_NO_CACHE);
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));
mmnif->rx_buff = (mm_rx_buffer_t *) (header_start_address + header_size * RCCE_IAM);
/* Alloc and clear shared memory for rx_buff
*/
@ -980,25 +910,25 @@ err_t mmnif_init(struct netif *netif)
// align size to the granularity of a page size
heap_size = (heap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
heap_start_address = (void*) RCCE_shmalloc(heap_size * MMNIF_CORES);
DEBUGPRINTF("RCCE_shmalloc : %p (size %u)\n", header_start_address, MMNIF_CORES * header_size);
DEBUGPRINTF("RCCE_shmalloc : %p (size %u)\n", heap_start_address, MMNIF_CORES * header_size);
// map physical address in the virtual address space
#if USE_CACHE
uint32_t n = (uint32_t) heap_start_address;
heap_start_address = map_region(0, heap_start_address, (MMNIF_CORES * heap_size) >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_NO_CACHE | MAP_MPE | MAP_WT);
map_region(heap_start_address + (heap_size) * (own_ip_address - router_ip_address), n + (heap_size) * (own_ip_address - router_ip_address), header_size >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_MPE | MAP_WT | MAP_REMAP);
map_region(heap_start_address + (heap_size) * RCCE_IAM, n + (heap_size) * RCCE_IAM, header_size >> PAGE_SHIFT, MAP_KERNEL_SPACE | MAP_MPE | MAP_WT | MAP_REMAP);
#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 | MAP_WT);
#endif // USE_CACHE
#endif // MMNIF_USE_MPB
DEBUGPRINTF("map_region : %p\n", header_start_address);
DEBUGPRINTF("map_region : %p\n", heap_start_address);
#if MMNIF_USE_MPB
mmnif->rx_heap = heap_start_address;
heap_start_address = heap_start_address - (RC_MY_COREID/2 * 16*1024*1024 ) - (RC_MY_COREID%2 * 0x2000);
DEBUGPRINTF("heap_start_address : %p\n", heap_start_address);
#else
mmnif->rx_heap = heap_start_address + (heap_size) * (own_ip_address - router_ip_address);
mmnif->rx_heap = heap_start_address + heap_size * RCCE_IAM;
#endif
if (!(heap_start_address))
@ -1007,13 +937,9 @@ err_t mmnif_init(struct netif *netif)
return ERR_MEM;
}
#if !MMNIF_USE_MPB
memset(mmnif->rx_buff, 0x00, header_size);
memset(mmnif->rx_heap, 0x00, heap_size);
*((int *)RCCE_fool_write_combine_buffer) = 1;
#else
#if MMNIF_USE_MPB
asm volatile (".byte 0x0f; .byte 0x0a;\n");
#endif
for(i=0; i<header_size; i++)
((uint8_t*)mmnif->rx_buff)[i] = 0x00;
@ -1021,6 +947,7 @@ err_t mmnif_init(struct netif *netif)
((uint8_t*)mmnif->rx_heap)[i] = 0x00;
*((int *)RCCE_fool_write_combine_buffer) = 1;
#if MMNIF_USE_MPB
asm volatile (".byte 0x0f; .byte 0x0a;\n");
#endif
@ -1030,9 +957,7 @@ err_t mmnif_init(struct netif *netif)
/* init the lock's for the hdr
*/
spinlock_init(&mmnif->rx_buff->rlock);
spinlock_init(&pseudolock);
spinlock_init(&mmnif->lock);
/* init the sems for communication art
*/
@ -1043,10 +968,9 @@ err_t mmnif_init(struct netif *netif)
mmnif_hashtable[i].socket = -1;
mmnif_hashtable[i].remote_socket = -1;
mmnif_hashtable[i].dest_ip = 0;
//mmnif_hashtable[i].counter = 0;
#if MMNIF_FAST_SOCKET_BLOCK
sem_init(&mmnif_hashtable[i].sem, 0);
#endif
}
for (i=0; i<MMNIF_MAX_ACCEPTORS; i++)
@ -1056,9 +980,6 @@ err_t mmnif_init(struct netif *netif)
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 */
@ -1100,25 +1021,24 @@ err_t mmnif_init(struct netif *netif)
static void mmnif_rx(struct netif *netif)
{
mmnif_t *mmnif = netif->state;
mm_rx_buffer_t *b = mmnif->rx_buff;
volatile mm_rx_buffer_t *b = mmnif->rx_buff;
uint16_t length = 0;
struct pbuf *p;
struct pbuf *q;
char *packet = NULL;
uint32_t i, j;
uint32_t i, j, flags;
uint8_t rdesc;
err_t err = ERR_OK;
bypass_rxdesc_t *bp;
anotherpacket:
flags = irq_nested_disable();
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);
goto out;
}
@ -1142,26 +1062,21 @@ anotherpacket:
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();
goto out;
} 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
irq_nested_enable(flags);
return;
}
spinlock_unlock(&b->rlock);
goto out;
}
}
if (b->desc_table[(j + i) % MMNIF_MAX_DESCRIPTORS].stat == MMNIF_STATUS_FREE)
{
spinlock_unlock(&b->rlock);
goto out;
}
}
spinlock_unlock(&b->rlock);
/* if there is no packet finished we encountered a random error
*/
@ -1176,6 +1091,8 @@ anotherpacket:
goto out;
}
irq_nested_enable(flags);
/* check for over/underflow */
if (BUILTIN_EXPECT((length < 20 /* IP header size */) || (length > 1536), 0))
{
@ -1253,9 +1170,12 @@ drop_packet:
/* TODO: error handling */
LINK_STATS_INC(link.drop);
mmnif->stats.rx_err++;
mmnif->check_in_progress = 0;
return;
out:
mmnif->check_in_progress = 0;
irq_nested_enable(flags);
return;
}
@ -1265,19 +1185,15 @@ out:
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;
uint16_t length;
char *packet;
volatile mm_rx_buffer_t *b = mmnif->rx_buff;
uint16_t length = 0;
char *packet = NULL;
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);
if (b->desc_table[b->dread].stat == MMNIF_STATUS_FREE) {
return -1;
}
@ -1296,14 +1212,10 @@ static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len)
}
}
// 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
*/
@ -1320,13 +1232,28 @@ static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len)
#ifdef DEBUG_MMNIF_PACKET
DEBUGPRINTF("\n RECIEVED - %p 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
if (BUILTIN_EXPECT(len < length, 0))
goto drop_packet;
#if USE_CACHE || MMNIF_USE_MPB
asm volatile (".byte 0x0f; .byte 0x0a;\n");
#endif
#if !USE_CACHE && !MMNIF_USE_MBP
memcpy_from_nc(data, (void*) mmnif->rx_buff->desc_table[rdesc].addr, mmnif->rx_buff->desc_table[rdesc].len);
#elif MMNIF_USE_MPB
memcpy_get(data, (void*) mmnif->rx_buff->desc_table[rdesc].addr, mmnif->rx_buff->desc_table[rdesc].len);
#else
memcpy(data, (void*) mmnif->rx_buff->desc_table[rdesc].addr, mmnif->rx_buff->desc_table[rdesc].len);
#endif
*((int *)RCCE_fool_write_combine_buffer) = 1;
#if MMNIF_USE_MPB
asm volatile (".byte 0x0f; .byte 0x0a;\n");
#endif
/* 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
*/
@ -1345,10 +1272,6 @@ static int mmnif_rx_bypass(struct netif *netif, int s, void *data, uint32_t len)
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++;
@ -1360,28 +1283,47 @@ drop_packet:
*/
int mmnif_recv(int s, void *data, uint32_t len, int flags)
{
mmnif_t* mmnif = (mmnif_t *) mmnif_dev->state;
bypass_rxdesc_t *p = mmnif_hashlookup(s);
int ret;
if (p == 0)
return lwip_recv(s, data, len, flags);
#if MMNIF_FAST_SOCKET_BLOCK
if (sem_trywait(&p->sem) == 0)
return mmnif_rx_bypass(mmnif_dev, s, data, len);
uint32_t state = irq_nested_disable();
if (mmnif->check_in_progress) {
uint32_t i,j;
volatile mm_rx_buffer_t *b = mmnif->rx_buff;
bypass_rxdesc_t *bp;
uint8_t rdesc;
/* 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) {
bp = mmnif_hashlookup(b->desc_table[rdesc].fast_sock);
if (bp) {
b->desc_table[rdesc].stat = MMNIF_STATUS_INPROC;
irq_nested_enable(state);
return mmnif_rx_bypass(mmnif_dev, s, data, len);
}
}
}
}
mmnif->check_in_progress = 0;
}
irq_nested_enable(state);
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;
return mmnif_rx_bypass(mmnif_dev, s, data, len);
}
/* mmnif_socket(): replacement of lwip_socket for
@ -1407,27 +1349,30 @@ int mmnif_socket(int domain, int type, int protocol)
*/
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;
struct sockaddr_in *client = (struct sockaddr_in*)addr;
volatile mm_rx_buffer_t *b = ((mmnif_t *) mmnif_dev->state)->rx_buff;
bypass_rxdesc_t *p;
int tmp1 = get_clock_tick();
int tmp2 = 0;
int i, tmp2 = 0;
uint16_t port;
// TODO: Bug, not compatible with BSD sockets
port = client->sin_port;
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);
RCCE_acquire_lock(RC_MY_COREID);
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);
RCCE_release_lock(RC_MY_COREID);
while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPT_ME)
NOP8;
@ -1435,48 +1380,46 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen)
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);
RCCE_acquire_lock(RC_MY_COREID);
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);
RCCE_release_lock(RC_MY_COREID);
return i;
}
}
return -1;
}
else
{
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);
RCCE_acquire_lock(RC_MY_COREID);
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);
RCCE_release_lock(RC_MY_COREID);
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);
RCCE_acquire_lock(RC_MY_COREID);
if (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat == MMNIF_ACC_STAT_ACCEPT_ME)
{
spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock);
RCCE_acquire_lock(RC_MY_COREID);
break;
}
DEBUGPRINTF("mmnif_accept(): Timout occoured, switching to normal accept()");
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);
RCCE_release_lock(RC_MY_COREID);
goto normalaccept;
}
NOP8;
@ -1485,14 +1428,15 @@ int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen)
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);
RCCE_acquire_lock(RC_MY_COREID);
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);
RCCE_release_lock(RC_MY_COREID);
return i;
}
}
return -1;
}
@ -1507,48 +1451,29 @@ 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;
volatile 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];
core = ip4_addr4(&p->sin_addr.s_addr);
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);
b = (volatile 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);
RCCE_acquire_lock(RC_COREID[core-1]);
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);
b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].src_ip = ip4_addr4(&mmnif_dev->ip_addr);
mmnif_hashadd(s, b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].nsock, core);
RCCE_release_lock(RC_COREID[core-1]);
while (b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat != MMNIF_ACC_STAT_ACCEPTED)
{
@ -1563,9 +1488,11 @@ int mmnif_connect(int s, const struct sockaddr *name, socklen_t namelen)
// }
NOP8;
}
spinlock_lock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock);
RCCE_acquire_lock(RC_COREID[core-1]);
b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].stat = MMNIF_ACC_STAT_CLOSED;
spinlock_unlock(&b->acceptors[(i + port) % MMNIF_MAX_ACCEPTORS].alock);
RCCE_release_lock(RC_COREID[core-1]);
return 0;
}
}
@ -1589,6 +1516,13 @@ int mmnif_bind(int s, const struct sockaddr *name, socklen_t namelen)
return 0;
}
int mmnif_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
{
if ((unsigned int)s < MMNIF_PSEUDO_SOCKET_START)
return lwip_setsockopt(s, level, optname, optval, optlen);
return 0;
}
/* mmnif_closesocket(): replacement if lwip_close for
* fast_sockets
*/
@ -1628,7 +1562,7 @@ static void mmnif_irqhandler(struct state* s)
mmnif = (mmnif_t *) mmnif_dev->state;
if (!mmnif->check_in_progress) {
if (tcpip_callback_with_block(mmnif_rx, (void*) mmnif_dev, 0) == ERR_OK) {
mmnif->check_in_progress = 1;
mmnif->check_in_progress = 1;
} else {
DEBUGPRINTF("rckemacif_handler: unable to send a poll request to the tcpip thread\n");
}

View file

@ -24,26 +24,50 @@
#ifdef CONFIG_LWIP
#include <lwip/err.h>
#include <lwip/netif.h> /* lwip netif */
#include <lwip/sockets.h>
#define AF_MMNIF_NET 0x1337
#define AF_MMNIF_NET 0x42
#define MMNIF_AUTOACTIVATE_FAST_SOCKETS 0
#define MMNIF_AUTOACTIVATE_FAST_SOCKETS 1
#if MMNIF_AUTOACTIVATE_FAST_SOCKETS
int mmnif_socket(int domain, int type, int protocol);
int mmnif_send(int s, void *data, size_t size, int flags);
int mmnif_recv(int s, void *data, uint32_t len, int flags);
int mmnif_accept(int s, struct sockaddr *addr, socklen_t * addrlen);
int mmnif_connect(int s, const struct sockaddr *name, socklen_t namelen);
int mmnif_listen(int s, int backlog);
int mmnif_bind(int s, const struct sockaddr *name, socklen_t namelen);
int mmnif_closesocket(int s);
int mmnif_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
int mmnif_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
#undef accept
#define accept(a,b,c) mmnif_accept(a,b,c)
#undef closesocket
#define closesocket(s) mmnif_closesocket(s)
#undef connect
#define connect(a,b,c) mmnif_connect(a,b,c)
#undef recv
#define recv(a,b,c,d) mmnif_recv(a,b,c,d)
#undef send
#define send(a,b,c,d) mmnif_send(a,b,c,d)
#undef socket
#define socket(a,b,c) mmnif_socket(a,b,c)
#undef bind
#define bind(a,b,c) mmnif_bind(a,b,c)
#undef listen
#define listen(a,b) mmnif_listen(a,b)
#undef setsockopt
#define setsockopt(a,b,c,d,e) mmnif_setsockopt(a,b,c,d,e)
#undef select
#endif
err_t mmnif_init(struct netif*);
err_t mmnif_shutdown(void);
int mmnif_worker(void *e);
void mmnif_print_driver_status();
void mmnif_print_driver_status(void);
#endif

View file

@ -36,8 +36,8 @@ extern "C" {
* initialize the VGA output. If configured.*/
int lowlevel_init(void);
/** @brief Shutdown the system */
int shutdown(void);
/** @brief Shutdown the network */
int network_shutdown(void);
/** @brief Entry point of the init task */
int initd(void* arg);

View file

@ -171,7 +171,7 @@ static void tcpip_init_done(void* arg)
}
#endif
static int network_shutdown(void)
int network_shutdown(void)
{
#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK)
mmnif_shutdown();
@ -183,15 +183,6 @@ static int network_shutdown(void)
return 0;
}
int shutdown(void)
{
int ret;
ret = network_shutdown();
return ret;
}
static void list_fs(vfs_node_t* node, uint32_t depth)
{
int j, i = 0;