2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
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.
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.
39 #include <mach/flipc_cb.h>
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.
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.
49 * As long as it is at it, this function prints buffers that are
50 * doubly owned (valid pointers to them from two places).
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
59 static void flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t
,
61 void flipcdbg_print_unowned_buffers(void);
62 void flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr
);
68 flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t cb_ctl
,
69 flipc_data_buffer_t buffer
)
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;
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
));
83 flipc_debug_buffer_bitvec
[element
] |= (1 << subbitpos
);
87 flipcdbg_print_unowned_buffers(void)
89 flipc_comm_buffer_ctl_t cb_ctl
=
90 (flipc_comm_buffer_ctl_t
) flipc_cb_base
;
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;
99 /* Clean out the bitvec. */
100 for (i
= 0; i
< bitvec_length
; i
++)
101 flipc_debug_buffer_bitvec
[i
] = 0;
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
) {
108 int element
, subbitpos
;
110 current_buffer
= FLIPC_DATA_BUFFER_PTR(current_cbptr
);
111 flipcdbg_update_bufferset_bitvec(cb_ctl
, current_buffer
);
114 /* Go through all the endpoints, again setting bits for each buffer. */
115 for (current_endpoint
= FLIPC_ENDPOINT_PTR(cb_ctl
->endpoint
.start
);
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
;
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
);
133 /* Mark this as set. */
134 flipcdbg_update_bufferset_bitvec(cb_ctl
, current_buffer
);
136 /* Increment the current pointer. */
137 current_ptr
= NEXT_BUFFERLIST_PTR_ME(current_ptr
,
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
++) {
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) {
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
);
161 /* Print header if necessary. */
162 if (!header_printed
) {
164 printf("Unreferenced buffers (ptr,idx,cbptr):");
168 printf(" (0x%x,%d,0x%x)", buffer_ptr
, buffer_bitpos
,
179 flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr
)
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;
186 flipc_endpoint_t current_endpoint
;
188 flipc_cb_ptr current_cbptr
;
189 flipc_data_buffer_t current_buffer
;
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;
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.**");
205 if (found_on_freelist
)
206 printf("(Total buffers on freelist: %d/%d)\n", i
,
207 cb_ctl
->data_buffer
.number
);
209 /* Go through all the endpoints, again looking for the buffer. */
210 for (current_endpoint
= FLIPC_ENDPOINT_PTR(cb_ctl
->endpoint
.start
);
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
;
222 while (current_ptr
!= limit_ptr
) {
223 current_cbptr
= *FLIPC_BUFFERLIST_PTR(current_ptr
);
225 if (current_cbptr
== buffer_cbptr
) {
226 printf("Buffer found on endpoint 0x%x (idx: %d)\n",
229 - FLIPC_ENDPOINT_PTR(cb_ctl
->endpoint
.start
)));
230 found_on_endpoints
= 1;
233 /* Increment the current pointer. */
234 current_ptr
= NEXT_BUFFERLIST_PTR_ME(current_ptr
,