Commit 9331efca authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

Prelim work on ipc.

parent da5ab68f
......@@ -2,13 +2,6 @@
* Authors: Anton Burtsev <aburtsev@flux.utah.edu>
* Charles Jacobsen <charlesj@cs.utah.edu>
* Copyright: University of Utah
*
* This simple prototype uses a global lock on an lcd's cspace. No
* rights checking. The lcd need only have a valid cnode mapped by
* the cptr. Capability grants just copy cnode data from one cspace
* to another. Capabilities cannot be revoked, so if a cnode is valid,
* it can be used freely. Cnodes are allocated in a linear order, so
* no need to do fancy free lists, etc.
*/
#ifndef LCD_PROTOTYPE_API_DEFS_H
......@@ -17,9 +10,19 @@
#include <linux/mutex.h>
#include <linux/sched.h>
#include <lcd-prototype/lcd.h>
#include "../include/api-internal.h"
/* CAPABILITIES -------------------------------------------------- */
/*
* This simple prototype uses a global lock on an lcd's cspace. No
* rights checking. The lcd need only have a valid cnode mapped by
* the cptr. Capability grants just copy cnode data from one cspace
* to another. Capabilities cannot be revoked, so if a cnode is valid,
* it can be used freely. Cnodes are allocated in a linear order, so
* no need to do fancy free lists, etc.
*/
enum lcd_cap_type {
LCD_CAP_TYPE_UNFORMED = 0,
LCD_CAP_TYPE_SYNC_EP = 1,
......@@ -163,4 +166,30 @@ static inline int lcd_cap_can_grant(struct cspace *cspace, cptr_t cptr)
*/
void lcd_rm_cspace(struct cspace *cspace);
/* IPC -------------------------------------------------- */
/*
* There is no low-level interface to the api code, so we need
* to make the ipc routines directly callable for now, in
* include/api-internal.h. All other api code is directly or
* indirectly accessed via ipc.
*/
struct sync_endpoint {
struct list_head senders;
struct list_head receivers;
struct mutex lock;
};
/**
* Create a synchronous end point, and install it in t's cspace
* at location c.
*/
int lcd_mk_sync_endpoint(struct task_struct *t, cptr_t c);
/**
* Remove synchronous end point identified by c in t's cspace.
*/
int lcd_rm_sync_endpoint(struct task_struct *t, cptr_t c);
#endif /* LCD_PROTOTYPE_API_DEFS_H */
......@@ -13,13 +13,44 @@
#include <lcd-prototype/lcd.h>
struct lcd_handler {
cptr_t c;
int (*handler)(void);
};
/*
* These will be replaced by "hypercall" handlers in the real thing,
* so the task argument most likely won't be needed.
*
* Note that lcd thread's directly call into these routines,
* violating the isolation of the lcd's from the api code.
*/
int __lcd_send(cptr_t c);
int __lcd_call(cptr_t c);
int __lcd_select(struct lcd_handlers *hs, int hs_count);
/**
* Send data in from's lcd->utcb to first receiver in line for the
* endpoint identified by c in t's cspace. The receiver will get
* a copy of from's registers (up to max valid) and out capabilities
* will be copied and inserted into the receiver's cspace, using
* the in cap registers.
*
* If a receiver is not waiting, from is placed in the end point's
* sender wait list, and from is put to sleep.
*/
int __lcd_send(struct task_struct *from, cptr_t c);
/**
* Other side of send (see above).
*
* If a sender is not waiting, to is placed in wait list and put to
* sleep.
*/
int __lcd_recv(struct task_struct *to, cptr_t c);
/**
* Like a send, but does a matching receive call on a capability just
* for this purpose. The receiver gets a copy of this capability that
* it can use once for a return call.
*/
int __lcd_call(struct task_struct *from, cptr_t c);
/**
* Places from on receive queue for all end points identified by the
* cptr's cs. When a matching send is received, idx points to the
* cptr in cs on which the receive happened.
*/
int __lcd_select(struct task_struct *from, cptr_t *cs, int cs_count,
cptr_t *c_out);
#endif /* LCD_PROTOTYPE_API_INTERNAL_H */
......@@ -16,21 +16,36 @@
#include "utcb.h"
#include "api-internal.h"
struct lcd_handler {
cptr_t c;
int (*handler)(void);
};
static inline int lcd_send(cptr_t c)
{
return __lcd_send(c);
return __lcd_send(current, c);
}
static inline int lcd_reply(void)
{
return lcd_send(lcd_reply_cap());
return lcd_send(current, lcd_reply_cap());
}
static inline int lcd_call(cptr_t c)
{
return __lcd_call(c);
return __lcd_call(current, c);
}
static inline int lcd_select(struct lcd_handlers *hs, int hs_count)
{
return __lcd_select(hs, hs_count);
cptr_t cs[hs_count];
int recv_idx;
int i;
int ret;
for (i = 0; i < hs_count; i++)
cs[i] = hs[i].c;
ret = __lcd_select(current, cs, hs_count, &idx);
if (ret)
return ret;
else
return hs[idx].handler();
}
#endif /* LCD_PROTOTYPE_IPC_H */
......@@ -338,7 +338,7 @@ fail1:
int execution_loop(void)
{
int ret;
struct lcd_handler *handlers[] = {
struct lcd_handler handlers[] = {
{ manufacturer_interface_cptrs.mk_engine,
mk_engine_callee },
{ manufacturer_interface_cptrs.mk_automobile,
......
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