Commit 4b3d41c7 authored by Charles Jacobsen's avatar Charles Jacobsen Committed by Vikram Narayanan

Fixed some major bugs, still no clean run yet, but closer.

parent eaea7b30
......@@ -41,9 +41,11 @@ static void copy_msg_caps(struct lcd *from, struct lcd *to)
{
int i;
for (i = 0; i < from->utcb.max_valid_out_cap_reg_idx &&
i < to->utcb.max_valid_in_cap_reg_idx; i++)
i < to->utcb.max_valid_in_cap_reg_idx; i++) {
LCD_MSG("copying cap at %d", i);
copy_msg_cap(from, to, from->utcb.out_cap_regs[i],
to->utcb.in_cap_regs[i]);
}
/*
* reset
*/
......@@ -111,12 +113,15 @@ static int lcd_do_send(struct lcd *from, cptr_t c, int making_call)
* Lookup cnode
*/
ret = __lcd_cnode_lookup(from->cspace, c, &cnode);
if (ret)
if (ret) {
LCD_ERR("looking up cnode");
goto fail1;
}
/*
* Confirm type and permissions
*/
if (!__lcd_cnode_is_sync_ep(cnode) || !__lcd_cnode_can_write(cnode)) {
LCD_ERR("cnode not an endpoint, or bad perms");
ret = -EACCES;
goto fail1;
}
......@@ -132,8 +137,10 @@ static int lcd_do_send(struct lcd *from, cptr_t c, int making_call)
* it's used primarily when cap is locked.)
*/
ret = mutex_lock_interruptible(&e->lock);
if (ret)
if (ret) {
LCD_ERR("interrupted");
goto fail1;
}
if (list_empty(&e->receivers)) {
/*
......@@ -225,12 +232,15 @@ static int lcd_do_recv(struct lcd *to, cptr_t c)
* Lookup cnode
*/
ret = __lcd_cnode_lookup(to->cspace, c, &cnode);
if (ret)
if (ret) {
LCD_ERR("recvr looking up cnode");
goto fail1;
}
/*
* Confirm type and permissions
*/
if (!__lcd_cnode_is_sync_ep(cnode) || !__lcd_cnode_can_read(cnode)) {
LCD_ERR("not an endpoint, or bad perms");
ret = -EACCES;
goto fail1;
}
......@@ -246,8 +256,10 @@ static int lcd_do_recv(struct lcd *to, cptr_t c)
* it's used primarily when cap is locked.)
*/
ret = mutex_lock_interruptible(&e->lock);
if (ret)
if (ret) {
LCD_ERR("interrupted");
return ret;
}
if (list_empty(&e->senders)) {
/*
......@@ -306,8 +318,10 @@ static int lcd_reply_alloc(struct lcd *lcd)
int ret;
ret = lcd_cnode_alloc(lcd->cspace, &reply_cap);
if (ret)
if (ret) {
LCD_ERR("alloc failed");
return ret;
}
lcd->utcb.reply_endpoint_cap = reply_cap;
......@@ -347,12 +361,16 @@ static int lcd_call_alloc(struct lcd *lcd)
cptr_t call_cptr;
ret = lcd_cnode_alloc(lcd->cspace, &call_cptr);
if (ret)
if (ret) {
LCD_ERR("alloc failed");
return ret;
}
ret = __lcd_mk_sync_endpoint(lcd, call_cptr);
if (ret)
if (ret) {
LCD_ERR("couldn't make endpoint");
return ret;
}
lcd->utcb.call_endpoint_cap = call_cptr;
......
......@@ -24,8 +24,8 @@ static inline u8 lcd_max_valid_reg_idx(void)
}
static inline void lcd_update_max_valid_reg_idx(u8 idx)
{
if (idx > current->lcd->utcb.max_valid_reg_idx)
current->lcd->utcb.max_valid_reg_idx = idx;
if (idx >= current->lcd->utcb.max_valid_reg_idx)
current->lcd->utcb.max_valid_reg_idx = idx + 1;
}
#define LCD_MK_REG_ACCESS(idx) \
static inline u64 lcd_r##idx(void) \
......@@ -56,8 +56,8 @@ static inline u8 lcd_max_valid_out_cap_reg_idx(void)
}
static inline void lcd_update_max_valid_out_cap_reg_idx(u8 idx)
{
if (idx > current->lcd->utcb.max_valid_out_cap_reg_idx)
current->lcd->utcb.max_valid_out_cap_reg_idx = idx;
if (idx >= current->lcd->utcb.max_valid_out_cap_reg_idx)
current->lcd->utcb.max_valid_out_cap_reg_idx = idx + 1;
}
#define LCD_MK_OUT_CAP_REG_ACCESS(idx) \
static inline u64 lcd_out_cap##idx(void) \
......@@ -88,8 +88,8 @@ static inline u8 lcd_max_valid_in_cap_reg_idx(void)
}
static inline void lcd_update_max_valid_in_cap_reg_idx(u8 idx)
{
if (idx > current->lcd->utcb.max_valid_in_cap_reg_idx)
current->lcd->utcb.max_valid_in_cap_reg_idx = idx;
if (idx >= current->lcd->utcb.max_valid_in_cap_reg_idx)
current->lcd->utcb.max_valid_in_cap_reg_idx = idx + 1;
}
#define LCD_MK_IN_CAP_REG_ACCESS(idx) \
static inline u64 lcd_in_cap##idx(void) \
......
......@@ -21,7 +21,7 @@ static inline struct lcd * test_mk_lcd(void)
lcd = kmalloc(sizeof(*lcd), GFP_KERNEL);
if (!lcd)
return NULL;
memset(lcd, 0, sizeof(*lcd));
ret = lcd_mk_cspace(&lcd->cspace);
if (ret) {
kfree(lcd);
......@@ -91,6 +91,7 @@ static int lcd_boot(void)
struct lcd_boot_info ci;
cptr_t mcptr;
cptr_t dcptr;
cptr_t dcptr2;
cptr_t ccptr;
/*
......@@ -147,7 +148,7 @@ static int lcd_boot(void)
goto clean5;
if (ccptr != 31) {
ret = -1;
LCD_ERR("customer cptr not = %d, so need to change macro first",
LCD_ERR("customer cptr = %d, so need to change macro first",
ccptr);
goto clean5;
}
......@@ -156,6 +157,19 @@ static int lcd_boot(void)
if (ret)
goto clean5;
/*
* Alloc cnode slot for dealer
*/
ret = lcd_cnode_alloc(dealer_lcd->cspace, &dcptr2);
if (ret)
goto clean5;
if (dcptr2 != 30) {
ret = -1;
LCD_ERR("dealer cptr = %d, so need to change macro first",
dcptr2);
goto clean5;
}
/*
* Init completions
*/
......
......@@ -40,6 +40,8 @@ struct automobile * dealer_buy_car(void)
struct automobile *a;
struct engine *e;
int ret;
LCD_MSG("customer buying car");
/*
* Alloc caller copy of hierarchy
*/
......@@ -114,6 +116,8 @@ fail:
/* MAIN EXEC LOOP -------------------------------------------------- */
extern struct completion dealer_ready;
int customer_start(void)
{
int ret;
......@@ -123,6 +127,7 @@ int customer_start(void)
ret = wait_for_completion_interruptible(&dealer_ready);
if (ret)
return ret;
LCD_MSG("customer ok to proceed");
/*
* Call customer init (will buy car)
*/
......
......@@ -30,12 +30,18 @@ EXPORT_SYMBOL(dealer_ready);
/* INTERFACE WRAPPERS -------------------------------------------------- */
cptr_t manufacturer_interface_cap;
struct engine * mk_engine_caller(int cylinders);
struct automobile * mk_automobile_caller(struct engine *e, int doors);
void free_engine_caller(struct engine *e);
void free_automobile_caller(struct automobile *a);
struct manufacturer_interface __mi = {
.mk_engine = mk_engine_caller,
.mk_automobile = mk_automobile_caller,
.free_engine = free_engine_caller,
.free_automobile = free_automobile_caller,
};
/**
* dealer_register_manufacturer_callee
* -----------------------------------
......@@ -49,12 +55,6 @@ void free_automobile_caller(struct automobile *a);
static int dealer_register_manufacturer_callee(void)
{
int ret;
struct manufacturer_interface __mi = {
.mk_engine = mk_engine_caller,
.mk_automobile = mk_automobile_caller,
.free_engine = free_engine_caller,
.free_automobile = free_automobile_caller,
};
/*
* Register ...
*/
......@@ -69,7 +69,8 @@ static int dealer_register_manufacturer_callee(void)
goto fail1;
}
complete(dealer_ready);
LCD_MSG("dealer registered");
complete(&dealer_ready);
return ret;
......@@ -93,6 +94,13 @@ static int dealer_buy_car_callee(void)
struct automobile *a;
dsptr_t auto_dsptr;
dsptr_t engine_dsptr;
cptr_t reply_cptr;
/*
* Remember reply cptr
*
* XXX: hack?
*/
reply_cptr = current_lcd()->utcb.reply_endpoint_cap;
/*
* Call into internal code
*/
......@@ -116,11 +124,12 @@ static int dealer_buy_car_callee(void)
goto fail3;
}
/*
* Reply
* Reply, putting reply cptr back in
*/
lcd_store_r0(0);
lcd_store_r1(auto_dsptr);
lcd_store_r2(engine_dsptr);
current->lcd->utcb.reply_endpoint_cap = reply_cptr;
ret = lcd_reply();
if (ret) {
LCD_ERR("couldn't reply");
......@@ -199,7 +208,7 @@ int dealer_die_callee(void)
* Kill manufacturer
*/
lcd_store_r0(MANUFACTURER_DIE);
ret = lcd_call(manufacturer_interface_cap);
ret = lcd_call(DEALER_MANUFACTURER_OBJ_CAP);
if (ret)
return ret;
/*
......@@ -236,7 +245,7 @@ struct engine * mk_engine_caller(int cylinders)
*/
lcd_store_r0(MANUFACTURER_MK_ENGINE);
lcd_store_r1(cylinders);
ret = lcd_call(manufacturer_interface_cap);
ret = lcd_call(DEALER_MANUFACTURER_OBJ_CAP);
if (ret) {
LCD_ERR("call failed");
goto fail2;
......@@ -276,7 +285,7 @@ struct automobile * mk_automobile_caller(struct engine *e, int doors)
lcd_store_r0(MANUFACTURER_MK_AUTOMOBILE);
lcd_store_r1(doors);
lcd_store_r2(e->self);
ret = lcd_call(manufacturer_interface_cap);
ret = lcd_call(DEALER_MANUFACTURER_OBJ_CAP);
if (ret) {
LCD_ERR("call failed");
goto fail2;
......@@ -306,7 +315,7 @@ void free_engine_caller(struct engine *e)
*/
lcd_store_r0(MANUFACTURER_FREE_ENGINE);
lcd_store_r1(e->self);
ret = lcd_call(manufacturer_interface_cap);
ret = lcd_call(DEALER_MANUFACTURER_OBJ_CAP);
if (ret) {
LCD_ERR("call failed");
goto fail;
......@@ -335,7 +344,7 @@ void free_automobile_caller(struct automobile *a)
*/
lcd_store_r0(MANUFACTURER_FREE_AUTOMOBILE);
lcd_store_r1(a->self);
ret = lcd_call(manufacturer_interface_cap);
ret = lcd_call(DEALER_MANUFACTURER_OBJ_CAP);
if (ret) {
LCD_ERR("call failed");
goto fail;
......@@ -364,20 +373,29 @@ int execution_loop(void)
/*
* Listen for incoming message
*/
/*
* XXX: this only needs to be done once, but for simplicity,
* the dealer always allows receipt of one capability
*/
lcd_store_in_cap0(DEALER_MANUFACTURER_OBJ_CAP);
ret = lcd_recv(DEALER_DEALER_INTERFACE_CAP);
if (ret)
goto out;
switch (lcd_r0()) {
case DEALER_REGISTER_MANUFACTURER:
LCD_MSG("dealer handling reg manufacturer");
ret = dealer_register_manufacturer_callee();
break;
case DEALER_BUY_CAR:
LCD_MSG("dealer handling buy car");
ret = dealer_buy_car_callee();
break;
case DEALER_RETURN_CAR:
LCD_MSG("dealer handling return car");
ret = dealer_return_car_callee();
break;
case DEALER_DIE:
LCD_MSG("dealer handling die");
ret = dealer_die_callee();
goto out;
}
......@@ -411,6 +429,7 @@ EXPORT_SYMBOL(dealer_start);
int __init dealer_init(void)
{
init_completion(&dealer_ready);
return 0;
}
......
......@@ -15,5 +15,6 @@ enum dealer_interface {
};
#define DEALER_DEALER_INTERFACE_CAP 31
#define DEALER_MANUFACTURER_OBJ_CAP 30
#endif
......@@ -31,6 +31,10 @@ struct automobile * dealer_buy_car(void)
struct engine *e;
struct automobile *a;
if (!manufacturer) {
LCD_ERR("manufacturer interface not set!");
return NULL;
}
/*
* Make an 8 cylinder engine
*/
......
......@@ -319,20 +319,24 @@ int execution_loop(void)
if (ret)
goto out;
switch (lcd_r0()) {
case MANUFACTURER_MK_ENGINE:
LCD_MSG("manufacturer handling mk engine");
ret = mk_engine_callee();
break;
case MANUFACTURER_MK_AUTOMOBILE:
LCD_MSG("manufacturer handling mk auto");
ret = mk_automobile_callee();
break;
case MANUFACTURER_FREE_ENGINE:
LCD_MSG("manufacturer handling free engine");
ret = free_engine_callee();
break;
case MANUFACTURER_FREE_AUTOMOBILE:
LCD_MSG("manufacturer handling free auto");
ret = free_automobile_callee();
break;
case MANUFACTURER_DIE:
LCD_MSG("manufacturer dying");
manufacturer_die_callee();
goto out;
}
......@@ -367,6 +371,7 @@ int manufacturer_start(void)
/*
* Now enter loop and listen for calls
*/
LCD_MSG("manufacturer entering loop");
return execution_loop();
}
EXPORT_SYMBOL(manufacturer_start);
......
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