Merge branch 'svm' of git.lfbs.rwth-aachen.de:metalsvm into svm

This commit is contained in:
Stefan Lankes 2011-11-08 01:12:13 -08:00
commit d24958f8b1
3 changed files with 82 additions and 6 deletions

View file

@ -117,6 +117,7 @@ static int mail_noise(void*arg) {
#define N 1024
//#define N 514
#define LAZY
#define L2_ENABLE
volatile static int* A[N];
volatile static int* B[N];
@ -132,6 +133,9 @@ static int svm_test(void *arg)
{
uint64_t start, end;
uint32_t i, j, k;
uint32_t svm_flags = SVM_STRONG;
int my_ue, num_ues;
register int tmp;
@ -184,11 +188,17 @@ static int svm_test(void *arg)
#endif
// allocate and initialize SVM region
#ifndef LAZY
A[0] = (int*) svmmalloc(3*N*N*sizeof(int), SVM_STRONG);
#else
A[0] = (int*) svmmalloc(3*N*N*sizeof(int), SVM_LAZYRELEASE);
#ifdef LAZY
svm_flags = SVM_LAZYRELEASE;
#endif
#ifdef L2_ENABLE
svm_flags |= SVM_L2;
#endif
A[0] = (int*) svmmalloc(3*N*N*sizeof(int), svm_flags);
if (!my_ue)
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));

View file

@ -33,6 +33,9 @@ extern "C" {
#define SVM_STRONG (1 << 0)
#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
*

View file

@ -50,6 +50,66 @@ typedef struct {
static volatile atomic_increg_t *incregs = NULL;
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.
* 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;
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)
map_flags |= MAP_SVM_STRONG;
@ -235,7 +298,7 @@ void* svm_malloc(size_t size, uint32_t consistency)
if (BUILTIN_EXPECT(!phyaddr, 0))
return NULL;
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;
}