add SVM demo example and redesign of the SVM system
This commit is contained in:
parent
7980fd5bd7
commit
62e7ead997
5 changed files with 138 additions and 10 deletions
|
@ -26,6 +26,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
|
||||
/** @brief Memory allocator of the SVM subsystem.
|
||||
*
|
||||
* Like RCCE function, belongs svmmalloc to the synchronous
|
||||
|
@ -39,7 +41,9 @@ void* svmmalloc(size_t size);
|
|||
*
|
||||
* Like RCCE function, belongs svmfree to the synchronous function.
|
||||
*/
|
||||
void svmfree(void* addr);
|
||||
void svmfree(void* addr, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -354,6 +354,10 @@ size_t map_region(size_t viraddr, size_t phyaddr, uint32_t npages, uint32_t flag
|
|||
if (flags & MAP_MPE)
|
||||
pgt->entries[index] |= PG_MPE;
|
||||
#endif
|
||||
if (flags & MAP_SVM)
|
||||
pgt->entries[index] |= PG_SVM;
|
||||
if (flags & MAP_NO_ACCESS)
|
||||
pgt->entries[index] &= ~(PG_PRESENT|PG_RW);
|
||||
|
||||
if (flags & MAP_USER_SPACE)
|
||||
atomic_int32_inc(&task->user_usage);
|
||||
|
@ -395,6 +399,9 @@ int change_page_permissions(size_t start, size_t end, uint32_t flags)
|
|||
phyaddr = pgt->entries[index2] & 0xFFFFF000;
|
||||
newflags = pgt->entries[index2] & 0xFFF; // get old flags
|
||||
|
||||
if ((newflags & PG_SVM) && !(newflags & PG_PRESENT) && (flags & (VMA_WRITE|VMA_READ)))
|
||||
newflags |= PG_PRESENT;
|
||||
|
||||
// update flags
|
||||
if (!(flags & VMA_WRITE))
|
||||
newflags &= ~PG_RW;
|
||||
|
|
|
@ -20,19 +20,61 @@
|
|||
#include <metalsvm/stddef.h>
|
||||
#include <metalsvm/stdio.h>
|
||||
#include <metalsvm/stdlib.h>
|
||||
#include <asm/svm.h>
|
||||
#include <metalsvm/mmu.h>
|
||||
#include <metalsvm/page.h>
|
||||
#include <asm/irqflags.h>
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
#include <asm/RCCE_lib.h>
|
||||
#include <asm/SCC_API.h>
|
||||
#include <asm/icc.h>
|
||||
#endif
|
||||
#include <asm/svm.h>
|
||||
|
||||
void* svmmalloc(size_t size)
|
||||
{
|
||||
return (void*) RCCE_shmalloc(size);
|
||||
size_t phyaddr;
|
||||
size_t viraddr;
|
||||
uint32_t flags;
|
||||
uint32_t map_flags = MAP_KERNEL_SPACE|MAP_MPE|MAP_SVM;
|
||||
|
||||
// currently, we allocate memory in page size granulation
|
||||
size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
phyaddr = (size_t) RCCE_shmalloc(size);
|
||||
|
||||
if (RCCE_ue())
|
||||
map_flags |= MAP_NO_ACCESS;
|
||||
irq_nested_enable(flags);
|
||||
|
||||
viraddr = map_region(0, phyaddr, size >> PAGE_SHIFT, map_flags);
|
||||
|
||||
//kprintf("shmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, viraddr, size);
|
||||
|
||||
return (void*) viraddr;
|
||||
}
|
||||
|
||||
void svmfree(void* addr)
|
||||
void svmfree(void* addr, size_t size)
|
||||
{
|
||||
RCCE_free((t_vcharp) addr);
|
||||
size_t phyaddr;
|
||||
uint32_t flags;
|
||||
|
||||
if (BUILTIN_EXPECT(!addr || !size, 0))
|
||||
return;
|
||||
|
||||
phyaddr = virt_to_phys((size_t) addr);
|
||||
|
||||
// currently, we allocate memory in page size granulation
|
||||
size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
|
||||
//kprintf("shmmalloc: phyaddr 0x%x, viraddr 0x%x, size 0x%x\n", phyaddr, addr, size);
|
||||
|
||||
unmap_region((size_t) addr, size >> PAGE_SHIFT);
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
RCCE_shfree((t_vcharp) phyaddr);
|
||||
irq_nested_enable(flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,6 +48,9 @@ extern "C" {
|
|||
#ifdef CONFIG_ROCKCREEK
|
||||
#define MAP_MPE (1 << 8)
|
||||
#endif
|
||||
#define MAP_SVM (1 << 9)
|
||||
#define MAP_NO_ACCESS (1 << 10)
|
||||
|
||||
void NORETURN abort(void);
|
||||
|
||||
/** @brief Kernel's memory allocator function.
|
||||
|
|
|
@ -24,12 +24,14 @@
|
|||
#include <metalsvm/semaphore.h>
|
||||
#include <metalsvm/mailbox.h>
|
||||
#include <metalsvm/syscall.h>
|
||||
#include <metalsvm/vma.h>
|
||||
#ifdef CONFIG_ROCKCREEK
|
||||
#include <asm/icc.h>
|
||||
#include <asm/RCCE.h>
|
||||
#include <asm/RCCE_lib.h>
|
||||
#include <asm/iRCCE.h>
|
||||
#include <asm/iRCCE_lib.h>
|
||||
#include <asm/svm.h>
|
||||
|
||||
#include <asm/SCC_API.h>
|
||||
#include <lwip/sockets.h>
|
||||
|
@ -111,6 +113,75 @@ int mail_ping(void* arg) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cache_invalidate(void)
|
||||
{
|
||||
asm volatile ( ".byte 0x0f; .byte 0x0a;\n" ); // CL1FLUSHMB
|
||||
}
|
||||
|
||||
#define N 1024
|
||||
|
||||
volatile static int* A[N];
|
||||
volatile static int* B[N];
|
||||
volatile static int* C[N];
|
||||
|
||||
static int svm_test(void *arg)
|
||||
{
|
||||
uint32_t i, j, k, flags;
|
||||
int my_ue, num_ues;
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||
my_ue = RCCE_ue();
|
||||
num_ues = RCCE_num_ues();
|
||||
irq_nested_enable(flags);
|
||||
|
||||
// allocate and initialize SVM region
|
||||
A[0] = (int*) svmmalloc(3*N*N*sizeof(int));
|
||||
if (!my_ue)
|
||||
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));
|
||||
|
||||
// initialize matrices
|
||||
for(i=0; i<N; i++) {
|
||||
A[i] = A[0] + i*N;
|
||||
B[i] = A[0] + i*N + N*N;
|
||||
C[i] = A[0] + i*N + 2*N*N;
|
||||
}
|
||||
if (!my_ue) {
|
||||
for(i=0; i<N; i++) {
|
||||
A[i][i] = 1;
|
||||
for(j=0; j<N; j++)
|
||||
B[i][j] = j;
|
||||
}
|
||||
}
|
||||
|
||||
// CL1FLUSH
|
||||
cache_invalidate();
|
||||
|
||||
// Now, we need only read access on A and B
|
||||
change_page_permissions(A[0], A[0]+2*N*N, VMA_CACHEABLE|VMA_READ);
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||
irq_nested_enable(flags);
|
||||
|
||||
// start calculation
|
||||
for(i=my_ue*(N/num_ues); i<(my_ue+1)*(N/num_ues); i++)
|
||||
for(j=0; j<N; j++)
|
||||
for(k=0; k<N; k++)
|
||||
; //C[i][j] = A[i][k] * B[k][j];
|
||||
|
||||
// iRCCE is not thread save => disable interrupts
|
||||
flags = irq_nested_disable();
|
||||
RCCE_barrier(&RCCE_COMM_WORLD);
|
||||
irq_nested_enable(flags);
|
||||
|
||||
svmfree(A[0], 3*N*sizeof(int));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int join_test(void* arg)
|
||||
|
@ -273,16 +344,17 @@ int test_init(void)
|
|||
// create_kernel_task(NULL,client_task,NULL);
|
||||
#endif
|
||||
|
||||
create_kernel_task(NULL, foo, "Hello from foo1");
|
||||
create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, foo, "Hello from foo1");
|
||||
//create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, producer, NULL);
|
||||
//create_kernel_task(NULL, consumer, NULL);
|
||||
//create_kernel_task(NULL, mail_ping, NULL);
|
||||
create_kernel_task(NULL, svm_test, NULL);
|
||||
//create_user_task(NULL, "/bin/hello", argv);
|
||||
create_user_task(NULL, "/bin/tests", argv);
|
||||
//create_user_task(NULL, "/bin/tests", argv);
|
||||
//create_user_task(NULL, "/bin/jacobi", argv);
|
||||
//create_user_task(NULL, "/bin/jacobi", argv);
|
||||
create_user_task(NULL, "/bin/server", server_argv);
|
||||
//create_user_task(NULL, "/bin/server", server_argv);
|
||||
//sleep(5);
|
||||
//create_user_task(NULL, "/bin/client", client_argv);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue