summaryrefslogtreecommitdiffstats
path: root/external
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2017-12-07 10:52:29 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-14 23:58:26 -0600
commit781b10633945df32fa2292ee8b196c74f8ef2c7c (patch)
treef712cc950095181c690dd34f0a42b5a5c11a0734 /external
parent49999302251b3e3e2fdca2cbcdeb6aab9add7412 (diff)
downloadblackbird-skiboot-781b10633945df32fa2292ee8b196c74f8ef2c7c.tar.gz
blackbird-skiboot-781b10633945df32fa2292ee8b196c74f8ef2c7c.zip
opal-prd: occ: Add support for runtime OCC load/start in ZZ
This patch adds support to handle OCC load/start event from FSP/PRD. During IPL we send a success directly to FSP without invoking any HBRT load routines on recieving OCC load mbox message from FSP. At runtime we forward this event to host opal-prd. This patch provides support for invoking OCC load/start HBRT routines like load_pm_complex() and start_pm_complex() from opal-prd. Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'external')
-rw-r--r--external/opal-prd/opal-prd.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c
index fb573e4f..5a15f1d2 100644
--- a/external/opal-prd/opal-prd.c
+++ b/external/opal-prd/opal-prd.c
@@ -306,6 +306,8 @@ extern int call_sbe_message_passing(uint32_t i_chipId);
extern uint64_t call_get_ipoll_events(void);
extern int call_firmware_notify(uint64_t len, void *data);
extern int call_reset_pm_complex(uint64_t chip);
+extern int call_load_pm_complex(u64 chip, u64 homer, u64 occ_common, u32 mode);
+extern int call_start_pm_complex(u64 chip);
void hservice_puts(const char *str)
{
@@ -1421,6 +1423,61 @@ static int handle_msg_occ_error(struct opal_prd_ctx *ctx,
return 0;
}
+static int pm_complex_load_start(void)
+{
+ struct prd_range *range;
+ u64 homer, occ_common;
+ int rc = -1, i;
+
+ if (!hservice_runtime->load_pm_complex) {
+ pr_log_nocall("load_pm_complex");
+ return rc;
+ }
+
+ if (!hservice_runtime->start_pm_complex) {
+ pr_log_nocall("start_pm_complex");
+ return rc;
+ }
+
+ range = find_range("ibm,occ-common-area", 0);
+ if (!range) {
+ pr_log(LOG_ERR, "PM: ibm,occ-common-area not found");
+ return rc;
+ }
+ occ_common = range->physaddr;
+
+ for (i = 0; i < nr_chips; i++) {
+ range = find_range("ibm,homer-image", chips[i]);
+ if (!range) {
+ pr_log(LOG_ERR, "PM: ibm,homer-image not found 0x%lx",
+ chips[i]);
+ return -1;
+ }
+ homer = range->physaddr;
+
+ pr_debug("PM: calling load_pm_complex(0x%lx, 0x%lx, 0x%lx, LOAD)",
+ chips[i], homer, occ_common);
+ rc = call_load_pm_complex(chips[i], homer, occ_common, 0);
+ if (rc) {
+ pr_log(LOG_ERR, "PM: Failed load_pm_complex(0x%lx) %m",
+ chips[i]);
+ return rc;
+ }
+ }
+
+ for (i = 0; i < nr_chips; i++) {
+ pr_debug("PM: calling start_pm_complex(0x%lx)", chips[i]);
+ rc = call_start_pm_complex(chips[i]);
+ if (rc) {
+ pr_log(LOG_ERR, "PM: Failed start_pm_complex(0x%lx): %m",
+ chips[i]);
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
static int pm_complex_reset(uint64_t chip)
{
int rc;
@@ -1430,13 +1487,24 @@ static int pm_complex_reset(uint64_t chip)
* BMC system -> process_occ_reset
*/
if (is_fsp_system()) {
+ int i;
+
if (!hservice_runtime->reset_pm_complex) {
pr_log_nocall("reset_pm_complex");
return -1;
}
- pr_debug("PM: calling pm_complex_reset(%ld)", chip);
- rc = call_reset_pm_complex(chip);
+ for (i = 0; i < nr_chips; i++) {
+ pr_debug("PM: calling pm_complex_reset(%ld)", chips[i]);
+ rc = call_reset_pm_complex(chip);
+ if (rc) {
+ pr_log(LOG_ERR, "PM: Failed pm_complex_reset(%ld): %m",
+ chips[i]);
+ return rc;
+ }
+ }
+
+ rc = pm_complex_load_start();
} else {
if (!hservice_runtime->process_occ_reset) {
pr_log_nocall("process_occ_reset");
@@ -1542,6 +1610,27 @@ static int handle_msg_fsp_occ_reset(struct opal_prd_msg *msg)
return rc;
}
+static int handle_msg_fsp_occ_load_start(struct opal_prd_msg *msg)
+{
+ struct opal_prd_msg omsg;
+ int rc;
+
+ pr_debug("FW: FSP requested OCC load/start");
+ rc = pm_complex_load_start();
+
+ omsg.hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START_STATUS;
+ omsg.hdr.size = htobe16(sizeof(omsg));
+ omsg.fsp_occ_reset_status.chip = msg->occ_reset.chip;
+ omsg.fsp_occ_reset_status.status = htobe64(rc);
+
+ if (write(ctx->fd, &omsg, sizeof(omsg)) != sizeof(omsg)) {
+ pr_log(LOG_ERR, "FW: Failed to send FSP_OCC_LOAD_START_STATUS msg: %m");
+ return -1;
+ }
+
+ return rc;
+}
+
static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
{
int rc = -1;
@@ -1565,6 +1654,9 @@ static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET:
rc = handle_msg_fsp_occ_reset(msg);
break;
+ case OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START:
+ rc = handle_msg_fsp_occ_load_start(msg);
+ break;
default:
pr_log(LOG_WARNING, "Invalid incoming message type 0x%x",
msg->hdr.type);
OpenPOWER on IntegriCloud