This commit is contained in:
Taku Shimosawa
2011-12-02 12:35:38 +09:00
parent 5fdb3b2bb2
commit 7999653a00
18 changed files with 536 additions and 64 deletions

View File

@@ -1,6 +1,6 @@
AALDIR=$(AALBASE)/$(TARGET)
OBJS = init.o mem.o debug.o mikc.o listeners.o ap.o syscall.o cls.o host.o
OBJS += process.o
OBJS += process.o copy.o
DEPSRCS=$(wildcard $(SRC)/*.c)
include $(SRC)/configs/config.$(TARGET)

32
kernel/copy.c Normal file
View File

@@ -0,0 +1,32 @@
#include <aal/dma.h>
#include <amemcpy.h>
int memcpy_async(unsigned long dest, unsigned long src,
unsigned long len, int wait, unsigned long *notify)
{
struct aal_dma_request req;
unsigned long fin = 0;
if (notify)
*notify = 0;
memset(&req, 0, sizeof(req));
req.src_phys = src;
req.dest_phys = dest;
req.size = len;
if (notify) {
req.notify = (void *)virt_to_phys(notify);
req.priv = (void *)1;
} else if (wait) {
req.notify = (void *)virt_to_phys(&fin);
req.priv = (void *)1;
}
aal_mc_dma_request(0, &req);
if (wait) {
while (!fin) {
barrier();
}
}
return 0;
}

View File

@@ -36,6 +36,9 @@ int kprintf(const char *format, ...)
va_start(va, format);
flags = aal_mc_spinlock_lock(&kmsg_lock);
if (kmsg_buf.tail >= kmsg_buf.len - 1) {
kmsg_buf.tail = 0;
}
len = vsnprintf(kmsg_buf.str + kmsg_buf.tail,
kmsg_buf.len - kmsg_buf.tail, format, va);

View File

@@ -19,6 +19,7 @@ static void process_msg_prepare_process(unsigned long rphys)
struct program_load_desc *p, *pn;
int i, npages, n;
struct process *proc;
unsigned long addr;
sz = sizeof(struct program_load_desc)
+ sizeof(struct program_image_section) * 16;
@@ -38,6 +39,9 @@ static void process_msg_prepare_process(unsigned long rphys)
proc = create_process(p->entry);
proc->pid = p->pid;
/* TODO: Clear it at the proper timing */
cpu_local_var(scp).post_idx = 0;
for (i = 0; i < n; i++) {
s = (pn->sections[i].vaddr) & PAGE_MASK;
e = (pn->sections[i].vaddr + pn->sections[i].len
@@ -65,8 +69,25 @@ static void process_msg_prepare_process(unsigned long rphys)
}
proc->region.brk_start = proc->region.brk_end = proc->region.data_end;
proc->region.map_start = proc->region.map_end =
(USER_END / 3) & PAGE_MASK;
(USER_END / 3) & LARGE_PAGE_MASK;
/* Map system call stuffs */
addr = proc->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,
VR_REMOTE | VR_RESERVED);
addr = e;
e = addr + PAGE_SIZE * REQUEST_PAGE_COUNT;
add_process_memory_range(proc, addr, e,
cpu_local_var(scp).request_pa,
VR_REMOTE | VR_RESERVED);
addr = e;
e = addr + PAGE_SIZE * RESPONSE_PAGE_COUNT;
add_process_memory_range(proc, addr, e,
cpu_local_var(scp).response_pa,
VR_RESERVED);
p->rprocess = (unsigned long)proc;
init_process_stack(proc);
@@ -84,7 +105,7 @@ static void process_msg_init(struct ikc_scd_init_param *pcp)
struct syscall_params *lparam;
lparam = &cpu_local_var(scp);
lparam->response_va = allocate_pages(1, 0);
lparam->response_va = allocate_pages(RESPONSE_PAGE_COUNT, 0);
lparam->response_pa = virt_to_phys(lparam->response_va);
pcp->request_page = 0;
@@ -100,16 +121,27 @@ static void process_msg_init_acked(unsigned long pphys)
lparam = &cpu_local_var(scp);
lparam->request_rpa = param->request_page;
lparam->request_pa = aal_mc_map_memory(NULL, param->request_page,
PAGE_SIZE);
lparam->request_va = aal_mc_map_virtual(lparam->request_pa, 1,
REQUEST_PAGE_COUNT * PAGE_SIZE);
lparam->request_va = aal_mc_map_virtual(lparam->request_pa,
REQUEST_PAGE_COUNT,
PTATTR_WRITABLE);
lparam->doorbell_rpa = param->doorbell_page;
lparam->doorbell_pa = aal_mc_map_memory(NULL, param->doorbell_page,
DOORBELL_PAGE_COUNT *
PAGE_SIZE);
lparam->doorbell_va = aal_mc_map_virtual(lparam->doorbell_pa, 1,
lparam->doorbell_va = aal_mc_map_virtual(lparam->doorbell_pa,
DOORBELL_PAGE_COUNT,
PTATTR_WRITABLE);
lparam->post_rpa = param->post_page;
lparam->post_pa = aal_mc_map_memory(NULL, param->post_page,
PAGE_SIZE);
lparam->post_va = aal_mc_map_virtual(lparam->post_pa, 1,
PTATTR_WRITABLE);
lparam->post_fin = 1;
kprintf("Syscall parameters:\n");
kprintf(" Response: %lx, %p\n",
lparam->response_pa, lparam->response_va);
@@ -117,7 +149,8 @@ static void process_msg_init_acked(unsigned long pphys)
lparam->request_pa, lparam->request_rpa, lparam->request_va);
kprintf(" Doorbell: %lx, %lx, %p\n",
lparam->doorbell_pa, lparam->doorbell_rpa, lparam->doorbell_va);
kprintf(" Post: %lx, %lx, %p\n",
lparam->post_pa, lparam->post_rpa, lparam->post_va);
}
static void syscall_channel_send(struct aal_ikc_channel_desc *c,
@@ -150,6 +183,7 @@ static int syscall_packet_handler(struct aal_ikc_channel_desc *c,
case SCD_MSG_SCHEDULE_PROCESS:
kprintf("next one : %lx\n", packet->arg);
cpu_local_var(next) = (struct process *)packet->arg;
return 0;
}

16
kernel/include/amemcpy.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef HEADER_AMEMCPY_H
#define HEADER_AMEMCPY_H
#include <aal/cpu.h>
static void memcpy_async_wait(unsigned long *notify)
{
while (!*notify) {
cpu_pause();
}
}
int memcpy_async(unsigned long dest, unsigned long src,
unsigned long len, int wait, unsigned long *notify);
#endif

View File

@@ -6,7 +6,12 @@
#include <aal/mm.h>
#include <list.h>
#define VR_STACK 1
#define VR_STACK 0x1
#define VR_RESERVED 0x2
#define VR_IO_NOCACHE 0x100
#define VR_REMOTE 0x200
#define PS_ZOMBIE 0x1
struct vm_range {
struct list_head list;
@@ -37,6 +42,9 @@ struct process {
};
struct process *create_process(unsigned long user_pc);
void destroy_process(struct process *proc);
void free_process_memory(struct process *proc);
int add_process_memory_range(struct process *process,
unsigned long start, unsigned long end,
unsigned long phys, unsigned long flag);

View File

@@ -3,6 +3,12 @@
#define NUM_SYSCALLS 255
#define REQUEST_PAGE_COUNT 16
#define RESPONSE_PAGE_COUNT 16
#define DOORBELL_PAGE_COUNT 1
#define SCD_RESERVED_COUNT \
(REQUEST_PAGE_COUNT + RESPONSE_PAGE_COUNT + DOORBELL_PAGE_COUNT)
#define SCD_MSG_PREPARE_PROCESS 0x1
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
#define SCD_MSG_SCHEDULE_PROCESS 0x3
@@ -40,6 +46,7 @@ struct ikc_scd_init_param {
unsigned long request_page;
unsigned long response_page;
unsigned long doorbell_page;
unsigned long post_page;
};
struct syscall_request {
@@ -52,6 +59,10 @@ struct syscall_response {
long ret;
};
struct syscall_post {
unsigned long v[4];
};
struct syscall_params {
unsigned long request_rpa, request_pa;
struct syscall_request *request_va;
@@ -60,6 +71,12 @@ struct syscall_params {
unsigned long doorbell_rpa, doorbell_pa;
unsigned long *doorbell_va;
unsigned int post_idx;
unsigned long post_rpa, post_pa;
struct syscall_post *post_va;
unsigned long post_fin;
struct syscall_post post_buf;
};
#endif

View File

@@ -53,31 +53,49 @@ static void dma_test(void)
}
}
extern char *aal_mc_get_kernel_args(void);
char *find_command_line(char *name)
{
char *cmdline = aal_mc_get_kernel_args();
if (!cmdline) {
return NULL;
}
return strstr(cmdline, name);
}
static void pc_test(void)
{
int i;
int kmode = PERFCTR_USER_MODE;
int x[2][4] = { { APT_TYPE_L1D_MISS, APT_TYPE_L1I_MISS,
int kmode = PERFCTR_KERNEL_MODE;
int imode = 1;
char *p;
int x[2][4] = { { APT_TYPE_L1D_REQUEST,
APT_TYPE_L1D_MISS,
APT_TYPE_L2_MISS, APT_TYPE_INSTRUCTIONS, },
{ APT_TYPE_STALL, APT_TYPE_L1I_MISS,
APT_TYPE_L2_MISS, APT_TYPE_INSTRUCTIONS, }};
{ APT_TYPE_L1I_MISS, APT_TYPE_LLC_MISS,
APT_TYPE_STALL, APT_TYPE_CYCLE },
};
if (!(p = find_command_line("perfctr"))) {
kprintf("perfctr not initialized.\n");
return;
}
if (p[7] == '=' && p[8] >= '0' && p[8] <= '5') {
i = p[8] - '0';
kmode = (i >> 1) + 1;
imode = (i & 1);
} else {
kprintf("perfctr not initialized.\n");
return;
}
kprintf("perfctr mode : priv = %d, set = %d\n", kmode, imode);
for (i = 0; i < 4; i++) {
aal_mc_perfctr_init(i, x[1][i], kmode);
aal_mc_perfctr_init(i, x[imode][i], kmode);
}
aal_mc_perfctr_start(0xf);
/*
aal_mc_perfctr_read_mask(0x0f, st);
for (i = 0; i < 100000; i++) {
data[i & 1023] += i;
asm volatile("" : : : "memory");
}
aal_mc_perfctr_read_mask(0x0f, ed);
aal_mc_perfctr_stop(1);
kprintf("INS = %ld, %ld, %ld\n", st[0], ed[0], ed[0] - st[0]);
kprintf("L2M = %ld, %ld, %ld\n", st[1], ed[1], ed[1] - st[1]);
*/
}
static void rest_init(void)

View File

@@ -151,6 +151,8 @@ void *kmalloc(int size, enum aal_mc_ap_flag flag)
struct cpu_local_var *v = get_this_cpu_local_var();
struct malloc_header *h = &v->free_list, *prev, *p;
int u, req_page;
unsigned long flags;
if (size >= PAGE_SIZE * 4) {
return NULL;
@@ -158,6 +160,8 @@ void *kmalloc(int size, enum aal_mc_ap_flag flag)
u = (size + sizeof(*h) - 1) / sizeof(*h);
flags = cpu_disable_interrupt_save();
prev = h;
h = h->next;
@@ -172,12 +176,15 @@ void *kmalloc(int size, enum aal_mc_ap_flag flag)
/* Guard entry */
p = h + h->size + 1;
p->next = &v->free_list;
p->size = 0;
h->next = p;
}
if (h->size >= u) {
if (h->size == u || h->size == u + 1) {
prev->next = h->next;
cpu_restore_interrupt(flags);
return h + 1;
} else { /* Divide */
h->size -= u + 1;
@@ -185,6 +192,7 @@ void *kmalloc(int size, enum aal_mc_ap_flag flag)
p = h + h->size + 1;
p->size = u;
cpu_restore_interrupt(flags);
return p + 1;
}
}
@@ -198,7 +206,9 @@ void kfree(void *ptr)
struct cpu_local_var *v = get_this_cpu_local_var();
struct malloc_header *h = &v->free_list, *p = ptr;
int combined = 0;
unsigned long flags;
flags = cpu_disable_interrupt_save();
h = h->next;
p--;
@@ -212,14 +222,19 @@ void kfree(void *ptr)
h->size += p->size + 1;
}
if (h->next == p + p->size + 1 && h->next->size != 0) {
combined = 1;
h->size += h->next->size + 1;
h->next = h->next->next;
}
if (!combined) {
if (combined) {
h->size += h->next->size + 1;
h->next = h->next->next;
} else {
p->size += h->next->size + 1;
p->next = h->next->next;
h->next = p;
}
} else if (!combined) {
p->next = h->next;
h->next = p;
}
cpu_restore_interrupt(flags);
}
void print_free_list(void)

View File

@@ -23,14 +23,18 @@ struct process *create_process(unsigned long user_pc)
return proc;
}
void update_process_page_table(struct process *process, struct vm_range *range)
extern void __host_update_process_range(struct process *process,
struct vm_range *range);
void update_process_page_table(struct process *process, struct vm_range *range,
enum aal_mc_pt_attribute flag)
{
unsigned long p, pa = range->phys;
p = range->start;
while (p < range->end) {
aal_mc_pt_set_page(process->page_table, (void *)p,
pa, PTATTR_WRITABLE | PTATTR_USER);
pa, PTATTR_WRITABLE | PTATTR_USER | flag);
pa += PAGE_SIZE;
p += PAGE_SIZE;
@@ -57,7 +61,17 @@ int add_process_memory_range(struct process *process,
range->start, range->end, range->phys, range->phys +
range->end - range->start);
update_process_page_table(process, range);
if (flag & VR_REMOTE) {
update_process_page_table(process, range, AAL_PTA_REMOTE);
} else if (flag & VR_IO_NOCACHE) {
update_process_page_table(process, range, PTATTR_UNCACHABLE);
} else {
update_process_page_table(process, range, 0);
}
if (!(flag & VR_REMOTE)) {
__host_update_process_range(process, range);
}
list_add_tail(&range->list, &process->vm_range_list);
@@ -73,19 +87,23 @@ void init_process_stack(struct process *process)
add_process_memory_range(process, USER_END - PAGE_SIZE,
USER_END,
virt_to_phys(p), VR_STACK);
virt_to_phys(stack), VR_STACK);
/* TODO: fill with actual value of argc, argv, envp */
p[-1] = 0; /* env: "" */
p[-2] = 0x41; /* argv(0): "a" */
p[-3] = USER_END - sizeof(unsigned long); /* envp: END - 8 */
p[-4] = 0; /* argv[1] = NULL */
p[-5] = USER_END - sizeof(unsigned long) * 2; /* argv[0] = END - 16 */
p[-6] = 1; /* argc */
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[-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) * 6);
USER_END - sizeof(unsigned long) * 8);
process->region.stack_end = USER_END;
process->region.stack_start = USER_END - PAGE_SIZE;
}
@@ -128,6 +146,7 @@ int remove_process_region(struct process *proc,
return -EINVAL;
}
/* We defer freeing to the time of exit */
while (start < end) {
aal_mc_pt_clear_page(proc->page_table, (void *)start);
start += PAGE_SIZE;
@@ -136,6 +155,32 @@ int remove_process_region(struct process *proc,
return 0;
}
extern void print_free_list(void);
void free_process_memory(struct process *proc)
{
struct vm_range *range, *next;
list_for_each_entry_safe(range, next, &proc->vm_range_list,
list) {
if (!(range->flag & VR_REMOTE) &&
!(range->flag & VR_IO_NOCACHE) &&
!(range->flag & VR_RESERVED)) {
aal_mc_free_pages(phys_to_virt(range->phys),
(range->end - range->start)
>> PAGE_SHIFT);
}
list_del(&range->list);
aal_mc_free(range);
}
/* TODO: Free page tables */
proc->status = PS_ZOMBIE;
}
void destroy_process(struct process *proc)
{
aal_mc_free_pages(proc, 1);
}
static void idle(void)
{
while (1) {
@@ -175,7 +220,8 @@ void schedule(void)
cpu_enable_interrupt();
if (switch_ctx) {
kprintf("schedule: %p => %p \n", prev, next);
kprintf("schedule: %p (%p) => %p (%p) \n", prev,
prev->page_table, next, next->page_table);
aal_mc_load_page_table(next->page_table);
if (prev) {

View File

@@ -8,21 +8,36 @@
#include <cls.h>
#include <syscall.h>
#include <page.h>
#include <amemcpy.h>
int memcpy_async(unsigned long dest, unsigned long src,
unsigned long len, int wait, unsigned long *notify);
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;
res->status = 0;
/* TODO: copy by DMA */
memcpy_long(cpu_local_var(scp).request_va, req, sizeof(*req));
memcpy_async(cpu_local_var(scp).request_pa,
virt_to_phys(req), sizeof(*req), 0, &fin);
memcpy_async_wait(&cpu_local_var(scp).post_fin);
cpu_local_var(scp).post_va->v[0] = cpu_local_var(scp).post_idx;
memcpy_async_wait(&fin);
*(unsigned int *)cpu_local_var(scp).doorbell_va = 1;
#ifdef SYSCALL_BY_IKC
packet.msg = SCD_MSG_SYSCALL_ONESIDE;
packet.ref = aal_mc_get_processor_id();
packet.arg = cpu_local_var(scp).request_rpa;
aal_ikc_send(cpu_local_var(syscall_channel), &packet, 0);
aal_ikc_send(cpu_local_var(syscall_channel), &packet, 0);
#endif
}
static int do_syscall(struct syscall_request *req)
@@ -103,9 +118,7 @@ static int stop(void)
SYSCALL_DECLARE(open)
{
SYSCALL_HEADER;
SYSCALL_ARGS_3(MI, D, D);
SYSCALL_FOOTER;
}
@@ -169,10 +182,11 @@ SYSCALL_DECLARE(lseek)
SYSCALL_DECLARE(exit_group)
{
SYSCALL_HEADER;
send_syscall(&request);
do_syscall(&request);
cpu_local_var(current) = NULL;
free_process_memory(cpu_local_var(current));
cpu_local_var(next) = &cpu_local_var(idle);
schedule();
return 0;
@@ -308,3 +322,34 @@ long syscall(int num, aal_mc_user_context_t *ctx)
return -ENOSYS;
}
}
void __host_update_process_range(struct process *process,
struct vm_range *range)
{
struct syscall_post *post;
int idx;
memcpy_async_wait(&cpu_local_var(scp).post_fin);
post = &cpu_local_var(scp).post_buf;
post->v[0] = 1;
post->v[1] = range->start;
post->v[2] = range->end;
post->v[3] = range->phys;
cpu_disable_interrupt();
if (cpu_local_var(scp).post_idx >=
PAGE_SIZE / sizeof(struct syscall_post)) {
/* XXX: Wait until it is consumed */
} else {
idx = ++(cpu_local_var(scp).post_idx);
cpu_local_var(scp).post_fin = 0;
memcpy_async(cpu_local_var(scp).post_pa +
idx * sizeof(*post),
virt_to_phys(post), sizeof(*post), 0,
&cpu_local_var(scp).post_fin);
}
cpu_enable_interrupt();
}