2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  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. 
  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. 
  45 #include <mach/flipc_cb.h> 
  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. 
  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. 
  55  * As long as it is at it, this function prints buffers that are 
  56  * doubly owned (valid pointers to them from two places). 
  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 
  65 static void flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t
, 
  67 void flipcdbg_print_unowned_buffers(void); 
  68 void flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr
); 
  74 flipcdbg_update_bufferset_bitvec(flipc_comm_buffer_ctl_t cb_ctl
, 
  75                                  flipc_data_buffer_t buffer
) 
  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; 
  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
)); 
  89     flipc_debug_buffer_bitvec
[element
] |= (1 << subbitpos
); 
  93 flipcdbg_print_unowned_buffers(void) 
  95     flipc_comm_buffer_ctl_t cb_ctl 
= 
  96         (flipc_comm_buffer_ctl_t
) flipc_cb_base
; 
  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; 
 105     /* Clean out the bitvec.  */ 
 106     for (i 
= 0; i 
< bitvec_length
; i
++) 
 107         flipc_debug_buffer_bitvec
[i
] = 0; 
 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
) { 
 114         int element
, subbitpos
; 
 116         current_buffer 
= FLIPC_DATA_BUFFER_PTR(current_cbptr
); 
 117         flipcdbg_update_bufferset_bitvec(cb_ctl
, current_buffer
); 
 120     /* Go through all the endpoints, again setting bits for each buffer.  */ 
 121     for (current_endpoint 
= FLIPC_ENDPOINT_PTR(cb_ctl
->endpoint
.start
); 
 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
; 
 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
); 
 139                 /* Mark this as set.  */ 
 140                 flipcdbg_update_bufferset_bitvec(cb_ctl
, current_buffer
); 
 142                 /* Increment the current pointer.  */ 
 143                 current_ptr 
= NEXT_BUFFERLIST_PTR_ME(current_ptr
, 
 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
++) { 
 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) { 
 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
); 
 167                     /* Print header if necessary.  */ 
 168                     if (!header_printed
) { 
 170                         printf("Unreferenced buffers (ptr,idx,cbptr):"); 
 174                     printf(" (0x%x,%d,0x%x)", buffer_ptr
, buffer_bitpos
, 
 185 flipcdbg_buffer_find_refs(flipc_cb_ptr buffer_cbptr
) 
 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; 
 192     flipc_endpoint_t current_endpoint
; 
 194     flipc_cb_ptr current_cbptr
; 
 195     flipc_data_buffer_t current_buffer
; 
 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; 
 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.**"); 
 211     if (found_on_freelist
) 
 212         printf("(Total buffers on freelist: %d/%d)\n", i
, 
 213                cb_ctl
->data_buffer
.number
); 
 215     /* Go through all the endpoints, again looking for the buffer.  */ 
 216     for (current_endpoint 
= FLIPC_ENDPOINT_PTR(cb_ctl
->endpoint
.start
); 
 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
; 
 228             while (current_ptr 
!= limit_ptr
) { 
 229                 current_cbptr 
= *FLIPC_BUFFERLIST_PTR(current_ptr
); 
 231                 if (current_cbptr 
== buffer_cbptr
) { 
 232                     printf("Buffer found on endpoint 0x%x (idx: %d)\n", 
 235                             - FLIPC_ENDPOINT_PTR(cb_ctl
->endpoint
.start
))); 
 236                     found_on_endpoints 
= 1; 
 239                 /* Increment the current pointer.  */ 
 240                 current_ptr 
= NEXT_BUFFERLIST_PTR_ME(current_ptr
,