temp
This commit is contained in:
@@ -24,7 +24,7 @@ static void ap_wait(void)
|
|||||||
kprintf("ap started.\n");
|
kprintf("ap started.\n");
|
||||||
kmalloc_init();
|
kmalloc_init();
|
||||||
sched_init();
|
sched_init();
|
||||||
init_host_syscall_channel();
|
/* init_host_syscall_channel(); */
|
||||||
|
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,5 +28,6 @@ int memcpy_async(unsigned long dest, unsigned long src,
|
|||||||
barrier();
|
barrier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,26 +53,27 @@ static void process_msg_prepare_process(unsigned long rphys)
|
|||||||
|
|
||||||
/* TODO: Maybe we need flag */
|
/* TODO: Maybe we need flag */
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
proc->region.text_start = s;
|
proc->vm->region.text_start = s;
|
||||||
proc->region.text_end = e;
|
proc->vm->region.text_end = e;
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
proc->region.data_start = s;
|
proc->vm->region.data_start = s;
|
||||||
proc->region.data_end = e;
|
proc->vm->region.data_end = e;
|
||||||
} else {
|
} else {
|
||||||
proc->region.data_start =
|
proc->vm->region.data_start =
|
||||||
(s < proc->region.data_start ?
|
(s < proc->vm->region.data_start ?
|
||||||
s : proc->region.data_start);
|
s : proc->vm->region.data_start);
|
||||||
proc->region.data_end =
|
proc->vm->region.data_end =
|
||||||
(e > proc->region.data_end ?
|
(e > proc->vm->region.data_end ?
|
||||||
e : proc->region.data_end);
|
e : proc->vm->region.data_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proc->region.brk_start = proc->region.brk_end = proc->region.data_end;
|
proc->vm->region.brk_start = proc->vm->region.brk_end =
|
||||||
proc->region.map_start = proc->region.map_end =
|
proc->vm->region.data_end;
|
||||||
|
proc->vm->region.map_start = proc->vm->region.map_end =
|
||||||
(USER_END / 3) & LARGE_PAGE_MASK;
|
(USER_END / 3) & LARGE_PAGE_MASK;
|
||||||
|
|
||||||
/* Map system call stuffs */
|
/* Map system call stuffs */
|
||||||
addr = proc->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
||||||
e = addr + PAGE_SIZE * DOORBELL_PAGE_COUNT;
|
e = addr + PAGE_SIZE * DOORBELL_PAGE_COUNT;
|
||||||
add_process_memory_range(proc, addr, e,
|
add_process_memory_range(proc, addr, e,
|
||||||
cpu_local_var(scp).doorbell_pa,
|
cpu_local_var(scp).doorbell_pa,
|
||||||
@@ -92,7 +93,7 @@ static void process_msg_prepare_process(unsigned long rphys)
|
|||||||
init_process_stack(proc);
|
init_process_stack(proc);
|
||||||
|
|
||||||
kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||||
proc->page_table);
|
proc->vm->page_table);
|
||||||
|
|
||||||
aal_mc_free(pn);
|
aal_mc_free(pn);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct cpu_local_var {
|
|||||||
struct malloc_header free_list;
|
struct malloc_header free_list;
|
||||||
|
|
||||||
struct process idle;
|
struct process idle;
|
||||||
|
struct process_vm idle_vm;
|
||||||
|
|
||||||
struct process *current;
|
struct process *current;
|
||||||
struct process *next;
|
struct process *next;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <aal/context.h>
|
#include <aal/context.h>
|
||||||
#include <aal/cpu.h>
|
#include <aal/cpu.h>
|
||||||
#include <aal/mm.h>
|
#include <aal/mm.h>
|
||||||
|
#include <aal/atomic.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
|
|
||||||
#define VR_STACK 0x1
|
#define VR_STACK 0x1
|
||||||
@@ -28,20 +29,27 @@ struct vm_regions {
|
|||||||
unsigned long stack_start, stack_end;
|
unsigned long stack_start, stack_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct process_vm {
|
||||||
|
aal_atomic_t refcount;
|
||||||
|
|
||||||
|
struct page_table *page_table;
|
||||||
|
struct list_head vm_range_list;
|
||||||
|
struct vm_regions region;
|
||||||
|
};
|
||||||
|
|
||||||
struct process {
|
struct process {
|
||||||
int pid;
|
int pid;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
struct page_table *page_table;
|
struct process_vm *vm;
|
||||||
struct list_head vm_range_list;
|
|
||||||
|
|
||||||
struct vm_regions region;
|
|
||||||
|
|
||||||
aal_mc_kernel_context_t ctx;
|
aal_mc_kernel_context_t ctx;
|
||||||
aal_mc_user_context_t *uctx;
|
aal_mc_user_context_t *uctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct process *create_process(unsigned long user_pc);
|
struct process *create_process(unsigned long user_pc);
|
||||||
|
struct process *clone_process(struct process *org,
|
||||||
|
unsigned long pc, unsigned long sp);
|
||||||
void destroy_process(struct process *proc);
|
void destroy_process(struct process *proc);
|
||||||
void free_process_memory(struct process *proc);
|
void free_process_memory(struct process *proc);
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,13 @@ static void dma_test(void)
|
|||||||
{
|
{
|
||||||
struct aal_dma_request req;
|
struct aal_dma_request req;
|
||||||
unsigned long fin = 0;
|
unsigned long fin = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
data[i] = 8 - i;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("DMA Test Started.\n");
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
req.src_phys = virt_to_phys(data);
|
req.src_phys = virt_to_phys(data);
|
||||||
req.dest_phys = virt_to_phys(data + 256);
|
req.dest_phys = virt_to_phys(data + 256);
|
||||||
@@ -46,11 +52,17 @@ static void dma_test(void)
|
|||||||
req.notify = (void *)virt_to_phys(&fin);
|
req.notify = (void *)virt_to_phys(&fin);
|
||||||
req.priv = (void *)0x2984;
|
req.priv = (void *)0x2984;
|
||||||
|
|
||||||
aal_mc_dma_request(0, &req);
|
kprintf("VtoP : %p, %lx\n", data, virt_to_phys(data));
|
||||||
|
|
||||||
|
if (aal_mc_dma_request(0, &req) != 0) {
|
||||||
|
kprintf("Failed to request DMA!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("DMA Test Wait.\n");
|
||||||
while (!fin) {
|
while (!fin) {
|
||||||
barrier();
|
barrier();
|
||||||
}
|
}
|
||||||
|
kprintf("DMA Test End.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char *aal_mc_get_kernel_args(void);
|
extern char *aal_mc_get_kernel_args(void);
|
||||||
@@ -127,7 +139,7 @@ static void post_init(void)
|
|||||||
cpu_pause();
|
cpu_pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
init_host_syscall_channel();
|
/* init_host_syscall_channel(); */
|
||||||
ap_start();
|
ap_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,13 @@
|
|||||||
#include <aal/debug.h>
|
#include <aal/debug.h>
|
||||||
#include <page.h>
|
#include <page.h>
|
||||||
|
|
||||||
|
void init_process_vm(struct process_vm *vm)
|
||||||
|
{
|
||||||
|
aal_atomic_set(&vm->refcount, 1);
|
||||||
|
INIT_LIST_HEAD(&vm->vm_range_list);
|
||||||
|
vm->page_table = aal_mc_pt_create();
|
||||||
|
}
|
||||||
|
|
||||||
struct process *create_process(unsigned long user_pc)
|
struct process *create_process(unsigned long user_pc)
|
||||||
{
|
{
|
||||||
struct process *proc;
|
struct process *proc;
|
||||||
@@ -17,8 +24,33 @@ struct process *create_process(unsigned long user_pc)
|
|||||||
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
|
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
|
||||||
((char *)proc) + PAGE_SIZE, user_pc, 0);
|
((char *)proc) + PAGE_SIZE, user_pc, 0);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&proc->vm_range_list);
|
proc->vm = (struct process_vm *)(proc + 1);
|
||||||
proc->page_table = aal_mc_pt_create();
|
|
||||||
|
init_process_vm(proc->vm);
|
||||||
|
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct process *clone_process(struct process *org, unsigned long pc,
|
||||||
|
unsigned long sp)
|
||||||
|
{
|
||||||
|
struct process *proc;
|
||||||
|
|
||||||
|
proc = aal_mc_alloc_pages(1, 0);
|
||||||
|
|
||||||
|
memset(proc, 0, sizeof(struct process));
|
||||||
|
|
||||||
|
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
|
||||||
|
((char *)proc) + PAGE_SIZE, pc, sp);
|
||||||
|
|
||||||
|
memcpy(proc->uctx, org->uctx, sizeof(*org->uctx));
|
||||||
|
aal_mc_modify_user_context(proc->uctx, AAL_UCR_STACK_POINTER,
|
||||||
|
sp);
|
||||||
|
aal_mc_modify_user_context(proc->uctx, AAL_UCR_PROGRAM_COUNTER,
|
||||||
|
pc);
|
||||||
|
|
||||||
|
aal_atomic_inc(&org->vm->refcount);
|
||||||
|
proc->vm = org->vm;
|
||||||
|
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
@@ -33,7 +65,7 @@ void update_process_page_table(struct process *process, struct vm_range *range,
|
|||||||
|
|
||||||
p = range->start;
|
p = range->start;
|
||||||
while (p < range->end) {
|
while (p < range->end) {
|
||||||
aal_mc_pt_set_page(process->page_table, (void *)p,
|
aal_mc_pt_set_page(process->vm->page_table, (void *)p,
|
||||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag);
|
pa, PTATTR_WRITABLE | PTATTR_USER | flag);
|
||||||
|
|
||||||
pa += PAGE_SIZE;
|
pa += PAGE_SIZE;
|
||||||
@@ -73,7 +105,7 @@ int add_process_memory_range(struct process *process,
|
|||||||
__host_update_process_range(process, range);
|
__host_update_process_range(process, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&range->list, &process->vm_range_list);
|
list_add_tail(&range->list, &process->vm->vm_range_list);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -90,22 +122,20 @@ void init_process_stack(struct process *process)
|
|||||||
virt_to_phys(stack), VR_STACK);
|
virt_to_phys(stack), VR_STACK);
|
||||||
|
|
||||||
/* TODO: fill with actual value of argc, argv, envp */
|
/* TODO: fill with actual value of argc, argv, envp */
|
||||||
kprintf("%lx, %p\n", virt_to_phys(stack), p);
|
|
||||||
|
|
||||||
p[-1] = 0; /* AT_NULL */
|
p[-1] = 0; /* AT_NULL */
|
||||||
p[-2] = 0;
|
p[-2] = 0;
|
||||||
p[-3] = USER_END - sizeof(unsigned long) * 2;
|
p[-3] = USER_END - sizeof(unsigned long) * 2;
|
||||||
p[-4] = 0; /* env: "" */
|
p[-4] = 0; /* env: "" */
|
||||||
p[-5] = 0x41; /* argv(0): "a" */
|
p[-5] = 0x41; /* argv(0): "a" */
|
||||||
p[-6] = USER_END - sizeof(unsigned long) * 4; /* envp: END - 8 */
|
p[-6] = 0; /* envp: NULL */
|
||||||
p[-7] = 0; /* argv[1] = NULL */
|
p[-7] = 0; /* argv[1] = NULL */
|
||||||
p[-8] = USER_END - sizeof(unsigned long) * 5; /* argv[0] = END - 16 */
|
p[-8] = USER_END - sizeof(unsigned long) * 5; /* argv[0] = END - 16 */
|
||||||
p[-9] = 1; /* argc */
|
p[-9] = 1; /* argc */
|
||||||
|
|
||||||
aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER,
|
aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER,
|
||||||
USER_END - sizeof(unsigned long) * 8);
|
USER_END - sizeof(unsigned long) * 9);
|
||||||
process->region.stack_end = USER_END;
|
process->vm->region.stack_end = USER_END;
|
||||||
process->region.stack_start = USER_END - PAGE_SIZE;
|
process->vm->region.stack_start = USER_END - PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +178,7 @@ int remove_process_region(struct process *proc,
|
|||||||
|
|
||||||
/* We defer freeing to the time of exit */
|
/* We defer freeing to the time of exit */
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
aal_mc_pt_clear_page(proc->page_table, (void *)start);
|
aal_mc_pt_clear_page(proc->vm->page_table, (void *)start);
|
||||||
start += PAGE_SIZE;
|
start += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +190,11 @@ void free_process_memory(struct process *proc)
|
|||||||
{
|
{
|
||||||
struct vm_range *range, *next;
|
struct vm_range *range, *next;
|
||||||
|
|
||||||
list_for_each_entry_safe(range, next, &proc->vm_range_list,
|
if (!aal_atomic_dec_and_test(&proc->vm->refcount)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(range, next, &proc->vm->vm_range_list,
|
||||||
list) {
|
list) {
|
||||||
if (!(range->flag & VR_REMOTE) &&
|
if (!(range->flag & VR_REMOTE) &&
|
||||||
!(range->flag & VR_IO_NOCACHE) &&
|
!(range->flag & VR_IO_NOCACHE) &&
|
||||||
@@ -195,6 +229,9 @@ void sched_init(void)
|
|||||||
struct process *idle_process = &cpu_local_var(idle);
|
struct process *idle_process = &cpu_local_var(idle);
|
||||||
|
|
||||||
memset(idle_process, 0, sizeof(struct process));
|
memset(idle_process, 0, sizeof(struct process));
|
||||||
|
memset(&cpu_local_var(idle_vm), 0, sizeof(struct process_vm));
|
||||||
|
|
||||||
|
idle_process->vm = &cpu_local_var(idle_vm);
|
||||||
|
|
||||||
aal_mc_init_context(&idle_process->ctx, NULL, idle);
|
aal_mc_init_context(&idle_process->ctx, NULL, idle);
|
||||||
|
|
||||||
@@ -220,9 +257,11 @@ void schedule(void)
|
|||||||
cpu_enable_interrupt();
|
cpu_enable_interrupt();
|
||||||
|
|
||||||
if (switch_ctx) {
|
if (switch_ctx) {
|
||||||
kprintf("schedule: %p (%p) => %p (%p) \n", prev,
|
kprintf("[%d] schedule: %d => %d \n",
|
||||||
prev ? prev->page_table : NULL, next, next->page_table);
|
aal_mc_get_processor_id(),
|
||||||
aal_mc_load_page_table(next->page_table);
|
prev ? prev->pid : 0, next ? next->pid : 0);
|
||||||
|
|
||||||
|
aal_mc_load_page_table(next->vm->page_table);
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
aal_mc_switch_context(&prev->ctx, &next->ctx);
|
aal_mc_switch_context(&prev->ctx, &next->ctx);
|
||||||
|
|||||||
@@ -18,12 +18,10 @@ static void send_syscall(struct syscall_request *req)
|
|||||||
struct ikc_scd_packet packet;
|
struct ikc_scd_packet packet;
|
||||||
struct syscall_response *res = cpu_local_var(scp).response_va;
|
struct syscall_response *res = cpu_local_var(scp).response_va;
|
||||||
unsigned long fin;
|
unsigned long fin;
|
||||||
|
int w;
|
||||||
|
|
||||||
res->status = 0;
|
res->status = 0;
|
||||||
|
req->valid = 0;
|
||||||
kprintf("CPU : %lx\n", aal_mc_get_processor_id());
|
|
||||||
kprintf("Target is %lx\n", cpu_local_var(scp).request_pa);
|
|
||||||
kprintf("SC req: %ld %ld %ld\n", req->valid, req->number, req->args[0]);
|
|
||||||
|
|
||||||
memcpy_async(cpu_local_var(scp).request_pa,
|
memcpy_async(cpu_local_var(scp).request_pa,
|
||||||
virt_to_phys(req), sizeof(*req), 0, &fin);
|
virt_to_phys(req), sizeof(*req), 0, &fin);
|
||||||
@@ -31,10 +29,12 @@ static void send_syscall(struct syscall_request *req)
|
|||||||
memcpy_async_wait(&cpu_local_var(scp).post_fin);
|
memcpy_async_wait(&cpu_local_var(scp).post_fin);
|
||||||
cpu_local_var(scp).post_va->v[0] = cpu_local_var(scp).post_idx;
|
cpu_local_var(scp).post_va->v[0] = cpu_local_var(scp).post_idx;
|
||||||
|
|
||||||
|
w = aal_mc_get_processor_id() + 1;
|
||||||
|
|
||||||
memcpy_async_wait(&fin);
|
memcpy_async_wait(&fin);
|
||||||
|
|
||||||
cpu_local_var(scp).request_va->valid = 1;
|
cpu_local_var(scp).request_va->valid = 1;
|
||||||
*(unsigned int *)cpu_local_var(scp).doorbell_va = 1;
|
*(unsigned int *)cpu_local_var(scp).doorbell_va = w;
|
||||||
|
|
||||||
#ifdef SYSCALL_BY_IKC
|
#ifdef SYSCALL_BY_IKC
|
||||||
packet.msg = SCD_MSG_SYSCALL_ONESIDE;
|
packet.msg = SCD_MSG_SYSCALL_ONESIDE;
|
||||||
@@ -61,7 +61,7 @@ static int do_syscall(struct syscall_request *req)
|
|||||||
long sys_brk(int n, aal_mc_user_context_t *ctx)
|
long sys_brk(int n, aal_mc_user_context_t *ctx)
|
||||||
{
|
{
|
||||||
unsigned long address = aal_mc_syscall_arg0(ctx);
|
unsigned long address = aal_mc_syscall_arg0(ctx);
|
||||||
struct vm_regions *region = &cpu_local_var(current)->region;
|
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
||||||
|
|
||||||
region->brk_end =
|
region->brk_end =
|
||||||
extend_process_region(cpu_local_var(current),
|
extend_process_region(cpu_local_var(current),
|
||||||
@@ -73,13 +73,12 @@ long sys_brk(int n, aal_mc_user_context_t *ctx)
|
|||||||
|
|
||||||
#define SYSCALL_DECLARE(name) long sys_##name(int n, aal_mc_user_context_t *ctx)
|
#define SYSCALL_DECLARE(name) long sys_##name(int n, aal_mc_user_context_t *ctx)
|
||||||
#define SYSCALL_HEADER struct syscall_request request; \
|
#define SYSCALL_HEADER struct syscall_request request; \
|
||||||
request.valid = 0; \
|
|
||||||
request.number = n
|
request.number = n
|
||||||
#define SYSCALL_ARG_D(n) request.args[n] = aal_mc_syscall_arg##n(ctx)
|
#define SYSCALL_ARG_D(n) request.args[n] = aal_mc_syscall_arg##n(ctx)
|
||||||
#define SYSCALL_ARG_MO(n) \
|
#define SYSCALL_ARG_MO(n) \
|
||||||
do { \
|
do { \
|
||||||
unsigned long __phys; \
|
unsigned long __phys; \
|
||||||
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, \
|
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, \
|
||||||
(void *)aal_mc_syscall_arg##n(ctx),\
|
(void *)aal_mc_syscall_arg##n(ctx),\
|
||||||
&__phys)) { \
|
&__phys)) { \
|
||||||
return -EFAULT; \
|
return -EFAULT; \
|
||||||
@@ -89,7 +88,7 @@ long sys_brk(int n, aal_mc_user_context_t *ctx)
|
|||||||
#define SYSCALL_ARG_MI(n) \
|
#define SYSCALL_ARG_MI(n) \
|
||||||
do { \
|
do { \
|
||||||
unsigned long __phys; \
|
unsigned long __phys; \
|
||||||
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, \
|
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table, \
|
||||||
(void *)aal_mc_syscall_arg##n(ctx),\
|
(void *)aal_mc_syscall_arg##n(ctx),\
|
||||||
&__phys)) { \
|
&__phys)) { \
|
||||||
return -EFAULT; \
|
return -EFAULT; \
|
||||||
@@ -201,7 +200,7 @@ SYSCALL_DECLARE(exit_group)
|
|||||||
SYSCALL_DECLARE(mmap)
|
SYSCALL_DECLARE(mmap)
|
||||||
{
|
{
|
||||||
unsigned long address, ret;
|
unsigned long address, ret;
|
||||||
struct vm_regions *region = &cpu_local_var(current)->region;
|
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
||||||
|
|
||||||
/* anonymous */
|
/* anonymous */
|
||||||
if (aal_mc_syscall_arg3(ctx) & 0x22) {
|
if (aal_mc_syscall_arg3(ctx) & 0x22) {
|
||||||
@@ -240,12 +239,12 @@ SYSCALL_DECLARE(getpid)
|
|||||||
return cpu_local_var(current)->pid;
|
return cpu_local_var(current)->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
long sys_uname(int n, aal_mc_user_context_t *ctx)
|
SYSCALL_DECLARE(uname)
|
||||||
{
|
{
|
||||||
struct syscall_request request;
|
SYSCALL_HEADER;
|
||||||
unsigned long phys;
|
unsigned long phys;
|
||||||
|
|
||||||
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table,
|
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->vm->page_table,
|
||||||
(void *)aal_mc_syscall_arg0(ctx), &phys)) {
|
(void *)aal_mc_syscall_arg0(ctx), &phys)) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@@ -253,7 +252,7 @@ long sys_uname(int n, aal_mc_user_context_t *ctx)
|
|||||||
request.number = n;
|
request.number = n;
|
||||||
request.args[0] = phys;
|
request.args[0] = phys;
|
||||||
|
|
||||||
return do_syscall(&request), stop();
|
return do_syscall(&request);
|
||||||
}
|
}
|
||||||
|
|
||||||
long sys_getxid(int n, aal_mc_user_context_t *ctx)
|
long sys_getxid(int n, aal_mc_user_context_t *ctx)
|
||||||
@@ -284,6 +283,29 @@ long sys_arch_prctl(int n, aal_mc_user_context_t *ctx)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYSCALL_DECLARE(clone)
|
||||||
|
{
|
||||||
|
/* Clone a new thread */
|
||||||
|
struct process *new;
|
||||||
|
struct syscall_request request;
|
||||||
|
|
||||||
|
new = clone_process(cpu_local_var(current), aal_mc_syscall_pc(ctx),
|
||||||
|
aal_mc_syscall_arg1(ctx));
|
||||||
|
/* XXX Assign new pid! */
|
||||||
|
new->pid = cpu_local_var(current)->pid;
|
||||||
|
kprintf("Cloned: %p \n", new);
|
||||||
|
|
||||||
|
aal_mc_syscall_ret(new->uctx) = 0;
|
||||||
|
|
||||||
|
/* Hope it is scheduled after... :) */
|
||||||
|
request.number = n;
|
||||||
|
request.args[0] = (unsigned long)new;
|
||||||
|
/* Sync */
|
||||||
|
do_syscall(&request);
|
||||||
|
kprintf("Clone ret.\n");
|
||||||
|
return new->pid;
|
||||||
|
}
|
||||||
|
|
||||||
static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
||||||
[0] = sys_read,
|
[0] = sys_read,
|
||||||
[1] = sys_write,
|
[1] = sys_write,
|
||||||
@@ -298,6 +320,7 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
|||||||
[17] = sys_pread,
|
[17] = sys_pread,
|
||||||
[18] = sys_pwrite,
|
[18] = sys_pwrite,
|
||||||
[39] = sys_getpid,
|
[39] = sys_getpid,
|
||||||
|
[56] = sys_clone,
|
||||||
[63] = sys_uname,
|
[63] = sys_uname,
|
||||||
[102] = sys_getxid,
|
[102] = sys_getxid,
|
||||||
[104] = sys_getxid,
|
[104] = sys_getxid,
|
||||||
@@ -309,22 +332,29 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
|
|||||||
[231] = sys_exit_group,
|
[231] = sys_exit_group,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DEBUG_PRINT_SC
|
||||||
|
|
||||||
long syscall(int num, aal_mc_user_context_t *ctx)
|
long syscall(int num, aal_mc_user_context_t *ctx)
|
||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
cpu_enable_interrupt();
|
cpu_enable_interrupt();
|
||||||
|
|
||||||
kprintf("SC(%d)[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n",
|
#ifdef DEBUG_PRINT_SC
|
||||||
|
kprintf("SC(%d)[%3d](%lx, %lx) @ %lx | %lx = ",
|
||||||
aal_mc_get_processor_id(),
|
aal_mc_get_processor_id(),
|
||||||
num,
|
num,
|
||||||
aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx),
|
aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx),
|
||||||
aal_mc_syscall_arg2(ctx), aal_mc_syscall_arg3(ctx),
|
aal_mc_syscall_arg2(ctx), aal_mc_syscall_arg3(ctx),
|
||||||
aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx),
|
aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx),
|
||||||
aal_mc_syscall_sp(ctx));
|
aal_mc_syscall_sp(ctx));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (syscall_table[num]) {
|
if (syscall_table[num]) {
|
||||||
l = syscall_table[num](num, ctx);
|
l = syscall_table[num](num, ctx);
|
||||||
|
#ifdef DEBUG_PRINT_SC
|
||||||
|
kprintf(" %lx\n", l);
|
||||||
|
#endif
|
||||||
return l;
|
return l;
|
||||||
} else {
|
} else {
|
||||||
kprintf("USC[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", num,
|
kprintf("USC[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", num,
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ int mcexec_load_image(aal_os_t os, struct program_transfer *__user upt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern unsigned long last_thread_exec;
|
||||||
|
|
||||||
static long mcexec_start_image(aal_os_t os,
|
static long mcexec_start_image(aal_os_t os,
|
||||||
struct program_load_desc * __user udesc)
|
struct program_load_desc * __user udesc)
|
||||||
{
|
{
|
||||||
@@ -117,6 +119,8 @@ static long mcexec_start_image(aal_os_t os,
|
|||||||
c = channels + desc.cpu;
|
c = channels + desc.cpu;
|
||||||
|
|
||||||
mcctrl_ikc_set_recv_cpu(desc.cpu);
|
mcctrl_ikc_set_recv_cpu(desc.cpu);
|
||||||
|
|
||||||
|
last_thread_exec = desc.cpu;
|
||||||
|
|
||||||
isp.msg = SCD_MSG_SCHEDULE_PROCESS;
|
isp.msg = SCD_MSG_SCHEDULE_PROCESS;
|
||||||
isp.ref = desc.cpu;
|
isp.ref = desc.cpu;
|
||||||
@@ -139,11 +143,14 @@ int mcexec_syscall(struct mcctrl_channel *c, unsigned long arg)
|
|||||||
int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
||||||
struct syscall_request *sc);
|
struct syscall_request *sc);
|
||||||
|
|
||||||
|
static int remaining_job, base_cpu, job_pos;
|
||||||
|
extern int num_channels;
|
||||||
|
|
||||||
int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
||||||
{
|
{
|
||||||
struct syscall_wait_desc swd;
|
struct syscall_wait_desc swd;
|
||||||
struct mcctrl_channel *c;
|
struct mcctrl_channel *c;
|
||||||
unsigned long s, w;
|
unsigned long s, w, d;
|
||||||
|
|
||||||
if (copy_from_user(&swd, req, sizeof(swd.cpu))) {
|
if (copy_from_user(&swd, req, sizeof(swd.cpu))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -157,20 +164,38 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
|||||||
#else
|
#else
|
||||||
while (1) {
|
while (1) {
|
||||||
rdtscll(s);
|
rdtscll(s);
|
||||||
while (!(*c->param.doorbell_va)) {
|
if (!remaining_job) {
|
||||||
mb();
|
while (!(*c->param.doorbell_va)) {
|
||||||
cpu_relax();
|
mb();
|
||||||
rdtscll(w);
|
cpu_relax();
|
||||||
if (w > s + 1024 * 1024 * 1024 * 1) {
|
rdtscll(w);
|
||||||
return -EINTR;
|
if (w > s + 1024UL * 1024 * 1024 * 10) {
|
||||||
|
return -EINTR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
d = (*c->param.doorbell_va) - 1;
|
||||||
|
*c->param.doorbell_va = 0;
|
||||||
|
|
||||||
|
if (d < 0 || d >= num_channels) {
|
||||||
|
d = 0;
|
||||||
|
}
|
||||||
|
base_cpu = d;
|
||||||
|
job_pos = 0;
|
||||||
|
remaining_job = 1;
|
||||||
|
} else {
|
||||||
|
job_pos++;
|
||||||
}
|
}
|
||||||
*c->param.doorbell_va = 0;
|
|
||||||
printk("(%p) %ld SC %ld: %lx\n",
|
for (; job_pos < num_channels; job_pos++) {
|
||||||
c->param.request_va,
|
if (base_cpu + job_pos >= num_channels) {
|
||||||
c->param.request_va->valid,
|
c = channels +
|
||||||
c->param.request_va->number,
|
(base_cpu + job_pos - num_channels);
|
||||||
c->param.request_va->args[0]);
|
} else {
|
||||||
|
c = channels + base_cpu + job_pos;
|
||||||
|
}
|
||||||
|
if (c->param.request_va &&
|
||||||
|
c->param.request_va->valid) {
|
||||||
|
c->param.request_va->valid = 0; /* ack */
|
||||||
if (__do_in_kernel_syscall(os, c, c->param.request_va)) {
|
if (__do_in_kernel_syscall(os, c, c->param.request_va)) {
|
||||||
#endif
|
#endif
|
||||||
if (copy_to_user(&req->sr, c->param.request_va,
|
if (copy_to_user(&req->sr, c->param.request_va,
|
||||||
@@ -178,8 +203,11 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
#ifndef DO_USER_MODE
|
#ifndef DO_USER_MODE
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remaining_job = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <aal/ikc.h>
|
#include <aal/ikc.h>
|
||||||
#include <ikc/master.h>
|
#include <ikc/master.h>
|
||||||
|
|
||||||
static int num_channels;
|
int num_channels;
|
||||||
|
|
||||||
struct mcctrl_channel *channels;
|
struct mcctrl_channel *channels;
|
||||||
|
|
||||||
@@ -45,6 +45,21 @@ int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp)
|
|||||||
return aal_ikc_send(channels[cpu].c, pisp, 0);
|
return aal_ikc_send(channels[cpu].c, pisp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg)
|
||||||
|
{
|
||||||
|
struct ikc_scd_packet packet;
|
||||||
|
|
||||||
|
if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.msg = msg;
|
||||||
|
packet.ref = ref;
|
||||||
|
packet.arg = arg;
|
||||||
|
|
||||||
|
return aal_ikc_send(channels[cpu].c, &packet, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int mcctrl_ikc_set_recv_cpu(int cpu)
|
int mcctrl_ikc_set_recv_cpu(int cpu)
|
||||||
{
|
{
|
||||||
aal_ikc_channel_set_cpu(channels[cpu].c,
|
aal_ikc_channel_set_cpu(channels[cpu].c,
|
||||||
@@ -54,6 +69,15 @@ int mcctrl_ikc_set_recv_cpu(int cpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mcctrl_ikc_is_valid_thread(int cpu)
|
||||||
|
{
|
||||||
|
if (cpu < 0 || cpu >= num_channels || !channels[cpu].c) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long *mcctrl_doorbell_va;
|
unsigned long *mcctrl_doorbell_va;
|
||||||
unsigned long mcctrl_doorbell_pa;
|
unsigned long mcctrl_doorbell_pa;
|
||||||
|
|
||||||
@@ -68,6 +92,8 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printk("IKC init: %d\n", cpu);
|
||||||
|
|
||||||
phys = aal_device_map_memory(aal_os_to_dev(os), rphys,
|
phys = aal_device_map_memory(aal_os_to_dev(os), rphys,
|
||||||
sizeof(struct ikc_scd_init_param));
|
sizeof(struct ikc_scd_init_param));
|
||||||
rpm = ioremap_wc(phys, sizeof(struct ikc_scd_init_param));
|
rpm = ioremap_wc(phys, sizeof(struct ikc_scd_init_param));
|
||||||
@@ -79,6 +105,7 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys)
|
|||||||
pmc->param.post_va = (void *)__get_free_page(GFP_KERNEL);
|
pmc->param.post_va = (void *)__get_free_page(GFP_KERNEL);
|
||||||
pmc->param.post_pa = virt_to_phys(pmc->param.post_va);
|
pmc->param.post_pa = virt_to_phys(pmc->param.post_va);
|
||||||
memset(pmc->param.doorbell_va, 0, PAGE_SIZE);
|
memset(pmc->param.doorbell_va, 0, PAGE_SIZE);
|
||||||
|
memset(pmc->param.request_va, 0, PAGE_SIZE);
|
||||||
memset(pmc->param.post_va, 0, PAGE_SIZE);
|
memset(pmc->param.post_va, 0, PAGE_SIZE);
|
||||||
|
|
||||||
pmc->param.response_rpa = rpm->response_page;
|
pmc->param.response_rpa = rpm->response_page;
|
||||||
@@ -86,8 +113,8 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys)
|
|||||||
= aal_device_map_memory(aal_os_to_dev(os),
|
= aal_device_map_memory(aal_os_to_dev(os),
|
||||||
pmc->param.response_rpa,
|
pmc->param.response_rpa,
|
||||||
PAGE_SIZE);
|
PAGE_SIZE);
|
||||||
pmc->param.response_va = ioremap_wc(pmc->param.response_pa,
|
pmc->param.response_va = ioremap_cache(pmc->param.response_pa,
|
||||||
PAGE_SIZE);
|
PAGE_SIZE);
|
||||||
|
|
||||||
pmc->dma_buf = (void *)__get_free_pages(GFP_KERNEL,
|
pmc->dma_buf = (void *)__get_free_pages(GFP_KERNEL,
|
||||||
DMA_PIN_SHIFT - PAGE_SHIFT);
|
DMA_PIN_SHIFT - PAGE_SHIFT);
|
||||||
@@ -103,6 +130,9 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys)
|
|||||||
printk("Request: %lx, Response: %lx, Doorbell: %lx\n",
|
printk("Request: %lx, Response: %lx, Doorbell: %lx\n",
|
||||||
pmc->param.request_pa, pmc->param.response_rpa,
|
pmc->param.request_pa, pmc->param.response_rpa,
|
||||||
pmc->param.doorbell_pa);
|
pmc->param.doorbell_pa);
|
||||||
|
printk("Request: %p, Response: %p, Doorbell: %p\n",
|
||||||
|
pmc->param.request_va, pmc->param.response_va,
|
||||||
|
pmc->param.doorbell_va);
|
||||||
|
|
||||||
aal_ikc_send(pmc->c, &packet, 0);
|
aal_ikc_send(pmc->c, &packet, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -61,5 +61,6 @@ struct mcctrl_channel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp);
|
int mcctrl_ikc_send(int cpu, struct ikc_scd_packet *pisp);
|
||||||
|
int mcctrl_ikc_send_msg(int cpu, int msg, int ref, unsigned long arg);
|
||||||
|
int mcctrl_ikc_is_valid_thread(int cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ static unsigned long translate_remote_va(struct mcctrl_channel *c,
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long last_thread_exec = 0;
|
||||||
|
|
||||||
|
extern struct mcctrl_channel *channels;
|
||||||
|
|
||||||
int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
||||||
struct syscall_request *sc)
|
struct syscall_request *sc)
|
||||||
{
|
{
|
||||||
@@ -84,7 +88,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
|||||||
unsigned long pa;
|
unsigned long pa;
|
||||||
|
|
||||||
switch (sc->number) {
|
switch (sc->number) {
|
||||||
case 0:
|
case 0: /* read */
|
||||||
case 1024:
|
case 1024:
|
||||||
if (sc->number & 1024) {
|
if (sc->number & 1024) {
|
||||||
sc->args[1] = translate_remote_va(c, sc->args[1]);
|
sc->args[1] = translate_remote_va(c, sc->args[1]);
|
||||||
@@ -108,7 +112,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
|||||||
__return_syscall(c, ret);
|
__return_syscall(c, ret);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 1:
|
case 1: /* write */
|
||||||
case 1025:
|
case 1025:
|
||||||
if (sc->number & 1024) {
|
if (sc->number & 1024) {
|
||||||
sc->args[1] = translate_remote_va(c, sc->args[1]);
|
sc->args[1] = translate_remote_va(c, sc->args[1]);
|
||||||
@@ -131,7 +135,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
|||||||
__return_syscall(c, ret);
|
__return_syscall(c, ret);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 2:
|
case 2: /* open */
|
||||||
case 1026:
|
case 1026:
|
||||||
if (sc->number & 1024) {
|
if (sc->number & 1024) {
|
||||||
sc->args[0] = translate_remote_va(c, sc->args[0]);
|
sc->args[0] = translate_remote_va(c, sc->args[0]);
|
||||||
@@ -155,11 +159,27 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
|||||||
__return_syscall(c, ret);
|
__return_syscall(c, ret);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 3:
|
case 3: /* Close */
|
||||||
ret = sys_close(sc->args[0]);
|
ret = sys_close(sc->args[0]);
|
||||||
__return_syscall(c, ret);
|
__return_syscall(c, ret);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case 56: /* Clone */
|
||||||
|
last_thread_exec++;
|
||||||
|
if (mcctrl_ikc_is_valid_thread(last_thread_exec)) {
|
||||||
|
printk("Clone notification: %lx\n", sc->args[0]);
|
||||||
|
if (channels[last_thread_exec].param.post_va) {
|
||||||
|
memcpy(channels[last_thread_exec].param.post_va,
|
||||||
|
c->param.post_va, PAGE_SIZE);
|
||||||
|
}
|
||||||
|
mcctrl_ikc_send_msg(last_thread_exec,
|
||||||
|
SCD_MSG_SCHEDULE_PROCESS,
|
||||||
|
last_thread_exec, sc->args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
__return_syscall(c, 0);
|
||||||
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (sc->number & 1024) {
|
if (sc->number & 1024) {
|
||||||
__return_syscall(c, -EFAULT);
|
__return_syscall(c, -EFAULT);
|
||||||
|
|||||||
Reference in New Issue
Block a user