Commit 5428e2ea authored by Dimitris Lampridis's avatar Dimitris Lampridis

sw: rework seq and sync_id logic (#24)

`seq` is now available to user applications

`sync_id` is defined internally as a unique ID per HMQ+CPU combo. User
applications do not need to define this anymore before sending a sync
message.
parent 958f1d43
......@@ -26,8 +26,6 @@ int pr_frm_debug(const char *fmt, ...)
}
#endif
uint32_t msg_seq = 0;
/**
* Make the given message an error message
*/
......@@ -323,7 +321,12 @@ static inline int rt_action_run(enum trtl_mq_type type,
msg_out.header->flags = TRTL_HMQ_HEADER_FLAG_ACK;
msg_out.header->msg_id = 0;
msg_out.header->len = 0;
msg_out.header->sync_id = msg->header->sync_id;
/*
* Every combination of CPU+HMQ has a unique sync_id. We avoid copying
* the sync_id from the incoming message and prefer rebuilding it in the
* firmware in order to detect possible wrong deliveries of sync messages.
*/
msg_out.header->sync_id = ((idx_mq << 8) | trtl_get_core_id()) & 0xffff;
err = action(msg, &msg_out);
if (err)
......
......@@ -109,9 +109,9 @@ struct trtl_hmq_header {
first __TRTL_MSG_ID_MAX_USER are free use */
/* word 1 */
uint16_t len; /**< message-length in 32bit words */
uint16_t sync_id;/**< synchronous identifier */
uint16_t sync_id;/**< synchronous identifier (automatically set by the library) */
/* word 2 */
uint32_t seq; /**< sequence number (automatically set by the library?) */
uint32_t seq; /**< sequence number (to be defined and used by the application if necessary) */
};
......
......@@ -252,7 +252,6 @@ struct trtl_cpu {
* @base_cfg: base address for the configuration ROM
* @base_smem: base address of the Shared Memory
* @irq_mask: IRQ mask in use
* @message_sequence: message sequence number
* @lock_cpu_sel:
* @lock_hmq_sel: protects the HMQ usage which is based on selection. It
* protects also last_seq which is related to HMQ messages
......@@ -263,8 +262,6 @@ struct trtl_cpu {
* @dbg_info: information
* @max_irq_loop: maximum number of messages that can be retrieved with a
* single IRQ. It regulates the HMQ IRQ handler
* @last_seq: last sequence number used. The same seq number cannot be used
* on different HMQ on the same CPU
* @debugger: debugfs interface for gdbserver
*/
struct trtl_dev {
......@@ -277,7 +274,6 @@ struct trtl_dev {
void *base_cfg;
void *base_smem;
uint64_t irq_mask;
uint32_t message_sequence;
spinlock_t lock_cpu_sel;
spinlock_t lock_hmq_sel;
const struct trtl_config_rom cfgrom;
......@@ -286,7 +282,6 @@ struct trtl_dev {
struct dentry *dbg_dir;
struct dentry *dbg_info;
unsigned int max_irq_loop;
uint32_t last_seq;
struct dentry *debugger;
};
......
......@@ -74,24 +74,6 @@ static void trtl_hmq_user_sync_wait_clr(struct trtl_hmq_user *user)
spin_unlock(&user->lock);
}
/**
* Get a valid sequence number
* @trtl: trtl device
*
* Return a valid sequence number
*/
static int trtl_msg_seq_get(struct trtl_dev *trtl)
{
unsigned long flags;
int seq;
spin_lock_irqsave(&trtl->lock_hmq_sel, flags);
seq = trtl->last_seq++;
spin_unlock_irqrestore(&trtl->lock_hmq_sel, flags);
return seq;
}
/**
* An opaque type. It is used to avoid mistakes when using features
* that requires the HMQ selection. If you do not provide this type (which is
......@@ -601,7 +583,7 @@ static int trtl_hmq_release(struct inode *inode, struct file *f)
/**
* Write a single message from a buffer
* @hmq: HMQ instance destination
* @user: HMQ instance destination
* @buf: source buffer
* Return: 0 on success, otherwise a negative error number
*/
......@@ -609,7 +591,7 @@ static int trtl_hmq_write_one(struct trtl_hmq_user *user,
const char __user *ubuf)
{
struct trtl_hmq *hmq = user->hmq;
struct trtl_dev *trtl = to_trtl_dev(hmq->dev.parent->parent);
struct trtl_cpu *cpu = to_trtl_cpu(hmq->dev.parent);
struct trtl_msg *msg;
int err = 0, copy_size;
size_t size;
......@@ -634,9 +616,9 @@ static int trtl_hmq_write_one(struct trtl_hmq_user *user,
return -EINVAL;
}
buf->msg_tmp.hdr.seq = trtl_msg_seq_get(trtl);
if (trtl_hmq_user_is_sync(user)) {
uint16_t sync_id = buf->msg_tmp.hdr.seq & 0xFFFF;
/* Every combination of CPU+HMQ has a unique sync_id */
uint16_t sync_id = ((hmq->index << 8) | cpu->index) & 0xFFFF;
buf->msg_tmp.hdr.flags |= TRTL_HMQ_HEADER_FLAG_SYNC;
buf->msg_tmp.hdr.sync_id = sync_id;
......@@ -905,8 +887,6 @@ static void trtl_message_pop(struct trtl_hmq *hmq, struct trtl_msg *msg)
trtl_hmq_data_read(ctx, msg->data, msg->hdr.len);
trtl_hmq_command(ctx, TRTL_MQ_CMD_DISCARD, 0);
spin_unlock_irqrestore(&trtl->lock_hmq_sel, flags);
msg->hdr.seq = trtl_msg_seq_get(trtl);
}
......
......@@ -19,8 +19,6 @@
*/
struct trtl_desc {
uint32_t devid; /**< device instance identifier */
uint32_t seq; /**< global sequence number for messages sent from
this instance*/
char name[TRTL_NAME_LEN]; /**< Name of the device */
char path[TRTL_PATH_LEN]; /**< path to device */
int fd_dev; /**< File Descriptor of the device */
......
......@@ -30,14 +30,11 @@ int trtl_fw_name(struct trtl_dev *trtl,
unsigned int idx_hmq,
char *name, size_t len)
{
struct trtl_desc *wdesc = (struct trtl_desc *)trtl;
struct trtl_msg msg;
int err;
memset(&msg, 0, sizeof(struct trtl_msg));
msg.hdr.msg_id = TRTL_MSG_ID_NAME;
msg.hdr.seq = wdesc->seq;
msg.hdr.sync_id = msg.hdr.seq;
msg.hdr.flags = TRTL_HMQ_HEADER_FLAG_RPC;
err = trtl_msg_sync(trtl, idx_cpu, idx_hmq, &msg, &msg,
......@@ -68,14 +65,11 @@ int trtl_fw_version(struct trtl_dev *trtl,
unsigned int idx_hmq,
struct trtl_fw_version *version)
{
struct trtl_desc *wdesc = (struct trtl_desc *)trtl;
struct trtl_msg msg;
int err;
memset(&msg, 0, sizeof(struct trtl_msg));
msg.hdr.msg_id = TRTL_MSG_ID_VER;
msg.hdr.seq = wdesc->seq;
msg.hdr.sync_id = msg.hdr.seq;
msg.hdr.flags = TRTL_HMQ_HEADER_FLAG_RPC;
err = trtl_msg_sync(trtl, idx_cpu, idx_hmq, &msg, &msg,
......@@ -106,14 +100,11 @@ int trtl_fw_ping_timeout(struct trtl_dev *trtl,
unsigned int idx_hmq,
int timeout_ms)
{
struct trtl_desc *wdesc = (struct trtl_desc *)trtl;
struct trtl_msg msg;
int err;
memset(&msg, 0, sizeof(struct trtl_msg));
msg.hdr.msg_id = TRTL_MSG_ID_PING;
msg.hdr.seq = wdesc->seq;
msg.hdr.sync_id = msg.hdr.seq;
msg.hdr.flags = TRTL_HMQ_HEADER_FLAG_RPC;
err = trtl_msg_sync(trtl, idx_cpu, idx_hmq, &msg, &msg,
......@@ -150,14 +141,11 @@ static int __trtl_fw_variable(struct trtl_dev *trtl,
unsigned int n_variables,
uint8_t msg_id)
{
struct trtl_desc *wdesc = (struct trtl_desc *)trtl;
struct trtl_msg msg;
int err;
memset(&msg, 0, sizeof(struct trtl_msg));
msg.hdr.msg_id = msg_id;
msg.hdr.seq = wdesc->seq;
msg.hdr.sync_id = msg.hdr.seq;
msg.hdr.flags = TRTL_HMQ_HEADER_FLAG_RPC;
msg.hdr.len = 2 * n_variables;
......@@ -290,8 +278,6 @@ static int __trtl_fw_buffer(struct trtl_dev *trtl,
memset(&msg, 0, sizeof(struct trtl_msg));
msg.hdr.msg_id = msg_id;
msg.hdr.seq = wdesc->seq;
msg.hdr.sync_id = msg.hdr.seq;
msg.hdr.flags = TRTL_HMQ_HEADER_FLAG_RPC;
msg.hdr.len = total_size / sizeof(uint32_t);
......
......@@ -257,8 +257,6 @@ struct trtl_dev *trtl_open(const char *device)
}
}
trtl->seq = 0;
return (struct trtl_dev *)trtl;
out_hmq_fd:
......@@ -999,8 +997,7 @@ int trtl_msg_sync_abort(struct trtl_dev *trtl,
}
/**
* Send and receive a synchronous message. It is up to the user to set the
* "sync_id" in the message that it would like to send.
* Send and receive a synchronous message.
* @param[in] trtl device token
* @param[in] idx_cpu CPU index
* @param[in] idx_hmq HMQ index
......
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