Merge branch 'svm' of git.lfbs.rwth-aachen.de:metalsvm into svm
Conflicts: arch/x86/mm/svm.c
This commit is contained in:
commit
e68568aa8f
6 changed files with 121 additions and 44 deletions
23
apps/tests.c
23
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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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*);
|
||||
|
|
Loading…
Add table
Reference in a new issue