diff --git a/apps/tests.c b/apps/tests.c index e4d6c3b4..f83b24c6 100644 --- a/apps/tests.c +++ b/apps/tests.c @@ -114,8 +114,9 @@ static int mail_noise(void*arg) { return 0; } -#define N 1024 -//#define N 514 +//#define N 1024 +//#define N 512 +#define N 128 #define LAZY #define L2_ENABLE @@ -139,6 +140,8 @@ static int svm_test(void *arg) int my_ue, num_ues; register int tmp; + kputs("Start SVM test...\n"); + RCCE_barrier(&RCCE_COMM_WORLD); my_ue = RCCE_ue(); num_ues = RCCE_num_ues(); @@ -191,9 +194,13 @@ static int svm_test(void *arg) #ifdef LAZY svm_flags = SVM_LAZYRELEASE; + kputs("Use Lazy Release consistency!\n"); +#else + kputs("Use Strong Release consistency!\n"); #endif #ifdef L2_ENABLE + kputs("Use Level 2 Cache!\n"); svm_flags |= SVM_L2; #endif @@ -216,7 +223,7 @@ static int svm_test(void *arg) } } - svm_flush(); + svm_flush(0); RCCE_barrier(&RCCE_COMM_WORLD); kputs("Start parallel calculation...\n"); @@ -238,7 +245,7 @@ static int svm_test(void *arg) } } - svm_flush(); + svm_flush(0); RCCE_barrier(&RCCE_COMM_WORLD); end = rdtsc(); @@ -320,9 +327,9 @@ int test_init(void) char* server_argv[] = {"/bin/server", "6789", NULL}; char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL}; - sem_init(&producing, 1); - sem_init(&consuming, 0); - mailbox_int32_init(&mbox); + //sem_init(&producing, 1); + //sem_init(&consuming, 0); + //mailbox_int32_init(&mbox); //create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO); //create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO); @@ -330,7 +337,7 @@ int test_init(void) //create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO); //create_kernel_task(NULL, mail_ping, NULL, NORMAL_PRIO); //create_kernel_task(NULL, mail_noise, NULL, NORMAL_PRIO); - //create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO); + create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO); //create_kernel_task(NULL, pi, NULL, NORMAL_PRIO); create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO); //create_user_task(NULL, "/bin/hello", argv); diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 5d35ac53..349bca82 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -67,6 +67,7 @@ /// Pattern flag #define PG_PAT (1 << _PAGE_BIT_PAT) /// This virtual address range is used by SVM system as marked +#define PG_SVM PG_SVM_STRONG #define PG_SVM_STRONG (1 << _PAGE_BIT_SVM_STRONG) /// This virtual address range is used by SVM system as marked #define PG_SVM_LAZYRELEASE (1 << _PAGE_BIT_SVM_LAZYRELEASE) diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 0f741138..27ebc604 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -31,6 +31,8 @@ extern "C" { #ifdef CONFIG_ROCKCREEK +#define SVM_WB + #define SVM_STRONG (1 << 0) #define SVM_LAZYRELEASE (1 << 1) #define SVM_L2 (1 << 4) @@ -93,7 +95,7 @@ static inline void svm_flush(void) *(int *)RCCE_fool_write_combine_buffer = 1; } #else -void svm_flush(void); +void svm_flush(size_t addr); #endif #endif diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 1e86cb53..76936314 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -784,7 +784,7 @@ int arch_paging_init(void) kprintf("Map configuration registers at 0x%x\n", viraddr); // 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); + viraddr = map_region(MPB_X0_Y0, MPB_X0_Y0, (MPB_OWN-MPB_X0_Y0+64*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_MPE); kprintf("Map message passing buffers at 0x%x\n", viraddr); // map the FPGA registers diff --git a/arch/x86/mm/svm.c b/arch/x86/mm/svm.c index b685eaed..619704c0 100644 --- a/arch/x86/mm/svm.c +++ b/arch/x86/mm/svm.c @@ -51,7 +51,7 @@ static volatile atomic_increg_t *incregs = NULL; static RCCE_FLAG release; /* - * Information to realize L2 flush + * Details on L2 cache (nedded for flushing) */ #define OWN_MPB 0xd8000000 @@ -80,36 +80,6 @@ __attribute__((always_inline)) static inline void svm_purge_set(const size_t set static size_t dummy_base = OWN_MPB + L2_CAPACITY; static size_t dummy_offset = 0; -/* - * Function to flush one page with L2 cache enabled! - */ - -void svm_flush_page(const size_t address) -{ - size_t line; - size_t dummy = dummy_base + dummy_offset; - size_t addr; - uint32_t flags; - - /* toggle between dummy areas */ - if(dummy_offset) - dummy_offset = 0; - else - dummy_offset = L2_CAPACITY; - - /* align the address to page boundaries */ - addr &= ~(PAGE_SIZE-1); - - /* disable iterrupts due to pseudo LRU behavior of L2 cache*/ - flags = irq_nested_disable(); - - /* for exact one page */ - for( line = 0; line < PAGE_SIZE; line += L2_LINESIZE ) - svm_purge_set( ( ( addr + line ) % L2_WBSTRIDE ) + dummy ); - - irq_nested_enable(flags); -} - /* * This array describes the owner of a specific page. * Only the owner of a page is able to change the possession. @@ -239,17 +209,22 @@ int svm_access_request(size_t addr) return ret; } +#if 0 static atomic_int32_t size_counter = ATOMIC_INIT(0); +#endif void* svm_malloc(size_t size, uint32_t consistency) { size_t viraddr; //size_t phyaddr, viraddr, i; //uint32_t flags; + task_t* task = per_core(current_task); uint32_t map_flags = MAP_KERNEL_SPACE; if( !(consistency & SVM_L2) ) map_flags |= MAP_MPE; + else + task->flags |= TASK_L2; if (consistency & SVM_STRONG) map_flags |= MAP_SVM_STRONG; @@ -411,7 +386,7 @@ int svm_emit_page(size_t phyaddr, int ue) } else { size_t viraddr; - svm_flush(); + svm_flush(phyaddr); // send response back to ue // ue is polling for the response => no irq is needed @@ -428,7 +403,7 @@ int svm_emit_page(size_t phyaddr, int ue) return 0; } -#ifdef SVM_WB +#if 0 void svm_flush(void) { int z, tmp; @@ -452,6 +427,97 @@ void svm_flush(void) } #endif +/* + * Function to flush one page or entire cache. + */ + +#ifdef SVM_WB +void svm_flush( size_t phyaddr ) +{ + task_t* task = per_core(current_task); + page_dir_t* pgd = task->pgd; + page_table_t* pgt = NULL; + + size_t step = 0; + size_t stride = L2_LINESIZE; + size_t range = L2_WBSTRIDE; + + size_t viraddr; + + uint32_t index1, index2; + + uint32_t flags; + + /* flush entire Cache if phyaddr == 0 */ + if(!phyaddr) { + if( task->flags & TASK_L2 ){ + goto flush_l2; + } else { + goto flush_l1; + } + /* flush one page */ + } else { + /* align the address to page boundaries */ + phyaddr &= ~(PAGE_SIZE-1); + + /* lookup pgt to check if L2 is enabled */ + viraddr = phys2virt[(phyaddr - shmbegin) >> PAGE_SHIFT]; + index1 = viraddr >> 22; + index2 = (viraddr >> 12) & 0x3FF; + + /* check if pgt is present */ + if (!pgd || !(pgd->entries[index1] & 0xFFFFF000)) + goto wrong_addr; + + pgt = (page_table_t*)((KERNEL_SPACE - 1024 * PAGE_SIZE + index1 * PAGE_SIZE) & 0xFFFFF000); + + if( pgt->entries[index2] & PG_MPE ) { + goto flush_l1; + } else { + phyaddr = phyaddr % L2_WBSTRIDE; + range = PAGE_SIZE; + goto flush_l2; + } + } + + /* + * FLUSH L1 CACHE: + */ + +flush_l1: + kputs("flush L1\n"); + *(int *)RCCE_fool_write_combine_buffer = 1; + //__asm__ volatile ( "wbinvd;\n\t" ); + flush_cache(); + return; + +flush_l2: + /* + * FLUSH L2 CACHE: + * disable iterrupts due to pseudo LRU behavior of L2 cache + */ + flags = irq_nested_disable(); + /* toggle between dummy areas */ + phyaddr += dummy_base + dummy_offset; + kprintf("flush-l2: phyaddr 0x%x\n", phyaddr); + if(dummy_offset) + dummy_offset = 0; + else + dummy_offset = L2_CAPACITY; + + flush_cache(); + for( step = 0; step < range; step += stride ) + svm_purge_set( phyaddr + step ); + irq_nested_enable(flags); + return; + +wrong_addr: + kputs("svm flush error: address not valid!\n"); + return; + +} +#endif + int svm_barrier(uint32_t type) { int i; @@ -459,7 +525,7 @@ int svm_barrier(uint32_t type) static int index = 0; if (type == SVM_LAZYRELEASE) { - svm_flush(); + svm_flush(0); svm_invalidate(); } diff --git a/include/metalsvm/tasks_types.h b/include/metalsvm/tasks_types.h index 759bbeea..6fc1f8d7 100644 --- a/include/metalsvm/tasks_types.h +++ b/include/metalsvm/tasks_types.h @@ -59,6 +59,7 @@ extern "C" { #define TASK_FPU_INIT (1 << 0) #define TASK_FPU_USED (1 << 1) #define TASK_TIMER (1 << 2) +#define TASK_L2 (1 << 3) typedef int (*entry_point_t)(void*); typedef int (STDCALL *internal_entry_point_t)(void*);