Merge branch 'svm' of git.lfbs.rwth-aachen.de:metalsvm into svm
This commit is contained in:
commit
d24958f8b1
3 changed files with 82 additions and 6 deletions
18
apps/tests.c
18
apps/tests.c
|
@ -117,6 +117,7 @@ static int mail_noise(void*arg) {
|
||||||
#define N 1024
|
#define N 1024
|
||||||
//#define N 514
|
//#define N 514
|
||||||
#define LAZY
|
#define LAZY
|
||||||
|
#define L2_ENABLE
|
||||||
|
|
||||||
volatile static int* A[N];
|
volatile static int* A[N];
|
||||||
volatile static int* B[N];
|
volatile static int* B[N];
|
||||||
|
@ -132,6 +133,9 @@ static int svm_test(void *arg)
|
||||||
{
|
{
|
||||||
uint64_t start, end;
|
uint64_t start, end;
|
||||||
uint32_t i, j, k;
|
uint32_t i, j, k;
|
||||||
|
|
||||||
|
uint32_t svm_flags = SVM_STRONG;
|
||||||
|
|
||||||
int my_ue, num_ues;
|
int my_ue, num_ues;
|
||||||
register int tmp;
|
register int tmp;
|
||||||
|
|
||||||
|
@ -184,11 +188,17 @@ static int svm_test(void *arg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// allocate and initialize SVM region
|
// allocate and initialize SVM region
|
||||||
#ifndef LAZY
|
|
||||||
A[0] = (int*) svmmalloc(3*N*N*sizeof(int), SVM_STRONG);
|
#ifdef LAZY
|
||||||
#else
|
svm_flags = SVM_LAZYRELEASE;
|
||||||
A[0] = (int*) svmmalloc(3*N*N*sizeof(int), SVM_LAZYRELEASE);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef L2_ENABLE
|
||||||
|
svm_flags |= SVM_L2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
A[0] = (int*) svmmalloc(3*N*N*sizeof(int), svm_flags);
|
||||||
|
|
||||||
if (!my_ue)
|
if (!my_ue)
|
||||||
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));
|
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ extern "C" {
|
||||||
|
|
||||||
#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_STRONG_L2 SVM_STRONG|SVM_L2
|
||||||
|
#define SVM_LAZYRELEASE_L2 SVM_LAZYRELEASE|SVM_L2
|
||||||
|
|
||||||
/** @brief Init routine of the SVM subsystem
|
/** @brief Init routine of the SVM subsystem
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,6 +50,66 @@ typedef struct {
|
||||||
static volatile atomic_increg_t *incregs = NULL;
|
static volatile atomic_increg_t *incregs = NULL;
|
||||||
static RCCE_FLAG release;
|
static RCCE_FLAG release;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Information to realize L2 flush
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OWN_MPB 0xd8000000
|
||||||
|
|
||||||
|
#define L2_LINESIZE 32UL
|
||||||
|
#define L2_WAYS 4UL
|
||||||
|
#define L2_CAPACITY (256*1024UL)
|
||||||
|
#define L2_WBSTRIDE (L2_CAPACITY/L2_WAYS)
|
||||||
|
|
||||||
|
/* Helper function to read data into all 4 ways of L2 cache */
|
||||||
|
|
||||||
|
__attribute__((always_inline)) static inline void svm_purge_set(const size_t set)
|
||||||
|
{
|
||||||
|
register char tmp;
|
||||||
|
|
||||||
|
/* Translate the set to a kernel space virtual address */
|
||||||
|
const volatile char* dummyData = (volatile char*)set;
|
||||||
|
|
||||||
|
/* Now read new data into all four ways, and then reread the first */
|
||||||
|
tmp = *dummyData;
|
||||||
|
tmp = *(dummyData + L2_WBSTRIDE);
|
||||||
|
tmp = *(dummyData + L2_WBSTRIDE * 2);
|
||||||
|
tmp = *(dummyData + L2_WBSTRIDE * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
* 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.
|
||||||
|
@ -163,7 +223,10 @@ void* svm_malloc(size_t size, uint32_t consistency)
|
||||||
{
|
{
|
||||||
size_t phyaddr, viraddr, i;
|
size_t phyaddr, viraddr, i;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t map_flags = MAP_KERNEL_SPACE|MAP_MPE;
|
uint32_t map_flags = MAP_KERNEL_SPACE;
|
||||||
|
|
||||||
|
if( !(consistency & SVM_L2) )
|
||||||
|
map_flags |= MAP_MPE;
|
||||||
|
|
||||||
if (consistency & SVM_STRONG)
|
if (consistency & SVM_STRONG)
|
||||||
map_flags |= MAP_SVM_STRONG;
|
map_flags |= MAP_SVM_STRONG;
|
||||||
|
@ -235,7 +298,7 @@ void* svm_malloc(size_t size, uint32_t consistency)
|
||||||
if (BUILTIN_EXPECT(!phyaddr, 0))
|
if (BUILTIN_EXPECT(!phyaddr, 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (BUILTIN_EXPECT(phyaddr & 0xFFF, 0)) {
|
if (BUILTIN_EXPECT(phyaddr & 0xFFF, 0)) {
|
||||||
kprintf("RCCE_shmalloc returns not a page aligned physiacl address: 0x%x\n", phyaddr);
|
kprintf("RCCE_shmalloc returns not a page aligned physical address: 0x%x\n", phyaddr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue