1/** 2 * \file 3 * \brief System-wide tracing 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <barrelfish/barrelfish.h> 17#include <barrelfish/dispatch.h> 18#include <barrelfish/dispatcher_arch.h> 19#include <barrelfish/curdispatcher_arch.h> 20#include <trace/trace.h> 21#include <spawndomain/spawndomain.h> 22 23STATIC_ASSERT_SIZEOF(struct trace_event, 16); 24STATIC_ASSERT((sizeof(struct trace_buffer) <= TRACE_PERCORE_BUF_SIZE), "size mismatch"); 25 26/** 27 * \brief Initialize per-core tracing buffer 28 * 29 * This function creates a cap for the tracing buffer in taskcn. 30 * It is called from init at startup. 31 * 32 * Note that it does *not* map the buffer into its own vspace. 33 */ 34errval_t trace_init(void) 35{ 36 errval_t err; 37 size_t bytes; 38 39 struct capref cap = { 40 .cnode = cnode_task, 41 .slot = TASKCN_SLOT_TRACEBUF 42 }; 43 44 err = frame_create(cap, TRACE_ALLOC_SIZE, &bytes); 45 if (err_is_fail(err)) { 46 return err_push(err, TRACE_ERR_CREATE_CAP); 47 } 48 49 return SYS_ERR_OK; 50} 51 52/** 53 * \brief Turn off tracing for this domain 54 */ 55errval_t trace_disable_domain(void) 56{ 57 dispatcher_handle_t handle = curdispatcher(); 58 struct dispatcher_generic *disp = get_dispatcher_generic(handle); 59 disp->trace_buf = NULL; 60 return SYS_ERR_OK; 61} 62 63 64/** 65 * Sets up tracing framework for current dispatcher 66 */ 67void trace_init_disp(void) 68{ 69 dispatcher_handle_t handle = curdispatcher(); 70 struct dispatcher_generic *disp = get_dispatcher_generic(handle); 71 disp->trace_buf = (struct trace_buffer*)trace_buffer_va; 72} 73 74/** 75 * \brief Setup the tracing buffer for a child domain 76 * 77 * Assumes that the child domain is currently being spawned 78 * (because we rely on libspawndomain having the right state to 79 * allow us to map the trace buffer into the child's vspace). 80 * 81 * trace_init must already have been called 82 */ 83errval_t trace_setup_child(struct cnoderef taskcn, 84 dispatcher_handle_t handle) 85{ 86 errval_t err; 87 88 // Pass tracing buffer cap to new domain 89 struct capref src = { 90 .cnode = cnode_task, 91 .slot = TASKCN_SLOT_TRACEBUF 92 }; 93 struct capref dst = { 94 .cnode = taskcn, 95 .slot = TASKCN_SLOT_TRACEBUF 96 }; 97 err = cap_copy(dst, src); 98 if (err_is_fail(err)) { 99 return err_push(err, TRACE_ERR_CAP_COPY); 100 } 101 102 return SYS_ERR_OK; 103} 104 105/** 106 * \brief Set up the trace buffer on the current core and notify the kernel. 107 * 108 * Clear the buffer. Return the cap for the buffer. 109 * Should be called once on each core. 110 */ 111errval_t trace_setup_on_core(struct capref *retcap) 112{ 113#ifdef __i386__ 114 return TRACE_ERR_NO_BUFFER; 115#endif 116 117 // Clear the buffer 118 trace_reset_buffer(); 119 120 // Tell the kernel that the trace buffer exists 121 struct capref tracecap = { 122 .cnode = cnode_task, 123 .slot = TASKCN_SLOT_TRACEBUF 124 }; 125 *retcap = tracecap; 126 127 return SYS_ERR_OK; 128} 129 130