aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2019-05-28 11:17:26 +0530
committerStewart Smith <stewart@linux.ibm.com>2019-06-03 10:28:57 +1000
commiteb86b1484f5442cc2fc78b7c60ff504647318ca2 (patch)
tree5b81ea7b17b6e6acc19628f8f5079cdf949332c6 /hw
parentfb702bf01aeabab92d3830d90c8060e5cbd57258 (diff)
downloadskiboot-eb86b1484f5442cc2fc78b7c60ff504647318ca2.zip
skiboot-eb86b1484f5442cc2fc78b7c60ff504647318ca2.tar.gz
skiboot-eb86b1484f5442cc2fc78b7c60ff504647318ca2.tar.bz2
prd: Implement generic FSP - HBRT interface
This patch implements generic interface to pass data from FSP to HBRT during runtime (FSP -> OPAL -> opal-prd -> HBRT). OPAL gets notification from FSP for new HBRT messages. We will convert MBOX message to firmware_notify format and send it to HBRT. Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/fsp/fsp.c2
-rw-r--r--hw/prd.c77
2 files changed, 78 insertions, 1 deletions
diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index f7e6748..8fe2aed 100644
--- a/hw/fsp/fsp.c
+++ b/hw/fsp/fsp.c
@@ -178,6 +178,8 @@ static struct fsp_cmdclass fsp_cmdclass[FSP_MCLASS_LAST - FSP_MCLASS_FIRST + 1]
DEF_CLASS(FSP_MCLASS_DIAG, 16),
DEF_CLASS(FSP_MCLASS_PCIE_LINK_TOPO, 16),
DEF_CLASS(FSP_MCLASS_OCC, 16),
+ DEF_CLASS(FSP_MCLASS_TRUSTED_BOOT, 2),
+ DEF_CLASS(FSP_MCLASS_HBRT, 2),
};
static void fsp_trace_msg(struct fsp_msg *msg, u8 dir __unused)
diff --git a/hw/prd.c b/hw/prd.c
index 042d977..fea8cf0 100644
--- a/hw/prd.c
+++ b/hw/prd.c
@@ -40,6 +40,7 @@ static uint8_t _prd_msg_buf[sizeof(struct opal_prd_msg) +
sizeof(struct prd_fw_msg)];
static struct opal_prd_msg *prd_msg = (struct opal_prd_msg *)&_prd_msg_buf;
static struct opal_prd_msg *prd_msg_fsp_req;
+static struct opal_prd_msg *prd_msg_fsp_notify;
static bool prd_msg_inuse, prd_active;
static struct dt_node *prd_node;
static bool prd_enabled = false;
@@ -82,10 +83,11 @@ static uint64_t prd_ipoll_mask;
static void send_next_pending_event(void);
-static void prd_msg_consumed(void *data, int status __unused)
+static void prd_msg_consumed(void *data, int status)
{
struct opal_prd_msg *msg = data;
uint32_t proc;
+ int notify_status = OPAL_SUCCESS;
uint8_t event = 0;
lock(&events_lock);
@@ -118,6 +120,18 @@ static void prd_msg_consumed(void *data, int status __unused)
prd_msg_fsp_req = NULL;
}
break;
+ case OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY:
+ if (prd_msg_fsp_notify) {
+ free(prd_msg_fsp_notify);
+ prd_msg_fsp_notify = NULL;
+ }
+ if (status != 0) {
+ prlog(PR_DEBUG,
+ "PRD: Failed to send FSP -> HBRT message\n");
+ notify_status = FSP_STATUS_GENERIC_FAILURE;
+ }
+ hservice_hbrt_msg_response(notify_status);
+ break;
case OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH:
proc = msg->sbe_passthrough.chip;
event = EVENT_SBE_PASSTHROUGH;
@@ -356,6 +370,67 @@ void prd_fw_resp_fsp_response(int status)
unlock(&events_lock);
}
+int prd_hbrt_fsp_msg_notify(void *data, u32 dsize)
+{
+ int size;
+ int rc = FSP_STATUS_GENERIC_FAILURE;
+ enum opal_msg_type msg_type = OPAL_MSG_PRD2;
+
+ if (!prd_enabled || !prd_active) {
+ prlog(PR_NOTICE, "PRD: PRD daemon is not ready\n");
+ return rc;
+ }
+
+ /* Calculate prd message size */
+ size = sizeof(prd_msg->hdr) + sizeof(prd_msg->token) +
+ sizeof(prd_msg->fw_notify) + dsize;
+
+ if (size > OPAL_PRD_MSG_SIZE_MAX) {
+ prlog(PR_DEBUG, "PRD: FSP - HBRT notify message size (0x%x)"
+ " is bigger than prd interface can handle\n", size);
+ return rc;
+ }
+
+ lock(&events_lock);
+
+ /* FSP - HBRT messages are serialized */
+ if (prd_msg_fsp_notify) {
+ prlog(PR_DEBUG, "PRD: FSP - HBRT notify message is busy\n");
+ goto unlock_events;
+ }
+
+ /* Handle message allocation */
+ prd_msg_fsp_notify = zalloc(size);
+ if (!prd_msg_fsp_notify) {
+ prlog(PR_DEBUG,
+ "PRD: %s: Failed to allocate memory.\n", __func__);
+ goto unlock_events;
+ }
+
+ prd_msg_fsp_notify->hdr.type = OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY;
+ prd_msg_fsp_notify->hdr.size = cpu_to_be16(size);
+ prd_msg_fsp_notify->token = 0;
+ prd_msg_fsp_notify->fw_notify.len = cpu_to_be64(dsize);
+ memcpy(&(prd_msg_fsp_notify->fw_notify.data), data, dsize);
+
+ /*
+ * If prd message size is <= OPAL_MSG_FIXED_PARAMS_SIZE then use
+ * OPAL_MSG_PRD to pass data to kernel. So that it works fine on
+ * older kernel (which does not support OPAL_MSG_PRD2).
+ */
+ if (prd_msg_fsp_notify->hdr.size < OPAL_MSG_FIXED_PARAMS_SIZE)
+ msg_type = OPAL_MSG_PRD;
+
+ rc = _opal_queue_msg(msg_type, prd_msg_fsp_notify,
+ prd_msg_consumed, size, prd_msg_fsp_notify);
+ if (!rc)
+ prd_msg_inuse = true;
+
+unlock_events:
+ unlock(&events_lock);
+ return rc;
+}
+
/* incoming message handlers */
static int prd_msg_handle_attn_ack(struct opal_prd_msg *msg)
{