|
Packit |
534379 |
// Copyright(c) 2017-2020, Intel Corporation
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
534379 |
// modification, are permitted provided that the following conditions are met:
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer.
|
|
Packit |
534379 |
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
534379 |
// this list of conditions and the following disclaimer in the documentation
|
|
Packit |
534379 |
// and/or other materials provided with the distribution.
|
|
Packit |
534379 |
// * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
534379 |
// may be used to endorse or promote products derived from this software
|
|
Packit |
534379 |
// without specific prior written permission.
|
|
Packit |
534379 |
//
|
|
Packit |
534379 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
534379 |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
534379 |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
534379 |
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
534379 |
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
534379 |
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
534379 |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
534379 |
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
534379 |
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
534379 |
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
534379 |
// POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
534379 |
#include <config.h>
|
|
Packit |
534379 |
#endif // HAVE_CONFIG_H
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include <string.h>
|
|
Packit |
534379 |
#include <uuid/uuid.h>
|
|
Packit |
534379 |
#include <json-c/json.h>
|
|
Packit |
534379 |
#include <sys/types.h>
|
|
Packit |
534379 |
#include <sys/stat.h>
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include "opae/utils.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#include "common_int.h"
|
|
Packit |
534379 |
#include "bitstream_int.h"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
#define METADATA_GUID "58656F6E-4650-4741-B747-425376303031"
|
|
Packit |
534379 |
#define METADATA_GUID_LEN 16
|
|
Packit |
534379 |
#define METADATA_MAX_LEN 8192
|
|
Packit |
534379 |
#define FPGA_GBS_6_3_0_MAGIC 0x1d1f8680 // dec: 488605312
|
|
Packit |
534379 |
#define PR_INTERFACE_ID "pr/interface_id"
|
|
Packit |
534379 |
#define INTFC_ID_LOW_LEN 16
|
|
Packit |
534379 |
#define INTFC_ID_HIGH_LEN 16
|
|
Packit |
534379 |
#define BUFFER_SIZE 32
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// GBS json metadata
|
|
Packit |
534379 |
// GBS version
|
|
Packit |
534379 |
#define GBS_VERSION "version"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU image
|
|
Packit |
534379 |
#define GBS_AFU_IMAGE "afu-image"
|
|
Packit |
534379 |
#define GBS_MAGIC_NUM "magic-no"
|
|
Packit |
534379 |
#define BBS_INTERFACE_ID "interface-uuid"
|
|
Packit |
534379 |
#define GBS_CLOCK_FREQUENCY_HIGH "clock-frequency-high"
|
|
Packit |
534379 |
#define GBS_CLOCK_FREQUENCY_LOW "clock-frequency-low"
|
|
Packit |
534379 |
#define GBS_AFU_POWER "power"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU Clusters
|
|
Packit |
534379 |
#define GBS_ACCELERATOR_CLUSTERS "accelerator-clusters"
|
|
Packit |
534379 |
#define GBS_AFU_NAME "name"
|
|
Packit |
534379 |
#define GBS_ACCELERATOR_TYPE_UUID "accelerator-type-uuid"
|
|
Packit |
534379 |
#define GBS_ACCELERATOR_TOTAL_CONTEXTS "total-contexts"
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result string_to_guid(const char *guid, fpga_guid *result)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
if (uuid_parse(guid, *result) < 0) {
|
|
Packit |
534379 |
OPAE_MSG("Error parsing GUID %s\n", guid);
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC json_bool get_json_object(json_object **object, json_object **parent,
|
|
Packit |
534379 |
char *field_name)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
return json_object_object_get_ex(*parent, field_name, &(*object));
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC uint64_t read_int_from_bitstream(const uint8_t *bitstream, uint8_t size)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint64_t ret = 0;
|
|
Packit |
534379 |
switch (size) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
case sizeof(uint8_t):
|
|
Packit |
534379 |
ret = *((uint8_t *) bitstream);
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case sizeof(uint16_t):
|
|
Packit |
534379 |
ret = *((uint16_t *) bitstream);
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case sizeof(uint32_t):
|
|
Packit |
534379 |
ret = *((uint32_t *) bitstream);
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
case sizeof(uint64_t):
|
|
Packit |
534379 |
ret = *((uint64_t *) bitstream);
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
default:
|
|
Packit |
534379 |
OPAE_ERR("Unknown integer size");
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return ret;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
STATIC int64_t int64_be_to_le(int64_t val)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
val = ((val << 8) & 0xFF00FF00FF00FF00ULL) |
|
|
Packit |
534379 |
((val >> 8) & 0x00FF00FF00FF00FFULL);
|
|
Packit |
534379 |
val = ((val << 16) & 0xFFFF0000FFFF0000ULL) |
|
|
Packit |
534379 |
((val >> 16) & 0x0000FFFF0000FFFFULL);
|
|
Packit |
534379 |
return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result get_interface_id(fpga_handle handle, uint64_t *id_l, uint64_t *id_h)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
|
|
Packit |
534379 |
struct _fpga_token *_token;
|
|
Packit |
534379 |
struct _fpga_handle *_handle = (struct _fpga_handle *)handle;
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
fpga_guid guid;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
_token = (struct _fpga_token *)_handle->token;
|
|
Packit |
534379 |
if (!_token) {
|
|
Packit |
534379 |
OPAE_MSG("Token is NULL");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (_token->magic != FPGA_TOKEN_MAGIC) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid token in handle");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (id_l == NULL || id_h == NULL) {
|
|
Packit |
534379 |
OPAE_MSG("id_l or id_h are NULL");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// PR Interface id
|
|
Packit |
534379 |
result = sysfs_get_interface_id(_token, guid);
|
|
Packit |
534379 |
if (FPGA_OK != result) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to get PR interface id");
|
|
Packit |
534379 |
return FPGA_EXCEPTION;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(id_h, guid, sizeof(uint64_t));
|
|
Packit |
534379 |
*id_h = int64_be_to_le(*id_h);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(id_l, guid + sizeof(uint64_t), sizeof(uint64_t));
|
|
Packit |
534379 |
*id_l = int64_be_to_le(*id_l);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result check_interface_id(fpga_handle handle,
|
|
Packit |
534379 |
uint32_t bitstream_magic_no,
|
|
Packit |
534379 |
uint64_t ifid_l, uint64_t ifid_h)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint64_t intfc_id_l = 0;
|
|
Packit |
534379 |
uint64_t intfc_id_h = 0;
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (bitstream_magic_no != FPGA_GBS_6_3_0_MAGIC) {
|
|
Packit |
534379 |
OPAE_MSG("Invalid bitstream magic number");
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (get_interface_id(handle, &intfc_id_l, &intfc_id_h)) {
|
|
Packit |
534379 |
OPAE_MSG("Get interface ID failed");
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if ((ifid_l != intfc_id_l) ||
|
|
Packit |
534379 |
(ifid_h != intfc_id_h)) {
|
|
Packit |
534379 |
OPAE_MSG("Interface id doesn't match metadata");
|
|
Packit |
534379 |
return FPGA_NOT_FOUND;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result check_bitstream_guid(const uint8_t *bitstream)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_guid bitstream_guid;
|
|
Packit |
534379 |
fpga_guid expected_guid;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(bitstream_guid, bitstream, sizeof(fpga_guid));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (string_to_guid(METADATA_GUID, &expected_guid) != FPGA_OK)
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (uuid_compare(bitstream_guid, expected_guid) != 0)
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return FPGA_OK;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int get_bitstream_header_len(const uint8_t *bitstream)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint32_t json_len = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!bitstream) {
|
|
Packit |
534379 |
OPAE_ERR("NULL input bitstream pointer");
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (check_bitstream_guid(bitstream) != FPGA_OK)
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_len = read_int_from_bitstream(bitstream + METADATA_GUID_LEN, sizeof(uint32_t));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return (METADATA_GUID_LEN + sizeof(uint32_t) + json_len);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
int32_t get_bitstream_json_len(const uint8_t *bitstream)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint32_t json_len = 0;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (!bitstream) {
|
|
Packit |
534379 |
OPAE_ERR("NULL input bitstream pointer");
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (check_bitstream_guid(bitstream) != FPGA_OK)
|
|
Packit |
534379 |
return -1;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_len = read_int_from_bitstream(bitstream + METADATA_GUID_LEN, sizeof(uint32_t));
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return json_len;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result validate_bitstream_metadata(fpga_handle handle,
|
|
Packit |
534379 |
const uint8_t *bitstream)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_result result = FPGA_EXCEPTION;
|
|
Packit |
534379 |
char *json_metadata = NULL;
|
|
Packit |
534379 |
uint32_t json_len = 0;
|
|
Packit |
534379 |
uint32_t bitstream_magic_no = 0;
|
|
Packit |
534379 |
uint64_t ifc_id_val_l, ifc_id_val_h;
|
|
Packit |
534379 |
const uint8_t *json_metadata_ptr = NULL;
|
|
Packit |
534379 |
json_object *root = NULL;
|
|
Packit |
534379 |
json_object *afu_image = NULL, *magic_no = NULL;
|
|
Packit |
534379 |
json_object *interface_id = NULL;
|
|
Packit |
534379 |
fpga_guid expected_guid;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (check_bitstream_guid(bitstream) != FPGA_OK)
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_len = read_int_from_bitstream(bitstream + METADATA_GUID_LEN, sizeof(uint32_t));
|
|
Packit |
534379 |
if (json_len == 0) {
|
|
Packit |
534379 |
OPAE_MSG("Bitstream has no metadata");
|
|
Packit |
534379 |
result = FPGA_OK;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (json_len >= METADATA_MAX_LEN) {
|
|
Packit |
534379 |
OPAE_ERR("Bitstream metadata too large");
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_metadata_ptr = bitstream + METADATA_GUID_LEN + sizeof(uint32_t);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_metadata = (char *) malloc(json_len + 1);
|
|
Packit |
534379 |
if (json_metadata == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Could not allocate memory for metadata");
|
|
Packit |
534379 |
return FPGA_NO_MEMORY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(json_metadata, json_metadata_ptr, json_len);
|
|
Packit |
534379 |
json_metadata[json_len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
root = json_tokener_parse(json_metadata);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (root != NULL) {
|
|
Packit |
534379 |
if (get_json_object(&afu_image, &root, GBS_AFU_IMAGE)) {
|
|
Packit |
534379 |
get_json_object(&magic_no, &afu_image, GBS_MAGIC_NUM);
|
|
Packit |
534379 |
get_json_object(&interface_id, &afu_image,
|
|
Packit |
534379 |
BBS_INTERFACE_ID);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (magic_no == NULL || interface_id == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = string_to_guid(
|
|
Packit |
534379 |
json_object_get_string(interface_id),
|
|
Packit |
534379 |
&expected_guid);
|
|
Packit |
534379 |
if (result != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid BBS interface ID");
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(&ifc_id_val_h, expected_guid, sizeof(uint64_t));
|
|
Packit |
534379 |
ifc_id_val_h = int64_be_to_le(ifc_id_val_h);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(&ifc_id_val_l,
|
|
Packit |
534379 |
expected_guid + sizeof(uint64_t),
|
|
Packit |
534379 |
sizeof(uint64_t));
|
|
Packit |
534379 |
ifc_id_val_l = int64_be_to_le(ifc_id_val_l);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
bitstream_magic_no = json_object_get_int(magic_no);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
result = check_interface_id(handle, bitstream_magic_no,
|
|
Packit |
534379 |
ifc_id_val_l, ifc_id_val_h);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (result != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_ERR("Interface ID check failed");
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("Invalid metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
if (root)
|
|
Packit |
534379 |
json_object_put(root);
|
|
Packit |
534379 |
if (json_metadata)
|
|
Packit |
534379 |
free(json_metadata);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
fpga_result read_gbs_metadata(const uint8_t *bitstream,
|
|
Packit |
534379 |
struct gbs_metadata *gbs_metadata)
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
uint32_t json_len = 0;
|
|
Packit |
534379 |
fpga_result result = FPGA_OK;
|
|
Packit |
534379 |
const uint8_t *json_metadata_ptr = NULL;
|
|
Packit |
534379 |
char *json_metadata = NULL;
|
|
Packit |
534379 |
json_object *root = NULL;
|
|
Packit |
534379 |
json_object *magic_num = NULL;
|
|
Packit |
534379 |
json_object *interface_id = NULL;
|
|
Packit |
534379 |
json_object *afu_image = NULL;
|
|
Packit |
534379 |
json_object *version = NULL;
|
|
Packit |
534379 |
json_object *accelerator_clusters = NULL;
|
|
Packit |
534379 |
json_object *cluster = NULL;
|
|
Packit |
534379 |
json_object *uuid = NULL;
|
|
Packit |
534379 |
json_object *name = NULL;
|
|
Packit |
534379 |
json_object *contexts = NULL;
|
|
Packit |
534379 |
json_object *power = NULL;
|
|
Packit |
534379 |
json_object *userclk1 = NULL;
|
|
Packit |
534379 |
json_object *userclk2 = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (gbs_metadata == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input metadata");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (bitstream == NULL) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid input bitstream");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (check_bitstream_guid(bitstream) != FPGA_OK) {
|
|
Packit |
534379 |
OPAE_ERR("Failed to read GUID");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_len = *((uint32_t *) (bitstream + METADATA_GUID_LEN));
|
|
Packit |
534379 |
if (!json_len || json_len >= METADATA_MAX_LEN) {
|
|
Packit |
534379 |
OPAE_ERR("Invalid bitstream metadata size");
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_metadata_ptr = bitstream + METADATA_GUID_LEN + sizeof(uint32_t);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
json_metadata = (char *) malloc(json_len + 1);
|
|
Packit |
534379 |
if (!json_metadata) {
|
|
Packit |
534379 |
OPAE_ERR("Could not allocate memory for metadata");
|
|
Packit |
534379 |
return FPGA_NO_MEMORY;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
memcpy(json_metadata, json_metadata_ptr, json_len);
|
|
Packit |
534379 |
json_metadata[json_len] = '\0';
|
|
Packit |
534379 |
|
|
Packit |
534379 |
root = json_tokener_parse(json_metadata);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (root) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// GBS version
|
|
Packit |
534379 |
if (get_json_object(&version, &root, GBS_VERSION)) {
|
|
Packit |
534379 |
gbs_metadata->version = json_object_get_double(version);
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("No GBS version");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// afu-image
|
|
Packit |
534379 |
if (get_json_object(&afu_image, &root, GBS_AFU_IMAGE)) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// magic number
|
|
Packit |
534379 |
if (get_json_object(&magic_num, &afu_image, GBS_MAGIC_NUM)) {
|
|
Packit |
534379 |
gbs_metadata->afu_image.magic_num = json_object_get_int64(magic_num);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// Interface type GUID
|
|
Packit |
534379 |
if (get_json_object(&interface_id, &afu_image, BBS_INTERFACE_ID)) {
|
|
Packit |
534379 |
memcpy(gbs_metadata->afu_image.interface_uuid,
|
|
Packit |
534379 |
json_object_get_string(interface_id),
|
|
Packit |
534379 |
GUID_LEN);
|
|
Packit |
534379 |
gbs_metadata->afu_image.interface_uuid[GUID_LEN] = '\0';
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("No interface ID found in JSON metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU user clock frequency High
|
|
Packit |
534379 |
if (get_json_object(&userclk1, &afu_image, GBS_CLOCK_FREQUENCY_HIGH)) {
|
|
Packit |
534379 |
gbs_metadata->afu_image.clock_frequency_high = json_object_get_int64(userclk1);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU user clock frequency Low
|
|
Packit |
534379 |
if (get_json_object(&userclk2, &afu_image, GBS_CLOCK_FREQUENCY_LOW)) {
|
|
Packit |
534379 |
gbs_metadata->afu_image.clock_frequency_low = json_object_get_int64(userclk2);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// GBS power
|
|
Packit |
534379 |
if (get_json_object(&power, &afu_image, GBS_AFU_POWER)) {
|
|
Packit |
534379 |
gbs_metadata->afu_image.power = json_object_get_int64(power);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("No AFU image in metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// afu clusters
|
|
Packit |
534379 |
if (get_json_object(&afu_image, &root, GBS_AFU_IMAGE) &&
|
|
Packit |
534379 |
get_json_object(&accelerator_clusters, &afu_image, GBS_ACCELERATOR_CLUSTERS)) {
|
|
Packit |
534379 |
|
|
Packit |
534379 |
cluster = json_object_array_get_idx(accelerator_clusters, 0);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU GUID
|
|
Packit |
534379 |
if (get_json_object(&uuid, &cluster, GBS_ACCELERATOR_TYPE_UUID)) {
|
|
Packit |
534379 |
memcpy(gbs_metadata->afu_image.afu_clusters.afu_uuid,
|
|
Packit |
534379 |
json_object_get_string(uuid),
|
|
Packit |
534379 |
GUID_LEN);
|
|
Packit |
534379 |
gbs_metadata->afu_image.afu_clusters.afu_uuid[GUID_LEN] = '\0';
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("No accelerator-type-uuid in JSON metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU Name
|
|
Packit |
534379 |
if (get_json_object(&name, &cluster, GBS_AFU_NAME)) {
|
|
Packit |
534379 |
memcpy(gbs_metadata->afu_image.afu_clusters.name,
|
|
Packit |
534379 |
json_object_get_string(name),
|
|
Packit |
534379 |
json_object_get_string_len(name));
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
// AFU Total number of contexts
|
|
Packit |
534379 |
if (get_json_object(&contexts, &cluster, GBS_ACCELERATOR_TOTAL_CONTEXTS)) {
|
|
Packit |
534379 |
gbs_metadata->afu_image.afu_clusters.total_contexts = json_object_get_int64(contexts);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("No accelerator clusters in metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
} else {
|
|
Packit |
534379 |
OPAE_ERR("Invalid JSON in metadata");
|
|
Packit |
534379 |
result = FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
goto out_free;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_free:
|
|
Packit |
534379 |
if (root)
|
|
Packit |
534379 |
json_object_put(root);
|
|
Packit |
534379 |
if (json_metadata)
|
|
Packit |
534379 |
free(json_metadata);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
return result;
|
|
Packit |
534379 |
}
|