diff options
author | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2019-05-28 11:17:26 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2019-06-03 10:28:57 +1000 |
commit | eb86b1484f5442cc2fc78b7c60ff504647318ca2 (patch) | |
tree | 5b81ea7b17b6e6acc19628f8f5079cdf949332c6 /hw | |
parent | fb702bf01aeabab92d3830d90c8060e5cbd57258 (diff) | |
download | skiboot-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.c | 2 | ||||
-rw-r--r-- | hw/prd.c | 77 |
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) @@ -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) { |