Commit 75c72eaa authored by Anton Burtsev's avatar Anton Burtsev Committed by Vikram Narayanan

First API call: create sync endpoint

parent fc2675ff
......@@ -8,7 +8,15 @@
#include <uapi/linux/lcd-api.h>
#include <lcd/cap.h>
#include <lcd/ipc.h>
#include <lcd/cap-cache.h>
int lcd_api_init(void);
int lcd_api_exit(void);
struct lcd_api {
struct cap_cache cap_cache;
int api_thread_exit;
capability_t rvp;
};
int lcd_api_init(struct lcd_api *api);
int lcd_api_exit(struct lcd_api *api);
#endif
......@@ -66,8 +66,8 @@ inline void transfer_msg(struct task_struct *to, struct task_struct *from) {
// BU: TODO: transfer capabilities
//
// Transfer call capability
//
// Transfer err code
to->utcb->msg_info.err = from->utcb->msg_info.err;
return;
}
......@@ -119,7 +119,7 @@ int ipc_send(capability_t rvp_cap, struct message_info *msg)
// XXX: BU: Maybe I need to do some reference counting for IPC
// objects here (before releasing the lock)
lcd_cnode_release(&cnode);
lcd_cnode_release(cnode);
spin_lock_irqsave(&sync_ipc->lock, flags);
if (list_empty(&sync_ipc->receivers)) {
......
......@@ -10,9 +10,8 @@
#include <linux/sched.h>
#include <linux/kthread.h>
struct cap_cache cap_cache;
int lcd_api_create_sync_endpoint(capability_t reply_cap) {
int lcd_api_create_sync_endpoint(struct lcd_api *api, capability_t reply_cap) {
int ret;
struct sync_ipc *rvp;
capability_t free_cap;
......@@ -26,7 +25,7 @@ int lcd_api_create_sync_endpoint(capability_t reply_cap) {
goto err;
};
ret = lcd_alloc_cap(&cap_cache, &free_cap);
ret = lcd_alloc_cap(&api->cap_cache, &free_cap);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
ret = -ENOSPC;
......@@ -53,7 +52,7 @@ int lcd_api_create_sync_endpoint(capability_t reply_cap) {
lcd_cap_drop(&current->cspace, free_cap);
lcd_free_cap(&cap_cache, free_cap);
lcd_free_cap(&api->cap_cache, free_cap);
return 0;
err:
msg->err = ret;
......@@ -61,30 +60,104 @@ err:
return ret;
};
int lcd_api_execution_loop(void) {
int lcd_api_execution_loop(struct lcd_api *lcd_api) {
struct message_info *msg = &current->utcb->msg_info;
capability_t reply_cap;
enum lcd_api_calls call;
int ret;
ret = lcd_alloc_cap(&lcd_api->cap_cache, &reply_cap);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
return -ENOSPC;
};
while (!lcd_api->api_thread_exit)
{
msg->valid_regs = sizeof(msg->regs)/sizeof(msg->regs[0]);
ret = ipc_recv(lcd_api->rvp, msg);
if (ret) {
printk(KERN_ERR "lcd_api: recv failed:%d\n", ret);
continue;
}
// We know we're serving a call invocation, reply cap must
// be there
if(msg->valid_regs == 0) {
printk(KERN_ERR "lcd_api: invalid invocation\n");
msg->valid_regs = 0;
msg->valid_cap_regs = 0;
ipc_reply(reply_cap, msg);
lcd_cap_drop(&current->cspace, reply_cap);
continue;
};
call = msg->regs[0];
switch (call) {
case LCD_CREATE_SYNC_ENDPOINT:
ret = lcd_api_create_sync_endpoint(lcd_api, reply_cap);
break;
default:
printk(KERN_ERR "lcd_api: invalid call number:%d\n", call);
msg->valid_regs = 0;
msg->valid_cap_regs = 0;
ipc_reply(reply_cap, msg);
lcd_cap_drop(&current->cspace, reply_cap);
};
};
lcd_free_cap(&lcd_api->cap_cache, reply_cap);
return 0;
};
int lcd_api_thread(void *p) {
int ret;
return lcd_api_execution_loop();
return lcd_api_execution_loop((struct lcd_api*) p);
};
int lcd_api_init(void) {
int lcd_api_init(struct lcd_api *api) {
int ret;
struct task_struct *t;
struct sync_ipc *rvp;
struct cnode *cnode;
ret = lcd_init_list_cache(&cap_cache, LCD_MAX_CAPS);
ret = lcd_init_list_cache(&api->cap_cache, LCD_MAX_CAPS);
if (ret) {
printk(KERN_ERR "Failed to initialize cap cache:%d\n", ret);
return ret;
}
t = kthread_create(lcd_api_thread, NULL, "lcd-api");
rvp = alloc_sync_ipc();
if(!rvp) {
printk(KERN_ERR "Failed to allocate memory\n");
return -ENOMEM;
};
ret = lcd_alloc_cap(&api->cap_cache, &api->rvp);
if(ret) {
printk(KERN_ERR "Failed to allocate free capability\n");
kfree(rvp);
return -ENOSPC;
};
cnode = lcd_cnode_lookup(&current->cspace, api->rvp);
if(cnode == 0) {
printk(KERN_ERR "Failed to create capability\n");
kfree(rvp);
return -ENOMEM;
};
cnode->type = LCD_TYPE_SYNC_EP;
cnode->object = rvp;
lcd_cnode_release(cnode);
t = kthread_create(lcd_api_thread, api, "lcd-api");
if (!t) {
printk(KERN_ERR "Failed to create LCD API thread\n");
return -EINVAL;
......@@ -94,5 +167,7 @@ int lcd_api_init(void) {
return 0;
}
int lcd_api_exit(struct lcd_api *api) {
api->api_thread_exit = 1;
};
......@@ -18,10 +18,13 @@
#include <lcd/lcd.h>
#include <lcd/cap.h>
#include <lcd/api.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LCD driver");
struct lcd_api lcd_api;
int lcd_enter(void) {
current->utcb = kmalloc(sizeof(struct utcb), GFP_KERNEL);
......@@ -107,6 +110,12 @@ static int __init lcd_init(void)
if(r)
return r;
r = lcd_api_init(&lcd_api);
if(r)
return r;
#if 0
printk(KERN_ERR "LCD module loaded\n");
......@@ -128,6 +137,9 @@ static int __init lcd_init(void)
static void __exit lcd_exit(void)
{
lcd_cap_exit();
lcd_api_exit(&lcd_api);
#if 0
misc_deregister(&lcd_dev);
lcd_vmx_exit();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment