1/** 2 * \file 3 * \brief Monitor's connection with the dispatchers on the same core 4 */ 5 6/* 7 * Copyright (c) 2009, 2010, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include "monitor.h" 16#include <barrelfish/debug.h> // XXX: To set the cap_identify_reply handler 17#include <barrelfish/sys_debug.h> // XXX: for sys_debug_send_ipi 18#include <trace/trace.h> 19#include <if/mem_defs.h> 20#include <barrelfish/monitor_client.h> 21#include <if/monitor_loopback_defs.h> 22#include <notify_ipi.h> 23 24struct ipi_alloc_notify_reply_state { 25 struct monitor_msg_queue_elem elem; 26 struct monitor_ipi_alloc_notify_reply__tx_args args; 27}; 28 29static void 30ipi_alloc_notify_reply_cont(struct monitor_binding *b, 31 uintptr_t state, struct capref notify_cap, 32 errval_t err); 33 34static void ipi_alloc_notify_reply_handler(struct monitor_binding *b, 35 struct monitor_msg_queue_elem *e) 36{ 37 struct ipi_alloc_notify_reply_state *st = 38 (struct ipi_alloc_notify_reply_state *)e; 39 ipi_alloc_notify_reply_cont(b, st->args.state, st->args.notify, 40 st->args.err); 41 free(st); 42} 43 44static void ipi_alloc_notify_reply_cont(struct monitor_binding *b, 45 uintptr_t state, 46 struct capref notify_cap, 47 errval_t reterr) 48{ 49 errval_t err = 50 b->tx_vtbl.ipi_alloc_notify_reply(b, NOP_CONT, state, 51 notify_cap, reterr); 52 53 if(err_is_fail(err)) { 54 if (err_no(err) == FLOUNDER_ERR_TX_BUSY) { 55 struct monitor_state *st = b->st; 56 struct ipi_alloc_notify_reply_state *me = 57 malloc(sizeof(struct ipi_alloc_notify_reply_state)); 58 assert(me != NULL); 59 me->args.state = state; 60 me->args.notify = notify_cap; 61 me->args.err = reterr; 62 me->elem.cont = ipi_alloc_notify_reply_handler; 63 err = monitor_enqueue_send(b, &st->queue, 64 get_default_waitset(), &me->elem.queue); 65 if (err_is_fail(err)) { 66 USER_PANIC_ERR(err, "monitor_enqueue_send failed"); 67 } 68 return; 69 } 70 USER_PANIC_ERR(err, "sending reply"); 71 } 72 assert(err_is_ok(err)); 73} 74 75static void ipi_alloc_notify_request(struct monitor_binding *st, 76 struct capref ep, uintptr_t state) 77{ 78 errval_t err; 79 struct capref notify_cap = NULL_CAP; 80 81 // Allocate a local notify channel ID 82 int chanid; 83 err = notification_allocate(ep, &chanid); 84 if(err_is_fail(err)) { 85 goto out; 86 } 87 88 // Get my arch ID 89 uintptr_t my_arch_id = 0; 90 err = invoke_monitor_get_arch_id(&my_arch_id); 91 assert(err == SYS_ERR_OK); 92 93 // Create notify cap 94 err = notification_create_cap(chanid, my_arch_id, ¬ify_cap); 95 96 out: 97 // Return the notify cap or error 98 ipi_alloc_notify_reply_cont(st, state, notify_cap, err); 99} 100 101errval_t monitor_server_arch_init(struct monitor_binding *b) 102{ 103 b->rx_vtbl.ipi_alloc_notify_request = ipi_alloc_notify_request; 104 return SYS_ERR_OK; 105} 106