dpdk/drivers/net/nfp/nfpcore/nfp_mip.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2018 Netronome Systems, Inc.
   3 * All rights reserved.
   4 */
   5
   6#include <stdio.h>
   7#include <rte_byteorder.h>
   8
   9#include "nfp_cpp.h"
  10#include "nfp_mip.h"
  11#include "nfp_nffw.h"
  12
  13#define NFP_MIP_SIGNATURE       rte_cpu_to_le_32(0x0050494d)  /* "MIP\0" */
  14#define NFP_MIP_VERSION         rte_cpu_to_le_32(1)
  15#define NFP_MIP_MAX_OFFSET      (256 * 1024)
  16
  17struct nfp_mip {
  18        uint32_t signature;
  19        uint32_t mip_version;
  20        uint32_t mip_size;
  21        uint32_t first_entry;
  22
  23        uint32_t version;
  24        uint32_t buildnum;
  25        uint32_t buildtime;
  26        uint32_t loadtime;
  27
  28        uint32_t symtab_addr;
  29        uint32_t symtab_size;
  30        uint32_t strtab_addr;
  31        uint32_t strtab_size;
  32
  33        char name[16];
  34        char toolchain[32];
  35};
  36
  37/* Read memory and check if it could be a valid MIP */
  38static int
  39nfp_mip_try_read(struct nfp_cpp *cpp, uint32_t cpp_id, uint64_t addr,
  40                 struct nfp_mip *mip)
  41{
  42        int ret;
  43
  44        ret = nfp_cpp_read(cpp, cpp_id, addr, mip, sizeof(*mip));
  45        if (ret != sizeof(*mip)) {
  46                printf("Failed to read MIP data (%d, %zu)\n",
  47                        ret, sizeof(*mip));
  48                return -EIO;
  49        }
  50        if (mip->signature != NFP_MIP_SIGNATURE) {
  51                printf("Incorrect MIP signature (0x%08x)\n",
  52                         rte_le_to_cpu_32(mip->signature));
  53                return -EINVAL;
  54        }
  55        if (mip->mip_version != NFP_MIP_VERSION) {
  56                printf("Unsupported MIP version (%d)\n",
  57                         rte_le_to_cpu_32(mip->mip_version));
  58                return -EINVAL;
  59        }
  60
  61        return 0;
  62}
  63
  64/* Try to locate MIP using the resource table */
  65static int
  66nfp_mip_read_resource(struct nfp_cpp *cpp, struct nfp_mip *mip)
  67{
  68        struct nfp_nffw_info *nffw_info;
  69        uint32_t cpp_id;
  70        uint64_t addr;
  71        int err;
  72
  73        nffw_info = nfp_nffw_info_open(cpp);
  74        if (!nffw_info)
  75                return -ENODEV;
  76
  77        err = nfp_nffw_info_mip_first(nffw_info, &cpp_id, &addr);
  78        if (err)
  79                goto exit_close_nffw;
  80
  81        err = nfp_mip_try_read(cpp, cpp_id, addr, mip);
  82exit_close_nffw:
  83        nfp_nffw_info_close(nffw_info);
  84        return err;
  85}
  86
  87/*
  88 * nfp_mip_open() - Get device MIP structure
  89 * @cpp:        NFP CPP Handle
  90 *
  91 * Copy MIP structure from NFP device and return it.  The returned
  92 * structure is handled internally by the library and should be
  93 * freed by calling nfp_mip_close().
  94 *
  95 * Return: pointer to mip, NULL on failure.
  96 */
  97struct nfp_mip *
  98nfp_mip_open(struct nfp_cpp *cpp)
  99{
 100        struct nfp_mip *mip;
 101        int err;
 102
 103        mip = malloc(sizeof(*mip));
 104        if (!mip)
 105                return NULL;
 106
 107        err = nfp_mip_read_resource(cpp, mip);
 108        if (err) {
 109                free(mip);
 110                return NULL;
 111        }
 112
 113        mip->name[sizeof(mip->name) - 1] = 0;
 114
 115        return mip;
 116}
 117
 118void
 119nfp_mip_close(struct nfp_mip *mip)
 120{
 121        free(mip);
 122}
 123
 124const char *
 125nfp_mip_name(const struct nfp_mip *mip)
 126{
 127        return mip->name;
 128}
 129
 130/*
 131 * nfp_mip_symtab() - Get the address and size of the MIP symbol table
 132 * @mip:        MIP handle
 133 * @addr:       Location for NFP DDR address of MIP symbol table
 134 * @size:       Location for size of MIP symbol table
 135 */
 136void
 137nfp_mip_symtab(const struct nfp_mip *mip, uint32_t *addr, uint32_t *size)
 138{
 139        *addr = rte_le_to_cpu_32(mip->symtab_addr);
 140        *size = rte_le_to_cpu_32(mip->symtab_size);
 141}
 142
 143/*
 144 * nfp_mip_strtab() - Get the address and size of the MIP symbol name table
 145 * @mip:        MIP handle
 146 * @addr:       Location for NFP DDR address of MIP symbol name table
 147 * @size:       Location for size of MIP symbol name table
 148 */
 149void
 150nfp_mip_strtab(const struct nfp_mip *mip, uint32_t *addr, uint32_t *size)
 151{
 152        *addr = rte_le_to_cpu_32(mip->strtab_addr);
 153        *size = rte_le_to_cpu_32(mip->strtab_size);
 154}
 155