Commit c0d05162 authored by Vikram Narayanan's avatar Vikram Narayanan
Browse files

lcd/testmods: Make changes to nullnet



Rename variables
add more functions from pmfs
Create a KLCD and an LCD as opposed to 2 LCDs
Signed-off-by: Vikram Narayanan's avatarVikram Narayanan <vikram186@gmail.com>
parent 6addf306
......@@ -56,39 +56,25 @@ static int boot_main(void)
goto fail4;
}
/* ---------- Grant caps ---------- */
/*
ret = cptr_alloc(lcd_to_boot_cptr_cache(net_ctx),
&net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("alloc cptr");
goto fail5;
}
ret = lcd_cap_grant(net_lcd, net_chnl, net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail6;
} */
ret = cptr_alloc(lcd_to_boot_cptr_cache(dummy_ctx),
&dummy_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("alloc cptr");
goto fail7;
goto fail5;
}
ret = lcd_cap_grant(dummy_lcd, net_chnl, dummy_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail8;
goto fail6;
}
/* ---------- Set up boot info ---------- */
// lcd_to_boot_info(net_ctx)->cptrs[0] = net_chnl_domain_cptr;
// HACK: But WTF is this?
net_chnl_domain_cptr = __cptr(3);
ret = lcd_cap_grant(net_lcd, net_chnl, net_chnl_domain_cptr);
if (ret) {
LIBLCD_ERR("grant");
goto fail6;
goto fail7;
}
lcd_to_boot_info(dummy_ctx)->cptrs[0] = dummy_chnl_domain_cptr;
......@@ -100,7 +86,7 @@ static int boot_main(void)
ret = lcd_run(net_lcd);
if (ret) {
LIBLCD_ERR("failed to start vfs lcd");
goto fail9;
goto fail8;
}
/* Wait a few moments so vfs lcd has a chance to enter its
* dispatch loop. This is obviously a hack. You could use some
......@@ -111,7 +97,7 @@ static int boot_main(void)
ret = lcd_run(dummy_lcd);
if (ret) {
LIBLCD_ERR("failed to start dummy lcd");
goto fail10;
goto fail9;
}
/*
* Wait for 4 seconds
......@@ -126,13 +112,13 @@ static int boot_main(void)
/* The destroy's will free up everything ... */
out:
fail10:
fail9:
fail8:
fail7:
fail6:
lcd_cap_delete(dummy_lcd);
lcd_destroy_create_ctx(dummy_ctx);
fail6:
fail5:
fail4:
lcd_cap_delete(net_lcd);
fail3:
......
......@@ -4,24 +4,20 @@
#include <liblcd/glue_cspace.h>
#include "../../glue_helper.h"
#include "../nullnet_caller.h"
static struct cptr c;
struct cptr sync_ep;
static struct glue_cspace *c_cspace;
struct thc_channel *net_async;
static struct lcd_sync_channel_group *nullnet_group;
int glue_nullnet_init(struct cptr c1, struct lcd_sync_channel_group *nullnet_group1)
int glue_nullnet_init(void)
{
int ret;
c = c1;
nullnet_group = nullnet_group1;
ret = glue_cap_init();
if (!ret) {
if (ret) {
LIBLCD_ERR("cap init");
goto fail1;
}
ret = glue_cap_create(&c_cspace);
if (!ret) {
if (ret) {
LIBLCD_ERR("cap create");
goto fail2;
}
......@@ -40,13 +36,185 @@ void glue_nullnet_exit()
}
static int setup_async_channel(cptr_t *buf1_cptr_out, cptr_t *buf2_cptr_out,
struct thc_channel **chnl_out)
{
int ret;
cptr_t buf1_cptr, buf2_cptr;
gva_t buf1_addr, buf2_addr;
struct fipc_ring_channel *fchnl;
struct thc_channel *chnl;
unsigned int pg_order = PMFS_ASYNC_RPC_BUFFER_ORDER - PAGE_SHIFT;
/*
* Allocate buffers
*
* (We use the lower level alloc. If we used the heap, even though
* we may alloc only 1 - 2 pages, we would end up sharing around
* 4 MB chunks of memory, since the heap uses coarse microkernel
* allocations.)
*/
ret = _lcd_alloc_pages(GFP_KERNEL, pg_order, &buf1_cptr);
if (ret) {
LIBLCD_ERR("buf1 alloc");
goto fail1;
}
ret = _lcd_alloc_pages(GFP_KERNEL, pg_order, &buf2_cptr);
if (ret) {
LIBLCD_ERR("buf2 alloc");
goto fail2;
}
/*
* Map them somewhere
*/
ret = lcd_map_virt(buf1_cptr, pg_order, &buf1_addr);
if (ret) {
LIBLCD_ERR("error mapping buf1");
goto fail3;
}
ret = lcd_map_virt(buf2_cptr, pg_order, &buf2_addr);
if (ret) {
LIBLCD_ERR("error mapping buf2");
goto fail4;
}
/*
* Prep buffers for rpc
*/
ret = fipc_prep_buffers(PMFS_ASYNC_RPC_BUFFER_ORDER,
(void *)gva_val(buf1_addr),
(void *)gva_val(buf2_addr));
if (ret) {
LIBLCD_ERR("prep buffers");
goto fail5;
}
/*
* Alloc and init channel header
*/
fchnl = kmalloc(sizeof(*fchnl), GFP_KERNEL);
if (!fchnl) {
ret = -ENOMEM;
LIBLCD_ERR("chnl alloc");
goto fail6;
}
ret = fipc_ring_channel_init(fchnl, PMFS_ASYNC_RPC_BUFFER_ORDER,
(void *)gva_val(buf1_addr),
(void *)gva_val(buf2_addr));
if (ret) {
LIBLCD_ERR("ring chnl init");
goto fail7;
}
/*
* Install async channel in async dispatch loop
*/
chnl = kzalloc(sizeof(*chnl), GFP_KERNEL);
if (!chnl) {
ret = -ENOMEM;
LIBLCD_ERR("alloc failed");
goto fail8;
}
ret = thc_channel_init(chnl, fchnl);
if (ret) {
LIBLCD_ERR("error init'ing async channel group item");
goto fail9;
}
*buf1_cptr_out = buf1_cptr;
*buf2_cptr_out = buf2_cptr;
*chnl_out = chnl;
return 0;
fail9:
kfree(chnl);
fail8:
fail7:
kfree(fchnl);
fail6:
fail5:
lcd_unmap_virt(buf1_addr, pg_order);
fail4:
lcd_unmap_virt(buf1_addr, pg_order);
fail3:
lcd_cap_delete(buf2_cptr);
fail2:
lcd_cap_delete(buf1_cptr);
fail1:
return ret;
}
static void destroy_async_channel(struct thc_channel *chnl)
{
unsigned int pg_order = PMFS_ASYNC_RPC_BUFFER_ORDER - PAGE_SHIFT;
gva_t tx_gva, rx_gva;
cptr_t tx, rx;
int ret;
unsigned long unused1, unused2;
/*
* Translate ring buffers to cptrs
*/
tx_gva = __gva((unsigned long)thc_channel_to_fipc(chnl)->tx.buffer);
rx_gva = __gva((unsigned long)thc_channel_to_fipc(chnl)->rx.buffer);
ret = lcd_virt_to_cptr(tx_gva, &tx, &unused1, &unused2);
if (ret) {
LIBLCD_ERR("failed to translate tx to cptr");
goto fail1;
}
ret = lcd_virt_to_cptr(rx_gva, &rx, &unused1, &unused2);
if (ret) {
LIBLCD_ERR("failed to translate rx to cptr");
goto fail2;
}
/*
* Unmap and kill tx/rx
*/
lcd_unmap_virt(tx_gva, pg_order);
lcd_cap_delete(tx);
lcd_unmap_virt(rx_gva, pg_order);
lcd_cap_delete(rx);
/*
* Free chnl header
*/
kfree(thc_channel_to_fipc(chnl));
/*
* Free the async channel
*
* XXX: This is ok to do because there is no dispatch loop
* polling on the channel when we free it.
*/
kfree(chnl);
return;
fail2:
fail1:
return;
}
cptr_t net_sync_endpoint;
int __rtnl_link_register(struct rtnl_link_ops *ops)
{
struct rtnl_link_ops_container *ops_container;
int err;
struct fipc_message *request;
struct fipc_message *response;
cptr_t tx, rx;
struct thc_channel *chnl;
int ret;
/*
* Set up async and sync channels
*/
ret = lcd_create_sync_endpoint(&net_sync_endpoint);
if (ret) {
LIBLCD_ERR("lcd_create_sync_endpoint");
goto fail1;
}
ret = setup_async_channel(&tx, &rx, &chnl);
if (ret) {
LIBLCD_ERR("async chnl setup failed");
goto fail2;
}
ops_container = container_of(ops, struct rtnl_link_ops_container, rtnl_link_ops);
err = glue_cap_insert_rtnl_link_ops_type(c_cspace, ops_container, &ops_container->my_ref);
if (err) {
......@@ -69,6 +237,11 @@ int __rtnl_link_register(struct rtnl_link_ops *ops)
ops_container->other_ref.cptr = fipc_get_reg2(response);
ret = fipc_get_reg2(response);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), response);
return ret;
fail2:
lcd_cap_delete(net_sync_endpoint);
fail1:
return ret;
}
......@@ -336,6 +509,8 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops)
}
glue_cap_remove(c_cspace, ops_container->my_ref);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), response);
destroy_async_channel(net_async);
return;
}
......
......@@ -14,8 +14,8 @@
cptr_t nullnet_register_channel;
struct thc_channel *nullnet_async_chnl;
struct glue_cspace *nullnet_cspace;
cptr_t nullnet_sync_endpoint;
//struct glue_cspace *nullnet_cspace;
//cptr_t nullnet_sync_endpoint;
int dummy_done;
int dummy_init_module(void);
void dummy_cleanup_module(void);
......
......@@ -3,7 +3,7 @@
#include "../glue_helper.h"
int glue_nullnet_init(struct cptr c, struct lcd_sync_channel_group *nullnet_group);
int glue_nullnet_init(void);
void glue_nullnet_exit(void);
int ndo_init_callee(struct fipc_message *request, struct thc_channel *channel, struct cspace *cspace, struct cptr sync_ep);
int ndo_uninit_callee(struct fipc_message *request, struct thc_channel *channel, struct cspace *cspace, struct cptr sync_ep);
......
......@@ -42,6 +42,7 @@ enum dispatch_t {
SETUP
};
#define PMFS_ASYNC_RPC_BUFFER_ORDER 12
/* CONTAINERS ---------- */
struct net_device_container {
struct net_device net_device;
......
......@@ -7,27 +7,44 @@
#include "../nullnet_callee.h"
struct thc_channel *net_async;
struct cspace *c_cspace;
struct glue_cspace *gc_cspace;
//struct cspace *c_cspace;
struct cptr sync_ep;
struct trampoline_hidden_args {
void *struct_container;
struct cspace *cspace;
struct glue_cspace *cspace;
struct lcd_trampoline_handle *t_handle;
struct thc_channel *async_chnl;
struct cptr sync_ep;
};
//static struct cptr c;
static struct glue_cspace *c_cspace;
int glue_nullnet_init(void)
{
return 0;
int ret;
ret = glue_cap_init();
if (ret) {
LIBLCD_ERR("cap init");
goto fail1;
}
ret = glue_cap_create(&c_cspace);
if (ret) {
LIBLCD_ERR("cap create");
goto fail2;
}
return 0;
fail2:
glue_cap_exit();
fail1:
return ret;
}
void glue_nullnet_exit(void)
void glue_nullnet_exit()
{
glue_cap_destroy(c_cspace);
glue_cap_exit();
}
......@@ -440,7 +457,7 @@ int register_netdevice_callee(struct fipc_message *request, struct thc_channel *
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
}
err = glue_cap_insert_net_device_type(gc_cspace, dev_container, &dev_container->my_ref);
err = glue_cap_insert_net_device_type(c_cspace, dev_container, &dev_container->my_ref);
if (!err) {
LIBLCD_ERR("lcd insert");
lcd_exit(-1);
......@@ -797,7 +814,7 @@ int __rtnl_link_register_callee(struct fipc_message *request, struct thc_channel
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
}
err = glue_cap_insert_rtnl_link_ops_type(gc_cspace, ops_container, &ops_container->my_ref);
err = glue_cap_insert_rtnl_link_ops_type(c_cspace, ops_container, &ops_container->my_ref);
if (!err) {
LIBLCD_ERR("lcd insert");
lcd_exit(-1);
......@@ -883,7 +900,7 @@ int rtnl_link_unregister_callee(struct fipc_message *request, struct thc_channel
struct trampoline_hidden_args *validate_hidden_args;
request_cookie = thc_get_request_cookie(request);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), request);
err = glue_cap_lookup_rtnl_link_ops_type(gc_cspace, __cptr(fipc_get_reg2(request)), &ops_container);
err = glue_cap_lookup_rtnl_link_ops_type(c_cspace, __cptr(fipc_get_reg2(request)), &ops_container);
if (err) {
LIBLCD_ERR("lookup");
lcd_exit(-1);
......@@ -895,7 +912,7 @@ int rtnl_link_unregister_callee(struct fipc_message *request, struct thc_channel
}
// ops->kind = fipc_get_reg1(request);
rtnl_link_unregister(( &ops_container->rtnl_link_ops ));
glue_cap_remove(gc_cspace, ops_container->my_ref);
glue_cap_remove(c_cspace, ops_container->my_ref);
setup_hidden_args = LCD_TRAMPOLINE_TO_HIDDEN_ARGS(ops_container->rtnl_link_ops.setup);
kfree(setup_hidden_args->t_handle);
kfree(setup_hidden_args);
......@@ -979,7 +996,7 @@ int consume_skb_callee(struct fipc_message *request, struct thc_channel *channel
unsigned int request_cookie;
request_cookie = thc_get_request_cookie(request);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), request);
err = glue_cap_lookup_sk_buff_type(gc_cspace, __cptr(fipc_get_reg1(request)), &skb_container);
err = glue_cap_lookup_sk_buff_type(c_cspace, __cptr(fipc_get_reg1(request)), &skb_container);
if (err) {
LIBLCD_ERR("lookup");
lcd_exit(-1);
......
......@@ -11,8 +11,105 @@
/* COMPILER: This is always included after all includes. */
#include <lcd_config/post_hook.h>
/* LOOP ------------------------------------------------------------ */
#if 0
static int async_loop(struct fs_info **fs_out, struct fipc_message **msg_out)
{
struct fs_info *cursor, *next;
int ret;
list_for_each_entry_safe(cursor, next, &fs_infos, list) {
ret = thc_ipc_poll_recv(cursor->chnl, msg_out);
if (ret == -EPIPE) {
/*
* fs channel is dead; free the channel,
* and remove from list
*/
kfree(cursor->chnl);
remove_fs(cursor);
} else if (ret == -EWOULDBLOCK) {
/*
* Skip over empty channels
*/
continue;
} else if (ret) {
/*
* Unexpected error
*/
LIBLCD_ERR("error ret = %d on async channel");
return ret;
} else {
/*
* Got a msg
*/
*fs_out = cursor;
return 0;
}
}
/*
* Nothing for us to recv right now
*/
return -EWOULDBLOCK;
}
static int do_one_register(cptr_t register_chnl)
{
int ret;
cptr_t sync_endpoint, tx, rx;
/*
* Set up cptrs
*/
ret = lcd_cptr_alloc(&sync_endpoint);
if (ret) {
LIBLCD_ERR("cptr alloc failed");
goto fail1;
}
ret = lcd_cptr_alloc(&tx);
if (ret) {
LIBLCD_ERR("cptr alloc failed");
goto fail2;
}
ret = lcd_cptr_alloc(&rx);
if (ret) {
LIBLCD_ERR("cptr alloc failed");
goto fail3;
}
/*
* Set up regs and poll
*/
lcd_set_cr0(sync_endpoint);
lcd_set_cr1(tx);
lcd_set_cr2(rx);
ret = lcd_sync_poll_recv(register_chnl);
if (ret) {
if (ret == -EWOULDBLOCK)
ret = 0;
goto free_cptrs;
}
/*
* Dispatch to register handler
*/
ret = dispatch_sync_loop();
if (ret)
return ret; /* dispatch fn is responsible for cptr cleanup */
return 0;
free_cptrs:
lcd_set_cr0(CAP_CPTR_NULL);
lcd_set_cr1(CAP_CPTR_NULL);
lcd_set_cr2(CAP_CPTR_NULL);
lcd_cptr_free(sync_endpoint);
fail3:
lcd_cptr_free(tx);
fail2:
lcd_cptr_free(rx);
fail1:
return ret;
}
#endif
/* LOOP -------------------------------------------------- */
//static void loop(struct lcd_sync_channel_group *group)
......@@ -52,19 +149,25 @@ static int net_klcd_init(void)
/*
* Set up cptr cache, etc.
*/
//LIBLCD_MSG(">>>>>> Entering LCD mode\n");
ret = lcd_enter();
if (ret) {
LIBLCD_ERR("lcd enter");
goto fail1;
}
net_chnl = lcd_get_boot_info()->cptrs[0];
/*
* XXX: Hack: boot provided us with one cptr for the net chnl
*/
ret = lcd_cptr_alloc(&net_chnl);
if (ret) {
LIBLCD_ERR("alloc cptr");
goto fail2;
}
/*
* Init net glue
*/
// ret = glue_nullnet_init();
ret = glue_nullnet_init();
if (ret) {
LIBLCD_ERR("net init");
goto fail3;
......@@ -72,18 +175,19 @@ static int net_klcd_init(void)
/*
* Enter sync/async dispatch loop
*/
//LIBLCD_MSG(">>>>> Looping .... \n");
LIBLCD_MSG(">>>>> Looping .... \n");
loop(net_chnl);
/*
* Tear down net glue
*/
//glue_nullnet_exit();
glue_nullnet_exit();
lcd_exit(0);
return 0;
fail3:
fail2:
lcd_exit(ret);
fail1:
return ret;
......@@ -92,14 +196,11 @@ fail1:
static int __net_klcd_init(void)
{
int ret = 0;
// printk("net klcd_init\n");
if (1) {
LCD_MAIN({
ret = net_klcd_init();
});
}
return ret;
}
......@@ -109,10 +210,6 @@ static int __net_klcd_init(void)
*/
static void __exit net_klcd_exit(void)
{
// glue_nullnet_exit();
lcd_exit(0);