[Skiboot] [PATCH 6/7] prd: Implement generic FSP - HBRT interface
Vasant Hegde
hegdevasant at linux.vnet.ibm.com
Thu Mar 28 22:18:20 AEDT 2019
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 at linux.vnet.ibm.com>
---
core/hostservices.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
hw/fsp/fsp.c | 2 ++
hw/prd.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
include/fsp.h | 6 ++++-
include/hostservices.h | 2 ++
include/skiboot.h | 1 +
platforms/ibm-fsp/zz.c | 1 +
7 files changed, 126 insertions(+), 1 deletion(-)
diff --git a/core/hostservices.c b/core/hostservices.c
index cb307e848..fbb399b9d 100644
--- a/core/hostservices.c
+++ b/core/hostservices.c
@@ -879,3 +879,63 @@ out_tce_unmap:
fsp_tce_unmap(PSI_DMA_HBRT_FSP_MSG, PSI_DMA_HBRT_FSP_MSG_SIZE);
return rc;
}
+
+void hservice_hbrt_msg_response(uint32_t rc)
+{
+ struct fsp_msg *resp;
+
+ resp = fsp_mkmsg(FSP_RSP_FSP_TO_HBRT | rc, 0);
+ if (!resp) {
+ prlog(PR_DEBUG,
+ "HBRT: Failed to allocate FSP - HBRT response message\n");
+ return;
+ }
+
+ if (fsp_queue_msg(resp, fsp_freemsg)) {
+ prlog(PR_DEBUG,
+ "HBRT: Failed to send FSP - HBRT response message\n");
+ fsp_freemsg(resp);
+ return;
+ }
+}
+
+/* FSP sends HBRT message notification. Pass this message to HBRT */
+static bool hservice_hbrt_msg_notify(uint32_t cmd_sub_mod, struct fsp_msg *msg)
+{
+ u32 tce_token, len;
+ void *buf;
+
+ if (cmd_sub_mod != FSP_CMD_FSP_TO_HBRT)
+ return false;
+
+ prlog(PR_TRACE, "HBRT: FSP - HBRT message generated\n");
+
+ tce_token = msg->data.words[1];
+ len = msg->data.words[2];
+ buf = fsp_inbound_buf_from_tce(tce_token);
+ if (!buf) {
+ prlog(PR_DEBUG, "HBRT: Invalid inbound data\n");
+ hservice_hbrt_msg_response(FSP_STATUS_INVALID_DATA);
+ return true;
+ }
+
+ prd_hbrt_fsp_msg_notify(buf, len);
+ return true;
+}
+
+static struct fsp_client fsp_hbrt_msg_client = {
+ .message = hservice_hbrt_msg_notify,
+};
+
+/* Register for FSP 0xF2 class messages */
+void hservice_fsp_init(void)
+{
+ if (proc_gen < proc_gen_p9)
+ return;
+
+ if (!fsp_present())
+ return;
+
+ /* Register for Class F2 */
+ fsp_register_client(&fsp_hbrt_msg_client, FSP_MCLASS_HBRT);
+}
diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index f7e674830..8fe2aed2d 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 d032d42ca..8333dbf3b 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;
@@ -118,6 +119,13 @@ static void prd_msg_consumed(void *data)
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;
+ }
+ hservice_hbrt_msg_response(OPAL_SUCCESS);
+ break;
case OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH:
proc = msg->sbe_passthrough.chip;
event = EVENT_SBE_PASSTHROUGH;
@@ -344,6 +352,53 @@ void prd_fw_resp_fsp_response(int status)
unlock(&events_lock);
}
+void prd_hbrt_fsp_msg_notify(void *data, u32 dsize)
+{
+ int size, rc;
+
+ if (!prd_enabled || !prd_active) {
+ prlog(PR_NOTICE, "PRD: PRD daemon is not ready\n");
+ hservice_hbrt_msg_response(FSP_STATUS_GENERIC_FAILURE);
+ return;
+ }
+
+ /* Calculate prd message size */
+ size = sizeof(prd_msg->hdr) + sizeof(prd_msg->token) +
+ sizeof(prd_msg->fw_notify) + dsize;
+
+ lock(&events_lock);
+
+ /* Handle message allocation part */
+ if (prd_msg_fsp_notify) {
+ prlog(PR_DEBUG, "PRD: FSP - HBRT notify message is busy\n");
+ hservice_hbrt_msg_response(FSP_STATUS_GENERIC_FAILURE);
+ goto unlock_events;
+ }
+
+ prd_msg_fsp_notify = zalloc(size);
+ if (!prd_msg_fsp_notify) {
+ prlog(PR_DEBUG,
+ "PRD: %s: Failed to allocate memory\n", __func__);
+ hservice_hbrt_msg_response(FSP_STATUS_GENERIC_FAILURE);
+ goto unlock_events;
+ }
+
+ prd_msg_fsp_notify->hdr.size = size;
+ prd_msg_fsp_notify->hdr.type = OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY;
+ 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);
+
+ rc = opal_queue_msg_extended(OPAL_MSG_PRD, prd_msg_fsp_notify,
+ prd_msg_consumed, size,
+ prd_msg_fsp_notify);
+ if (!rc)
+ prd_msg_inuse = true;
+
+unlock_events:
+ unlock(&events_lock);
+}
+
/* incoming message handlers */
static int prd_msg_handle_attn_ack(struct opal_prd_msg *msg)
{
diff --git a/include/fsp.h b/include/fsp.h
index 751886703..cfa51afbc 100644
--- a/include/fsp.h
+++ b/include/fsp.h
@@ -296,7 +296,9 @@
#define FSP_MCLASS_DIAG 0xee
#define FSP_MCLASS_PCIE_LINK_TOPO 0xef
#define FSP_MCLASS_OCC 0xf0
-#define FSP_MCLASS_LAST 0xf0
+#define FSP_MCLASS_TRUSTED_BOOT 0xf1
+#define FSP_MCLASS_HBRT 0xf2
+#define FSP_MCLASS_LAST 0xf2
/*
* Commands are provided in rxxyyzz form where:
@@ -584,6 +586,8 @@
* Class F2
*/
#define FSP_CMD_HBRT_TO_FSP 0x1f20100 /* HV->FSP: HBRT message */
+#define FSP_CMD_FSP_TO_HBRT 0x0f20200 /* FSP->HV: HBRT message */
+#define FSP_RSP_FSP_TO_HBRT 0x0f28200 /* HV->FSP: HBRT message */
/*
diff --git a/include/hostservices.h b/include/hostservices.h
index 8c54935d7..bdff9daec 100644
--- a/include/hostservices.h
+++ b/include/hostservices.h
@@ -43,5 +43,7 @@ int hservice_wakeup(uint32_t i_core, uint32_t i_mode);
int fsp_occ_reset_status(u64 chipid, s64 status);
int fsp_occ_load_start_status(u64 chipid, s64 status);
int hservice_send_hbrt_msg(void *data, u64 dsize);
+void hservice_hbrt_msg_response(uint32_t rc);
+void hservice_fsp_init(void);
#endif /* __HOSTSERVICES_H */
diff --git a/include/skiboot.h b/include/skiboot.h
index 0a7c84a8b..68a983080 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -292,6 +292,7 @@ extern void prd_register_reserved_memory(void);
extern void prd_fsp_occ_reset(uint32_t proc);
extern void prd_fsp_occ_load_start(u32 proc);
extern void prd_fw_resp_fsp_response(int status);
+extern void prd_hbrt_fsp_msg_notify(void *data, u32 dsize);
/* Flatten device-tree */
extern void *create_dtb(const struct dt_node *root, bool exclusive);
diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c
index 29dd6089d..705906a04 100644
--- a/platforms/ibm-fsp/zz.c
+++ b/platforms/ibm-fsp/zz.c
@@ -66,6 +66,7 @@ static uint32_t ibm_fsp_occ_timeout(void)
static void zz_init(void)
{
ibm_fsp_init();
+ hservice_fsp_init();
}
DECLARE_PLATFORM(zz) = {
--
2.14.3
More information about the Skiboot
mailing list