LCOV - code coverage report
Current view: top level - drivers/net/nfp/nfpcore - nfp_rtsym.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 215 0.0 %
Date: 2024-01-22 15:35:40 Functions: 0 23 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 101 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Netronome Systems, Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : /*
       7                 :            :  * nfp_rtsym.c
       8                 :            :  * Interface for accessing run-time symbol table
       9                 :            :  */
      10                 :            : 
      11                 :            : #include "nfp_rtsym.h"
      12                 :            : 
      13                 :            : #include <rte_byteorder.h>
      14                 :            : 
      15                 :            : #include "nfp_logs.h"
      16                 :            : #include "nfp_mip.h"
      17                 :            : #include "nfp_target.h"
      18                 :            : #include "nfp6000/nfp6000.h"
      19                 :            : 
      20                 :            : enum nfp_rtsym_type {
      21                 :            :         NFP_RTSYM_TYPE_NONE,
      22                 :            :         NFP_RTSYM_TYPE_OBJECT,
      23                 :            :         NFP_RTSYM_TYPE_FUNCTION,
      24                 :            :         NFP_RTSYM_TYPE_ABS,
      25                 :            : };
      26                 :            : 
      27                 :            : #define NFP_RTSYM_TARGET_NONE           0
      28                 :            : #define NFP_RTSYM_TARGET_LMEM           -1
      29                 :            : #define NFP_RTSYM_TARGET_EMU_CACHE      -7
      30                 :            : 
      31                 :            : /* These need to match the linker */
      32                 :            : #define SYM_TGT_LMEM            0
      33                 :            : #define SYM_TGT_EMU_CACHE       0x17
      34                 :            : 
      35                 :            : struct nfp_rtsym_entry {
      36                 :            :         uint8_t type;
      37                 :            :         uint8_t target;
      38                 :            :         uint8_t island;
      39                 :            :         uint8_t addr_hi;
      40                 :            :         uint32_t addr_lo;
      41                 :            :         uint16_t name;
      42                 :            :         uint8_t menum;
      43                 :            :         uint8_t size_hi;
      44                 :            :         uint32_t size_lo;
      45                 :            : };
      46                 :            : 
      47                 :            : /*
      48                 :            :  * Structure describing a run-time NFP symbol.
      49                 :            :  *
      50                 :            :  * The memory target of the symbol is generally the CPP target number and can be
      51                 :            :  * used directly by the nfp_cpp API calls.  However, in some cases (i.e., for
      52                 :            :  * local memory or control store) the target is encoded using a negative number.
      53                 :            :  *
      54                 :            :  * When the target type can not be used to fully describe the location of a
      55                 :            :  * symbol the domain field is used to further specify the location (i.e., the
      56                 :            :  * specific ME or island number).
      57                 :            :  *
      58                 :            :  * For ME target resources, 'domain' is an MEID.
      59                 :            :  * For Island target resources, 'domain' is an island ID, with the one exception
      60                 :            :  * of "sram" symbols for backward compatibility, which are viewed as global.
      61                 :            :  */
      62                 :            : struct nfp_rtsym {
      63                 :            :         const char *name;  /**< Symbol name */
      64                 :            :         uint64_t addr;     /**< Address in the domain/target's address space */
      65                 :            :         uint64_t size;     /**< Size (in bytes) of the symbol */
      66                 :            :         enum nfp_rtsym_type type; /**< NFP_RTSYM_TYPE_* of the symbol */
      67                 :            :         int target;        /**< CPP target identifier, or NFP_RTSYM_TARGET_* */
      68                 :            :         int domain;        /**< CPP target domain */
      69                 :            : };
      70                 :            : 
      71                 :            : struct nfp_rtsym_table {
      72                 :            :         struct nfp_cpp *cpp;
      73                 :            :         int num;
      74                 :            :         char *strtab;
      75                 :            :         struct nfp_rtsym symtab[];
      76                 :            : };
      77                 :            : 
      78                 :            : static int
      79                 :            : nfp_meid(uint8_t island_id,
      80                 :            :                 uint8_t menum)
      81                 :            : {
      82         [ #  # ]:          0 :         return (island_id & 0x3F) == island_id && menum < 12 ?
      83                 :          0 :                 (island_id << 4) | (menum + 4) : -1;
      84                 :            : }
      85                 :            : 
      86                 :            : static void
      87                 :          0 : nfp_rtsym_sw_entry_init(struct nfp_rtsym_table *cache,
      88                 :            :                 uint32_t strtab_size,
      89                 :            :                 struct nfp_rtsym *sw,
      90                 :            :                 struct nfp_rtsym_entry *fw)
      91                 :            : {
      92                 :          0 :         sw->type = fw->type;
      93                 :          0 :         sw->name = cache->strtab + rte_le_to_cpu_16(fw->name) % strtab_size;
      94                 :          0 :         sw->addr = ((uint64_t)fw->addr_hi << 32) |
      95                 :          0 :                         rte_le_to_cpu_32(fw->addr_lo);
      96                 :          0 :         sw->size = ((uint64_t)fw->size_hi << 32) |
      97                 :          0 :                         rte_le_to_cpu_32(fw->size_lo);
      98                 :            : 
      99      [ #  #  # ]:          0 :         switch (fw->target) {
     100                 :          0 :         case SYM_TGT_LMEM:
     101                 :          0 :                 sw->target = NFP_RTSYM_TARGET_LMEM;
     102                 :          0 :                 break;
     103                 :          0 :         case SYM_TGT_EMU_CACHE:
     104                 :          0 :                 sw->target = NFP_RTSYM_TARGET_EMU_CACHE;
     105                 :          0 :                 break;
     106                 :          0 :         default:
     107                 :          0 :                 sw->target = fw->target;
     108                 :          0 :                 break;
     109                 :            :         }
     110                 :            : 
     111         [ #  # ]:          0 :         if (fw->menum != 0xff)
     112         [ #  # ]:          0 :                 sw->domain = nfp_meid(fw->island, fw->menum);
     113         [ #  # ]:          0 :         else if (fw->island != 0xff)
     114                 :          0 :                 sw->domain = fw->island;
     115                 :            :         else
     116                 :          0 :                 sw->domain = -1;
     117                 :          0 : }
     118                 :            : 
     119                 :            : static struct nfp_rtsym_table *
     120                 :          0 : nfp_rtsym_table_read_real(struct nfp_cpp *cpp,
     121                 :            :                 const struct nfp_mip *mip)
     122                 :            : {
     123                 :            :         int n;
     124                 :            :         int err;
     125                 :            :         uint32_t size;
     126                 :            :         uint32_t strtab_addr;
     127                 :            :         uint32_t symtab_addr;
     128                 :            :         uint32_t strtab_size;
     129                 :            :         uint32_t symtab_size;
     130                 :            :         struct nfp_rtsym_table *cache;
     131                 :            :         struct nfp_rtsym_entry *rtsymtab;
     132                 :            :         const uint32_t dram =
     133                 :            :                 NFP_CPP_ID(NFP_CPP_TARGET_MU, NFP_CPP_ACTION_RW, 0) |
     134                 :            :                 NFP_ISL_EMEM0;
     135                 :            : 
     136         [ #  # ]:          0 :         if (mip == NULL)
     137                 :            :                 return NULL;
     138                 :            : 
     139                 :          0 :         nfp_mip_strtab(mip, &strtab_addr, &strtab_size);
     140                 :          0 :         nfp_mip_symtab(mip, &symtab_addr, &symtab_size);
     141                 :            : 
     142   [ #  #  #  #  :          0 :         if (symtab_size == 0 || strtab_size == 0 || symtab_size % sizeof(*rtsymtab) != 0)
                   #  # ]
     143                 :            :                 return NULL;
     144                 :            : 
     145                 :            :         /* Align to 64 bits */
     146                 :          0 :         symtab_size = RTE_ALIGN_CEIL(symtab_size, 8);
     147                 :          0 :         strtab_size = RTE_ALIGN_CEIL(strtab_size, 8);
     148                 :            : 
     149                 :          0 :         rtsymtab = malloc(symtab_size);
     150         [ #  # ]:          0 :         if (rtsymtab == NULL)
     151                 :            :                 return NULL;
     152                 :            : 
     153                 :            :         size = sizeof(*cache);
     154                 :          0 :         size += symtab_size / sizeof(*rtsymtab) * sizeof(struct nfp_rtsym);
     155                 :          0 :         size += strtab_size + 1;
     156                 :          0 :         cache = malloc(size);
     157         [ #  # ]:          0 :         if (cache == NULL)
     158                 :          0 :                 goto exit_free_rtsym_raw;
     159                 :            : 
     160                 :          0 :         cache->cpp = cpp;
     161                 :          0 :         cache->num = symtab_size / sizeof(*rtsymtab);
     162                 :          0 :         cache->strtab = (void *)&cache->symtab[cache->num];
     163                 :            : 
     164                 :          0 :         err = nfp_cpp_read(cpp, dram, symtab_addr, rtsymtab, symtab_size);
     165         [ #  # ]:          0 :         if (err != (int)symtab_size)
     166                 :          0 :                 goto exit_free_cache;
     167                 :            : 
     168                 :          0 :         err = nfp_cpp_read(cpp, dram, strtab_addr, cache->strtab, strtab_size);
     169         [ #  # ]:          0 :         if (err != (int)strtab_size)
     170                 :          0 :                 goto exit_free_cache;
     171                 :          0 :         cache->strtab[strtab_size] = '\0';
     172                 :            : 
     173         [ #  # ]:          0 :         for (n = 0; n < cache->num; n++)
     174                 :          0 :                 nfp_rtsym_sw_entry_init(cache, strtab_size,
     175                 :          0 :                                 &cache->symtab[n], &rtsymtab[n]);
     176                 :            : 
     177                 :          0 :         free(rtsymtab);
     178                 :            : 
     179                 :          0 :         return cache;
     180                 :            : 
     181                 :          0 : exit_free_cache:
     182                 :          0 :         free(cache);
     183                 :          0 : exit_free_rtsym_raw:
     184                 :          0 :         free(rtsymtab);
     185                 :          0 :         return NULL;
     186                 :            : }
     187                 :            : 
     188                 :            : struct nfp_rtsym_table *
     189                 :          0 : nfp_rtsym_table_read(struct nfp_cpp *cpp)
     190                 :            : {
     191                 :            :         struct nfp_mip *mip;
     192                 :            :         struct nfp_rtsym_table *rtbl;
     193                 :            : 
     194                 :          0 :         mip = nfp_mip_open(cpp);
     195                 :          0 :         rtbl = nfp_rtsym_table_read_real(cpp, mip);
     196                 :          0 :         nfp_mip_close(mip);
     197                 :            : 
     198                 :          0 :         return rtbl;
     199                 :            : }
     200                 :            : 
     201                 :            : /**
     202                 :            :  * Get the number of RTSYM descriptors
     203                 :            :  *
     204                 :            :  * @param rtbl
     205                 :            :  *   NFP RTSYM table
     206                 :            :  *
     207                 :            :  * @return
     208                 :            :  *   Number of RTSYM descriptors
     209                 :            :  */
     210                 :            : int
     211                 :          0 : nfp_rtsym_count(struct nfp_rtsym_table *rtbl)
     212                 :            : {
     213         [ #  # ]:          0 :         if (rtbl == NULL)
     214                 :            :                 return -EINVAL;
     215                 :            : 
     216                 :          0 :         return rtbl->num;
     217                 :            : }
     218                 :            : 
     219                 :            : /**
     220                 :            :  * Get the Nth RTSYM descriptor
     221                 :            :  *
     222                 :            :  * @param rtbl
     223                 :            :  *   NFP RTSYM table
     224                 :            :  * @param idx
     225                 :            :  *   Index (0-based) of the RTSYM descriptor
     226                 :            :  *
     227                 :            :  * @return
     228                 :            :  *   Const pointer to a struct nfp_rtsym descriptor, or NULL
     229                 :            :  */
     230                 :            : const struct nfp_rtsym *
     231                 :          0 : nfp_rtsym_get(struct nfp_rtsym_table *rtbl,
     232                 :            :                 int idx)
     233                 :            : {
     234         [ #  # ]:          0 :         if (rtbl == NULL)
     235                 :            :                 return NULL;
     236                 :            : 
     237         [ #  # ]:          0 :         if (idx >= rtbl->num)
     238                 :            :                 return NULL;
     239                 :            : 
     240                 :          0 :         return &rtbl->symtab[idx];
     241                 :            : }
     242                 :            : 
     243                 :            : /**
     244                 :            :  * Return the RTSYM descriptor for a symbol name
     245                 :            :  *
     246                 :            :  * @param rtbl
     247                 :            :  *   NFP RTSYM table
     248                 :            :  * @param name
     249                 :            :  *   Symbol name
     250                 :            :  *
     251                 :            :  * @return
     252                 :            :  *   Const pointer to a struct nfp_rtsym descriptor, or NULL
     253                 :            :  */
     254                 :            : const struct nfp_rtsym *
     255                 :          0 : nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl,
     256                 :            :                 const char *name)
     257                 :            : {
     258                 :            :         int n;
     259                 :            : 
     260         [ #  # ]:          0 :         if (rtbl == NULL)
     261                 :            :                 return NULL;
     262                 :            : 
     263         [ #  # ]:          0 :         for (n = 0; n < rtbl->num; n++)
     264         [ #  # ]:          0 :                 if (strcmp(name, rtbl->symtab[n].name) == 0)
     265                 :          0 :                         return &rtbl->symtab[n];
     266                 :            : 
     267                 :            :         return NULL;
     268                 :            : }
     269                 :            : 
     270                 :            : static uint64_t
     271                 :          0 : nfp_rtsym_size(const struct nfp_rtsym *sym)
     272                 :            : {
     273   [ #  #  #  # ]:          0 :         switch (sym->type) {
     274                 :          0 :         case NFP_RTSYM_TYPE_NONE:
     275                 :          0 :                 PMD_DRV_LOG(ERR, "The type of rtsym '%s' is NONE", sym->name);
     276                 :          0 :                 return 0;
     277                 :          0 :         case NFP_RTSYM_TYPE_OBJECT:
     278                 :            :                 /* FALLTHROUGH */
     279                 :            :         case NFP_RTSYM_TYPE_FUNCTION:
     280                 :          0 :                 return sym->size;
     281                 :            :         case NFP_RTSYM_TYPE_ABS:
     282                 :            :                 return sizeof(uint64_t);
     283                 :          0 :         default:
     284                 :          0 :                 PMD_DRV_LOG(ERR, "Unknown RTSYM type %u", sym->type);
     285                 :          0 :                 return 0;
     286                 :            :         }
     287                 :            : }
     288                 :            : 
     289                 :            : static int
     290                 :          0 : nfp_rtsym_to_dest(struct nfp_cpp *cpp,
     291                 :            :                 const struct nfp_rtsym *sym,
     292                 :            :                 uint8_t action,
     293                 :            :                 uint8_t token,
     294                 :            :                 uint64_t offset,
     295                 :            :                 uint32_t *cpp_id,
     296                 :            :                 uint64_t *addr)
     297                 :            : {
     298         [ #  # ]:          0 :         if (sym->type != NFP_RTSYM_TYPE_OBJECT) {
     299                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s': direct access to non-object rtsym",
     300                 :            :                                 sym->name);
     301                 :          0 :                 return -EINVAL;
     302                 :            :         }
     303                 :            : 
     304                 :          0 :         *addr = sym->addr + offset;
     305                 :            : 
     306         [ #  # ]:          0 :         if (sym->target >= 0) {
     307                 :          0 :                 *cpp_id = NFP_CPP_ISLAND_ID(sym->target, action, token, sym->domain);
     308         [ #  # ]:          0 :         } else if (sym->target == NFP_RTSYM_TARGET_EMU_CACHE) {
     309                 :          0 :                 int locality_off = nfp_cpp_mu_locality_lsb(cpp);
     310                 :            : 
     311                 :          0 :                 *addr &= ~(NFP_MU_ADDR_ACCESS_TYPE_MASK << locality_off);
     312                 :          0 :                 *addr |= NFP_MU_ADDR_ACCESS_TYPE_DIRECT << locality_off;
     313                 :            : 
     314                 :          0 :                 *cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU, action, token,
     315                 :            :                                 sym->domain);
     316                 :            :         } else {
     317                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s': unhandled target encoding: %d",
     318                 :            :                                 sym->name, sym->target);
     319                 :          0 :                 return -EINVAL;
     320                 :            :         }
     321                 :            : 
     322                 :            :         return 0;
     323                 :            : }
     324                 :            : 
     325                 :            : static int
     326                 :          0 : nfp_rtsym_read_real(struct nfp_cpp *cpp,
     327                 :            :                 const struct nfp_rtsym *sym,
     328                 :            :                 uint8_t action,
     329                 :            :                 uint8_t token,
     330                 :            :                 uint64_t offset,
     331                 :            :                 void *buf,
     332                 :            :                 size_t len)
     333                 :            : {
     334                 :            :         int err;
     335                 :            :         uint64_t addr;
     336                 :            :         uint32_t cpp_id;
     337                 :            :         size_t length = len;
     338                 :          0 :         uint64_t sym_size = nfp_rtsym_size(sym);
     339                 :            : 
     340         [ #  # ]:          0 :         if (offset >= sym_size) {
     341                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s' read out of bounds", sym->name);
     342                 :          0 :                 return -ENXIO;
     343                 :            :         }
     344                 :            : 
     345                 :          0 :         if (length > sym_size - offset)
     346                 :            :                 length = sym_size - offset;
     347                 :            : 
     348         [ #  # ]:          0 :         if (sym->type == NFP_RTSYM_TYPE_ABS) {
     349                 :            :                 union {
     350                 :            :                         uint64_t value_64;
     351                 :            :                         uint8_t value_8[8];
     352                 :            :                 } tmp;
     353                 :            : 
     354                 :          0 :                 tmp.value_64 = sym->addr;
     355                 :          0 :                 memcpy(buf, &tmp.value_8[offset], length);
     356                 :            : 
     357                 :          0 :                 return length;
     358                 :            :         }
     359                 :            : 
     360                 :          0 :         err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr);
     361         [ #  # ]:          0 :         if (err != 0)
     362                 :            :                 return err;
     363                 :            : 
     364                 :          0 :         return nfp_cpp_read(cpp, cpp_id, addr, buf, length);
     365                 :            : }
     366                 :            : 
     367                 :            : int
     368                 :          0 : nfp_rtsym_read(struct nfp_cpp *cpp,
     369                 :            :                 const struct nfp_rtsym *sym,
     370                 :            :                 uint64_t offset,
     371                 :            :                 void *buf,
     372                 :            :                 size_t len)
     373                 :            : {
     374                 :          0 :         return nfp_rtsym_read_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, buf, len);
     375                 :            : }
     376                 :            : 
     377                 :            : static int
     378                 :          0 : nfp_rtsym_readl_real(struct nfp_cpp *cpp,
     379                 :            :                 const struct nfp_rtsym *sym,
     380                 :            :                 uint8_t action,
     381                 :            :                 uint8_t token,
     382                 :            :                 uint64_t offset,
     383                 :            :                 uint32_t *value)
     384                 :            : {
     385                 :            :         int ret;
     386                 :            :         uint64_t addr;
     387                 :            :         uint32_t cpp_id;
     388                 :            : 
     389         [ #  # ]:          0 :         if (offset + 4 > nfp_rtsym_size(sym)) {
     390                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s': readl out of bounds", sym->name);
     391                 :          0 :                 return -ENXIO;
     392                 :            :         }
     393                 :            : 
     394                 :          0 :         ret = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr);
     395         [ #  # ]:          0 :         if (ret != 0)
     396                 :            :                 return ret;
     397                 :            : 
     398                 :          0 :         return nfp_cpp_readl(cpp, cpp_id, addr, value);
     399                 :            : }
     400                 :            : 
     401                 :            : int
     402                 :          0 : nfp_rtsym_readl(struct nfp_cpp *cpp,
     403                 :            :                 const struct nfp_rtsym *sym,
     404                 :            :                 uint64_t offset,
     405                 :            :                 uint32_t *value)
     406                 :            : {
     407                 :          0 :         return nfp_rtsym_readl_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value);
     408                 :            : }
     409                 :            : 
     410                 :            : static int
     411                 :          0 : nfp_rtsym_readq_real(struct nfp_cpp *cpp,
     412                 :            :                 const struct nfp_rtsym *sym,
     413                 :            :                 uint8_t action,
     414                 :            :                 uint8_t token,
     415                 :            :                 uint64_t offset,
     416                 :            :                 uint64_t *value)
     417                 :            : {
     418                 :            :         int ret;
     419                 :            :         uint64_t addr;
     420                 :            :         uint32_t cpp_id;
     421                 :            : 
     422         [ #  # ]:          0 :         if (offset + 8 > nfp_rtsym_size(sym)) {
     423                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s': readq out of bounds", sym->name);
     424                 :          0 :                 return -ENXIO;
     425                 :            :         }
     426                 :            : 
     427         [ #  # ]:          0 :         if (sym->type == NFP_RTSYM_TYPE_ABS) {
     428                 :          0 :                 *value = sym->addr;
     429                 :          0 :                 return 0;
     430                 :            :         }
     431                 :            : 
     432                 :          0 :         ret = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr);
     433         [ #  # ]:          0 :         if (ret != 0)
     434                 :            :                 return ret;
     435                 :            : 
     436                 :          0 :         return nfp_cpp_readq(cpp, cpp_id, addr, value);
     437                 :            : }
     438                 :            : 
     439                 :            : int
     440                 :          0 : nfp_rtsym_readq(struct nfp_cpp *cpp,
     441                 :            :                 const struct nfp_rtsym *sym,
     442                 :            :                 uint64_t offset,
     443                 :            :                 uint64_t *value)
     444                 :            : {
     445                 :          0 :         return nfp_rtsym_readq_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value);
     446                 :            : }
     447                 :            : 
     448                 :            : static int
     449                 :          0 : nfp_rtsym_write_real(struct nfp_cpp *cpp,
     450                 :            :                 const struct nfp_rtsym *sym,
     451                 :            :                 uint8_t action,
     452                 :            :                 uint8_t token,
     453                 :            :                 uint64_t offset,
     454                 :            :                 void *buf,
     455                 :            :                 size_t len)
     456                 :            : {
     457                 :            :         int err;
     458                 :            :         uint64_t addr;
     459                 :            :         uint32_t cpp_id;
     460                 :            :         size_t length = len;
     461                 :          0 :         uint64_t sym_size = nfp_rtsym_size(sym);
     462                 :            : 
     463         [ #  # ]:          0 :         if (offset > sym_size) {
     464                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s' write out of bounds", sym->name);
     465                 :          0 :                 return -ENXIO;
     466                 :            :         }
     467                 :            : 
     468                 :          0 :         if (length > sym_size - offset)
     469                 :            :                 length = sym_size - offset;
     470                 :            : 
     471                 :          0 :         err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr);
     472         [ #  # ]:          0 :         if (err != 0)
     473                 :            :                 return err;
     474                 :            : 
     475                 :          0 :         return nfp_cpp_write(cpp, cpp_id, addr, buf, length);
     476                 :            : }
     477                 :            : 
     478                 :            : int
     479                 :          0 : nfp_rtsym_write(struct nfp_cpp *cpp,
     480                 :            :                 const struct nfp_rtsym *sym,
     481                 :            :                 uint64_t offset,
     482                 :            :                 void *buf,
     483                 :            :                 size_t len)
     484                 :            : {
     485                 :          0 :         return nfp_rtsym_write_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, buf, len);
     486                 :            : }
     487                 :            : 
     488                 :            : static int
     489                 :          0 : nfp_rtsym_writel_real(struct nfp_cpp *cpp,
     490                 :            :                 const struct nfp_rtsym *sym,
     491                 :            :                 uint8_t action,
     492                 :            :                 uint8_t token,
     493                 :            :                 uint64_t offset,
     494                 :            :                 uint32_t value)
     495                 :            : {
     496                 :            :         int err;
     497                 :            :         uint64_t addr;
     498                 :            :         uint32_t cpp_id;
     499                 :            : 
     500         [ #  # ]:          0 :         if (offset + 4 > nfp_rtsym_size(sym)) {
     501                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s' write out of bounds", sym->name);
     502                 :          0 :                 return -ENXIO;
     503                 :            :         }
     504                 :            : 
     505                 :          0 :         err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr);
     506         [ #  # ]:          0 :         if (err != 0)
     507                 :            :                 return err;
     508                 :            : 
     509                 :          0 :         return nfp_cpp_writel(cpp, cpp_id, addr, value);
     510                 :            : }
     511                 :            : 
     512                 :            : int
     513                 :          0 : nfp_rtsym_writel(struct nfp_cpp *cpp,
     514                 :            :                 const struct nfp_rtsym *sym,
     515                 :            :                 uint64_t offset,
     516                 :            :                 uint32_t value)
     517                 :            : {
     518                 :          0 :         return nfp_rtsym_writel_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value);
     519                 :            : }
     520                 :            : 
     521                 :            : static int
     522                 :          0 : nfp_rtsym_writeq_real(struct nfp_cpp *cpp,
     523                 :            :                 const struct nfp_rtsym *sym,
     524                 :            :                 uint8_t action,
     525                 :            :                 uint8_t token,
     526                 :            :                 uint64_t offset,
     527                 :            :                 uint64_t value)
     528                 :            : {
     529                 :            :         int err;
     530                 :            :         uint64_t addr;
     531                 :            :         uint32_t cpp_id;
     532                 :            : 
     533         [ #  # ]:          0 :         if (offset + 8 > nfp_rtsym_size(sym)) {
     534                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s' write out of bounds", sym->name);
     535                 :          0 :                 return -ENXIO;
     536                 :            :         }
     537                 :            : 
     538                 :          0 :         err = nfp_rtsym_to_dest(cpp, sym, action, token, offset, &cpp_id, &addr);
     539         [ #  # ]:          0 :         if (err != 0)
     540                 :            :                 return err;
     541                 :            : 
     542                 :          0 :         return nfp_cpp_writeq(cpp, cpp_id, addr, value);
     543                 :            : }
     544                 :            : 
     545                 :            : int
     546                 :          0 : nfp_rtsym_writeq(struct nfp_cpp *cpp,
     547                 :            :                 const struct nfp_rtsym *sym,
     548                 :            :                 uint64_t offset,
     549                 :            :                 uint64_t value)
     550                 :            : {
     551                 :          0 :         return nfp_rtsym_writeq_real(cpp, sym, NFP_CPP_ACTION_RW, 0, offset, value);
     552                 :            : }
     553                 :            : 
     554                 :            : /**
     555                 :            :  * Read a simple unsigned scalar value from symbol
     556                 :            :  *
     557                 :            :  * Lookup a symbol, map, read it and return it's value. Value of the symbol
     558                 :            :  * will be interpreted as a simple little-endian unsigned value. Symbol can
     559                 :            :  * be 4 or 8 bytes in size.
     560                 :            :  *
     561                 :            :  * @param rtbl
     562                 :            :  *   NFP RTSYM table
     563                 :            :  * @param name
     564                 :            :  *   Symbol name
     565                 :            :  * @param error
     566                 :            :  *   Pointer to error code (optional)
     567                 :            :  *
     568                 :            :  * @return
     569                 :            :  *   Value read, on error sets the error and returns ~0ULL.
     570                 :            :  */
     571                 :            : uint64_t
     572                 :          0 : nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl,
     573                 :            :                 const char *name,
     574                 :            :                 int *error)
     575                 :            : {
     576                 :            :         int err;
     577                 :            :         uint64_t val;
     578                 :            :         uint32_t val32;
     579                 :            :         const struct nfp_rtsym *sym;
     580                 :            : 
     581                 :          0 :         sym = nfp_rtsym_lookup(rtbl, name);
     582         [ #  # ]:          0 :         if (sym == NULL) {
     583                 :            :                 err = -ENOENT;
     584                 :          0 :                 goto exit;
     585                 :            :         }
     586                 :            : 
     587      [ #  #  # ]:          0 :         switch (sym->size) {
     588                 :          0 :         case 4:
     589                 :          0 :                 err = nfp_rtsym_readl(rtbl->cpp, sym, 0, &val32);
     590                 :          0 :                 val = val32;
     591                 :          0 :                 break;
     592                 :          0 :         case 8:
     593                 :          0 :                 err = nfp_rtsym_readq(rtbl->cpp, sym, 0, &val);
     594                 :          0 :                 break;
     595                 :          0 :         default:
     596                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s' unsupported size: %#lx",
     597                 :            :                                 name, sym->size);
     598                 :            :                 err = -EINVAL;
     599                 :          0 :                 break;
     600                 :            :         }
     601                 :            : 
     602                 :          0 : exit:
     603         [ #  # ]:          0 :         if (error != NULL)
     604                 :          0 :                 *error = err;
     605                 :            : 
     606         [ #  # ]:          0 :         if (err != 0)
     607                 :            :                 return ~0ULL;
     608                 :            : 
     609                 :          0 :         return val;
     610                 :            : }
     611                 :            : 
     612                 :            : /**
     613                 :            :  * Write an unsigned scalar value to a symbol
     614                 :            :  *
     615                 :            :  * Lookup a symbol and write a value to it. Symbol can be 4 or 8 bytes in size.
     616                 :            :  * If 4 bytes then the lower 32-bits of 'value' are used. Value will be
     617                 :            :  * written as simple little-endian unsigned value.
     618                 :            :  *
     619                 :            :  * @param rtbl
     620                 :            :  *   NFP RTSYM table
     621                 :            :  * @param name
     622                 :            :  *   Symbol name
     623                 :            :  * @param value
     624                 :            :  *   Value to write
     625                 :            :  *
     626                 :            :  * @return
     627                 :            :  *   0 on success or error code.
     628                 :            :  */
     629                 :            : int
     630                 :          0 : nfp_rtsym_write_le(struct nfp_rtsym_table *rtbl,
     631                 :            :                 const char *name,
     632                 :            :                 uint64_t value)
     633                 :            : {
     634                 :            :         int err;
     635                 :            :         uint64_t sym_size;
     636                 :            :         const struct nfp_rtsym *sym;
     637                 :            : 
     638                 :          0 :         sym = nfp_rtsym_lookup(rtbl, name);
     639         [ #  # ]:          0 :         if (sym == NULL)
     640                 :            :                 return -ENOENT;
     641                 :            : 
     642                 :          0 :         sym_size = nfp_rtsym_size(sym);
     643      [ #  #  # ]:          0 :         switch (sym_size) {
     644                 :          0 :         case 4:
     645                 :          0 :                 err = nfp_rtsym_writel(rtbl->cpp, sym, 0, value);
     646                 :          0 :                 break;
     647                 :          0 :         case 8:
     648                 :          0 :                 err = nfp_rtsym_writeq(rtbl->cpp, sym, 0, value);
     649                 :          0 :                 break;
     650                 :          0 :         default:
     651                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s' unsupported size: %#lx",
     652                 :            :                                 name, sym_size);
     653                 :            :                 err = -EINVAL;
     654                 :          0 :                 break;
     655                 :            :         }
     656                 :            : 
     657                 :            :         return err;
     658                 :            : }
     659                 :            : 
     660                 :            : uint8_t *
     661                 :          0 : nfp_rtsym_map(struct nfp_rtsym_table *rtbl,
     662                 :            :                 const char *name,
     663                 :            :                 uint32_t min_size,
     664                 :            :                 struct nfp_cpp_area **area)
     665                 :            : {
     666                 :            :         int ret;
     667                 :            :         uint8_t *mem;
     668                 :            :         uint64_t addr;
     669                 :            :         uint32_t cpp_id;
     670                 :            :         const struct nfp_rtsym *sym;
     671                 :            : 
     672                 :          0 :         sym = nfp_rtsym_lookup(rtbl, name);
     673         [ #  # ]:          0 :         if (sym == NULL) {
     674                 :          0 :                 PMD_DRV_LOG(ERR, "Symbol lookup fails for %s", name);
     675                 :          0 :                 return NULL;
     676                 :            :         }
     677                 :            : 
     678                 :          0 :         ret = nfp_rtsym_to_dest(rtbl->cpp, sym, NFP_CPP_ACTION_RW, 0, 0,
     679                 :            :                         &cpp_id, &addr);
     680         [ #  # ]:          0 :         if (ret != 0) {
     681                 :          0 :                 PMD_DRV_LOG(ERR, "rtsym '%s': mapping failed", name);
     682                 :          0 :                 return NULL;
     683                 :            :         }
     684                 :            : 
     685         [ #  # ]:          0 :         if (sym->size < min_size) {
     686                 :          0 :                 PMD_DRV_LOG(ERR, "Symbol %s too small (%" PRIu64 " < %u)", name,
     687                 :            :                                 sym->size, min_size);
     688                 :          0 :                 return NULL;
     689                 :            :         }
     690                 :            : 
     691                 :          0 :         mem = nfp_cpp_map_area(rtbl->cpp, cpp_id, addr, sym->size, area);
     692         [ #  # ]:          0 :         if (mem == NULL) {
     693                 :          0 :                 PMD_DRV_LOG(ERR, "Failed to map symbol %s", name);
     694                 :          0 :                 return NULL;
     695                 :            :         }
     696                 :            : 
     697                 :            :         return mem;
     698                 :            : }

Generated by: LCOV version 1.14