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