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