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