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