aboutsummaryrefslogtreecommitdiff
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
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>
-rw-r--r--core/hostservices.c62
-rw-r--r--hw/fsp/fsp.c2
-rw-r--r--hw/prd.c77
-rw-r--r--include/fsp.h6
-rw-r--r--include/hostservices.h2
-rw-r--r--include/skiboot.h1
-rw-r--r--platforms/ibm-fsp/zz.c1
7 files changed, 149 insertions, 2 deletions
diff --git a/core/hostservices.c b/core/hostservices.c
index bf1b308..d515f13 100644
--- a/core/hostservices.c
+++ b/core/hostservices.c
@@ -879,3 +879,65 @@ 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 | (uint8_t)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 notification message. 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;
+ }
+
+ if (prd_hbrt_fsp_msg_notify(buf, len))
+ hservice_hbrt_msg_response(FSP_STATUS_GENERIC_FAILURE);
+
+ 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 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)
{
diff --git a/include/fsp.h b/include/fsp.h
index 7518867..cfa51af 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 8c54935..bdff9da 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 0a7c84a..d70d828 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 int 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 29dd608..705906a 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) = {