coverage-reporting: Add OP-TEE SPMC coverage support
diff --git a/coverage-tool/coverage-plugin/coverage_trace.cc b/coverage-tool/coverage-plugin/coverage_trace.cc
index 4dc72ee..d2b13fd 100644
--- a/coverage-tool/coverage-plugin/coverage_trace.cc
+++ b/coverage-tool/coverage-plugin/coverage_trace.cc
@@ -1,6 +1,6 @@
/*!
##############################################################################
-# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
##############################################################################
@@ -12,6 +12,7 @@
#include "MTI/PluginFactory.h"
#include "MTI/PluginInstance.h"
#include "MTI/ModelTraceInterface.h"
+#include "MTI/ParameterInterface.h"
#include "plugin_utils.h"
#include "trace_sources.h"
@@ -26,6 +27,7 @@
#include <typeinfo>
#include <typeindex>
#include <utility>
+#include "SimpleCADI.h"
#ifdef SG_MODEL_BUILD
#include "builddata.h"
@@ -34,19 +36,58 @@
#define PLUGIN_VERSION "unreleased"
#endif
+enum plugin_param_t
+{
+TRACE_FILE_PREFIX,
+TRACE_MODE,
+TOTAL_PARAMETERS
+};
using namespace eslapi;
using namespace MTI;
using namespace std;
// Implements the plugin interface for trace coverage
-class CoverageTrace :public PluginInstance
+
+// Class used to return a static object CAInterface. CAInterface provides a
+// basis for a software model built around ’components’ and ’interfaces’.
+// A component provides concrete implementations of one or more interfaces.
+// Interfaces are identified by a string name (of type if_name_t), and an
+// integer revision (type if_rev_t). A higher revision number indicates a newer
+// revision of the same interface.
+class ThePluginFactory :public PluginFactory
+{
+public:
+ virtual CAInterface *ObtainInterface(if_name_t ifName,
+ if_rev_t minRev,
+ if_rev_t * actualRev);
+
+ virtual uint32_t GetNumberOfParameters();
+
+ virtual eslapi::CADIReturn_t
+ GetParameterInfos(eslapi::CADIParameterInfo_t *parameter_info_list);
+
+ virtual CAInterface *Instantiate(const char *instance_name,
+ uint32_t number_of_parameters,
+ eslapi::CADIParameterValue_t *parameter_values);
+
+ virtual void Release();
+
+ virtual const char *GetType() const { return "CoverageTrace"; }
+ virtual const char *GetVersion() const { return PLUGIN_VERSION; }
+};
+
+static ThePluginFactory *GetThePluginFactory();
+class CoverageTrace :
+ public ParameterInterface,
+ public PluginInstance
{
public:
virtual CAInterface * ObtainInterface(if_name_t ifName,
if_rev_t minRev,
if_rev_t * actualRev);
- CoverageTrace(const char *instance_name, const char *trace_file_prefix);
+ CoverageTrace(const char *instance_name, const char *trace_file_prefix,
+ int _mode);
~CoverageTrace();
/** This is to associate a plugin with a simulation instance. Exactly one
@@ -58,9 +99,24 @@
// This is called before the plugin .dll/.so is unloaded and should allow
// the plugin to do it's cleanup.
virtual void Release();
+ void Save(void);
virtual const char *GetName() const;
+ virtual eslapi::CADIReturn_t GetParameterInfos(uint32_t start_index,
+ uint32_t desired_num_of_params,
+ uint32_t* actual_num_of_params,
+ eslapi::CADIParameterInfo_t* params);
+ virtual eslapi::CADIReturn_t GetParameterInfo(const char* parameterName,
+ eslapi::CADIParameterInfo_t* param);
+
+ virtual eslapi::CADIReturn_t GetParameterValues(uint32_t parameter_count,
+ uint32_t* actual_num_of_params_read,
+ eslapi::CADIParameterValue_t* param_values_out);
+ virtual eslapi::CADIReturn_t SetParameterValues(uint32_t parameter_count,
+ eslapi::CADIParameterValue_t* parameters,
+ eslapi::CADIFactoryErrorMessage_t* error);
+ ModeChangeTraceContext *mode_change;
private:
std::string instance_name;
@@ -68,6 +124,7 @@
vector<TraceComponentContext*> trace_components;
std::string trace_file_prefix;
+ int trace_mode;
};
CAInterface *CoverageTrace::ObtainInterface(if_name_t ifName,
@@ -76,14 +133,14 @@
{
printf("CoverageTrace::ObtainInterface\n");
// If someone is asking for the matching interface
- if((strcmp(ifName,IFNAME()) == 0) &&
+ if((strcmp(ifName,PluginInstance::IFNAME()) == 0) &&
// and the revision of this interface implementation is
- (minRev <= IFREVISION()))
+ (minRev <= PluginInstance::IFREVISION()))
// at least what is being asked for
{
if (actualRev) // Make sure this is not a NULL pointer
- *actualRev = IFREVISION();
- return this;
+ *actualRev = PluginInstance::IFREVISION();
+ return dynamic_cast<PluginInstance *>(this);
}
if((strcmp(ifName, CAInterface::IFNAME()) == 0) &&
@@ -91,16 +148,25 @@
{
if (actualRev != NULL)
*actualRev = CAInterface::IFREVISION();
- return this;// Dynamic_cast<TracePluginInterface *>(this);
+ return dynamic_cast<CAInterface *>(dynamic_cast<PluginInstance *>(this));
}
+ if((strcmp(ifName, ParameterInterface::IFNAME()) == 0) &&
+ minRev <= ParameterInterface::IFREVISION())
+ {
+ if (actualRev != NULL)
+ *actualRev = ParameterInterface::IFREVISION();
+ return dynamic_cast<ParameterInterface *>(this);
+ }
+ printf("CoverageTrace::ObtainInterface Failed!\n");
return NULL;
}
CoverageTrace::CoverageTrace(const char *instance_name_,
- const char *trace_file_prefix_) :
+ const char *trace_file_prefix_, int _mode) :
instance_name(instance_name_),
- trace_file_prefix(trace_file_prefix_)
+ trace_file_prefix(trace_file_prefix_),
+ trace_mode(_mode)
{
printf("CoverageTrace::CoverageTrace\n");
}
@@ -142,6 +208,9 @@
CAInterface *caif = sys_if->GetComponentTrace(tci);
ComponentTraceInterface *cti =
caif->ObtainPointer<ComponentTraceInterface>();
+ InstructionTraceContext *inst_cont = NULL;
+ MTI::EventClass * event = NULL;
+
if (cti == 0) {
Error("Could not get TraceInterface for component.");
continue;
@@ -154,16 +223,39 @@
// To register a new trace source the arguments are the
// name of the trace source followed by a vector of
// pairs of (field name,field type).
- InstructionTraceContext *inst_cont = new InstructionTraceContext(
- "INST",
- { {"PC", u32},
- {"SIZE", u32}}
- );
+ inst_cont = new InstructionTraceContext(
+ "INST",
+ { {"PC", u32},
+ {"SIZE", u32}}
+ );
inst_cont->nb_insts = 0;
- inst_cont->CreateEvent(&cti, inst_cont->Callback);
+ event = inst_cont->CreateEvent(&cti, inst_cont->Callback);
+ event->UnregisterCallback(inst_cont->Callback, inst_cont);
trace_component->AddTraceSource(inst_cont);
trace_components.push_back(trace_component);
}
+ if (cti->GetTraceSource("MODE_CHANGE") != 0) {
+ MTI::EventClass * mode_event = NULL;
+ if(!event) {
+ Error("Could not set mode_change event");
+ continue;
+ }
+ // To register a new trace source the arguments are the
+ // name of the trace source followed by a vector of
+ // pairs of (field name,field type).
+ this->mode_change = new ModeChangeTraceContext(
+ "MODE_CHANGE",
+ { {"MODE", u8},
+ {"NON_SECURE", u8}
+ }
+ );
+ mode_event = this->mode_change->CreateEvent(&cti, this->mode_change->Callback);
+ this->mode_change->event = event;
+ this->mode_change->itc = inst_cont;
+ this->mode_change->mode_mask = trace_mode;
+ mode_event->RegisterCallback(this->mode_change->Callback, mode_change);
+ }
+
}
return CADI_STATUS_OK;
@@ -174,8 +266,14 @@
void
CoverageTrace::Release()
{
- printf("CoverageTrace::Release\n");
+ printf("CoverageTrace::Release\n");
// We can dump our data now
+ this->Save();
+}
+
+void
+CoverageTrace::Save(void)
+{
int error = 0;
char* fname;
int ret;
@@ -191,7 +289,7 @@
int status = asprintf(&fname, "%s-%s.log",
this->trace_file_prefix.c_str(),
tcont->trace_path.c_str());
- if ( status != 0)
+ if ( status == -1)
{
printf("Error in asprintf: %d\n", status);
printf("Error description is : %s\n", strerror(errno));
@@ -223,8 +321,9 @@
free(fname);
}
-if (error != 0)
- delete this;
+ printf("Everything saved\n");
+ if (error != 0)
+ delete this;
}
const char *
@@ -234,33 +333,103 @@
return instance_name.c_str();
}
-// Class used to return a static object CAInterface. CAInterface provides a
-// basis for a software model built around ’components’ and ’interfaces’.
-// A component provides concrete implementations of one or more interfaces.
-// Interfaces are identified by a string name (of type if_name_t), and an
-// integer revision (type if_rev_t). A higher revision number indicates a newer
-// revision of the same interface.
-class ThePluginFactory :public PluginFactory
+CADIReturn_t CoverageTrace::GetParameterInfos(uint32_t start_index,
+ uint32_t desired_num_of_params,
+ uint32_t* actual_num_of_params,
+ CADIParameterInfo_t* params)
{
-public:
- virtual CAInterface *ObtainInterface(if_name_t ifName,
- if_rev_t minRev,
- if_rev_t * actualRev);
- virtual uint32_t GetNumberOfParameters();
+ *actual_num_of_params = GetThePluginFactory()->GetNumberOfParameters();
+ return GetThePluginFactory()->GetParameterInfos(params);
- virtual eslapi::CADIReturn_t
- GetParameterInfos(eslapi::CADIParameterInfo_t *parameter_info_list);
+}
- virtual CAInterface *Instantiate(const char *instance_name,
- uint32_t number_of_parameters,
- eslapi::CADIParameterValue_t *parameter_values);
+CADIReturn_t CoverageTrace::GetParameterInfo(const char* parameterName,
+ CADIParameterInfo_t* param)
+{
+ uint32_t num_of_params = GetThePluginFactory()->GetNumberOfParameters();
+ CADIParameterInfo_t* plugin_parameters = NULL;
- virtual void Release();
+ GetThePluginFactory()->GetParameterInfos(plugin_parameters);
- virtual const char *GetType() const { return "CoverageTrace"; }
- virtual const char *GetVersion() const { return PLUGIN_VERSION; }
-};
+ if (param == nullptr)
+ {
+ return CADI_STATUS_IllegalArgument;
+ }
+
+ printf("Reading parameter info %s \n", parameterName);
+ for (uint32_t i = 0; i < num_of_params; ++i)
+ {
+ if (strcmp(plugin_parameters[i].name, parameterName) == 0)
+ {
+ *param = plugin_parameters[i];
+ return CADI_STATUS_OK;
+ }
+ }
+ *param = plugin_parameters[0];
+ return CADI_STATUS_OK;
+
+}
+
+CADIReturn_t CoverageTrace::GetParameterValues(uint32_t parameter_count,
+ uint32_t* actual_num_of_params_read,
+ CADIParameterValue_t *param_values_out)
+{
+ if (param_values_out == nullptr || actual_num_of_params_read == nullptr)
+ {
+ return CADI_STATUS_IllegalArgument;
+ }
+
+ *actual_num_of_params_read = 0;
+ for (uint32_t i = 0; i < parameter_count; ++i)
+ {
+ CADIParameterValue_t ¶m_value = param_values_out[i];
+
+ switch (param_value.parameterID)
+ {
+ case TRACE_FILE_PREFIX:
+ strncpy(param_value.stringValue,
+ this->trace_file_prefix.c_str(),
+ sizeof(param_value.stringValue));
+ break;
+
+ case TRACE_MODE:
+ param_value.intValue = this->mode_change->mode_mask;
+ break;
+ default: // unknown ID
+
+ *actual_num_of_params_read = i;
+ return CADI_STATUS_IllegalArgument;
+ }
+ }
+
+ *actual_num_of_params_read = parameter_count;
+ return CADI_STATUS_OK;
+}
+
+CADIReturn_t CoverageTrace::SetParameterValues(uint32_t parameter_count,
+ CADIParameterValue_t* parameters,
+ CADIFactoryErrorMessage_t* error)
+{
+ for (uint32_t i = 0; i < parameter_count; ++i)
+ {
+ CADIParameterValue_t ¶meter = parameters[i];
+ switch(parameter.parameterID)
+ {
+ case TRACE_FILE_PREFIX:
+ this->trace_file_prefix = parameter.stringValue;
+ this->Save();
+ break;
+ case TRACE_MODE:
+ this->mode_change->mode_mask = parameter.intValue;
+ break;
+ default:
+ ;
+ break;
+ }
+ }
+ return CADI_STATUS_OK;
+}
// Allows a client to obtain a reference to any of the interfaces that the
// component implements. The client specifies the id and revision of the
@@ -296,7 +465,7 @@
uint32_t ThePluginFactory::GetNumberOfParameters()
{
printf("ThePluginFactory::GetNumberOfParameters\n");
- return 1;
+ return TOTAL_PARAMETERS;
}
eslapi::CADIReturn_t
@@ -304,10 +473,12 @@
eslapi::CADIParameterInfo_t *parameter_info_list)
{
printf("ThePluginFactory::GetParameterInfos\n");
- *parameter_info_list = CADIParameterInfo_t(
- 0, "trace-file-prefix", CADI_PARAM_STRING,
- "Prefix of the trace files.", 0, 0, 0, 0, "covtrace"
- );
+ parameter_info_list[0] = CADIParameterInfo_t(
+ TRACE_FILE_PREFIX, "trace-file-prefix", CADI_PARAM_STRING,
+ "Prefix of the trace files.", true, 0, 0, 0, "covtrace");
+ parameter_info_list[1] = CADIParameterInfo_t(
+ TRACE_MODE, "trace-mode", CADI_PARAM_INT,
+ "Selects which modes to trace.", true, 0, 0xffffffff, 0xffffffff, 0);
return CADI_STATUS_OK;
}
@@ -318,16 +489,21 @@
{
printf("ThePluginFactory::Instantiate\n");
const char *trace_file_prefix = 0;
+ int mode_value = 0xffffffff;
+
printf("CoverageTrace: number of params: %d\n", param_nb);
for (uint32_t i = 0; i < param_nb; ++i) {
- if (values[i].parameterID == 0) {
+ if (values[i].parameterID == TRACE_FILE_PREFIX) {
trace_file_prefix = values[i].stringValue;
+ } else if (values[i].parameterID == TRACE_MODE) {
+ mode_value = values[i].intValue;
} else {
printf("\tCoverageTrace: got unexpected param %d\n",
values[i].parameterID);
}
}
- return new CoverageTrace(instance_name, trace_file_prefix);
+ return (PluginInstance*)new CoverageTrace(instance_name, trace_file_prefix,
+ mode_value);
}
void ThePluginFactory::Release()
@@ -345,5 +521,9 @@
printf("********->GetCAInterface\n");
return &factory_instance;
}
+static ThePluginFactory *GetThePluginFactory()
+{
+ return &factory_instance;
+}
// End of file CoverageTrace.cpp