diff --git a/drivers/lcd-prototype/api/ipc.c b/drivers/lcd-prototype/api/ipc.c index 04ecc0ab6089852fba5f79d974bb7593c88b982e..fdae54bbc190fd5ac33ccfeaf26792b35918818f 100644 --- a/drivers/lcd-prototype/api/ipc.c +++ b/drivers/lcd-prototype/api/ipc.c @@ -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; diff --git a/drivers/lcd-prototype/include/utcb.h b/drivers/lcd-prototype/include/utcb.h index 0b14d0c36effeb610ec05d2657f9af6127683166..eb3bc22a884c063edd4676d7866fa96811e63188 100644 --- a/drivers/lcd-prototype/include/utcb.h +++ b/drivers/lcd-prototype/include/utcb.h @@ -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) \ diff --git a/drivers/lcd-prototype/test/boot.c b/drivers/lcd-prototype/test/boot.c index 16e5905cd968b98a3258cb124182bf997c348971..283f003e8d818e19ba28e7a43d4177c4190bb5e9 100644 --- a/drivers/lcd-prototype/test/boot.c +++ b/drivers/lcd-prototype/test/boot.c @@ -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 */ diff --git a/drivers/lcd-prototype/test/customer-idl.c b/drivers/lcd-prototype/test/customer-idl.c index c21a4c05d3bd86ef915c57b997d448e3cbfd5cf8..2a3e82ec725c06f18c6995ec919137b147e8c677 100644 --- a/drivers/lcd-prototype/test/customer-idl.c +++ b/drivers/lcd-prototype/test/customer-idl.c @@ -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) */ diff --git a/drivers/lcd-prototype/test/dealer-idl.c b/drivers/lcd-prototype/test/dealer-idl.c index 615390b2383ea28f3b1ba335169bd8a128bc6220..e8bd4633b3ad3c87ce6a4dda0bc1b2c846d697ce 100644 --- a/drivers/lcd-prototype/test/dealer-idl.c +++ b/drivers/lcd-prototype/test/dealer-idl.c @@ -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; } diff --git a/drivers/lcd-prototype/test/dealer-idl.h b/drivers/lcd-prototype/test/dealer-idl.h index 2caf583808c5638e34ed31235ef2058e906228df..55526a26d4b786e5e6cae5040e512cdf430346a9 100644 --- a/drivers/lcd-prototype/test/dealer-idl.h +++ b/drivers/lcd-prototype/test/dealer-idl.h @@ -15,5 +15,6 @@ enum dealer_interface { }; #define DEALER_DEALER_INTERFACE_CAP 31 +#define DEALER_MANUFACTURER_OBJ_CAP 30 #endif diff --git a/drivers/lcd-prototype/test/dealer.c b/drivers/lcd-prototype/test/dealer.c index c7327fbe2f4f9fc88791e5985645d7845d0d8e45..38e601c5996e9fdec806afdb3a5971d1eb59cb8a 100644 --- a/drivers/lcd-prototype/test/dealer.c +++ b/drivers/lcd-prototype/test/dealer.c @@ -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 */ diff --git a/drivers/lcd-prototype/test/manufacturer-idl.c b/drivers/lcd-prototype/test/manufacturer-idl.c index e5d6e29d37c4a23a41cdd53c88909f1ad0586f8f..e68e8ba489fe119be840b99eaf55fd6c517b6101 100644 --- a/drivers/lcd-prototype/test/manufacturer-idl.c +++ b/drivers/lcd-prototype/test/manufacturer-idl.c @@ -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);