System call delegation supports DMA alignment
This commit is contained in:
@ -1,6 +1,8 @@
|
|||||||
#ifndef __HEADER_SYSCALL_H
|
#ifndef __HEADER_SYSCALL_H
|
||||||
#define __HEADER_SYSCALL_H
|
#define __HEADER_SYSCALL_H
|
||||||
|
|
||||||
|
#include <aal/memconst.h>
|
||||||
|
|
||||||
#define NUM_SYSCALLS 255
|
#define NUM_SYSCALLS 255
|
||||||
|
|
||||||
#define REQUEST_PAGE_COUNT 16
|
#define REQUEST_PAGE_COUNT 16
|
||||||
@ -61,7 +63,7 @@ struct syscall_response {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct syscall_post {
|
struct syscall_post {
|
||||||
unsigned long v[4];
|
unsigned long v[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct syscall_params {
|
struct syscall_params {
|
||||||
@ -77,7 +79,7 @@ struct syscall_params {
|
|||||||
unsigned long post_rpa, post_pa;
|
unsigned long post_rpa, post_pa;
|
||||||
struct syscall_post *post_va;
|
struct syscall_post *post_va;
|
||||||
unsigned long post_fin;
|
unsigned long post_fin;
|
||||||
struct syscall_post post_buf;
|
struct syscall_post post_buf AAL_DMA_ALIGN;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -72,7 +72,7 @@ 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 AAL_DMA_ALIGN; \
|
||||||
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) \
|
||||||
@ -257,7 +257,7 @@ SYSCALL_DECLARE(uname)
|
|||||||
|
|
||||||
long sys_getxid(int n, aal_mc_user_context_t *ctx)
|
long sys_getxid(int n, aal_mc_user_context_t *ctx)
|
||||||
{
|
{
|
||||||
struct syscall_request request;
|
struct syscall_request request AAL_DMA_ALIGN;
|
||||||
|
|
||||||
request.number = n;
|
request.number = n;
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ SYSCALL_DECLARE(clone)
|
|||||||
{
|
{
|
||||||
/* Clone a new thread */
|
/* Clone a new thread */
|
||||||
struct process *new;
|
struct process *new;
|
||||||
struct syscall_request request;
|
struct syscall_request request AAL_DMA_ALIGN;
|
||||||
|
|
||||||
new = clone_process(cpu_local_var(current), aal_mc_syscall_pc(ctx),
|
new = clone_process(cpu_local_var(current), aal_mc_syscall_pc(ctx),
|
||||||
aal_mc_syscall_arg1(ctx));
|
aal_mc_syscall_arg1(ctx));
|
||||||
@ -332,8 +332,6 @@ 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;
|
||||||
@ -345,9 +343,7 @@ long syscall(int num, aal_mc_user_context_t *ctx)
|
|||||||
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_pc(ctx), aal_mc_syscall_sp(ctx));
|
||||||
aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx),
|
|
||||||
aal_mc_syscall_sp(ctx));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (syscall_table[num]) {
|
if (syscall_table[num]) {
|
||||||
|
|||||||
@ -8,6 +8,12 @@
|
|||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
#include "mcctrl.h"
|
#include "mcctrl.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define dprintk printk
|
||||||
|
#else
|
||||||
|
#define dprintk(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(wq_prepare);
|
static DECLARE_WAIT_QUEUE_HEAD(wq_prepare);
|
||||||
extern struct mcctrl_channel *channels;
|
extern struct mcctrl_channel *channels;
|
||||||
int mcctrl_ikc_set_recv_cpu(int cpu);
|
int mcctrl_ikc_set_recv_cpu(int cpu);
|
||||||
@ -145,6 +151,7 @@ int __do_in_kernel_syscall(aal_os_t os, struct mcctrl_channel *c,
|
|||||||
|
|
||||||
static int remaining_job, base_cpu, job_pos;
|
static int remaining_job, base_cpu, job_pos;
|
||||||
extern int num_channels;
|
extern int num_channels;
|
||||||
|
extern int mcctrl_dma_abort;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -163,6 +170,7 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
|||||||
c->req = 0;
|
c->req = 0;
|
||||||
#else
|
#else
|
||||||
while (1) {
|
while (1) {
|
||||||
|
c = channels + swd.cpu;
|
||||||
rdtscll(s);
|
rdtscll(s);
|
||||||
if (!remaining_job) {
|
if (!remaining_job) {
|
||||||
while (!(*c->param.doorbell_va)) {
|
while (!(*c->param.doorbell_va)) {
|
||||||
@ -193,9 +201,15 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
|||||||
} else {
|
} else {
|
||||||
c = channels + base_cpu + job_pos;
|
c = channels + base_cpu + job_pos;
|
||||||
}
|
}
|
||||||
|
if (!c) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (c->param.request_va &&
|
if (c->param.request_va &&
|
||||||
c->param.request_va->valid) {
|
c->param.request_va->valid) {
|
||||||
c->param.request_va->valid = 0; /* ack */
|
c->param.request_va->valid = 0; /* ack */
|
||||||
|
dprintk("SC #%lx, %lx\n",
|
||||||
|
c->param.request_va->number,
|
||||||
|
c->param.request_va->args[0]);
|
||||||
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,
|
||||||
@ -204,6 +218,9 @@ int mcexec_wait_syscall(aal_os_t os, struct syscall_wait_desc *__user req)
|
|||||||
}
|
}
|
||||||
#ifndef DO_USER_MODE
|
#ifndef DO_USER_MODE
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
if (mcctrl_dma_abort) {
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,16 +300,33 @@ long mcexec_ret_syscall(aal_os_t os, struct syscall_ret_desc *__user arg)
|
|||||||
mc->param.response_va->ret = ret.ret;
|
mc->param.response_va->ret = ret.ret;
|
||||||
|
|
||||||
if (ret.size > 0) {
|
if (ret.size > 0) {
|
||||||
|
/* Host => Accel. Write is fast. */
|
||||||
|
unsigned long phys;
|
||||||
|
void *rpm;
|
||||||
|
|
||||||
|
phys = aal_device_map_memory(aal_os_to_dev(os), ret.dest,
|
||||||
|
ret.size);
|
||||||
|
rpm = ioremap_wc(phys, ret.size);
|
||||||
|
|
||||||
|
memcpy(rpm, phys_to_virt(ret.src), ret.size);
|
||||||
|
mc->param.response_va->status = 1;
|
||||||
|
|
||||||
|
iounmap(rpm);
|
||||||
|
aal_device_unmap_memory(aal_os_to_dev(os), phys, ret.size);
|
||||||
|
|
||||||
|
/*
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
request.src_os = NULL;
|
request.src_os = NULL;
|
||||||
request.src_phys = ret.src;
|
request.src_phys = ret.src;
|
||||||
request.dest_os = os;
|
request.dest_os = os;
|
||||||
request.dest_phys = ret.dest;
|
request.dest_phys = ret.dest;
|
||||||
request.size = ret.size;
|
request.size = ret.size;
|
||||||
request.notify = (void *)mc->param.response_pa;
|
request.notify_os = os;
|
||||||
|
request.notify = (void *)mc->param.response_rpa;
|
||||||
request.priv = (void *)1;
|
request.priv = (void *)1;
|
||||||
|
|
||||||
aal_dma_request(channel, &request);
|
aal_dma_request(channel, &request);
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
mc->param.response_va->status = 1;
|
mc->param.response_va->status = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
extern long __mcctrl_control(aal_os_t, unsigned int, unsigned long);
|
extern long __mcctrl_control(aal_os_t, unsigned int, unsigned long);
|
||||||
extern int prepare_ikc_channels(aal_os_t os);
|
extern int prepare_ikc_channels(aal_os_t os);
|
||||||
|
extern void destroy_ikc_channels(aal_os_t os);
|
||||||
|
|
||||||
static long mcctrl_ioctl(aal_os_t os, unsigned int request, void *priv,
|
static long mcctrl_ioctl(aal_os_t os, unsigned int request, void *priv,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
@ -47,13 +48,14 @@ static int __init mcctrl_init(void)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return aal_os_register_user_call_handlers(os, &mcctrl_uc);
|
return aal_os_register_user_call_handlers(os, &mcctrl_uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit mcctrl_exit(void)
|
static void __exit mcctrl_exit(void)
|
||||||
{
|
{
|
||||||
|
printk("mcctrl: unregistered.\n");
|
||||||
aal_os_unregister_user_call_handlers(os, &mcctrl_uc);
|
aal_os_unregister_user_call_handlers(os, &mcctrl_uc);
|
||||||
|
destroy_ikc_channels(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|||||||
@ -7,6 +7,8 @@
|
|||||||
#include <aal/ikc.h>
|
#include <aal/ikc.h>
|
||||||
#include <ikc/master.h>
|
#include <ikc/master.h>
|
||||||
|
|
||||||
|
#define REQUEST_SHIFT 16
|
||||||
|
|
||||||
int num_channels;
|
int num_channels;
|
||||||
|
|
||||||
struct mcctrl_channel *channels;
|
struct mcctrl_channel *channels;
|
||||||
@ -98,7 +100,9 @@ static void mcctrl_ikc_init(aal_os_t os, int cpu, unsigned long 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));
|
||||||
|
|
||||||
pmc->param.request_va = (void *)__get_free_pages(GFP_KERNEL, 4);
|
pmc->param.request_va =
|
||||||
|
(void *)__get_free_pages(GFP_KERNEL,
|
||||||
|
REQUEST_SHIFT - PAGE_SHIFT);
|
||||||
pmc->param.request_pa = virt_to_phys(pmc->param.request_va);
|
pmc->param.request_pa = virt_to_phys(pmc->param.request_va);
|
||||||
pmc->param.doorbell_va = mcctrl_doorbell_va;
|
pmc->param.doorbell_va = mcctrl_doorbell_va;
|
||||||
pmc->param.doorbell_pa = mcctrl_doorbell_pa;
|
pmc->param.doorbell_pa = mcctrl_doorbell_pa;
|
||||||
@ -199,3 +203,33 @@ int prepare_ikc_channels(aal_os_t os)
|
|||||||
aal_ikc_listen_port(os, &listen_param);
|
aal_ikc_listen_port(os, &listen_param);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __destroy_ikc_channel(aal_os_t os, struct mcctrl_channel *pmc)
|
||||||
|
{
|
||||||
|
free_pages((unsigned long)pmc->param.request_va,
|
||||||
|
REQUEST_SHIFT - PAGE_SHIFT);
|
||||||
|
free_page((unsigned long)pmc->param.post_va);
|
||||||
|
|
||||||
|
iounmap(pmc->param.response_va);
|
||||||
|
aal_device_unmap_memory(aal_os_to_dev(os),
|
||||||
|
pmc->param.response_pa, PAGE_SIZE);
|
||||||
|
free_pages((unsigned long)pmc->dma_buf,
|
||||||
|
DMA_PIN_SHIFT - PAGE_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_ikc_channels(aal_os_t os)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_channels; i++) {
|
||||||
|
if (channels[i].c) {
|
||||||
|
// aal_ikc_disconnect(channels[i].c);
|
||||||
|
aal_ikc_free_channel(channels[i].c);
|
||||||
|
__destroy_ikc_channel(os, channels + i);
|
||||||
|
printk("Channel #%d freed.\n", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free_page((unsigned long)mcctrl_doorbell_va);
|
||||||
|
|
||||||
|
kfree(channels);
|
||||||
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#define SCD_MSG_SYSCALL_ONESIDE 0x4
|
#define SCD_MSG_SYSCALL_ONESIDE 0x4
|
||||||
|
|
||||||
#define DMA_PIN_SHIFT 16
|
#define DMA_PIN_SHIFT 21
|
||||||
|
|
||||||
struct ikc_scd_packet {
|
struct ikc_scd_packet {
|
||||||
int msg;
|
int msg;
|
||||||
@ -35,7 +35,7 @@ struct ikc_scd_init_param {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct syscall_post {
|
struct syscall_post {
|
||||||
unsigned long v[4];
|
unsigned long v[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct syscall_params {
|
struct syscall_params {
|
||||||
|
|||||||
@ -9,11 +9,28 @@
|
|||||||
#include <asm/delay.h>
|
#include <asm/delay.h>
|
||||||
#include "mcctrl.h"
|
#include "mcctrl.h"
|
||||||
|
|
||||||
|
#define ALIGN_WAIT_BUF(z) (((z + 63) >> 6) << 6)
|
||||||
|
|
||||||
|
#define SC_DEBUG
|
||||||
|
#ifdef SC_DEBUG
|
||||||
|
static struct aal_dma_request last_request;
|
||||||
|
|
||||||
|
static void print_dma_lastreq(void)
|
||||||
|
{
|
||||||
|
printk("SRC OS : %p | %lx\nDESTOS : %p | %lx\n", last_request.src_os,
|
||||||
|
last_request.src_phys, last_request.dest_os,
|
||||||
|
last_request.dest_phys);
|
||||||
|
printk("SIZE : %lx | NOTIFY : %p | PRIV : %p\n",
|
||||||
|
last_request.size, last_request.notify, last_request.priv);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int do_async_copy(aal_os_t os, unsigned long dest, unsigned long src,
|
static int do_async_copy(aal_os_t os, unsigned long dest, unsigned long src,
|
||||||
unsigned long size, unsigned int inbound)
|
unsigned long size, unsigned int inbound)
|
||||||
{
|
{
|
||||||
struct aal_dma_request request;
|
struct aal_dma_request request;
|
||||||
aal_dma_channel_t channel;
|
aal_dma_channel_t channel;
|
||||||
|
unsigned long asize = ALIGN_WAIT_BUF(size);
|
||||||
|
|
||||||
channel = aal_device_get_dma_channel(aal_os_to_dev(os), 0);
|
channel = aal_device_get_dma_channel(aal_os_to_dev(os), 0);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
@ -21,28 +38,48 @@ static int do_async_copy(aal_os_t os, unsigned long dest, unsigned long src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
request.src_os = os;
|
request.src_os = inbound ? os : NULL;
|
||||||
request.src_phys = src;
|
request.src_phys = src;
|
||||||
request.dest_os = NULL;
|
request.dest_os = inbound ? NULL : os;
|
||||||
request.dest_phys = dest;
|
request.dest_phys = dest;
|
||||||
request.size = size;
|
request.size = size;
|
||||||
request.notify = (void *)(inbound ? dest + size : src + size);
|
request.notify = (void *)(inbound ? dest + asize : src + asize);
|
||||||
request.priv = (void *)1;
|
request.priv = (void *)1;
|
||||||
|
|
||||||
|
*(unsigned long *)phys_to_virt((unsigned long)request.notify) = 0;
|
||||||
|
#ifdef SC_DEBUG
|
||||||
|
last_request = request;
|
||||||
|
#endif
|
||||||
|
|
||||||
aal_dma_request(channel, &request);
|
aal_dma_request(channel, &request);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mcctrl_dma_abort;
|
||||||
|
|
||||||
static void async_wait(unsigned char *p, int size)
|
static void async_wait(unsigned char *p, int size)
|
||||||
{
|
{
|
||||||
while (!p[size]) {
|
int asize = ALIGN_WAIT_BUF(size);
|
||||||
|
unsigned long long s, w;
|
||||||
|
|
||||||
|
rdtscll(s);
|
||||||
|
while (!p[asize]) {
|
||||||
mb();
|
mb();
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
rdtscll(w);
|
||||||
|
if (w > s + 1024UL * 1024 * 1024 * 10) {
|
||||||
|
printk("DMA Timed out : %p (%p + %d) => %d\n",
|
||||||
|
p + asize, p, size, p[asize]);
|
||||||
|
print_dma_lastreq();
|
||||||
|
mcctrl_dma_abort = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void clear_wait(unsigned char *p, int size)
|
static void clear_wait(unsigned char *p, int size)
|
||||||
{
|
{
|
||||||
|
int asize = ALIGN_WAIT_BUF(size);
|
||||||
p[size] = 0;
|
p[size] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +112,6 @@ static unsigned long translate_remote_va(struct mcctrl_channel *c,
|
|||||||
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long last_thread_exec = 0;
|
unsigned long last_thread_exec = 0;
|
||||||
|
|
||||||
extern struct mcctrl_channel *channels;
|
extern struct mcctrl_channel *channels;
|
||||||
|
|||||||
Reference in New Issue
Block a user