From patchwork Fri Nov 17 07:22:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shilpasri G Bhat X-Patchwork-Id: 838881 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ydV266vYrz9s5L for ; Fri, 17 Nov 2017 18:22:54 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3ydV265nfQzDqyR for ; Fri, 17 Nov 2017 18:22:54 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=shilpa.bhat@linux.vnet.ibm.com; receiver=) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3ydV1p56ZSzDrK5 for ; Fri, 17 Nov 2017 18:22:38 +1100 (AEDT) Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vAH7M2Aw104002 for ; Fri, 17 Nov 2017 02:22:36 -0500 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 2e9tr5shde-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 17 Nov 2017 02:22:36 -0500 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 17 Nov 2017 07:22:33 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 17 Nov 2017 07:22:30 -0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vAH7MUNV26148876; Fri, 17 Nov 2017 07:22:30 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EBE31A4053; Fri, 17 Nov 2017 07:17:19 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 485B0A4040; Fri, 17 Nov 2017 07:17:19 +0000 (GMT) Received: from oc4502181600.in.ibm.com (unknown [9.124.35.51]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Fri, 17 Nov 2017 07:17:19 +0000 (GMT) From: Shilpasri G Bhat To: skiboot@lists.ozlabs.org Date: Fri, 17 Nov 2017 12:52:23 +0530 X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1510903344-31008-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> References: <1510903344-31008-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17111707-0020-0000-0000-000003CD6D0C X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17111707-0021-0000-0000-00004262A9FE Message-Id: <1510903344-31008-2-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-11-17_02:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1711170098 Subject: [Skiboot] [PATCH 1/2] opal-prd: Add support for runtime OCC reset in ZZ X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" 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 Reviewed-by: Vasant Hegde --- core/direct-controls.c | 31 +++++++++++++++++++++++++++-- core/hostservices.c | 30 ++++++++++++++++++++++++++++ external/opal-prd/opal-prd.c | 40 ++++++++++++++++++++++++++++++++++++- external/opal-prd/thunk.S | 2 +- hw/occ.c | 47 +++++++++++++++++++++++++++++++++++++++++++- hw/prd.c | 9 +++++++++ include/cpu.h | 4 ++++ include/hostservices.h | 1 + include/opal-api.h | 10 ++++++++++ include/skiboot.h | 2 ++ 10 files changed, 171 insertions(+), 5 deletions(-) diff --git a/core/direct-controls.c b/core/direct-controls.c index 512cb36..62f9824 100644 --- a/core/direct-controls.c +++ b/core/direct-controls.c @@ -220,7 +220,7 @@ static int p9_sreset_thread(struct cpu_thread *cpu) return 0; } -static int dctl_set_special_wakeup(struct cpu_thread *t) +int dctl_set_special_wakeup(struct cpu_thread *t) { struct cpu_thread *c = t->primary; int rc = OPAL_SUCCESS; @@ -238,7 +238,7 @@ static int dctl_set_special_wakeup(struct cpu_thread *t) return rc; } -static int dctl_clear_special_wakeup(struct cpu_thread *t) +int dctl_clear_special_wakeup(struct cpu_thread *t) { struct cpu_thread *c = t->primary; int rc = OPAL_SUCCESS; @@ -259,6 +259,33 @@ out: return rc; } +int dctl_clear_all_special_wakeup(void) +{ + struct proc_chip *chip; + struct cpu_thread *c; + int rc; + + if (proc_gen != proc_gen_p9) + return OPAL_UNSUPPORTED; + + for_each_chip(chip) + for_each_available_core_in_chip(c, chip->id) { + lock(&c->dctl_lock); + if (c->special_wakeup_count) { + rc = p9_core_clear_special_wakeup(c); + if (!rc) { + c->special_wakeup_count = 0; + } else { + unlock(&c->dctl_lock); + return rc; + } + } + unlock(&c->dctl_lock); + } + + return OPAL_SUCCESS; +} + static int dctl_stop(struct cpu_thread *t) { struct cpu_thread *c = t->primary; diff --git a/core/hostservices.c b/core/hostservices.c index dd8cae2..be5f6c2 100644 --- a/core/hostservices.c +++ b/core/hostservices.c @@ -755,6 +755,36 @@ static int hservice_wakeup(uint32_t i_core, uint32_t i_mode) } } +int hservice_wakeup_p9(u32 core, u32 mode) +{ + struct cpu_thread *cpu; + + core &= SPR_PIR_P9_MASK; + core <<= 2; + + switch (mode) { + case 0: /* Assert special wakeup */ + cpu = find_cpu_by_pir(core); + if (!cpu) + return OPAL_PARAMETER; + prlog(PR_DEBUG, "HBRT: Special wakeup assert for core 0x%x," + " count=%d\n", core, cpu->special_wakeup_count); + return dctl_set_special_wakeup(cpu); + case 1: /* Deassert special wakeup */ + cpu = find_cpu_by_pir(core); + if (!cpu) + return OPAL_PARAMETER; + prlog(PR_DEBUG, "HBRT: Special wakeup release for core" + " 0x%x, count=%d\n", core, cpu->special_wakeup_count); + return dctl_clear_special_wakeup(cpu); + case 2: /* Clear all special wakeups */ + prlog(PR_DEBUG, "HBRT: Special wakeup release for all cores\n"); + return dctl_clear_all_special_wakeup(); + default: + return OPAL_PARAMETER; + } +} + static struct host_interfaces hinterface = { .interface_version = HOSTBOOT_RUNTIME_INTERFACE_VERSION, .puts = hservice_puts, diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c index b15063f..3fb0459 100644 --- a/external/opal-prd/opal-prd.c +++ b/external/opal-prd/opal-prd.c @@ -524,6 +524,25 @@ int hservice_i2c_write(uint64_t i_master, uint16_t i_devAddr, i_offset, i_length, i_data); } +int hservice_wakeup(u32 core, u32 mode) +{ + int rc; + struct opal_prd_msg msg; + + msg.hdr.type = OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP; + msg.hdr.size = htobe16(sizeof(msg)); + msg.spl_wakeup.core = htobe32(core); + msg.spl_wakeup.mode = htobe32(mode); + + rc = write(ctx->fd, &msg, sizeof(msg)); + if (rc != sizeof(msg)) { + pr_log(LOG_ERR, "FW: Failed for core %x : %m\n", core); + return rc; + } + + return 0; +} + static void ipmi_init(struct opal_prd_ctx *ctx) { insert_module("ipmi_devintf"); @@ -1383,6 +1402,7 @@ static int pm_complex_reset(uint64_t chip) static int handle_msg_occ_reset(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg) { + struct opal_prd_msg omsg; uint32_t proc; int rc; @@ -1392,7 +1412,22 @@ static int handle_msg_occ_reset(struct opal_prd_ctx *ctx, rc = pm_complex_reset(proc); - return rc; + if (!is_fsp_system()) + return rc; + + /* Send only for zz */ + omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET_STATUS; + omsg.hdr.size = htobe16(sizeof(omsg)); + omsg.occ_reset_status.chip = htobe64(proc); + omsg.occ_reset_status.status = htobe64(rc); + + rc = write(ctx->fd, &omsg, sizeof(omsg)); + if (rc != sizeof(omsg)) { + pr_log(LOG_ERR, "FW: Failed to send OCC_RESET status message: %m"); + return rc; + } + + return 0; } static int handle_msg_firmware_notify(struct opal_prd_ctx *ctx, @@ -1988,6 +2023,9 @@ static int run_prd_daemon(struct opal_prd_ctx *ctx) hinterface.pnor_write = NULL; } + if (!is_fsp_system()) + hinterface.wakeup = NULL; + ipmi_init(ctx); pr_debug("HBRT: calling hservices_init"); diff --git a/external/opal-prd/thunk.S b/external/opal-prd/thunk.S index cca5890..ee3d7c3 100644 --- a/external/opal-prd/thunk.S +++ b/external/opal-prd/thunk.S @@ -183,7 +183,7 @@ hinterface: DISABLED_THUNK(hservice_lid_load) DISABLED_THUNK(hservice_lid_unload) CALLBACK_THUNK(hservice_get_reserved_mem) - DISABLED_THUNK(hservice_wakeup) + CALLBACK_THUNK(hservice_wakeup) CALLBACK_THUNK(hservice_nanosleep) DISABLED_THUNK(hservice_report_occ_failure) CALLBACK_THUNK(hservice_clock_gettime) diff --git a/hw/occ.c b/hw/occ.c index 78c6a6a..14f4880 100644 --- a/hw/occ.c +++ b/hw/occ.c @@ -1837,6 +1837,40 @@ 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; + + 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); + } + + 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; @@ -1877,7 +1911,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; + for_each_chip(chip) + prd_occ_reset(chip->id); + return; + default: + return; + } /* Handle fallback to preload */ if (rc == -ENOENT && chip->homer_base) { diff --git a/hw/prd.c b/hw/prd.c index c00e10a..253ad24 100644 --- a/hw/prd.c +++ b/hw/prd.c @@ -23,6 +23,7 @@ #include #include #include +#include enum events { EVENT_ATTN = 1 << 0, @@ -430,6 +431,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_OCC_RESET_STATUS: + rc = fsp_occ_reset_status(msg->occ_reset_status.chip, + msg->occ_reset_status.status); + break; + case OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP: + rc = hservice_wakeup_p9(msg->spl_wakeup.core, + msg->spl_wakeup.mode); + break; default: rc = OPAL_UNSUPPORTED; } diff --git a/include/cpu.h b/include/cpu.h index 168fa99..87c397f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -284,4 +284,8 @@ extern void cpu_idle_delay(unsigned long delay); extern void cpu_set_radix_mode(void); extern void cpu_fast_reboot_complete(void); +int dctl_set_special_wakeup(struct cpu_thread *t); +int dctl_clear_special_wakeup(struct cpu_thread *t); +int dctl_clear_all_special_wakeup(void); + #endif /* __CPU_H */ diff --git a/include/hostservices.h b/include/hostservices.h index 62ef04b..b7d54a0 100644 --- a/include/hostservices.h +++ b/include/hostservices.h @@ -40,4 +40,5 @@ int find_master_and_slave_occ(uint64_t **master, uint64_t **slave, int *nr_masters, int *nr_slaves); int hservice_send_error_log(uint32_t plid, uint32_t dsize, void *data); +int hservice_wakeup_p9(u32 core, u32 mode); #endif /* __HOSTSERVICES_H */ diff --git a/include/opal-api.h b/include/opal-api.h index 0bc036e..9c9d7fb 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -1054,6 +1054,8 @@ enum opal_prd_msg_type { OPAL_PRD_MSG_TYPE_FIRMWARE_RESPONSE, /* HBRT <-- OPAL */ OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY, /* HBRT <-- OPAL */ OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_OCC_RESET_STATUS, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP, /* HBRT --> OPAL */ }; struct opal_prd_msg_header { @@ -1101,6 +1103,14 @@ struct opal_prd_msg { struct { __be64 chip; } sbe_passthrough; + struct { + __be64 chip; + __be64 status; /* 0 SUCCESS */ + } occ_reset_status; + struct { + __be32 core; + __be32 mode; + } spl_wakeup; }; }; diff --git a/include/skiboot.h b/include/skiboot.h index db91325..221ed4b 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -333,4 +333,6 @@ extern int occ_sensor_group_clear(u32 group_hndl, int token); extern void occ_add_sensor_groups(struct dt_node *sg, u32 *phandles, int nr_phandles, int chipid); +extern int fsp_occ_reset_status(u64 chipid, s64 status); +extern int core_special_wakeup(u32 core, u32 mode); #endif /* __SKIBOOT_H */ From patchwork Fri Nov 17 07:22:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shilpasri G Bhat X-Patchwork-Id: 838882 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ydV2J33mPz9s5L for ; Fri, 17 Nov 2017 18:23:04 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3ydV2J2DCFzDrKN for ; Fri, 17 Nov 2017 18:23:04 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=shilpa.bhat@linux.vnet.ibm.com; receiver=) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3ydV1t5ZbLzDrKQ for ; Fri, 17 Nov 2017 18:22:42 +1100 (AEDT) Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vAH7Ikho041628 for ; Fri, 17 Nov 2017 02:22:40 -0500 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 2e9s3156n0-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 17 Nov 2017 02:22:40 -0500 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 17 Nov 2017 07:22:35 -0000 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 17 Nov 2017 07:22:33 -0000 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id vAH7MWcX66388064; Fri, 17 Nov 2017 07:22:32 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 30995A4057; Fri, 17 Nov 2017 07:17:22 +0000 (GMT) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3FF1AA4051; Fri, 17 Nov 2017 07:17:21 +0000 (GMT) Received: from oc4502181600.in.ibm.com (unknown [9.124.35.51]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Fri, 17 Nov 2017 07:17:21 +0000 (GMT) From: Shilpasri G Bhat To: skiboot@lists.ozlabs.org Date: Fri, 17 Nov 2017 12:52:24 +0530 X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1510903344-31008-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> References: <1510903344-31008-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17111707-0020-0000-0000-000003CD6D0F X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17111707-0021-0000-0000-00004262AA02 Message-Id: <1510903344-31008-3-git-send-email-shilpa.bhat@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-11-17_02:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1711170098 Subject: [Skiboot] [PATCH 2/2] opal-prd: occ: Add support for runtime OCC load/start in ZZ X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" 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 --- external/opal-prd/opal-prd.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ hw/occ.c | 66 +++++++++++++++++++++++++++++++------ hw/prd.c | 17 ++++++++++ include/opal-api.h | 2 ++ include/skiboot.h | 2 ++ 5 files changed, 155 insertions(+), 10 deletions(-) diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c index 3fb0459..6ffcac4 100644 --- a/external/opal-prd/opal-prd.c +++ b/external/opal-prd/opal-prd.c @@ -303,6 +303,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) { @@ -1471,6 +1473,79 @@ static int handle_msg_sbe_passthrough(struct opal_prd_ctx *ctx, return rc; } +static int pm_complex_load_start(struct opal_prd_ctx *ctx, + struct opal_prd_msg *msg) +{ + struct opal_prd_msg omsg; + struct prd_range *range; + u64 homer, occ_common; + u32 proc; + int rc; + + proc = be64toh(msg->occ_reset.chip); + pr_debug("FW: Firmware requested OCC load for proc 0x%x", proc); + + if (!hservice_runtime->load_pm_complex) { + pr_log_nocall("load_pm_complex"); + rc = -1; + goto out; + } + + if (!hservice_runtime->start_pm_complex) { + pr_log_nocall("start_pm_complex"); + rc = -1; + goto out; + } + + range = find_range("ibm,homer-image", proc); + if (!range) { + pr_log(LOG_ERR, "Homer image not found"); + rc = -1; + goto out; + } + + homer = range->physaddr; + range = NULL; + range = find_range("ibm,occ-common-area", 0); + if (!range) { + pr_log(LOG_ERR, "occ common area not found"); + rc = -1; + goto out; + } + occ_common = range->physaddr; + pr_debug("PM: calling load_pm_complex(0x%x, 0x%lx, 0x%lx, LOAD)", + proc, homer, occ_common); + + rc = call_load_pm_complex(proc, homer, occ_common, 0); + if (rc) { + pr_log(LOG_ERR, "PM: load_pm_complex(0x%x) failed %m", proc); + goto out; + } + + pr_debug("PM: calling start_pm_complex(0x%x)", proc); + rc = call_start_pm_complex(proc); + if (rc) + pr_log(LOG_ERR, "PM: start_pm_complex(0x%x) failed", proc); + +out: + if (!is_fsp_system()) + return rc; + + /* Send only for zz */ + omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_LOAD_START_STATUS; + omsg.hdr.size = htobe16(sizeof(omsg)); + omsg.occ_reset_status.chip = htobe64(proc); + omsg.occ_reset_status.status = htobe64(rc); + + rc = write(ctx->fd, &omsg, sizeof(omsg)); + if (rc != sizeof(omsg)) { + pr_log(LOG_ERR, "FW: Failed to send OCC_RESET status message: %m"); + return rc; + } + + return rc; +} + static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg) { int rc = -1; @@ -1491,6 +1566,9 @@ static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg) case OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH: rc = handle_msg_sbe_passthrough(ctx, msg); break; + case OPAL_PRD_MSG_TYPE_OCC_LOAD_START: + rc = pm_complex_load_start(ctx, msg); + break; default: pr_log(LOG_WARNING, "Invalid incoming message type 0x%x", msg->hdr.type); diff --git a/hw/occ.c b/hw/occ.c index 14f4880..8582faf 100644 --- a/hw/occ.c +++ b/hw/occ.c @@ -1748,6 +1748,8 @@ void occ_poke_load_queue(void) } } +static u32 last_seq_id; +static bool in_ipl = true; static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id) { struct fsp_msg *rsp; @@ -1780,15 +1782,29 @@ static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id) return; if (proc_gen == proc_gen_p9) { - rc = -ENOMEM; - /* OCC is pre-loaded in P9, so send SUCCESS to FSP */ - rsp = fsp_mkmsg(FSP_CMD_LOAD_OCC_STAT, 2, 0, seq_id); - if (rsp) + if (in_ipl) { + /* OCC is pre-loaded in P9, so send SUCCESS to FSP */ + rsp = fsp_mkmsg(FSP_CMD_LOAD_OCC_STAT, 2, 0, seq_id); + if (!rsp) + return; + rc = fsp_queue_msg(rsp, fsp_freemsg); - if (rc) { - log_simple_error(&e_info(OPAL_RC_OCC_LOAD), - "OCC: Error %d queueing FSP OCC LOAD STATUS msg", rc); - fsp_freemsg(rsp); + if (rc) { + log_simple_error(&e_info(OPAL_RC_OCC_LOAD), + "OCC: Error %d queueing OCC LOAD STATUS msg", + rc); + fsp_freemsg(rsp); + } + in_ipl = false; + } else { + struct proc_chip *chip; + + last_seq_id = seq_id; + for_each_chip(chip) { + if (scope == 0x1 && dbob_id != chip->dbob_id) + continue; + prd_occ_load_start(chip->id); + } } return; } @@ -1837,8 +1853,6 @@ out: return rc; } -static u32 last_seq_id; - int fsp_occ_reset_status(u64 chipid, s64 status) { struct fsp_msg *stat; @@ -1871,6 +1885,38 @@ int fsp_occ_reset_status(u64 chipid, s64 status) return rc; } +int fsp_occ_load_start_status(u64 chipid, s64 status) +{ + struct fsp_msg *stat; + int rc = OPAL_NO_MEM; + int status_word = 0; + + if (status) { + struct proc_chip *chip = get_chip(chipid); + + if (!chip) + return OPAL_PARAMETER; + + status_word = 0xB500 | (chip->pcid & 0xff); + log_simple_error(&e_info(OPAL_RC_OCC_LOAD), + "OCC: Error %d in load/start OCC %lld\n", rc, + chipid); + } + + stat = fsp_mkmsg(FSP_CMD_LOAD_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_LOAD), + "OCC: Error %d queueing FSP OCC LOAD STATUS msg", rc); + } + + return rc; +} + static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) { struct fsp_msg *rsp, *stat; diff --git a/hw/prd.c b/hw/prd.c index 253ad24..e426068 100644 --- a/hw/prd.c +++ b/hw/prd.c @@ -30,6 +30,7 @@ enum events { EVENT_OCC_ERROR = 1 << 1, EVENT_OCC_RESET = 1 << 2, EVENT_SBE_PASSTHROUGH = 1 << 3, + EVENT_OCC_LOAD_START = 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_OCC_LOAD_START: + proc = msg->occ_reset.chip; + event = EVENT_OCC_LOAD_START; + 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_OCC_LOAD_START) { + prd_msg->hdr.type = OPAL_PRD_MSG_TYPE_OCC_LOAD_START; + prd_msg->occ_reset.chip = proc; } /* @@ -280,6 +288,11 @@ void prd_sbe_passthrough(uint32_t proc) prd_event(proc, EVENT_SBE_PASSTHROUGH); } +void prd_occ_load_start(uint32_t proc) +{ + prd_event(proc, EVENT_OCC_LOAD_START); +} + /* incoming message handlers */ static int prd_msg_handle_attn_ack(struct opal_prd_msg *msg) { @@ -439,6 +452,10 @@ static int64_t opal_prd_msg(struct opal_prd_msg *msg) rc = hservice_wakeup_p9(msg->spl_wakeup.core, msg->spl_wakeup.mode); break; + case OPAL_PRD_MSG_TYPE_OCC_LOAD_START_STATUS: + rc = fsp_occ_load_start_status(msg->occ_reset_status.chip, + msg->occ_reset_status.status); + break; default: rc = OPAL_UNSUPPORTED; } diff --git a/include/opal-api.h b/include/opal-api.h index 9c9d7fb..3cfb43f 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -1056,6 +1056,8 @@ enum opal_prd_msg_type { OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH, /* HBRT <-- OPAL */ OPAL_PRD_MSG_TYPE_OCC_RESET_STATUS, /* HBRT --> OPAL */ OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_OCC_LOAD_START, /* HBRT --> OPAL */ + OPAL_PRD_MSG_TYPE_OCC_LOAD_START_STATUS, /* HBRT --> OPAL */ }; struct opal_prd_msg_header { diff --git a/include/skiboot.h b/include/skiboot.h index 221ed4b..2131e4a 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -293,6 +293,7 @@ extern void prd_occ_reset(uint32_t proc); extern void prd_sbe_passthrough(uint32_t proc); extern void prd_init(void); extern void prd_register_reserved_memory(void); +extern void prd_occ_load_start(u32 proc); /* Flatten device-tree */ extern void *create_dtb(const struct dt_node *root, bool exclusive); @@ -335,4 +336,5 @@ extern void occ_add_sensor_groups(struct dt_node *sg, u32 *phandles, extern int fsp_occ_reset_status(u64 chipid, s64 status); extern int core_special_wakeup(u32 core, u32 mode); +extern int fsp_occ_load_start_status(u64 chipid, s64 status); #endif /* __SKIBOOT_H */