Blame opae-libs/plugins/xfpga/metrics/afu_metrics.c

Packit 534379
// Copyright(c) 2018-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
/**
Packit 534379
* \file afu_metrics.c
Packit 534379
* \brief Enumerates AFU Metrics BBB & retrives afu metrics values
Packit 534379
*/
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 <sys/types.h>
Packit 534379
#include <sys/stat.h>
Packit 534379
#include <fcntl.h>
Packit 534379
#include <dirent.h>
Packit 534379
#include <uuid/uuid.h>
Packit 534379
Packit 534379
#include "xfpga.h"
Packit 534379
#include "common_int.h"
Packit 534379
#include "metrics_int.h"
Packit 534379
#include "types_int.h"
Packit 534379
#include "opae/metrics.h"
Packit 534379
#include "metrics/vector.h"
Packit 534379
Packit 534379
// AFU BBB GUID
Packit 534379
#define METRICS_BBB_GUID            "87816958-C148-4CD0-9D73-E8F258E9E3D7"
Packit 534379
#define METRICS_BBB_ID_H            0x87816958C1484CD0
Packit 534379
#define METRICS_BBB_ID_L            0x9D73E8F258E9E3D7
Packit 534379
Packit 534379
#define FEATURE_TYPE_BBB            0x2
Packit 534379
Packit 534379
#define METRIC_CSR_OFFSET           0x20
Packit 534379
#define METRIC_NEXT_CSR             0x8
Packit 534379
Packit 534379
Packit 534379
fpga_result discover_afu_metrics_feature(fpga_handle handle, uint64_t *offset)
Packit 534379
{
Packit 534379
	fpga_result result               = FPGA_OK;
Packit 534379
	feature_definition feature_def;
Packit 534379
	uint64_t bbs_offset              = 0;
Packit 534379
Packit 534379
	if (offset == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	memset(&feature_def, 0, sizeof(feature_def));
Packit 534379
Packit 534379
	// Read AFU DFH
Packit 534379
	result = xfpga_fpgaReadMMIO64(handle, 0, 0x0, &(feature_def.dfh.csr));
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Invalid handle file descriptor");
Packit 534379
		result = FPGA_NOT_SUPPORTED;
Packit 534379
		return result;
Packit 534379
	}
Packit 534379
Packit 534379
	// Serach for AFU Metrics BBB DFH
Packit 534379
	while (feature_def.dfh.eol != 0 && feature_def.dfh.next_header_offset != 0) {
Packit 534379
Packit 534379
		bbs_offset = feature_def.dfh.next_header_offset;
Packit 534379
Packit 534379
		result = xfpga_fpgaReadMMIO64(handle, 0, feature_def.dfh.next_header_offset, &(feature_def.dfh.csr));
Packit 534379
		if (result != FPGA_OK) {
Packit 534379
			OPAE_ERR("Invalid handle file descriptor");
Packit 534379
			result = FPGA_NOT_SUPPORTED;
Packit 534379
			return result;
Packit 534379
		}
Packit 534379
Packit 534379
		if (feature_def.dfh.type == FEATURE_TYPE_BBB) {
Packit 534379
Packit 534379
			result = xfpga_fpgaReadMMIO64(handle, 0, bbs_offset +0x8, &(feature_def.guid[0]));
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Invalid handle file descriptor");
Packit 534379
				result = FPGA_NOT_SUPPORTED;
Packit 534379
				return result;
Packit 534379
			}
Packit 534379
Packit 534379
			result = xfpga_fpgaReadMMIO64(handle, 0, bbs_offset + 0x10, &(feature_def.guid[1]));
Packit 534379
			if (result != FPGA_OK) {
Packit 534379
				OPAE_ERR("Invalid handle file descriptor");
Packit 534379
				result = FPGA_NOT_SUPPORTED;
Packit 534379
				return result;
Packit 534379
			}
Packit 534379
Packit 534379
			if (feature_def.guid[0] == METRICS_BBB_ID_L &&
Packit 534379
				feature_def.guid[1] == METRICS_BBB_ID_H) {
Packit 534379
				*offset = bbs_offset;
Packit 534379
				return FPGA_OK;
Packit 534379
			} else	{
Packit 534379
				OPAE_ERR(" Metrics BBB Not Found \n ");
Packit 534379
			}
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
	}
Packit 534379
Packit 534379
	OPAE_ERR("AFU Metrics BBB Not Found \n ");
Packit 534379
	return FPGA_NOT_FOUND;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
fpga_result get_afu_metric_value(fpga_handle handle,
Packit 534379
				fpga_metric_vector *enum_vector,
Packit 534379
				uint64_t metric_num,
Packit 534379
				struct fpga_metric *fpga_metric)
Packit 534379
{
Packit 534379
	fpga_result result                           = FPGA_OK;
Packit 534379
	uint64_t index                               = 0;
Packit 534379
	struct metric_bbb_value metric_csr;
Packit 534379
	struct _fpga_enum_metric *_fpga_enum_metric  = NULL;
Packit 534379
	uint64_t num_enun_metrics                    = 0;
Packit 534379
Packit 534379
	if (handle == NULL ||
Packit 534379
		enum_vector == NULL ||
Packit 534379
		fpga_metric == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	memset(&metric_csr, 0, sizeof(metric_csr));
Packit 534379
Packit 534379
	result = fpga_vector_total(enum_vector, &num_enun_metrics);
Packit 534379
	if (result != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get metric total");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	result = FPGA_NOT_FOUND;
Packit 534379
	for (index = 0; index < num_enun_metrics; index++) {
Packit 534379
Packit 534379
		_fpga_enum_metric = (struct _fpga_enum_metric *)	fpga_vector_get(enum_vector, index);
Packit 534379
Packit 534379
		if (metric_num == _fpga_enum_metric->metric_num) {
Packit 534379
Packit 534379
			result = xfpga_fpgaReadMMIO64(handle, 0, _fpga_enum_metric->mmio_offset, &metric_csr.csr);
Packit 534379
Packit 534379
				fpga_metric->value.ivalue = metric_csr.value;
Packit 534379
				result = FPGA_OK;
Packit 534379
Packit 534379
		}
Packit 534379
Packit 534379
	}
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result add_afu_metrics_vector(fpga_metric_vector *vector,
Packit 534379
				  uint64_t *metric_id,
Packit 534379
				  uint64_t group_value,
Packit 534379
				  uint64_t metric_value,
Packit 534379
				  uint64_t metric_offset)
Packit 534379
{
Packit 534379
	fpga_result result                      = FPGA_OK;
Packit 534379
	struct metric_bbb_group group_csr;
Packit 534379
	struct metric_bbb_value metric_csr;
Packit 534379
	char group_name[SYSFS_PATH_MAX]         = { 0 };
Packit 534379
	char metric_name[SYSFS_PATH_MAX]        = { 0 };
Packit 534379
	char qualifier_name[SYSFS_PATH_MAX]     = { 0 };
Packit 534379
	char metric_units[SYSFS_PATH_MAX]       = { 0 };
Packit 534379
Packit 534379
	if (metric_id == NULL ||
Packit 534379
		vector == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	memset(&group_csr, 0, sizeof(group_csr));
Packit 534379
	memset(&metric_csr, 0, sizeof(metric_csr));
Packit 534379
Packit 534379
	group_csr.csr = group_value;
Packit 534379
	metric_csr.csr = metric_value;
Packit 534379
Packit 534379
	snprintf(group_name, sizeof(group_name), "%x", group_csr.group_id);
Packit 534379
	snprintf(metric_name, sizeof(metric_name), "%x", metric_csr.counter_id);
Packit 534379
Packit 534379
	snprintf(qualifier_name, sizeof(qualifier_name), "%s:%x", "AFU", group_csr.group_id);
Packit 534379
	snprintf(metric_units, sizeof(metric_units), "%x", group_csr.units);
Packit 534379
Packit 534379
	*metric_id = *metric_id + 1;
Packit 534379
Packit 534379
	result = add_metric_vector(vector, *metric_id, qualifier_name, group_name, "",
Packit 534379
			metric_name, "", metric_units, FPGA_METRIC_DATATYPE_INT, FPGA_METRIC_TYPE_AFU, FPGA_HW_MCP, metric_offset);
Packit 534379
Packit 534379
	return result;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
fpga_result enum_afu_metrics(fpga_handle handle,
Packit 534379
			    fpga_metric_vector *vector,
Packit 534379
			    uint64_t *metric_id,
Packit 534379
			    uint64_t metrics_offset)
Packit 534379
{
Packit 534379
	fpga_result result                    = FPGA_NOT_FOUND;
Packit 534379
	struct metric_bbb_group group_csr;
Packit 534379
	struct metric_bbb_value metric_csr;
Packit 534379
	uint64_t value_offset                 = 0;
Packit 534379
	uint64_t group_offset                 = 0;
Packit 534379
Packit 534379
	if (handle == NULL ||
Packit 534379
		vector == NULL ||
Packit 534379
		metric_id == NULL) {
Packit 534379
		OPAE_ERR("Invalid Input Paramters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	memset(&group_csr, 0, sizeof(group_csr));
Packit 534379
	memset(&metric_csr, 0, sizeof(metric_csr));
Packit 534379
Packit 534379
	group_offset = metrics_offset + METRIC_CSR_OFFSET;
Packit 534379
Packit 534379
	while (true) {
Packit 534379
Packit 534379
			result = xfpga_fpgaReadMMIO64(handle, 0, group_offset, &group_csr.csr);
Packit 534379
Packit 534379
			if (group_csr.group_id != 0) {
Packit 534379
Packit 534379
				value_offset = group_offset + METRIC_NEXT_CSR;
Packit 534379
				result = xfpga_fpgaReadMMIO64(handle, 0, value_offset, &metric_csr.csr);
Packit 534379
Packit 534379
				while (metric_csr.counter_id != 0) {
Packit 534379
Packit 534379
					// add to counter
Packit 534379
					result = add_afu_metrics_vector(vector, metric_id, group_csr.csr, metric_csr.csr, value_offset);
Packit 534379
					if (result != FPGA_OK) {
Packit 534379
						OPAE_ERR("Failed to add metrics vector");
Packit 534379
					}
Packit 534379
Packit 534379
Packit 534379
					if (metric_csr.eol == 0) {
Packit 534379
						value_offset = value_offset + METRIC_NEXT_CSR;
Packit 534379
						result = xfpga_fpgaReadMMIO64(handle, 0, value_offset, &metric_csr.csr);
Packit 534379
					} else {
Packit 534379
						break;
Packit 534379
					}
Packit 534379
Packit 534379
				} // end while
Packit 534379
Packit 534379
				if (group_offset == group_offset + group_csr.next_group_offset)
Packit 534379
					break;
Packit 534379
Packit 534379
				group_offset = group_offset + group_csr.next_group_offset;
Packit 534379
Packit 534379
			} else {
Packit 534379
				break;
Packit 534379
			}
Packit 534379
Packit 534379
	} // end while
Packit 534379
Packit 534379
	return result;
Packit 534379
}