1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. ([email protected]). All rights
3 * reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17
18 * * Neither the name of Cavium Inc. nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
21 * permission.
22
23 * This Software, including technical data, may be subject to U.S. export control
24 * laws, including the U.S. Export Administration Act and its associated
25 * regulations, and may be subject to export or import regulations in other
26 * countries.
27
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
39
40
41
42 /**
43 * @file
44 * cvmx-shmem supplies the cross application shared memory implementation
45 *
46 * <hr>$Revision: 41586 $<hr>
47 */
48 #include "cvmx.h"
49 #include "cvmx-bootmem.h"
50 #include "cvmx-tlb.h"
51 #include "cvmx-shmem.h"
52
53 //#define DEBUG
54
55 struct cvmx_shmem_smdr *__smdr = NULL;
56
57 #ifdef CVMX_BUILD_FOR_LINUX_USER
58 static int __cvmx_shmem_devmemfd = 0; /* fd for /dev/mem */
59 #endif
60
61 #define __CHECK_APP_SMDR do { \
62 if (__smdr == NULL) { \
63 cvmx_dprintf("cvmx_shmem: %s is not set up, Quit line %d \n", \
64 CVMX_SHMEM_DSCPTR_NAME, __LINE__ ); \
65 exit(-1); \
66 } \
67 }while(0)
68
69
70
71 /**
72 * @INTERNAL
73 * Virtual sbrk, assigning virtual address in a global virtual address space.
74 *
75 * @param alignment alignment requirement in bytes
76 * @param size size in bytes
77 */
__cvmx_shmem_vsbrk_64(uint64_t alignment,uint64_t size)78 static inline void *__cvmx_shmem_vsbrk_64(uint64_t alignment, uint64_t size)
79 {
80 uint64_t nbase_64 = CAST64(__smdr->break64);
81 void *nbase = NULL;
82
83 /* Skip unaligned bytes */
84 if (nbase_64 & alignment)
85 nbase_64 += ~(nbase_64 & alignment) + 1;
86
87 if (nbase_64 + size < CVMX_SHMEM_VADDR64_END)
88 {
89 nbase = CASTPTR(void *, nbase_64);
90 __smdr->break64 = nbase + size;
91 }
92
93 return nbase;
94 }
95
96 /**
97 * @INTERNAL
98 * Initialize all SMDR entries, only need to be called once
99 *
100 * @param smdr pointer to the SMDR
101 */
__smdr_new(struct cvmx_shmem_smdr * smdr)102 static inline void __smdr_new(struct cvmx_shmem_smdr *smdr) {
103
104 if (smdr != NULL)
105 {
106 int i;
107
108 cvmx_spinlock_init (&smdr->lock);
109 cvmx_spinlock_lock (&smdr->lock);
110
111 for ( i = 0; i < CVMX_SHMEM_NUM_DSCPTR; i++ )
112 {
113 smdr -> shmd[i].owner = CVMX_SHMEM_OWNER_NONE;
114 smdr -> shmd[i].is_named_block = 0;
115 smdr -> shmd[i].use_count = 0;
116 smdr -> shmd[i].name = NULL;
117 smdr -> shmd[i].vaddr = NULL;
118 smdr -> shmd[i].paddr = 0;
119 smdr -> shmd[i].size = 0;
120 smdr -> shmd[i].alignment = 0;
121 };
122
123 /* Init vaddr */
124 smdr->break64 = (void *)CVMX_SHMEM_VADDR64_START;
125 cvmx_spinlock_unlock (&smdr->lock);
126 }
127
128 /* Make sure the shmem descriptor region is created */
129 __CHECK_APP_SMDR;
130 };
131
132
133
134 /**
135 * @INTERNAL
136 * Initialize __smdr pointer, if SMDR exits already. If not, create a new
137 * one. Once SMDR is created (as a bootmem named block), it is persistent.
138 */
__smdr_init()139 static inline struct cvmx_shmem_smdr *__smdr_init()
140 {
141 const cvmx_bootmem_named_block_desc_t *smdr_nblk = NULL;
142 size_t smdr_size = sizeof(*__smdr);
143 char *smdr_name = CVMX_SHMEM_DSCPTR_NAME;
144
145 __smdr = (struct cvmx_shmem_smdr *) cvmx_bootmem_alloc_named(smdr_size, 0x10000, smdr_name);
146
147 if (__smdr)
148 __smdr_new (__smdr);
149 else
150 {
151 /* Check if SMDR exists already */
152 smdr_nblk = cvmx_bootmem_find_named_block(smdr_name);
153 if (smdr_nblk)
154 {
155 __smdr = (struct cvmx_shmem_smdr *)
156 (cvmx_phys_to_ptr(smdr_nblk->base_addr));
157
158 cvmx_spinlock_lock (&__smdr->lock);
159 if (smdr_nblk->size != smdr_size)
160 {
161 cvmx_dprintf("SMDR named block is created by another "
162 "application with different size %lu, "
163 "expecting %lu \n",
164 (long unsigned int)smdr_nblk->size, (long unsigned int)smdr_size);
165 __smdr = NULL;
166 }
167 cvmx_spinlock_unlock (&__smdr->lock);
168 }
169 }
170
171 if (!__smdr)
172 cvmx_dprintf("cvmx_shmem: Failed to allocate or find SMDR from bootmem \n");
173
174 return __smdr;
175 };
176
177
178 /**
179 * @INTERNAL
180 * Generic Iterator function for all SMDR entries
181 *
182 * @param void(*f)(dscptr) the function to be invoked for every descriptor
183 * @param param
184 *
185 * @return the descriptor iterator stopped at.
186 */
__smdr_iterator(struct cvmx_shmem_dscptr * (* f)(struct cvmx_shmem_dscptr * dscptr,void * p),void * param)187 static struct cvmx_shmem_dscptr *__smdr_iterator(struct cvmx_shmem_dscptr *(*f)(struct cvmx_shmem_dscptr *dscptr, void *p), void *param )
188 {
189 struct cvmx_shmem_dscptr *d, *dscptr = NULL;
190 int i;
191
192 __CHECK_APP_SMDR;
193
194 for (i = 0; i < CVMX_SHMEM_NUM_DSCPTR; i++)
195 {
196 d = &__smdr->shmd[i];
197 if ((dscptr = (*f)(d, param)) != NULL)
198 break; /* stop iteration */
199 }
200
201 return dscptr;
202 }
203
204
205 /**
206 * @INTERNAL
207 * SMDR name match functor. to be used for iterator.
208 *
209 * @param dscptr descriptor passed in by the iterator
210 * @param name string to match against
211 *
212 * @return !NULL descriptor matched
213 * NULL not match
214 */
__cvmx_shmem_smdr_match_name(struct cvmx_shmem_dscptr * dscptr,void * name)215 static struct cvmx_shmem_dscptr *__cvmx_shmem_smdr_match_name(struct cvmx_shmem_dscptr *dscptr, void *name)
216 {
217 char *name_to_match = (char *) name;
218 struct cvmx_shmem_dscptr *ret = NULL;
219
220 if (dscptr->owner == CVMX_SHMEM_OWNER_NONE)
221 return NULL;
222
223 if (strcmp(dscptr->name, name_to_match) == 0)
224 ret = dscptr;
225
226 return ret;
227 }
228
229 /**
230 * @INTERNAL
231 * Find by name
232 *
233 * @param name string to match against
234 *
235 * @return !NULL descriptor matched
236 * NULL not match
237 */
__cvmx_shmem_smdr_find_by_name(char * name)238 static struct cvmx_shmem_dscptr *__cvmx_shmem_smdr_find_by_name(char *name)
239 {
240 return __smdr_iterator( __cvmx_shmem_smdr_match_name, name);
241 }
242
243 /**
244 * @INTERNAL
245 * SMDR is free functor. to be used for iterator.
246 *
247 * @param dscptr descriptor passed in by the iterator
248 * @param nouse
249 *
250 * @return !NULL descriptor is free
251 * NULL descriptor is not free
252 */
__cvmx_shmem_smdr_is_free(struct cvmx_shmem_dscptr * dscptr,void * nouse)253 static struct cvmx_shmem_dscptr *__cvmx_shmem_smdr_is_free(struct cvmx_shmem_dscptr* dscptr, void *nouse)
254 {
255 if (dscptr->owner == CVMX_SHMEM_OWNER_NONE)
256 return dscptr;
257 else
258 return NULL;
259 }
260
261 /**
262 * @INTERNAL
263 * Search SMDR to find the first free descriptor
264 *
265 * @return !NULL free descriptor found
266 * NULL nothing found
267 */
__cvmx_shmem_smdr_find_free_dscptr(void)268 struct cvmx_shmem_dscptr *__cvmx_shmem_smdr_find_free_dscptr(void)
269 {
270 return __smdr_iterator(__cvmx_shmem_smdr_is_free, NULL);
271 }
272
273 /**
274 * @INTERNAL
275 * free a descriptor
276 *
277 * @param dscptr descriptor to be freed
278 */
__cvmx_shmem_smdr_free(struct cvmx_shmem_dscptr * dscptr)279 static void __cvmx_shmem_smdr_free(struct cvmx_shmem_dscptr *dscptr)
280 {
281 dscptr->owner = CVMX_SHMEM_OWNER_NONE;
282 }
283
284
285 /**
286 * Per core shmem init function
287 *
288 * @return cvmx_shmem_smdr* pointer to __smdr
289 */
cvmx_shmem_init()290 struct cvmx_shmem_smdr *cvmx_shmem_init()
291 {
292 return __smdr_init();
293 }
294
295 /**
296 * Open shared memory based on named block
297 *
298 * @return dscptr descriptor of the opened named block
299 */
cvmx_shmem_named_block_open(char * name,uint32_t size,int oflag)300 struct cvmx_shmem_dscptr *cvmx_shmem_named_block_open(char *name, uint32_t size, int oflag)
301 {
302 const cvmx_bootmem_named_block_desc_t *shmem_nblk = NULL;
303 struct cvmx_shmem_dscptr *dscptr = NULL;
304 int nblk_allocated = 0; /* Assume we don't need to allocate a new
305 bootmem block */
306 void *vaddr = NULL;
307 const uint64_t size_4k = 4*1024, size_512mb = 512*1024*1024;
308
309 __CHECK_APP_SMDR;
310
311 /* Check size, Make sure it is minimal 4K, no bigger than 512MB */
312 if (size > size_512mb) {
313 cvmx_dprintf("Shared memory size can not be bigger than 512MB \n");
314 return NULL;
315 }
316 if (size < size_4k)
317 size = size_4k;
318
319 size = __upper_power_of_two(size);
320
321 cvmx_spinlock_lock(&__smdr->lock);
322
323 shmem_nblk = cvmx_bootmem_find_named_block(name);
324 if ((shmem_nblk == NULL) && (oflag & CVMX_SHMEM_O_CREAT))
325 {
326 void *p;
327 /* The named block does not exist, create it if caller specifies
328 the O_CREAT flag */
329 nblk_allocated = 1;
330 p = cvmx_bootmem_alloc_named(size, size, name);
331 if (p)
332 shmem_nblk = cvmx_bootmem_find_named_block(name);
333 #ifdef DEBUG
334 cvmx_dprintf("cvmx-shmem-dbg:"
335 "creating a new block %s: blk %p, shmem_nblk %p \n",
336 name, p, shmem_nblk);
337 #endif
338 }
339
340 if (shmem_nblk == NULL)
341 goto err;
342
343 /* We are now holding a valid named block */
344
345 dscptr = __cvmx_shmem_smdr_find_by_name(name);
346 if (dscptr)
347 {
348 if (nblk_allocated)
349 {
350 /* name conflict between bootmem name space and SMDR name space */
351 cvmx_dprintf("cvmx-shmem: SMDR descriptor name conflict, %s \n", name);
352 goto err;
353 }
354 /* Make sure size and alignment matches with existing descriptor */
355 if ((size != dscptr->size) || (size != dscptr -> alignment))
356 goto err;
357 }
358 else
359 {
360 /* Create a new descriptor */
361 dscptr = __cvmx_shmem_smdr_find_free_dscptr();
362 if (dscptr)
363 goto init;
364 else
365 {
366 cvmx_dprintf("cvmx-shmem: SMDR out of descriptors \n");
367 goto err;
368 }
369 }
370
371 /* Maintain the reference count */
372 if (dscptr != NULL)
373 dscptr->use_count += 1;
374
375 cvmx_spinlock_unlock(&__smdr->lock);
376 return dscptr;
377
378 err:
379 #ifdef DEBUG
380 cvmx_dprintf("cvmx-shmem-dbg: named block open failed \n");
381 #endif
382
383 if (dscptr)
384 __cvmx_shmem_smdr_free(dscptr);
385 if (shmem_nblk && nblk_allocated)
386 cvmx_bootmem_free_named(name);
387 cvmx_spinlock_unlock(&__smdr->lock);
388
389 return NULL;
390
391 init:
392
393 #ifdef DEBUG
394 cvmx_dprintf("cvmx-shmem-dbg: init SMDR descriptor %p \n", dscptr);
395 #endif
396
397 /* Assign vaddr for single address space mapping */
398 vaddr = __cvmx_shmem_vsbrk_64(size, size);
399 if (vaddr == NULL) {
400 /* Failed to allocate virtual address, clean up */
401 goto err;
402 }
403
404 #ifdef DEBUG
405 cvmx_dprintf("cmvx-shmem-dbg: allocated vaddr %p \n", vaddr);
406 #endif
407 dscptr->vaddr = vaddr;
408
409 /* Store descriptor information, name, alignment,size... */
410 dscptr->owner = cvmx_get_core_num();
411 dscptr->is_named_block = 1;
412 dscptr->use_count = 1;
413 dscptr->name =shmem_nblk->name ;
414 dscptr->paddr = shmem_nblk->base_addr;
415 dscptr->size = size;
416 dscptr->alignment = size;
417
418 /* Store permission bits */
419 if (oflag & CVMX_SHMEM_O_WRONLY)
420 dscptr->p_wronly = 1;
421 if (oflag & CVMX_SHMEM_O_RDWR)
422 dscptr->p_rdwr = 1;
423
424 cvmx_spinlock_unlock(&__smdr->lock);
425 return dscptr;
426 }
427
428 /**
429 * @INTERNAL
430 *
431 * For stand along SE application only.
432 *
433 * Add TLB mapping to map the shared memory
434 *
435 * @param dscptr shared memory descriptor
436 * @param pflag protection flags
437 *
438 * @return vaddr the virtual address mapped for the shared memory
439 */
440 #ifndef CVMX_BUILD_FOR_LINUX_USER
__cvmx_shmem_map_standalone(struct cvmx_shmem_dscptr * dscptr,int pflag)441 void *__cvmx_shmem_map_standalone(struct cvmx_shmem_dscptr *dscptr, int pflag)
442 {
443 int free_index;
444
445 /* Find a free tlb entry */
446 free_index = cvmx_tlb_allocate_runtime_entry();
447
448 if (free_index < 0 )
449 {
450 cvmx_dprintf("cvmx-shmem: shmem_map failed, out TLB entries \n");
451 return NULL;
452 }
453
454 #ifdef DEBUG
455 cvmx_dprintf("cmvx-shmem-dbg:"
456 "shmem_map TLB %d: vaddr %p paddr %lx, size %x \n",
457 free_index, dscptr->vaddr, dscptr->paddr, dscptr->size );
458 #endif
459
460 cvmx_tlb_write_runtime_entry(free_index, CAST64(dscptr->vaddr),
461 dscptr->paddr, dscptr->size,
462 TLB_DIRTY | TLB_VALID | TLB_GLOBAL);
463
464 return dscptr -> vaddr;
465 }
466 #endif
467
468 /**
469 * @INTERNAL
470 *
471 * For Linux user application only
472 *
473 * Add mmap the shared memory
474 *
475 * @param dscptr shared memory descriptor
476 * @param pflag protection flags
477 *
478 * @return vaddr the virtual address mapped for the shared memory
479 */
480 #ifdef CVMX_BUILD_FOR_LINUX_USER
__cvmx_shmem_map_linux(struct cvmx_shmem_dscptr * dscptr,int pflag)481 static inline void *__cvmx_shmem_map_linux(struct cvmx_shmem_dscptr *dscptr, int pflag)
482 {
483 void *vaddr = NULL;
484
485 if(__cvmx_shmem_devmemfd == 0)
486 {
487 __cvmx_shmem_devmemfd = open("/dev/mem", O_RDWR);
488 if (__cvmx_shmem_devmemfd < 0)
489 {
490 cvmx_dprintf("Failed to open /dev/mem\n");
491 exit(-1);
492 }
493 }
494
495 vaddr = mmap(dscptr->vaddr, dscptr->size, PROT_READ|PROT_WRITE,
496 MAP_SHARED, __cvmx_shmem_devmemfd, 0);
497
498 /* Make sure the mmap maps to the same virtual address specified in
499 * descriptor
500 */
501 if ((vaddr!=NULL) && (vaddr != dscptr->vaddr))
502 {
503 munmap(vaddr, dscptr->size);
504 vaddr = NULL;
505 }
506 return vaddr;
507 }
508 #endif
509
510 /**
511 * cvmx_shmem API
512 *
513 * Add mapping for the shared memory
514 *
515 * @param dscptr shared memory descriptor
516 * @param pflag protection flags
517 *
518 * @return vaddr the virtual address mapped for the shared memory
519 */
cvmx_shmem_map(struct cvmx_shmem_dscptr * dscptr,int pflag)520 void *cvmx_shmem_map(struct cvmx_shmem_dscptr *dscptr, int pflag)
521 {
522 void *vaddr = NULL;
523 #ifdef CVMX_BUILD_FOR_LINUX_USER
524 vaddr = __cvmx_shmem_map_linux(dscptr, pflag);
525 #else
526 vaddr = __cvmx_shmem_map_standalone(dscptr, pflag);
527 #endif
528 return vaddr;
529 }
530
531
532 /**
533 * @INTERNAL
534 *
535 * For Linux user application only
536 *
537 * ummap the shared memory
538 *
539 * @param dscptr shared memory descriptor
540 *
541 */
542 #ifdef CVMX_BUILD_FOR_LINUX_USER
__cvmx_shmem_unmap_linux(struct cvmx_shmem_dscptr * dscptr)543 static inline void __cvmx_shmem_unmap_linux(struct cvmx_shmem_dscptr* dscptr)
544 {
545 if (__cvmx_shmem_devmemfd && dscptr)
546 munmap(dscptr->vaddr, dscptr->size);
547 }
548 #endif
549
550
551 /**
552 * @INTERNAL
553 *
554 * For stand along SE application only.
555 *
556 * ummap the shared memory
557 *
558 * @param dscptr shared memory descriptor
559 *
560 */
561 #ifndef CVMX_BUILD_FOR_LINUX_USER
562 static inline void
__cvmx_shmem_unmap_standalone(struct cvmx_shmem_dscptr * dscptr)563 __cvmx_shmem_unmap_standalone(struct cvmx_shmem_dscptr *dscptr)
564 {
565 int index;
566
567 index = cvmx_tlb_lookup(CAST64(dscptr->vaddr));
568
569 #ifdef DEBUG
570 cvmx_dprintf("cmvx-shmem-dbg:"
571 "shmem_unmap TLB %d \n", index);
572 #endif
573 cvmx_tlb_free_runtime_entry(index);
574 }
575 #endif
576
577 /**
578 * ummap the shared memory
579 *
580 * @param dscptr shared memory descriptor
581 *
582 */
cvmx_shmem_unmap(struct cvmx_shmem_dscptr * dscptr)583 void cvmx_shmem_unmap(struct cvmx_shmem_dscptr *dscptr)
584 {
585 #ifdef CVMX_BUILD_FOR_LINUX_USER
586 __cvmx_shmem_unmap_linux(dscptr);
587 #else
588 __cvmx_shmem_unmap_standalone(dscptr);
589 #endif
590 }
591
592 /**
593 * @INTERNAL
594 *
595 * Common implementation of closing a descriptor.
596 *
597 * @param dscptr shared memory descriptor
598 * @param remove 1: remove the descriptor and named block if this
599 * this is the last user of the descriptor
600 * 0: do not remove
601 * @return 0: Success
602 * !0: Failed
603 *
604 */
__cvmx_shmem_close_dscptr(struct cvmx_shmem_dscptr * dscptr,int remove)605 static inline int __cvmx_shmem_close_dscptr(struct cvmx_shmem_dscptr *dscptr, int remove)
606 {
607 cvmx_spinlock_lock(&dscptr->lock);
608
609 if (dscptr->use_count >0)
610 dscptr->use_count-= 1;
611
612 if ((dscptr->use_count == 0) && remove)
613 {
614 /* Free this descriptor */
615 __cvmx_shmem_smdr_free(dscptr);
616
617 /* Free named block if this is the last user, and the block
618 is created by the application */
619 if (dscptr->is_named_block)
620 {
621 #ifdef DEBUG
622 cvmx_dprintf("cvmx-shmem-dbg: remove named block %s \n", dscptr->name);
623 #endif
624 cvmx_bootmem_phy_named_block_free(dscptr->name, 0);
625 }
626 }
627 cvmx_spinlock_unlock(&dscptr->lock);
628 return 0;
629 }
630
631
632 /**
633 * @INTERNAL
634 *
635 * For stand along SE application only.
636 *
637 * close a descriptor.
638 *
639 * @param dscptr shared memory descriptor
640 * @param remove 1: remove the descriptor and named block if this
641 * this is the last user of the descriptor
642 * 0: do not remove
643 * @return 0: Success
644 * !0: Failed
645 *
646 */
647 #ifndef CVMX_BUILD_FOR_LINUX_USER
__cvmx_shmem_close_standalone(struct cvmx_shmem_dscptr * dscptr,int remove)648 static inline int __cvmx_shmem_close_standalone(struct cvmx_shmem_dscptr *dscptr, int remove)
649 {
650 return __cvmx_shmem_close_dscptr(dscptr, remove);
651 }
652 #endif
653
654 /**
655 * @INTERNAL
656 *
657 * For Linux user application only.
658 *
659 * close a descriptor.
660 *
661 * @param dscptr shared memory descriptor
662 * @param remove 1: remove the descriptor and named block if this
663 * this is the last user of the descriptor
664 * 0: do not remove
665 * @return 0: Success
666 * !0: Failed
667 *
668 */
669 #ifdef CVMX_BUILD_FOR_LINUX_USER
__cvmx_shmem_close_linux(struct cvmx_shmem_dscptr * dscptr,int remove)670 int __cvmx_shmem_close_linux(struct cvmx_shmem_dscptr *dscptr, int remove)
671 {
672 int ret;
673 ret = __cvmx_shmem_close_dscptr(dscptr, remove);
674
675 if (ret && __cvmx_shmem_devmemfd)
676 {
677 close(__cvmx_shmem_devmemfd);
678 __cvmx_shmem_devmemfd=0;
679 }
680
681 return ret;
682
683 }
684 #endif
685
686 /**
687 *
688 * close a descriptor.
689 *
690 * @param dscptr shared memory descriptor
691 * @param remove 1: remove the descriptor and named block if this
692 * this is the last user of the descriptor
693 * 0: do not remove
694 * @return 0: Success
695 * !0: Failed
696 *
697 */
cvmx_shmem_close(struct cvmx_shmem_dscptr * dscptr,int remove)698 int cvmx_shmem_close(struct cvmx_shmem_dscptr *dscptr, int remove)
699 {
700 int ret;
701 #ifdef CVMX_BUILD_FOR_LINUX_USER
702 ret = __cvmx_shmem_close_linux(dscptr, remove);
703 #else
704 ret = __cvmx_shmem_close_standalone(dscptr, remove);
705 #endif
706 return ret;
707 }
708
709 #ifdef DEBUG
710 /**
711 * @INTERNAL
712 * SMDR non-free descriptor dump functor. to be used for iterator.
713 *
714 * @param dscptr descriptor passed in by the iterator
715 *
716 * @return NULL always
717 */
__cvmx_shmem_smdr_display_dscptr(struct cvmx_shmem_dscptr * dscptr,void * nouse)718 static struct cvmx_shmem_dscptr *__cvmx_shmem_smdr_display_dscptr(struct cvmx_shmem_dscptr *dscptr, void *nouse)
719 {
720 if ((dscptr != NULL ) && (dscptr -> owner != CVMX_SHMEM_OWNER_NONE))
721 {
722 cvmx_dprintf(" %s: phy: %lx, size %d, alignment %lx, virt %p use_count %d\n",
723 dscptr->name, dscptr-> paddr,
724 dscptr->size, dscptr-> alignment,
725 dscptr->vaddr, dscptr->use_count);
726 }
727
728 return NULL;
729 }
730 #endif
731
732 /**
733 * SMDR descriptor show
734 *
735 * list all non-free descriptors
736 */
cvmx_shmem_show(void)737 void cvmx_shmem_show(void)
738 {
739 __CHECK_APP_SMDR;
740
741 #ifdef DEBUG
742 cvmx_dprintf("SMDR descriptor list: \n");
743 cvmx_spinlock_lock(&__smdr->lock);
744 __smdr_iterator(__cvmx_shmem_smdr_display_dscptr, NULL);
745 cvmx_spinlock_unlock(&__smdr->lock);
746 cvmx_dprintf("\n\n");
747 #endif
748 }
749