diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2017-12-07 10:52:28 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-12-14 23:58:26 -0600 |
commit | 49999302251b3e3e2fdca2cbcdeb6aab9add7412 (patch) | |
tree | 741a3a2a01880bf2ab8925b15f863d1d8d46f56d /hw | |
parent | 5d847a1b9d495a4b09f675677ffc75a02a8f210a (diff) | |
download | skiboot-49999302251b3e3e2fdca2cbcdeb6aab9add7412.zip skiboot-49999302251b3e3e2fdca2cbcdeb6aab9add7412.tar.gz skiboot-49999302251b3e3e2fdca2cbcdeb6aab9add7412.tar.bz2 |
opal-prd: Add support for runtime OCC reset in ZZ
This patch handles OCC_RESET runtime events in host opal-prd and also
provides support for calling 'hostinterface->wakeup()' which is
required for doing the reset operation.
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Acked-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/occ.c | 51 | ||||
-rw-r--r-- | hw/prd.c | 21 |
2 files changed, 71 insertions, 1 deletions
@@ -1843,6 +1843,44 @@ out: return rc; } +static u32 last_seq_id; + +int fsp_occ_reset_status(u64 chipid, s64 status) +{ + struct fsp_msg *stat; + int rc = OPAL_NO_MEM; + int status_word = 0; + + prlog(PR_INFO, "HBRT: OCC stop() completed with %lld\n", status); + + if (status) { + struct proc_chip *chip = get_chip(chipid); + + if (!chip) + return OPAL_PARAMETER; + + status_word = 0xfe00 | (chip->pcid & 0xff); + log_simple_error(&e_info(OPAL_RC_OCC_RESET), + "OCC: Error %lld in OCC reset of chip %lld\n", + status, chipid); + } else { + occ_msg_queue_occ_reset(); + } + + stat = fsp_mkmsg(FSP_CMD_RESET_OCC_STAT, 2, status_word, last_seq_id); + if (!stat) + return rc; + + rc = fsp_queue_msg(stat, fsp_freemsg); + if (rc) { + fsp_freemsg(stat); + log_simple_error(&e_info(OPAL_RC_OCC_RESET), + "OCC: Error %d queueing FSP OCC RESET STATUS message\n", + rc); + } + return rc; +} + static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) { struct fsp_msg *rsp, *stat; @@ -1883,7 +1921,18 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) * FSP will request OCC to left in stopped state. */ - rc = host_services_occ_stop(); + switch (proc_gen) { + case proc_gen_p8: + rc = host_services_occ_stop(); + break; + case proc_gen_p9: + last_seq_id = seq_id; + chip = next_chip(NULL); + prd_fsp_occ_reset(chip->id); + return; + default: + return; + } /* Handle fallback to preload */ if (rc == -ENOENT && chip->homer_base) { @@ -30,6 +30,7 @@ enum events { EVENT_OCC_ERROR = 1 << 1, EVENT_OCC_RESET = 1 << 2, EVENT_SBE_PASSTHROUGH = 1 << 3, + EVENT_FSP_OCC_RESET = 1 << 4, }; static uint8_t events[MAX_CHIPS]; @@ -115,6 +116,10 @@ static void prd_msg_consumed(void *data) proc = msg->sbe_passthrough.chip; event = EVENT_SBE_PASSTHROUGH; break; + case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET: + proc = msg->occ_reset.chip; + event = EVENT_FSP_OCC_RESET; + break; default: prlog(PR_ERR, "PRD: invalid msg consumed, type: 0x%x\n", msg->hdr.type); @@ -189,6 +194,9 @@ static void send_next_pending_event(void) } else if (event & EVENT_SBE_PASSTHROUGH) { prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH; prd_msg->sbe_passthrough.chip = proc; + } else if (event & EVENT_FSP_OCC_RESET) { + prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_RESET; + prd_msg->occ_reset.chip = proc; } /* @@ -275,6 +283,11 @@ void prd_occ_reset(uint32_t proc) prd_event(proc, EVENT_OCC_RESET); } +void prd_fsp_occ_reset(uint32_t proc) +{ + prd_event(proc, EVENT_FSP_OCC_RESET); +} + void prd_sbe_passthrough(uint32_t proc) { prd_event(proc, EVENT_SBE_PASSTHROUGH); @@ -431,6 +444,14 @@ static int64_t opal_prd_msg(struct opal_prd_msg *msg) case OPAL_PRD_MSG_TYPE_FIRMWARE_REQUEST: rc = prd_msg_handle_firmware_req(msg); break; + case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET_STATUS: + rc = fsp_occ_reset_status(msg->fsp_occ_reset_status.chip, + msg->fsp_occ_reset_status.status); + break; + case OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP: + rc = hservice_wakeup(msg->spl_wakeup.core, + msg->spl_wakeup.mode); + break; default: rc = OPAL_UNSUPPORTED; } |