#define FLCN_DBG(f,fmt,a...) FLCN_PRINTK(debug, (f), fmt, ##a)
#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK(error, (f), fmt, ##a)
+/**
+ * struct nv_falcon_msg - header for all messages
+ *
+ * @unit_id: id of firmware process that sent the message
+ * @size: total size of message
+ * @ctrl_flags: control flags
+ * @seq_id: used to match a message from its corresponding command
+ */
+struct nv_falcon_msg {
+ u8 unit_id;
+ u8 size;
+ u8 ctrl_flags;
+ u8 seq_id;
+};
+
struct nvkm_falcon_qmgr;
int nvkm_falcon_qmgr_new(struct nvkm_falcon *, struct nvkm_falcon_qmgr **);
void nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **);
+typedef int
+(*nvkm_falcon_qmgr_callback)(void *priv, struct nv_falcon_msg *);
+
struct nvkm_falcon_cmdq;
int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_cmdq **);
int
nvkm_msgqueue_post(struct nvkm_msgqueue *priv, enum msgqueue_msg_priority prio,
- struct nvkm_msgqueue_hdr *cmd, nvkm_msgqueue_callback cb,
+ struct nvkm_msgqueue_hdr *cmd, nvkm_falcon_qmgr_callback cb,
struct completion *completion, bool wait_init)
{
struct nvkm_msgqueue_seq *seq;
cmd->ctrl_flags = CMD_FLAGS_STATUS | CMD_FLAGS_INTR;
seq->callback = cb;
+ seq->priv = priv;
seq->state = SEQ_STATE_USED;
seq->completion = completion;
static int
msg_queue_read(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_queue *queue,
- struct nvkm_msgqueue_hdr *hdr)
+ struct nv_falcon_msg *hdr)
{
const struct nvkm_subdev *subdev = priv->falcon->owner;
int ret;
static int
msgqueue_msg_handle(struct nvkm_msgqueue *priv,
struct nvkm_falcon_msgq *msgq,
- struct nvkm_msgqueue_hdr *hdr)
+ struct nv_falcon_msg *hdr)
{
const struct nvkm_subdev *subdev = priv->falcon->owner;
struct nvkm_msgqueue_seq *seq;
if (seq->state == SEQ_STATE_USED) {
if (seq->callback)
- seq->callback(priv, hdr);
+ seq->result = seq->callback(seq->priv, hdr);
}
if (seq->completion)
}
static int
-msgqueue_handle_init_msg(struct nvkm_msgqueue *priv,
- struct nvkm_msgqueue_hdr *hdr)
+msgqueue_handle_init_msg(struct nvkm_msgqueue *priv)
{
struct nvkm_falcon *falcon = priv->falcon;
const struct nvkm_subdev *subdev = falcon->owner;
const u32 tail_reg = falcon->func->msgq.tail;
+ u8 msg_buffer[MSG_BUF_SIZE];
+ struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
u32 tail;
int ret;
* stack space to work with.
*/
u8 msg_buffer[MSG_BUF_SIZE];
- struct nvkm_msgqueue_hdr *hdr = (void *)msg_buffer;
+ struct nv_falcon_msg *hdr = (void *)msg_buffer;
int ret;
/* the first message we receive must be the init message */
if ((!priv->init_msg_received)) {
- ret = msgqueue_handle_init_msg(priv, hdr);
+ ret = msgqueue_handle_init_msg(priv);
if (!ret)
priv->init_msg_received = true;
} else {
#ifndef __NVKM_CORE_FALCON_MSGQUEUE_H
#define __NVKM_CORE_FALCON_MSGQUEUE_H
-
+#include <core/falcon.h>
#include <core/msgqueue.h>
/*
};
struct nvkm_msgqueue;
-typedef void
-(*nvkm_msgqueue_callback)(struct nvkm_msgqueue *, struct nvkm_msgqueue_hdr *);
/**
* struct nvkm_msgqueue_init_func - msgqueue functions related to initialization
void nvkm_msgqueue_ctor(const struct nvkm_msgqueue_func *, struct nvkm_falcon *,
struct nvkm_msgqueue *);
int nvkm_msgqueue_post(struct nvkm_msgqueue *, enum msgqueue_msg_priority,
- struct nvkm_msgqueue_hdr *, nvkm_msgqueue_callback,
+ struct nvkm_msgqueue_hdr *, nvkm_falcon_qmgr_callback,
struct completion *, bool);
void nvkm_msgqueue_process_msgs(struct nvkm_msgqueue *,
struct nvkm_msgqueue_queue *);
ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS = 0x03,
};
-static void
-acr_init_wpr_callback(struct nvkm_msgqueue *queue,
- struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_init_wpr_callback(void *priv, struct nv_falcon_msg *hdr)
{
+ struct nvkm_msgqueue *queue = priv;
struct {
- struct nvkm_msgqueue_msg base;
+ struct nv_falcon_msg base;
+ u8 msg_type;
u32 error_code;
} *msg = (void *)hdr;
const struct nvkm_subdev *subdev = queue->falcon->owner;
if (msg->error_code) {
nvkm_error(subdev, "ACR WPR init failure: %d\n",
msg->error_code);
- return;
+ return -EINVAL;
}
nvkm_debug(subdev, "ACR WPR init complete\n");
complete_all(&queue->init_done);
+ return 0;
}
static int
}
-static void
-acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
- struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
{
+ struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg {
- struct nvkm_msgqueue_msg base;
-
+ struct nv_falcon_msg base;
+ u8 msg_type;
u32 falcon_id;
} *msg = (void *)hdr;
const struct nvkm_subdev *subdev = priv->falcon->owner;
if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id);
- return;
+ return -EINVAL;
}
+
nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
+ return 0;
}
enum {
return 0;
}
-static void
-acr_boot_multiple_falcons_callback(struct nvkm_msgqueue *priv,
- struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_boot_multiple_falcons_callback(void *_priv, struct nv_falcon_msg *hdr)
{
+ struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg {
- struct nvkm_msgqueue_msg base;
-
+ struct nv_falcon_msg base;
+ u8 msg_type;
u32 falcon_mask;
} *msg = (void *)hdr;
const struct nvkm_subdev *subdev = priv->falcon->owner;
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon mask 0x%x\n",
msg->falcon_mask);
- return;
+ return -EINVAL;
}
+
+ return 0;
}
static int
ACR_CMD_BOOTSTRAP_FALCON = 0x00,
};
-static void
-acr_boot_falcon_callback(struct nvkm_msgqueue *priv,
- struct nvkm_msgqueue_hdr *hdr)
+static int
+acr_boot_falcon_callback(void *_priv, struct nv_falcon_msg *hdr)
{
+ struct nvkm_msgqueue *priv = _priv;
struct acr_bootstrap_falcon_msg {
- struct nvkm_msgqueue_msg base;
-
+ struct nv_falcon_msg base;
+ u8 msg_type;
u32 error_code;
u32 falcon_id;
} *msg = (void *)hdr;
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "expected error code 0x%x\n",
msg->error_code);
- return;
+ return -EINVAL;
}
if (falcon_id >= NVKM_SECBOOT_FALCON_END) {
nvkm_error(subdev, "in bootstrap falcon callback:\n");
nvkm_error(subdev, "invalid falcon ID 0x%x\n", falcon_id);
- return;
+ return -EINVAL;
}
nvkm_debug(subdev, "%s booted\n", nvkm_secboot_falcon_name[falcon_id]);
+ return 0;
}
enum {
#include <core/falcon.h>
#include "msgqueue.h"
-#define HDR_SIZE sizeof(struct nvkm_msgqueue_hdr)
+#define HDR_SIZE sizeof(struct nv_falcon_msg)
#define QUEUE_ALIGNMENT 4
/* max size of the messages we can receive */
#define MSG_BUF_SIZE 128
SEQ_STATE_USED,
SEQ_STATE_CANCELLED
} state;
- nvkm_msgqueue_callback callback;
+ nvkm_falcon_qmgr_callback callback;
+ void *priv;
struct completion *completion;
+ int result;
};
/*