From 318324949e803997a916b5c0c257bdbccae89313 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 29 May 2011 13:02:04 -0700 Subject: [PATCH 01/59] add missing directory to the list of the lwip directories --- Makefile.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.example b/Makefile.example index 554c241d..71ff1725 100644 --- a/Makefile.example +++ b/Makefile.example @@ -1,7 +1,7 @@ TOPDIR = $(shell pwd) ARCH = x86 NAME = metalsvm -LWIPDIRS = lwip/src/api lwip/src/core lwip/src/core/ipv4 lwip/src/netif +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) SUBDIRS = $(KERNDIRS) From 5d16090b766a7ba02de70ef7bac468997d7a70da Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 29 May 2011 15:30:34 -0700 Subject: [PATCH 02/59] map FPGA registers to the kernel space --- arch/x86/include/asm/SCC_API.h | 3 +++ arch/x86/mm/page.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/arch/x86/include/asm/SCC_API.h b/arch/x86/include/asm/SCC_API.h index eb1bf99c..8812fefc 100644 --- a/arch/x86/include/asm/SCC_API.h +++ b/arch/x86/include/asm/SCC_API.h @@ -155,6 +155,9 @@ #define CRB_X5_Y3 0xf7000000 #define CRB_OWN 0xf8000000 +// FPGA registers +#define FPGA_BASE 0xf9000000 + // Symbol for RPC #define RPC_BASE 0xfb000000 diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 184f8865..a202a1bb 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -733,6 +733,10 @@ int arch_paging_init(void) // map SCC's message passing buffers viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+16*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE); kprintf("Map message passing buffers at 0x%x\n", viraddr); + + // map the FPGA registers + viraddr = map_region(FPGA_BASE, FPGA_BASE, (16*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); + kprintf("Map FPGA regsiters at 0x%x\n", viraddr); #endif /* enable paging */ From 7fdb044e9a63b0b91a00acfc39f98b83715bf803 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Mon, 30 May 2011 11:22:54 +0200 Subject: [PATCH 03/59] Encapsulated FPU restore instructions. There is a new procedure restore_fpu_state() in arch/x86/include/asm/tasks_types. Will need this code in lguest, too. --- arch/x86/include/asm/tasks_types.h | 7 +++++++ arch/x86/kernel/isrs.c | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/tasks_types.h b/arch/x86/include/asm/tasks_types.h index ffaee4fd..34c01228 100644 --- a/arch/x86/include/asm/tasks_types.h +++ b/arch/x86/include/asm/tasks_types.h @@ -68,6 +68,13 @@ static inline void save_fpu_state(union fpu_state* state) { asm volatile ("fsave %0; fwait" : "=m"((*state).fsave)); } +static inline void restore_fpu_state(union fpu_state* state) { + if (has_fxsr()) + asm volatile ("fxrstor %0" :: "m"(state->fxsave)); + else + asm volatile ("frstor %0" :: "m"(state->fsave)); +} + #ifdef __cplusplus } #endif diff --git a/arch/x86/kernel/isrs.c b/arch/x86/kernel/isrs.c index 4c461894..ed0d6792 100644 --- a/arch/x86/kernel/isrs.c +++ b/arch/x86/kernel/isrs.c @@ -196,11 +196,7 @@ static void fpu_handler(struct state *s) task->flags |= TASK_FPU_INIT; } - // restore the FPU context - if (has_fxsr()) - asm volatile ("fxrstor %0" :: "m"(task->fpu.fxsave)); - else - asm volatile ("frstor %0" :: "m"(task->fpu.fsave)); + restore_fpu_state(&task->fpu); task->flags |= TASK_FPU_USED; } From 683f36b83e68b1b4afe957f990a9f7a0fb77a259 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 10:22:26 +0200 Subject: [PATCH 04/59] added mailbox-system --- arch/x86/scc/iRCCE_mailbox.c | 360 +++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 arch/x86/scc/iRCCE_mailbox.c diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c new file mode 100644 index 00000000..107b56a6 --- /dev/null +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -0,0 +1,360 @@ +//****************************************************************************** +// Mailbox system. +//****************************************************************************** +// +// Author: Rob F. Van der Wijngaart +// Intel Corporation +// Date: 008/30/2010 +// +//****************************************************************************** +// +// Copyright 2010 Intel Corporation +// +// 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. +// +// [2011-05-08] implemented mailbox send/recv routines +// by Simon Pickartz, Chair for Operating Systems, +// RWTH Aachen University +// +#include "iRCCE_lib.h" +#include +#include + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_print_header +//------------------------------------------------------------------------------ +// routine for printing given header (debugging purpose) +//------------------------------------------------------------------------------ +void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) { + + printf( "\n" + "-------------------------\n" + "| RCK%d\n" + "-------------------------\n" + "| Sender\t: %d\t\n" + "| Size\t\t: %d\t\n" + "| Tag\t\t: %d\t\n" + "| Prio\t\t: %d\t\n" + "| Payload\t: %s\n" + "-------------------------\n\n", + RCCE_IAM, header->source, + header->size, header->tag, + header->prio, header->payload); +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_enqueue_header +//------------------------------------------------------------------------------ +// routine to put push received header into iRCCE_mailbox_recv_queue +//------------------------------------------------------------------------------ +static int iRCCE_mail_fetch( + int rank // rank from whom to empty mailbox + ) { + + iRCCE_MAIL_HEADER* header; + + // check for memory in garbage collection or allocate new + if( iRCCE_mail_garbage.first ) { + header = iRCCE_mail_garbage.first; + iRCCE_mail_garbage.first = + iRCCE_mail_garbage.first->next; + + header->next = NULL; + if( iRCCE_mail_garbage.first == NULL ) { + iRCCE_mail_garbage.last = NULL; + } + } + else { + header = (iRCCE_MAIL_HEADER*)kmalloc(sizeof(iRCCE_MAIL_HEADER)); + } + + + // copy header to allocated memory + RC_cache_invalidate(); + iRCCE_memcpy_get( (void*)header, (void*)iRCCE_mailbox_recv[rank], + RCCE_LINE_SIZE ); + + // check if received a last-mail + if( header->tag == iRCCE_LAST_MAIL ) { + iRCCE_last_mail[rank] = 1; + iRCCE_mailbox_close( rank ); // we can close respective mailbox + free( header ); + } + else { + // check mail priority + int prio = header->prio; + + // enqueue accordingly + if( iRCCE_mailbox_recv_queue[prio] == NULL ) { + iRCCE_mailbox_recv_queue[prio] = header; + } + else { + iRCCE_MAIL_HEADER* run = iRCCE_mailbox_recv_queue[prio]; + while( run->next != NULL ) run = run->next; + run->next = header; + } + } + + + return iRCCE_SUCCESS; +} + + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_check +//------------------------------------------------------------------------------ +// routine to check for new mail in mailboxes +//------------------------------------------------------------------------------ +static int iRCCE_mailbox_check() { + int i, j; + int tmp; + + for( i=0; isent ) { + iRCCE_mail_fetch(i); + + // reset senders flag + RC_cache_invalidate(); + iRCCE_mailbox_recv[i]->sent = RCCE_FLAG_UNSET; + *(int *)RCCE_fool_write_combine_buffer = 1; + } + } + } + + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_recv +//------------------------------------------------------------------------------ +// routine for fetching received headers out of iRCCE_mailbox_recv_queue +//------------------------------------------------------------------------------ +int iRCCE_mail_recv( + iRCCE_MAIL_HEADER** header // pointer to incoming header + ) { // (memory allocated by iRCCE) + + int i; + + // if there is no mail, check for incoming + if ( !iRCCE_mailbox_recv_queue[0] ) { + iRCCE_mailbox_check(); + } + + // check priority queues + for( i=0; inext; + help_header->next = NULL; + + + *header = help_header; + return iRCCE_SUCCESS; + } + } + + // no mail queued + *header = NULL; + return iRCCE_MAILBOX_EMPTY; + +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_release +//------------------------------------------------------------------------------ +// routine to free memory for given header +//------------------------------------------------------------------------------ +int iRCCE_mail_release( + iRCCE_MAIL_HEADER** header + ) { + + // put header in garbage collection + if( (iRCCE_mail_garbage.first == NULL) + && (iRCCE_mail_garbage.last == NULL ) ) { + + iRCCE_mail_garbage.first = *header; + iRCCE_mail_garbage.last = *header; + } + else { + iRCCE_mail_garbage.last->next = *header; + iRCCE_mail_garbage.last = *header; + } + iRCCE_mail_garbage.last->next = NULL; + + // reset header + *header = NULL; + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mail_send +//------------------------------------------------------------------------------ +// routine for sending headers into receivers mailbox (blocking) +//------------------------------------------------------------------------------ +int iRCCE_mail_send( + size_t size, // size of following message expected to be send/received + int tag, // tag to indicate message type + char prio, // mail priority + char* payload, // pointer to buffer for header payload + int dest // UE that will receive the header + ) { + + // if dest mailbox is full, check for incoming mail + RC_cache_invalidate(); + while( iRCCE_mailbox_send[dest]->sent ) { + iRCCE_mailbox_check(); + RC_cache_invalidate(); + } + + // check if mailbox is closed + RCCE_acquire_lock( dest ); + RC_cache_invalidate(); + if( iRCCE_mailbox_send[dest]->closed ) { + RCCE_release_lock( dest ); + return iRCCE_MAILBOX_CLOSED; + } + + // prepare header + iRCCE_MAIL_HEADER header = { RCCE_IAM, size, tag, NULL, prio, + RCCE_FLAG_UNSET, RCCE_FLAG_UNSET, + {[0 ... iRCCE_MAIL_HEADER_PAYLOAD-1] = 0} }; + + // payload within the header? + if( payload ) { + memcpy( header.payload, payload, iRCCE_MAIL_HEADER_PAYLOAD ); + } + + // do the actual copy to MPB + RC_cache_invalidate(); + iRCCE_memcpy_put( (void*)iRCCE_mailbox_send[dest], + (void*)&header, RCCE_LINE_SIZE ); + + // set senders flag + RC_cache_invalidate(); + iRCCE_mailbox_send[dest]->sent = RCCE_FLAG_SET; + *(int *)RCCE_fool_write_combine_buffer = 1; + RC_cache_invalidate(); + + RCCE_release_lock( dest ); + + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_last_mail_recv +//------------------------------------------------------------------------------ +// check if all final headers are received from all UEs +//------------------------------------------------------------------------------ +int iRCCE_last_mail_recv(void) { + int i; + int res = iRCCE_SUCCESS; + + for( i=0; inext; + free( erase_header ); + erase_header = iRCCE_mailbox_recv_queue[i]; + } + } + return iRCCE_SUCCESS; +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_close_one +//------------------------------------------------------------------------------ +// routine to close one mailbox +//------------------------------------------------------------------------------ +static int iRCCE_mailbox_close_one(int rank) { + RCCE_acquire_lock( RCCE_IAM ); + + // check if it contains new mail + RC_cache_invalidate(); + if( iRCCE_mailbox_recv[rank]->sent ) { + iRCCE_mail_fetch(rank); + + } + + // close mailbox + iRCCE_MAIL_HEADER help_header = { 0, 0, 0, NULL, 0, RCCE_FLAG_UNSET, + RCCE_FLAG_SET, {[0 ... iRCCE_MAIL_HEADER_PAYLOAD-1] = 0} }; + + RC_cache_invalidate(); + iRCCE_memcpy_put( (void*)iRCCE_mailbox_recv[rank], + &help_header, RCCE_LINE_SIZE ); + + RCCE_release_lock( RCCE_IAM ); + + iRCCE_mailbox_status[rank] = iRCCE_MAILBOX_CLOSED; + + return iRCCE_SUCCESS; +} + + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_mailbox_close() +//------------------------------------------------------------------------------ +// routine to close one or all mailboxes +//------------------------------------------------------------------------------ +int iRCCE_mailbox_close(int rank) { + if( rank == iRCCE_MAILBOX_ALL ) { + int i; + for( i=0; i Date: Tue, 31 May 2011 10:45:22 +0200 Subject: [PATCH 05/59] added mailbox-support --- arch/x86/include/asm/iRCCE.h | 58 ++++++++++++++++++++++++++++---- arch/x86/include/asm/iRCCE_lib.h | 17 ++++++++++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/iRCCE.h b/arch/x86/include/asm/iRCCE.h index 8b878bfd..5c0edfc3 100644 --- a/arch/x86/include/asm/iRCCE.h +++ b/arch/x86/include/asm/iRCCE.h @@ -30,12 +30,29 @@ #ifndef IRCCE_H #define IRCCE_H -#include +#include "RCCE.h" #define iRCCE_SUCCESS RCCE_SUCCESS -#define iRCCE_PENDING -1 -#define iRCCE_RESERVED -2 -#define iRCCE_NOT_ENQUEUED -3 +#define iRCCE_PENDING -1 +#define iRCCE_RESERVED -2 +#define iRCCE_NOT_ENQUEUED -3 + +#define iRCCE_ANY_SOURCE -1 + +#define iRCCE_PRIOS 5 +#define iRCCE_MAILBOX_EMPTY -2 +#define iRCCE_LAST_MAILS_NOT_RECV -3 +#define iRCCE_MAILBOX_ALL -4 +#define iRCCE_MAILBOX_OPEN 0 +#define iRCCE_MAILBOX_CLOSED 1 + +// iRCCE-mailbox-system tags +#define iRCCE_LAST_MAIL -1 +#define iRCCE_ANYLENGTH -2 +#define iRCCE_ANYLENGTH_PIGGYBACK -3 + + +typedef volatile char iRCCE_SHORT_FLAG; typedef struct _iRCCE_SEND_REQUEST { char *privbuf; // source buffer in local private memory (send buffer) @@ -94,15 +111,32 @@ typedef struct _iRCCE_WAIT_LIST { } iRCCE_WAIT_LIST; +#define iRCCE_MAIL_HEADER_PAYLOAD 13 +typedef struct _iRCCE_MAIL_HEADER { + int source; // UE that will send the header + size_t size; // size of the message which will be send/received + int tag; // tag indicating which kind of message we have + struct _iRCCE_MAIL_HEADER* next;// pointer for queue - could be replaced by list-object + char prio; // priority of the mail + iRCCE_SHORT_FLAG sent; // flag indicating that header is new + iRCCE_SHORT_FLAG closed; // flag indication that mailbox is closed + char payload[iRCCE_MAIL_HEADER_PAYLOAD]; // payload for small messages +} iRCCE_MAIL_HEADER; + +typedef struct _iRCCE_MAIL_TRASH_BIN { + iRCCE_MAIL_HEADER* first; + iRCCE_MAIL_HEADER* last; +} iRCCE_MAIL_TRASH_BIN; + /////////////////////////////////////////////////////////////// // // THE iRCCE API: // -// Initialize function: +// Initialize/Finalize functions: int iRCCE_init(void); // // Non-blocking send/recv functions: -int iRCCE_isend(char *, size_t, int, iRCCE_SEND_REQUEST *); +int iRCCE_isend(char *, ssize_t, int, iRCCE_SEND_REQUEST *); int iRCCE_isend_test(iRCCE_SEND_REQUEST *, int *); int iRCCE_isend_wait(iRCCE_SEND_REQUEST *); int iRCCE_isend_push(void); @@ -133,6 +167,18 @@ int iRCCE_wait_any(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST **, iRCCE_RECV_REQUEST int iRCCE_isend_cancel(iRCCE_SEND_REQUEST *, int *); int iRCCE_irecv_cancel(iRCCE_RECV_REQUEST *, int *); // +// Blocking send/recv functions for mailbox system +int iRCCE_mail_send(size_t, int, char, char*, int); +int iRCCE_mail_recv(iRCCE_MAIL_HEADER**); +// +// functions to empty mailbox-queue and to check for last mails: +int iRCCE_mail_release(iRCCE_MAIL_HEADER**); +int iRCCE_last_mail_recv(void); +int iRCCE_mailbox_wait(void); +int iRCCE_mailbox_flush(void); +int iRCCE_mailbox_close(int); +void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER*); +// /////////////////////////////////////////////////////////////// // // Just for for convenience: diff --git a/arch/x86/include/asm/iRCCE_lib.h b/arch/x86/include/asm/iRCCE_lib.h index 0d8b4e16..372b9cdd 100644 --- a/arch/x86/include/asm/iRCCE_lib.h +++ b/arch/x86/include/asm/iRCCE_lib.h @@ -29,6 +29,23 @@ extern iRCCE_SEND_REQUEST* iRCCE_isend_queue; extern iRCCE_RECV_REQUEST* iRCCE_irecv_queue[RCCE_MAXNP]; +extern iRCCE_RECV_REQUEST* iRCCE_irecv_any_source_queue; + +// pointer to MPB-mailbox-space +extern volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_send[RCCE_MAXNP]; +extern volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_recv[RCCE_MAXNP]; + +// queue for received headers +extern iRCCE_MAIL_HEADER* iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; + +// flags for last mail +extern iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; + +// field to store open/closed status of mailboxes +extern iRCCE_SHORT_FLAG iRCCE_mailbox_status[RCCE_MAXNP]; + +// garbage collection for mailbox +extern iRCCE_MAIL_TRASH_BIN iRCCE_mail_garbage; #ifdef _OPENMP #pragma omp threadprivate (iRCCE_isend_queue, iRCCE_irecv_queue) #endif From b05400348aaa064edc14050f704f99403a682602 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 10:48:28 +0200 Subject: [PATCH 06/59] anylength support in isend --- arch/x86/scc/Makefile | 2 +- arch/x86/scc/iRCCE_admin.c | 47 +++++++++++++- arch/x86/scc/iRCCE_isend.c | 127 +++++++++++++++++++++++++++---------- 3 files changed, 140 insertions(+), 36 deletions(-) diff --git a/arch/x86/scc/Makefile b/arch/x86/scc/Makefile index 2003a259..c3ffb3c8 100644 --- a/arch/x86/scc/Makefile +++ b/arch/x86/scc/Makefile @@ -1,4 +1,4 @@ -C_source := icc.c SCC_API.c iRCCE_admin.c iRCCE_send.c iRCCE_isend.c iRCCE_irecv.c iRCCE_recv.c iRCCE_get.c iRCCE_put.c iRCCE_synch.c RCCE_malloc.c RCCE_shmalloc.c RCCE_debug.c RCCE_qsort.c RCCE_DCMflush.c RCCE_send.c RCCE_recv.c RCCE_flags.c RCCE_comm.c RCCE_put.c RCCE_get.c RCCE_synch.c RCCE_bcast.c RCCE_admin.c # RCCE_power_management.c +C_source := icc.c SCC_API.c iRCCE_admin.c iRCCE_mailbox.c iRCCE_send.c iRCCE_isend.c iRCCE_irecv.c iRCCE_recv.c iRCCE_get.c iRCCE_put.c iRCCE_synch.c RCCE_malloc.c RCCE_shmalloc.c RCCE_debug.c RCCE_qsort.c RCCE_DCMflush.c RCCE_send.c RCCE_recv.c RCCE_flags.c RCCE_comm.c RCCE_put.c RCCE_get.c RCCE_synch.c RCCE_bcast.c RCCE_admin.c # RCCE_power_management.c ASM_source := MODULE := arch_x86_scc diff --git a/arch/x86/scc/iRCCE_admin.c b/arch/x86/scc/iRCCE_admin.c index c61d66b9..ba465765 100644 --- a/arch/x86/scc/iRCCE_admin.c +++ b/arch/x86/scc/iRCCE_admin.c @@ -47,6 +47,27 @@ iRCCE_SEND_REQUEST* iRCCE_isend_queue; // recv request queue iRCCE_RECV_REQUEST* iRCCE_irecv_queue[RCCE_MAXNP]; +// recv request queue for those with source = iRCCE_ANY_SOURCE: +iRCCE_RECV_REQUEST* iRCCE_irecv_any_source_queue; + +// mailbox in MPB +volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_recv[RCCE_MAXNP]; // store addresses for receiving headers +volatile iRCCE_MAIL_HEADER* iRCCE_mailbox_send[RCCE_MAXNP]; // store addresses for sending headeres + +// mailbox recv queue +iRCCE_MAIL_HEADER* iRCCE_mailbox_recv_queue[iRCCE_PRIOS]; + +// mail garbage queue +iRCCE_MAIL_TRASH_BIN iRCCE_mail_garbage; + +// flag indicating if last header was received +iRCCE_SHORT_FLAG iRCCE_last_mail[RCCE_MAXNP]; + +// field to store open/closed status of mailboxes +iRCCE_SHORT_FLAG iRCCE_mailbox_status[RCCE_MAXNP]; + + + //-------------------------------------------------------------------------------------- // FUNCTION: iRCCE_init //-------------------------------------------------------------------------------------- @@ -56,10 +77,34 @@ int iRCCE_init(void) { int i; for(i=0; i= RCCE_NP) - return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_ID)); - else { - iRCCE_init_send_request(privbuf, RCCE_buff_ptr, RCCE_chunk, - &RCCE_ready_flag[dest], &RCCE_sent_flag[RCCE_IAM], - size, dest, request); - if(iRCCE_isend_queue == NULL) { + iRCCE_init_send_request(privbuf, RCCE_buff_ptr, RCCE_chunk, + &RCCE_ready_flag[dest], &RCCE_sent_flag[RCCE_IAM], + size, dest, request); - if(iRCCE_push_send_request(request) == iRCCE_SUCCESS) { - return(iRCCE_SUCCESS); - } - else { - iRCCE_isend_queue = request; + if(iRCCE_isend_queue == NULL) { - if(request == &blocking_isend_request) { - iRCCE_isend_wait(request); - return(iRCCE_SUCCESS); - } - - return(iRCCE_PENDING); - } + if(iRCCE_push_send_request(request) == iRCCE_SUCCESS) { + return(iRCCE_SUCCESS); } else { - if(iRCCE_isend_queue->next == NULL) { - iRCCE_isend_queue->next = request; - } - else { - iRCCE_SEND_REQUEST *run = iRCCE_isend_queue; - while(run->next != NULL) run = run->next; - run->next = request; - } + iRCCE_isend_queue = request; if(request == &blocking_isend_request) { iRCCE_isend_wait(request); return(iRCCE_SUCCESS); } - return(iRCCE_RESERVED); + return(iRCCE_PENDING); } } + else { + if(iRCCE_isend_queue->next == NULL) { + iRCCE_isend_queue->next = request; + } + else { + iRCCE_SEND_REQUEST *run = iRCCE_isend_queue; + while(run->next != NULL) run = run->next; + run->next = request; + } + + if(request == &blocking_isend_request) { + iRCCE_isend_wait(request); + return(iRCCE_SUCCESS); + } + + return(iRCCE_RESERVED); + } +} + +//------------------------------------------------------------------------------ +// FUNCTION: iRCCE_isend +//------------------------------------------------------------------------------ +// wrapper function to differentiate between anylength and normal call +//------------------------------------------------------------------------------ +static iRCCE_SEND_REQUEST blocking_isend_request; +int iRCCE_isend( + char *privbuf, + ssize_t size, + int dest, + iRCCE_SEND_REQUEST *request + ) { + if(request == NULL) request = &blocking_isend_request; + + if (dest<0 || dest >= RCCE_NP) { + return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_ID)); + } + else { + // anylength call + if( size < 0 ){ + // convert size to positive range */ + int send_size = -size; + + // use header payload + if( send_size <= iRCCE_MAIL_HEADER_PAYLOAD ) { + iRCCE_init_send_request(privbuf, RCCE_buff_ptr, + RCCE_chunk, &RCCE_ready_flag[dest], + &RCCE_sent_flag[RCCE_IAM], + send_size, dest, request); + request->finished = 1; + + iRCCE_mail_send( send_size, + iRCCE_ANYLENGTH_PIGGYBACK, + 0, privbuf, dest ); + return iRCCE_SUCCESS; + } + // we need an extra isend-call + else { + iRCCE_mail_send( send_size, iRCCE_ANYLENGTH, + 0, NULL, dest ); + return iRCCE_isend_general( privbuf, send_size, + dest, request ); + } + } + // normal call + else if( size > 0 ) { + return iRCCE_isend_general( privbuf, size, + dest, request ); + } + // do nothing + else { + iRCCE_init_send_request(privbuf, RCCE_buff_ptr, + RCCE_chunk, &RCCE_ready_flag[dest], + &RCCE_sent_flag[RCCE_IAM], + size, dest, request); + request->finished = 1; + return(iRCCE_SUCCESS); + } + + } + } //-------------------------------------------------------------------------------------- From cb3f4295e4be7db3c8a0579836627d0dc8bd4f5b Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 01:50:47 -0700 Subject: [PATCH 07/59] add iRCCE_mailbox.c to Makefile --- arch/x86/scc/Makefile | 2 +- arch/x86/scc/iRCCE_mailbox.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/x86/scc/Makefile b/arch/x86/scc/Makefile index 2003a259..74d355a4 100644 --- a/arch/x86/scc/Makefile +++ b/arch/x86/scc/Makefile @@ -1,4 +1,4 @@ -C_source := icc.c SCC_API.c iRCCE_admin.c iRCCE_send.c iRCCE_isend.c iRCCE_irecv.c iRCCE_recv.c iRCCE_get.c iRCCE_put.c iRCCE_synch.c RCCE_malloc.c RCCE_shmalloc.c RCCE_debug.c RCCE_qsort.c RCCE_DCMflush.c RCCE_send.c RCCE_recv.c RCCE_flags.c RCCE_comm.c RCCE_put.c RCCE_get.c RCCE_synch.c RCCE_bcast.c RCCE_admin.c # RCCE_power_management.c +C_source := icc.c SCC_API.c iRCCE_admin.c iRCCE_send.c iRCCE_isend.c iRCCE_irecv.c iRCCE_recv.c iRCCE_get.c iRCCE_put.c iRCCE_synch.c iRCCE_mailbox.c RCCE_malloc.c RCCE_shmalloc.c RCCE_debug.c RCCE_qsort.c RCCE_DCMflush.c RCCE_send.c RCCE_recv.c RCCE_flags.c RCCE_comm.c RCCE_put.c RCCE_get.c RCCE_synch.c RCCE_bcast.c RCCE_admin.c # RCCE_power_management.c ASM_source := MODULE := arch_x86_scc diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index 107b56a6..cd8783d8 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -26,9 +26,12 @@ // by Simon Pickartz, Chair for Operating Systems, // RWTH Aachen University // -#include "iRCCE_lib.h" -#include -#include +#include +#include + + +#ifdef CONFIG_ROCKCREEK +#include //------------------------------------------------------------------------------ // FUNCTION: iRCCE_mailbox_print_header @@ -37,7 +40,7 @@ //------------------------------------------------------------------------------ void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) { - printf( "\n" + kprintf( "\n" "-------------------------\n" "| RCK%d\n" "-------------------------\n" @@ -358,3 +361,5 @@ int iRCCE_mailbox_close(int rank) { return iRCCE_SUCCESS; } + +#endif From d1fd6d151fff6bba32d4978c55d2d2c6c1cc6e1f Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 01:57:48 -0700 Subject: [PATCH 08/59] kfree calls match to inteface now --- arch/x86/scc/iRCCE_mailbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index cd8783d8..4c235da9 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -91,7 +91,7 @@ static int iRCCE_mail_fetch( if( header->tag == iRCCE_LAST_MAIL ) { iRCCE_last_mail[rank] = 1; iRCCE_mailbox_close( rank ); // we can close respective mailbox - free( header ); + kfree( header, sizeof(iRCCE_MAIL_HEADER) ); } else { // check mail priority @@ -305,7 +305,7 @@ int iRCCE_mailbox_flush(void) { while( erase_header != NULL ) { iRCCE_mailbox_recv_queue[i] = iRCCE_mailbox_recv_queue[i]->next; - free( erase_header ); + kfree( erase_header, sizeof(iRCCE_MAIL_HEADER) ); erase_header = iRCCE_mailbox_recv_queue[i]; } } From 3cf792d2502e17a15dadede09e6aa54571cb5d3d Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 02:55:40 -0700 Subject: [PATCH 09/59] add mailbox test --- arch/x86/scc/icc.c | 19 +++++++++++++++++++ kernel/Makefile | 2 +- kernel/mailbox.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ kernel/main.c | 4 ++-- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 kernel/mailbox.c diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 05292396..2cb97066 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -230,6 +230,25 @@ int icc_ping(int ue) return 0; } +int icc_mail_ping( void ) +{ + int remote_rank = (my_ue+1)%2; + + // send mail + iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); + + // wait for mail from remote rank + iRCCE_MAIL_HEADER* mail; + do { + iRCCE_mail_recv( &mail ); + } while( !mail ); + + // show content + iRCCE_mailbox_print_header( mail ); + + return 0; + +} static void interpret_header(icc_header_t* header, int recv_ue) { //kprintf("Got ICC message %d from %d\n", header->type, recv_ue); diff --git a/kernel/Makefile b/kernel/Makefile index fdddee71..f70f6a77 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c +C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c mailbox.c MODULE := kernel include $(TOPDIR)/Makefile.inc diff --git a/kernel/mailbox.c b/kernel/mailbox.c new file mode 100644 index 00000000..f34f9e1a --- /dev/null +++ b/kernel/mailbox.c @@ -0,0 +1,44 @@ +/* + * Copyright 2010 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 +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ROCKCREEK +#include + +int STDCALL mail_ping(void* arg) { + icc_mail_ping(); + + return 0; +} + +int mailbox_test_init(void) +{ + char* argv[] = {"/bin/mailbox", NULL}; + + create_user_task(NULL, "/bin/mailbox", argv); + + return 0; +} +#endif diff --git a/kernel/main.c b/kernel/main.c index daf7f3af..ac65706f 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -35,7 +35,7 @@ #endif extern int test_init(void); - +extern int mailbox_test_init(void); /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. @@ -115,7 +115,7 @@ int main(void) sleep(5); list_root(); test_init(); - + mailbox_test_init(); per_core(current_task)->status = TASK_IDLE; reschedule(); From 9aa95fee0ce547bd5d92094d3565bd7d5ceb7fd6 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 12:58:15 +0200 Subject: [PATCH 10/59] add anysource support for irecv and recv --- arch/x86/scc/iRCCE_irecv.c | 233 +++++++++++++++++++++++++++++++++---- arch/x86/scc/iRCCE_recv.c | 12 ++ 2 files changed, 220 insertions(+), 25 deletions(-) diff --git a/arch/x86/scc/iRCCE_irecv.c b/arch/x86/scc/iRCCE_irecv.c index e7d5ad1d..4af79efb 100644 --- a/arch/x86/scc/iRCCE_irecv.c +++ b/arch/x86/scc/iRCCE_irecv.c @@ -50,7 +50,9 @@ static int iRCCE_push_recv_request(iRCCE_RECV_REQUEST *request) { char padline[RCCE_LINE_SIZE]; // copy buffer, used if message not multiple of line size int test; // flag for calling iRCCE_test_flag() - if(request->finished) return(iRCCE_SUCCESS); + if(request->finished) { + return(iRCCE_SUCCESS); + } if(request->label == 1) goto label1; if(request->label == 2) goto label2; @@ -167,6 +169,25 @@ static void iRCCE_init_recv_request( return; } +int iRCCE_irecv_search_source() { + int i, j; + int res =iRCCE_ANY_SOURCE; + + for( i=0; inext == NULL ) { + iRCCE_irecv_any_source_queue->next = request; + } + else { + iRCCE_RECV_REQUEST* run = iRCCE_irecv_any_source_queue; + while( run->next != NULL ) run = run->next; + run->next = request; + } + } + return iRCCE_RESERVED; + } + } if (source<0 || source >= RCCE_NP) return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_ID)); @@ -211,10 +273,10 @@ int iRCCE_irecv(char *privbuf, size_t size, int source, iRCCE_RECV_REQUEST *requ run->next = request; } - if(request == &blocking_irecv_request) { - iRCCE_irecv_wait(request); - return(iRCCE_SUCCESS); - } + if(request == &blocking_irecv_request) { + iRCCE_irecv_wait(request); + return(iRCCE_SUCCESS); + } return(iRCCE_RESERVED); } @@ -243,29 +305,98 @@ int iRCCE_irecv_test(iRCCE_RECV_REQUEST *request, int *test) { } } - source = request->source; + // does request still have no source? + if( request->source == iRCCE_ANY_SOURCE ) { + request->source = iRCCE_irecv_search_source(); - if(request->finished) { - if (test) (*test) = 1; - return(iRCCE_SUCCESS); + if( request->source == iRCCE_ANY_SOURCE ) { + if (test) (*test) = 0; + return iRCCE_RESERVED; + } + else { // take request out of wait_any_source-list + + // find request in queue + if( request == iRCCE_irecv_any_source_queue ) { + iRCCE_irecv_any_source_queue = iRCCE_irecv_any_source_queue->next; + } + else { + iRCCE_RECV_REQUEST* run = iRCCE_irecv_any_source_queue; + while( run->next != request ) run = run->next; + run->next = request->next; + } + + request->next = NULL; + request->sent = &RCCE_sent_flag[request->source]; // set senders flag + source = request->source; + + // queue request in iRCCE_irecv_queue + if(iRCCE_irecv_queue[source] == NULL) { + + if(iRCCE_push_recv_request(request) == iRCCE_SUCCESS) { + if (test) (*test) = 1; + return(iRCCE_SUCCESS); + } + else { + iRCCE_irecv_queue[source] = request; + + if(request == &blocking_irecv_request) { + iRCCE_irecv_wait(request); + if (test) (*test) = 1; + return(iRCCE_SUCCESS); + } + if (test) (*test) = 0; + return(iRCCE_PENDING); + } + } + else { + if(iRCCE_irecv_queue[source]->next == NULL) { + iRCCE_irecv_queue[source]->next = request; + } + else { + iRCCE_RECV_REQUEST *run = iRCCE_irecv_queue[source]; + while(run->next != NULL) run = run->next; + run->next = request; + } + + if(request == &blocking_irecv_request) { + iRCCE_irecv_wait(request); + if (test) (*test) = 1; + return(iRCCE_SUCCESS); + } + + if (test) (*test) = 1; + return(iRCCE_RESERVED); + } + + + } } + else { + + source = request->source; + + if(request->finished) { + if (test) (*test) = 1; + return(iRCCE_SUCCESS); + } + + if(iRCCE_irecv_queue[source] != request) { + if (test) (*test) = 0; + return(iRCCE_RESERVED); + } + + iRCCE_push_recv_request(request); + + if(request->finished) { + iRCCE_irecv_queue[source] = request->next; + + if (test) (*test) = 1; + return(iRCCE_SUCCESS); + } - if(iRCCE_irecv_queue[source] != request) { if (test) (*test) = 0; - return(iRCCE_RESERVED); + return(iRCCE_PENDING); } - - iRCCE_push_recv_request(request); - - if(request->finished) { - iRCCE_irecv_queue[source] = request->next; - - if (test) (*test) = 1; - return(iRCCE_SUCCESS); - } - - if (test) (*test) = 0; - return(iRCCE_PENDING); } @@ -297,6 +428,40 @@ static int iRCCE_irecv_push_source(int source) { } int iRCCE_irecv_push(void) { + iRCCE_RECV_REQUEST* help_request; + + // first check sourceless requests + if( iRCCE_irecv_any_source_queue != NULL) { + while( iRCCE_irecv_any_source_queue != NULL ) { + iRCCE_irecv_any_source_queue->source = iRCCE_irecv_search_source(); + + if( iRCCE_irecv_any_source_queue->source == iRCCE_ANY_SOURCE ) { + + break; + } + // source found for first request in iRCCE_irecv_any_source_queue + else { + // set senders flag + iRCCE_irecv_any_source_queue->sent = &RCCE_sent_flag[iRCCE_irecv_any_source_queue->source]; + + // take request out of irecv_any_source_queue + help_request = iRCCE_irecv_any_source_queue; + iRCCE_irecv_any_source_queue = iRCCE_irecv_any_source_queue->next; + help_request->next = NULL; + + // put request into irecv_queue + if(iRCCE_irecv_queue[help_request->source] == NULL) { + iRCCE_irecv_queue[help_request->source] = help_request; + } + else { + iRCCE_RECV_REQUEST *run = iRCCE_irecv_queue[help_request->source]; + while(run->next != NULL) run = run->next; + run->next = help_request; + } + } + } + + } int i, j; int retval = iRCCE_SUCCESS; @@ -310,7 +475,7 @@ int iRCCE_irecv_push(void) { } } - return retval; + return (iRCCE_irecv_any_source_queue == NULL)? retval : iRCCE_RESERVED; } //-------------------------------------------------------------------------------------- @@ -352,6 +517,24 @@ int iRCCE_irecv_cancel(iRCCE_RECV_REQUEST *request, int *test) { return iRCCE_NOT_ENQUEUED; } + + // does request have any source specified? + if( request->source == iRCCE_ANY_SOURCE ) { + for( run = iRCCE_irecv_any_source_queue; run->next != NULL; run = run->next ) { + if( run->next == request ) { + run->next = run->next->next; + + if (test) (*test) = 1; + return iRCCE_SUCCESS; + } + } + + if (test) (*test) = 0; + return iRCCE_NOT_ENQUEUED; + } + + + source = request->source; if(iRCCE_irecv_queue[source] == NULL) { diff --git a/arch/x86/scc/iRCCE_recv.c b/arch/x86/scc/iRCCE_recv.c index 17beccfd..7733675b 100644 --- a/arch/x86/scc/iRCCE_recv.c +++ b/arch/x86/scc/iRCCE_recv.c @@ -177,6 +177,18 @@ int iRCCE_recv(char *privbuf, size_t size, int source) { iRCCE_isend_push(); } + + // determine source of request if given source = iRCCE_ANY_SOURCE + if ( source==iRCCE_ANY_SOURCE ){ + int i, res; + for( i=0;;i=(++i)%RCCE_NP ){ + if ( (i != RCCE_IAM) && (res = RCCE_probe(RCCE_sent_flag[i])) ){ + source = i; + break; + } + } + } + if (source<0 || source >= RCCE_NP) return(RCCE_error_return(RCCE_debug_comm,RCCE_ERROR_ID)); else { From 4a1930fb9f729abaf27f420fbc9dc5fe5568d603 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 04:29:20 -0700 Subject: [PATCH 11/59] bug fix --- arch/x86/scc/icc.c | 6 ++++++ kernel/main.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 2cb97066..594b6ebb 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -232,8 +232,12 @@ int icc_ping(int ue) int icc_mail_ping( void ) { + uint32_t flags; int remote_rank = (my_ue+1)%2; + // iRCCE is not thread save => disable interrupts + flags = irq_nested_disable(); + // send mail iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); @@ -246,6 +250,8 @@ int icc_mail_ping( void ) // show content iRCCE_mailbox_print_header( mail ); + irq_nested_enable(flags); + return 0; } diff --git a/kernel/main.c b/kernel/main.c index ac65706f..38803cf9 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -115,7 +115,9 @@ int main(void) sleep(5); list_root(); test_init(); + kprintf( "calling mailbox test ... \n" ); mailbox_test_init(); + kprintf( "mailbox test succeded!\n" ); per_core(current_task)->status = TASK_IDLE; reschedule(); From e59860dde379a2ca379e16b21ff6fe5c1ef10fa3 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 04:57:55 -0700 Subject: [PATCH 12/59] add icc_mail_ping to icc.h --- arch/x86/include/asm/icc.h | 2 ++ arch/x86/scc/icc.c | 1 + kernel/mailbox.c | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/icc.h b/arch/x86/include/asm/icc.h index dfc69302..f08bd07c 100644 --- a/arch/x86/include/asm/icc.h +++ b/arch/x86/include/asm/icc.h @@ -54,6 +54,8 @@ int icc_init(void); int icc_ping(int ue); void icc_check(void); int icc_halt(void); +int icc_mail_ping(void); + #endif #ifdef __cplusplus diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 594b6ebb..531001e6 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -237,6 +237,7 @@ int icc_mail_ping( void ) // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); + kprintf( "Hello from icc_mail_ping\n" ); // send mail iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); diff --git a/kernel/mailbox.c b/kernel/mailbox.c index f34f9e1a..36e01e59 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -28,6 +28,7 @@ #include int STDCALL mail_ping(void* arg) { + kprintf( "Hello from mail_ping\n" ); icc_mail_ping(); return 0; @@ -36,7 +37,7 @@ int STDCALL mail_ping(void* arg) { int mailbox_test_init(void) { char* argv[] = {"/bin/mailbox", NULL}; - + kprintf( "Hello from mailbox_test_init\n" ); create_user_task(NULL, "/bin/mailbox", argv); return 0; From 11e61b681602a6e4c7ad72359361ee1749051eaf Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 31 May 2011 05:47:16 -0700 Subject: [PATCH 13/59] add printfs --- arch/x86/scc/icc.c | 3 ++- kernel/mailbox.c | 7 +++++-- kernel/main.c | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 531001e6..d50bcf3b 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -235,13 +235,14 @@ int icc_mail_ping( void ) uint32_t flags; int remote_rank = (my_ue+1)%2; + kprintf( "### Hello from icc_mail_ping\n" ); // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); - kprintf( "Hello from icc_mail_ping\n" ); // send mail iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); + // wait for mail from remote rank iRCCE_MAIL_HEADER* mail; do { diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 36e01e59..016e22aa 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -28,8 +28,11 @@ #include int STDCALL mail_ping(void* arg) { - kprintf( "Hello from mail_ping\n" ); + + kprintf( "### Hello from mail_ping\n" ); + icc_mail_ping(); + kprintf( "### mail_ping finished\n" ); return 0; } @@ -37,7 +40,7 @@ int STDCALL mail_ping(void* arg) { int mailbox_test_init(void) { char* argv[] = {"/bin/mailbox", NULL}; - kprintf( "Hello from mailbox_test_init\n" ); + kprintf( "### Hello from mailbox_test_init\n" ); create_user_task(NULL, "/bin/mailbox", argv); return 0; diff --git a/kernel/main.c b/kernel/main.c index 38803cf9..f3b7d36f 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -114,7 +114,7 @@ int main(void) sleep(5); list_root(); - test_init(); + //test_init(); kprintf( "calling mailbox test ... \n" ); mailbox_test_init(); kprintf( "mailbox test succeded!\n" ); From 3645a598da02edb6d2c9de297c7aca257287bb0f Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 31 May 2011 23:44:03 +0200 Subject: [PATCH 14/59] remove typo --- arch/x86/scc/RCCE_admin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/scc/RCCE_admin.c b/arch/x86/scc/RCCE_admin.c index a9a624ae..2ad87e18 100644 --- a/arch/x86/scc/RCCE_admin.c +++ b/arch/x86/scc/RCCE_admin.c @@ -337,7 +337,7 @@ int RCCE_init( RCCE_shmalloc_init(RC_SHM_BUFFER_START()+RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX); #ifdef SHMDBG - kprintf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: % x %x\n", RCCE_IAM, + kprintf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: %x %x\n", RCCE_IAM, __FILE__,__LINE__,RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX); #endif #else From 6c80f9e15a1ba550997cfa5f026d53fa48b3e77b Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 5 Jun 2011 00:05:41 -0700 Subject: [PATCH 15/59] add initial version of eMAC driver as workround for some bugs, a few LwIP features and the interrupt handling in ICC are disabled --- arch/x86/scc/icc.c | 4 +- drivers/net/Makefile | 2 +- drivers/net/rckemac.c | 735 ++++++++++++++++++++++++++++++++++++ drivers/net/rckemac.h | 61 +++ kernel/Makefile | 2 +- kernel/init.c | 31 +- kernel/tests.c | 2 +- lwip/src/include/lwipopts.h | 4 +- 8 files changed, 829 insertions(+), 12 deletions(-) create mode 100644 drivers/net/rckemac.c create mode 100644 drivers/net/rckemac.h diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 05292396..730add0b 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -132,6 +132,7 @@ int icc_init(void) RCCE_barrier(&RCCE_COMM_WORLD); +#if 0 kputs("RCCE test...\t"); if (my_ue == 0) msg = 0x4711; @@ -139,6 +140,7 @@ int icc_init(void) kprintf("successfull! (0x%x)\n", msg); else kprintf("failed! (0x%x)\n", msg); +#endif // reset INTR/LINT0 flag z = Z_PID(RC_COREID[my_ue]); @@ -147,7 +149,7 @@ int icc_init(void) SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp); // set interrupt handler (INTR/LINT0) - irq_install_handler(124, intr_handler); + //irq_install_handler(124, intr_handler); kputs("Now, the SCC is initialized!\n"); diff --git a/drivers/net/Makefile b/drivers/net/Makefile index bee77167..871a955c 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -1,4 +1,4 @@ -C_source := rtl8139.c +C_source := rtl8139.c rckemac.c MODULE := drivers_net include $(TOPDIR)/Makefile.inc diff --git a/drivers/net/rckemac.c b/drivers/net/rckemac.c new file mode 100644 index 00000000..319ac04b --- /dev/null +++ b/drivers/net/rckemac.c @@ -0,0 +1,735 @@ +/* + * Copyright 2011 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) +#include +#include +#include +#include +#include + +/* Limits */ +#define BUFFER_ORDER 9 +#define BUFFER_NUM (1 << BUFFER_ORDER) +#define BUFFER_SIZE (BUFFER_NUM * PAGE_SIZE) + +#define EMAC0 0x01 +#define EMAC1 0x02 +#define EMAC2 0x04 +#define EMAC3 0x08 + +#define EMAC_IPCONF 0x3200 +#define EMAC_RX_CONTROL 0x9000 +#define EMAC_TX_CONTROL 0x9900 + +/* Xilinx IP configuration - offsets */ +#define CONFIG_FLOW_CONTROL_ADD 0xC0 +#define TRANSMITTER_ADDRESS 0x80 +#define RECEIVER1_ADDRESS 0x40 +#define CONFIG_ADD 0x100 +#define ADD_FILTER_MOD 0x190 + +/* EMAC RX */ +#define EMAC_RX_BUFFER_START_ADDRESS 0x0000 +#define EMAC_RX_BUFFER_READ_OFFSET 0x0100 +#define EMAC_RX_BUFFER_WRITE_OFFSET 0x0200 +#define EMAC_RX_BUFFER_SIZE 0x0300 +#define EMAC_RX_BUFFER_THRESHOLD 0x0400 +#define EMAC_RX_MODE 0x0500 +#define EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI 0x0600 +#define EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO 0x0700 +#define EMAC_RX_NETWORK_PORT_ENABLE 0x0800 + +/* EMAC TX */ +#define EMAC_TX_BUFFER_START_ADDRESS 0x0000 +#define EMAC_TX_BUFFER_READ_OFFSET 0x0100 +#define EMAC_TX_BUFFER_WRITE_OFFSET 0x0200 +#define EMAC_TX_BUFFER_SIZE 0x0300 +#define EMAC_TX_MODE 0x0400 +#define EMAC_TX_NETWORK_PORT_ENABLE 0x0500 + +// Using of LVT1 as interrupt line +#define EMAC_IRQ_MASK 0x00000001 +#define EMAC_IRQ_NR 3 +#define EMAC_LVT APIC_LVT1 +#define EMAC_IRQ_CONFIG 1 + +#define IRQ_STATUS 0xD000 +#define IRQ_MASK 0xD200 +#define IRQ_RESET 0xD400 +#define IRQ_CONFIG 0xD800 + +/* 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_PACKETS(_x) (CLINE_ALIGN(_x) >> CLINE_SHIFT) + +#define MAC_ADDRESS 0x00454D414331ULL +#define MAC_HI(_x) ((((_x) >> 32)) & 0xFFFF) +#define MAC_LO(_x) (((_x) ) & 0xFFFFFFFF) + +static struct netif* mynetif[4] = {NULL, NULL, NULL, NULL}; + +static inline int read_emac(int num_emac, int offset, int core) +{ + return *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); +} + +static inline void write_emac(int num_emac, int offset, int core, int value) +{ + *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)) = value; +} + +/* + * @return error code + * - ERR_OK: packet transferred to hardware + * - ERR_CONN: no link or link failure + * - ERR_IF: could not transfer to link (hardware buffer full?) + */ +static err_t rckemacif_output(struct netif* netif, struct pbuf* p) +{ + rckemacif_t* rckemacif = netif->state; + uint32_t i; + struct pbuf *q; + void *addr = NULL; + uint16_t read_offset = 0; + int rest = 0; + int packets = 0; + int sum = 0; + + /* check for over/underflow */ + if (BUILTIN_EXPECT(p->tot_len > 1536, 0)) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_output: illegal packet length %d => drop\n", p->len)); + return ERR_IF; + } + + rckemacif->tx_write_offset++; + /* check if we need to wrap */ + if (rckemacif->tx_write_offset > rckemacif->tx_buffer_max) + rckemacif->tx_write_offset = 1; + + packets = CLINE_PACKETS(p->tot_len + 2); + + read_offset = read_emac(rckemacif->num_emac, EMAC_TX_CONTROL+EMAC_TX_BUFFER_READ_OFFSET, rckemacif->core); +#if 1 +again: + if (read_offset < rckemacif->tx_write_offset) { + sum = rckemacif->tx_buffer_max - rckemacif->tx_write_offset + read_offset - 1; + } else if (read_offset > rckemacif->tx_write_offset) { + sum = read_offset - rckemacif->tx_write_offset - 1; + } + + if (sum < packets) { + LWIP_DEBUGF(NETIF_DEBUG, ("Warning: not enough space available, retrying...\n")); + goto again; + } +#endif + + addr = rckemacif->tx_buffer + rckemacif->tx_write_offset * 32; + + /* Set frame length */ + ((uint8_t*)addr)[0] = p->tot_len % 256; + ((uint8_t*)addr)[1] = p->tot_len / 256; + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + if (rckemacif->tx_write_offset + packets - 1 <= rckemacif->tx_buffer_max) { + /* + * q traverses through linked list of pbuf's + * This list MUST consist of a single packet ONLY + */ + for (q = p, i = 0; q != 0; q = q->next) { + memcpy(addr + 2 + i, q->payload, q->len); + i += q->len; + } + + /* increment write ptr */ + rckemacif->tx_write_offset += packets - 1; + } else { + /* wrap in offsets. first copy to the end, second at the starting + * point + */ + int bytes_left = p->tot_len; + int bytes_to_copy = (rckemacif->tx_buffer_max - rckemacif->tx_write_offset + 1) * 32 - 2; + int sz = 0; + + if (bytes_left < bytes_to_copy) + bytes_to_copy = bytes_left; + + LWIP_DEBUGF(NETIF_DEBUG, ("special case: copy last %d bytes\n", bytes_to_copy)); + + q = p; i = 0; + while ((q != 0) && (i < bytes_to_copy)) { + sz = q->len > bytes_to_copy-i ? bytes_to_copy-i : q->len; + memcpy(addr + 2 + i, q->payload, sz); + bytes_left -= sz; + i += sz; + if (i < bytes_to_copy) + q = q->next; + } + + if (bytes_left != 0) { + rckemacif->tx_write_offset = 1; + addr = rckemacif->tx_buffer + 32; + LWIP_DEBUGF(NETIF_DEBUG, ("special case: copy remaining %d bytes\n", bytes_left)); + + i = 0; + if (sz < q->len) { + memcpy(addr, q->payload + sz, q->len - sz); + bytes_left -= (q->len - sz); + i = q->len - sz; + } + for(q=q->next; (q != 0); q = q->next) { + memcpy(addr+i, q->payload, q->len); + i += q->len; + } + + rest = bytes_left % 32; + if (rest != 0) + rest = 32 - rest; + + LWIP_DEBUGF(NETIF_DEBUG, ("Rest is %d\n", rest)); + rckemacif->tx_write_offset += CLINE_PACKETS(bytes_left + rest) - 1; + } + } + + *((volatile int*) rckemacif->tx_buffer) = 2; + + /* set new write offset */ + LWIP_DEBUGF(NETIF_DEBUG, ("Update tx write offset: %d (read offset %d)\n", rckemacif->tx_write_offset, read_offset)); + + write_emac(rckemacif->num_emac, EMAC_TX_CONTROL+EMAC_TX_BUFFER_WRITE_OFFSET, rckemacif->core, rckemacif->tx_write_offset); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +#if 0 +static void rtl_rx_inthandler(struct netif* netif) +{ + rtl1839if_t* rtl8139if = netif->state; + uint16_t header; + uint16_t length, i; + uint8_t cmd; + struct pbuf *p = NULL; + struct pbuf* q; + + cmd = inportb(rtl8139if->iobase + CR); + while(!(cmd & CR_BUFE)) { + header = *((uint16_t*) (rtl8139if->rx_buffer+rtl8139if->rx_pos)); + rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % (8192+16); + + if (header & ISR_ROK) { + length = *((uint16_t*) (rtl8139if->rx_buffer+rtl8139if->rx_pos)) - 4; // copy packet (but not the CRC) + rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % (8192+16); +#if ETH_PAD_SIZE + length += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); + if (p) { +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + for (q=p; q!=NULL; q=q->next) { + for(i=0; ilen; i++) { + ((uint8_t*) q->payload)[i] = rtl8139if->rx_buffer[rtl8139if->rx_pos]; + rtl8139if->rx_pos = (rtl8139if->rx_pos + 1) % (8192+16); + } + } +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + mailbox_ptr_post(&rtl8139if->mbox, (void*)p); + //rtl8139if_input(netif, p); + LINK_STATS_INC(link.recv); + } else { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: not enough memory!\n")); + rtl8139if->rx_pos += (rtl8139if->rx_pos + length) % (8192+16); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + } + + // packets are dword aligned + rtl8139if->rx_pos = ((rtl8139if->rx_pos + 4 + 3) & ~0x3) % (8192+16); + outportw(rtl8139if->iobase + CAPR, rtl8139if->rx_pos - 0x10); + } else { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: invalid header!\n")); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + break; + } + + cmd = inportb(rtl8139if->iobase + CR); + } +} + +static void rtl_tx_inthandler(struct netif* netif) +{ + rtl1839if_t* rtl8139if = netif->state; + uint32_t checks = rtl8139if->tx_queue - rtl8139if->tx_complete; + uint32_t txstatus; + uint8_t tmp8; + + while(checks > 0) + { + tmp8 = rtl8139if->tx_complete % 4; + txstatus = inportl(rtl8139if->iobase + TSD0 + tmp8 * 4); + + if (!(txstatus & (TSD_TOK|TSD_TUN|TSD_TABT))) + return; + + if (txstatus & (TSD_TABT | TSD_OWC)) { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_tx_inthandler: major error\n")); + continue; + } + + if (txstatus & TSD_TUN) { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_tx_inthandler: transmit underrun\n")); + } + + if (txstatus & TSD_TOK) { + rtl8139if->tx_inuse[tmp8] = 0; + rtl8139if->tx_complete++; + checks--; + } + } +} +#endif + +static void rckemacif_handler(struct state* s) +{ + LWIP_DEBUGF(NETIF_DEBUG, ("HELLO! Got interrupt!\n")); + +#if 0 + rtl1839if_t* rtl8139if = mynetif->state; + uint16_t isr_contents; + + while (1) { + isr_contents = inportw(rtl8139if->iobase + ISR); + if (isr_contents == 0) + break; + + if (isr_contents & ISR_ROK) { + rtl_rx_inthandler(mynetif); + outportw(rtl8139if->iobase + ISR, ISR_ROK); + } + + if (isr_contents & ISR_TOK) { + rtl_tx_inthandler(mynetif); + outportw(rtl8139if->iobase + ISR, ISR_TOK); + } + + if (isr_contents & ISR_RER) { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: RX error detected!\n")); + outportw(rtl8139if->iobase + ISR, ISR_RER); + } + + if (isr_contents & ISR_TER) { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: TX error detected!\n")); + outportw(rtl8139if->iobase + ISR, ISR_TER); + } + + if (isr_contents & ISR_RXOVW) { + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: RX overflow detected!\n")); + outportw(rtl8139if->iobase + ISR, ISR_RXOVW); + } + } +#endif +} + +err_t rckemacif_wait(struct netif* netif, uint32_t poll) +{ + return ERR_OK; +#if 0 + rckemacif_t* rckemacif = netif->state; + struct eth_hdr *ethhdr; + struct pbuf *p = NULL; + err_t err = ERR_OK; + + LWIP_DEBUGF(NETIF_DEBUG, ("Hello from rckemacif_wait!\n")); + + if (poll) { + if (mailbox_ptr_tryfetch(&(rckemacif->mbox), (void**) &p)) + return err; + } else { + mailbox_ptr_fetch(&(rckemacif->mbox), (void**) &p); + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_ARP: + case ETHTYPE_IP: +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + /* full packet send to tcpip_thread to process */ + if ((err = mynetif[netif->num]->input(p, mynetif[netif->num])) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_poll: IP input error\n")); + pbuf_free(p); + } + break; + default: + pbuf_free(p); + break; + } + + return err; +#endif +} + +err_t rckemacif_init(struct netif* netif) +{ + rckemacif_t* rckemacif; + int num, num_emac; + int macPorts; + int i, tmp, x, y, z, core; + uint64_t tile_offset; + uint16_t write_offset = 0; + uint16_t read_offset = 0; + int mode = 0; + int subdest = 0; + int route = 0; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + // Find out who I am... + tmp = ReadConfigReg(CRB_OWN+MYTILEID); + x = (tmp>>3) & 0x0f; // bits 06:03 + y = (tmp>>7) & 0x0f; // bits 10:07 + z = (tmp ) & 0x07; // bits 02:00 + core = 12 * y + 2 * x + z; + + rckemacif = kmalloc(sizeof(rckemacif_t)); + if (!rckemacif) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: out of memory\n")); + return ERR_MEM; + } + memset(rckemacif, 0, sizeof(rckemacif_t)); + rckemacif->core = core; + + /* allocate the receive buffer */ + rckemacif->rx_buffer = mem_allocation(BUFFER_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE); + if (!(rckemacif->rx_buffer)) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: out of memory\n")); + kfree(rckemacif, sizeof(rckemacif_t)); + return ERR_MEM; + } + memset(rckemacif->rx_buffer, 0, BUFFER_SIZE); + rckemacif->rx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1; + + /* allocate the send buffers */ + rckemacif->tx_buffer = mem_allocation(BUFFER_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE); + if (!(rckemacif->tx_buffer)) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: out of memory\n")); + kfree(rckemacif->rx_buffer, BUFFER_SIZE); + kfree(rckemacif, sizeof(rckemacif_t)); + return ERR_MEM; + } + memset(rckemacif->tx_buffer, 0, BUFFER_SIZE); + rckemacif->tx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1; + + mailbox_ptr_init(&rckemacif->mbox); + netif->state = rckemacif; + + /* Depending on core location read own private data + * (offset, subdest, route) + */ + if (z == 0) { + tmp = ReadConfigReg(CRB_OWN + GLCFG0); + rckemacif->irq_address = CRB_OWN + GLCFG0; + } else { + tmp = ReadConfigReg(CRB_OWN + GLCFG1); + rckemacif->irq_address = CRB_OWN + GLCFG1; + } + tile_offset = (unsigned long long)((unsigned long long) tmp & 0x3FF) << 24; + subdest = (tmp >> 10) & 0x07; + route = (tmp >> 13) & 0xFF; + mode = (subdest << 8) + route; + + /* get fpga/sccKit port settings */ + tmp = *((volatile int*)(FPGA_BASE + 0x822C)); + macPorts = ((tmp >> 9 ) & 0xFF); + + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: eMAC0: %s eMAC1: %s eMAC2: %s eMAC3: %s\n", + (macPorts & EMAC0) != 0 ? "present" : "-", + (macPorts & EMAC1) != 0 ? "present" : "-", + (macPorts & EMAC2) != 0 ? "present" : "-", + (macPorts & EMAC3) != 0 ? "present" : "-")); + + // determine device and emac number + for(num=0; (num<4) && (mynetif[num] != NULL); num++) + ; + if (num >= 4) + return ERR_ARG; + for(i=0, num_emac=0; (i<=num) && (num_emac < 4); i++) { + while (((macPorts & (1 << num_emac)) == 0) && (num_emac < 4)) + num_emac++; + } + if (num_emac >= 4) + return ERR_ARG; + mynetif[num] = netif; + rckemacif->num_emac = num_emac; + + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: map device %d to eMAC %d\n", num, num_emac)); + + if (core == 0) { + /* Only core 0 initialize the xilinx port */ + int flow_control = 0; + int transmitter_addr = 0; + int receiver1_addr = 0; + int config_add = 0; + int add_filter_mod = 0; + + /* Disable tx and rx flow control of eMAC */ + LWIP_DEBUGF(NETIF_DEBUG, ("Disabling tx/rx flow control of eMAC%d\n", num_emac)); + flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); + + /* Set top 3 bits of the flow control configuration to zero, + * therefore disabling tx and rx flow control + */ + flow_control &= 0x7FFFFFF; + write_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0, flow_control); + + /* Sanity check */ + flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); + LWIP_DEBUGF(NETIF_DEBUG, (" CONFIG_FLOW_CONTROL_ADD set: 0x%x\n", flow_control)); + + /* Setting the tx configuration bit to enable the transmitter and + * set to full duplex mode. + */ + LWIP_DEBUGF(NETIF_DEBUG, ("Setting rx configuration of eMAC%d\n", num_emac)); + transmitter_addr = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); + + /* Now set the relevant bits and write back into the register: + * 26 (half duplex) = 0, 28 (transmit enable) = 1, 31 (reset) = 0 + */ + transmitter_addr &= ~(1 << 31); + transmitter_addr &= ~(1 << 26); + transmitter_addr |= (1 << 28); + write_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0, transmitter_addr); + + transmitter_addr = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); + LWIP_DEBUGF(NETIF_DEBUG, (" TRANSMITTER_ADDRESS set: %x\n", transmitter_addr)); + + /* Setting the rx configuration bit to enable the transmitter and + * set to full duplex mode. + */ + LWIP_DEBUGF(NETIF_DEBUG, ("Setting IP configuration of EMAC%d\n", num_emac)); + + /* Read the current config value from the register */ + receiver1_addr = read_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, core); + + /* Now set the relevant bits and write back into the register: + * 25 = 1, 26 = 0, 28 = 1, 31 = 0 + */ + /* Length/Type Error Check Disable */ + receiver1_addr |= (1 << 25); + /* Disable Half Duplex => Full Duplex */ + receiver1_addr &= ~(1 << 26); + /* Receiver enable */ + receiver1_addr |= (1 << 28); + /* Reset */ + receiver1_addr &= ~(1 << 31); + write_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, 0, receiver1_addr); + + receiver1_addr = read_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, 0); + LWIP_DEBUGF(NETIF_DEBUG, (" RECEIVER1_ADDRESS set: %x\n", receiver1_addr)); + + /* Setting the speed to eMAC to 1Gb/s */ + LWIP_DEBUGF(NETIF_DEBUG, ("Setting speed of EMAC%d to 1Gb/s\n", num_emac)); + + /* Read the current config value from register */ + config_add = read_emac(num_emac, EMAC_IPCONF+CONFIG_ADD, 0); + + /* Now set the relevant bits and write back into the register: + * 31 = 1, 30 = 0 + */ + /* MAC Speed Configuration: 00 - 10Mbps, 01 - 100Mbps, 10 - 1Gbps */ + config_add |= (1 << 31); + config_add &= ~(1 << 30); + write_emac(num_emac, EMAC_IPCONF+CONFIG_ADD, 0, config_add); + + config_add = read_emac(num_emac, EMAC_IPCONF+CONFIG_ADD, 0); + LWIP_DEBUGF(NETIF_DEBUG, (" CONFIG_ADD set: %x\n", config_add)); + + /* Read the current config addr filter mode */ + add_filter_mod = read_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0); + + /* Not set the relevant bits and write back into the register: + * 31 (promiscuous mode) = 1 not working, but thats ok! + */ + add_filter_mod |= (1 << 31); + write_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0, add_filter_mod); + + add_filter_mod = read_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0); + LWIP_DEBUGF(NETIF_DEBUG, (" ADD_FILTER_MOD set: %x\n", add_filter_mod)); + } + + sleep(3); + + /* Start address */ + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer %p (%lx phys)\n", rckemacif->rx_buffer, virt_to_phys(rckemacif->rx_buffer))); + + /**** Receiver configuration ****/ + + uint32_t utmp = virt_to_phys(rckemacif->rx_buffer); + uint32_t addr_offset = tile_offset + utmp; + addr_offset >>= 5; + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core, addr_offset); + utmp = read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer set to @%x\n", utmp)); + + /* Set buffer write offset */ + write_offset = read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, core); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer write offset at: %d\n", write_offset)); + + /* Set buffer read offset to write offset */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core, write_offset); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer read offset set to: %d\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core))); + rckemacif->rx_read_offset = write_offset; + + /* Size */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_SIZE, core, rckemacif->rx_buffer_max); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Size set to %d\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_SIZE, core))); + + /* Threshold */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core, 0x01); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Threshold set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core))); + + /* Route */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core, (core << 24) | (((y << 4) | x) << 16) | mode); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Mode set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core))); + + // determine mac address + uint32_t mac1 = *((uint32_t*)(FPGA_BASE+0x7E00)); + uint32_t mac2 = *((uint32_t*)(FPGA_BASE+0x7E04)); + uint64_t mac = (((unsigned long long)mac1) << 32) + ( unsigned long long ) mac2; + if (mac == 0x00) + mac = MAC_ADDRESS; + /* Calculate mac address of core depending on selected emac device */ + mac = mac + (1 << num_emac) * 0x100 + core; + + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: MAC address ")); + for (i=0; i<6; i++) { + mynetif[num]->hwaddr[i] = mac & 0xFF; + mac = mac >> 8; + LWIP_DEBUGF(NETIF_DEBUG, ("%02x ", mynetif[num]->hwaddr[i])); + } + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core, MAC_HI(mac)); + LWIP_DEBUGF(NETIF_DEBUG, (" MAC1 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core))); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core, MAC_LO(mac)); + LWIP_DEBUGF(NETIF_DEBUG, (" MAC2 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core))); + + /* Activate network port by setting enable bit */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core, 0x01); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Port enable set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core))); + + /**** Transfer configuration ****/ + + /* Start address */ + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer %p (%lx phys)\n", rckemacif->tx_buffer, virt_to_phys(rckemacif->tx_buffer))); + utmp = virt_to_phys(rckemacif->tx_buffer); + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core, (tmp + tile_offset) >> 5); + utmp = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer set to @%x\n", tmp)); + + /* Get buffer read offset */ + read_offset = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_READ_OFFSET, core); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer read offset at: %d\n", read_offset)); + + /* Set buffer write offset to read offset */ + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_WRITE_OFFSET, core, read_offset); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer write offset set to: %d\n", read_emac(num_emac, EMAC_TX_CONTROL+ EMAC_TX_BUFFER_WRITE_OFFSET, core))); + rckemacif->tx_write_offset = read_offset; + + /* Size */ + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_SIZE, core, rckemacif->tx_buffer_max); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Size set to %d\n", read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_SIZE, core))); + + /* Route */ + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_MODE, core, mode); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Mode set to %x\n", read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_MODE, core))); + + /* Activate network port by setting enable bit */ + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_NETWORK_PORT_ENABLE, core, 0x01); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Port enable set to %x\n", read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_NETWORK_PORT_ENABLE, core))); + + // set interrupt handler (INTR/LINT0) + irq_install_handler(125, rckemacif_handler); + + /* Enable interrupt */ + tmp = *((volatile int*) (FPGA_BASE + IRQ_MASK + core * 2 * 4)); + *((volatile int*) (FPGA_BASE + IRQ_MASK + core * 2 * 4)) = tmp & ~(1 << num_emac); + *((volatile int*) (FPGA_BASE + IRQ_CONFIG + core * 4)) = EMAC_IRQ_CONFIG; + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 1000 /* speed */); + + /* administrative details */ + netif->name[0] = 'e'; + netif->name[1] = 'n'; + netif->num = num; + /* downward functions */ + netif->output = etharp_output; + netif->linkoutput = rckemacif_output; + /* maximum transfer unit */ + netif->mtu = 1500; + /* broadcast capability */ + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + /* hardware address length */ + netif->hwaddr_len = 6; + + rckemacif->ethaddr = (struct eth_addr *)netif->hwaddr; + + return ERR_OK; +} +#endif diff --git a/drivers/net/rckemac.h b/drivers/net/rckemac.h new file mode 100644 index 00000000..b8a8a5ae --- /dev/null +++ b/drivers/net/rckemac.h @@ -0,0 +1,61 @@ +/* + * Copyright 2011 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. + */ + +#ifndef __HAVE_RCKEMAC_H__ +#define __HAVE_RCKEMAC_H__ + +#include +#include + +#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) + +/* + * Helper struct to hold private data used to operate your ethernet interface. + */ +typedef struct rckemacif { + struct eth_addr *ethaddr; + /* Add whatever per-interface state that is needed here. */ + uint8_t* tx_buffer; + uint8_t* rx_buffer; + uint32_t rx_buffer_max; + uint32_t rx_read_offset; + uint32_t tx_buffer_max; + uint32_t tx_write_offset; + void* irq_address; + uint32_t core; + uint32_t num_emac; + mailbox_ptr_t mbox; +} rckemacif_t; + +/* + * Wait for incoming messages. + * + * poll = 0 : wait blocks until a message is received + * poll != 0: non-blocking wait + */ +err_t rckemacif_wait(struct netif* netif, uint32_t poll); + +/* + * Initialize the eMAC network driver + */ +err_t rckemacif_init(struct netif* netif); + +#endif + +#endif diff --git a/kernel/Makefile b/kernel/Makefile index fdddee71..8c3b4c8c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c +C_source := main.c tasks.c syscall.c tests.c echo.c init.c #ping.c init.c MODULE := kernel include $(TOPDIR)/Makefile.inc diff --git a/kernel/init.c b/kernel/init.c index 2ba3b81f..8a8f3d37 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -37,6 +37,11 @@ #include #endif #include +#include +#ifdef CONFIG_ROCKCREEK +#include +#include +#endif void echo_init(void); void ping_init(void); @@ -50,7 +55,7 @@ int lowlevel_init(void) return 0; } -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) +#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) static tid_t netid; int STDCALL network_task(void* arg) @@ -62,10 +67,15 @@ int STDCALL network_task(void* arg) kputs("Network task is started\n"); +#ifdef CONFIG_ROCKCREEK /* Set network address variables */ - //IP4_ADDR(&gw, 192,168,1,254); - //IP4_ADDR(&ipaddr, 192,168,1,100); - //IP4_ADDR(&netmask, 255,255,255,0); + IP4_ADDR(&gw, 192,168,4,254); + IP4_ADDR(&ipaddr, 192,168,4,RCCE_ue()+1); + IP4_ADDR(&netmask, 255,255,255,0); + + /* Bring up the network interface */ + if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, ethernet_input)) { +#else /* Clear network address because we use DHCP to get an ip address */ IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&ipaddr, 0,0,0,0); @@ -73,6 +83,7 @@ int STDCALL network_task(void* arg) /* Bring up the network interface */ if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, ethernet_input)) { +#endif kputs("Unable to add network interface\n"); return -ENXIO; } @@ -84,6 +95,7 @@ int STDCALL network_task(void* arg) return -EIO; } +#ifndef CONFIG_ROCKCREEK kprintf("Starting DHCPCD...\n"); dhcp_start(&netif); @@ -92,17 +104,24 @@ int STDCALL network_task(void* arg) rtl8139if_wait(&netif, 1); udelay(500000); } +#endif // start echo and ping server echo_init(); - ping_init(); + //ping_init(); while(!done) { +#ifdef CONFIG_PCI rtl8139if_wait(&netif, 0); +#elif defined(CONFIG_ROCKCREEK) + rckemacif_wait(&netif, 0); +#endif } +#ifndef CONFIG_ROCKCREEK dhcp_release(&netif); dhcp_stop(&netif); +#endif return 0; } @@ -122,7 +141,7 @@ int network_init(void) lwip_init(); #endif -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) +#if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) return create_kernel_task(&netid, network_task, NULL); #else return 0; diff --git a/kernel/tests.c b/kernel/tests.c index 8427ca56..78b6f9df 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -139,7 +139,7 @@ int test_init(void) #ifdef CONFIG_LWIP // use ping to test LWIP - ping_send_now(); + //ping_send_now(); #endif return 0; diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index 7279f5c7..b779464f 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -13,7 +13,7 @@ * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 * Mainly for compatibility to old versions. */ -#define NO_SYS_NO_TIMERS 0 +#define NO_SYS_NO_TIMERS 1 /** * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) @@ -53,7 +53,7 @@ /** * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c */ -#define LWIP_HAVE_LOOPIF 1 +#define LWIP_HAVE_LOOPIF 0 /** * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP From 771ed2190eef83f4f27762fa85242074cec4a111 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Sun, 5 Jun 2011 13:08:44 +0200 Subject: [PATCH 16/59] a --- kernel/mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 016e22aa..8b7a8b78 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -41,7 +41,7 @@ int mailbox_test_init(void) { char* argv[] = {"/bin/mailbox", NULL}; kprintf( "### Hello from mailbox_test_init\n" ); - create_user_task(NULL, "/bin/mailbox", argv); + create_kernel_task(NULL, mail_ping, argv); return 0; } From ddc72ef51e083223ec5ff2135d58a018c311f5ea Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Sun, 5 Jun 2011 05:46:39 -0700 Subject: [PATCH 17/59] add some printfs for debugging purpose --- arch/x86/scc/icc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index d50bcf3b..96ea623d 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -235,13 +235,13 @@ int icc_mail_ping( void ) uint32_t flags; int remote_rank = (my_ue+1)%2; - kprintf( "### Hello from icc_mail_ping\n" ); + kprintf( "#### Hello from icc_mail_ping\n" ); // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); // send mail iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); - + kprintf( "### Message sent ...\n" ); // wait for mail from remote rank iRCCE_MAIL_HEADER* mail; From 7ecdc87d89c7321d78df7ed03f97c0d0712ee733 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 5 Jun 2011 21:39:57 +0200 Subject: [PATCH 18/59] integration of MetalSVM features into LwIP - setting LwIP macro NO_SYS to 0 - this approach based on Carl-Benedikt Krueger's LwIP branch "krueger" --- lwip/src/arch/sys_arch.c | 216 ++++++++++++++++++++++++++++++- lwip/src/include/arch/sys_arch.h | 42 +++--- lwip/src/include/lwipopts.h | 30 ++++- 3 files changed, 262 insertions(+), 26 deletions(-) diff --git a/lwip/src/arch/sys_arch.c b/lwip/src/arch/sys_arch.c index 185cc282..ca3b15d4 100644 --- a/lwip/src/arch/sys_arch.c +++ b/lwip/src/arch/sys_arch.c @@ -24,9 +24,13 @@ #include "lwip/opt.h" #include "lwip/stats.h" -void sys_init(void) -{ -} +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif /** Returns the current time in milliseconds, * may be the same as sys_jiffies or at least based on it. */ @@ -41,3 +45,209 @@ sys_jiffies(void) { return (get_clock_tick() / TIMER_FREQ) * 1000; } + +#if !NO_SYS + +/* sys_init(): init needed system resources + * Note: At the moment there are none + */ +void +sys_init(void) +{ +} + +/** + * Sleep for some ms. Timeouts are NOT processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void +sys_msleep(u32_t ms) +{ + if (ms > 0) { + sys_sem_t delaysem; + err_t err = sys_sem_new(&delaysem, 0); + if (err == ERR_OK) { + sys_arch_sem_wait(&delaysem, ms); + sys_sem_free(&delaysem); + } + } +} + +/* sys_thread_new(): Spawns a new thread with given attributes as supportet + * Note: In MetalSVM this is realized as kernel tasks + */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) +{ + tid_t tmp; + create_kernel_task(&tmp,thread,arg); + return tmp; +} + +/* sys_sem_free(): destroy's given semaphore + * and releases system resources. + * This semaphore also gets invalid. + */ +void sys_sem_free(sys_sem_t* sem) +{ + sem->valid = FALSE; + sem_destroy(&sem->sem); +} + +/* sys_sem_valid(): returns if semaphore is valid + * at the moment + */ +int sys_sem_valid(sys_sem_t* sem) +{ + return sem->valid; +} + +/* sys_sem_new(): creates a new semaphre with given count. + * This semaphore becomes valid + */ +err_t sys_sem_new(sys_sem_t* sem,u8_t count) +{ + sem->valid = TRUE; + return sem_init(&sem->sem,count); +} + +/* sys_sem_set_invalid(): this semapohore becomes invalid + * Note: this does not mean it is destroyed + */ +void sys_sem_set_invalid(sys_sem_t * sem) +{ + sem->valid = FALSE; +} + +/* sys_sem_signal(): this semaphore is signaled + * + */ +void sys_sem_signal(sys_sem_t* sem) +{ + sem_post(&sem->sem); +} + +/* sys_arch_sem_wait): wait for the given semaphore for + * a given timeout + * Note: timeout = 0 means wait forever + */ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ + int err; + if (!timeout) + return sem_wait(&sem->sem); + while (timeout) + { + err = sem_trywait(&sem->sem); + if (err != -1) + return err; + timeout--; + } + return SYS_ARCH_TIMEOUT; +} + +/* sys_mbox_valid() : returns if the given mailbox + * is valid + */ +int sys_mbox_valid(sys_mbox_t * mbox) +{ + return mbox->valid; +} + +/* sys_arch_mbox_fetch(): wait for the given mailbox for a specified + * amount of time. + * Note: timeout = 0 means wait forever + */ +u32_t sys_arch_mbox_fetch(sys_mbox_t * mbox, void **msg, u32_t timeout) +{ + if (!timeout) + return mailbox_ptr_fetch(&mbox->mailbox,msg); + + while(timeout) + { + if (!mailbox_ptr_tryfetch(&mbox->mailbox,msg)) + return 0; + timeout--; + } + + return SYS_ARCH_TIMEOUT; +} + +/* sys_mbox_free() : free the given mailbox, release the system resources + * and set mbox to invalid + */ +void sys_mbox_free(sys_mbox_t* mbox) +{ + mbox->valid = FALSE; + mailbox_ptr_destroy(&mbox->mailbox); +} + +/* sys_arch_mbox_tryfetch(): poll for new data in mailbox + * + */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t* mbox, void** msg) +{ + return mailbox_ptr_tryfetch(&mbox->mailbox,msg); +} + +/* sys_mbox_new(): create a new mailbox with a minimum size of "size" + * + */ +err_t sys_mbox_new(sys_mbox_t* mbox,int size) +{ + mbox->valid = TRUE; + return mailbox_ptr_init(&mbox->mailbox); +} + +/* sys_mbox_set_invalid(): set the given mailbox to invald + * Note: system resources are NOT freed + */ +void sys_mbox_set_invalid(sys_mbox_t* mbox) +{ + mbox->valid = FALSE; +} + +/* sys_mbox_trypost(): try to post data to the mailbox + * Note: There is at the moment no try post implemented + * so we use the normal post instead + */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + return mailbox_ptr_post(&mbox->mailbox,msg); +} + +/* sys_mbox_post(): post new data to the mailbox + * + */ +void sys_mbox_post(sys_mbox_t* mbox,void* msg) +{ + mailbox_ptr_post(&mbox->mailbox,msg); +} + +/* sys_mutex_lock(): lock the given mutex + * Note: There is no specific mutex in MetalSVM + * so we use a semaphore with 1 element + */ +void sys_mutex_lock(sys_mutex_t* mutex) +{ + sem_wait(mutex); +} + +/* sys_mutex_unlock(): unlock the given mutex + * + */ +void sys_mutex_unlock(sys_mutex_t* mutex) +{ + sem_post(mutex); +} + +/* sys_mutex_new(): create a new mutex + * + */ +err_t sys_mutex_new(sys_mutex_t * mutex) +{ + sem_init(mutex,1); + return 0; +} + +#endif /* !NO_SYS */ diff --git a/lwip/src/include/arch/sys_arch.h b/lwip/src/include/arch/sys_arch.h index 6074d05a..d55cde38 100644 --- a/lwip/src/include/arch/sys_arch.h +++ b/lwip/src/include/arch/sys_arch.h @@ -1,20 +1,22 @@ -/* - * Copyright (c) 2010 Stefan Lankes, Chair for Operating Systems, RWTH Aachen University, Germany - * All rights reserved - */ -#ifndef __ARCH_SYS_ARCH_H__ -#define __ARCH_SYS_ARCH_H__ - -#include -#include -#include - -#define SYS_MBOX_NULL NULL -#define SYS_SEM_NULL NULL - -typedef sem_t* sys_sem_t; -typedef mailbox_ptr_t* sys_mbox_t; -typedef tid_t* sys_thread_t; - -#endif /* __ARCH_SYS_ARCH_H__ */ - +#ifndef __ARCH_SYS_ARCH_H__ +#define __ARCH_SYS_ARCH_H__ + +#include +#include + +typedef sem_t sys_mutex_t; + +typedef struct +{ + sem_t sem; + int valid; +} sys_sem_t; + +typedef struct +{ mailbox_ptr_t mailbox; + int valid; +} sys_mbox_t; + +typedef tid_t* sys_thread_t; + +#endif /* __ARCH_SYS_ARCH_H__ */ diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index 7279f5c7..f96a41f1 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -7,7 +7,7 @@ * NO_SYS==1: Provides VERY minimal functionality. Otherwise, * use lwIP facilities. */ -#define NO_SYS 1 +#define NO_SYS 0 /** * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 @@ -40,6 +40,30 @@ */ #define LWIP_TCP 1 +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ 0 +#endif + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF 2048 +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + + /** * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) */ @@ -53,13 +77,13 @@ /** * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c */ -#define LWIP_HAVE_LOOPIF 1 +#define LWIP_HAVE_LOOPIF 0 /** * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP * address equal to the netif IP address, looping them back up the stack. */ -#define LWIP_NETIF_LOOPBACK 1 +#define LWIP_NETIF_LOOPBACK 0 /** * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. From 521c3e1bc9fb9579def74c7d1ac9e2392a6d8cd8 Mon Sep 17 00:00:00 2001 From: Generic account for RWTHAachen Students Date: Mon, 6 Jun 2011 06:45:17 -0700 Subject: [PATCH 19/59] free allocated memory for iRCCE_MAIL_HEADER now; call iRCCE_finalize() in icc_halt() --- arch/x86/include/asm/iRCCE.h | 1 + arch/x86/scc/iRCCE_admin.c | 19 +++++++++++++++++++ arch/x86/scc/iRCCE_mailbox.c | 3 +-- arch/x86/scc/icc.c | 2 ++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/iRCCE.h b/arch/x86/include/asm/iRCCE.h index 5c0edfc3..7c071d5b 100644 --- a/arch/x86/include/asm/iRCCE.h +++ b/arch/x86/include/asm/iRCCE.h @@ -134,6 +134,7 @@ typedef struct _iRCCE_MAIL_TRASH_BIN { // // Initialize/Finalize functions: int iRCCE_init(void); +int iRCCE_finalize(void); // // Non-blocking send/recv functions: int iRCCE_isend(char *, ssize_t, int, iRCCE_SEND_REQUEST *); diff --git a/arch/x86/scc/iRCCE_admin.c b/arch/x86/scc/iRCCE_admin.c index ba465765..2a28f09e 100644 --- a/arch/x86/scc/iRCCE_admin.c +++ b/arch/x86/scc/iRCCE_admin.c @@ -109,4 +109,23 @@ int iRCCE_init(void) { return (iRCCE_SUCCESS); } +//-------------------------------------------------------------------------------------- +// FUNCTION: iRCCE_finalize +//-------------------------------------------------------------------------------------- +// finalize the library +//-------------------------------------------------------------------------------------- +int iRCCE_finalize(void) { + // empty iRCCE_mail_garbage + iRCCE_MAIL_HEADER* run; + iRCCE_MAIL_HEADER* erase_header; + + for( run = iRCCE_mail_garbage.first; run != NULL; ) { + erase_header = run; + run = run->next; + kfree( erase_header, sizeof(iRCCE_MAIL_HEADER) ); + } + + iRCCE_mail_garbage.first = iRCCE_mail_garbage.last = NULL; + return iRCCE_SUCCESS; +} #endif diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index 4c235da9..4680a34d 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -119,8 +119,7 @@ static int iRCCE_mail_fetch( // routine to check for new mail in mailboxes //------------------------------------------------------------------------------ static int iRCCE_mailbox_check() { - int i, j; - int tmp; + int i; for( i=0; i Date: Mon, 6 Jun 2011 08:32:59 -0700 Subject: [PATCH 20/59] little memory optimization in fetch-function --- arch/x86/scc/iRCCE_mailbox.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index 4680a34d..8b14480a 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -33,6 +33,10 @@ #ifdef CONFIG_ROCKCREEK #include +// forward declaration +static int iRCCE_mailbox_close_one(int rank, int check); + + //------------------------------------------------------------------------------ // FUNCTION: iRCCE_mailbox_print_header //------------------------------------------------------------------------------ @@ -90,8 +94,8 @@ static int iRCCE_mail_fetch( // check if received a last-mail if( header->tag == iRCCE_LAST_MAIL ) { iRCCE_last_mail[rank] = 1; - iRCCE_mailbox_close( rank ); // we can close respective mailbox - kfree( header, sizeof(iRCCE_MAIL_HEADER) ); + iRCCE_mailbox_close_one( rank, 0 ); // we can close respective mailbox + iRCCE_mail_release( &header ); } else { // check mail priority @@ -316,12 +320,12 @@ int iRCCE_mailbox_flush(void) { //------------------------------------------------------------------------------ // routine to close one mailbox //------------------------------------------------------------------------------ -static int iRCCE_mailbox_close_one(int rank) { +static int iRCCE_mailbox_close_one(int rank, int check) { RCCE_acquire_lock( RCCE_IAM ); // check if it contains new mail RC_cache_invalidate(); - if( iRCCE_mailbox_recv[rank]->sent ) { + if( check && iRCCE_mailbox_recv[rank]->sent ) { iRCCE_mail_fetch(rank); } @@ -351,11 +355,11 @@ int iRCCE_mailbox_close(int rank) { if( rank == iRCCE_MAILBOX_ALL ) { int i; for( i=0; i Date: Mon, 6 Jun 2011 21:45:10 +0200 Subject: [PATCH 21/59] add the support of the Socket API --- lwip/src/api/Makefile | 2 +- lwip/src/include/arch/sys_arch.h | 3 +++ lwip/src/include/lwipopts.h | 45 +++++++------------------------- 3 files changed, 14 insertions(+), 36 deletions(-) diff --git a/lwip/src/api/Makefile b/lwip/src/api/Makefile index bb5170be..01a9faf4 100644 --- a/lwip/src/api/Makefile +++ b/lwip/src/api/Makefile @@ -1,4 +1,4 @@ -C_source := err.c +C_source := api_lib.c api_msg.c err.c netbuf.c netifapi.c sockets.c tcpip.c MODULE := lwip_src_api include $(TOPDIR)/Makefile.inc diff --git a/lwip/src/include/arch/sys_arch.h b/lwip/src/include/arch/sys_arch.h index d55cde38..fde4fbc2 100644 --- a/lwip/src/include/arch/sys_arch.h +++ b/lwip/src/include/arch/sys_arch.h @@ -3,6 +3,9 @@ #include #include +#include + +#define EWOULDBLOCK EAGAIN /* Operation would block */ typedef sem_t sys_mutex_t; diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index f96a41f1..1565c8af 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -9,21 +9,15 @@ */ #define NO_SYS 0 -/** - * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 - * Mainly for compatibility to old versions. - */ -#define NO_SYS_NO_TIMERS 0 - /** * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) */ -#define LWIP_SOCKET 0 +#define LWIP_SOCKET 1 /** * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) */ -#define LWIP_NETCONN 0 +#define LWIP_NETCONN 1 /** * LWIP_DHCP==1: Enable DHCP module. @@ -40,29 +34,10 @@ */ #define LWIP_TCP 1 -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#ifndef TCP_QUEUE_OOSEQ -#define TCP_QUEUE_OOSEQ 0 -#endif - /** * TCP_SND_BUF: TCP sender buffer space (bytes). */ -#ifndef TCP_SND_BUF #define TCP_SND_BUF 2048 -#endif - -/** - * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least - * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. - */ -#ifndef TCP_SND_QUEUELEN -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) -#endif - /** * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) @@ -74,22 +49,22 @@ */ #define LWIP_MULTICAST_PING 1 +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + */ +#define MEMP_NUM_SYS_TIMEOUT 7 + /** * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c */ -#define LWIP_HAVE_LOOPIF 0 +#define LWIP_HAVE_LOOPIF 1 /** * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP * address equal to the netif IP address, looping them back up the stack. */ -#define LWIP_NETIF_LOOPBACK 0 - -/** - * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. - * (requires NO_SYS==0) - */ -#define MEMP_NUM_SYS_TIMEOUT 7 +#define LWIP_NETIF_LOOPBACK 1 /** * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from From 413af27f9bb0695217ba9ad4e27b42bd12982a37 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Mon, 6 Jun 2011 23:29:00 -0700 Subject: [PATCH 22/59] add counter for mail_ping latency --- arch/x86/scc/icc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 96ea623d..bf12483d 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -238,16 +238,22 @@ int icc_mail_ping( void ) kprintf( "#### Hello from icc_mail_ping\n" ); // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); - + + // start timer + uint64_t timer = rdtsc(); + // send mail iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); - kprintf( "### Message sent ...\n" ); // wait for mail from remote rank iRCCE_MAIL_HEADER* mail; do { iRCCE_mail_recv( &mail ); } while( !mail ); + + timer = timer - rdtsc(); + + kprintf( "Received mail in %d ticks!\n", timer ); // show content iRCCE_mailbox_print_header( mail ); From 570b559b5e188ac9137f18adec37ccbb11de5572 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Tue, 7 Jun 2011 12:38:35 +0200 Subject: [PATCH 23/59] add mail_ping interrupt test-scenario --- arch/x86/scc/icc.c | 52 ++++++++++++++++++++++++++++++++-------- include/metalsvm/tasks.h | 3 ++- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 40a07199..cd2c3b50 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -235,30 +235,46 @@ int icc_ping(int ue) int icc_mail_ping( void ) { uint32_t flags; + uint64_t timer; int remote_rank = (my_ue+1)%2; - - kprintf( "#### Hello from icc_mail_ping\n" ); + + if( !my_rank ) { + return 0; + } + // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); - // send mail - iRCCE_mail_send( 0, my_ue, 0, NULL, remote_rank ); - kprintf( "### Message sent ...\n" ); + // start timer + timer = rdtsc(); - // wait for mail from remote rank + iRCCE_mail_send( 0, 1, 0, NULL, remote_rank ); + kprintf( "Sent pingrequest to %d ...\n", remote_rank ); + + // wait for response iRCCE_MAIL_HEADER* mail; do { iRCCE_mail_recv( &mail ); } while( !mail ); - // show content - iRCCE_mailbox_print_header( mail ); - + // stop timer + timer = rdtsc() - timer; + + if( mail->tag == 2 ) { + kprintf( "Response received in %d ticks!\n", timer ); + } + else { + krpintf( "Response didn't arrive!\n" ); + } + + + irq_nested_enable(flags); - + return 0; } + static void interpret_header(icc_header_t* header, int recv_ue) { //kprintf("Got ICC message %d from %d\n", header->type, recv_ue); @@ -325,4 +341,20 @@ void icc_check(void) iRCCE_isend_push(); } +void icc_mail_check(void) +{ + iRCCE_MAIL_HEADER* header; + int res; + + // empty mailbox and interpret headers + do { + res = iRCCE_mail_recv( &header ); + if( header->tag == 1 ) { + iRCCE_mail_send( 0, 2, 0, NULL, header->source ); + } + + iRCCE_mail_release( &header ); + } while( res == iRCCE_SUCCESS ); +} + #endif diff --git a/include/metalsvm/tasks.h b/include/metalsvm/tasks.h index 5329fc61..ec6ed665 100644 --- a/include/metalsvm/tasks.h +++ b/include/metalsvm/tasks.h @@ -143,7 +143,8 @@ static inline void check_workqueues(void) uint32_t flags = irq_nested_disable(); #ifdef CONFIG_ROCKCREEK - icc_check(); + //icc_check(); + icc_mail_check(); #endif irq_nested_enable(flags); From 262e9f085aa4b4c0a3b2bd69d91f609f30f32e70 Mon Sep 17 00:00:00 2001 From: Generic account for RWTHAachen Students Date: Tue, 7 Jun 2011 03:53:37 -0700 Subject: [PATCH 24/59] bug fix --- arch/x86/include/asm/icc.h | 1 + arch/x86/scc/icc.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/icc.h b/arch/x86/include/asm/icc.h index f08bd07c..b02be40e 100644 --- a/arch/x86/include/asm/icc.h +++ b/arch/x86/include/asm/icc.h @@ -53,6 +53,7 @@ typedef struct { int icc_init(void); int icc_ping(int ue); void icc_check(void); +void icc_mail_check(void); int icc_halt(void); int icc_mail_ping(void); diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 02c8b80a..9c94a600 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -238,7 +238,7 @@ int icc_mail_ping( void ) uint64_t timer; int remote_rank = (my_ue+1)%2; - if( !my_rank ) { + if( !my_ue ) { return 0; } @@ -268,7 +268,7 @@ int icc_mail_ping( void ) kprintf( "Response received in %d ticks!\n", timer ); } else { - krpintf( "Response didn't arrive!\n" ); + kprintf( "Response didn't arrive!\n" ); } From bba87c8e2726a25da41ea46504a428f268057f75 Mon Sep 17 00:00:00 2001 From: Generic account for RWTHAachen Students Date: Tue, 7 Jun 2011 05:53:16 -0700 Subject: [PATCH 25/59] bug fix in mail_ping --- arch/x86/kernel/irq.c | 2 +- arch/x86/scc/icc.c | 17 +++++++++++------ include/metalsvm/tasks.h | 2 +- kernel/mailbox.c | 1 - kernel/main.c | 3 ++- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3c4b621f..9e8ca5e8 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -235,7 +235,7 @@ void irq_handler(struct state *s) void (*handler) (struct state * s); // at first, we check our work queues - check_workqueues(); + if( s->int_no == 124 ) check_workqueues(); /* * Find out if we have a custom handler to run for this diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 9c94a600..d0ff8bb2 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -238,7 +238,7 @@ int icc_mail_ping( void ) uint64_t timer; int remote_rank = (my_ue+1)%2; - if( !my_ue ) { + if( my_ue ) { return 0; } @@ -251,15 +251,16 @@ int icc_mail_ping( void ) iRCCE_mail_send( 0, 1, 0, NULL, remote_rank ); kprintf( "Sent pingrequest to %d ...\n", remote_rank ); + + // wake up receiver + icc_send_irq( remote_rank ); + // wait for response iRCCE_MAIL_HEADER* mail; do { iRCCE_mail_recv( &mail ); } while( !mail ); - timer = timer - rdtsc(); - - kprintf( "Received mail in %d ticks!\n", timer ); // stop timer timer = rdtsc() - timer; @@ -347,16 +348,20 @@ void icc_check(void) void icc_mail_check(void) { + if( !my_ue ) return ; + iRCCE_MAIL_HEADER* header; int res; - + + kprintf( "Hello from icc_mail_check() \n" ); // empty mailbox and interpret headers do { res = iRCCE_mail_recv( &header ); if( header->tag == 1 ) { + kprintf( "Received mail_ping request ...\n" ); iRCCE_mail_send( 0, 2, 0, NULL, header->source ); } - + iRCCE_mail_release( &header ); } while( res == iRCCE_SUCCESS ); } diff --git a/include/metalsvm/tasks.h b/include/metalsvm/tasks.h index ec6ed665..b8822dfa 100644 --- a/include/metalsvm/tasks.h +++ b/include/metalsvm/tasks.h @@ -143,7 +143,7 @@ static inline void check_workqueues(void) uint32_t flags = irq_nested_disable(); #ifdef CONFIG_ROCKCREEK - //icc_check(); +// icc_check(); icc_mail_check(); #endif diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 8b7a8b78..e20e9e36 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -40,7 +40,6 @@ int STDCALL mail_ping(void* arg) { int mailbox_test_init(void) { char* argv[] = {"/bin/mailbox", NULL}; - kprintf( "### Hello from mailbox_test_init\n" ); create_kernel_task(NULL, mail_ping, argv); return 0; diff --git a/kernel/main.c b/kernel/main.c index f3b7d36f..50894054 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -114,13 +114,14 @@ int main(void) sleep(5); list_root(); - //test_init(); +// test_init(); kprintf( "calling mailbox test ... \n" ); mailbox_test_init(); kprintf( "mailbox test succeded!\n" ); per_core(current_task)->status = TASK_IDLE; reschedule(); + while(1) { #ifdef CONFIG_ROCKCREEK icc_halt(); From f1aa9fa24c869e169578a0effa21244bb6a8e46d Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Wed, 8 Jun 2011 04:59:23 -0700 Subject: [PATCH 26/59] little mail test --- arch/x86/scc/icc.c | 2 +- kernel/main.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 7d9f4603..bf4c5180 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -253,7 +253,7 @@ int icc_mail_ping( void ) iRCCE_mail_recv( &mail ); } while( !mail ); - timer = timer - rdtsc(); + timer = rdtsc() - timer; kprintf( "Received mail in %d ticks!\n", timer ); diff --git a/kernel/main.c b/kernel/main.c index f3b7d36f..9519dafc 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -115,9 +115,7 @@ int main(void) sleep(5); list_root(); //test_init(); - kprintf( "calling mailbox test ... \n" ); mailbox_test_init(); - kprintf( "mailbox test succeded!\n" ); per_core(current_task)->status = TASK_IDLE; reschedule(); From 0d5eb148929b8e4ef6f945ce81f74354d36ab505 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Wed, 8 Jun 2011 05:07:22 -0700 Subject: [PATCH 27/59] fix in icc_mail_check --- arch/x86/scc/icc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 49cc0734..1c3e7f05 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -242,7 +242,7 @@ int icc_mail_ping( void ) return 0; } - // iRCCE is not thread save => disable interrupts + // disable interrupts flags = irq_nested_disable(); // start timer @@ -353,6 +353,7 @@ void icc_mail_check(void) int res; kprintf( "Hello from icc_mail_check() \n" ); + // empty mailbox and interpret headers do { res = iRCCE_mail_recv( &header ); From 46b86a6746554ffefbbacd40dc0d9c7fa74398b3 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 8 Jun 2011 06:03:57 -0700 Subject: [PATCH 28/59] remove typo --- drivers/net/rckemac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/rckemac.c b/drivers/net/rckemac.c index 319ac04b..8e996dc6 100644 --- a/drivers/net/rckemac.c +++ b/drivers/net/rckemac.c @@ -560,7 +560,7 @@ err_t rckemacif_init(struct netif* netif) LWIP_DEBUGF(NETIF_DEBUG, ("Setting IP configuration of EMAC%d\n", num_emac)); /* Read the current config value from the register */ - receiver1_addr = read_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, core); + receiver1_addr = read_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, 0); /* Now set the relevant bits and write back into the register: * 25 = 1, 26 = 0, 28 = 1, 31 = 0 From fbd30d8f5a98de1dd8248fc6b82814230bbc7419 Mon Sep 17 00:00:00 2001 From: Generic account for RWTHAachen Students Date: Wed, 8 Jun 2011 09:23:05 -0700 Subject: [PATCH 29/59] testing mail_check --- arch/x86/kernel/irq.c | 5 ++++- arch/x86/scc/iRCCE_mailbox.c | 2 -- arch/x86/scc/icc.c | 14 +++++++++----- kernel/main.c | 3 +-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 9e8ca5e8..017491fb 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -235,7 +235,10 @@ void irq_handler(struct state *s) void (*handler) (struct state * s); // at first, we check our work queues - if( s->int_no == 124 ) check_workqueues(); + if( s->int_no == 124 ) { + kprintf( "Got remote interrupt!\n" ); + check_workqueues(); + } /* * Find out if we have a custom handler to run for this diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index 8b14480a..901799c2 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -169,12 +169,10 @@ int iRCCE_mail_recv( iRCCE_mailbox_recv_queue[i]->next; help_header->next = NULL; - *header = help_header; return iRCCE_SUCCESS; } } - // no mail queued *header = NULL; return iRCCE_MAILBOX_EMPTY; diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 1c3e7f05..16e7cc73 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -234,6 +234,8 @@ int icc_ping(int ue) int icc_mail_ping( void ) { + kprintf( "Hello from mail_ping ... \n" ); + uint32_t flags; uint64_t timer; int remote_rank = (my_ue+1)%2; @@ -249,7 +251,7 @@ int icc_mail_ping( void ) timer = rdtsc(); iRCCE_mail_send( 0, 1, 0, NULL, remote_rank ); - kprintf( "Sent pingrequest to %d ...\n", remote_rank ); +// kprintf( "Sent pingrequest to %d ...\n", remote_rank ); // wake up receiver @@ -347,10 +349,10 @@ void icc_check(void) void icc_mail_check(void) { - if( !my_ue ) return ; - iRCCE_MAIL_HEADER* header; - int res; + int res, count = 0; + +// if( !my_ue ) return; kprintf( "Hello from icc_mail_check() \n" ); @@ -361,9 +363,11 @@ void icc_mail_check(void) kprintf( "Received mail_ping request ...\n" ); iRCCE_mail_send( 0, 2, 0, NULL, header->source ); } - + count++; iRCCE_mail_release( &header ); } while( res == iRCCE_SUCCESS ); + + kprintf( "received %d headers!\n", count ); } #endif diff --git a/kernel/main.c b/kernel/main.c index 4238ea72..f2fcf076 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -86,7 +86,6 @@ int main(void) kprintf("This is MetalSVM %s Build %u, %u\n", METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME); popbg(); - system_init(); irq_init(); timer_init(); @@ -103,7 +102,6 @@ int main(void) irq_enable(); kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end); - system_calibration(); network_init(); @@ -115,6 +113,7 @@ int main(void) sleep(5); list_root(); // test_init(); + kprintf( "starting mailbox ...\n " ); mailbox_test_init(); per_core(current_task)->status = TASK_IDLE; reschedule(); From 393808e198a2f6bf32f0af235f13f76e2c08a894 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 9 Jun 2011 08:18:12 +0200 Subject: [PATCH 30/59] fix bug in the initializtion of the BSS section - DO NOT LONGER USE the compiler flag "-fno-zero-initialized-in-bss" --- Makefile.example | 4 ++-- arch/x86/kernel/entry.asm | 2 +- arch/x86/kernel/gdt.c | 4 ++-- arch/x86/kernel/multiboot.c | 2 +- kernel/init.c | 12 ++++++++++++ link.ld | 5 ++--- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Makefile.example b/Makefile.example index 71ff1725..3e87db1e 100644 --- a/Makefile.example +++ b/Makefile.example @@ -26,9 +26,9 @@ MAKE = make NASMFLAGS = -felf32 -g INCLUDE = -I$(TOPDIR)/include -I$(TOPDIR)/arch/$(ARCH)/include -I$(TOPDIR)/lwip/src/include -I$(TOPDIR)/lwip/src/include/ipv4 -I$(TOPDIR)/drivers # Compiler options for final code -CFLAGS = -g -m32 -march=i586 -Wall -O2 -fno-zero-initialized-in-bss -fno-builtin -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc $(INCLUDE) -fno-stack-protector +CFLAGS = -g -m32 -march=i586 -Wall -O2 -fno-builtin -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc $(INCLUDE) -fno-stack-protector # Compiler options for debuuging -#CFLAGS = -g -O -m32 -march=i586 -Wall -fno-zero-initialized-in-bss -fno-builtin -DWITH_FRAME_POINTER -nostdinc $(INCLUDE) -fno-stack-protector +#CFLAGS = -g -O -m32 -march=i586 -Wall -fno-builtin -DWITH_FRAME_POINTER -nostdinc $(INCLUDE) -fno-stack-protector ARFLAGS = rsv RM = rm -rf LDFLAGS = -T link.ld -z max-page-size=4096 --defsym __BUILD_DATE=$(shell date +'%Y%m%d') --defsym __BUILD_TIME=$(shell date +'%H%M%S') diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index 5610c6b8..6fb00652 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -73,7 +73,7 @@ stublet: ; clears the current pgd entry xor eax, eax mov cr3, eax -; disable SSE support (TODO) +; at this stage, we disable the SSE support mov eax, cr4 and eax, 0xfffbf9ff mov cr4, eax diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 5be409c6..53a83b95 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -28,10 +28,10 @@ gdt_ptr_t gp; static tss_t task_state_segments[MAX_TASKS] __attribute__ ((aligned (PAGE_SIZE))); -static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE))); +static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE) section (".data"))); // currently, our kernel has full access to the ioports static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}}; -unsigned char* default_stack_pointer = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t); +unsigned char* default_stack_pointer __attribute__ ((section (".data"))) = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t); /* * This is in start.asm. We use this to properly reload diff --git a/arch/x86/kernel/multiboot.c b/arch/x86/kernel/multiboot.c index d57b5f96..ec124479 100644 --- a/arch/x86/kernel/multiboot.c +++ b/arch/x86/kernel/multiboot.c @@ -37,7 +37,7 @@ */ /** Global multiboot information structure pointer */ -multiboot_info_t* mb_info = NULL; +multiboot_info_t* mb_info __attribute__ ((section (".data"))) = NULL; #endif /** @brief initialization procedure for Multiboot information structure diff --git a/kernel/init.c b/kernel/init.c index 2ba3b81f..c4dea9b7 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -43,10 +43,22 @@ void ping_init(void); static volatile int done = 0; +/* + * Note that linker symbols are not variables, they have no memory allocated for + * maintaining a value, rather their address is their value. + */ +extern const void bss_start; +extern const void bss_end; + int lowlevel_init(void) { + // initialize .bss section + memset((void*)&bss_start, 0x00, ((size_t) &bss_end - (size_t) &bss_start)); + koutput_init(); + //kprintf("Now, the BSS section (0x%x - 0x%x) is initialized.\n", (size_t) &bss_start, (size_t) &bss_end); + return 0; } diff --git a/link.ld b/link.ld index bbb2a9d4..ad03b8f5 100644 --- a/link.ld +++ b/link.ld @@ -13,9 +13,6 @@ SECTIONS .text ALIGN(4096) : AT(ADDR(.text)) { *(.text) } - .rdata ALIGN(4096) : AT(ADDR(.rdata)) { - *(.rdata) - } .rodata ALIGN(4096) : AT(ADDR(.rodata)) { *(.rodata) *(.rodata.*) @@ -23,8 +20,10 @@ SECTIONS .data ALIGN(4096) : AT(ADDR(.data)) { *(.data) } + bss_start = .; .bss ALIGN(4096) : AT(ADDR(.bss)) { *(.bss) } + bss_end = .; kernel_end = .; } From 9085bb67e48bdad899759b95074231207d6adb24 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 9 Jun 2011 08:29:06 +0200 Subject: [PATCH 31/59] fix typo --- arch/x86/kernel/gdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 53a83b95..ed863eaa 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -28,7 +28,7 @@ gdt_ptr_t gp; static tss_t task_state_segments[MAX_TASKS] __attribute__ ((aligned (PAGE_SIZE))); -static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE) section (".data"))); +static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE), section (".data"))); // currently, our kernel has full access to the ioports static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}}; unsigned char* default_stack_pointer __attribute__ ((section (".data"))) = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t); From b4639fc1ae540ae6f076bf05dcbadcf80af44aaf Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 8 Jun 2011 23:42:20 -0700 Subject: [PATCH 32/59] fix typo, remove some SCC workarounds --- arch/x86/kernel/gdt.c | 2 +- kernel/init.c | 2 +- kernel/tests.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 53a83b95..ed863eaa 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -28,7 +28,7 @@ gdt_ptr_t gp; static tss_t task_state_segments[MAX_TASKS] __attribute__ ((aligned (PAGE_SIZE))); -static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE) section (".data"))); +static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE), section (".data"))); // currently, our kernel has full access to the ioports static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}}; unsigned char* default_stack_pointer __attribute__ ((section (".data"))) = kstacks[0] + KERNEL_STACK_SIZE - sizeof(size_t); diff --git a/kernel/init.c b/kernel/init.c index da2f7dc1..7fc9d0f1 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -120,7 +120,7 @@ int STDCALL network_task(void* arg) // start echo and ping server echo_init(); - //ping_init(); + ping_init(); while(!done) { #ifdef CONFIG_PCI diff --git a/kernel/tests.c b/kernel/tests.c index 78b6f9df..8427ca56 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -139,7 +139,7 @@ int test_init(void) #ifdef CONFIG_LWIP // use ping to test LWIP - //ping_send_now(); + ping_send_now(); #endif return 0; From 5517d505db5791a776f2c34caa02ad522c6be49a Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 8 Jun 2011 23:43:29 -0700 Subject: [PATCH 33/59] remove SCC workaround --- kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/Makefile b/kernel/Makefile index 8c3b4c8c..fdddee71 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c init.c #ping.c init.c +C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c MODULE := kernel include $(TOPDIR)/Makefile.inc From f6fed124b697be109c678110bddb03105a0ef747 Mon Sep 17 00:00:00 2001 From: Simon Pickartz Date: Thu, 9 Jun 2011 04:23:17 -0700 Subject: [PATCH 34/59] use interrupts+anylength_call now --- arch/x86/kernel/irq.c | 5 ++-- arch/x86/scc/iRCCE_isend.c | 28 ++++++++++++++++++++++ arch/x86/scc/iRCCE_mailbox.c | 1 - arch/x86/scc/icc.c | 46 ++++++++++++++++++++---------------- kernel/mailbox.c | 7 +----- kernel/main.c | 4 +--- 6 files changed, 57 insertions(+), 34 deletions(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 017491fb..413c2932 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -235,10 +235,9 @@ void irq_handler(struct state *s) void (*handler) (struct state * s); // at first, we check our work queues - if( s->int_no == 124 ) { - kprintf( "Got remote interrupt!\n" ); +// if( s->int_no == 124 ) { check_workqueues(); - } +// } /* * Find out if we have a custom handler to run for this diff --git a/arch/x86/scc/iRCCE_isend.c b/arch/x86/scc/iRCCE_isend.c index 15c4e242..51cde3eb 100644 --- a/arch/x86/scc/iRCCE_isend.c +++ b/arch/x86/scc/iRCCE_isend.c @@ -41,6 +41,28 @@ #ifdef CONFIG_ROCKCREEK #include +#include +static int send_irq(int ue) { + int tmp, x, y, z, addr; + + 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; + + +} + static int iRCCE_push_send_request(iRCCE_SEND_REQUEST *request) { @@ -240,12 +262,18 @@ int iRCCE_isend( iRCCE_mail_send( send_size, iRCCE_ANYLENGTH_PIGGYBACK, 0, privbuf, dest ); + NOP8; + NOP8; + send_irq( dest ); return iRCCE_SUCCESS; } // we need an extra isend-call else { iRCCE_mail_send( send_size, iRCCE_ANYLENGTH, 0, NULL, dest ); + NOP8; + NOP8; + send_irq( dest ); return iRCCE_isend_general( privbuf, send_size, dest, request ); } diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index 901799c2..e23bceb1 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -187,7 +187,6 @@ int iRCCE_mail_recv( int iRCCE_mail_release( iRCCE_MAIL_HEADER** header ) { - // put header in garbage collection if( (iRCCE_mail_garbage.first == NULL) && (iRCCE_mail_garbage.last == NULL ) ) { diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 16e7cc73..77282567 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -232,30 +232,32 @@ int icc_ping(int ue) return 0; } +#define MAIL_MSG_SIZE 20 + int icc_mail_ping( void ) { - kprintf( "Hello from mail_ping ... \n" ); uint32_t flags; uint64_t timer; int remote_rank = (my_ue+1)%2; + char send_buffer[MAIL_MSG_SIZE]; + int length = MAIL_MSG_SIZE; + if( my_ue ) { return 0; } - + + kprintf( "Hello from mail_ping ... \n" ); + // disable interrupts flags = irq_nested_disable(); // start timer timer = rdtsc(); - iRCCE_mail_send( 0, 1, 0, NULL, remote_rank ); -// kprintf( "Sent pingrequest to %d ...\n", remote_rank ); - - - // wake up receiver - icc_send_irq( remote_rank ); + // start anylength send + iRCCE_isend( send_buffer, -length, remote_rank, NULL ); // wait for response iRCCE_MAIL_HEADER* mail; @@ -349,25 +351,27 @@ void icc_check(void) void icc_mail_check(void) { - iRCCE_MAIL_HEADER* header; - int res, count = 0; - -// if( !my_ue ) return; - - kprintf( "Hello from icc_mail_check() \n" ); + iRCCE_MAIL_HEADER* header = NULL; + int res; + char* recv_buffer; // empty mailbox and interpret headers - do { - res = iRCCE_mail_recv( &header ); + while( (res = iRCCE_mail_recv( &header )) == iRCCE_SUCCESS ) { if( header->tag == 1 ) { - kprintf( "Received mail_ping request ...\n" ); iRCCE_mail_send( 0, 2, 0, NULL, header->source ); } - count++; - iRCCE_mail_release( &header ); - } while( res == iRCCE_SUCCESS ); + else if( header->tag == iRCCE_ANYLENGTH ) { + recv_buffer = (char*)kmalloc( header->size ); + iRCCE_irecv( recv_buffer, header->size, header->source, NULL ); + iRCCE_mail_send( 0, 2, 0, NULL, header->source ); + } + else if( header->tag == iRCCE_ANYLENGTH_PIGGYBACK ) { + iRCCE_mail_send( 0, 2, 0, NULL, header->source ); + } + + iRCCE_mail_release( &header ); + } - kprintf( "received %d headers!\n", count ); } #endif diff --git a/kernel/mailbox.c b/kernel/mailbox.c index e20e9e36..c790f984 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -28,19 +28,14 @@ #include int STDCALL mail_ping(void* arg) { - - kprintf( "### Hello from mail_ping\n" ); - icc_mail_ping(); - kprintf( "### mail_ping finished\n" ); return 0; } int mailbox_test_init(void) { - char* argv[] = {"/bin/mailbox", NULL}; - create_kernel_task(NULL, mail_ping, argv); + create_kernel_task(NULL, mail_ping, NULL); return 0; } diff --git a/kernel/main.c b/kernel/main.c index f2fcf076..91e3c1ea 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -113,12 +113,10 @@ int main(void) sleep(5); list_root(); // test_init(); - kprintf( "starting mailbox ...\n " ); mailbox_test_init(); per_core(current_task)->status = TASK_IDLE; reschedule(); - - + while(1); while(1) { #ifdef CONFIG_ROCKCREEK icc_halt(); From 692e554a3a507f2853992bda90b8afbaef8e168d Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 21 Jun 2011 23:10:45 -0700 Subject: [PATCH 35/59] remove obsolete test --- kernel/tests.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/kernel/tests.c b/kernel/tests.c index 8427ca56..1fbc7a48 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -137,10 +137,5 @@ int test_init(void) //create_user_task(NULL, "/bin/jacobi", argv); //create_user_task(NULL, "/bin/jacobi", argv); -#ifdef CONFIG_LWIP - // use ping to test LWIP - ping_send_now(); -#endif - return 0; } From b68e9051cbf8bfacacc99439a344830eeb814731 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 21 Jun 2011 23:12:09 -0700 Subject: [PATCH 36/59] MetalSVM is a research project => we trust the incoming IP packets - set ETHARP_TRUST_IP_MAC to 1 --- lwip/src/include/lwipopts.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index f6912703..af8d018c 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -29,6 +29,18 @@ */ #define DHCP_DOES_ARP_CHECK 0 +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#define ETHARP_TRUST_IP_MAC 1 + /** * LWIP_TCP==1: Turn on TCP. */ @@ -58,7 +70,7 @@ /** * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c */ -#define LWIP_HAVE_LOOPIF 1 +#define LWIP_HAVE_LOOPIF 1 /** * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP From fd89f4f825947c62965905d04b3bccfe82ca0bb0 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 21 Jun 2011 23:18:10 -0700 Subject: [PATCH 37/59] use the socket version of ping, if this feature is enabled in LwIP --- kernel/ping.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/ping.c b/kernel/ping.c index 4a02ff0e..98398300 100644 --- a/kernel/ping.c +++ b/kernel/ping.c @@ -53,6 +53,10 @@ #include #include +#if LWIP_SOCKET +#define PING_USE_SOCKETS 1 +#endif + #if PING_USE_SOCKETS #include #include @@ -68,7 +72,7 @@ /** ping target - should be a "ip_addr_t" */ #ifndef PING_TARGET -#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any) +#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any) #endif /** ping receive timeout - in milliseconds */ From 19fffd46c5455de9a8de7948287db9b7211ebfbd Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 21 Jun 2011 23:19:28 -0700 Subject: [PATCH 38/59] use netif_set_up to enable the network device --- kernel/init.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index 7fc9d0f1..2f9b883f 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -101,11 +101,7 @@ int STDCALL network_task(void* arg) } netif_set_default(&netif); - - if (netif_is_up(&netif)) { - kputs("Network interface is not up\n"); - return -EIO; - } + netif_set_up(&netif); #ifndef CONFIG_ROCKCREEK kprintf("Starting DHCPCD...\n"); From f8be2e34833b3c121afb1939527a86b91a1bc986 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 21 Jun 2011 23:26:31 -0700 Subject: [PATCH 39/59] add first functional version of the eMAC driver - this driver required at least sccKit 1.4.0 --- arch/x86/mm/page.c | 2 +- drivers/net/rckemac.c | 432 +++++++++++++++++++++++------------------- drivers/net/rckemac.h | 2 +- 3 files changed, 238 insertions(+), 198 deletions(-) diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index a202a1bb..4551edc1 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -735,7 +735,7 @@ int arch_paging_init(void) kprintf("Map message passing buffers at 0x%x\n", viraddr); // map the FPGA registers - viraddr = map_region(FPGA_BASE, FPGA_BASE, (16*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); + viraddr = map_region(FPGA_BASE, FPGA_BASE, 0x10000 >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); kprintf("Map FPGA regsiters at 0x%x\n", viraddr); #endif diff --git a/drivers/net/rckemac.c b/drivers/net/rckemac.c index 8e996dc6..b2b07f4e 100644 --- a/drivers/net/rckemac.c +++ b/drivers/net/rckemac.c @@ -17,6 +17,12 @@ * This file is part of MetalSVM. */ +/* + * This eMAC driver required at least sccKit 1.4.0 and based on + * the eMAC Driver Description (section 9.6.5) in the + * SccKit 1.4.0 User’s Guide (Revision 0.92 Part 9). + */ + #include #include #include @@ -50,7 +56,7 @@ #define EMAC_RX_CONTROL 0x9000 #define EMAC_TX_CONTROL 0x9900 -/* Xilinx IP configuration - offsets */ +/* IP configuration - offsets */ #define CONFIG_FLOW_CONTROL_ADD 0xC0 #define TRANSMITTER_ADDRESS 0x80 #define RECEIVER1_ADDRESS 0x40 @@ -94,18 +100,30 @@ #define CLINE_ALIGN(_x) (((_x) + CLINE_SIZE - 1) & CLINE_MASK) #define CLINE_PACKETS(_x) (CLINE_ALIGN(_x) >> CLINE_SHIFT) +/* Flush */ +#define CL1FLUSH __asm__ volatile (".byte 0x0F; .byte 0x0A;\n") + +/* Read 16bit from buffer */ +#define U16(_addr) (256 * (*((uint8_t*) (_addr + 1))) + (*((uint8_t*)(_addr)))) + #define MAC_ADDRESS 0x00454D414331ULL #define MAC_HI(_x) ((((_x) >> 32)) & 0xFFFF) #define MAC_LO(_x) (((_x) ) & 0xFFFFFFFF) -static struct netif* mynetif[4] = {NULL, NULL, NULL, NULL}; +static struct netif* mynetif; -static inline int read_emac(int num_emac, int offset, int core) +static int read_emac(int num_emac, int offset, int core) { - return *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); + int ret; + + ret = *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); + /* no error: read twice, as xilinx ip need some time... */ + ret = *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); + + return ret; } -static inline void write_emac(int num_emac, int offset, int core, int value) +static void write_emac(int num_emac, int offset, int core, int value) { *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)) = value; } @@ -121,14 +139,14 @@ static err_t rckemacif_output(struct netif* netif, struct pbuf* p) rckemacif_t* rckemacif = netif->state; uint32_t i; struct pbuf *q; - void *addr = NULL; - uint16_t read_offset = 0; - int rest = 0; - int packets = 0; + void *addr; + uint16_t read_offset; + int rest; + int packets; int sum = 0; /* check for over/underflow */ - if (BUILTIN_EXPECT(p->tot_len > 1536, 0)) { + if (BUILTIN_EXPECT((p->tot_len < 20) || (p->tot_len > 1536), 0)) { LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_output: illegal packet length %d => drop\n", p->len)); return ERR_IF; } @@ -170,8 +188,8 @@ again: * q traverses through linked list of pbuf's * This list MUST consist of a single packet ONLY */ - for (q = p, i = 0; q != 0; q = q->next) { - memcpy(addr + 2 + i, q->payload, q->len); + for (q=p, i=0; q!=0; q=q->next) { + memcpy(((uint8_t*)addr) + 2 + i, q->payload, q->len); i += q->len; } @@ -193,7 +211,7 @@ again: q = p; i = 0; while ((q != 0) && (i < bytes_to_copy)) { sz = q->len > bytes_to_copy-i ? bytes_to_copy-i : q->len; - memcpy(addr + 2 + i, q->payload, sz); + memcpy(((uint8_t*) addr) + 2 + i, q->payload, sz); bytes_left -= sz; i += sz; if (i < bytes_to_copy) @@ -207,12 +225,12 @@ again: i = 0; if (sz < q->len) { - memcpy(addr, q->payload + sz, q->len - sz); + memcpy((uint8_t*) addr, q->payload + sz, q->len - sz); bytes_left -= (q->len - sz); i = q->len - sz; } for(q=q->next; (q != 0); q = q->next) { - memcpy(addr+i, q->payload, q->len); + memcpy(((uint8_t*) addr) + i, q->payload, q->len); i += q->len; } @@ -228,8 +246,7 @@ again: *((volatile int*) rckemacif->tx_buffer) = 2; /* set new write offset */ - LWIP_DEBUGF(NETIF_DEBUG, ("Update tx write offset: %d (read offset %d)\n", rckemacif->tx_write_offset, read_offset)); - + //LWIP_DEBUGF(NETIF_DEBUG, ("Update tx write offset: %d (read offset %d)\n", rckemacif->tx_write_offset, read_offset)); write_emac(rckemacif->num_emac, EMAC_TX_CONTROL+EMAC_TX_BUFFER_WRITE_OFFSET, rckemacif->core, rckemacif->tx_write_offset); #if ETH_PAD_SIZE @@ -241,151 +258,177 @@ again: return ERR_OK; } -#if 0 -static void rtl_rx_inthandler(struct netif* netif) +static void rckemacif_rx_handler(struct netif* netif, unsigned int write_offset) { - rtl1839if_t* rtl8139if = netif->state; - uint16_t header; - uint16_t length, i; - uint8_t cmd; - struct pbuf *p = NULL; + rckemacif_t* rckemacif = netif->state; + unsigned short read_offset; + unsigned int counter; + volatile void *addr; + uint16_t i, length; + struct pbuf *p; struct pbuf* q; - cmd = inportb(rtl8139if->iobase + CR); - while(!(cmd & CR_BUFE)) { - header = *((uint16_t*) (rtl8139if->rx_buffer+rtl8139if->rx_pos)); - rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % (8192+16); + if (write_offset > rckemacif->rx_buffer_max) { + LWIP_DEBUGF(NETIF_DEBUG, ("Warning, write offset > buffer max!! (%d > %d)\n", write_offset, rckemacif->rx_buffer_max)); + read_offset = 1; + write_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, rckemacif->core, read_offset); + rckemacif->rx_read_offset = read_offset; + return; + } + + while(1) { + if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset)) { + read_offset = rckemacif->rx_read_offset; + read_offset++; + if (read_offset < 1 || read_offset > rckemacif->rx_buffer_max) { + read_offset = 1; + } + addr = rckemacif->rx_buffer + read_offset * 32; + + length = U16(addr); + + // Check for over/underflow + if ((length < 20) || (length > 1536)) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_rx_handler(): illegal packet length %d => drop\n", length)); + LWIP_DEBUGF(NETIF_DEBUG, ("start read at %d; write_offset at %d; addr: %p, packet len: %d\n", read_offset, write_offset, addr, length)); + + read_offset = write_offset; +#if 1 + kprintf("Buffer:\n"); + for (i = 0; i < 32; i++) { + kprintf("%2.2x ", ((char*)addr)[i] & 0xFF); + } + kprintf("\n"); + + kprintf("Buffer0:\n"); + for (i = 0; i < 32; i++) { + kprintf("%2.2x ", ((char*)rckemacif->rx_buffer)[i] & 0xFF); + } + kprintf("\n"); +#endif + + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + + goto rxDone; + } - if (header & ISR_ROK) { - length = *((uint16_t*) (rtl8139if->rx_buffer+rtl8139if->rx_pos)) - 4; // copy packet (but not the CRC) - rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % (8192+16); #if ETH_PAD_SIZE length += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif + //LWIP_DEBUGF(NETIF_DEBUG, ("length %u, read_offset %u, write_offset %u\n", length, read_offset, write_offset)); p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); if (p) { #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif - for (q=p; q!=NULL; q=q->next) { - for(i=0; ilen; i++) { - ((uint8_t*) q->payload)[i] = rtl8139if->rx_buffer[rtl8139if->rx_pos]; - rtl8139if->rx_pos = (rtl8139if->rx_pos + 1) % (8192+16); - } - } + if (read_offset < write_offset) { + for (q=p, counter=0; q!=NULL; q=q->next) { + for(i=0; ilen; i++, counter++) { + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[2 + counter]; + } + } + + read_offset += CLINE_PACKETS(p->len + 2) - 1; + } else { + int rest; + int bytesLeft = length; + int bytesToCopy = length; + + /* rest to the end of buffer - 2 bytes length information */ + rest = (rckemacif->rx_buffer_max - read_offset + 1) * 32 - 2; + if (length > rest) + bytesToCopy = rest; + LWIP_DEBUGF(NETIF_DEBUG, ("bytes to copy: %d, bytesLeft: %d\n", bytesToCopy, bytesLeft)); + + for (q=p, counter=0; q!=NULL; q=q->next) { + for(i=0; ilen; i++, counter++) { + if (counter < bytesToCopy) + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[2 + counter]; + else + goto out; + } + } +out: + bytesLeft -= bytesToCopy; + + if (bytesLeft != 0) { + addr = rckemacif->rx_buffer + 0x20; + LWIP_DEBUGF(NETIF_DEBUG, ("copying from %p, left: %d (%x)\n", addr, bytesLeft, ((uint8_t*)addr)[0])); + for(counter=0; (ilen) && (counter < bytesLeft); i++, counter++) + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter]; + for(q=q->next; (q!=NULL) && (counter < bytesLeft); q=q->next) { + for(i=0; (ilen) && (counter < bytesLeft); i++, counter++) { + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter]; + } + } + read_offset = CLINE_PACKETS(bytesLeft); + } else { + read_offset += CLINE_PACKETS(p->len + 2) - 1; + } + } + #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif - mailbox_ptr_post(&rtl8139if->mbox, (void*)p); - //rtl8139if_input(netif, p); + mailbox_ptr_post(&rckemacif->mbox, (void*)p); LINK_STATS_INC(link.recv); } else { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: not enough memory!\n")); - rtl8139if->rx_pos += (rtl8139if->rx_pos + length) % (8192+16); + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_rx_inthandler: not enough memory!\n")); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); } - // packets are dword aligned - rtl8139if->rx_pos = ((rtl8139if->rx_pos + 4 + 3) & ~0x3) % (8192+16); - outportw(rtl8139if->iobase + CAPR, rtl8139if->rx_pos - 0x10); - } else { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: invalid header!\n")); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - break; - } - - cmd = inportb(rtl8139if->iobase + CR); +rxDone: + /* set new read pointer */ + //LWIP_DEBUGF(NETIF_DEBUG, ("Update rx read offset: %d\n", read_offset)); + write_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, rckemacif->core, read_offset); + rckemacif->rx_read_offset = read_offset; + } else break; } } -static void rtl_tx_inthandler(struct netif* netif) -{ - rtl1839if_t* rtl8139if = netif->state; - uint32_t checks = rtl8139if->tx_queue - rtl8139if->tx_complete; - uint32_t txstatus; - uint8_t tmp8; - - while(checks > 0) - { - tmp8 = rtl8139if->tx_complete % 4; - txstatus = inportl(rtl8139if->iobase + TSD0 + tmp8 * 4); - - if (!(txstatus & (TSD_TOK|TSD_TUN|TSD_TABT))) - return; - - if (txstatus & (TSD_TABT | TSD_OWC)) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_tx_inthandler: major error\n")); - continue; - } - - if (txstatus & TSD_TUN) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_tx_inthandler: transmit underrun\n")); - } - - if (txstatus & TSD_TOK) { - rtl8139if->tx_inuse[tmp8] = 0; - rtl8139if->tx_complete++; - checks--; - } - } -} -#endif - static void rckemacif_handler(struct state* s) { - LWIP_DEBUGF(NETIF_DEBUG, ("HELLO! Got interrupt!\n")); + unsigned int status, tmp; + unsigned int write_offset; + rckemacif_t* rckemacif = mynetif->state; -#if 0 - rtl1839if_t* rtl8139if = mynetif->state; - uint16_t isr_contents; - - while (1) { - isr_contents = inportw(rtl8139if->iobase + ISR); - if (isr_contents == 0) - break; - - if (isr_contents & ISR_ROK) { - rtl_rx_inthandler(mynetif); - outportw(rtl8139if->iobase + ISR, ISR_ROK); - } - - if (isr_contents & ISR_TOK) { - rtl_tx_inthandler(mynetif); - outportw(rtl8139if->iobase + ISR, ISR_TOK); - } - - if (isr_contents & ISR_RER) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: RX error detected!\n")); - outportw(rtl8139if->iobase + ISR, ISR_RER); - } - - if (isr_contents & ISR_TER) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: TX error detected!\n")); - outportw(rtl8139if->iobase + ISR, ISR_TER); - } - - if (isr_contents & ISR_RXOVW) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: RX overflow detected!\n")); - outportw(rtl8139if->iobase + ISR, ISR_RXOVW); - } + status = *((volatile int*) (FPGA_BASE + IRQ_STATUS + rckemacif->core * 2 * 4)); + // read twice to be sure + status = *((volatile int*) (FPGA_BASE + IRQ_STATUS + rckemacif->core * 2 * 4)); + if (!(status & (1 << rckemacif->num_emac))) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_handler: no interrupt\n")); + return; } -#endif + +nexttry: + /* check for updated write offset */ + CL1FLUSH; + write_offset = *((volatile unsigned int*) (rckemacif->rx_buffer)) & 0xFFFF; + //write_offset = read_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, rckemacif->core); + if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset)) { + rckemacif_rx_handler(mynetif, write_offset); + goto nexttry; + } + + /* Set interrupt bit */ + tmp = *((volatile unsigned int*) rckemacif->irq_address); + tmp &= ~(EMAC_IRQ_MASK); + *((volatile unsigned int*) rckemacif->irq_address) = tmp; + + /* Reset */ + *((volatile unsigned*) (FPGA_BASE + IRQ_RESET + rckemacif->core * 2 * 4)) = (1 << rckemacif->num_emac); } err_t rckemacif_wait(struct netif* netif, uint32_t poll) { - return ERR_OK; -#if 0 rckemacif_t* rckemacif = netif->state; struct eth_hdr *ethhdr; struct pbuf *p = NULL; err_t err = ERR_OK; - LWIP_DEBUGF(NETIF_DEBUG, ("Hello from rckemacif_wait!\n")); - if (poll) { if (mailbox_ptr_tryfetch(&(rckemacif->mbox), (void**) &p)) return err; @@ -396,6 +439,8 @@ err_t rckemacif_wait(struct netif* netif, uint32_t poll) /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; + //LWIP_DEBUGF(NETIF_DEBUG, ("Got packet of type 0x%x!\n", htons(ethhdr->type))); + switch (htons(ethhdr->type)) { /* IP or ARP packet? */ case ETHTYPE_ARP: @@ -406,7 +451,7 @@ err_t rckemacif_wait(struct netif* netif, uint32_t poll) case ETHTYPE_PPPOE: #endif /* PPPOE_SUPPORT */ /* full packet send to tcpip_thread to process */ - if ((err = mynetif[netif->num]->input(p, mynetif[netif->num])) != ERR_OK) { + if ((err = mynetif->input(p, mynetif)) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_poll: IP input error\n")); pbuf_free(p); } @@ -417,21 +462,20 @@ err_t rckemacif_wait(struct netif* netif, uint32_t poll) } return err; -#endif } err_t rckemacif_init(struct netif* netif) { rckemacif_t* rckemacif; - int num, num_emac; + int num_emac; int macPorts; int i, tmp, x, y, z, core; uint64_t tile_offset; - uint16_t write_offset = 0; - uint16_t read_offset = 0; - int mode = 0; - int subdest = 0; - int route = 0; + uint16_t write_offset; + uint16_t read_offset; + int mode; + int subdest; + int route; LWIP_ASSERT("netif != NULL", (netif != NULL)); @@ -457,7 +501,8 @@ err_t rckemacif_init(struct netif* netif) kfree(rckemacif, sizeof(rckemacif_t)); return ERR_MEM; } - memset(rckemacif->rx_buffer, 0, BUFFER_SIZE); + memset(rckemacif->rx_buffer, 0x00, 0x20); + memset(rckemacif->rx_buffer + 0x20, 0xDA, BUFFER_SIZE - 0x20); rckemacif->rx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1; /* allocate the send buffers */ @@ -468,7 +513,8 @@ err_t rckemacif_init(struct netif* netif) kfree(rckemacif, sizeof(rckemacif_t)); return ERR_MEM; } - memset(rckemacif->tx_buffer, 0, BUFFER_SIZE); + memset(rckemacif->tx_buffer, 0x00, 0x20); + memset(rckemacif->tx_buffer + 0x20, 0xDA, BUFFER_SIZE - 0x20); rckemacif->tx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1; mailbox_ptr_init(&rckemacif->mbox); @@ -478,42 +524,42 @@ err_t rckemacif_init(struct netif* netif) * (offset, subdest, route) */ if (z == 0) { - tmp = ReadConfigReg(CRB_OWN + GLCFG0); - rckemacif->irq_address = CRB_OWN + GLCFG0; + tmp = ReadConfigReg(CRB_OWN + LUT0); + rckemacif->irq_address = (void*) (CRB_OWN + GLCFG0); } else { - tmp = ReadConfigReg(CRB_OWN + GLCFG1); - rckemacif->irq_address = CRB_OWN + GLCFG1; + tmp = ReadConfigReg(CRB_OWN + LUT1); + rckemacif->irq_address = (void*) (CRB_OWN + GLCFG1); } - tile_offset = (unsigned long long)((unsigned long long) tmp & 0x3FF) << 24; + tile_offset = (uint64_t)((uint64_t) tmp & 0x3FF) << 24; subdest = (tmp >> 10) & 0x07; route = (tmp >> 13) & 0xFF; mode = (subdest << 8) + route; + LWIP_DEBUGF(NETIF_DEBUG, ("tile_offset = 0x%llx\n", tile_offset)); /* get fpga/sccKit port settings */ tmp = *((volatile int*)(FPGA_BASE + 0x822C)); + tmp = *((volatile int*)(FPGA_BASE + 0x822C)); macPorts = ((tmp >> 9 ) & 0xFF); - LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: eMAC0: %s eMAC1: %s eMAC2: %s eMAC3: %s\n", - (macPorts & EMAC0) != 0 ? "present" : "-", - (macPorts & EMAC1) != 0 ? "present" : "-", - (macPorts & EMAC2) != 0 ? "present" : "-", - (macPorts & EMAC3) != 0 ? "present" : "-")); + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: eMAC0: %s eMAC1: %s eMAC2: %s eMAC3: %s\n", + (macPorts & EMAC0) != 0 ? "present" : "-", + (macPorts & EMAC1) != 0 ? "present" : "-", + (macPorts & EMAC2) != 0 ? "present" : "-", + (macPorts & EMAC3) != 0 ? "present" : "-")); // determine device and emac number - for(num=0; (num<4) && (mynetif[num] != NULL); num++) - ; - if (num >= 4) - return ERR_ARG; - for(i=0, num_emac=0; (i<=num) && (num_emac < 4); i++) { - while (((macPorts & (1 << num_emac)) == 0) && (num_emac < 4)) - num_emac++; - } + num_emac=0; + while (((macPorts & (1 << num_emac)) == 0) && (num_emac < 4)) + num_emac++; if (num_emac >= 4) return ERR_ARG; - mynetif[num] = netif; + mynetif = netif; rckemacif->num_emac = num_emac; - LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: map device %d to eMAC %d\n", num, num_emac)); + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: used eMAC device %d\n", num_emac)); + + tmp = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); + tmp = read_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, 0); if (core == 0) { /* Only core 0 initialize the xilinx port */ @@ -524,23 +570,23 @@ err_t rckemacif_init(struct netif* netif) int add_filter_mod = 0; /* Disable tx and rx flow control of eMAC */ - LWIP_DEBUGF(NETIF_DEBUG, ("Disabling tx/rx flow control of eMAC%d\n", num_emac)); - flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); + LWIP_DEBUGF(NETIF_DEBUG, ("Disabling tx/rx flow control of eMAC%d\n", num_emac)); + flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); /* Set top 3 bits of the flow control configuration to zero, * therefore disabling tx and rx flow control */ flow_control &= 0x7FFFFFF; - write_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0, flow_control); + write_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0, flow_control); /* Sanity check */ flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); - LWIP_DEBUGF(NETIF_DEBUG, (" CONFIG_FLOW_CONTROL_ADD set: 0x%x\n", flow_control)); + LWIP_DEBUGF(NETIF_DEBUG, (" CONFIG_FLOW_CONTROL_ADD set: 0x%x\n", flow_control)); /* Setting the tx configuration bit to enable the transmitter and * set to full duplex mode. */ - LWIP_DEBUGF(NETIF_DEBUG, ("Setting rx configuration of eMAC%d\n", num_emac)); + LWIP_DEBUGF(NETIF_DEBUG, ("Setting rx configuration of eMAC%d\n", num_emac)); transmitter_addr = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); /* Now set the relevant bits and write back into the register: @@ -552,7 +598,7 @@ err_t rckemacif_init(struct netif* netif) write_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0, transmitter_addr); transmitter_addr = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); - LWIP_DEBUGF(NETIF_DEBUG, (" TRANSMITTER_ADDRESS set: %x\n", transmitter_addr)); + LWIP_DEBUGF(NETIF_DEBUG, (" TRANSMITTER_ADDRESS set: %x\n", transmitter_addr)); /* Setting the rx configuration bit to enable the transmitter and * set to full duplex mode. @@ -602,32 +648,29 @@ err_t rckemacif_init(struct netif* netif) * 31 (promiscuous mode) = 1 not working, but thats ok! */ add_filter_mod |= (1 << 31); - write_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0, add_filter_mod); + write_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0, add_filter_mod); - add_filter_mod = read_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0); + add_filter_mod = read_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0); LWIP_DEBUGF(NETIF_DEBUG, (" ADD_FILTER_MOD set: %x\n", add_filter_mod)); } sleep(3); /* Start address */ - LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer %p (%lx phys)\n", rckemacif->rx_buffer, virt_to_phys(rckemacif->rx_buffer))); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer %p (%lx phys)\n", rckemacif->rx_buffer, virt_to_phys((uint32_t)rckemacif->rx_buffer))); /**** Receiver configuration ****/ - uint32_t utmp = virt_to_phys(rckemacif->rx_buffer); - uint32_t addr_offset = tile_offset + utmp; - addr_offset >>= 5; - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core, addr_offset); - utmp = read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer set to @%x\n", utmp)); + uint64_t addr_offset = (tile_offset + (uint64_t) virt_to_phys((uint32_t) rckemacif->rx_buffer)) >> 5; + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core, (uint32_t) addr_offset); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer set to @%x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core))); - /* Set buffer write offset */ + /* Get buffer write offset */ write_offset = read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, core); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer write offset at: %d\n", write_offset)); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer write offset at: %d\n", write_offset)); /* Set buffer read offset to write offset */ - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core, write_offset); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core, write_offset); LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer read offset set to: %d\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core))); rckemacif->rx_read_offset = write_offset; @@ -637,49 +680,46 @@ err_t rckemacif_init(struct netif* netif) /* Threshold */ write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core, 0x01); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Threshold set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core))); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Threshold set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core))); /* Route */ - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core, (core << 24) | (((y << 4) | x) << 16) | mode); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core, (z << 24) | (((y << 4) | x) << 16) | mode); LWIP_DEBUGF(NETIF_DEBUG, (" RX Mode set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core))); // determine mac address - uint32_t mac1 = *((uint32_t*)(FPGA_BASE+0x7E00)); - uint32_t mac2 = *((uint32_t*)(FPGA_BASE+0x7E04)); - uint64_t mac = (((unsigned long long)mac1) << 32) + ( unsigned long long ) mac2; + uint32_t mac1 = *((volatile uint32_t*)(FPGA_BASE+0x7E00)); + uint32_t mac2 = *((volatile uint32_t*)(FPGA_BASE+0x7E04)); + uint64_t mac = (((unsigned long long)mac1) << 32) + (unsigned long long) mac2; if (mac == 0x00) mac = MAC_ADDRESS; /* Calculate mac address of core depending on selected emac device */ mac = mac + (1 << num_emac) * 0x100 + core; + for (i=0; i<6; i++) + mynetif->hwaddr[5-i] = (mac >> (i*8)) & 0xFF; LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: MAC address ")); - for (i=0; i<6; i++) { - mynetif[num]->hwaddr[i] = mac & 0xFF; - mac = mac >> 8; - LWIP_DEBUGF(NETIF_DEBUG, ("%02x ", mynetif[num]->hwaddr[i])); - } + for (i=0; i<6; i++) + LWIP_DEBUGF(NETIF_DEBUG, ("%02x ", mynetif->hwaddr[i])); LWIP_DEBUGF(NETIF_DEBUG, ("\n")); write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core, MAC_HI(mac)); - LWIP_DEBUGF(NETIF_DEBUG, (" MAC1 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core))); - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core, MAC_LO(mac)); - LWIP_DEBUGF(NETIF_DEBUG, (" MAC2 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core))); + LWIP_DEBUGF(NETIF_DEBUG, (" MAC1 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core))); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core, MAC_LO(mac)); + LWIP_DEBUGF(NETIF_DEBUG, (" MAC2 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core))); - /* Activate network port by setting enable bit */ - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core, 0x01); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Port enable set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core))); + /* Activate network port by setting enable bit */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core, 0x01); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Port enable set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core))); /**** Transfer configuration ****/ /* Start address */ - LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer %p (%lx phys)\n", rckemacif->tx_buffer, virt_to_phys(rckemacif->tx_buffer))); - utmp = virt_to_phys(rckemacif->tx_buffer); - write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core, (tmp + tile_offset) >> 5); - utmp = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core); - LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer set to @%x\n", tmp)); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer %p (%lx phys)\n", rckemacif->tx_buffer, virt_to_phys((uint32_t)rckemacif->tx_buffer))); + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core, (uint32_t) (((uint64_t) virt_to_phys((uint32_t)rckemacif->tx_buffer) + tile_offset) >> 5)); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer set to @%x\n", read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core))); - /* Get buffer read offset */ - read_offset = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_READ_OFFSET, core); + /* Get buffer read offset */ + read_offset = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_READ_OFFSET, core); LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer read offset at: %d\n", read_offset)); /* Set buffer write offset to read offset */ @@ -717,7 +757,7 @@ err_t rckemacif_init(struct netif* netif) /* administrative details */ netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->num = num; + netif->num = 0; /* downward functions */ netif->output = etharp_output; netif->linkoutput = rckemacif_output; diff --git a/drivers/net/rckemac.h b/drivers/net/rckemac.h index b8a8a5ae..2c53523f 100644 --- a/drivers/net/rckemac.h +++ b/drivers/net/rckemac.h @@ -31,10 +31,10 @@ typedef struct rckemacif { struct eth_addr *ethaddr; /* Add whatever per-interface state that is needed here. */ - uint8_t* tx_buffer; uint8_t* rx_buffer; uint32_t rx_buffer_max; uint32_t rx_read_offset; + uint8_t* tx_buffer; uint32_t tx_buffer_max; uint32_t tx_write_offset; void* irq_address; From cf6fdf406781aaca0f09fc838fe9c8ce1cfcecd5 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 22 Jun 2011 08:38:49 +0200 Subject: [PATCH 40/59] reducing the size of the kernel image by using unintialized global arrays --- mm/memory.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index c6241d52..ad29aedd 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -39,7 +39,7 @@ * * Set whole address space as occupied */ -static uint8_t bitmap[BITMAP_SIZE] = {[0 ... BITMAP_SIZE-1] = 0xFF}; +static uint8_t bitmap[BITMAP_SIZE]; // = {[0 ... BITMAP_SIZE-1] = 0xFF}; static spinlock_t bitmap_lock = SPINLOCK_INIT; static size_t alloc_start; atomic_int32_t total_pages = ATOMIC_INIT(0); @@ -94,6 +94,9 @@ int mmu_init(void) unsigned int i; size_t addr; + // at first, set default value of the bitmap + memset(bitmap, 0xFF, sizeof(uint8_t)*BITMAP_SIZE); + #ifdef CONFIG_MULTIBOOT if (mb_info && (mb_info->flags & MULTIBOOT_INFO_MEM_MAP)) { size_t end_addr; From 499fc1192f925d586361f0174442c74b4df80187 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 22 Jun 2011 11:29:59 -0700 Subject: [PATCH 41/59] comment ping example --- kernel/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/init.c b/kernel/init.c index 2f9b883f..17b31c37 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -116,7 +116,7 @@ int STDCALL network_task(void* arg) // start echo and ping server echo_init(); - ping_init(); + //ping_init(); while(!done) { #ifdef CONFIG_PCI From 7b2dfe4497013f4d3dd4ab9615c2bd4855369224 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 27 Jun 2011 15:12:58 -0700 Subject: [PATCH 42/59] map off-die shared memory in the kernel address space - plus example code --- arch/x86/scc/RCCE_admin.c | 5 +++-- arch/x86/scc/icc.c | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/x86/scc/RCCE_admin.c b/arch/x86/scc/RCCE_admin.c index 2ad87e18..dc7db27d 100644 --- a/arch/x86/scc/RCCE_admin.c +++ b/arch/x86/scc/RCCE_admin.c @@ -26,6 +26,7 @@ // #include +#include #ifdef CONFIG_ROCKCREEK @@ -335,13 +336,13 @@ int RCCE_init( RCCE_malloc_init(RCCE_comm_buffer[RCCE_IAM],RCCE_BUFF_SIZE); #ifdef SHMADD - RCCE_shmalloc_init(RC_SHM_BUFFER_START()+RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX); + RCCE_shmalloc_init(map_region(NULL, RC_SHM_BUFFER_START()+RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX/PAGE_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE), RCCE_SHM_SIZE_MAX); #ifdef SHMDBG kprintf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: %x %x\n", RCCE_IAM, __FILE__,__LINE__,RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX); #endif #else - RCCE_shmalloc_init(RC_SHM_BUFFER_START(),RCCE_SHM_SIZE_MAX); + RCCE_shmalloc_init(map_region(NULL, RC_SHM_BUFFER_START(), RCCE_SHM_SIZE_MAX/PAGE_SIZE, MAP_KERNEL_SPACE|MAP_NO_CACHE), RCCE_SHM_SIZE_MAX); #endif // initialize the (global) flag bookkeeping data structure diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 730add0b..4e77fb79 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -142,6 +142,17 @@ int icc_init(void) kprintf("failed! (0x%x)\n", msg); #endif +#if 0 + char* str = RCCE_shmalloc(128); + if (my_ue == 1) { + memset(str, 0x00, 128); + strcpy(str, "Hello RCCE_shmalloc\n"); + } + RCCE_barrier(&RCCE_COMM_WORLD); + kprintf("RCCE_shmalloc test: %s\n", str); + RCCE_shfree(str); +#endif + // reset INTR/LINT0 flag z = Z_PID(RC_COREID[my_ue]); tmp=ReadConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1)); From 01a7530d6354267da878f97a7041ebf1bdc1f839 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 28 Jun 2011 10:58:32 -0700 Subject: [PATCH 43/59] use the FPGA registers to determine the number slots, which are used as private memory --- include/metalsvm/config.h.example | 5 ---- mm/memory.c | 49 ++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/include/metalsvm/config.h.example b/include/metalsvm/config.h.example index f5b35948..34a2717a 100644 --- a/include/metalsvm/config.h.example +++ b/include/metalsvm/config.h.example @@ -63,11 +63,6 @@ extern "C" { #define SHMADD #define SHMDBG //#define SHMADD_CACHEABLE -/* default values for 16 GB system */ -#define PRIVATE_MEM1_START 0x00000000 -#define PRIVATE_MEM1_END 0x13FFFFFF -#define PRIVATE_MEM2_START 0xFF000000 -#define PRIVATE_MEM2_END 0xFFFFFFFF #define SCC_BOOTINFO 0x80000 #define BUILTIN_EXPECT(exp, b) __builtin_expect((exp), (b)) diff --git a/mm/memory.c b/mm/memory.c index ad29aedd..efa3d5c6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -30,6 +30,9 @@ #include #endif #ifdef CONFIG_ROCKCREEK +#include +#include +#include #include #endif @@ -93,6 +96,7 @@ int mmu_init(void) size_t kernel_size; unsigned int i; size_t addr; + int ret; // at first, set default value of the bitmap memset(bitmap, 0xFF, sizeof(uint8_t)*BITMAP_SIZE); @@ -148,15 +152,8 @@ int mmu_init(void) } } #elif defined(CONFIG_ROCKCREEK) - for(addr=PRIVATE_MEM1_START; addr> PAGE_SHIFT); - if (addr > addr + PAGE_SIZE) - break; - atomic_int32_inc(&total_pages); - atomic_int32_inc(&total_available_pages); - } - - for(addr=PRIVATE_MEM2_START; addr> PAGE_SHIFT); if (addr > addr + PAGE_SIZE) break; @@ -200,7 +197,39 @@ int mmu_init(void) if ((size_t) &kernel_end & (PAGE_SIZE-1)) alloc_start++; - return paging_init(); + ret = paging_init(); + +#ifdef CONFIG_ROCKCREEK + /* + * Now, we are able to read the FPGA register and to + * determin the number of slots. + */ + uint32_t slots = *((volatile uint32_t*) (FPGA_BASE + 0x8244)); + if (slots == 0) + slots = 21; + + kprintf("MetalSVM use %d slots for private memory\n", slots); + + // define all the private slots as free + for(addr=0x1000000; addr<(slots-1)*0x1000000; addr+=PAGE_SIZE) { + page_clear_mark(addr >> PAGE_SHIFT); + if (addr > addr + PAGE_SIZE) + break; + atomic_int32_inc(&total_pages); + atomic_int32_inc(&total_available_pages); + } + + // Note: The last slot belongs always to the private memory. + for(addr=0xFF000000; addr<0xFFFFFFFF; addr+=PAGE_SIZE) { + page_clear_mark(addr >> PAGE_SHIFT); + if (addr > addr + PAGE_SIZE) + break; + atomic_int32_inc(&total_pages); + atomic_int32_inc(&total_available_pages); + } +#endif + + return ret; } /* From af2345d15cb36a2b11a6e7c294c90e0b7096e42c Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 28 Jun 2011 13:45:12 -0700 Subject: [PATCH 44/59] remove typos and cosmetic changes --- mm/memory.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index efa3d5c6..11f6fdce 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -152,8 +152,8 @@ int mmu_init(void) } } #elif defined(CONFIG_ROCKCREEK) - /* of course, the first slot belongs to the private memory */ - for(addr=0x00; addr<0x1000000; addr+=PAGE_SIZE) { + /* of course, the first twenty slots belong to the private memory */ + for(addr=0x00; addr<20*0x1000000; addr+=PAGE_SIZE) { page_clear_mark(addr >> PAGE_SHIFT); if (addr > addr + PAGE_SIZE) break; @@ -161,6 +161,15 @@ int mmu_init(void) atomic_int32_inc(&total_available_pages); } + // Note: The last slot belongs always to the private memory. + for(addr=0xFF000000; addr<0xFFFFFFFF; addr+=PAGE_SIZE) { + page_clear_mark(addr >> PAGE_SHIFT); + if (addr > addr + PAGE_SIZE) + break; + atomic_int32_inc(&total_pages); + atomic_int32_inc(&total_available_pages); + } + /* * Mark the bootinfo as used. */ @@ -201,8 +210,8 @@ int mmu_init(void) #ifdef CONFIG_ROCKCREEK /* - * Now, we are able to read the FPGA register and to - * determin the number of slots. + * Now, we are able to read the FPGA registers and to + * determine the number of slots for private memory. */ uint32_t slots = *((volatile uint32_t*) (FPGA_BASE + 0x8244)); if (slots == 0) @@ -210,17 +219,8 @@ int mmu_init(void) kprintf("MetalSVM use %d slots for private memory\n", slots); - // define all the private slots as free - for(addr=0x1000000; addr<(slots-1)*0x1000000; addr+=PAGE_SIZE) { - page_clear_mark(addr >> PAGE_SHIFT); - if (addr > addr + PAGE_SIZE) - break; - atomic_int32_inc(&total_pages); - atomic_int32_inc(&total_available_pages); - } - - // Note: The last slot belongs always to the private memory. - for(addr=0xFF000000; addr<0xFFFFFFFF; addr+=PAGE_SIZE) { + // define the residual private slots as free + for(addr=20*0x1000000; addr<(slots-1)*0x1000000; addr+=PAGE_SIZE) { page_clear_mark(addr >> PAGE_SHIFT); if (addr > addr + PAGE_SIZE) break; From 11e25ee5c879948fb680553390c994a2624f1b24 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Tue, 28 Jun 2011 23:39:40 -0700 Subject: [PATCH 45/59] fix copy/paste failure, Simon has written the mailbox system => fix failure in copyright statement --- arch/x86/scc/iRCCE_mailbox.c | 55 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index e23bceb1..ae3132cb 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -1,31 +1,30 @@ -//****************************************************************************** -// Mailbox system. -//****************************************************************************** -// -// Author: Rob F. Van der Wijngaart -// Intel Corporation -// Date: 008/30/2010 -// -//****************************************************************************** -// -// Copyright 2010 Intel Corporation -// -// 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. -// -// [2011-05-08] implemented mailbox send/recv routines -// by Simon Pickartz, Chair for Operating Systems, -// RWTH Aachen University -// +/* + * Copyright 2011 Simon Pickartz, 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. + */ + +/* + * Mailbox system + * + * [2011-05-08] implemented mailbox send/recv routines + * by Simon Pickartz, Chair for Operating Systems, + * RWTH Aachen University + */ + #include #include From de216756d1c9d2655748b725261c261d91e60085 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 29 Jun 2011 12:29:04 -0700 Subject: [PATCH 46/59] move mailbox example to tests.c --- kernel/Makefile | 2 +- kernel/mailbox.c | 42 ------------------------------------------ kernel/main.c | 7 +++---- kernel/tests.c | 12 +++++------- 4 files changed, 9 insertions(+), 54 deletions(-) delete mode 100644 kernel/mailbox.c diff --git a/kernel/Makefile b/kernel/Makefile index f70f6a77..fdddee71 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c mailbox.c +C_source := main.c tasks.c syscall.c tests.c echo.c ping.c init.c MODULE := kernel include $(TOPDIR)/Makefile.inc diff --git a/kernel/mailbox.c b/kernel/mailbox.c deleted file mode 100644 index c790f984..00000000 --- a/kernel/mailbox.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010 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 -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_ROCKCREEK -#include - -int STDCALL mail_ping(void* arg) { - icc_mail_ping(); - - return 0; -} - -int mailbox_test_init(void) -{ - create_kernel_task(NULL, mail_ping, NULL); - - return 0; -} -#endif diff --git a/kernel/main.c b/kernel/main.c index 91e3c1ea..566ff932 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -35,7 +35,7 @@ #endif extern int test_init(void); -extern int mailbox_test_init(void); + /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. @@ -112,11 +112,10 @@ int main(void) sleep(5); list_root(); -// test_init(); - mailbox_test_init(); + test_init(); per_core(current_task)->status = TASK_IDLE; reschedule(); - while(1); + while(1) { #ifdef CONFIG_ROCKCREEK icc_halt(); diff --git a/kernel/tests.c b/kernel/tests.c index 1fbc7a48..ad600b3e 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -87,13 +87,13 @@ static int STDCALL foo(void* arg) } #ifdef CONFIG_ROCKCREEK -static int STDCALL ping(void* arg) -{ +int STDCALL mail_ping(void* arg) { int i; for(i=0; i<20; i++) { - icc_ping(1); - HALT; + icc_mail_ping(); + //icc_halt(); + udelay(500000); } return 0; @@ -117,8 +117,6 @@ static int STDCALL join_test(void* arg) return 0; } -void ping_send_now(); - int test_init(void) { char* argv[] = {"/bin/tests", NULL}; @@ -131,7 +129,7 @@ int test_init(void) //create_kernel_task(NULL, join_test, NULL); //create_kernel_task(NULL, producer, NULL); //create_kernel_task(NULL, consumer, NULL); - //create_kernel_task(NULL, ping, NULL); + //create_kernel_task(NULL, mail_ping, NULL); //create_user_task(NULL, "/bin/hello", argv); create_user_task(NULL, "/bin/tests", argv); //create_user_task(NULL, "/bin/jacobi", argv); From e1d3ac2ec5e43482f73648823fab67145caae42f Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 29 Jun 2011 12:31:32 -0700 Subject: [PATCH 47/59] remove obsolete code & minor optimizations --- arch/x86/include/asm/icc.h | 7 ++- arch/x86/scc/iRCCE_isend.c | 28 ++------- arch/x86/scc/icc.c | 122 +++---------------------------------- include/metalsvm/tasks.h | 1 - 4 files changed, 17 insertions(+), 141 deletions(-) diff --git a/arch/x86/include/asm/icc.h b/arch/x86/include/asm/icc.h index b02be40e..e2197326 100644 --- a/arch/x86/include/asm/icc.h +++ b/arch/x86/include/asm/icc.h @@ -45,16 +45,17 @@ typedef struct { uint32_t length; } icc_header_t; +/* #define ICC_TYPE_IP (1 << 0) #define ICC_TYPE_SVM (1 << 1) #define ICC_TYPE_PINGREQUEST (1 << 2) #define ICC_TYPE_PINGRESPONSE (1 << 3) +*/ int icc_init(void); -int icc_ping(int ue); -void icc_check(void); -void icc_mail_check(void); int icc_halt(void); +int icc_send_irq(int ue); +void icc_mail_check(void); int icc_mail_ping(void); #endif diff --git a/arch/x86/scc/iRCCE_isend.c b/arch/x86/scc/iRCCE_isend.c index 51cde3eb..042de0ce 100644 --- a/arch/x86/scc/iRCCE_isend.c +++ b/arch/x86/scc/iRCCE_isend.c @@ -34,6 +34,8 @@ // [2010-12-09] added cancel functions for non-blocking send/recv requests // by Carsten Clauss // +// [2011-06-29] added the support of using IPIs +// by Simon Pickartz, Stefan Lankes #include #include @@ -42,27 +44,7 @@ #include #include -static int send_irq(int ue) { - int tmp, x, y, z, addr; - - 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; - - -} - +#include static int iRCCE_push_send_request(iRCCE_SEND_REQUEST *request) { @@ -264,7 +246,7 @@ int iRCCE_isend( 0, privbuf, dest ); NOP8; NOP8; - send_irq( dest ); + icc_send_irq( dest ); return iRCCE_SUCCESS; } // we need an extra isend-call @@ -273,7 +255,7 @@ int iRCCE_isend( 0, NULL, dest ); NOP8; NOP8; - send_irq( dest ); + icc_send_irq( dest ); return iRCCE_isend_general( privbuf, send_size, dest, request ); } diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index ca2bd9b4..b2a517b9 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -160,14 +160,14 @@ int icc_init(void) SetConfigReg(CRB_OWN + (z==0 ? GLCFG0 : GLCFG1), tmp); // set interrupt handler (INTR/LINT0) - //irq_install_handler(124, intr_handler); + irq_install_handler(124, intr_handler); kputs("Now, the SCC is initialized!\n"); return 0; } -static inline int icc_send_irq(int ue) +int icc_send_irq(int ue) { int tmp, x, y, z, addr; @@ -196,60 +196,24 @@ int icc_halt(void) // iRCCE is not thread save => disable interrupts flags = irq_nested_disable(); - if (do_send) + if (do_send) { do_send = (iRCCE_isend_push() == iRCCE_PENDING); - icc_check(); + iRCCE_irecv_push(); + } + icc_mail_check(); irq_nested_enable(flags); } while(do_send); - iRCCE_finalize(); - HALT; return 0; } -static volatile uint64_t ping_start = 0; -static icc_header_t ping_request = {ICC_TYPE_PINGREQUEST, 0, 0}; -static icc_header_t ping_response = {ICC_TYPE_PINGRESPONSE, 0, 0}; - -int icc_ping(int ue) -{ - uint32_t flags; - - if (BUILTIN_EXPECT(ue == my_ue, 0)) - return -EINVAL; - if (BUILTIN_EXPECT((ue < 0) || (ue >= num_ues), 0)) - return -EINVAL; - - while(ping_start) { - NOP8; - } - - ping_start = rdtsc(); - - // iRCCE is not thread save => disable interrupts - flags = irq_nested_disable(); - - iRCCE_isend((char*) &ping_request, sizeof(icc_header_t), ue, NULL); - - // wait some time - NOP8; - - // wake up receiver - icc_send_irq(ue); - - irq_nested_enable(flags); - - return 0; -} - #define MAIL_MSG_SIZE 20 int icc_mail_ping( void ) -{ - +{ uint32_t flags; uint64_t timer; int remote_rank = (my_ue+1)%2; @@ -288,78 +252,9 @@ int icc_mail_ping( void ) kprintf( "Response didn't arrive!\n" ); } - - irq_nested_enable(flags); return 0; - -} - -static void interpret_header(icc_header_t* header, int recv_ue) -{ - //kprintf("Got ICC message %d from %d\n", header->type, recv_ue); - - switch(header->type) - { - case ICC_TYPE_PINGREQUEST: { - - iRCCE_isend((char*) &ping_response, sizeof(icc_header_t), recv_ue, NULL); - - // wait some time - NOP8; - - // wake up remote core - icc_send_irq(recv_ue); - } - break; - case ICC_TYPE_PINGRESPONSE: - kprintf("Receive ping response. Ticks: %d\n", rdtsc()-ping_start); - ping_start = 0; - break; - default: - kprintf("Receive unknown ICC message (%d)\n", header->type); - } -} - -/* - * By entering this function, interrupts are already disables - * => No race by using the static variables - */ -void icc_check(void) -{ - static icc_header_t header[MAX_SCC_CORES]; - static iRCCE_RECV_REQUEST request[MAX_SCC_CORES]; - static int8_t first_call = 1; - int i, ret; - - if (first_call) { - first_call = 0; - - for(i=0; i Date: Thu, 30 Jun 2011 14:16:55 +0200 Subject: [PATCH 48/59] add missing delays --- lwip/src/arch/sys_arch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lwip/src/arch/sys_arch.c b/lwip/src/arch/sys_arch.c index ca3b15d4..2eef4727 100644 --- a/lwip/src/arch/sys_arch.c +++ b/lwip/src/arch/sys_arch.c @@ -141,6 +141,7 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) err = sem_trywait(&sem->sem); if (err != -1) return err; + udelay(1000); timeout--; } return SYS_ARCH_TIMEOUT; @@ -167,6 +168,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t * mbox, void **msg, u32_t timeout) { if (!mailbox_ptr_tryfetch(&mbox->mailbox,msg)) return 0; + udelay(1000); timeout--; } From 86b1d02945943de2b1d0e557befd312185717f48 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 30 Jun 2011 12:11:58 -0700 Subject: [PATCH 49/59] remove obsolete lines --- arch/x86/include/asm/icc.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/x86/include/asm/icc.h b/arch/x86/include/asm/icc.h index e2197326..cb806761 100644 --- a/arch/x86/include/asm/icc.h +++ b/arch/x86/include/asm/icc.h @@ -39,12 +39,6 @@ typedef struct { extern bootinfo_t* bootinfo; -typedef struct { - uint8_t type; - uint8_t tag; - uint32_t length; -} icc_header_t; - /* #define ICC_TYPE_IP (1 << 0) #define ICC_TYPE_SVM (1 << 1) From fec9f9cfe11a2b4038b655078cd66aea43306a0e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 30 Jun 2011 12:26:16 -0700 Subject: [PATCH 50/59] switch back to the ping example - use RAW interface - cut the timer debug messages --- kernel/init.c | 2 +- kernel/ping.c | 4 ---- kernel/tests.c | 6 ++++++ lwip/src/include/lwipopts.h | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index 17b31c37..2f9b883f 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -116,7 +116,7 @@ int STDCALL network_task(void* arg) // start echo and ping server echo_init(); - //ping_init(); + ping_init(); while(!done) { #ifdef CONFIG_PCI diff --git a/kernel/ping.c b/kernel/ping.c index 98398300..6d8433a7 100644 --- a/kernel/ping.c +++ b/kernel/ping.c @@ -53,10 +53,6 @@ #include #include -#if LWIP_SOCKET -#define PING_USE_SOCKETS 1 -#endif - #if PING_USE_SOCKETS #include #include diff --git a/kernel/tests.c b/kernel/tests.c index ad600b3e..9ef0a393 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -117,6 +117,8 @@ static int STDCALL join_test(void* arg) return 0; } +void ping_send_now(); + int test_init(void) { char* argv[] = {"/bin/tests", NULL}; @@ -125,6 +127,10 @@ int test_init(void) sem_init(&consuming, 0); mailbox_int32_init(&mbox); +#ifdef CONFIG_LWIP + ping_send_now(); +#endif + create_kernel_task(NULL, foo, "Hello from foo1\n"); //create_kernel_task(NULL, join_test, NULL); //create_kernel_task(NULL, producer, NULL); diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index af8d018c..5ef66a0b 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -95,6 +95,6 @@ #define IP_DEBUG LWIP_DBG_OFF #define INET_DEBUG LWIP_DBG_OFF #define NETIF_DEBUG LWIP_DBG_ON -#define TIMERS_DEBUG LWIP_DBG_ON +#define TIMERS_DEBUG LWIP_DBG_OFF #endif From 32a36c5e6eb113e80089334a5a33762850efa0c1 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 2 Jul 2011 00:28:41 -0700 Subject: [PATCH 51/59] disable ping example --- kernel/init.c | 2 +- kernel/ping.c | 1 + kernel/tests.c | 2 +- lwip/src/include/lwipopts.h | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index 2f9b883f..17b31c37 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -116,7 +116,7 @@ int STDCALL network_task(void* arg) // start echo and ping server echo_init(); - ping_init(); + //ping_init(); while(!done) { #ifdef CONFIG_PCI diff --git a/kernel/ping.c b/kernel/ping.c index 6d8433a7..da707c3f 100644 --- a/kernel/ping.c +++ b/kernel/ping.c @@ -201,6 +201,7 @@ ping_thread(void *arg) LWIP_UNUSED_ARG(arg); if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { + LWIP_DEBUGF( PING_DEBUG, ("ping: invalid socket\n")); return; } diff --git a/kernel/tests.c b/kernel/tests.c index 9ef0a393..bea18b65 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -128,7 +128,7 @@ int test_init(void) mailbox_int32_init(&mbox); #ifdef CONFIG_LWIP - ping_send_now(); + //ping_send_now(); #endif create_kernel_task(NULL, foo, "Hello from foo1\n"); diff --git a/lwip/src/include/lwipopts.h b/lwip/src/include/lwipopts.h index 5ef66a0b..4a23eb71 100644 --- a/lwip/src/include/lwipopts.h +++ b/lwip/src/include/lwipopts.h @@ -89,12 +89,13 @@ #define DHCP_DEBUG LWIP_DBG_OFF #define ETHARP_DEBUG LWIP_DBG_OFF #define TCPIP_DEBUG LWIP_DBG_OFF -#define SYS_DEBUG LWIP_DBG_ON +#define SYS_DEBUG LWIP_DBG_OFF #define RAW_DEBUG LWIP_DBG_OFF #define MEM_DEBUG LWIP_DBG_OFF #define IP_DEBUG LWIP_DBG_OFF #define INET_DEBUG LWIP_DBG_OFF #define NETIF_DEBUG LWIP_DBG_ON #define TIMERS_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF #endif From 4b3efa14a324e6dfa2c482dd29cb2ba544f9b9f2 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 2 Jul 2011 03:10:07 -0700 Subject: [PATCH 52/59] add Simon's patch --- arch/x86/scc/iRCCE_mailbox.c | 146 +++++++++++++++++++++++++++++++---- 1 file changed, 132 insertions(+), 14 deletions(-) diff --git a/arch/x86/scc/iRCCE_mailbox.c b/arch/x86/scc/iRCCE_mailbox.c index ae3132cb..257a12c9 100644 --- a/arch/x86/scc/iRCCE_mailbox.c +++ b/arch/x86/scc/iRCCE_mailbox.c @@ -28,19 +28,31 @@ #include #include - #ifdef CONFIG_ROCKCREEK #include +/** + * + * @file contains implementation of the mailbox system + * @author Simon Pickartz + * + * + */ + + // forward declaration static int iRCCE_mailbox_close_one(int rank, int check); - //------------------------------------------------------------------------------ // FUNCTION: iRCCE_mailbox_print_header //------------------------------------------------------------------------------ // routine for printing given header (debugging purpose) //------------------------------------------------------------------------------ +/** + * @brief routine for printing a given header + * @param header is a pointer to a given iRCCE_MAIL_HEADER structure +*/ + void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) { kprintf( "\n" @@ -59,9 +71,20 @@ void iRCCE_mailbox_print_header(iRCCE_MAIL_HEADER* header) { } //------------------------------------------------------------------------------ -// FUNCTION: iRCCE_mailbox_enqueue_header +// FUNCTION: iRCCE_mail_fetch //------------------------------------------------------------------------------ -// routine to put push received header into iRCCE_mailbox_recv_queue +/** + * @brief routine to check for new mail in a given mailbox + * @param rank is the ID of the ranks mailbox to be emptied + * + * The function checks if the mailbox has new mail for a given rank. In case of + * new mail it needs memory for the received header. Either there is memory + * in the internal garbage collection or it has to allocated. The next step is + * to check wheter a last-mail was received or a normal one. A last-mail is + * indicated by the iRCCE_LAST_MAIL tag. A last-mail entails the appropriate + * flag in the iRCCE_last_mail array to be set. Otherwise the header has to be + * enqueued in the mailbox_recv_queue accordingly to the priority field. + */ //------------------------------------------------------------------------------ static int iRCCE_mail_fetch( int rank // rank from whom to empty mailbox @@ -119,12 +142,23 @@ static int iRCCE_mail_fetch( //------------------------------------------------------------------------------ // FUNCTION: iRCCE_mailbox_check //------------------------------------------------------------------------------ -// routine to check for new mail in mailboxes +/** + * @brief routine to check for new mail in mailboxes + * + * This function has to be called from time to time. It empties all mailboxes of + * the participating cores if the corresponding sent-flag is set and the mailbox + * is not closed. After calling iRCCE_mail_fetch the sent-flag has to be reset. + * Here we have to use a little trick because we can only write to the MPB in + * cacheline granularity. We set the appropriate flag to zero and afterwords + * touch the MPB on another cacheline. That causes the write combine buffer to + * write out the data. + */ //------------------------------------------------------------------------------ static int iRCCE_mailbox_check() { int i; for( i=0; i Date: Sat, 2 Jul 2011 03:13:24 -0700 Subject: [PATCH 53/59] fine tuning to increase the performance of the mailbox example --- arch/x86/include/asm/icc.h | 10 +++--- arch/x86/kernel/processor.c | 3 ++ arch/x86/scc/icc.c | 61 +++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/icc.h b/arch/x86/include/asm/icc.h index cb806761..9cca3390 100644 --- a/arch/x86/include/asm/icc.h +++ b/arch/x86/include/asm/icc.h @@ -39,12 +39,10 @@ typedef struct { extern bootinfo_t* bootinfo; -/* -#define ICC_TYPE_IP (1 << 0) -#define ICC_TYPE_SVM (1 << 1) -#define ICC_TYPE_PINGREQUEST (1 << 2) -#define ICC_TYPE_PINGRESPONSE (1 << 3) -*/ +#define ICC_TAG_IP 0 +#define ICC_TAG_SVM 1 +#define ICC_TAG_PINGREQUEST 2 +#define ICC_TAG_PINGRESPONSE 3 int icc_init(void); int icc_halt(void); diff --git a/arch/x86/kernel/processor.c b/arch/x86/kernel/processor.c index 4210c38f..93e5f540 100644 --- a/arch/x86/kernel/processor.c +++ b/arch/x86/kernel/processor.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_ROCKCREEK #include #endif @@ -104,6 +105,8 @@ void udelay(uint32_t usecs) mb(); end = rdtsc(); diff = end > start ? end - start : start - end; + if ((diff < deadline) && (deadline - diff > 50000)) + check_workqueues(); } while(diff < deadline); } diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index b2a517b9..963eabc3 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -203,27 +203,25 @@ int icc_halt(void) icc_mail_check(); irq_nested_enable(flags); + + NOP1; } while(do_send); - HALT; + //HALT; return 0; } #define MAIL_MSG_SIZE 20 +uint64_t timer; int icc_mail_ping( void ) { uint32_t flags; - uint64_t timer; int remote_rank = (my_ue+1)%2; - char send_buffer[MAIL_MSG_SIZE]; - int length = MAIL_MSG_SIZE; - - if( my_ue ) { - return 0; - } + if (my_ue) + return -1; kprintf( "Hello from mail_ping ... \n" ); @@ -233,25 +231,16 @@ int icc_mail_ping( void ) // start timer timer = rdtsc(); - // start anylength send - iRCCE_isend( send_buffer, -length, remote_rank, NULL ); + /* send ping request */ + iRCCE_mail_send(0, ICC_TAG_PINGREQUEST, 0, NULL, remote_rank); - // wait for response - iRCCE_MAIL_HEADER* mail; - do { - iRCCE_mail_recv( &mail ); - } while( !mail ); - - // stop timer - timer = rdtsc() - timer; + NOP8; + icc_send_irq(remote_rank); - if( mail->tag == 2 ) { - kprintf( "Response received in %d ticks!\n", timer ); - } - else { - kprintf( "Response didn't arrive!\n" ); - } + /* check for incoming messages */ + icc_mail_check(); + // enable interrupts irq_nested_enable(flags); return 0; @@ -261,21 +250,33 @@ void icc_mail_check(void) { iRCCE_MAIL_HEADER* header = NULL; int res; - char* recv_buffer; + //char* recv_buffer; // empty mailbox and interpret headers while( (res = iRCCE_mail_recv( &header )) == iRCCE_SUCCESS ) { - if( header->tag == 1 ) { - iRCCE_mail_send( 0, 2, 0, NULL, header->source ); - } - else if( header->tag == iRCCE_ANYLENGTH ) { + switch(header->tag) + { + case ICC_TAG_PINGREQUEST: + iRCCE_mail_send( 0, ICC_TAG_PINGRESPONSE, 0, NULL, header->source ); + NOP8; + icc_send_irq( header->source ); + break; + case ICC_TAG_PINGRESPONSE: + timer = rdtsc() - timer; + kprintf( "Response received in %d ticks!\n", timer ); + break; + default: + kprintf("Invalid mail: tag = %d\n", header->tag); + break; + } + /*else if( header->tag == iRCCE_ANYLENGTH ) { recv_buffer = (char*)kmalloc( header->size ); iRCCE_irecv( recv_buffer, header->size, header->source, NULL ); iRCCE_mail_send( 0, 2, 0, NULL, header->source ); } else if( header->tag == iRCCE_ANYLENGTH_PIGGYBACK ) { iRCCE_mail_send( 0, 2, 0, NULL, header->source ); - } + }*/ iRCCE_mail_release( &header ); } From e5c0e2b037a2354d095e1a325019cebb9221bbe1 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 2 Jul 2011 03:40:08 -0700 Subject: [PATCH 54/59] integrate the timer values of the icc ping example in the payload of the mailbox header => remove some static variables --- arch/x86/scc/icc.c | 14 +++++++------- kernel/tests.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index 963eabc3..e3057706 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -212,13 +212,12 @@ int icc_halt(void) return 0; } -#define MAIL_MSG_SIZE 20 -uint64_t timer; - int icc_mail_ping( void ) { uint32_t flags; int remote_rank = (my_ue+1)%2; + uint8_t payload[iRCCE_MAIL_HEADER_PAYLOAD]; + uint64_t* timer = (uint64_t*) payload; if (my_ue) return -1; @@ -229,10 +228,10 @@ int icc_mail_ping( void ) flags = irq_nested_disable(); // start timer - timer = rdtsc(); + *timer = rdtsc(); /* send ping request */ - iRCCE_mail_send(0, ICC_TAG_PINGREQUEST, 0, NULL, remote_rank); + iRCCE_mail_send(sizeof(uint64_t), ICC_TAG_PINGREQUEST, 0, payload, remote_rank); NOP8; icc_send_irq(remote_rank); @@ -250,6 +249,7 @@ void icc_mail_check(void) { iRCCE_MAIL_HEADER* header = NULL; int res; + uint64_t timer; //char* recv_buffer; // empty mailbox and interpret headers @@ -257,12 +257,12 @@ void icc_mail_check(void) switch(header->tag) { case ICC_TAG_PINGREQUEST: - iRCCE_mail_send( 0, ICC_TAG_PINGRESPONSE, 0, NULL, header->source ); + iRCCE_mail_send( header->size, ICC_TAG_PINGRESPONSE, 0, header->payload, header->source ); NOP8; icc_send_irq( header->source ); break; case ICC_TAG_PINGRESPONSE: - timer = rdtsc() - timer; + timer = rdtsc() - *((uint64_t*) header->payload); kprintf( "Response received in %d ticks!\n", timer ); break; default: diff --git a/kernel/tests.c b/kernel/tests.c index bea18b65..72d16abb 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -91,8 +91,8 @@ int STDCALL mail_ping(void* arg) { int i; for(i=0; i<20; i++) { - icc_mail_ping(); - //icc_halt(); + if (BUILTIN_EXPECT(icc_mail_ping(), 0)) + return -1; udelay(500000); } From e08f6a9d530149b872ae403f5a372fd04b077e3d Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 2 Jul 2011 13:04:26 -0700 Subject: [PATCH 55/59] add UART support --- arch/x86/include/asm/io.h | 5 +++++ include/metalsvm/config.h.example | 1 + libkern/stdio.c | 14 +++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 8443ec0a..8765b7cc 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -93,6 +93,11 @@ inline static void outportl(unsigned short _port, unsigned int _data) asm volatile("outl %1, %0"::"dN"(_port), "a"(_data)); } +inline static void uart_putchar(unsigned char _data) +{ + outportb(0x2F8, _data); +} + #ifdef __cplusplus } #endif diff --git a/include/metalsvm/config.h.example b/include/metalsvm/config.h.example index 34a2717a..a9e94864 100644 --- a/include/metalsvm/config.h.example +++ b/include/metalsvm/config.h.example @@ -52,6 +52,7 @@ extern "C" { #define CONFIG_PCI #define CONFIG_LWIP #define CONFIG_VGA +//#define CONFIG_UART #define CONFIG_KEYBOARD #define CONFIG_MULTIBOOT //#define CONFIG_ROCKCREEK diff --git a/libkern/stdio.c b/libkern/stdio.c index a8bdc9de..281fe11d 100644 --- a/libkern/stdio.c +++ b/libkern/stdio.c @@ -24,15 +24,19 @@ #include #include #include +#include #ifdef CONFIG_VGA #include #endif #define NO_EARLY_PRINT 0 #define VGA_EARLY_PRINT 1 +#define UART_EARLY_PRINT 2 #ifdef CONFIG_VGA static uint32_t early_print = VGA_EARLY_PRINT; +#elif defined(CONFIG_UART) +static uint32_t early_print = UART_EARLY_PRINT; #else static uint32_t early_print = NO_EARLY_PRINT; #endif @@ -56,8 +60,12 @@ int kputchar(int c) kmessages[pos % KMSG_SIZE] = (unsigned char) c; #ifdef CONFIG_VGA if (early_print == VGA_EARLY_PRINT) - vga_putchar(c); + vga_putchar(c); #endif +#ifdef CONFIG_UART + if (early_print == UART_EARLY_PRINT) + uart_putchar(c); +#endif return 1; } @@ -73,6 +81,10 @@ int kputs(const char *str) #ifdef CONFIG_VGA if (early_print == VGA_EARLY_PRINT) vga_putchar(str[i]); +#endif +#ifdef CONFIG_UART + if (early_print == UART_EARLY_PRINT) + uart_putchar(str[i]); #endif } From 351a0f6391092a3fe6ae1156871f5c3c22bd9a94 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 3 Jul 2011 02:31:40 -0700 Subject: [PATCH 56/59] remove obsolete iRCCE_*_push --- arch/x86/scc/icc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/scc/icc.c b/arch/x86/scc/icc.c index e3057706..d5d660cb 100644 --- a/arch/x86/scc/icc.c +++ b/arch/x86/scc/icc.c @@ -190,6 +190,7 @@ int icc_send_irq(int ue) int icc_halt(void) { uint32_t flags; +#if 0 uint32_t do_send = 1; do { @@ -206,7 +207,13 @@ int icc_halt(void) NOP1; } while(do_send); - +#else + // iRCCE is not thread save => disable interrupts + flags = irq_nested_disable(); + icc_mail_check(); + irq_nested_enable(flags); + NOP1; +#endif //HALT; return 0; From 0fe5027a63721763ec698adbf64e776e6683a7dc Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 4 Jul 2011 10:51:30 -0700 Subject: [PATCH 57/59] if LwIP supports sockets, the ping example will switch to the socket interface --- kernel/ping.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel/ping.c b/kernel/ping.c index da707c3f..46951113 100644 --- a/kernel/ping.c +++ b/kernel/ping.c @@ -43,7 +43,7 @@ #include #include -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ +#if LWIP_RAW || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ #include #include @@ -53,6 +53,10 @@ #include #include +#if LWIP_SOCKET +#define PING_USE_SOCKETS 1 +#endif + #if PING_USE_SOCKETS #include #include @@ -194,7 +198,7 @@ ping_recv(int s) static void ping_thread(void *arg) { - int s; + int s, i; int timeout = PING_RCV_TIMEO; ip_addr_t ping_target; @@ -207,7 +211,7 @@ ping_thread(void *arg) lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - while (1) { + for(i=0; i<10; i++) { ping_target = PING_TARGET; if (ping_send(s, &ping_target) == ERR_OK) { @@ -224,6 +228,8 @@ ping_thread(void *arg) } sys_msleep(PING_DELAY); } + + lwip_close(s); } #else /* PING_USE_SOCKETS */ From f48c738d8e02ec20b89ac5a8d99bc4a73bbaf1a3 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 4 Jul 2011 10:52:30 -0700 Subject: [PATCH 58/59] fix bug in the initialization of LwIP --- kernel/init.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/init.c b/kernel/init.c index 17b31c37..29885661 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -116,7 +117,7 @@ int STDCALL network_task(void* arg) // start echo and ping server echo_init(); - //ping_init(); + ping_init(); while(!done) { #ifdef CONFIG_PCI @@ -142,11 +143,16 @@ int network_shutdown(void) return 0; } +static void tcp_init_ok(void* e) +{ + kprintf("TCP/IP init COMPLETE!!"); +} + int network_init(void) { #if defined(CONFIG_LWIP) // Initialize lwIP modules - lwip_init(); + tcpip_init(tcp_init_ok, NULL); #endif #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) From 42b5542881c25f34df3feefaa42fe2b4777d3c8e Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Mon, 4 Jul 2011 10:53:34 -0700 Subject: [PATCH 59/59] don't longer use ping_send_now --- kernel/tests.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/tests.c b/kernel/tests.c index 72d16abb..8502d2aa 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -117,7 +117,9 @@ static int STDCALL join_test(void* arg) return 0; } +#ifdef CONFIG_LWIP void ping_send_now(); +#endif int test_init(void) { @@ -127,8 +129,8 @@ int test_init(void) sem_init(&consuming, 0); mailbox_int32_init(&mbox); -#ifdef CONFIG_LWIP - //ping_send_now(); +#if 0 + ping_send_now(); #endif create_kernel_task(NULL, foo, "Hello from foo1\n");