This commit is contained in:
Taku Shimosawa
2012-01-06 17:06:42 +09:00
parent 00107164b3
commit d2591c6d25
12 changed files with 244 additions and 73 deletions

View File

@@ -24,7 +24,7 @@ static void ap_wait(void)
kprintf("ap started.\n");
kmalloc_init();
sched_init();
init_host_syscall_channel();
/* init_host_syscall_channel(); */
schedule();
}

View File

@@ -28,5 +28,6 @@ int memcpy_async(unsigned long dest, unsigned long src,
barrier();
}
}
return 0;
}

View File

@@ -53,26 +53,27 @@ static void process_msg_prepare_process(unsigned long rphys)
/* TODO: Maybe we need flag */
if (i == 0) {
proc->region.text_start = s;
proc->region.text_end = e;
proc->vm->region.text_start = s;
proc->vm->region.text_end = e;
} else if (i == 1) {
proc->region.data_start = s;
proc->region.data_end = e;
proc->vm->region.data_start = s;
proc->vm->region.data_end = e;
} else {
proc->region.data_start =
(s < proc->region.data_start ?
s : proc->region.data_start);
proc->region.data_end =
(e > proc->region.data_end ?
e : proc->region.data_end);
proc->vm->region.data_start =
(s < proc->vm->region.data_start ?
s : proc->vm->region.data_start);
proc->vm->region.data_end =
(e > proc->vm->region.data_end ?
e : proc->vm->region.data_end);
}
}
proc->region.brk_start = proc->region.brk_end = proc->region.data_end;
proc->region.map_start = proc->region.map_end =
proc->vm->region.brk_start = proc->vm->region.brk_end =
proc->vm->region.data_end;
proc->vm->region.map_start = proc->vm->region.map_end =
(USER_END / 3) & LARGE_PAGE_MASK;
/* 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;
add_process_memory_range(proc, addr, e,
cpu_local_var(scp).doorbell_pa,
@@ -92,7 +93,7 @@ static void process_msg_prepare_process(unsigned long rphys)
init_process_stack(proc);
kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
proc->page_table);
proc->vm->page_table);
aal_mc_free(pn);

View File

@@ -17,6 +17,7 @@ struct cpu_local_var {
struct malloc_header free_list;
struct process idle;
struct process_vm idle_vm;
struct process *current;
struct process *next;

View File

@@ -4,6 +4,7 @@
#include <aal/context.h>
#include <aal/cpu.h>
#include <aal/mm.h>
#include <aal/atomic.h>
#include <list.h>
#define VR_STACK 0x1
@@ -28,20 +29,27 @@ struct vm_regions {
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 {
int pid;
int status;
struct page_table *page_table;
struct list_head vm_range_list;
struct vm_regions region;
struct process_vm *vm;
aal_mc_kernel_context_t ctx;
aal_mc_user_context_t *uctx;
};
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 free_process_memory(struct process *proc);

View File

@@ -38,7 +38,13 @@ static void dma_test(void)
{
struct aal_dma_request req;
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));
req.src_phys = virt_to_phys(data);
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.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) {
barrier();
}
kprintf("DMA Test End.\n");
}
extern char *aal_mc_get_kernel_args(void);
@@ -127,7 +139,7 @@ static void post_init(void)
cpu_pause();
}
init_host_syscall_channel();
/* init_host_syscall_channel(); */
ap_start();
}

View File

@@ -6,6 +6,13 @@
#include <aal/debug.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 *proc;
@@ -17,8 +24,33 @@ struct process *create_process(unsigned long user_pc)
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
((char *)proc) + PAGE_SIZE, user_pc, 0);
INIT_LIST_HEAD(&proc->vm_range_list);
proc->page_table = aal_mc_pt_create();
proc->vm = (struct process_vm *)(proc + 1);
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;
}
@@ -33,7 +65,7 @@ void update_process_page_table(struct process *process, struct vm_range *range,
p = range->start;
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 += PAGE_SIZE;
@@ -73,7 +105,7 @@ int add_process_memory_range(struct process *process,
__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;
}
@@ -90,22 +122,20 @@ void init_process_stack(struct process *process)
virt_to_phys(stack), VR_STACK);
/* TODO: fill with actual value of argc, argv, envp */
kprintf("%lx, %p\n", virt_to_phys(stack), p);
p[-1] = 0; /* AT_NULL */
p[-2] = 0;
p[-3] = USER_END - sizeof(unsigned long) * 2;
p[-4] = 0; /* env: "" */
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[-8] = USER_END - sizeof(unsigned long) * 5; /* argv[0] = END - 16 */
p[-9] = 1; /* argc */
aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER,
USER_END - sizeof(unsigned long) * 8);
process->region.stack_end = USER_END;
process->region.stack_start = USER_END - PAGE_SIZE;
USER_END - sizeof(unsigned long) * 9);
process->vm->region.stack_end = USER_END;
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 */
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;
}
@@ -160,7 +190,11 @@ void free_process_memory(struct process *proc)
{
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) {
if (!(range->flag & VR_REMOTE) &&
!(range->flag & VR_IO_NOCACHE) &&
@@ -195,6 +229,9 @@ void sched_init(void)
struct process *idle_process = &cpu_local_var(idle);
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);
@@ -220,9 +257,11 @@ void schedule(void)
cpu_enable_interrupt();
if (switch_ctx) {
kprintf("schedule: %p (%p) => %p (%p) \n", prev,
prev ? prev->page_table : NULL, next, next->page_table);
aal_mc_load_page_table(next->page_table);
kprintf("[%d] schedule: %d => %d \n",
aal_mc_get_processor_id(),
prev ? prev->pid : 0, next ? next->pid : 0);
aal_mc_load_page_table(next->vm->page_table);
if (prev) {
aal_mc_switch_context(&prev->ctx, &next->ctx);

View File

@@ -18,12 +18,10 @@ static void send_syscall(struct syscall_request *req)
struct ikc_scd_packet packet;
struct syscall_response *res = cpu_local_var(scp).response_va;
unsigned long fin;
int w;
res->status = 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]);
req->valid = 0;
memcpy_async(cpu_local_var(scp).request_pa,
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);
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);
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
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)
{
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 =
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_HEADER struct syscall_request request; \
request.valid = 0; \
request.number = n
#define SYSCALL_ARG_D(n) request.args[n] = aal_mc_syscall_arg##n(ctx)
#define SYSCALL_ARG_MO(n) \
do { \
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),\
&__phys)) { \
return -EFAULT; \
@@ -89,7 +88,7 @@ long sys_brk(int n, aal_mc_user_context_t *ctx)
#define SYSCALL_ARG_MI(n) \
do { \
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),\
&__phys)) { \
return -EFAULT; \
@@ -201,7 +200,7 @@ SYSCALL_DECLARE(exit_group)
SYSCALL_DECLARE(mmap)
{
unsigned long address, ret;
struct vm_regions *region = &cpu_local_var(current)->region;
struct vm_regions *region = &cpu_local_var(current)->vm->region;
/* anonymous */
if (aal_mc_syscall_arg3(ctx) & 0x22) {
@@ -240,12 +239,12 @@ SYSCALL_DECLARE(getpid)
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;
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)) {
return -EFAULT;
}
@@ -253,7 +252,7 @@ long sys_uname(int n, aal_mc_user_context_t *ctx)
request.number = n;
request.args[0] = phys;
return do_syscall(&request), stop();
return do_syscall(&request);
}
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;
}
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 *) = {
[0] = sys_read,
[1] = sys_write,
@@ -298,6 +320,7 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
[17] = sys_pread,
[18] = sys_pwrite,
[39] = sys_getpid,
[56] = sys_clone,
[63] = sys_uname,
[102] = sys_getxid,
[104] = sys_getxid,
@@ -309,22 +332,29 @@ static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
[231] = sys_exit_group,
};
#define DEBUG_PRINT_SC
long syscall(int num, aal_mc_user_context_t *ctx)
{
long l;
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(),
num,
aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx),
aal_mc_syscall_arg2(ctx), aal_mc_syscall_arg3(ctx),
aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx),
aal_mc_syscall_sp(ctx));
#endif
if (syscall_table[num]) {
l = syscall_table[num](num, ctx);
#ifdef DEBUG_PRINT_SC
kprintf(" %lx\n", l);
#endif
return l;
} else {
kprintf("USC[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", num,