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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define N 1024
|
//#define N 1024
|
||||||
//#define N 514
|
//#define N 512
|
||||||
|
#define N 128
|
||||||
#define LAZY
|
#define LAZY
|
||||||
#define L2_ENABLE
|
#define L2_ENABLE
|
||||||
|
|
||||||
|
@ -139,6 +140,8 @@ static int svm_test(void *arg)
|
||||||
int my_ue, num_ues;
|
int my_ue, num_ues;
|
||||||
register int tmp;
|
register int tmp;
|
||||||
|
|
||||||
|
kputs("Start SVM test...\n");
|
||||||
|
|
||||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||||
my_ue = RCCE_ue();
|
my_ue = RCCE_ue();
|
||||||
num_ues = RCCE_num_ues();
|
num_ues = RCCE_num_ues();
|
||||||
|
@ -191,9 +194,13 @@ static int svm_test(void *arg)
|
||||||
|
|
||||||
#ifdef LAZY
|
#ifdef LAZY
|
||||||
svm_flags = SVM_LAZYRELEASE;
|
svm_flags = SVM_LAZYRELEASE;
|
||||||
|
kputs("Use Lazy Release consistency!\n");
|
||||||
|
#else
|
||||||
|
kputs("Use Strong Release consistency!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef L2_ENABLE
|
#ifdef L2_ENABLE
|
||||||
|
kputs("Use Level 2 Cache!\n");
|
||||||
svm_flags |= SVM_L2;
|
svm_flags |= SVM_L2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -216,7 +223,7 @@ static int svm_test(void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
svm_flush();
|
svm_flush(0);
|
||||||
|
|
||||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||||
kputs("Start parallel calculation...\n");
|
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);
|
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||||
end = rdtsc();
|
end = rdtsc();
|
||||||
|
@ -320,9 +327,9 @@ int test_init(void)
|
||||||
char* server_argv[] = {"/bin/server", "6789", NULL};
|
char* server_argv[] = {"/bin/server", "6789", NULL};
|
||||||
char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL};
|
char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL};
|
||||||
|
|
||||||
sem_init(&producing, 1);
|
//sem_init(&producing, 1);
|
||||||
sem_init(&consuming, 0);
|
//sem_init(&consuming, 0);
|
||||||
mailbox_int32_init(&mbox);
|
//mailbox_int32_init(&mbox);
|
||||||
|
|
||||||
//create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
|
//create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
|
||||||
//create_kernel_task(NULL, join_test, NULL, 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, consumer, NULL, NORMAL_PRIO);
|
||||||
//create_kernel_task(NULL, mail_ping, 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, 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, pi, NULL, NORMAL_PRIO);
|
||||||
create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO);
|
create_kernel_task(NULL, laplace, NULL, NORMAL_PRIO);
|
||||||
//create_user_task(NULL, "/bin/hello", argv);
|
//create_user_task(NULL, "/bin/hello", argv);
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
/// Pattern flag
|
/// Pattern flag
|
||||||
#define PG_PAT (1 << _PAGE_BIT_PAT)
|
#define PG_PAT (1 << _PAGE_BIT_PAT)
|
||||||
/// This virtual address range is used by SVM system as marked
|
/// 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)
|
#define PG_SVM_STRONG (1 << _PAGE_BIT_SVM_STRONG)
|
||||||
/// This virtual address range is used by SVM system as marked
|
/// This virtual address range is used by SVM system as marked
|
||||||
#define PG_SVM_LAZYRELEASE (1 << _PAGE_BIT_SVM_LAZYRELEASE)
|
#define PG_SVM_LAZYRELEASE (1 << _PAGE_BIT_SVM_LAZYRELEASE)
|
||||||
|
|
|
@ -31,6 +31,8 @@ extern "C" {
|
||||||
|
|
||||||
#ifdef CONFIG_ROCKCREEK
|
#ifdef CONFIG_ROCKCREEK
|
||||||
|
|
||||||
|
#define SVM_WB
|
||||||
|
|
||||||
#define SVM_STRONG (1 << 0)
|
#define SVM_STRONG (1 << 0)
|
||||||
#define SVM_LAZYRELEASE (1 << 1)
|
#define SVM_LAZYRELEASE (1 << 1)
|
||||||
#define SVM_L2 (1 << 4)
|
#define SVM_L2 (1 << 4)
|
||||||
|
@ -93,7 +95,7 @@ static inline void svm_flush(void)
|
||||||
*(int *)RCCE_fool_write_combine_buffer = 1;
|
*(int *)RCCE_fool_write_combine_buffer = 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void svm_flush(void);
|
void svm_flush(size_t addr);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -784,7 +784,7 @@ int arch_paging_init(void)
|
||||||
kprintf("Map configuration registers at 0x%x\n", viraddr);
|
kprintf("Map configuration registers at 0x%x\n", viraddr);
|
||||||
|
|
||||||
// map SCC's message passing buffers
|
// 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);
|
kprintf("Map message passing buffers at 0x%x\n", viraddr);
|
||||||
|
|
||||||
// map the FPGA registers
|
// map the FPGA registers
|
||||||
|
|
|
@ -51,7 +51,7 @@ static volatile atomic_increg_t *incregs = NULL;
|
||||||
static RCCE_FLAG release;
|
static RCCE_FLAG release;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Information to realize L2 flush
|
* Details on L2 cache (nedded for flushing)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define OWN_MPB 0xd8000000
|
#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_base = OWN_MPB + L2_CAPACITY;
|
||||||
static size_t dummy_offset = 0;
|
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.
|
* This array describes the owner of a specific page.
|
||||||
* Only the owner of a page is able to change the possession.
|
* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static atomic_int32_t size_counter = ATOMIC_INIT(0);
|
static atomic_int32_t size_counter = ATOMIC_INIT(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
void* svm_malloc(size_t size, uint32_t consistency)
|
void* svm_malloc(size_t size, uint32_t consistency)
|
||||||
{
|
{
|
||||||
size_t viraddr;
|
size_t viraddr;
|
||||||
//size_t phyaddr, viraddr, i;
|
//size_t phyaddr, viraddr, i;
|
||||||
//uint32_t flags;
|
//uint32_t flags;
|
||||||
|
task_t* task = per_core(current_task);
|
||||||
uint32_t map_flags = MAP_KERNEL_SPACE;
|
uint32_t map_flags = MAP_KERNEL_SPACE;
|
||||||
|
|
||||||
if( !(consistency & SVM_L2) )
|
if( !(consistency & SVM_L2) )
|
||||||
map_flags |= MAP_MPE;
|
map_flags |= MAP_MPE;
|
||||||
|
else
|
||||||
|
task->flags |= TASK_L2;
|
||||||
|
|
||||||
if (consistency & SVM_STRONG)
|
if (consistency & SVM_STRONG)
|
||||||
map_flags |= MAP_SVM_STRONG;
|
map_flags |= MAP_SVM_STRONG;
|
||||||
|
@ -411,7 +386,7 @@ int svm_emit_page(size_t phyaddr, int ue)
|
||||||
} else {
|
} else {
|
||||||
size_t viraddr;
|
size_t viraddr;
|
||||||
|
|
||||||
svm_flush();
|
svm_flush(phyaddr);
|
||||||
|
|
||||||
// send response back to ue
|
// send response back to ue
|
||||||
// ue is polling for the response => no irq is needed
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SVM_WB
|
#if 0
|
||||||
void svm_flush(void)
|
void svm_flush(void)
|
||||||
{
|
{
|
||||||
int z, tmp;
|
int z, tmp;
|
||||||
|
@ -452,6 +427,97 @@ void svm_flush(void)
|
||||||
}
|
}
|
||||||
#endif
|
#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 svm_barrier(uint32_t type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -459,7 +525,7 @@ int svm_barrier(uint32_t type)
|
||||||
static int index = 0;
|
static int index = 0;
|
||||||
|
|
||||||
if (type == SVM_LAZYRELEASE) {
|
if (type == SVM_LAZYRELEASE) {
|
||||||
svm_flush();
|
svm_flush(0);
|
||||||
svm_invalidate();
|
svm_invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ extern "C" {
|
||||||
#define TASK_FPU_INIT (1 << 0)
|
#define TASK_FPU_INIT (1 << 0)
|
||||||
#define TASK_FPU_USED (1 << 1)
|
#define TASK_FPU_USED (1 << 1)
|
||||||
#define TASK_TIMER (1 << 2)
|
#define TASK_TIMER (1 << 2)
|
||||||
|
#define TASK_L2 (1 << 3)
|
||||||
|
|
||||||
typedef int (*entry_point_t)(void*);
|
typedef int (*entry_point_t)(void*);
|
||||||
typedef int (STDCALL *internal_entry_point_t)(void*);
|
typedef int (STDCALL *internal_entry_point_t)(void*);
|
||||||
|
|
Loading…
Add table
Reference in a new issue