eal: remove sys/queue.h from public headers
[dpdk.git] / drivers / net / bnxt / tf_core / tf_sram_mgr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include "tf_sram_mgr.h"
8 #include "tf_core.h"
9 #include "tf_rm.h"
10 #include "tf_common.h"
11 #include "assert.h"
12 #include "tf_util.h"
13 #include "tfp.h"
14 #if (STATS_CLEAR_ON_READ_SUPPORT == 0)
15 #include "tf_msg.h"
16 #endif
17 /***************************
18  * Internal Data Structures
19  ***************************/
20
21 /**
22  * TF SRAM block info
23  *
24  * Contains all the information about a particular 64B SRAM
25  * block and the slices within it.
26  */
27 struct tf_sram_block {
28         /* Previous block
29          */
30         struct tf_sram_block *prev;
31         /* Next block
32          */
33         struct tf_sram_block *next;
34
35         /** Bitmap indicating which slices are in use
36          *  If a bit is set, it indicates the slice
37          *  in the row is in use.
38          */
39         uint8_t in_use_mask;
40
41         /** Block id - this is a 64B offset
42          */
43         uint16_t block_id;
44 };
45
46 /**
47  * TF SRAM block list
48  *
49  * List of 64B SRAM blocks used for fixed size slices (8, 16, 32, 64B)
50  */
51 struct tf_sram_slice_list {
52         /** Pointer to head of linked list of blocks.
53          */
54         struct tf_sram_block *head;
55
56         /** Pointer to tail of linked list of blocks.
57          */
58         struct tf_sram_block *tail;
59
60         /** Total count of blocks
61          */
62         uint32_t cnt;
63
64         /** First non-full block in the list
65          */
66         struct tf_sram_block *first_not_full_block;
67
68         /** Entry slice size for this list
69          */
70         enum tf_sram_slice_size size;
71 };
72
73
74 /**
75  * TF SRAM bank info consists of lists of different slice sizes per bank
76  */
77 struct tf_sram_bank_info {
78         struct tf_sram_slice_list slice[TF_SRAM_SLICE_SIZE_MAX];
79 };
80
81 /**
82  * SRAM banks consist of SRAM bank information
83  */
84 struct tf_sram_bank {
85         struct tf_sram_bank_info bank[TF_SRAM_BANK_ID_MAX];
86 };
87
88 /**
89  * SRAM banks consist of SRAM bank information
90  */
91 struct tf_sram {
92         struct tf_sram_bank dir[TF_DIR_MAX];
93 };
94
95 /**********************
96  * Internal functions
97  **********************/
98
99 /**
100  * Get slice size in string format
101  */
102 const char
103 *tf_sram_slice_2_str(enum tf_sram_slice_size slice_size)
104 {
105         switch (slice_size) {
106         case TF_SRAM_SLICE_SIZE_8B:
107                 return "8B slice";
108         case TF_SRAM_SLICE_SIZE_16B:
109                 return "16B slice";
110         case TF_SRAM_SLICE_SIZE_32B:
111                 return "32B slice";
112         case TF_SRAM_SLICE_SIZE_64B:
113                 return "64B slice";
114         default:
115                 return "Invalid slice size";
116         }
117 }
118
119 /**
120  * Get bank in string format
121  */
122 const char
123 *tf_sram_bank_2_str(enum tf_sram_bank_id bank_id)
124 {
125         switch (bank_id) {
126         case TF_SRAM_BANK_ID_0:
127                 return "bank_0";
128         case TF_SRAM_BANK_ID_1:
129                 return "bank_1";
130         case TF_SRAM_BANK_ID_2:
131                 return "bank_2";
132         case TF_SRAM_BANK_ID_3:
133                 return "bank_3";
134         default:
135                 return "Invalid bank_id";
136         }
137 }
138
139 /**
140  * TF SRAM get slice list
141  */
142 static int
143 tf_sram_get_slice_list(struct tf_sram *sram,
144                        struct tf_sram_slice_list **slice_list,
145                        enum tf_sram_slice_size slice_size,
146                        enum tf_dir dir,
147                        enum tf_sram_bank_id bank_id)
148 {
149         int rc = 0;
150
151         TF_CHECK_PARMS2(sram, slice_list);
152
153         *slice_list = &sram->dir[dir].bank[bank_id].slice[slice_size];
154
155         return rc;
156 }
157
158 uint16_t tf_sram_bank_2_base_offset[TF_SRAM_BANK_ID_MAX] = {
159         0,
160         2048,
161         4096,
162         6144
163 };
164
165 /**
166  * Translate a block id and bank_id to an 8B offset
167  */
168 static void
169 tf_sram_block_id_2_offset(enum tf_sram_bank_id bank_id, uint16_t block_id,
170                           uint16_t *offset)
171 {
172         *offset = (block_id + tf_sram_bank_2_base_offset[bank_id]) << 3;
173 }
174
175 /**
176  * Translates an 8B offset and bank_id to a block_id
177  */
178 static void
179 tf_sram_offset_2_block_id(enum tf_sram_bank_id bank_id, uint16_t offset,
180                           uint16_t *block_id, uint16_t *slice_offset)
181 {
182         *slice_offset = offset & 0x7;
183         *block_id = ((offset & ~0x7) >> 3) -
184                     tf_sram_bank_2_base_offset[bank_id];
185 }
186
187 /**
188  * Find a matching block_id within the slice list
189  */
190 static struct tf_sram_block
191 *tf_sram_find_block(uint16_t block_id, struct tf_sram_slice_list *slice_list)
192 {
193         uint32_t cnt;
194         struct tf_sram_block *block;
195
196         cnt = slice_list->cnt;
197         block = slice_list->head;
198
199         while (cnt > 0 && block) {
200                 if (block->block_id == block_id)
201                         return block;
202                 block = block->next;
203                 cnt--;
204         }
205         return NULL;
206 }
207
208 /**
209  * Given the current block get the next block within the slice list
210  *
211  * List is not changed.
212  */
213 static struct tf_sram_block
214 *tf_sram_get_next_block(struct tf_sram_block *block)
215 {
216         struct tf_sram_block *nblock;
217
218         if (block != NULL)
219                 nblock = block->next;
220         else
221                 nblock = NULL;
222         return nblock;
223 }
224
225 /**
226  * Free an allocated slice from a block and if the block is empty,
227  * return an indication so that the block can be freed.
228  */
229 static int
230 tf_sram_free_slice(enum tf_sram_slice_size slice_size,
231                    uint16_t slice_offset, struct tf_sram_block *block,
232                    bool *block_is_empty)
233 {
234         int rc = 0;
235         uint8_t shift;
236         uint8_t slice_mask = 0;
237
238         TF_CHECK_PARMS2(block, block_is_empty);
239
240         switch (slice_size) {
241         case TF_SRAM_SLICE_SIZE_8B:
242                 shift = slice_offset >> 0;
243                 assert(shift < 8);
244                 slice_mask = 1 << shift;
245                 break;
246
247         case TF_SRAM_SLICE_SIZE_16B:
248                 shift = slice_offset >> 1;
249                 assert(shift < 4);
250                 slice_mask = 1 << shift;
251                 break;
252
253         case TF_SRAM_SLICE_SIZE_32B:
254                 shift = slice_offset >> 2;
255                 assert(shift < 2);
256                 slice_mask = 1 << shift;
257                 break;
258
259         case TF_SRAM_SLICE_SIZE_64B:
260         default:
261                 shift = slice_offset >> 0;
262                 assert(shift < 1);
263                 slice_mask = 1 << shift;
264                 break;
265         }
266
267         if ((block->in_use_mask & slice_mask) == 0) {
268                 rc = -EINVAL;
269                 TFP_DRV_LOG(ERR, "block_id(0x%x) slice(%d) was not allocated\n",
270                             block->block_id, slice_offset);
271                 return rc;
272         }
273
274         block->in_use_mask &= ~slice_mask;
275
276         if (block->in_use_mask == 0)
277                 *block_is_empty = true;
278         else
279                 *block_is_empty = false;
280
281         return rc;
282 }
283
284 /**
285  * TF SRAM get next slice
286  *
287  * Gets the next slice_offset available in the block
288  * and updates the in_use_mask.
289  */
290 static int
291 tf_sram_get_next_slice_in_block(struct tf_sram_block *block,
292                                 enum tf_sram_slice_size slice_size,
293                                 uint16_t *slice_offset,
294                                 bool *block_is_full)
295 {
296         int rc, free_id = -1;
297         uint8_t shift, max_slices, mask, i, full_mask;
298
299         TF_CHECK_PARMS3(block, slice_offset, block_is_full);
300
301         switch (slice_size) {
302         case TF_SRAM_SLICE_SIZE_8B:
303                 shift      = 0;
304                 max_slices = 8;
305                 full_mask  = 0xff;
306                 break;
307         case TF_SRAM_SLICE_SIZE_16B:
308                 shift      = 1;
309                 max_slices = 4;
310                 full_mask  = 0xf;
311                 break;
312         case TF_SRAM_SLICE_SIZE_32B:
313                 shift      = 2;
314                 max_slices = 2;
315                 full_mask  = 0x3;
316                 break;
317         case TF_SRAM_SLICE_SIZE_64B:
318         default:
319                 shift      = 0;
320                 max_slices = 1;
321                 full_mask  = 1;
322                 break;
323         }
324
325         mask = block->in_use_mask;
326
327         for (i = 0; i < max_slices; i++) {
328                 if ((mask & 1) == 0) {
329                         free_id = i;
330                         block->in_use_mask |= 1 << free_id;
331                         break;
332                 }
333                 mask = mask >> 1;
334         }
335
336         if (block->in_use_mask == full_mask)
337                 *block_is_full = true;
338         else
339                 *block_is_full = false;
340
341
342         if (free_id >= 0) {
343                 *slice_offset = free_id << shift;
344                 rc = 0;
345         } else {
346                 *slice_offset = 0;
347                 rc = -ENOMEM;
348         }
349
350         return rc;
351 }
352
353 /**
354  * TF SRAM get indication as to whether the slice offset is
355  * allocated in the block.
356  *
357  */
358 static int
359 tf_sram_is_slice_allocated_in_block(struct tf_sram_block *block,
360                                     enum tf_sram_slice_size slice_size,
361                                     uint16_t slice_offset,
362                                     bool *is_allocated)
363 {
364         int rc = 0;
365         uint8_t shift;
366         uint8_t slice_mask = 0;
367
368         TF_CHECK_PARMS2(block, is_allocated);
369
370         *is_allocated = false;
371
372         switch (slice_size) {
373         case TF_SRAM_SLICE_SIZE_8B:
374                 shift = slice_offset >> 0;
375                 assert(shift < 8);
376                 slice_mask = 1 << shift;
377                 break;
378
379         case TF_SRAM_SLICE_SIZE_16B:
380                 shift = slice_offset >> 1;
381                 assert(shift < 4);
382                 slice_mask = 1 << shift;
383                 break;
384
385         case TF_SRAM_SLICE_SIZE_32B:
386                 shift = slice_offset >> 2;
387                 assert(shift < 2);
388                 slice_mask = 1 << shift;
389                 break;
390
391         case TF_SRAM_SLICE_SIZE_64B:
392         default:
393                 shift = slice_offset >> 0;
394                 assert(shift < 1);
395                 slice_mask = 1 << shift;
396                 break;
397         }
398
399         if ((block->in_use_mask & slice_mask) == 0) {
400                 TFP_DRV_LOG(ERR, "block_id(0x%x) slice(%d) was not allocated\n",
401                             block->block_id, slice_offset);
402                 *is_allocated = false;
403         } else {
404                 *is_allocated = true;
405         }
406
407         return rc;
408 }
409
410 /**
411  * Get the block count
412  */
413 static uint32_t
414 tf_sram_get_block_cnt(struct tf_sram_slice_list *slice_list)
415 {
416         return slice_list->cnt;
417 }
418
419
420 /**
421  * Free a block data structure - does not free to the RM
422  */
423 static void
424 tf_sram_free_block(struct tf_sram_slice_list *slice_list,
425                    struct tf_sram_block *block)
426 {
427         if (slice_list->head == block && slice_list->tail == block) {
428                 slice_list->head = NULL;
429                 slice_list->tail = NULL;
430         } else if (slice_list->head == block) {
431                 slice_list->head = block->next;
432                 slice_list->head->prev = NULL;
433         } else if (slice_list->tail == block) {
434                 slice_list->tail = block->prev;
435                 slice_list->tail->next = NULL;
436         } else {
437                 block->prev->next = block->next;
438                 block->next->prev = block->prev;
439         }
440         tfp_free(block);
441         slice_list->cnt--;
442 }
443 /**
444  * Free the entire slice_list
445  */
446 static void
447 tf_sram_free_slice_list(struct tf_sram_slice_list *slice_list)
448 {
449         uint32_t i, block_cnt;
450         struct tf_sram_block *nblock, *block;
451
452         block_cnt = tf_sram_get_block_cnt(slice_list);
453         block = slice_list->head;
454
455         for (i = 0; i < block_cnt; i++) {
456                 nblock = block->next;
457                 tf_sram_free_block(slice_list, block);
458                 block = nblock;
459         }
460 }
461
462 /**
463  * Allocate a single SRAM block from memory and add it to the slice list
464  */
465 static struct tf_sram_block
466 *tf_sram_alloc_block(struct tf_sram_slice_list *slice_list,
467                      uint16_t block_id)
468 {
469         struct tf_sram_block *block;
470         struct tfp_calloc_parms cparms;
471         int rc;
472
473         cparms.nitems = 1;
474         cparms.size = sizeof(struct tf_sram_block);
475         cparms.alignment = 0;
476         rc = tfp_calloc(&cparms);
477         if (rc) {
478                 /* Log error */
479                 TFP_DRV_LOG(ERR,
480                             "Failed to allocate block, rc:%s\n",
481                             strerror(-rc));
482                 return NULL;
483         }
484         block = (struct tf_sram_block *)cparms.mem_va;
485         block->block_id = block_id;
486
487         if (slice_list->head == NULL) {
488                 slice_list->head = block;
489                 slice_list->tail = block;
490                 block->next = NULL;
491                 block->prev = NULL;
492         } else {
493                 block->next = slice_list->head;
494                 block->prev = NULL;
495                 block->next->prev = block;
496                 slice_list->head = block->next->prev;
497         }
498         slice_list->cnt++;
499         return block;
500 }
501
502 /**
503  * Find the first not full block in the slice list
504  */
505 static void
506 tf_sram_find_first_not_full_block(struct tf_sram_slice_list *slice_list,
507                                   enum tf_sram_slice_size slice_size,
508                                   struct tf_sram_block **first_not_full_block)
509 {
510         struct tf_sram_block *block = slice_list->head;
511         uint8_t slice_mask, mask;
512
513         switch (slice_size) {
514         case TF_SRAM_SLICE_SIZE_8B:
515                 slice_mask = 0xff;
516                 break;
517
518         case TF_SRAM_SLICE_SIZE_16B:
519                 slice_mask = 0xf;
520                 break;
521
522         case TF_SRAM_SLICE_SIZE_32B:
523                 slice_mask = 0x3;
524                 break;
525
526         case TF_SRAM_SLICE_SIZE_64B:
527         default:
528                 slice_mask = 0x1;
529                 break;
530         }
531
532         *first_not_full_block = NULL;
533
534         while (block) {
535                 mask = block->in_use_mask & slice_mask;
536                 if (mask != slice_mask) {
537                         *first_not_full_block = block;
538                         break;
539                 }
540                 block = block->next;
541         }
542 }
543 static void
544 tf_sram_dump_block(struct tf_sram_block *block)
545 {
546         TFP_DRV_LOG(INFO, "block_id(0x%x) in_use_mask(0x%02x)\n",
547                     block->block_id,
548                     block->in_use_mask);
549 }
550
551 /**********************
552  * External functions
553  **********************/
554 int
555 tf_sram_mgr_bind(void **sram_handle)
556 {
557         int rc = 0;
558         struct tf_sram *sram;
559         struct tfp_calloc_parms cparms;
560
561         TF_CHECK_PARMS1(sram_handle);
562
563         cparms.nitems = 1;
564         cparms.size = sizeof(struct tf_sram);
565         cparms.alignment = 0;
566         rc = tfp_calloc(&cparms);
567         if (rc) {
568                 /* Log error */
569                 TFP_DRV_LOG(ERR,
570                             "Failed to allocate SRAM mgmt data, rc:%s\n",
571                             strerror(-rc));
572                 return rc;
573         }
574         sram = (struct tf_sram *)cparms.mem_va;
575         *sram_handle = sram;
576         return rc;
577 }
578
579 int
580 tf_sram_mgr_unbind(void *sram_handle)
581 {
582         int rc = 0;
583         struct tf_sram *sram;
584         enum tf_sram_bank_id bank_id;
585         enum tf_sram_slice_size slice_size;
586         enum tf_dir dir;
587         struct tf_sram_slice_list *slice_list;
588
589         TF_CHECK_PARMS1(sram_handle);
590
591         sram = (struct tf_sram *)sram_handle;
592
593         for (dir = 0; dir < TF_DIR_MAX; dir++) {
594                 /* For each bank
595                  */
596                 for (bank_id = TF_SRAM_BANK_ID_0;
597                      bank_id < TF_SRAM_BANK_ID_MAX;
598                      bank_id++) {
599                         /* For each slice size
600                          */
601                         for (slice_size = TF_SRAM_SLICE_SIZE_8B;
602                              slice_size < TF_SRAM_SLICE_SIZE_MAX;
603                              slice_size++) {
604                                 rc = tf_sram_get_slice_list(sram, &slice_list,
605                                                             slice_size, dir,
606                                                             bank_id);
607                                 if (rc) {
608                                         /* Log error */
609                                         TFP_DRV_LOG(ERR,
610                                                   "No SRAM slice list, rc:%s\n",
611                                                   strerror(-rc));
612                                         return rc;
613                                 }
614                                 if (tf_sram_get_block_cnt(slice_list))
615                                         tf_sram_free_slice_list(slice_list);
616                         }
617                 }
618         }
619
620         tfp_free(sram);
621         sram_handle = NULL;
622
623         /* Freeing of the RM resources is handled by the table manager */
624         return rc;
625 }
626
627 int tf_sram_mgr_alloc(void *sram_handle,
628                       struct tf_sram_mgr_alloc_parms *parms)
629 {
630         int rc = 0;
631         struct tf_sram *sram;
632         struct tf_sram_slice_list *slice_list;
633         uint16_t block_id, slice_offset = 0;
634         uint32_t index;
635         struct tf_sram_block *block;
636         struct tf_rm_allocate_parms aparms = { 0 };
637         bool block_is_full;
638         uint16_t block_offset;
639
640         TF_CHECK_PARMS3(sram_handle, parms, parms->sram_offset);
641
642         sram = (struct tf_sram *)sram_handle;
643
644         /* Check the current slice list
645          */
646         rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size,
647                                     parms->dir, parms->bank_id);
648         if (rc) {
649                 /* Log error */
650                 TFP_DRV_LOG(ERR,
651                             "No SRAM slice list, rc:%s\n",
652                             strerror(-rc));
653                 return rc;
654         }
655
656         /* If the list is empty or all entries are full allocate a new block
657          */
658         if (!slice_list->first_not_full_block) {
659                 /* Allocate and insert a new block
660                  */
661                 aparms.index = &index;
662                 aparms.subtype = parms->tbl_type;
663                 aparms.rm_db = parms->rm_db;
664                 rc = tf_rm_allocate(&aparms);
665                 if (rc)
666                         return rc;
667
668                 block_id = index;
669                 block = tf_sram_alloc_block(slice_list, block_id);
670         } else {
671                 /* Block exists
672                  */
673                 block =
674                  (struct tf_sram_block *)(slice_list->first_not_full_block);
675         }
676         rc = tf_sram_get_next_slice_in_block(block,
677                                              parms->slice_size,
678                                              &slice_offset,
679                                              &block_is_full);
680
681         /* Find the new first non-full block in the list
682          */
683         tf_sram_find_first_not_full_block(slice_list,
684                                           parms->slice_size,
685                                           &slice_list->first_not_full_block);
686
687         tf_sram_block_id_2_offset(parms->bank_id, block->block_id,
688                                   &block_offset);
689
690         *parms->sram_offset = block_offset + slice_offset;
691         return rc;
692 }
693
694 int
695 tf_sram_mgr_free(void *sram_handle,
696                  struct tf_sram_mgr_free_parms *parms)
697 {
698         int rc = 0;
699         struct tf_sram *sram;
700         struct tf_sram_slice_list *slice_list;
701         uint16_t block_id, slice_offset;
702         struct tf_sram_block *block;
703         bool block_is_empty;
704         struct tf_rm_free_parms fparms = { 0 };
705
706         TF_CHECK_PARMS2(sram_handle, parms);
707
708         sram = (struct tf_sram *)sram_handle;
709
710         /* Check the current slice list
711          */
712         rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size,
713                                     parms->dir, parms->bank_id);
714         if (rc) {
715                 /* Log error */
716                 TFP_DRV_LOG(ERR,
717                             "No SRAM slice list, rc:%s\n",
718                             strerror(-rc));
719                 return rc;
720         }
721
722         /* Determine the block id and slice offset from the SRAM offset
723          */
724         tf_sram_offset_2_block_id(parms->bank_id, parms->sram_offset, &block_id,
725                                   &slice_offset);
726
727         /* Search the list of blocks for the matching block id
728          */
729         block = tf_sram_find_block(block_id, slice_list);
730         if (block == NULL) {
731                 TFP_DRV_LOG(ERR, "block not found 0x%x\n", block_id);
732                 return rc;
733         }
734
735         /* If found, search for the matching SRAM slice in use.
736          */
737         rc = tf_sram_free_slice(parms->slice_size, slice_offset,
738                                 block, &block_is_empty);
739         if (rc) {
740                 TFP_DRV_LOG(ERR, "Error freeing slice (%s)\n", strerror(-rc));
741                 return rc;
742         }
743 #if (STATS_CLEAR_ON_READ_SUPPORT == 0)
744         /* If this is a counter, clear it.  In the future we need to switch to
745          * using the special access registers on Thor to automatically clear on
746          * read.
747          */
748         /* If this is counter table, clear the entry on free */
749         if (parms->tbl_type == TF_TBL_TYPE_ACT_STATS_64) {
750                 uint8_t data[8] = { 0 };
751                 uint16_t hcapi_type = 0;
752                 struct tf_rm_get_hcapi_parms hparms = { 0 };
753
754                 /* Get the hcapi type */
755                 hparms.rm_db = parms->rm_db;
756                 hparms.subtype = parms->tbl_type;
757                 hparms.hcapi_type = &hcapi_type;
758                 rc = tf_rm_get_hcapi_type(&hparms);
759                 if (rc) {
760                         TFP_DRV_LOG(ERR,
761                                     "%s, Failed type lookup, type:%s, rc:%s\n",
762                                     tf_dir_2_str(parms->dir),
763                                     tf_tbl_type_2_str(parms->tbl_type),
764                                     strerror(-rc));
765                         return rc;
766                 }
767                 /* Clear the counter
768                  */
769                 rc = tf_msg_set_tbl_entry(parms->tfp,
770                                           parms->dir,
771                                           hcapi_type,
772                                           sizeof(data),
773                                           data,
774                                           parms->sram_offset);
775                 if (rc) {
776                         TFP_DRV_LOG(ERR,
777                                     "%s, Set failed, type:%s, rc:%s\n",
778                                     tf_dir_2_str(parms->dir),
779                                     tf_tbl_type_2_str(parms->tbl_type),
780                                     strerror(-rc));
781                         return rc;
782                 }
783         }
784 #endif
785         /* If the block is empty, free the block to the RM
786          */
787         if (block_is_empty) {
788                 fparms.rm_db = parms->rm_db;
789                 fparms.subtype = parms->tbl_type;
790                 fparms.index = block_id;
791                 rc = tf_rm_free(&fparms);
792
793                 if (rc) {
794                         TFP_DRV_LOG(ERR, "Free block_id(%d) failed error(%s)\n",
795                                     block_id, strerror(-rc));
796                 }
797                 /* Free local entry regardless
798                  */
799                 tf_sram_free_block(slice_list, block);
800
801                 /* Find the next non-full block in the list
802                  */
803                 tf_sram_find_first_not_full_block(slice_list,
804                                              parms->slice_size,
805                                              &slice_list->first_not_full_block);
806         }
807
808         return rc;
809 }
810
811 int
812 tf_sram_mgr_dump(void *sram_handle,
813                  struct tf_sram_mgr_dump_parms *parms)
814 {
815         int rc = 0;
816         struct tf_sram *sram;
817         struct tf_sram_slice_list *slice_list;
818         uint32_t block_cnt, i;
819         struct tf_sram_block *block;
820
821         TF_CHECK_PARMS2(sram_handle, parms);
822
823         sram = (struct tf_sram *)sram_handle;
824
825         rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size,
826                                     parms->dir, parms->bank_id);
827         if (rc)
828                 return rc;
829
830         if (slice_list->cnt || slice_list->first_not_full_block) {
831                 TFP_DRV_LOG(INFO, "\n********** %s: %s: %s ***********\n",
832                             tf_sram_bank_2_str(parms->bank_id),
833                             tf_dir_2_str(parms->dir),
834                             tf_sram_slice_2_str(parms->slice_size));
835
836                 block_cnt = tf_sram_get_block_cnt(slice_list);
837                 TFP_DRV_LOG(INFO, "block_cnt(%d)\n", block_cnt);
838                 if (slice_list->first_not_full_block)
839                         TFP_DRV_LOG(INFO, "first_not_full_block(0x%x)\n",
840                             slice_list->first_not_full_block->block_id);
841                 block = slice_list->head;
842                 for (i = 0; i < block_cnt; i++) {
843                         tf_sram_dump_block(block);
844                         block = tf_sram_get_next_block(block);
845                 }
846                 TFP_DRV_LOG(INFO, "*********************************\n");
847         }
848         return rc;
849 }
850 /**
851  * Validate an SRAM Slice is allocated
852  *
853  * Validate whether the SRAM slice is allocated
854  *
855  * [in] sram_handle
856  *   Pointer to SRAM handle
857  *
858  * [in] parms
859  *   Pointer to the SRAM alloc parameters
860  *
861  * Returns
862  *   - (0) if successful
863  *   - (-EINVAL) on failure
864  *
865  */
866 int tf_sram_mgr_is_allocated(void *sram_handle,
867                              struct tf_sram_mgr_is_allocated_parms *parms)
868 {
869         int rc = 0;
870         struct tf_sram *sram;
871         struct tf_sram_slice_list *slice_list;
872         uint16_t block_id, slice_offset;
873         struct tf_sram_block *block;
874
875         TF_CHECK_PARMS3(sram_handle, parms, parms->is_allocated);
876
877         sram = (struct tf_sram *)sram_handle;
878
879         /* Check the current slice list
880          */
881         rc = tf_sram_get_slice_list(sram, &slice_list, parms->slice_size,
882                                     parms->dir, parms->bank_id);
883         if (rc) {
884                 /* Log error */
885                 TFP_DRV_LOG(ERR,
886                             "No SRAM slice list, rc:%s\n",
887                             strerror(-rc));
888                 return rc;
889         }
890
891         /* If the list is empty, then it cannot be allocated
892          */
893         if (!slice_list->cnt) {
894                 TFP_DRV_LOG(ERR, "List is empty for %s:%s:%s\n",
895                             tf_dir_2_str(parms->dir),
896                             tf_sram_slice_2_str(parms->slice_size),
897                             tf_sram_bank_2_str(parms->bank_id));
898
899                 parms->is_allocated = false;
900                 goto done;
901         }
902
903         /* Determine the block id and slice offset from the SRAM offset
904          */
905         tf_sram_offset_2_block_id(parms->bank_id, parms->sram_offset, &block_id,
906                                   &slice_offset);
907
908         /* Search the list of blocks for the matching block id
909          */
910         block = tf_sram_find_block(block_id, slice_list);
911         if (block == NULL) {
912                 TFP_DRV_LOG(ERR, "block not found in list 0x%x\n",
913                             parms->sram_offset);
914                 parms->is_allocated = false;
915                 goto done;
916         }
917
918         rc = tf_sram_is_slice_allocated_in_block(block,
919                                                  parms->slice_size,
920                                                  slice_offset,
921                                                  parms->is_allocated);
922 done:
923         return rc;
924 }