LCOV - code coverage report
Current view: top level - drivers/net/bnxt/tf_core - tf_sram_mgr.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 283 0.0 %
Date: 2024-01-22 16:26:08 Functions: 0 14 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 163 0.0 %

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

Generated by: LCOV version 1.14