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

@@ -102,6 +102,8 @@ int mcexec_load_image(aal_os_t os, struct program_transfer *__user upt)
return 0;
}
extern unsigned long last_thread_exec;
static long mcexec_start_image(aal_os_t os,
struct program_load_desc * __user udesc)
{
@@ -117,6 +119,8 @@ static long mcexec_start_image(aal_os_t os,
c = channels + desc.cpu;
mcctrl_ikc_set_recv_cpu(desc.cpu);
last_thread_exec = desc.cpu;
isp.msg = SCD_MSG_SCHEDULE_PROCESS;
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,
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)
{
struct syscall_wait_desc swd;
struct mcctrl_channel *c;
unsigned long s, w;
unsigned long s, w, d;
if (copy_from_user(&swd, req, sizeof(swd.cpu))) {
return -EFAULT;
@@ -157,20 +164,38 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
#else
while (1) {
rdtscll(s);
while (!(*c->param.doorbell_va)) {
mb();
cpu_relax();
rdtscll(w);
if (w > s + 1024 * 1024 * 1024 * 1) {
return -EINTR;
if (!remaining_job) {
while (!(*c->param.doorbell_va)) {
mb();
cpu_relax();
rdtscll(w);
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",
c->param.request_va,
c->param.request_va->valid,
c->param.request_va->number,
c->param.request_va->args[0]);
for (; job_pos < num_channels; job_pos++) {
if (base_cpu + job_pos >= num_channels) {
c = channels +
(base_cpu + job_pos - num_channels);
} 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)) {
#endif
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;
}
#ifndef DO_USER_MODE
break;
return 0;
}
}
}
remaining_job = 0;
}
#endif
return 0;

View File

@@ -7,7 +7,7 @@
#include <aal/ikc.h>
#include <ikc/master.h>
static int num_channels;
int num_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);
}
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)
{
aal_ikc_channel_set_cpu(channels[cpu].c,
@@ -54,6 +69,15 @@ int mcctrl_ikc_set_recv_cpu(int cpu)
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_pa;
@@ -68,6 +92,8 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long rphys)
return;
}
printk("IKC init: %d\n", cpu);
phys = aal_device_map_memory(aal_os_to_dev(os), rphys,
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_pa = virt_to_phys(pmc->param.post_va);
memset(pmc->param.doorbell_va, 0, PAGE_SIZE);
memset(pmc->param.request_va, 0, PAGE_SIZE);
memset(pmc->param.post_va, 0, PAGE_SIZE);
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),
pmc->param.response_rpa,
PAGE_SIZE);
pmc->param.response_va = ioremap_wc(pmc->param.response_pa,
PAGE_SIZE);
pmc->param.response_va = ioremap_cache(pmc->param.response_pa,
PAGE_SIZE);
pmc->dma_buf = (void *)__get_free_pages(GFP_KERNEL,
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",
pmc->param.request_pa, pmc->param.response_rpa,
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);

View File

@@ -61,5 +61,6 @@ struct mcctrl_channel {
};
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

View File

@@ -76,6 +76,10 @@ static unsigned long translate_remote_va(struct mcctrl_channel *c,
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,
struct syscall_request *sc)
{
@@ -84,7 +88,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
unsigned long pa;
switch (sc->number) {
case 0:
case 0: /* read */
case 1024:
if (sc->number & 1024) {
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 0;
case 1:
case 1: /* write */
case 1025:
if (sc->number & 1024) {
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 0;
case 2:
case 2: /* open */
case 1026:
if (sc->number & 1024) {
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 0;
case 3:
case 3: /* Close */
ret = sys_close(sc->args[0]);
__return_syscall(c, ret);
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:
if (sc->number & 1024) {
__return_syscall(c, -EFAULT);