1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Netronome Systems, Inc.
6 /* Parse the hwinfo table that the ARM firmware builds in the ARM scratch SRAM
9 * Examples of the fields:
11 * me.mask = 0x7f_ffff_ffff
13 * me.count is the total number of MEs on the system.
14 * me.mask is the bitmask of MEs that are available for application usage.
16 * (ie, in this example, ME 39 has been reserved by boardconfig.)
23 #include "nfp6000/nfp6000.h"
24 #include "nfp_resource.h"
25 #include "nfp_hwinfo.h"
29 nfp_hwinfo_is_updating(struct nfp_hwinfo *hwinfo)
31 return hwinfo->version & NFP_HWINFO_VERSION_UPDATING;
35 nfp_hwinfo_db_walk(struct nfp_hwinfo *hwinfo, uint32_t size)
37 const char *key, *val, *end = hwinfo->data + size;
39 for (key = hwinfo->data; *key && key < end;
40 key = val + strlen(val) + 1) {
41 val = key + strlen(key) + 1;
43 printf("Bad HWINFO - overflowing key\n");
47 if (val + strlen(val) + 1 > end) {
48 printf("Bad HWINFO - overflowing value\n");
56 nfp_hwinfo_db_validate(struct nfp_hwinfo *db, uint32_t len)
58 uint32_t size, new_crc, *crc;
62 printf("Unsupported hwinfo size %u > %u\n", size, len);
66 size -= sizeof(uint32_t);
67 new_crc = nfp_crc32_posix((char *)db, size);
68 crc = (uint32_t *)(db->start + size);
69 if (new_crc != *crc) {
70 printf("Corrupt hwinfo table (CRC mismatch)\n");
71 printf("\tcalculated 0x%x, expected 0x%x\n", new_crc, *crc);
75 return nfp_hwinfo_db_walk(db, size);
78 static struct nfp_hwinfo *
79 nfp_hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size)
81 struct nfp_hwinfo *header;
88 res = nfp_resource_acquire(cpp, NFP_RESOURCE_NFP_HWINFO);
90 cpp_id = nfp_resource_cpp_id(res);
91 cpp_addr = nfp_resource_address(res);
92 *cpp_size = nfp_resource_size(res);
94 nfp_resource_release(res);
96 if (*cpp_size < HWINFO_SIZE_MIN)
102 db = malloc(*cpp_size + 1);
106 err = nfp_cpp_read(cpp, cpp_id, cpp_addr, db, *cpp_size);
107 if (err != (int)*cpp_size)
111 printf("NFP HWINFO header: %08x\n", *(uint32_t *)header);
112 if (nfp_hwinfo_is_updating(header))
115 if (header->version != NFP_HWINFO_VERSION_2) {
116 printf("Unknown HWInfo version: 0x%08x\n",
121 /* NULL-terminate for safety */
122 db[*cpp_size] = '\0';
130 static struct nfp_hwinfo *
131 nfp_hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size)
133 struct timespec wait;
134 struct nfp_hwinfo *db;
138 wait.tv_nsec = 10000000;
142 db = nfp_hwinfo_try_fetch(cpp, hwdb_size);
146 nanosleep(&wait, NULL);
148 printf("NFP access error\n");
155 nfp_hwinfo_read(struct nfp_cpp *cpp)
157 struct nfp_hwinfo *db;
158 size_t hwdb_size = 0;
161 db = nfp_hwinfo_fetch(cpp, &hwdb_size);
165 err = nfp_hwinfo_db_validate(db, hwdb_size);
174 * nfp_hwinfo_lookup() - Find a value in the HWInfo table by name
175 * @hwinfo: NFP HWinfo table
176 * @lookup: HWInfo name to search for
178 * Return: Value of the HWInfo name, or NULL
181 nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup)
183 const char *key, *val, *end;
185 if (!hwinfo || !lookup)
188 end = hwinfo->data + hwinfo->size - sizeof(uint32_t);
190 for (key = hwinfo->data; *key && key < end;
191 key = val + strlen(val) + 1) {
192 val = key + strlen(key) + 1;
194 if (strcmp(key, lookup) == 0)