Commit a5459794 authored by Dimitris Lampridis's avatar Dimitris Lampridis

sw: add fw application rep cap and associated attributes

parent c4e57572
......@@ -36,7 +36,7 @@
`define WRTD_IO_MSG_WORD_SIZE 2
`define WRTD_CFG_MSG_WORD_SIZE 5
`define WRTD_ROOT_WORD_SIZE 9
`define WRTD_ROOT_WORD_SIZE 13
`define WRTD_RULE_WORD_SIZE 43
`define WRTD_ALRM_WORD_SIZE 15
......@@ -217,6 +217,7 @@ typedef struct {
typedef struct {
uint32_t addr;
WrtdId fw_name;
uint32_t fw_id;
uint32_t nbr_alarms;
uint32_t alarms_addr;
......
......@@ -119,23 +119,28 @@ class WrtdDrv;
this.roots[i].addr = data[0];
// retrieve root
msg_readw ( i, this.roots[i].addr, `WRTD_ROOT_WORD_SIZE, data );
this.roots[i].fw_id = data[1];
this.roots[i].capabilities = ( data[2] & 'hff000000 ) >> 24;
this.roots[i].nbr_rules = ( data[2] & 'h00ff0000 ) >> 16;
this.roots[i].nbr_alarms = ( data[2] & 'h0000ff00 ) >> 8;
this.roots[i].nbr_devs = ( data[2] & 'h000000ff ) >> 0;
this.roots[i].fw_name = new();
this.roots[i].fw_name.data_unpack(data[1:4]);
this.roots[i].fw_id = data[5];
this.roots[i].capabilities = ( data[6] & 'hff000000 ) >> 24;
this.roots[i].nbr_rules = ( data[6] & 'h00ff0000 ) >> 16;
this.roots[i].nbr_alarms = ( data[6] & 'h0000ff00 ) >> 8;
this.roots[i].nbr_devs = ( data[6] & 'h000000ff ) >> 0;
for ( j = 0; j < 4; j++)
begin
this.roots[i].nbr_channels[j] = ( data[5] >> j*8 ) & 'hff;
this.roots[i].channel_dir[j] = ( data[6] >> j*8 ) & 'hff;
this.roots[i].nbr_channels[j] = ( data[9] >> j*8 ) & 'hff;
this.roots[i].channel_dir[j] = ( data[10] >> j*8 ) & 'hff;
end
this.roots[i].rules_addr = data[7];
this.roots[i].alarms_addr = data[8];
this.roots[i].rules_addr = data[11];
this.roots[i].alarms_addr = data[12];
// init free rule slots
this.free_rule_slots[i] = this.roots[i].nbr_rules;
// turn on all logging if enabled
if ( this.enable_logging )
msg_writew ( i, this.roots[i].addr + 16, 1, { data[4] | 32'hff } );
msg_writew ( i, this.roots[i].addr + 32, 1, { data[8] | 32'hff } );
mdisplay( $sformatf("CPU %0d: WRTD app '%s', id '0x%x'", i,
this.roots[i].fw_name.get(),
this.roots[i].fw_id) );
end
// initialise rules
......
......@@ -61,6 +61,7 @@ static struct wrtd_root root =
.ver_major = WRTD_VERSION_MAJOR,
.ver_minor = WRTD_VERSION_MINOR,
.fw_name = APP_NAME,
.fw_id = APP_ID,
.nbr_devices = NBR_DEVICES,
......
......@@ -167,6 +167,7 @@ struct wrtd_root {
uint8_t pad0_0;
uint8_t pad0_1;
char fw_name[WRTD_ID_LEN];
uint32_t fw_id;
/* Config. */
......
......@@ -72,12 +72,10 @@ class PyWrtd():
WRTD_ERROR_RULE_DOES_NOT_EXIST = __WRTD_SPECIFIC_ERROR_BASE + 0x07
__WRTD_ATTR_BASE = 1150000
WRTD_ATTR_MAJOR_VERSION = __WRTD_ATTR_BASE + 0x00
WRTD_ATTR_MINOR_VERSION = __WRTD_ATTR_BASE + 0x01
WRTD_ATTR_EVENT_LOG_EMPTY = __WRTD_ATTR_BASE + 0x02
WRTD_ATTR_EVENT_LOG_ENABLED = __WRTD_ATTR_BASE + 0x03
WRTD_ATTR_IS_TIME_SYNCHRONIZED = __WRTD_ATTR_BASE + 0x04
WRTD_ATTR_SYS_TIME = __WRTD_ATTR_BASE + 0x05
WRTD_ATTR_EVENT_LOG_EMPTY = __WRTD_ATTR_BASE + 0x00
WRTD_ATTR_EVENT_LOG_ENABLED = __WRTD_ATTR_BASE + 0x01
WRTD_ATTR_IS_TIME_SYNCHRONIZED = __WRTD_ATTR_BASE + 0x02
WRTD_ATTR_SYS_TIME = __WRTD_ATTR_BASE + 0x03
WRTD_ATTR_ALARM_COUNT = __WRTD_ATTR_BASE + 0x10
WRTD_ATTR_ALARM_ENABLED = __WRTD_ATTR_BASE + 0x11
WRTD_ATTR_ALARM_SETUP_TIME = __WRTD_ATTR_BASE + 0x12
......@@ -106,7 +104,11 @@ class PyWrtd():
WRTD_ATTR_STAT_RULE_RX_LATENCY_MIN = __WRTD_ATTR_BASE + 0x39
WRTD_ATTR_STAT_RULE_RX_LATENCY_MAX = __WRTD_ATTR_BASE + 0x3A
WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG = __WRTD_ATTR_BASE + 0x3B
WRTD_ATTR_STAT_RULE_RX_PERIOD_AVG = __WRTD_ATTR_BASE + 0x3C
WRTD_ATTR_FW_COUNT = __WRTD_ATTR_BASE + 0x80
WRTD_ATTR_FW_MAJOR_VERSION = __WRTD_ATTR_BASE + 0x81
WRTD_ATTR_FW_MINOR_VERSION = __WRTD_ATTR_BASE + 0x82
WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED = __WRTD_ATTR_BASE + 0x83
WRTD_ATTR_FW_MINOR_VERSION_REQUIRED = __WRTD_ATTR_BASE + 0x84
WRTD_GLOBAL_REP_CAP_ID = 'WGRCI'
......@@ -243,6 +245,11 @@ class PyWrtd():
self.wrtd_lib.wrtd_reset_rule_stats.errcheck = self.__errcheck
self.wrtd_lib.wrtd_reset_rule_stats.argtypes = [POINTER(wrtd_dev), c_char_p]
self.wrtd_lib.wrtd_get_fw_name.restype = c_int
self.wrtd_lib.wrtd_get_fw_name.errcheck = self.__errcheck
self.wrtd_lib.wrtd_get_fw_name.argtypes = [POINTER(wrtd_dev), c_int32,
c_int32, c_char_p]
self.resource_name = resource_name.encode('utf-8')
self.wrtd_p = POINTER(wrtd_dev)()
ret = self.wrtd_lib.wrtd_init(self.resource_name, 0, None, byref(self.wrtd_p))
......@@ -383,6 +390,15 @@ class PyWrtd():
def reset_rule_stats(self, rep_cap_id):
self.wrtd_lib.wrtd_reset_rule_stats(self.wrtd_p, rep_cap_id)
def get_fw_name(self, index):
buf_size = self.wrtd_lib.wrtd_get_fw_name(self.wrtd_p,
index,
0, None)
name = create_string_buffer(buf_size)
self.wrtd_lib.wrtd_get_fw_name(self.wrtd_p, index,
buf_size, name)
return name.value.decode('ascii')
def __errcheck(self, ret, func, args):
"""Generic error checker for WRTD functions"""
if ret < self.WRTD_SUCCESS:
......
......@@ -11,32 +11,68 @@
#include "libwrtd-private.h"
#include "mockturtle/libmockturtle.h"
enum wrtd_status wrtd_attr_get_major_version(struct wrtd_dev *wrtd,
enum wrtd_status wrtd_attr_get_fw_major_version(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value)
{
enum wrtd_status status;
unsigned int idx;
status = wrtd_find_fw(wrtd, rep_cap_id, &idx, __func__);
WRTD_RETURN_IF_ERROR(status);
*value = RT_VERSION_MAJ(wrtd->fw_version[idx].rt_version);
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_get_fw_minor_version(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value)
{
enum wrtd_status status;
unsigned int idx;
status = wrtd_find_fw(wrtd, rep_cap_id, &idx, __func__);
WRTD_RETURN_IF_ERROR(status);
*value = RT_VERSION_MIN(wrtd->fw_version[idx].rt_version);
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_get_fw_major_version_required(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value)
{
enum wrtd_status status;
unsigned int idx;
status = wrtd_fill_roots(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
/* all cpu firmwares should be built against the same lib version,
it's enough to read one. */
*value = wrtd->roots[0].ver_major;
status = wrtd_find_fw(wrtd, rep_cap_id, &idx, __func__);
WRTD_RETURN_IF_ERROR(status);
*value = wrtd->roots[idx].ver_major;
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_get_minor_version(struct wrtd_dev *wrtd,
enum wrtd_status wrtd_attr_get_fw_minor_version_required(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value)
{
enum wrtd_status status;
unsigned int idx;
status = wrtd_fill_roots(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
/* all cpu firmwares should be built against the same lib version,
it's enough to read one. */
*value = wrtd->roots[0].ver_minor;
status = wrtd_find_fw(wrtd, rep_cap_id, &idx, __func__);
WRTD_RETURN_IF_ERROR(status);
*value = wrtd->roots[idx].ver_minor;
return WRTD_SUCCESS;
}
......
......@@ -623,3 +623,35 @@ inline enum wrtd_status wrtd_rule_check_disabled(struct wrtd_dev *wrtd, unsigned
caller_func, __func__);
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_find_fw(struct wrtd_dev *wrtd,
const char *rep_cap_id,
unsigned *idx,
const char *caller_func)
{
enum wrtd_status status;
unsigned i;
if(wrtd == NULL){
return WRTD_ERROR_NOT_INITIALIZED;
}
/* 1. Validate rep_cap_id. */
status = wrtd_validate_id(wrtd, rep_cap_id, caller_func);
WRTD_RETURN_IF_ERROR(status);
/* 2. Load all roots. */
status = wrtd_fill_roots(wrtd, caller_func);
WRTD_RETURN_IF_ERROR(status);
/* 3. Search it. */
for (i = 0; i < wrtd->nbr_cpus; i++)
if (wrtd_id_eq(wrtd->roots[i].fw_name, rep_cap_id)) {
*idx = i;
return WRTD_SUCCESS;
}
return wrtd_return_error(wrtd, WRTD_ERROR_RESOURCE_UNKNOWN,
"%s/%s: Unknown firmware name",
caller_func, __func__);
}
......@@ -9,6 +9,8 @@
#ifndef __LIBWRTD_PRIVATE__H__
#define __LIBWRTD_PRIVATE__H__
#include "mockturtle/libmockturtle.h"
#define WRTD_RETURN_IF_ERROR(status) if(status != WRTD_SUCCESS) return status
#define WRTD_DEFAULT_TIMEOUT 1000
......@@ -43,7 +45,7 @@ struct wrtd_lib_rule {
};
struct wrtd_dev {
/* Associated mock-turtle device. */
/* Associated Mock Turtle device. */
struct trtl_dev *trtl;
/* Last error. */
......@@ -55,6 +57,9 @@ struct wrtd_dev {
/* Number of cpus. Valid if > 0. */
uint32_t nbr_cpus;
/* Firmware version information from Mock Turtle */
struct trtl_fw_version fw_version[WRTD_MAX_CPUS];
/* Per-cpu hmq length (from MT config) - this is needed for
readw/writew. */
uint32_t hmq_words[WRTD_MAX_CPUS];
......@@ -143,6 +148,12 @@ enum wrtd_status wrtd_write_rule(struct wrtd_dev *wrtd, unsigned idx,
enum wrtd_status wrtd_fill_rules(struct wrtd_dev *wrtd,
const char *caller_func);
/* Find firmware index by id. */
enum wrtd_status wrtd_find_fw(struct wrtd_dev *wrtd,
const char *rep_cap_id,
unsigned *idx,
const char *caller_func);
/* Reconfigure route tables and write-back rules. */
enum wrtd_status wrtd_reconfigure(struct wrtd_dev *wrtd, const char *caller_func);
......@@ -164,9 +175,17 @@ enum wrtd_status wrtd_log_read(struct wrtd_dev *wrtd,
const char *caller_func);
/* Get/set attribute implementation function prototypes */
enum wrtd_status wrtd_attr_get_major_version(struct wrtd_dev *wrtd,
enum wrtd_status wrtd_attr_get_fw_major_version(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value);
enum wrtd_status wrtd_attr_get_fw_minor_version(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value);
enum wrtd_status wrtd_attr_get_minor_version(struct wrtd_dev *wrtd,
enum wrtd_status wrtd_attr_get_fw_major_version_required(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value);
enum wrtd_status wrtd_attr_get_fw_minor_version_required(struct wrtd_dev *wrtd,
const char *rep_cap_id,
int32_t *value);
enum wrtd_status wrtd_attr_get_alarm_count(struct wrtd_dev *wrtd,
int32_t *value);
......
......@@ -97,7 +97,14 @@ wrtd_status wrtd_init(const char *resource_name,
status = wrtd_msg_get_config(res, i, &msg, __func__);
WRTD_RETURN_IF_ERROR(status);
res->root_addr[i] = msg.root_addr;
/* FIXME: check firmware version ? */
}
for (i = 0; i < cfgrom->n_cpu; i++) {
if (trtl_fw_version(res->trtl, i, WRTD_HMQ, &res->fw_version[i]) < 0)
return wrtd_return_error(
res, WRTD_ERROR_INTERNAL,
"%s: Could not retrieve firmware vesion info (%s)",
__func__, trtl_strerror(errno));
}
res->nbr_cpus = cfgrom->n_cpu;
......@@ -501,8 +508,11 @@ wrtd_status wrtd_set_attr_int32(wrtd_dev *wrtd,
case WRTD_ATTR_RULE_RESYNC_FACTOR:
return wrtd_attr_set_rule_resync_factor
(wrtd, rep_cap_id, value);
case WRTD_ATTR_MAJOR_VERSION:
case WRTD_ATTR_MINOR_VERSION:
case WRTD_ATTR_FW_COUNT:
case WRTD_ATTR_FW_MAJOR_VERSION:
case WRTD_ATTR_FW_MINOR_VERSION:
case WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED:
case WRTD_ATTR_FW_MINOR_VERSION_REQUIRED:
case WRTD_ATTR_ALARM_COUNT:
case WRTD_ATTR_RULE_COUNT:
case WRTD_ATTR_STAT_RULE_RX_EVENTS:
......@@ -554,20 +564,30 @@ wrtd_status wrtd_get_attr_int32(wrtd_dev *wrtd,
}
switch(id) {
case WRTD_ATTR_MAJOR_VERSION:
case WRTD_ATTR_FW_COUNT:
status = wrtd_attr_global
(wrtd, rep_cap_id);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_attr_get_major_version
(wrtd, value);
*value = wrtd->nbr_cpus;
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MAJOR_VERSION:
status = wrtd_attr_get_fw_major_version
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_MINOR_VERSION:
status = wrtd_attr_global
(wrtd, rep_cap_id);
case WRTD_ATTR_FW_MINOR_VERSION:
status = wrtd_attr_get_fw_minor_version
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_attr_get_minor_version
(wrtd, value);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED:
status = wrtd_attr_get_fw_major_version_required
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_FW_MINOR_VERSION_REQUIRED:
status = wrtd_attr_get_fw_minor_version_required
(wrtd, rep_cap_id, value);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
case WRTD_ATTR_ALARM_COUNT:
......@@ -1363,7 +1383,7 @@ wrtd_status wrtd_get_alarm_name(wrtd_dev *wrtd,
status = wrtd_fill_alarms(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
/* 3. Search it. */
/* Search it. */
for (n = 0, i = 0; i < wrtd->nbr_alarms; i++) {
const char *aid = wrtd->alarms[i].alarm.event.id;
if (wrtd_id_null(aid))
......@@ -1601,7 +1621,7 @@ wrtd_status wrtd_get_rule_name(wrtd_dev *wrtd,
status = wrtd_fill_rules(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
/* 3. Search it. */
/* Search it. */
for (n = 0, i = 0; i < wrtd->nbr_rules; i++) {
const char *aid = wrtd->rules[i].rule.conf.id;
if (wrtd_id_null(aid))
......@@ -1659,3 +1679,61 @@ wrtd_status wrtd_reset_rule_stats(wrtd_dev *wrtd,
/**
*@} End group Rules
*/
/**
* @defgroup Rules
* Functions to add/remove and access WRTD Rules.
* @{
*/
/**
* Retrieve the name of a firmware application, based on the provided index.
* Complies with the IVI "Parameter style"
* for repeated capabilities (see IVI-3.4, section 12).
*
* This function complies with IVI-3.2, section 3.1.2.1 (Additional Compliance Rules
* for C Functions with ViChar Array Output Parameters), with the exception of
* the buffer_size < 0 case, which produces an error instead of allowing a potential
* buffer overflow.
*
* @param[in] wrtd Device token.
* @param[in] index index of the firmware application.
* @param[in] name_buffer_size Size of pre-allocated `name` buffer.
* @param[out] name Buffer to store the retrieved application name.
* @return #wrtd_status. See also IVI-3.2, section 3.1.2.1.
*/
wrtd_status wrtd_get_fw_name(wrtd_dev *wrtd,
int32_t index,
int32_t name_buffer_size,
char *name)
{
wrtd_status status;
unsigned i;
if(wrtd == NULL){
return WRTD_ERROR_NOT_INITIALIZED;
}
/* Load all roots. */
status = wrtd_fill_roots(wrtd, __func__);
WRTD_RETURN_IF_ERROR(status);
/* Search it. */
for (i = 0; i < wrtd->nbr_cpus; i++) {
if (i == index) {
status = wrtd_id_copy_buf
(wrtd, name, name_buffer_size,
wrtd->roots[i].fw_name, __func__);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
}
}
return wrtd_return_error(wrtd, WRTD_ERROR_INVALID_VALUE,
"Invalid value (%d) for function %s, "
"parameter index.", index, __func__);
}
/**
*@} End group Firmware
*/
......@@ -113,20 +113,14 @@ typedef enum wrtd_attr {
/** Same as *IVI_INSTR_SPECIFIC_ATTR_BASE*. */
__WRTD_ATTR_BASE = 1150000,
/** `RO` `int32` `global` Major part of WRTD version supported by the device.
It must be equal to the major version of the WRTD library in use. */
WRTD_ATTR_MAJOR_VERSION = __WRTD_ATTR_BASE + 0x00,
/** `RO` `int32` `global` Minor part of WRTD version supported by the device.
It must be less than or equal to the minor version of the WRTD library in use. */
WRTD_ATTR_MINOR_VERSION = __WRTD_ATTR_BASE + 0x01,
/** `RO` `bool` `global` True if the Event Log is empty. */
WRTD_ATTR_EVENT_LOG_EMPTY = __WRTD_ATTR_BASE + 0x02,
WRTD_ATTR_EVENT_LOG_EMPTY = __WRTD_ATTR_BASE + 0x00,
/** `RW` `bool` `global` Enable/dsiable the Event Log. */
WRTD_ATTR_EVENT_LOG_ENABLED = __WRTD_ATTR_BASE + 0x03,
WRTD_ATTR_EVENT_LOG_ENABLED = __WRTD_ATTR_BASE + 0x01,
/** `RO` `bool` `global` True if the device is synchronized to White Rabbit time. */
WRTD_ATTR_IS_TIME_SYNCHRONIZED = __WRTD_ATTR_BASE + 0x04,
WRTD_ATTR_IS_TIME_SYNCHRONIZED = __WRTD_ATTR_BASE + 0x02,
/** `RO` `tstamp` `global` Current system time. */
WRTD_ATTR_SYS_TIME = __WRTD_ATTR_BASE + 0x05,
WRTD_ATTR_SYS_TIME = __WRTD_ATTR_BASE + 0x03,
/** `RO` `int32` `global` Number of defined Alarms. */
WRTD_ATTR_ALARM_COUNT = __WRTD_ATTR_BASE + 0x10,
......@@ -219,6 +213,21 @@ typedef enum wrtd_attr {
reception by WRTD. */
WRTD_ATTR_STAT_RULE_RX_LATENCY_AVG = __WRTD_ATTR_BASE + 0x3B,
/** `RO` `int32` `global` Number of separate WRTD firmware applications
running on the device. */
WRTD_ATTR_FW_COUNT = __WRTD_ATTR_BASE + 0x80,
/** `RO` `int32` Major part of the firmware's version. */
WRTD_ATTR_FW_MAJOR_VERSION = __WRTD_ATTR_BASE + 0x81,
/** `RO` `int32` Major part of the firmware's version. */
WRTD_ATTR_FW_MINOR_VERSION = __WRTD_ATTR_BASE + 0x82,
/** `RO` `int32` Major part of WRTD version supported by the firmware.
It must be equal to the major version of the WRTD library in use. */
WRTD_ATTR_FW_MAJOR_VERSION_REQUIRED = __WRTD_ATTR_BASE + 0x83,
/** `RO` `int32` Minor part of WRTD version supported by the firmware.
It must be less than or equal to the minor version of the WRTD library in use. */
WRTD_ATTR_FW_MINOR_VERSION_REQUIRED = __WRTD_ATTR_BASE + 0x84,
/** Always last entry in this enum */
__WRTD_ATTR_MAX_NUMBER,
}wrtd_attr;
......@@ -343,6 +352,13 @@ wrtd_status wrtd_get_rule_name(wrtd_dev *wrtd,
wrtd_status wrtd_reset_rule_stats(wrtd_dev *wrtd,
const char *rep_cap_id);
/* Firmware applications */
wrtd_status wrtd_get_fw_name(wrtd_dev *wrtd,
int32_t index,
int32_t name_buffer_size,
char *name);
#ifdef __cplusplus
};
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment