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