]> git.saurik.com Git - apple/xnu.git/blame - osfmk/mach/flipc_debug.h
xnu-344.21.73.tar.gz
[apple/xnu.git] / osfmk / mach / flipc_debug.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d7e50217 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
d7e50217
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d7e50217
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * @OSF_COPYRIGHT@
27 *
28 */
29
30/*
31 * Really a C file, but I'd like to have this code available in both
32 * the kernel and the application, so I'll put it in a .h file. This
33 * file needs to be included only once in the AIL or ME, into a .c file
34 * where it will be compiled.
35 */
36
37/*
38 * Since these are debug functions, it doesn't matter which processor macro
39 * version I use; I don't mind spoiling cache while I'm debugging.
40 */
41
42#include <mach/flipc_cb.h>
43/*
44 * Print (using printf) all buffers in the communications buffer that
45 * are not on any endpoint or on the buffer freelist. Only active
46 * endpoints are checked.
47 *
48 * Note that no locking is done; this function implicitly assumes the
49 * communications buffer is in a quiescent state. It is expected that
50 * this function will normally be called from a debugger.
51 *
52 * As long as it is at it, this function prints buffers that are
53 * doubly owned (valid pointers to them from two places).
54 */
55
56/*
57 * Given that these functions will normally be called from the debugger,
58 * there isn't any need to globally visible prototypes for them. To
59 * eliminate compilation warnings, we include prototypes for the functions
60 * here in the file.
61 */
62static void flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t,
63 flipc_data_buffer_t);
64void flipcdbg_print_unowned_buffers(void);
65void flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr);
66
67#ifdef __GNUC__
68__inline__
69#endif
70static void
71flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t cb_ctl,
72 flipc_data_buffer_t buffer)
73{
74 unsigned char *buffer_base = flipc_cb_base + cb_ctl->data_buffer.start;
75 int bitpos = ((((unsigned char *) buffer) - buffer_base)
76 / cb_ctl->data_buffer_size);
77 int element = bitpos / (sizeof(unsigned long) * 8);
78 int subbitpos = bitpos - element * sizeof(unsigned long) * 8;
79
80 /* Is that position set already? */
81 if (flipc_debug_buffer_bitvec[element] & (1 << subbitpos))
82 printf("Buffer 0x%x (idx: %d, cbptr: 0x%x) is multiply referenced.\n",
83 buffer, bitpos, FLIPC_CBPTR(buffer));
84
85 /* Set it. */
86 flipc_debug_buffer_bitvec[element] |= (1 << subbitpos);
87}
88
89void
90flipcdbg_print_unowned_buffers(void)
91{
92 flipc_comm_buffer_ctl_t cb_ctl =
93 (flipc_comm_buffer_ctl_t) flipc_cb_base;
94 int i;
95 unsigned long bitvec_length = ((cb_ctl->data_buffer.number + sizeof(unsigned long) * 8)
96 / (sizeof(unsigned int) * 8));
97 flipc_data_buffer_t current_buffer;
98 flipc_endpoint_t current_endpoint;
99 flipc_cb_ptr current_cbptr;
100 int header_printed = 0;
101
102 /* Clean out the bitvec. */
103 for (i = 0; i < bitvec_length; i++)
104 flipc_debug_buffer_bitvec[i] = 0;
105
106 /* Go through the freelist, setting bits for each buffer. */
107 for (current_cbptr = cb_ctl->data_buffer.free;
108 current_cbptr != FLIPC_CBPTR_NULL;
109 current_cbptr = current_buffer->u.free) {
110 int bitpos;
111 int element, subbitpos;
112
113 current_buffer = FLIPC_DATA_BUFFER_PTR(current_cbptr);
114 flipcdbg_update_bufferset_bitvec(cb_ctl, current_buffer);
115 }
116
117 /* Go through all the endpoints, again setting bits for each buffer. */
118 for (current_endpoint = FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start);
119 (current_endpoint
120 < (FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)
121 + cb_ctl->endpoint.number));
122 current_endpoint++) {
123 if (EXTRACT_ENABLED(current_endpoint->saildm_dpb_or_enabled)) {
124 flipc_cb_ptr current_ptr =
125 (EXTRACT_DPB(current_endpoint->saildm_dpb_or_enabled)
126 ? current_endpoint->sme_process_ptr
127 : current_endpoint->shrd_acquire_ptr);
128 flipc_cb_ptr limit_ptr = current_endpoint->sail_release_ptr;
129
130 while (current_ptr != limit_ptr) {
131 flipc_cb_ptr current_buffer_cbptr =
132 *FLIPC_BUFFERLIST_PTR(current_ptr);
133 flipc_data_buffer_t current_buffer =
134 FLIPC_DATA_BUFFER_PTR(current_buffer_cbptr);
135
136 /* Mark this as set. */
137 flipcdbg_update_bufferset_bitvec(cb_ctl, current_buffer);
138
139 /* Increment the current pointer. */
140 current_ptr = NEXT_BUFFERLIST_PTR_ME(current_ptr,
141 current_endpoint);
142 }
143 }
144 }
145
146 /* Ok, we should have marked every buffer that has a reference.
147 Print out all the ones that done have references. */
148 for (i = 0; i < bitvec_length; i++) {
149 int this_limit =
150 ((i == bitvec_length - 1)
151 ? cb_ctl->data_buffer.number % (sizeof(unsigned long)*8)
152 : sizeof(unsigned long)*8);
153 if (flipc_debug_buffer_bitvec[i] != (unsigned long) -1) {
154 int j;
155 for (j = 0; j < this_limit; j++) {
156 if (!(flipc_debug_buffer_bitvec[i] & (1 << j))) {
157 int buffer_bitpos = i * sizeof(unsigned long) * 8 + j;
158 flipc_cb_ptr buffer_cbptr =
159 (buffer_bitpos * cb_ctl->data_buffer_size
160 + cb_ctl->data_buffer.start);
161 flipc_data_buffer_t buffer_ptr =
162 FLIPC_DATA_BUFFER_PTR(buffer_cbptr);
163
164 /* Print header if necessary. */
165 if (!header_printed) {
166 header_printed = 1;
167 printf("Unreferenced buffers (ptr,idx,cbptr):");
168 }
169
170 /* Print buffer. */
171 printf(" (0x%x,%d,0x%x)", buffer_ptr, buffer_bitpos,
172 buffer_cbptr);
173 }
174 }
175 }
176 }
177 if (header_printed)
178 printf("\n");
179}
180
181void
182flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr)
183{
184 flipc_comm_buffer_ctl_t cb_ctl =
185 (flipc_comm_buffer_ctl_t) flipc_cb_base;
186 int found_on_freelist = 0;
187 int found_on_endpoints = 0;
188 int i;
189 flipc_endpoint_t current_endpoint;
190
191 flipc_cb_ptr current_cbptr;
192 flipc_data_buffer_t current_buffer;
193
194 /* Go through the freelist, looking for buffer. */
195 for (i = 0, current_cbptr = cb_ctl->data_buffer.free;
196 current_cbptr != FLIPC_CBPTR_NULL;
197 i++, current_cbptr = current_buffer->u.free) {
198 if (current_cbptr == buffer_cbptr) {
199 printf("Buffer found on freelist in position %d\n", i);
200 found_on_freelist = 1;
201 }
202 current_buffer = FLIPC_DATA_BUFFER_PTR(current_cbptr);
203 if (i > cb_ctl->data_buffer.number) {
204 printf ("**Some form of corruption following freelist.**");
205 return;
206 }
207 }
208 if (found_on_freelist)
209 printf("(Total buffers on freelist: %d/%d)\n", i,
210 cb_ctl->data_buffer.number);
211
212 /* Go through all the endpoints, again looking for the buffer. */
213 for (current_endpoint = FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start);
214 (current_endpoint
215 < (FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)
216 + cb_ctl->endpoint.number));
217 current_endpoint++) {
218 if (EXTRACT_ENABLED(current_endpoint->saildm_dpb_or_enabled)) {
219 flipc_cb_ptr current_ptr =
220 (EXTRACT_DPB(current_endpoint->saildm_dpb_or_enabled)
221 ? current_endpoint->sme_process_ptr
222 : current_endpoint->shrd_acquire_ptr);
223 flipc_cb_ptr limit_ptr = current_endpoint->sail_release_ptr;
224
225 while (current_ptr != limit_ptr) {
226 current_cbptr = *FLIPC_BUFFERLIST_PTR(current_ptr);
227
228 if (current_cbptr == buffer_cbptr) {
229 printf("Buffer found on endpoint 0x%x (idx: %d)\n",
230 current_endpoint,
231 (current_endpoint
232 - FLIPC_ENDPOINT_PTR(cb_ctl->endpoint.start)));
233 found_on_endpoints = 1;
234 }
235
236 /* Increment the current pointer. */
237 current_ptr = NEXT_BUFFERLIST_PTR_ME(current_ptr,
238 current_endpoint);
239 }
240 }
241 }
242}
243
244
245