diff --git a/hermit/arch/x86/kernel/entry.asm b/hermit/arch/x86/kernel/entry.asm index 70648e3ac..f1ab648c1 100644 --- a/hermit/arch/x86/kernel/entry.asm +++ b/hermit/arch/x86/kernel/entry.asm @@ -57,6 +57,7 @@ align 4 global current_boot_id global isle global possible_isles + global phy_rcce_internals global phy_isle_locks global heap_phy_start_address global header_phy_start_address @@ -70,7 +71,7 @@ align 4 boot_processor dd -1 cpu_online dd 0 possible_cpus dd 0 - dq 0 ; reserved for future extensions + phy_rcce_internals dq 0 current_boot_id dd 0 isle dd -1 image_size dq 0 diff --git a/hermit/arch/x86/kernel/tasks.c b/hermit/arch/x86/kernel/tasks.c index 2b71c04fa..0b967e21c 100644 --- a/hermit/arch/x86/kernel/tasks.c +++ b/hermit/arch/x86/kernel/tasks.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -502,9 +503,16 @@ static int load_task(load_args_t* largs) page_map(START_ADDRESS - PAGE_SIZE, base, 1, PG_USER|PG_XD); else page_map(START_ADDRESS - PAGE_SIZE, base, 1, PG_USER); - //kprintf("Map kernel info: 0x%zx - 0x%xz\n", START_ADDRESS - PAGE_SIZE, START_ADDRESS - 1); + //kprintf("Map kernel info: 0x%zx - 0x%zx\n", START_ADDRESS - PAGE_SIZE, START_ADDRESS - 1); vma_add(START_ADDRESS - PAGE_SIZE, START_ADDRESS - 1, VMA_READ|VMA_CACHEABLE|VMA_USER); + if (has_nx()) + page_map(START_ADDRESS - 2*PAGE_SIZE, phy_rcce_internals, 1, PG_USER|PG_RW|PG_XD); + else + page_map(START_ADDRESS - 2*PAGE_SIZE, phy_rcce_internals, 1, PG_USER|PG_RW); + //kprintf("Map rcce info: 0x%zx - 0x%zx\n", START_ADDRESS - 2*PAGE_SIZE, START_ADDRESS - PAGE_SIZE - 1); + vma_add(START_ADDRESS - 2*PAGE_SIZE, START_ADDRESS - PAGE_SIZE - 11, VMA_READ|VMA_WRITE|VMA_CACHEABLE|VMA_USER); + //vma_dump(); enter_user_task(header.entry, stack+offset); diff --git a/hermit/drivers/net/mmnif.c b/hermit/drivers/net/mmnif.c index 818f33483..a4c6ea331 100644 --- a/hermit/drivers/net/mmnif.c +++ b/hermit/drivers/net/mmnif.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -213,45 +214,6 @@ typedef struct mmnif { sem_t com_poll; } mmnif_t; -typedef struct islelock { - /// Internal queue - atomic_int32_t queue; - /// Internal dequeue - atomic_int32_t dequeue; -} islelock_t; - -inline static int islelock_init(islelock_t* s) -{ - atomic_int32_set(&s->queue, 0); - atomic_int32_set(&s->dequeue, 1); - - return 0; -} - -inline static int islelock_destroy(islelock_t* s) -{ - return 0; -} - -static inline int islelock_lock(islelock_t* s) -{ - int ticket; - - ticket = atomic_int32_inc(&s->queue); - while(atomic_int32_read(&s->dequeue) != ticket) { - PAUSE; - } - - return 0; -} - -static inline int islelock_unlock(islelock_t* s) -{ - atomic_int32_inc(&s->dequeue); - - return 0; -} - // alread initialized by Linux static islelock_t* isle_locks = NULL; diff --git a/hermit/include/hermit/islelock.h b/hermit/include/hermit/islelock.h new file mode 100644 index 000000000..c56f8792e --- /dev/null +++ b/hermit/include/hermit/islelock.h @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Stefan Lankes, RWTH Aachen University + * All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2 (https://www.gnu.org/licenses/gpl-2.0.txt) + * or the BSD license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ISLELOCK_H__ +#define __ISLELOCK_H__ + +#include +#include + +typedef struct islelock { + /// Internal queue + atomic_int32_t queue; + /// Internal dequeue + atomic_int32_t dequeue; +} islelock_t; + +inline static int islelock_init(islelock_t* s) +{ + atomic_int32_set(&s->queue, 0); + atomic_int32_set(&s->dequeue, 1); + + return 0; +} + +inline static int islelock_destroy(islelock_t* s) +{ + return 0; +} + +static inline int islelock_lock(islelock_t* s) +{ + int ticket; + + ticket = atomic_int32_inc(&s->queue); + while(atomic_int32_read(&s->dequeue) != ticket) { + PAUSE; + } + + return 0; +} + +static inline int islelock_unlock(islelock_t* s) +{ + atomic_int32_inc(&s->dequeue); + + return 0; +} + +#endif diff --git a/hermit/include/hermit/rcce.h b/hermit/include/hermit/rcce.h new file mode 100644 index 000000000..96e4a2651 --- /dev/null +++ b/hermit/include/hermit/rcce.h @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Stefan Lankes, RWTH Aachen University + * All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2 (https://www.gnu.org/licenses/gpl-2.0.txt) + * or the BSD license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __RCCE_H__ +#define __RCCE_H__ + +#include +#include + +#define RCCE_MAXNP 8 + +typedef struct tas { + unsigned char reg; + unsigned char reserved[CACHE_LINE-1]; +} tas_t __attribute__ ((aligned (CACHE_LINE))); + +typedef struct rcce_mpb { + int id; // session id; + tas_t tas[RCCE_MAXNP]; + size_t mpb[MAX_ISLE]; +} rcce_mpb_t; + +#define MAX_RCCE_SESSIONS ((PAGE_SIZE - CACHE_LINE*(RCCE_MAXNP+1)) / sizeof(rcce_mpb_t)) + +extern islelock_t* rcce_lock; +extern rcce_mpb_t* rcce_mpb; +extern uint64_t phy_rcce_internals; + +#endif diff --git a/hermit/include/hermit/syscall.h b/hermit/include/hermit/syscall.h index 9717efa4b..341720d4d 100644 --- a/hermit/include/hermit/syscall.h +++ b/hermit/include/hermit/syscall.h @@ -86,6 +86,9 @@ extern "C" { #define __NR_clone 41 #define __NR_sem_cancelablewait 42 #define __NR_get_ticks 43 +#define __NR_rcce_init 44 +#define __NR_rcce_fini 45 +#define __NR_rcce_malloc 46 #ifdef __cplusplus } diff --git a/hermit/kernel/main.c b/hermit/kernel/main.c index e54b0719a..c3201dfd7 100644 --- a/hermit/kernel/main.c +++ b/hermit/kernel/main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,9 @@ extern atomic_int32_t possible_cpus; extern int32_t isle; extern int32_t possible_isles; +islelock_t* rcce_lock = NULL; +rcce_mpb_t* rcce_mpb = NULL; + #if 0 static int foo(void* arg) { @@ -216,6 +220,24 @@ int smp_main(void) } #endif +static int init_rcce(void) +{ + size_t addr; + + addr = vma_alloc(PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE); + if (BUILTIN_EXPECT(!addr, 0)) + return -ENOMEM; + if (page_map(addr, phy_rcce_internals, 1, PG_GLOBAL|PG_RW)) { + vma_free(addr, addr + PAGE_SIZE); + return -ENOMEM; + } + + rcce_lock = (islelock_t*) addr; + rcce_mpb = (rcce_mpb_t*) (addr + CACHE_LINE*(RCCE_MAXNP+1)); + + return 0; +} + // init task => creates all other tasks an initialize the LwIP static int initd(void* arg) { @@ -237,6 +259,7 @@ static int initd(void* arg) //create_user_task(NULL, "/bin/thr_hello", argv4, NORMAL_PRIO); init_netifs(); + init_rcce(); s = socket(PF_INET , SOCK_STREAM , 0); if (s < 0) { diff --git a/hermit/kernel/syscall.c b/hermit/kernel/syscall.c index 91811c221..b6d9fca4f 100644 --- a/hermit/kernel/syscall.c +++ b/hermit/kernel/syscall.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,9 @@ //TODO: don't use one big kernel lock to comminicate with all proxies static spinlock_t lwip_lock = SPINLOCK_INIT; +extern int32_t isle; +extern int32_t possible_isles; + static tid_t sys_getpid(void) { task_t* task = per_core(current_task); @@ -384,6 +389,134 @@ static off_t sys_lseek(int fd, off_t offset, int whence) return off; } +static int sys_rcce_init(int session_id) +{ + int i, err = 0; + size_t paddr = 0; + + if (session_id <= 0) + return -EINVAL; + + islelock_lock(rcce_lock); + + for(i=0; i=MAX_RCCE_SESSIONS) + { + for(i=0; i= MAX_RCCE_SESSIONS) + { + err = -EINVAL; + goto out; + } + + paddr = get_pages(2); + if (BUILTIN_EXPECT(!paddr, 0)) + { + err = -ENOMEM; + goto out; + } + + rcce_mpb[i].mpb[isle] = paddr; + +out: + islelock_unlock(rcce_lock); + + kprintf("Create MPB for session %d at 0x%zx, using of slot %d\n", session_id, paddr, i); + + return err; +} + +static size_t sys_rcce_malloc(int session_id, int ue) +{ + size_t vaddr = 0; + int i; + + if (session_id <= 0) + return -EINVAL; + + for(i=0; i= MAX_RCCE_SESSIONS) + goto out; + + if (!rcce_mpb[i].mpb[ue]) + goto out; + + + vaddr = vma_alloc(2*PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_USER|VMA_CACHEABLE); + if (BUILTIN_EXPECT(!vaddr, 0)) + goto out; + + if (page_map(vaddr, rcce_mpb[i].mpb[ue], 2, PG_RW|PG_USER|PG_PRESENT)) { + vma_free(vaddr, vaddr + 2*PAGE_SIZE); + goto out; + } + + kprintf("Map MPB of session %d at 0x%zx, using of slot %d, isle %d\n", session_id, vaddr, i, ue); + +out: + return vaddr; +} + +static int sys_rcce_fini(int session_id) +{ + int i, j; + int ret = 0; + + // we have to free the MPB + + if (session_id <= 0) + return -EINVAL; + + islelock_lock(rcce_lock); + + for(i=0; i= MAX_RCCE_SESSIONS) { + ret = -EINVAL; + goto out; + } + + if (rcce_mpb[i].mpb[isle]) + put_pages(rcce_mpb[i].mpb[isle], 2); + rcce_mpb[i].mpb[isle] = 0; + + for(j=0; (j= MAX_ISLE) + rcce_mpb[i].id = 0; + +out: + islelock_unlock(rcce_lock); + + return ret; +} + static size_t sys_get_ticks(void) { return get_clock_tick(); @@ -446,5 +579,8 @@ size_t syscall_table[] = { (size_t) default_handler, /* __NR_setprio */ (size_t) sys_clone, /* __NR_clone */ (size_t) sys_sem_timedwait, /* __NR_sem_cancelablewait */ - (size_t) sys_get_ticks /* __NR_get_ticks */ + (size_t) sys_get_ticks, /* __NR_get_ticks */ + (size_t) sys_rcce_init, /* __NR_rcce_init */ + (size_t) sys_rcce_fini, /* __NR_rcce_fini */ + (size_t) sys_rcce_malloc /* __NR_rcce_malloc */ };