Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/814249/?format=api
{ "id": 814249, "url": "http://patchwork.ozlabs.org/api/patches/814249/?format=api", "web_url": "http://patchwork.ozlabs.org/project/skiboot/patch/1505478062-1623-2-git-send-email-akshay.adiga@linux.vnet.ibm.com/", "project": { "id": 44, "url": "http://patchwork.ozlabs.org/api/projects/44/?format=api", "name": "skiboot firmware development", "link_name": "skiboot", "list_id": "skiboot.lists.ozlabs.org", "list_email": "skiboot@lists.ozlabs.org", "web_url": "http://github.com/open-power/skiboot", "scm_url": "http://github.com/open-power/skiboot", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1505478062-1623-2-git-send-email-akshay.adiga@linux.vnet.ibm.com>", "list_archive_url": null, "date": "2017-09-15T12:20:55", "name": "[v5,1/8] SLW: Add support for p9_stop_api", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "36e471f24caa14a9b1f47e8d9cfba8a93f925a71", "submitter": { "id": 68766, "url": "http://patchwork.ozlabs.org/api/people/68766/?format=api", "name": "Akshay Adiga", "email": "akshay.adiga@linux.vnet.ibm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/skiboot/patch/1505478062-1623-2-git-send-email-akshay.adiga@linux.vnet.ibm.com/mbox/", "series": [ { "id": 3295, "url": "http://patchwork.ozlabs.org/api/series/3295/?format=api", "web_url": "http://patchwork.ozlabs.org/project/skiboot/list/?series=3295", "date": "2017-09-15T12:20:54", "name": "Enable stop4 idle state", "version": 5, "mbox": "http://patchwork.ozlabs.org/series/3295/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/814249/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/814249/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "skiboot@lists.ozlabs.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "skiboot@lists.ozlabs.org" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xtvgT6BN2z9s7C\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 15 Sep 2017 22:23:01 +1000 (AEST)", "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xtvgS70lbzDrYr\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 15 Sep 2017 22:23:00 +1000 (AEST)", "from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com\n\t[148.163.158.5])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3xtvg26217zDrYh\n\tfor <skiboot@lists.ozlabs.org>; Fri, 15 Sep 2017 22:22:38 +1000 (AEST)", "from pps.filterd (m0098421.ppops.net [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv8FCIvF0037357\n\tfor <skiboot@lists.ozlabs.org>; Fri, 15 Sep 2017 08:22:36 -0400", "from e23smtp06.au.ibm.com (e23smtp06.au.ibm.com [202.81.31.148])\n\tby mx0a-001b2d01.pphosted.com with ESMTP id 2d0d6m4j8e-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <skiboot@lists.ozlabs.org>; Fri, 15 Sep 2017 08:22:34 -0400", "from localhost\n\tby e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <skiboot@lists.ozlabs.org> from <akshay.adiga@linux.vnet.ibm.com>;\n\tFri, 15 Sep 2017 22:22:31 +1000", "from d23relay07.au.ibm.com (202.81.31.226)\n\tby e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway:\n\tAuthorized Use Only! Violators will be prosecuted; \n\tFri, 15 Sep 2017 22:22:29 +1000", "from d23av06.au.ibm.com (d23av06.au.ibm.com [9.190.235.151])\n\tby d23relay07.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n\tv8FCLE3D32964698\n\tfor <skiboot@lists.ozlabs.org>; Fri, 15 Sep 2017 22:21:14 +1000", "from d23av06.au.ibm.com (localhost [127.0.0.1])\n\tby d23av06.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id\n\tv8FCLDj2024377\n\tfor <skiboot@lists.ozlabs.org>; Fri, 15 Sep 2017 22:21:13 +1000", "from aksadiga.in.ibm.com (aksadiga.in.ibm.com [9.124.35.28])\n\tby d23av06.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id\n\tv8FCL61J024170; Fri, 15 Sep 2017 22:21:10 +1000" ], "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=linux.vnet.ibm.com\n\t(client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com;\n\tenvelope-from=akshay.adiga@linux.vnet.ibm.com; receiver=<UNKNOWN>)", "From": "Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>", "To": "skiboot@lists.ozlabs.org", "Date": "Fri, 15 Sep 2017 17:50:55 +0530", "X-Mailer": "git-send-email 2.5.5", "In-Reply-To": "<1505478062-1623-1-git-send-email-akshay.adiga@linux.vnet.ibm.com>", "References": "<1505478062-1623-1-git-send-email-akshay.adiga@linux.vnet.ibm.com>", "X-TM-AS-MML": "disable", "x-cbid": "17091512-0040-0000-0000-000003564274", "X-IBM-AV-DETECTION": "SAVI=unused REMOTE=unused XFE=unused", "x-cbparentid": "17091512-0041-0000-0000-00000CD6AA4D", "Message-Id": "<1505478062-1623-2-git-send-email-akshay.adiga@linux.vnet.ibm.com>", "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-09-15_05:, , signatures=0", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=1\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000\n\tdefinitions=main-1709150179", "Subject": "[Skiboot] [PATCH v5 1/8] SLW: Add support for p9_stop_api", "X-BeenThere": "skiboot@lists.ozlabs.org", "X-Mailman-Version": "2.1.24", "Precedence": "list", "List-Id": "Mailing list for skiboot development <skiboot.lists.ozlabs.org>", "List-Unsubscribe": "<https://lists.ozlabs.org/options/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=unsubscribe>", "List-Archive": "<http://lists.ozlabs.org/pipermail/skiboot/>", "List-Post": "<mailto:skiboot@lists.ozlabs.org>", "List-Help": "<mailto:skiboot-request@lists.ozlabs.org?subject=help>", "List-Subscribe": "<https://lists.ozlabs.org/listinfo/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=subscribe>", "Cc": "ego@linux.vnet.ibm.com, shriyak@linux.vnet.ibm.com", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org", "Sender": "\"Skiboot\"\n\t<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>" }, "content": "p9_stop_api's are used to set SPR state on a core wakeup form a deeper\nlow power state. p9_stop_api uses low level platform formware and\nself-restore microcode to restore the sprs to requested values.\n\nCode is taken from :\nhttps://github.com/open-power/hostboot/tree/master/src/import/chips/p9/procedures/utils/stopreg\n\nSigned-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>\nReviewed-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>\n---\n include/p9_stop_api.H | 163 +++++\n libpore/Makefile.inc | 2 +-\n libpore/p9_cpu_reg_restore_instruction.H | 76 +++\n libpore/p9_hcd_header_defs.H | 152 +++++\n libpore/p9_hcd_memmap_base.H | 522 +++++++++++++++\n libpore/p9_stop_api.C | 1028 ++++++++++++++++++++++++++++++\n libpore/p9_stop_api.H | 163 +++++\n libpore/p9_stop_data_struct.H | 149 +++++\n libpore/p9_stop_util.C | 186 ++++++\n libpore/p9_stop_util.H | 145 +++++\n 10 files changed, 2585 insertions(+), 1 deletion(-)\n create mode 100644 include/p9_stop_api.H\n create mode 100644 libpore/p9_cpu_reg_restore_instruction.H\n create mode 100644 libpore/p9_hcd_header_defs.H\n create mode 100644 libpore/p9_hcd_memmap_base.H\n create mode 100644 libpore/p9_stop_api.C\n create mode 100644 libpore/p9_stop_api.H\n create mode 100644 libpore/p9_stop_data_struct.H\n create mode 100644 libpore/p9_stop_util.C\n create mode 100644 libpore/p9_stop_util.H", "diff": "diff --git a/include/p9_stop_api.H b/include/p9_stop_api.H\nnew file mode 100644\nindex 0000000..79abd00\n--- /dev/null\n+++ b/include/p9_stop_api.H\n@@ -0,0 +1,163 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+#ifndef __P9_STOP_IMAGE_API_\n+#define __P9_STOP_IMAGE_API_\n+\n+#include <stdint.h>\n+\n+#ifdef __SKIBOOT__\n+ #include <skiboot.h>\n+#endif\n+\n+///\n+/// @file p9_stop_api.H\n+/// @brief describes STOP API which create/manipulate STOP image.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+\n+#ifdef __cplusplus\n+namespace stopImageSection\n+{\n+#endif\n+\n+/**\n+ * @brief all SPRs and MSR for which register restore is to be supported.\n+ * @note STOP API design has built in support to accomodate 8 register of\n+ * scope core and thread each.\n+ */\n+typedef enum\n+{\n+ P9_STOP_SPR_DAWR = 180, // thread register\n+ P9_STOP_SPR_HSPRG0 = 304, // thread register\n+ P9_STOP_SPR_HRMOR = 313, // core register\n+ P9_STOP_SPR_LPCR = 318, // thread register\n+ P9_STOP_SPR_HMEER = 337, // core register\n+ P9_STOP_SPR_LDBAR = 850, // thread register\n+ P9_STOP_SPR_PSSCR = 855, // thread register\n+ P9_STOP_SPR_PMCR = 884, // core register\n+ P9_STOP_SPR_HID = 1008, // core register\n+ P9_STOP_SPR_MSR = 2000, // thread register\n+} CpuReg_t;\n+\n+/**\n+ * @brief lists all the bad error codes.\n+ */\n+typedef enum\n+{\n+ STOP_SAVE_SUCCESS = 0,\n+ STOP_SAVE_ARG_INVALID_IMG = 1,\n+ STOP_SAVE_ARG_INVALID_REG = 2,\n+ STOP_SAVE_ARG_INVALID_THREAD = 3,\n+ STOP_SAVE_ARG_INVALID_MODE = 4,\n+ STOP_SAVE_ARG_INVALID_CORE = 5,\n+ STOP_SAVE_SPR_ENTRY_NOT_FOUND = 6,\n+ STOP_SAVE_SPR_ENTRY_UPDATE_FAILED = 7,\n+ STOP_SAVE_SCOM_INVALID_OPERATION = 8,\n+ STOP_SAVE_SCOM_INVALID_SECTION = 9,\n+ STOP_SAVE_SCOM_INVALID_ADDRESS = 10,\n+ STOP_SAVE_SCOM_INVALID_CHIPLET = 11,\n+ STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED = 12,\n+ STOP_SAVE_INVALID_FUSED_CORE_STATUS = 13,\n+ STOP_SAVE_FAIL = 14, // for internal failure within firmware.\n+} StopReturnCode_t;\n+\n+/**\n+ * @brief summarizes all operations supported on scom entries of STOP image.\n+ */\n+typedef enum\n+{\n+ P9_STOP_SCOM_OP_MIN = 0,\n+ P9_STOP_SCOM_APPEND = 1,\n+ P9_STOP_SCOM_REPLACE = 2,\n+ P9_STOP_SCOM_OR = 3,\n+ P9_STOP_SCOM_AND = 4,\n+ P9_STOP_SCOM_NOOP = 5,\n+ P9_STOP_SCOM_RESET = 6,\n+ P9_STOP_SCOM_OR_APPEND = 7,\n+ P9_STOP_SCOM_AND_APPEND = 8,\n+ P9_STOP_SCOM_OP_MAX = 9\n+} ScomOperation_t;\n+\n+/**\n+ * @brief All subsections that contain scom entries in a STOP image.\n+ */\n+typedef enum\n+{\n+ P9_STOP_SECTION_MIN = 0,\n+ P9_STOP_SECTION_CORE_SCOM = 1,\n+ P9_STOP_SECTION_EQ_SCOM = 2,\n+ P9_STOP_SECTION_L2 = 3,\n+ P9_STOP_SECTION_L3 = 4,\n+ P9_STOP_SECTION_MAX = 5\n+} ScomSection_t;\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+/**\n+ * @brief Updates STOP image entry associated with CPU register.\n+ * @param[in] i_pImage start address of homer image associated with processor.\n+ * @param[in] i_regId id of SPR for which STOP image needs to be updated.\n+ * @param[in] i_regData data to be restored in SPR register.\n+ * @param[in] i_pir value of processor identification register (PIR)\n+ * @return STOP_SAVE_SUCCESS SUCCESS if image is updated successfully, error\n+ * code otherwise.\n+ */\n+\n+StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage,\n+ const CpuReg_t i_regId,\n+ const uint64_t i_regData,\n+ const uint64_t i_pir );\n+\n+/**\n+ * @brief Updates scom image entry associated with given core or cache in\n+ * STOP section of homer image.\n+ * @param[in] i_pImage start address of homer image of P9 chip.\n+ * @param[in] i_scomAddress fully qualified address of SCOM register.\n+ * @param[in] i_scomData data associated with SCOM register.\n+ * @param[in] i_operation operation to be done on SCOM image entry.\n+ * @param[in] i_section area to which given SCOM entry belongs.\n+ * @return STOP_SAVE_SUCCESS if image is updated successfully, error code\n+ * otherwise.\n+ * @note API is intended to update SCOM image entry associated with given\n+ * core or given part of a cache section. API doesn't validate if\n+ * a given SCOM address really belongs to given section.\n+ */\n+StopReturnCode_t p9_stop_save_scom( void* const i_pImage,\n+ const uint32_t i_scomAddress,\n+ const uint64_t i_scomData,\n+ const ScomOperation_t i_operation,\n+ const ScomSection_t i_section );\n+\n+#ifdef __cplusplus\n+} // extern \"C\"\n+}; // namespace stopImageSection ends\n+#endif //__cplusplus\n+\n+#endif //__P9_STOP_IMAGE_API_\ndiff --git a/libpore/Makefile.inc b/libpore/Makefile.inc\nindex 2eac595..cc89127 100644\n--- a/libpore/Makefile.inc\n+++ b/libpore/Makefile.inc\n@@ -1,4 +1,4 @@\n-LIBPORE_SRCS = p8_pore_table_gen_api_fixed.C\n+LIBPORE_SRCS = p8_pore_table_gen_api_fixed.C p9_stop_api.C p9_stop_util.C\n LIBPORE_SRCS += p8_pore_table_static_data.c sbe_xip_image.c pore_inline_assembler.c\n LIBPORE_OBJS_1 = $(LIBPORE_SRCS:%.c=%.o)\n LIBPORE_OBJS = $(LIBPORE_OBJS_1:%.C=%.o)\ndiff --git a/libpore/p9_cpu_reg_restore_instruction.H b/libpore/p9_cpu_reg_restore_instruction.H\nnew file mode 100644\nindex 0000000..e5689ae\n--- /dev/null\n+++ b/libpore/p9_cpu_reg_restore_instruction.H\n@@ -0,0 +1,76 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+\n+///\n+/// @file p9_cpu_reg_restore_instruction.H\n+/// @brief enumerates all the opcodes used for SPR restoration.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+\n+#ifndef __REG_RESTORE_INSTRUCTION_H\n+#define __REG_RESTORE_INSTRUCTION_H\n+\n+#include <stdint.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+\n+namespace stopImageSection\n+{\n+#endif\n+\n+/**\n+ * @brief enumerates opcodes for few instructions.\n+ */\n+enum\n+{\n+ ORI_OPCODE = 24,\n+ RFI_OPCODE = 19,\n+ RFI_CONST = 50,\n+ ORIS_OPCODE = 25,\n+ OPCODE_31 = 31,\n+ XOR_CONST = 316,\n+ RLDICR_OPCODE = 30,\n+ RLDICR_CONST = 1,\n+ MTSPR_CONST1 = 467,\n+ MTMSRD_CONST1 = 178,\n+ MR_R0_TO_R10 = 0x7c0a0378, //mr r10, r0\n+ MR_R0_TO_R21 = 0x7c150378, //mr r21, r0\n+ BLR_INST = 0x4e800020,\n+ MTSPR_BASE_OPCODE = 0x7c0003a6,\n+ ATTN_OPCODE = 0x00000200,\n+};\n+\n+#ifdef __cplusplus\n+} // namespace stopImageSection ends\n+\n+} // extern \"C\"\n+#endif //__cplusplus\n+\n+#endif //__REG_RESTORE_INSTRUCTION_H\ndiff --git a/libpore/p9_hcd_header_defs.H b/libpore/p9_hcd_header_defs.H\nnew file mode 100644\nindex 0000000..49c814a\n--- /dev/null\n+++ b/libpore/p9_hcd_header_defs.H\n@@ -0,0 +1,152 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_hcd_header_defs.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2016,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+///\n+/// @file p9_hcd_header_defs.H\n+/// @brief defines header constants based on file types\n+///\n+/// This header contains those cpp manifest constants required for processing\n+/// the linker scripts used to generate OCC code images. As these are used\n+/// by linker scripts as well as by C++ code, these cannot be solely be put\n+/// into a namespace. Prefixing these with the region name is the attempt\n+/// to make these globally unique when this header is included in C++ code.\n+///\n+// *HWP HWP Owner: David Du <daviddu@us.ibm.com>\n+// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner: Prem Jha <premjha2@in.ibm.com>\n+// *HWP Team: PM\n+// *HWP Level: 2\n+// *HWP Consumed by: PM\n+//\n+\n+#ifndef __HCD_HEADER_DEFS_H__\n+#define __HCD_HEADER_DEFS_H__\n+\n+/// Macros for generating an Hcode header section\n+///\n+/// The CPP macros HCD_HDR_UINTxx generate equivalent code depending on\n+/// whether they are being called from assembler (where they actually\n+/// create the header section data) or from C (where they specifiy a\n+/// C-structure form of the contents of the header section.\n+///\n+/// In assembler each invocation also creates space in the header section\n+\n+#ifdef __ASSEMBLER__\n+\n+// *INDENT-OFF*\n+ .macro hcd_header_uint64, symbol:req, value = 0\n+ .global \\symbol\n+\\symbol\\():\n+ .quad (\\value)\n+ .endm\n+\n+ .macro hcd_header_uint32, symbol:req, value = 0\n+ .global \\symbol\n+ \\symbol\\():\n+ .long (\\value)\n+ .endm\n+\n+ .macro hcd_header_uint16, symbol:req, value = 0\n+ .global \\symbol\n+\\symbol\\():\n+ .short (\\value)\n+ .endm\n+\n+ .macro hcd_header_uint8, symbol:req, value = 0\n+ .global \\symbol\n+\\symbol\\():\n+ .byte (\\value)\n+ .endm\n+\n+ .macro hcd_header_uint8_vec, symbol:req, number:req, value = 0\n+ .global \\symbol\n+\\symbol\\():\n+ .rept (\\number)\n+ .byte (\\value)\n+ .endr\n+ .endm\n+\n+ .macro hcd_header_attn, symbol:req, number = 1\n+ .global \\symbol\n+\\symbol\\():\n+ .rept (\\number)\n+ .long 0x00000200\n+ .endr\n+ .endm\n+\n+ .macro hcd_header_attn_pad, align:req\n+ .balignl (\\align), 0x00000200\n+ .endm\n+\n+ .macro hcd_header_pad, align:req\n+ .balignl (\\align), 0\n+ .endm\n+// *INDENT-ON*\n+\n+#define ULL(x) x\n+#define HCD_CONST(name, expr) .set name, expr;\n+#define HCD_CONST64(name, expr) .set name, expr;\n+\n+#define HCD_HDR_UINT64(symbol, value) hcd_header_uint64 symbol value\n+#define HCD_HDR_UINT32(symbol, value) hcd_header_uint32 symbol value\n+#define HCD_HDR_UINT16(symbol, value) hcd_header_uint16 symbol value\n+#define HCD_HDR_UINT8(symbol, value) hcd_header_uint8 symbol value\n+#define HCD_HDR_UINT8_VEC(symbol, number, value) hcd_header_uint8_vec symbol number value\n+#define HCD_HDR_ATTN(symbol, number) hcd_header_attn symbol number\n+#define HCD_HDR_ATTN_PAD(align) hcd_header_attn_pad align\n+#define HCD_HDR_PAD(align) hcd_header_pad align\n+\n+#else // NOT __ASSEMBLER__\n+\n+#ifdef __LINKERSCRIPT__\n+\n+ #define ULL(x) x\n+ #define POUND_DEFINE #define\n+ #define HCD_CONST(name, expr) POUND_DEFINE name expr\n+ #define HCD_CONST64(name, expr) POUND_DEFINE name expr\n+\n+#else\n+\n+ #define ULL(x) x##ull\n+ #define HCD_CONST(name, expr) enum { name = expr };\n+ #define HCD_CONST64(name, expr) enum { name = expr };\n+\n+ #define HCD_HDR_UINT64(symbol, value) uint64_t symbol\n+ #define HCD_HDR_UINT32(symbol, value) uint32_t symbol\n+ #define HCD_HDR_UINT16(symbol, value) uint16_t symbol\n+ #define HCD_HDR_UINT8(symbol, value) uint8_t symbol\n+ #define HCD_HDR_UINT8_VEC(symbol, number, value) uint8_t symbol[number]\n+ #define HCD_HDR_ATTN(symbol, number) uint32_t symbol[number]\n+ #define HCD_HDR_ATTN_PAD(align)\n+ #define HCD_HDR_PAD(align)\n+\n+#endif // __LINKERSCRIPT__\n+#endif // __ASSEMBLER__\n+\n+// Stringification\n+\n+#define STR_HELPER(x) #x\n+#define STR(x) STR_HELPER(x)\n+\n+#endif // __HCD_HEADER_DEFS_H__\ndiff --git a/libpore/p9_hcd_memmap_base.H b/libpore/p9_hcd_memmap_base.H\nnew file mode 100644\nindex 0000000..6e3b54d\n--- /dev/null\n+++ b/libpore/p9_hcd_memmap_base.H\n@@ -0,0 +1,522 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+///\n+/// @file p9_hcd_memmap_base.H\n+/// @brief defines region constants shared by different memory components.\n+///\n+\n+// *HWP HWP Owner: David Du <daviddu@us.ibm.com>\n+// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner: Prem S Jha <premjha2@in.ibm.com>\n+// *HWP Team: PM\n+// *HWP Level: 2\n+// *HWP Consumed by: PM:Hostboot:Phyp\n+\n+#ifndef __HCD_MEMMAP_BASE_H__\n+#define __HCD_MEMMAP_BASE_H__\n+\n+#include <p9_hcd_header_defs.H>\n+\n+// -------------------------------------------------------------------\n+// Note: There can be NO semicolons(\";\") at end of macros in this file\n+// There can ONLY have HCD_CONST/HCD_CONST64 macros in this file\n+// -------------------------------------------------------------------\n+\n+/// Image Magic Numbers\n+\n+HCD_CONST64(CPMR_MAGIC_NUMBER, ULL(0x43504d525f312e30)) // CPMR_1.0\n+HCD_CONST64(CME_MAGIC_NUMBER , ULL(0x434d455f5f312e30)) // CME__1.0\n+\n+HCD_CONST64(QPMR_MAGIC_NUMBER, ULL(0x51504d525f312e30)) // QPMR_1.0\n+HCD_CONST64(SGPE_MAGIC_NUMBER, ULL(0x534750455f312e30)) // SGPE_1.0\n+\n+HCD_CONST64(PPMR_MAGIC_NUMBER, ULL(0x50504d525f312e30)) // PPMR_1.0\n+HCD_CONST64(PGPE_MAGIC_NUMBER, ULL(0x504750455F312E30)) // PGPE_1.0\n+\n+HCD_CONST(CME_BUILD_VERSION, 0x001) // CME__1.0\n+HCD_CONST(SGPE_BUILD_VERSION, 0x001) // SGPE_1.0\n+HCD_CONST(PGPE_BUILD_VERSION, 0x001) // PGPE_1.0\n+\n+HCD_CONST64(CPMR_MAGIC_NUMBER_BASE, ULL(0x43504d525f302e30)) // CPMR_0.0\n+HCD_CONST(CPMR_REGION_CHECK_WORD, (0x43504d52)) // CPMR\n+HCD_CONST64(CME_MAGIC_NUMBER_BASE , ULL(0x434d455f5f302e30)) // CME__0.0\n+HCD_CONST64(QPMR_MAGIC_NUMBER_BASE, ULL(0x51504d525f302e30)) // QPMR_0.0\n+HCD_CONST64(SGPE_MAGIC_NUMBER_BASE, ULL(0x534750455f302e30)) // SGPE_0.0\n+HCD_CONST64(PPMR_MAGIC_NUMBER_BASE, ULL(0x50504d525f302e30)) // PPMR_0.0\n+HCD_CONST64(PGPE_MAGIC_NUMBER_BASE, ULL(0x504750455F302E30)) // PGPE_0.0\n+\n+/// Size constants\n+\n+HCD_CONST(HALF_KB, 512)\n+HCD_CONST(ONE_KB, 1024)\n+HCD_CONST(HALF_MB, (1024 * 512))\n+HCD_CONST(ONE_MB, (1024 * 1024))\n+HCD_CONST(TWO_MB, (2 * 1024 * 1024))\n+\n+/// Memory constants\n+\n+HCD_CONST(CME_SRAM_SIZE, (32 * ONE_KB))\n+HCD_CONST(OCC_SRAM_SIZE, (768 * ONE_KB))\n+\n+HCD_CONST(HOMER_MEMORY_SIZE, (4 * ONE_MB))\n+HCD_CONST(HOMER_OPMR_REGION_NUM, 0)\n+HCD_CONST(HOMER_QPMR_REGION_NUM, 1)\n+HCD_CONST(HOMER_CPMR_REGION_NUM, 2)\n+HCD_CONST(HOMER_PPMR_REGION_NUM, 3)\n+\n+/// Chip constants\n+\n+HCD_CONST(MAX_THREADS_PER_CORE, 4)\n+HCD_CONST(MAX_CORES_PER_CHIP, 24)\n+\n+HCD_CONST(MAX_CMES_PER_CHIP, 12)\n+HCD_CONST(MAX_EXES_PER_CHIP, 12)\n+\n+HCD_CONST(MAX_QUADS_PER_CHIP, 6)\n+HCD_CONST(MAX_CACHES_PER_CHIP, 6)\n+\n+HCD_CONST(MAX_CORES_PER_CME, 2)\n+HCD_CONST(MAX_CORES_PER_EX, 2)\n+\n+HCD_CONST(MAX_CMES_PER_QUAD, 2)\n+HCD_CONST(MAX_EXES_PER_QUAD, 2)\n+\n+HCD_CONST(CACHE0_CHIPLET_ID, 0x10)\n+HCD_CONST(CACHE_CHIPLET_ID_MIN, 0x10)\n+HCD_CONST(CACHE_CHIPLET_ID_MAX, 0x15)\n+\n+HCD_CONST(CORE0_CHIPLET_ID, 0x20)\n+HCD_CONST(CORE_CHIPLET_ID_MIN, 0x20)\n+HCD_CONST(CORE_CHIPLET_ID_MAX, 0x37)\n+\n+HCD_CONST(MAX_QUAD_ID_SUPPORTED, 5)\n+HCD_CONST(MAX_CORE_ID_SUPPORTED, 23)\n+HCD_CONST(MAX_THREAD_ID_SUPPORTED, 3)\n+\n+/// Image build constants\n+\n+HCD_CONST(HARDWARE_IMG_SIZE, ONE_MB)\n+\n+HCD_CONST(FUSED_CORE_MODE, 0xBB)\n+HCD_CONST(NONFUSED_CORE_MODE, 0xAA)\n+\n+HCD_CONST(SELF_RESTORE_BLR_INST, 0x4e800020)\n+HCD_CONST(CORE_RESTORE_PAD_OPCODE, 0x00000200) //ATTN Opcode\n+\n+HCD_CONST(SCOM_RESTORE_PAD_OPCODE, 0x00000000) //zero pads\n+HCD_CONST(SCOM_RESTORE_ENTRY_SIZE, 16) //4B pad,4B address,8B data\n+\n+HCD_CONST(CME_BLOCK_READ_LEN, 32)\n+HCD_CONST(CME_BLK_SIZE_SHIFT, 0x05)\n+\n+HCD_CONST(RING_ALIGN_BOUNDARY, 0x08)\n+HCD_CONST64(DARN_BAR_EN_POS, ULL(0x8000000000000000))\n+\n+//---------------------------------------------------------------------------------------\n+\n+/// OPMR\n+\n+HCD_CONST(OCC_HOST_AREA_SIZE, ONE_MB)\n+HCD_CONST(OPMR_OCC_IMAGE_SIZE, HALF_MB)\n+HCD_CONST(OPMR_HOST_AREA_SIZE, HALF_MB)\n+\n+//---------------------------------------------------------------------------------------\n+\n+/// QPMR Header\n+\n+HCD_CONST(QPMR_HOMER_OFFSET, (HOMER_QPMR_REGION_NUM* ONE_MB))\n+HCD_CONST(QPMR_HEADER_SIZE, 512)\n+\n+HCD_CONST(QPMR_MAGIC_NUMBER_BYTE, 0x00)\n+HCD_CONST(QPMR_BOOT_COPIER_OFFSET_BYTE, 0x08)\n+HCD_CONST(QPMR_BOOT_LOADER_OFFSET_BYTE, 0x10)\n+HCD_CONST(QPMR_BOOT_LOADER_LENGTH_BYTE, 0x14)\n+HCD_CONST(QPMR_BUILD_DATE_BYTE, 0x18)\n+HCD_CONST(QPMR_BUILD_VER_BYTE, 0x1C)\n+HCD_CONST(QPMR_SGPE_HCODE_OFFSET_BYTE, 0x28)\n+HCD_CONST(QPMR_SGPE_HCODE_LENGTH_BYTE, 0x2C)\n+HCD_CONST(QPMR_QUAD_COMMON_RINGS_OFFSET_BYTE, 0x30)\n+HCD_CONST(QPMR_QUAD_COMMON_RINGS_LENGTH_BYTE, 0x34)\n+HCD_CONST(QPMR_QUAD_OVERRIDE_RINGS_OFFSET_BYTE, 0x38)\n+HCD_CONST(QPMR_QUAD_OVERRIDE_RINGS_LENGTH_BYTE, 0x3C)\n+HCD_CONST(QPMR_QUAD_SPECIFIC_RINGS_OFFSET_BYTE, 0x40)\n+HCD_CONST(QPMR_QUAD_SPECIFIC_RINGS_LENGTH_BYTE, 0x44)\n+HCD_CONST(QPMR_QUAD_SCOM_RESTORE_OFFSET_BYTE, 0x48)\n+HCD_CONST(QPMR_QUAD_SCOM_RESTORE_LENGTH_BYTE, 0x4C)\n+HCD_CONST(QPMR_AUX_DATA_OFFSET_BYTE, 0x50)\n+HCD_CONST(QPMR_AUX_DATA_LENGTH_BYTE, 0x54)\n+HCD_CONST(QPMR_STOP_FFDC_OFFSET_BYTE, 0x58)\n+HCD_CONST(QPMR_STOP_FFDC_LENGTH_BYTE, 0x5C)\n+HCD_CONST(QPMR_SGPE_BOOT_PROG_CODE, 0x60)\n+HCD_CONST(QPMR_SGPE_IMAGE_SIZE, 0x64)\n+\n+/// SGPE Boot\n+\n+HCD_CONST(SGPE_BOOT_COPIER_QPMR_OFFSET, QPMR_HEADER_SIZE)\n+HCD_CONST(SGPE_BOOT_COPIER_SIZE, ONE_KB)\n+\n+HCD_CONST(SGPE_BOOT_LOADER_QPMR_OFFSET,\n+ (SGPE_BOOT_COPIER_QPMR_OFFSET + SGPE_BOOT_COPIER_SIZE))\n+HCD_CONST(SGPE_BOOT_LOADER_SIZE, ONE_KB)\n+HCD_CONST(SGPE_BOOT_LOADER_RESET_ADDR_VAL, 0x40)\n+\n+HCD_CONST(SGPE_INSTRUMENTATION_SIZE, (2 * ONE_KB))\n+\n+/// SGPE Image\n+\n+HCD_CONST(SGPE_IMAGE_QPMR_OFFSET,\n+ (SGPE_BOOT_LOADER_QPMR_OFFSET + SGPE_BOOT_LOADER_SIZE))\n+HCD_CONST(SGPE_IMAGE_SIZE, (80 * ONE_KB)) //RTC158543\n+HCD_CONST(SGPE_INT_VECTOR_SIZE, 384)\n+HCD_CONST(SGPE_HCODE_RESET_ADDR_VAL, 0x40)\n+\n+/// SGPE Header\n+\n+HCD_CONST(SGPE_HEADER_QPMR_OFFSET,\n+ (SGPE_IMAGE_QPMR_OFFSET + SGPE_INT_VECTOR_SIZE))\n+HCD_CONST(SGPE_HEADER_IMAGE_OFFSET, SGPE_INT_VECTOR_SIZE)\n+HCD_CONST(SGPE_HEADER_SIZE, 128)\n+\n+HCD_CONST(SGPE_MAGIC_NUMBER_BYTE, 0x00)\n+HCD_CONST(SGPE_SYSTEM_RESET_ADDR_BYTE, 0x08)\n+HCD_CONST(SGPE_IVPR_ADDR_BYTE, 0x10)\n+HCD_CONST(SGPE_BUILD_DATE_BYTE, 0x18)\n+HCD_CONST(SGPE_BUILD_VER_BYTE, 0x1C)\n+HCD_CONST(SGPE_STOP_FLAGS_BYTE, 0x20)\n+HCD_CONST(SGPE_LOCATION_ID_BYTE, 0x24)\n+HCD_CONST(SGPE_QUAD_COMMON_RING_SRAM_OFF_BYTE, 0x28)\n+HCD_CONST(SGPE_QUAD_OVERRIDE_RING_SRAM_OFF_BYTE, 0x2C)\n+HCD_CONST(SGPE_QUAD_SPECIFIC_RING_SRAM_OFF_BYTE, 0x30)\n+HCD_CONST(SGPE_QUAD_SCOM_RESTORE_SRAM_OFF_BYTE, 0x34)\n+HCD_CONST(SGPE_QUAD_SCOM_RESTORE_MEM_OFF_BYTE, 0x38)\n+HCD_CONST(SGPE_QUAD_SCOM_RESTORE_LENGTH_BYTE, 0x3C)\n+HCD_CONST(SGPE_AUX_DATA_OFFSET_BYTE, 0x40)\n+HCD_CONST(SGPE_AUX_DATA_LENGTH_BYTE, 0x44)\n+HCD_CONST(SGPE_AUX_CTRL_BYTE, 0x48)\n+HCD_CONST(SGPE_CHTM_MEM_CFG_BYTE, 0x50)\n+\n+HCD_CONST(SGPE_RESET_ADDR_IMAGE_OFFSET, (SGPE_HEADER_IMAGE_OFFSET + SGPE_SYSTEM_RESET_ADDR_BYTE))\n+HCD_CONST(SGPE_BUILD_DATE_IMAGE_OFFSET, (SGPE_HEADER_IMAGE_OFFSET + SGPE_BUILD_DATE_BYTE))\n+HCD_CONST(SGPE_BUILD_VER_IMAGE_OFFSET, (SGPE_HEADER_IMAGE_OFFSET + SGPE_BUILD_VER_BYTE))\n+\n+HCD_CONST(SGPE_STOP_4_TO_2_BIT_POS, 0x80000000)\n+HCD_CONST(SGPE_STOP_5_TO_4_BIT_POS, 0x40000000)\n+HCD_CONST(SGPE_STOP_8_TO_5_BIT_POS, 0x20000000)\n+HCD_CONST(SGPE_STOP_11_TO_8_BIT_POS, 0x10000000)\n+HCD_CONST(SGPE_ENABLE_CME_TRACE_ARRAY_BIT_POS, 0x08000000)\n+HCD_CONST(SGPE_VDM_ENABLE_BIT_POS, 0x04000000)\n+HCD_CONST(SGPE_ENABLE_CHTM_TRACE_CME_BIT_POS, 0x02000000)\n+HCD_CONST(SGPE_PROC_FAB_PUMP_MODE_BIT_POS, 0x00004000)\n+HCD_CONST(SGPE_CACHE_SKEWADJ_DISABLE_BIT_POS, 0x00002000)\n+HCD_CONST(SGPE_CACHE_DCADJ_DISABLE_BIT_POS, 0x00001000)\n+\n+///24x7\n+HCD_CONST(QPMR_AUX_OFFSET, (512 * ONE_KB))\n+HCD_CONST(QPMR_AUX_LENGTH, (64 * ONE_KB))\n+/// SGPE Hcode\n+\n+HCD_CONST(SGPE_HCODE_IMAGE_OFFSET, (SGPE_INT_VECTOR_SIZE + SGPE_HEADER_SIZE))\n+HCD_CONST(SGPE_HCODE_SIZE, ((45 * ONE_KB) + HALF_KB)) //RTC158543\n+HCD_CONST(SGPE_DEBUG_PTRS_OFFSET, 0x200)\n+HCD_CONST(SGPE_DEBUG_PTRS_SIZE, 0x24)\n+HCD_CONST(SGPE_DBG_PTR_AREA_SIZE, 64)\n+\n+/// Quad Scan\n+\n+// 400B * 9 rings * 3 types (base, RL, CC)\n+HCD_CONST(QUAD_COMMON_RING_SIZE, (13 * ONE_KB))\n+// 300B * 9 rings\n+HCD_CONST(QUAD_OVERRIDE_RING_SIZE, (3 * ONE_KB))\n+// 1KB/ring * 5 rings/cache\n+HCD_CONST(QUAD_SPECIFIC_RING_SIZE_PER_QUAD, ((3 * ONE_KB) + HALF_KB))\n+HCD_CONST(QUAD_SPECIFIC_RING_SIZE_TOTAL, (19 * ONE_KB)) //checkme?\n+\n+/// Quad Scom\n+\n+HCD_CONST(QUAD_SCOM_RESTORE_QPMR_OFFSET, (128 * ONE_KB))\n+HCD_CONST(QUAD_SCOM_RESTORE_HOMER_OFFSET,\n+ (QUAD_SCOM_RESTORE_QPMR_OFFSET + QPMR_HOMER_OFFSET))\n+\n+HCD_CONST(MAX_L2_SCOM_ENTRIES, 16)\n+HCD_CONST(MAX_L3_SCOM_ENTRIES, 16)\n+HCD_CONST(MAX_EQ_SCOM_ENTRIES, 15)\n+HCD_CONST(QUAD_SCOM_RESTORE_REGS_PER_QUAD,\n+ (MAX_EQ_SCOM_ENTRIES + MAX_L2_SCOM_ENTRIES + MAX_L3_SCOM_ENTRIES + 1))\n+\n+HCD_CONST(QUAD_SCOM_RESTORE_SIZE_PER_QUAD,\n+ (SCOM_RESTORE_ENTRY_SIZE* QUAD_SCOM_RESTORE_REGS_PER_QUAD))\n+\n+HCD_CONST(QUAD_SCOM_RESTORE_SIZE_TOTAL, (6 * ONE_KB)) //rounded to 6KB\n+\n+//---------------------------------------------------------------------------------------\n+\n+/// CPMR Header\n+\n+HCD_CONST(CPMR_HOMER_OFFSET, (HOMER_CPMR_REGION_NUM* ONE_MB))\n+HCD_CONST(CPMR_HEADER_SIZE, 256)\n+\n+HCD_CONST(CPMR_ATTN_WORD0_BYTE, 0x00)\n+HCD_CONST(CPMR_ATTN_WORD1_BYTE, 0x04)\n+HCD_CONST(CPMR_MAGIC_NUMBER_BYTE, 0x08)\n+HCD_CONST(CPMR_BUILD_DATE_BYTE, 0x10)\n+HCD_CONST(CPMR_BUILD_VER_BYTE, 0x14)\n+HCD_CONST(CPMR_CME_HCODE_OFFSET_BYTE, 0x20)\n+HCD_CONST(CPMR_CME_HCODE_LENGTH_BYTE, 0x24)\n+HCD_CONST(CPMR_CORE_COMMON_RING_OFFSET_BYTE, 0x28)\n+HCD_CONST(CPMR_CORE_COMMON_RING_LENGTH_BYTE, 0x2C)\n+HCD_CONST(CPMR_CME_LOCAL_PSTATE_OFFSET_BYTE, 0x30)\n+HCD_CONST(CPMR_CME_LOCAL_PSTATE_LENGTH_BYTE, 0x34)\n+HCD_CONST(CPMR_CORE_SPECIFIC_RING_OFFSET_BYTE, 0x38)\n+HCD_CONST(CPMR_CORE_SPECIFIC_RING_LENGTH_BYTE, 0x3C)\n+HCD_CONST(CPMR_CORE_SCOM_RESTORE_OFFSET_BYTE, 0x40)\n+HCD_CONST(CPMR_CORE_SCOM_RESTORE_LENGTH_BYTE, 0x44)\n+HCD_CONST(CPMR_SELF_RESTORE_OFFSET_BYTE, 0x48)\n+HCD_CONST(CPMR_SELF_RESTORE_LENGTH_BYTE, 0x4C)\n+\n+/// Self Restore\n+\n+HCD_CONST(SELF_RESTORE_CPMR_OFFSET, CPMR_HEADER_SIZE)\n+HCD_CONST(SELF_RESTORE_INT_SIZE, (8 * ONE_KB))\n+HCD_CONST(THREAD_LAUNCHER_SIZE, 256)\n+HCD_CONST(SELF_RESTORE_CODE_SIZE,\n+ (SELF_RESTORE_INT_SIZE + THREAD_LAUNCHER_SIZE))\n+\n+HCD_CONST(CORE_RESTORE_THREAD_AREA_SIZE, (ONE_KB))\n+HCD_CONST(CORE_RESTORE_CORE_AREA_SIZE, (ONE_KB))\n+HCD_CONST(CORE_RESTORE_SIZE_PER_THREAD,\n+ (CORE_RESTORE_THREAD_AREA_SIZE + CORE_RESTORE_CORE_AREA_SIZE))\n+HCD_CONST(SELF_RESTORE_CORE_REGS_SIZE,\n+ (CORE_RESTORE_SIZE_PER_THREAD*\n+ MAX_THREADS_PER_CORE* MAX_CORES_PER_CHIP))\n+\n+HCD_CONST(SELF_RESTORE_SIZE_TOTAL,\n+ (SELF_RESTORE_CODE_SIZE + SELF_RESTORE_CORE_REGS_SIZE))\n+\n+\n+/// Core Scom\n+\n+HCD_CONST(CORE_SCOM_RESTORE_CPMR_OFFSET, (256 * ONE_KB))\n+HCD_CONST(CORE_SCOM_RESTORE_HOMER_OFFSET,\n+ (CORE_SCOM_RESTORE_CPMR_OFFSET + CPMR_HOMER_OFFSET))\n+\n+HCD_CONST(MAX_CORE_SCOM_ENTRIES, 15)\n+HCD_CONST(CORE_SCOM_RESTORE_REGS_PER_CORE, (MAX_CORE_SCOM_ENTRIES + 1))\n+\n+HCD_CONST(CORE_SCOM_RESTORE_SIZE_PER_CORE,\n+ (SCOM_RESTORE_ENTRY_SIZE* CORE_SCOM_RESTORE_REGS_PER_CORE)) // 16*16=256\n+HCD_CONST(CORE_SCOM_RESTORE_SIZE_PER_CME,\n+ (CORE_SCOM_RESTORE_SIZE_PER_CORE* MAX_CORES_PER_CME)) // 256*2=512\n+\n+HCD_CONST(CORE_SCOM_RESTORE_SIZE_TOTAL,\n+ (CORE_SCOM_RESTORE_SIZE_PER_CME* MAX_CMES_PER_CHIP)) // 512*12=6K\n+\n+/// CME Image\n+\n+HCD_CONST(CME_IMAGE_CPMR_OFFSET,\n+ (CORE_SCOM_RESTORE_CPMR_OFFSET + CORE_SCOM_RESTORE_SIZE_TOTAL))\n+//HCD_CONST(CME_IMAGE_SIZE, 0)\n+HCD_CONST(CME_INT_VECTOR_SIZE, 384)\n+\n+/// CME Header\n+\n+HCD_CONST(CME_HEADER_CPMR_OFFSET,\n+ (CME_IMAGE_CPMR_OFFSET + CME_INT_VECTOR_SIZE))\n+HCD_CONST(CME_HEADER_IMAGE_OFFSET, CME_INT_VECTOR_SIZE)\n+HCD_CONST(CME_HEADER_SIZE, 128)\n+\n+HCD_CONST(CME_MAGIC_NUMBER_BYTE, 0x00)\n+HCD_CONST(CME_HCODE_OFFSET_BYTE, 0x08)\n+HCD_CONST(CME_HCODE_LENGTH_BYTE, 0x0C)\n+HCD_CONST(CME_CORE_COMMON_RING_OFFSET_BYTE, 0x10)\n+HCD_CONST(CME_CORE_OVERRIDE_RING_OFFSET_BYTE, 0x14)\n+HCD_CONST(CME_CORE_COMMON_RING_LENGTH_BYTE, 0x18)\n+HCD_CONST(CME_LOCAL_PSTATE_OFFSET_BYTE, 0x1C)\n+HCD_CONST(CME_LOCAL_PSTATE_LENGTH_BYTE, 0x20)\n+HCD_CONST(CME_CORE_SPECIFIC_RING_OFFSET_BYTE, 0x24)\n+HCD_CONST(CME_CORE_SPECIFIC_RING_LENGTH_BYTE, 0x28)\n+HCD_CONST(CME_CORE_SCOM_RESTORE_OFFSET_BYTE, 0x2C)\n+HCD_CONST(CME_CORE_SCOM_RESTORE_LENGTH_BYTE, 0x30)\n+HCD_CONST(CME_STOP_FLAGS_BYTE, 0x34)\n+HCD_CONST(CME_LOCATION_ID_BYTE, 0x38)\n+HCD_CONST(CME_QM_FLAGS_BYTE, 0x3A)\n+HCD_CONST(CME_HOMER_ADDRESS_BYTE, 0x40)\n+\n+HCD_CONST(CME_HCODE_OFF_IMAGE_OFFSET, (CME_HEADER_IMAGE_OFFSET + CME_HCODE_OFFSET_BYTE))\n+HCD_CONST(CME_HCODE_LEN_IMAGE_OFFSET, (CME_HEADER_IMAGE_OFFSET + CME_HCODE_LENGTH_BYTE))\n+\n+HCD_CONST(CME_STOP_3_TO_2_BIT_POS, 0x80000000)\n+HCD_CONST(CME_STOP_4_TO_2_BIT_POS, 0x40000000)\n+HCD_CONST(CME_STOP_5_TO_4_BIT_POS, 0x20000000)\n+HCD_CONST(CME_STOP_8_TO_5_BIT_POS, 0x10000000)\n+HCD_CONST(CME_STOP_11_TO_8_BIT_POS, 0x08000000)\n+HCD_CONST(CME_VDM_ENABLE_BIT_POS, 0x04000000)\n+HCD_CONST(CME_STOP_MAPPING_DISABLE_BIT_POS, 0x00000004)\n+HCD_CONST(CME_QUEUED_SCAN_DISABLE_BIT_POS, 0x00000002)\n+HCD_CONST(CME_SKIP_CORE_POWEROFF_BIT_POS, 0x00000001)\n+HCD_CONST(CME_QM_FLAG_RESCLK_ENABLE, 0x8000)\n+HCD_CONST(CME_QM_FLAG_SYS_IVRM_ENABLE, 0x4000)\n+HCD_CONST(CME_QM_FLAG_SYS_VDM_ENABLE, 0x2000)\n+HCD_CONST(CME_QM_FLAG_SYS_WOF_ENABLE, 0x1000)\n+HCD_CONST(CME_QM_FLAG_SYS_DYN_FMIN_ENABLE, 0x0800)\n+HCD_CONST(CME_QM_FLAG_SYS_DYN_FMAX_ENABLE, 0x0400)\n+HCD_CONST(CME_QM_FLAG_SYS_JUMP_PROTECT, 0x0200)\n+\n+/// CME Hcode\n+\n+HCD_CONST(CME_HCODE_IMAGE_OFFSET, (CME_INT_VECTOR_SIZE + CME_HEADER_SIZE))\n+//HCD_CONST(CME_HCODE_SIZE, 0)\n+HCD_CONST(CME_DEBUG_PTRS_OFFSET, 0x200)\n+HCD_CONST(CME_DEBUG_PTRS_SIZE, 0x24)\n+HCD_CONST(CME_INSTRUMENTATION_SIZE, HALF_KB)\n+HCD_CONST(CME_SRAM_HCODE_OFFSET, 0)\n+\n+/// Core Scan\n+\n+HCD_CONST(CORE_COMMON_RING_SIZE, (2 * ONE_KB))\n+HCD_CONST(CORE_OVERRIDE_RING_SIZE, (1 * ONE_KB))\n+HCD_CONST(CORE_SPECIFIC_RING_SIZE_PER_CORE, (1 * ONE_KB))\n+HCD_CONST(CORE_SPECIFIC_RING_SIZE_TOTAL, (32 * ONE_KB)) // rounded to 32K\n+\n+/// Quad P-State\n+\n+HCD_CONST(CME_QUAD_PSTATE_SIZE, HALF_KB)\n+\n+// CME Hcode + Core Scan + Pstate\n+\n+HCD_CONST(CME_REGION_SIZE, (64 * ONE_KB))\n+\n+// Debug\n+\n+HCD_CONST(CPMR_TRACE_REGION_OFFSET, (512 * ONE_KB))\n+HCD_CONST(CME_TRACE_REGION_SIZE, (16 * ONE_KB))\n+HCD_CONST(CPMR_TRACE_REGION_SIZE, (CME_TRACE_REGION_SIZE* MAX_CMES_PER_CHIP)) // 192K\n+HCD_CONST(CPMR_DEBUG_REGION_OFFSET, CPMR_TRACE_REGION_OFFSET + CPMR_TRACE_REGION_SIZE)\n+HCD_CONST(CPMR_DEBUG_REGION_SIZE, (64 * ONE_KB)) // 192K + 64K = 256K\n+\n+\n+\n+//---------------------------------------------------------------------------------------\n+\n+/// PPMR Header\n+\n+HCD_CONST(PPMR_HOMER_OFFSET, (HOMER_PPMR_REGION_NUM* ONE_MB))\n+HCD_CONST(PPMR_HEADER_SIZE, 512)\n+\n+HCD_CONST(PPMR_MAGIC_NUMBER_BYTE, 0x00)\n+HCD_CONST(PPMR_BOOT_COPIER_OFFSET_BYTE, 0x08)\n+HCD_CONST(PPMR_BOOT_LOADER_OFFSET_BYTE, 0x10)\n+HCD_CONST(PPMR_BOOT_LOADER_LENGTH_BYTE, 0x14)\n+HCD_CONST(PPMR_BUILD_DATE_BYTE, 0x18)\n+HCD_CONST(PPMR_BUILD_VER_BYTE, 0x1C)\n+HCD_CONST(PPMR_PGPE_HCODE_OFFSET_BYTE, 0x28)\n+HCD_CONST(PPMR_PGPE_HCODE_LENGTH_BYTE, 0x2C)\n+HCD_CONST(PPMR_GLOBAL_PSTATE_OFFSET_BYTE, 0x30)\n+HCD_CONST(PPMR_GLOBAL_PSTATE_LENGTH_BYTE, 0x34)\n+HCD_CONST(PPMR_LOCAL_PSTATE_OFFSET_BYTE, 0x38)\n+HCD_CONST(PPMR_LOCAL_PSTATE_LENGTH_BYTE, 0x3C)\n+HCD_CONST(PPMR_OCC_PSTATE_OFFSET_BYTE, 0x40)\n+HCD_CONST(PPMR_OCC_PSTATE_LENGTH_BYTE, 0x44)\n+HCD_CONST(PPMR_PSTATE_TABLE_OFFSET_BYTE, 0x48)\n+HCD_CONST(PPMR_PSTATE_TABLE_LENGTH_BYTE, 0x4C)\n+HCD_CONST(PPMR_PGPE_SRAM_IMAGE_SIZE_BYTE, 0x50)\n+HCD_CONST(PPMR_PGPE_BOOT_PROG_CODE_BYTE, 0x54)\n+\n+/// PGPE Boot\n+\n+HCD_CONST(PGPE_BOOT_COPIER_PPMR_OFFSET, PPMR_HEADER_SIZE)\n+HCD_CONST(PGPE_BOOT_COPIER_SIZE, ONE_KB)\n+\n+HCD_CONST(PGPE_BOOT_LOADER_PPMR_OFFSET,\n+ (PGPE_BOOT_COPIER_PPMR_OFFSET + PGPE_BOOT_COPIER_SIZE))\n+HCD_CONST(PGPE_BOOT_LOADER_SIZE, ONE_KB)\n+HCD_CONST(PGPE_BOOT_LOADER_RESET_ADDR_VAL, 0x40)\n+\n+HCD_CONST(PGPE_INSTRUMENTATION_SIZE, (2 * ONE_KB))\n+\n+/// PGPE Image\n+\n+HCD_CONST(PGPE_AUX_TASK_SIZE, (2 * ONE_KB))\n+HCD_CONST(PGPE_IMAGE_PPMR_OFFSET,\n+ (PGPE_BOOT_LOADER_PPMR_OFFSET + PGPE_BOOT_LOADER_SIZE))\n+HCD_CONST(PGPE_IMAGE_SIZE, (48 * ONE_KB)) //RTC158543\n+HCD_CONST(PGPE_INT_VECTOR_SIZE, 384)\n+HCD_CONST(PGPE_HCODE_RESET_ADDR_VAL, 0x40)\n+\n+/// PGPE Header\n+\n+HCD_CONST(PGPE_HEADER_IMAGE_OFFSET, PGPE_INT_VECTOR_SIZE)\n+HCD_CONST(PGPE_HEADER_PPMR_OFFSET,\n+ (PGPE_IMAGE_PPMR_OFFSET + PGPE_INT_VECTOR_SIZE))\n+HCD_CONST(PGPE_HEADER_SIZE, 128)\n+\n+HCD_CONST(PGPE_MAGIC_NUMBER_BYTE, 0x00)\n+HCD_CONST(PGPE_SYSTEM_RESET_ADDR_BYTE, 0x08)\n+HCD_CONST(PGPE_SHARED_SRAM_ADDR_BYTE, 0x0C)\n+HCD_CONST(PGPE_IVPR_ADDR_BYTE, 0x10)\n+HCD_CONST(PGPE_SHARED_SRAM_LENGTH_BYTE, 0x14)\n+HCD_CONST(PGPE_BUILD_DATE_BYTE, 0x18)\n+HCD_CONST(PGPE_BUILD_VER_BYTE, 0x1C)\n+HCD_CONST(PGPE_PGPE_FLAGS_BYTE, 0x20)\n+HCD_CONST(PGPE_GLOBAL_PSTATE_SRAM_ADDR_BYTE, 0x28)\n+HCD_CONST(PGPE_GLOBAL_PSTATE_MEM_OFFSET_BYTE, 0x30)\n+HCD_CONST(PGPE_GLOBAL_PSTATE_PPB_SIZE_BYTE, 0x34)\n+HCD_CONST(PGPE_GEN_PSTATE_TABLE_MEM_OFFSET_BYTE, 0x38)\n+HCD_CONST(PGPE_GEN_PSTATE_TABLE_SIZE_BYTE, 0x3C)\n+HCD_CONST(PGPE_OCC_PSTATE_TABLE_MEM_OFFSET_BYTE, 0x40)\n+HCD_CONST(PGPE_OCC_PSTATE_TABLE_SIZE_BYTE, 0x44)\n+HCD_CONST(PGPE_BEACON_ADDR_BYTE, 0x48)\n+HCD_CONST(PGPE_ACTUAL_QUAD_STATUS_ADDR_BYTE, 0x4C)\n+HCD_CONST(PGPE_WOF_TABLE_ADDR_BYTE, 0x50)\n+HCD_CONST(PGPE_WOF_TABLE_LENGTH_BYTE, 0x54)\n+\n+HCD_CONST(PGPE_RESET_ADDR_IMAGE_OFFSET, (PGPE_HEADER_IMAGE_OFFSET + PGPE_SYSTEM_RESET_ADDR_BYTE))\n+HCD_CONST(PGPE_BUILD_DATE_IMAGE_OFFSET, (PGPE_HEADER_IMAGE_OFFSET + PGPE_BUILD_DATE_BYTE))\n+HCD_CONST(PGPE_BUILD_VER_IMAGE_OFFSET, (PGPE_HEADER_IMAGE_OFFSET + PGPE_BUILD_VER_BYTE))\n+\n+/// PGPE Hcode\n+\n+//HCD_CONST(PGPE_HCODE_SIZE, (32 * ONE_KB)) //RTC158543\n+HCD_CONST(PGPE_DBG_PTR_AREA_SIZE, 64)\n+HCD_CONST(PGPE_GLOBAL_PSTATE_PARAM_BLOCK_SIZE, (4 * ONE_KB))\n+\n+/// Pstate Parameter Block + Pstate Table\n+\n+HCD_CONST(OCC_PSTATE_PARAM_BLOCK_PPMR_OFFSET, (128 * ONE_KB))\n+HCD_CONST(OCC_PSTATE_PARAM_BLOCK_SIZE, (8 * ONE_KB))\n+HCD_CONST(OCC_PSTATE_PARAM_BLOCK_REGION_SIZE, (16 * ONE_KB))\n+\n+HCD_CONST(PGPE_PSTATE_OUTPUT_TABLES_PPMR_OFFSET, (144 * ONE_KB))\n+HCD_CONST(PGPE_PSTATE_OUTPUT_TABLES_SIZE, (8 * ONE_KB))\n+HCD_CONST(PGPE_PSTATE_OUTPUT_TABLES_REGION_SIZE, (16 * ONE_KB))\n+\n+HCD_CONST(OCC_WOF_TABLES_PPMR_OFFSET, (768 * ONE_KB))\n+HCD_CONST(OCC_WOF_TABLES_SIZE, (256 * ONE_KB))\n+\n+HCD_CONST(WOF_TABLE_RESERVE,\n+ OCC_WOF_TABLES_PPMR_OFFSET - (PGPE_PSTATE_OUTPUT_TABLES_PPMR_OFFSET + PGPE_PSTATE_OUTPUT_TABLES_REGION_SIZE))\n+HCD_CONST(PGPE_IMAGE_RESERVE_SIZE,\n+ (OCC_PSTATE_PARAM_BLOCK_PPMR_OFFSET - PGPE_IMAGE_PPMR_OFFSET - PGPE_IMAGE_SIZE - PGPE_AUX_TASK_SIZE))\n+\n+#endif /* __HCD_MEMMAP_BASE_H__ */\ndiff --git a/libpore/p9_stop_api.C b/libpore/p9_stop_api.C\nnew file mode 100644\nindex 0000000..26a14bb\n--- /dev/null\n+++ b/libpore/p9_stop_api.C\n@@ -0,0 +1,1028 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+\n+///\n+/// @file p9_stop_api.C\n+/// @brief implements STOP API which create/manipulate STOP image.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+\n+#include \"p9_stop_api.H\"\n+#include \"p9_cpu_reg_restore_instruction.H\"\n+#include \"p9_stop_data_struct.H\"\n+#include <string.h>\n+#include \"p9_stop_util.H\"\n+#include <stdio.h>\n+\n+#ifdef __FAPI_2_\n+ #include <fapi2.H>\n+#endif\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+\n+namespace stopImageSection\n+{\n+#endif\n+// a true in the table below means register is of scope thread\n+// whereas a false meanse register is of scope core.\n+\n+const StopSprReg_t g_sprRegister[] =\n+{\n+ { P9_STOP_SPR_HSPRG0, true },\n+ { P9_STOP_SPR_HRMOR, false },\n+ { P9_STOP_SPR_LPCR, true },\n+ { P9_STOP_SPR_HMEER, false },\n+ { P9_STOP_SPR_LDBAR, true },\n+ { P9_STOP_SPR_PSSCR, true },\n+ { P9_STOP_SPR_PMCR, false },\n+ { P9_STOP_SPR_HID, false },\n+ { P9_STOP_SPR_MSR, true },\n+ { P9_STOP_SPR_DAWR, true },\n+};\n+\n+const uint32_t MAX_SPR_SUPPORTED =\n+ sizeof ( g_sprRegister ) / sizeof( StopSprReg_t );\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief validates input arguments provided by STOP API caller.\n+ * @param[in] i_pImage pointer to beginning of chip's HOMER image.\n+ * @param[in] i_regId SPR register id\n+ * @param[in] i_coreId core id\n+ * @param[in|out] i_pThreadId points to thread id\n+ * @param[in|out] i_pThreadLevelReg points to scope information of SPR\n+ * @return STOP_SAVE_SUCCESS if arguments found valid, error code otherwise.\n+ * @note for register of scope core, function shall force io_threadId to\n+ * zero.\n+ */\n+static StopReturnCode_t validateSprImageInputs( void* const i_pImage,\n+ const CpuReg_t i_regId,\n+ const uint32_t i_coreId,\n+ uint32_t* i_pThreadId,\n+ bool* i_pThreadLevelReg )\n+{\n+ uint32_t index = 0;\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+ bool sprSupported = false;\n+ *i_pThreadLevelReg = false;\n+\n+ do\n+ {\n+ if( NULL == i_pImage )\n+ {\n+ // Error: HOMER image start location is not valid\n+ // Cannot proceed further. So, let us exit.\n+ l_rc = STOP_SAVE_ARG_INVALID_IMG;\n+ MY_ERR( \"invalid image location \" );\n+\n+ break;\n+ }\n+\n+ // STOP API manages STOP image based on physical core Id. PIR value\n+ // is interpreted to calculate the physical core number and virtual\n+ // thread number.\n+ if( MAX_CORE_ID_SUPPORTED < i_coreId )\n+ {\n+ // Error: invalid core number. given core number exceeds maximum\n+ // cores supported by chip.\n+\n+ // Physical core number is calculated based on following formula:\n+ // core id = 4 * quad id (0..5) + core no within quad ( 0..3)\n+ l_rc = STOP_SAVE_ARG_INVALID_CORE;\n+ MY_ERR( \"invalid core id \" );\n+ break;\n+ }\n+\n+ if( MAX_THREAD_ID_SUPPORTED < *i_pThreadId )\n+ {\n+ //Error: invalid core thread. Given core thread exceeds maximum\n+ //threads supported in a core.\n+\n+ // 64 bit PIR value is interpreted to calculate virtual thread\n+ // Id. In fuse mode, b61 and b62 gives virtual thread id whereas in\n+ // non fuse mode, b62 and b63 is read to determine the same.\n+\n+ l_rc = STOP_SAVE_ARG_INVALID_THREAD;\n+ MY_ERR( \"invalid thread \" );\n+ break;\n+ }\n+\n+ for( index = 0; index < MAX_SPR_SUPPORTED; ++index )\n+ {\n+ if( i_regId == (CpuReg_t )g_sprRegister[index].sprId )\n+ {\n+ // given register is in the list of register supported\n+ sprSupported = true;\n+ *i_pThreadLevelReg = g_sprRegister[index].isThreadScope;\n+ *i_pThreadId = *i_pThreadLevelReg ? *i_pThreadId : 0;\n+ break;\n+ }\n+ }\n+\n+ if( !sprSupported )\n+ {\n+ // Following SPRs are supported\n+ // trace out all registers supported\n+ MY_ERR(\"Register not supported\" );\n+ // error code to caller.\n+ l_rc = STOP_SAVE_ARG_INVALID_REG;\n+ break;\n+ }\n+\n+ }\n+ while(0);\n+\n+ if( l_rc )\n+ {\n+ MY_ERR( \"image 0x%08x, regId %08d, coreId %d, \"\n+ \"threadId %d return code 0x%08x\", i_pImage, i_regId,\n+ i_coreId, *i_pThreadId, l_rc );\n+ }\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief generates ori instruction code.\n+ * @param[in] i_Rs Source register number\n+ * @param[in] i_Ra destination register number\n+ * @param[in] i_data 16 bit immediate data\n+ * @return returns 32 bit number representing ori instruction.\n+ */\n+static uint32_t getOriInstruction( const uint16_t i_Rs, const uint16_t i_Ra,\n+ const uint16_t i_data )\n+{\n+ uint32_t oriInstOpcode = 0;\n+ oriInstOpcode = 0;\n+ oriInstOpcode = ORI_OPCODE << 26;\n+ oriInstOpcode |= i_Rs << 21;\n+ oriInstOpcode |= i_Ra << 16;\n+ oriInstOpcode |= i_data;\n+\n+ return SWIZZLE_4_BYTE(oriInstOpcode);\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief generates 32 bit key used for SPR lookup in core section.\n+ */\n+static uint32_t genKeyForSprLookup( const CpuReg_t i_regId )\n+{\n+ return getOriInstruction( 0, 0, (uint16_t) i_regId );\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief generates xor instruction code.\n+ * @param[in] i_Rs source register number for xor operation\n+ * @param[in] i_Ra destination register number for xor operation result\n+ * @param[in] i_Rb source register number for xor operation\n+ * @return returns 32 bit number representing xor immediate instruction.\n+ */\n+static uint32_t getXorInstruction( const uint16_t i_Ra, const uint16_t i_Rs,\n+ const uint16_t i_Rb )\n+{\n+ uint32_t xorRegInstOpcode;\n+ xorRegInstOpcode = XOR_CONST << 1;\n+ xorRegInstOpcode |= OPCODE_31 << 26;\n+ xorRegInstOpcode |= i_Rs << 21;\n+ xorRegInstOpcode |= i_Ra << 16;\n+ xorRegInstOpcode |= i_Rb << 11;\n+\n+ return SWIZZLE_4_BYTE(xorRegInstOpcode);\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief generates oris instruction code.\n+ * @param[in] i_Rs source register number\n+ * @param[in] i_Ra destination register number\n+ * @param[in] i_data 16 bit immediate data\n+ * @return returns 32 bit number representing oris immediate instruction.\n+ */\n+static uint32_t getOrisInstruction( const uint16_t i_Rs, const uint16_t i_Ra,\n+ const uint16_t i_data )\n+{\n+ uint32_t orisInstOpcode;\n+ orisInstOpcode = 0;\n+ orisInstOpcode = ORIS_OPCODE << 26;\n+ orisInstOpcode |= ( i_Rs & 0x001F ) << 21 | ( i_Ra & 0x001F ) << 16;\n+ orisInstOpcode |= i_data;\n+\n+ return SWIZZLE_4_BYTE(orisInstOpcode);\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief generates instruction for mtspr\n+ * @param[in] i_Rs source register number\n+ * @param[in] i_Spr represents spr where data is to be moved.\n+ * @return returns 32 bit number representing mtspr instruction.\n+ */\n+static uint32_t getMtsprInstruction( const uint16_t i_Rs, const uint16_t i_Spr )\n+{\n+ uint32_t mtsprInstOpcode = 0;\n+ uint32_t temp = (( i_Spr & 0x03FF ) << 11);\n+ mtsprInstOpcode = (uint8_t)i_Rs << 21;\n+ mtsprInstOpcode = ( temp & 0x0000F800 ) << 5;\n+ mtsprInstOpcode |= ( temp & 0x001F0000 ) >> 5;\n+ mtsprInstOpcode |= MTSPR_BASE_OPCODE;\n+\n+ return SWIZZLE_4_BYTE(mtsprInstOpcode);\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief generates rldicr instruction.\n+ * @param[in] i_Rs source register number\n+ * @param[in] i_Ra destination register number\n+ * @param[in] i_sh bit position by which contents of i_Rs are to be shifted\n+ * @param[in] i_me bit position up to which mask should be 1.\n+ * @return returns 32 bit number representing rldicr instruction.\n+ */\n+static uint32_t getRldicrInstruction( const uint16_t i_Ra, const uint16_t i_Rs,\n+ const uint16_t i_sh, uint16_t i_me )\n+{\n+ uint32_t rldicrInstOpcode = 0;\n+ rldicrInstOpcode = 0;\n+ rldicrInstOpcode = ((RLDICR_OPCODE << 26 ) | ( i_Rs << 21 ) | ( i_Ra << 16 ));\n+ rldicrInstOpcode |= ( ( i_sh & 0x001F ) << 11 ) | (RLDICR_CONST << 2 );\n+ rldicrInstOpcode |= (( i_sh & 0x0020 ) >> 4);\n+ rldicrInstOpcode |= (i_me & 0x001F ) << 6;\n+ rldicrInstOpcode |= (i_me & 0x0020 );\n+ return SWIZZLE_4_BYTE(rldicrInstOpcode);\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief looks up entry for given SPR in given thread/core section.\n+ * @param[in] i_pThreadSectLoc start of given thread section or core section.\n+ * @param[in] i_lookUpKey search key for lookup of given SPR entry.\n+ * @param[in] i_isCoreReg true if register is of scope core, false\n+ * otherwise.\n+ * @param[in|out] io_pSprEntryLoc Input: NULL\n+ * Output: location of given entry or end of table.\n+ * @return STOP_SAVE_SUCCESS if entry is found, STOP_SAVE_FAIL in case of\n+ * an error.\n+ */\n+static StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc,\n+ const uint32_t i_lookUpKey,\n+ const bool i_isCoreReg,\n+ void** io_pSprEntryLoc )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_FAIL;\n+ uint32_t temp = i_isCoreReg ? (uint32_t)(CORE_RESTORE_CORE_AREA_SIZE) :\n+ (uint32_t)(CORE_RESTORE_THREAD_AREA_SIZE);\n+ uint32_t* i_threadSectEnd = i_pThreadSectLoc + temp;\n+ uint32_t bctr_inst = SWIZZLE_4_BYTE(BLR_INST);\n+ *io_pSprEntryLoc = NULL;\n+\n+ do\n+ {\n+ if( !i_pThreadSectLoc )\n+ {\n+ break;\n+ }\n+\n+ temp = 0;\n+\n+ while( ( i_pThreadSectLoc <= i_threadSectEnd ) &&\n+ ( temp != bctr_inst ) )\n+ {\n+ temp = *i_pThreadSectLoc;\n+\n+ if( ( temp == i_lookUpKey ) || ( temp == bctr_inst ) )\n+ {\n+ *io_pSprEntryLoc = i_pThreadSectLoc;\n+ l_rc = STOP_SAVE_SUCCESS;\n+ break;\n+ }\n+\n+ i_pThreadSectLoc = i_pThreadSectLoc + SIZE_PER_SPR_RESTORE_INST;\n+ }\n+\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief updates an SPR STOP image entry.\n+ * @param[in] i_pSprEntryLocation location of entry.\n+ * @param[in] i_regId register Id associated with SPR.\n+ * @param[in] i_regData data needs to be written to SPR entry.\n+ * @return STOP_SAVE_SUCCESS if update works, STOP_SAVE_FAIL otherwise.\n+ */\n+static StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation,\n+ const CpuReg_t i_regId,\n+ const uint64_t i_regData )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+ uint32_t tempInst = 0;\n+ uint64_t tempRegData = 0;\n+ bool newEntry = true;\n+ uint16_t regRs = 0; //to use R0 for SPR restore insruction generation\n+ uint16_t regRa = 0;\n+\n+ do\n+ {\n+ if( !i_pSprEntryLocation )\n+ {\n+ MY_ERR(\"invalid location of SPR image entry\" );\n+ l_rc = STOP_SAVE_FAIL;\n+ break;\n+ }\n+\n+ tempInst = genKeyForSprLookup( i_regId );\n+\n+ if( *i_pSprEntryLocation == tempInst )\n+ {\n+ newEntry = false;\n+ }\n+\n+ //Add SPR search instruction i.e. \"ori r0, r0, SPRID\"\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ //clear R0 i.e. \"xor ra, rs, rb\"\n+ tempInst = getXorInstruction( regRs, regRs, regRs );\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ tempRegData = i_regData >> 48;\n+ //get lower order 16 bits of SPR restore value in R0\n+ tempInst = getOrisInstruction( regRs, regRa, (uint16_t)tempRegData );\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ tempRegData = ((i_regData >> 32) & 0x0000FFFF );\n+ //get bit b16-b31 of SPR restore value in R0\n+ tempInst = getOriInstruction( regRs, regRa, (uint16_t)tempRegData );\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ //Rotate R0 to left by 32 bit position and zero lower order 32 bits.\n+ //Place the result in R0\n+ tempInst = getRldicrInstruction(regRa, regRs, 32, 31);\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ tempRegData = ((i_regData >> 16) & 0x000000FFFF );\n+ //get bit b32-b47 of SPR restore value to R0\n+ tempInst = getOrisInstruction( regRs, regRa, (uint16_t)tempRegData );\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ tempRegData = (uint16_t)i_regData;\n+ //get bit b48-b63 of SPR restore value to R0\n+ tempInst = getOriInstruction( regRs, regRa, (uint16_t)i_regData );\n+ *i_pSprEntryLocation = tempInst;\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+\n+ if( P9_STOP_SPR_MSR == i_regId )\n+ {\n+ //MSR cannot be restored completely with mtmsrd instruction.\n+ //as it does not update ME, LE and HV bits. In self restore code\n+ //inorder to restore MSR, contents of R21 is moved to SRR1. It also\n+ //executes an RFID which causes contents of SRR1 to be copied to\n+ //MSR. This allows copy of LE bit which are specifically interested\n+ //in. Instruction below moves contents of MSR Value (in R0 ) to R21.\n+ tempInst = SWIZZLE_4_BYTE( MR_R0_TO_R21 );\n+ }\n+ else if (P9_STOP_SPR_HRMOR == i_regId )\n+ {\n+ //Case HRMOR, move contents of R0 to a placeholder GPR (R10)\n+ //Thread Launcher expects HRMOR value in R10\n+ tempInst = SWIZZLE_4_BYTE( MR_R0_TO_R10 );\n+ }\n+ else\n+ {\n+ // Case other SPRs, move contents of R0 to SPR\n+ tempInst =\n+ getMtsprInstruction( 0, (uint16_t)i_regId );\n+ }\n+\n+ *i_pSprEntryLocation = tempInst;\n+\n+ if( newEntry )\n+ {\n+ i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST;\n+ //at the end of SPR restore, add instruction BLR to go back to thread\n+ //launcher.\n+ tempInst = SWIZZLE_4_BYTE(BLR_INST);\n+ *i_pSprEntryLocation = tempInst;\n+ }\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage,\n+ const CpuReg_t i_regId,\n+ const uint64_t i_regData,\n+ const uint64_t i_pir )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; // procedure return code\n+ HomerSection_t* chipHomer = NULL;\n+\n+ do\n+ {\n+ uint32_t threadId = 0;\n+ uint32_t coreId = 0;\n+ uint32_t lookUpKey = 0;\n+ void* pSprEntryLocation = NULL; // an offset w.r.t. to start of image\n+ void* pThreadLocation = NULL;\n+ bool threadScopeReg = false;\n+\n+ l_rc = getCoreAndThread( i_pImage, i_pir, &coreId, &threadId );\n+\n+ if( l_rc )\n+ {\n+ MY_ERR(\"Failed to determine Core Id and Thread Id from PIR 0x%016llx\",\n+ i_pir);\n+ break;\n+ }\n+\n+ MY_INF( \" PIR 0x%016llx coreId %d threadid %d \"\n+ \" registerId %d\", i_pir, coreId,\n+ threadId, i_regId );\n+\n+ // First of all let us validate all input arguments.\n+ l_rc = validateSprImageInputs( i_pImage,\n+ i_regId,\n+ coreId,\n+ &threadId,\n+ &threadScopeReg );\n+\n+ if( l_rc )\n+ {\n+ // Error: bad argument traces out error code\n+ MY_ERR(\"Bad input argument rc %d\", l_rc );\n+\n+ break;\n+ }\n+\n+ chipHomer = ( HomerSection_t*)i_pImage;\n+\n+ if( threadScopeReg )\n+ {\n+ pThreadLocation =\n+ &(chipHomer->coreThreadRestore[coreId][threadId].threadArea[0]);\n+ }\n+ else\n+ {\n+ pThreadLocation =\n+ &(chipHomer->coreThreadRestore[coreId][threadId].coreArea[0]);\n+ }\n+\n+ if( ( SWIZZLE_4_BYTE(BLR_INST) == *(uint32_t*)pThreadLocation ) ||\n+ ( SWIZZLE_4_BYTE(ATTN_OPCODE) == *(uint32_t*) pThreadLocation ) )\n+ {\n+ // table for given core id doesn't exit. It needs to be\n+ // defined.\n+ pSprEntryLocation = pThreadLocation;\n+ }\n+ else\n+ {\n+ // an SPR restore section for given core already exists\n+ lookUpKey = genKeyForSprLookup( i_regId );\n+ l_rc = lookUpSprInImage( (uint32_t*)pThreadLocation,\n+ lookUpKey,\n+ threadScopeReg,\n+ &pSprEntryLocation );\n+ }\n+\n+ if( l_rc )\n+ {\n+ MY_ERR(\"Invalid or corrupt SPR entry. CoreId 0x%08x threadId \",\n+ \"0x%08x regId 0x%08x lookUpKey 0x%08x pThreadLocation 0x%08x\"\n+ , coreId, threadId, i_regId, lookUpKey, pThreadLocation );\n+ break;\n+ }\n+\n+ l_rc = updateSprEntryInImage( (uint32_t*) pSprEntryLocation,\n+ i_regId,\n+ i_regData );\n+\n+ if( l_rc )\n+ {\n+ MY_ERR( \" Failed to update the SPR entry of PIR 0x%08x reg\"\n+ \"0x%08x\", i_pir, i_regId );\n+ break;\n+ }\n+\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief validates all the input arguments.\n+ * @param[in] i_pImage pointer to start of HOMER of image for proc chip.\n+ * @param[in] i_scomAddress SCOM address of register.\n+ * @param[in] i_chipletId core or cache chiplet id\n+ * @param[in] i_operation operation requested for SCOM entry.\n+ * @param[in] i_section image section on which operation is to be performed\n+ * @return STOP_SAVE_SUCCESS if arguments found valid, error code otherwise.\n+ * @note Function does not validate that the given SCOM address really\n+ * belongs to the given section.\n+ */\n+static StopReturnCode_t validateScomImageInputs( void* const i_pImage,\n+ const uint32_t i_scomAddress,\n+ const uint8_t i_chipletId,\n+ const ScomOperation_t i_operation,\n+ const ScomSection_t i_section )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+\n+ do\n+ {\n+ if( !i_pImage )\n+ {\n+ //Error Invalid image pointer\n+ l_rc = STOP_SAVE_ARG_INVALID_IMG;\n+ MY_ERR(\"invalid image location \");\n+ break;\n+ }\n+\n+ if( 0 == i_scomAddress )\n+ {\n+ l_rc = STOP_SAVE_SCOM_INVALID_ADDRESS;\n+ MY_ERR(\"invalid SCOM address\");\n+ break;\n+ }\n+\n+ if(( CACHE_CHIPLET_ID_MIN > i_chipletId ) ||\n+ ( CORE_CHIPLET_ID_MAX < i_chipletId ))\n+ {\n+ l_rc = STOP_SAVE_SCOM_INVALID_CHIPLET;\n+ MY_ERR(\"chiplet id not in range\");\n+ break;\n+ }\n+\n+ if(( CORE_CHIPLET_ID_MIN > i_chipletId ) &&\n+ ( CACHE_CHIPLET_ID_MAX < i_chipletId ))\n+ {\n+ l_rc = STOP_SAVE_SCOM_INVALID_CHIPLET;\n+ MY_ERR(\"chiplet id not valid\");\n+ break;\n+ }\n+\n+ if(( P9_STOP_SCOM_OP_MIN >= i_operation ) ||\n+ ( P9_STOP_SCOM_OP_MAX <= i_operation ))\n+ {\n+ //invalid SCOM image operation requested\n+ l_rc = STOP_SAVE_SCOM_INVALID_OPERATION;\n+ MY_ERR(\"invalid SCOM image operation\");\n+ break;\n+ }\n+\n+ if(( P9_STOP_SECTION_MIN >= i_section ) ||\n+ ( P9_STOP_SECTION_MAX <= i_section ))\n+ {\n+ // invalid cache sub section specified\n+ l_rc = STOP_SAVE_SCOM_INVALID_SECTION;\n+ MY_ERR(\"invalid section\");\n+ break;\n+ }\n+\n+ if(( i_operation == P9_STOP_SCOM_RESET ) &&\n+ ( i_chipletId < CORE_CHIPLET_ID_MIN ))\n+ {\n+ // replace requested with a cache chiplet Id\n+ l_rc = STOP_SAVE_SCOM_INVALID_OPERATION;\n+ MY_ERR( \"reset not supported for cache. chiplet Id 0x%08x\",\n+ i_chipletId );\n+ break;\n+ }\n+\n+ }\n+ while(0);\n+\n+ if( l_rc )\n+ {\n+ MY_ERR(\"image 0x%08x SCOMAddress 0x%08x chipletId 0x%08x operation\"\n+ \"0x%08x section 0x%08x\", i_pImage, i_scomAddress, i_chipletId,\n+ i_operation, i_section );\n+ }\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief edit SCOM entry associated with the given core.\n+ * @param[in] i_scomAddr SCOM address of register.\n+ * @param[in] i_scomData data associated with SCOM register.\n+ * @param[in] i_pEntryLocation points to a SCOM entry in HOMER image.\n+ * @param[in] i_operation operation to be performed on SCOM entry.\n+ * @return STOP_SAVE_SUCCESS if existing entry is updated, STOP_SAVE_FAIL\n+ * otherwise.\n+ */\n+static StopReturnCode_t editScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,\n+ ScomEntry_t* i_pEntryLocation,\n+ uint32_t i_operation )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+\n+ do\n+ {\n+ if( !i_pEntryLocation )\n+ {\n+ //Error: location of SCOM entry is not known\n+ //therefore no point moving forward\n+ MY_ERR(\"SCOM entry location not valid\");\n+ l_rc = STOP_SAVE_FAIL;\n+ break;\n+ }\n+\n+ switch( i_operation )\n+ {\n+ case P9_STOP_SCOM_OR:\n+ i_pEntryLocation->scomEntryData |= i_scomData;\n+ break;\n+\n+ case P9_STOP_SCOM_AND:\n+ i_pEntryLocation->scomEntryData &= i_scomData;\n+ break;\n+\n+ case P9_STOP_SCOM_NOOP:\n+ {\n+ uint32_t nopInst = getOriInstruction( 0, 0, 0 );\n+ i_pEntryLocation->scomEntryHeader = SWIZZLE_4_BYTE(SCOM_ENTRY_START);\n+ i_pEntryLocation->scomEntryData = nopInst;\n+ i_pEntryLocation->scomEntryAddress = nopInst;\n+ }\n+ break;\n+\n+ case P9_STOP_SCOM_APPEND:\n+ i_pEntryLocation->scomEntryHeader = SWIZZLE_4_BYTE(SCOM_ENTRY_START);\n+ i_pEntryLocation->scomEntryData = i_scomData;\n+ i_pEntryLocation->scomEntryAddress = i_scomAddr;\n+ break;\n+ }\n+\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+/**\n+ * @brief update SCOM entry associated with the given core.\n+ * @param[in] i_scomAddr SCOM address of register.\n+ * @param[in] i_scomData data associated with SCOM register.\n+ * @param[in] i_scomEntry points to a SCOM entry in cache section of HOMER image.\n+ * @return STOP_SAVE_SUCCESS if new entry is added, STOP_SAVE_FAIL otherwise.\n+ * @note adds an entry at a given location. It can be used to add entry in\n+ * place of NOP, at the end of table or as first entry of the cache\n+ * sub-section(L2, L3 or EQ ).\n+ */\n+static StopReturnCode_t updateScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,\n+ ScomEntry_t* i_scomEntry )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+\n+ do\n+ {\n+ if( !i_scomEntry )\n+ {\n+ MY_ERR( \"cache entry cannot be located\");\n+ l_rc = STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED;\n+ break;\n+ }\n+\n+ i_scomEntry->scomEntryHeader = SWIZZLE_4_BYTE(SCOM_ENTRY_START); // done for now\n+ i_scomEntry->scomEntryAddress = i_scomAddr;\n+ i_scomEntry->scomEntryData = i_scomData;\n+\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+//-----------------------------------------------------------------------------\n+\n+StopReturnCode_t p9_stop_save_scom( void* const i_pImage,\n+ const uint32_t i_scomAddress,\n+ const uint64_t i_scomData,\n+ const ScomOperation_t i_operation,\n+ const ScomSection_t i_section )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+ StopCacheSection_t* pStopCacheScomStart = NULL;\n+ ScomEntry_t* pScomEntry = NULL;\n+ uint32_t entryLimit = 0;\n+ uint8_t chipletId = 0;\n+\n+ uint32_t nopInst;\n+ ScomEntry_t* pEntryLocation = NULL;\n+ ScomEntry_t* pNopLocation = NULL;\n+ ScomEntry_t* pTableEndLocationtable = NULL;\n+ uint32_t swizzleAddr;\n+ uint64_t swizzleData;\n+ uint32_t swizzleAttn;\n+ uint32_t swizzleEntry;\n+ uint32_t index = 0;\n+ uint32_t swizzleBlr = SWIZZLE_4_BYTE(BLR_INST);\n+\n+ do\n+ {\n+ chipletId = i_scomAddress >> 24;\n+ chipletId = chipletId & 0x3F;\n+\n+ l_rc = validateScomImageInputs( i_pImage,\n+ i_scomAddress,\n+ chipletId,\n+ i_operation,\n+ i_section );\n+\n+ if( l_rc )\n+ {\n+ MY_ERR( \"invalid argument: aborting\");\n+ break;\n+ }\n+\n+ if( chipletId >= CORE_CHIPLET_ID_MIN )\n+ {\n+ // chiplet is core. So, let us find the start address of SCOM area\n+ // pertaining to a core in STOP image.\n+ pScomEntry = CORE_ID_SCOM_START(i_pImage,\n+ chipletId )\n+ entryLimit = MAX_CORE_SCOM_ENTRIES;\n+ }\n+ else\n+ {\n+ // chiplet is a cache. let us find start address of cache section\n+ // associated with given chiplet. A cache section associated with\n+ // given chiplet is split in to L2, L3 and EQ area.\n+ pStopCacheScomStart = CACHE_SECTN_START(i_pImage,\n+ chipletId);\n+ }\n+\n+ if(( !pStopCacheScomStart ) && ( !pScomEntry) )\n+ {\n+ //Error invalid pointer to SCOM entry in cache or core section\n+ //of STOP image.\n+ MY_ERR(\"invalid start location for chiplet %d\",\n+ chipletId );\n+ break;\n+ }\n+\n+ switch( i_section )\n+ {\n+ case P9_STOP_SECTION_EQ_SCOM:\n+ pScomEntry = pStopCacheScomStart->nonCacheArea;\n+ entryLimit = MAX_EQ_SCOM_ENTRIES;\n+ break;\n+\n+ case P9_STOP_SECTION_L2:\n+ pScomEntry = pStopCacheScomStart->l2CacheArea;\n+ entryLimit = MAX_L2_SCOM_ENTRIES;\n+ break;\n+\n+ case P9_STOP_SECTION_L3:\n+ pScomEntry = pStopCacheScomStart->l3CacheArea;\n+ entryLimit = MAX_L3_SCOM_ENTRIES;\n+ break;\n+\n+ case P9_STOP_SECTION_CORE_SCOM:\n+ //macro CORE_ID_SCOM_START already gives start of scom\n+ //entry for given core. entry limit too is assigned thereafter.\n+ //Handling for core and cache segment is different for scom\n+ //entries. It is because scom entries are organized differently\n+ //in core and cache segment.\n+ break;\n+\n+ default:\n+ l_rc = STOP_SAVE_SCOM_INVALID_SECTION;\n+ break;\n+ }\n+\n+ if(( !pScomEntry ) || ( l_rc ) )\n+ {\n+ // Error Invalid pointer to cache entry\n+ MY_ERR(\"invalid subsection %d or internal firmware failure\",\n+ i_section );\n+ l_rc = STOP_SAVE_FAIL;\n+ break;\n+ }\n+\n+ nopInst = getOriInstruction( 0, 0, 0 );\n+ pEntryLocation = NULL;\n+ pNopLocation = NULL;\n+ pTableEndLocationtable = NULL;\n+ swizzleAddr = SWIZZLE_4_BYTE(i_scomAddress);\n+ swizzleData = SWIZZLE_8_BYTE(i_scomData);\n+ swizzleAttn = SWIZZLE_4_BYTE(ATTN_OPCODE);\n+ swizzleEntry = SWIZZLE_4_BYTE(SCOM_ENTRY_START);\n+\n+ for( index = 0; index < entryLimit; ++index )\n+ {\n+ uint32_t entrySwzAddress = pScomEntry[index].scomEntryAddress;\n+\n+ if( ( swizzleAddr == entrySwzAddress ) && ( !pEntryLocation ) )\n+\n+ {\n+ pEntryLocation = &pScomEntry[index];\n+ }\n+\n+ if( (( nopInst == entrySwzAddress ) ||\n+ ( swizzleAttn == entrySwzAddress ) ||\n+ ( swizzleBlr == entrySwzAddress )) && ( !pNopLocation ) )\n+ {\n+ pNopLocation = &pScomEntry[index];\n+ }\n+\n+ if( swizzleEntry == pScomEntry[index].scomEntryHeader )\n+ {\n+ continue;\n+ }\n+\n+ pTableEndLocationtable = &pScomEntry[index];\n+ break;\n+ }\n+\n+ if( ( !pEntryLocation ) && ( !pTableEndLocationtable ) )\n+ {\n+ MY_ERR(\" exhausted all location available for section\"\n+ \"0x%08x scom address 0x%08x\",\n+ i_section, i_scomAddress );\n+ l_rc = STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED;\n+ break;\n+ }\n+\n+ switch( i_operation )\n+ {\n+ case P9_STOP_SCOM_APPEND:\n+ {\n+ ScomEntry_t* pScomAppend = NULL;\n+\n+ if( pNopLocation )\n+ {\n+ pScomAppend = pNopLocation;\n+ }\n+ else\n+ {\n+ pScomAppend = pTableEndLocationtable;\n+ }\n+\n+ l_rc = updateScomEntry ( swizzleAddr,\n+ swizzleData, pScomAppend );\n+ }\n+ break;\n+\n+ case P9_STOP_SCOM_REPLACE:\n+ {\n+ ScomEntry_t* scomReplace = NULL;\n+\n+ if( pEntryLocation )\n+ {\n+ scomReplace = pEntryLocation;\n+ }\n+ else\n+ {\n+ scomReplace = pTableEndLocationtable;\n+ }\n+\n+ l_rc = updateScomEntry( swizzleAddr,\n+ swizzleData, scomReplace );\n+ }\n+ break;\n+\n+ case P9_STOP_SCOM_OR:\n+ case P9_STOP_SCOM_AND:\n+ case P9_STOP_SCOM_NOOP:\n+\n+ if( pEntryLocation )\n+ {\n+ l_rc = editScomEntry( swizzleAddr,\n+ swizzleData,\n+ pEntryLocation,\n+ i_operation );\n+ }\n+ else\n+ {\n+ //Invalid operation requested.\n+ MY_ERR( \"entry not found edit chiplet Id 0x%08x \"\n+ \"swizzle addr 0x%08x \",\n+ chipletId, swizzleAddr );\n+\n+ l_rc = STOP_SAVE_SCOM_INVALID_OPERATION;\n+ }\n+\n+ break;\n+\n+ case P9_STOP_SCOM_RESET:\n+\n+ if( P9_STOP_SECTION_CORE_SCOM == i_section )\n+ {\n+ memset( pScomEntry, 0x00, CORE_SCOM_RESTORE_SIZE_PER_CORE );\n+ }\n+\n+ break;\n+\n+ case P9_STOP_SCOM_OR_APPEND:\n+ case P9_STOP_SCOM_AND_APPEND:\n+ {\n+ uint32_t tempOperation = P9_STOP_SCOM_APPEND;\n+ ScomEntry_t* editAppend = NULL;\n+\n+ if( NULL == pEntryLocation )\n+ {\n+ editAppend = pTableEndLocationtable;\n+ }\n+ else\n+ {\n+ editAppend = pEntryLocation;\n+\n+ if( P9_STOP_SCOM_OR_APPEND == i_operation )\n+ {\n+ tempOperation = P9_STOP_SCOM_OR;\n+ }\n+ else\n+ {\n+ tempOperation = P9_STOP_SCOM_AND;\n+ }\n+ }\n+\n+ l_rc = editScomEntry( swizzleAddr,\n+ swizzleData,\n+ editAppend,\n+ tempOperation );\n+ }\n+ break;\n+\n+ default:\n+ l_rc = STOP_SAVE_SCOM_INVALID_OPERATION;\n+ break;\n+ }\n+\n+ }\n+ while(0);\n+\n+ if( l_rc )\n+ {\n+ MY_ERR(\"SCOM image operation 0x%08x failed for chiplet 0x%08x addr\"\n+ \"0x%08x\", i_operation, chipletId ,\n+ i_scomAddress );\n+ }\n+\n+ return l_rc;\n+}\n+\n+\n+#ifdef __cplusplus\n+} //namespace stopImageSection ends\n+\n+} //extern \"C\"\n+#endif\ndiff --git a/libpore/p9_stop_api.H b/libpore/p9_stop_api.H\nnew file mode 100644\nindex 0000000..79abd00\n--- /dev/null\n+++ b/libpore/p9_stop_api.H\n@@ -0,0 +1,163 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+#ifndef __P9_STOP_IMAGE_API_\n+#define __P9_STOP_IMAGE_API_\n+\n+#include <stdint.h>\n+\n+#ifdef __SKIBOOT__\n+ #include <skiboot.h>\n+#endif\n+\n+///\n+/// @file p9_stop_api.H\n+/// @brief describes STOP API which create/manipulate STOP image.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+\n+#ifdef __cplusplus\n+namespace stopImageSection\n+{\n+#endif\n+\n+/**\n+ * @brief all SPRs and MSR for which register restore is to be supported.\n+ * @note STOP API design has built in support to accomodate 8 register of\n+ * scope core and thread each.\n+ */\n+typedef enum\n+{\n+ P9_STOP_SPR_DAWR = 180, // thread register\n+ P9_STOP_SPR_HSPRG0 = 304, // thread register\n+ P9_STOP_SPR_HRMOR = 313, // core register\n+ P9_STOP_SPR_LPCR = 318, // thread register\n+ P9_STOP_SPR_HMEER = 337, // core register\n+ P9_STOP_SPR_LDBAR = 850, // thread register\n+ P9_STOP_SPR_PSSCR = 855, // thread register\n+ P9_STOP_SPR_PMCR = 884, // core register\n+ P9_STOP_SPR_HID = 1008, // core register\n+ P9_STOP_SPR_MSR = 2000, // thread register\n+} CpuReg_t;\n+\n+/**\n+ * @brief lists all the bad error codes.\n+ */\n+typedef enum\n+{\n+ STOP_SAVE_SUCCESS = 0,\n+ STOP_SAVE_ARG_INVALID_IMG = 1,\n+ STOP_SAVE_ARG_INVALID_REG = 2,\n+ STOP_SAVE_ARG_INVALID_THREAD = 3,\n+ STOP_SAVE_ARG_INVALID_MODE = 4,\n+ STOP_SAVE_ARG_INVALID_CORE = 5,\n+ STOP_SAVE_SPR_ENTRY_NOT_FOUND = 6,\n+ STOP_SAVE_SPR_ENTRY_UPDATE_FAILED = 7,\n+ STOP_SAVE_SCOM_INVALID_OPERATION = 8,\n+ STOP_SAVE_SCOM_INVALID_SECTION = 9,\n+ STOP_SAVE_SCOM_INVALID_ADDRESS = 10,\n+ STOP_SAVE_SCOM_INVALID_CHIPLET = 11,\n+ STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED = 12,\n+ STOP_SAVE_INVALID_FUSED_CORE_STATUS = 13,\n+ STOP_SAVE_FAIL = 14, // for internal failure within firmware.\n+} StopReturnCode_t;\n+\n+/**\n+ * @brief summarizes all operations supported on scom entries of STOP image.\n+ */\n+typedef enum\n+{\n+ P9_STOP_SCOM_OP_MIN = 0,\n+ P9_STOP_SCOM_APPEND = 1,\n+ P9_STOP_SCOM_REPLACE = 2,\n+ P9_STOP_SCOM_OR = 3,\n+ P9_STOP_SCOM_AND = 4,\n+ P9_STOP_SCOM_NOOP = 5,\n+ P9_STOP_SCOM_RESET = 6,\n+ P9_STOP_SCOM_OR_APPEND = 7,\n+ P9_STOP_SCOM_AND_APPEND = 8,\n+ P9_STOP_SCOM_OP_MAX = 9\n+} ScomOperation_t;\n+\n+/**\n+ * @brief All subsections that contain scom entries in a STOP image.\n+ */\n+typedef enum\n+{\n+ P9_STOP_SECTION_MIN = 0,\n+ P9_STOP_SECTION_CORE_SCOM = 1,\n+ P9_STOP_SECTION_EQ_SCOM = 2,\n+ P9_STOP_SECTION_L2 = 3,\n+ P9_STOP_SECTION_L3 = 4,\n+ P9_STOP_SECTION_MAX = 5\n+} ScomSection_t;\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+/**\n+ * @brief Updates STOP image entry associated with CPU register.\n+ * @param[in] i_pImage start address of homer image associated with processor.\n+ * @param[in] i_regId id of SPR for which STOP image needs to be updated.\n+ * @param[in] i_regData data to be restored in SPR register.\n+ * @param[in] i_pir value of processor identification register (PIR)\n+ * @return STOP_SAVE_SUCCESS SUCCESS if image is updated successfully, error\n+ * code otherwise.\n+ */\n+\n+StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage,\n+ const CpuReg_t i_regId,\n+ const uint64_t i_regData,\n+ const uint64_t i_pir );\n+\n+/**\n+ * @brief Updates scom image entry associated with given core or cache in\n+ * STOP section of homer image.\n+ * @param[in] i_pImage start address of homer image of P9 chip.\n+ * @param[in] i_scomAddress fully qualified address of SCOM register.\n+ * @param[in] i_scomData data associated with SCOM register.\n+ * @param[in] i_operation operation to be done on SCOM image entry.\n+ * @param[in] i_section area to which given SCOM entry belongs.\n+ * @return STOP_SAVE_SUCCESS if image is updated successfully, error code\n+ * otherwise.\n+ * @note API is intended to update SCOM image entry associated with given\n+ * core or given part of a cache section. API doesn't validate if\n+ * a given SCOM address really belongs to given section.\n+ */\n+StopReturnCode_t p9_stop_save_scom( void* const i_pImage,\n+ const uint32_t i_scomAddress,\n+ const uint64_t i_scomData,\n+ const ScomOperation_t i_operation,\n+ const ScomSection_t i_section );\n+\n+#ifdef __cplusplus\n+} // extern \"C\"\n+}; // namespace stopImageSection ends\n+#endif //__cplusplus\n+\n+#endif //__P9_STOP_IMAGE_API_\ndiff --git a/libpore/p9_stop_data_struct.H b/libpore/p9_stop_data_struct.H\nnew file mode 100644\nindex 0000000..2201021\n--- /dev/null\n+++ b/libpore/p9_stop_data_struct.H\n@@ -0,0 +1,149 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_stop_data_struct.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+\n+///\n+/// @file p9_stop_data_struct.H\n+/// @brief describes data structures internal to STOP API.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+#ifndef __STOP_DATA_STRUCT_\n+#define __STOP_DATA_STRUCT_\n+\n+#ifndef _AIX\n+ #include <endian.h>\n+#endif\n+\n+#include \"p9_hcd_memmap_base.H\"\n+\n+#ifdef __SKIBOOT__\n+ #include <skiboot.h>\n+#endif\n+\n+#ifdef __FAPI_2_\n+ #include <fapi2.H>\n+#endif\n+\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+namespace stopImageSection\n+{\n+#endif\n+\n+enum\n+{\n+ MAX_SPR_RESTORE_INST = 0x08,\n+ SIZE_PER_SPR_RESTORE_INST = ((4 * sizeof(uint8_t)) / sizeof(uint32_t)),\n+};\n+\n+typedef struct\n+{\n+ uint32_t scomEntryHeader;\n+ uint32_t scomEntryAddress;\n+ uint64_t scomEntryData;\n+} ScomEntry_t;\n+\n+/**\n+ * @brief models a CPU register restoration area in STOP section of homer image.\n+ */\n+typedef struct\n+{\n+ uint8_t threadArea[CORE_RESTORE_THREAD_AREA_SIZE];\n+ uint8_t coreArea[CORE_RESTORE_CORE_AREA_SIZE];\n+} SprRestoreArea_t;\n+\n+/**\n+ * @brief models homer image of a chip.\n+ * @note sections not relevant for CPU register restoration have been\n+ * abstracted using field 'reserve'.\n+ */\n+typedef struct\n+{\n+ uint8_t occ_host_sgpe_area[ TWO_MB ]; // CPU restore area starts at an offset of 2MB from chip HOMER\n+ uint8_t interrruptHandler[SELF_RESTORE_INT_SIZE];\n+ uint8_t threadLauncher[THREAD_LAUNCHER_SIZE];\n+ SprRestoreArea_t coreThreadRestore[MAX_CORES_PER_CHIP][MAX_THREADS_PER_CORE];\n+ uint8_t reserve[(ONE_KB * ONE_KB) - SELF_RESTORE_SIZE_TOTAL];\n+} HomerSection_t;\n+\n+/**\n+ * @brief models cache subsection in STOP section of a given homer image.\n+ * @note given the start of cache subsection associated with a given core,\n+ * the structure below represents what a cache subsection would look\n+ * like. Based on known start address, quick traversing can be done\n+ * within the cache subsection.\n+ */\n+typedef struct\n+{\n+ ScomEntry_t nonCacheArea[MAX_EQ_SCOM_ENTRIES];\n+ ScomEntry_t l2CacheArea[MAX_L2_SCOM_ENTRIES];\n+ ScomEntry_t l3CacheArea[MAX_L3_SCOM_ENTRIES];\n+} StopCacheSection_t;\n+\n+/**\n+ * @brief summarizes attributes associated with a SPR register.\n+ */\n+typedef struct\n+{\n+ uint32_t sprId;\n+ bool isThreadScope;\n+} StopSprReg_t;\n+\n+enum\n+{\n+ SIZE_SCOM_ENTRY = sizeof( ScomEntry_t ),\n+ SCOM_ENTRY_START = 0xDEADDEAD,\n+};\n+\n+#ifdef __FAPI_2_\n+ #define MY_ERR( _fmt_, _args_...) FAPI_ERR(_fmt_, ##_args_)\n+ #define MY_INF(_fmt_, _args_...) FAPI_INF(_fmt_, ##_args_)\n+#else\n+ #define MY_ERR( _fmt_, _args_...)\n+ #define MY_INF(_fmt_, _args_...)\n+#endif\n+\n+#define CORE_ID_SCOM_START(io_image,\\\n+ i_chipletId) \\\n+((ScomEntry_t*)(((uint8_t*)(io_image)) + CORE_SCOM_RESTORE_HOMER_OFFSET +\\\n+ ((i_chipletId - CORE_CHIPLET_ID_MIN) * \\\n+ CORE_SCOM_RESTORE_SIZE_PER_CORE)));\n+\n+#define CACHE_SECTN_START(io_image,\\\n+ i_chipletId) \\\n+((StopCacheSection_t *)(((uint8_t *)(io_image)) + QUAD_SCOM_RESTORE_HOMER_OFFSET +\\\n+ ((i_chipletId - CACHE_CHIPLET_ID_MIN) * \\\n+ QUAD_SCOM_RESTORE_SIZE_PER_QUAD)));\n+#ifdef __cplusplus\n+} // extern \"C\"\n+\n+} //namespace stopImageSection ends\n+#endif //__cplusplus\n+\n+#endif\ndiff --git a/libpore/p9_stop_util.C b/libpore/p9_stop_util.C\nnew file mode 100644\nindex 0000000..6fb8d67\n--- /dev/null\n+++ b/libpore/p9_stop_util.C\n@@ -0,0 +1,186 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/utils/stopreg/p9_stop_util.C $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2015,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+\n+///\n+/// @file p9_stop_util.C\n+/// @brief implements some utilty functions for STOP API.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+\n+#include \"p9_stop_api.H\"\n+#include \"p9_stop_util.H\"\n+#include \"p9_stop_data_struct.H\"\n+\n+#ifdef __cplusplus\n+namespace stopImageSection\n+{\n+#endif\n+\n+/**\n+ * @brief Returns proc chip's fuse mode status.\n+ * @param i_pImage points to start of chip's HOMER image.\n+ * @param o_fusedMode points to fuse mode information.\n+ * @return STOP_SAVE_SUCCESS if functions succeeds, error code otherwise.\n+ */\n+static StopReturnCode_t isFusedMode( void* const i_pImage, bool* o_fusedMode )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+ *o_fusedMode = false;\n+\n+ do\n+ {\n+ HomerSection_t* pHomerDesc = ( HomerSection_t* ) i_pImage;\n+ HomerImgDesc_t* pHomer = (HomerImgDesc_t*)( pHomerDesc->interrruptHandler );\n+\n+ if( !i_pImage )\n+ {\n+ MY_ERR( \"invalid pointer to HOMER image\");\n+ l_rc = STOP_SAVE_ARG_INVALID_IMG;\n+ break;\n+ }\n+\n+\n+ uint64_t cpmrCheckWord = SWIZZLE_8_BYTE(pHomer->cpmrMagicWord);\n+ cpmrCheckWord = cpmrCheckWord >> 32;\n+\n+ if( CPMR_REGION_CHECK_WORD != cpmrCheckWord )\n+ {\n+ MY_ERR(\"corrupt or invalid HOMER image location 0x%016llx\",\n+ SWIZZLE_8_BYTE(pHomer->cpmrMagicWord) );\n+ l_rc = STOP_SAVE_ARG_INVALID_IMG;\n+ break;\n+ }\n+\n+ if( (uint8_t) FUSED_CORE_MODE == pHomer->fusedModeStatus )\n+ {\n+ *o_fusedMode = true;\n+ break;\n+ }\n+\n+ if( (uint8_t) NONFUSED_CORE_MODE == pHomer->fusedModeStatus )\n+ {\n+ break;\n+ }\n+\n+ MY_ERR(\"Unexpected value 0x%08x for fused mode. Bad or corrupt \"\n+ \"HOMER location\", pHomer->fuseModeStatus );\n+ l_rc = STOP_SAVE_INVALID_FUSED_CORE_STATUS ;\n+\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+//----------------------------------------------------------------------\n+\n+StopReturnCode_t getCoreAndThread( void* const i_pImage, const uint64_t i_pir,\n+ uint32_t* o_pCoreId, uint32_t* o_pThreadId )\n+{\n+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;\n+\n+ do\n+ {\n+ // for SPR restore using 'Virtual Thread' and 'Physical Core' number\n+ // In Fused Mode:\n+ // bit b28 and b31 of PIR give physical core and b29 and b30 gives\n+ // virtual thread id.\n+ // In Non Fused Mode\n+ // bit 28 and b29 of PIR give both logical and physical core number\n+ // whereas b30 and b31 gives logical and virtual thread id.\n+ bool fusedMode = false;\n+ uint8_t coreThreadInfo = (uint8_t)i_pir;\n+ *o_pCoreId = 0;\n+ *o_pThreadId = 0;\n+ l_rc = isFusedMode( i_pImage, &fusedMode );\n+\n+ if( l_rc )\n+ {\n+ MY_ERR(\" Checking Fused mode. Read failed 0x%08x\", l_rc );\n+ break;\n+ }\n+\n+ if( fusedMode )\n+ {\n+ if( coreThreadInfo & FUSED_CORE_BIT1 )\n+ {\n+ *o_pThreadId = 2;\n+ }\n+\n+ if( coreThreadInfo & FUSED_CORE_BIT2 )\n+ {\n+ *o_pThreadId += 1;\n+ }\n+\n+ if( coreThreadInfo & FUSED_CORE_BIT0 )\n+ {\n+ *o_pCoreId = 2;\n+ }\n+\n+ if( coreThreadInfo & FUSED_CORE_BIT3 )\n+ {\n+ *o_pCoreId += 1;\n+ }\n+ }\n+ else\n+ {\n+ if( coreThreadInfo & FUSED_CORE_BIT0 )\n+ {\n+ *o_pCoreId = 2;\n+ }\n+\n+ if ( coreThreadInfo & FUSED_CORE_BIT1 )\n+ {\n+ *o_pCoreId += 1;\n+ }\n+\n+ if( coreThreadInfo & FUSED_CORE_BIT2 )\n+ {\n+ *o_pThreadId = 2;\n+ }\n+\n+ if( coreThreadInfo & FUSED_CORE_BIT3 )\n+ {\n+ *o_pThreadId += 1;\n+ }\n+ }\n+\n+ MY_INF(\"Core Type %s\", fusedMode ? \"Fused\" : \"Un-Fused\" );\n+ //quad field is not affected by fuse mode\n+ *o_pCoreId += 4 * (( coreThreadInfo & 0x70 ) >> 4 );\n+ }\n+ while(0);\n+\n+ return l_rc;\n+}\n+\n+#ifdef __cplusplus\n+}//namespace stopImageSection ends\n+#endif\n+\ndiff --git a/libpore/p9_stop_util.H b/libpore/p9_stop_util.H\nnew file mode 100644\nindex 0000000..3266fde\n--- /dev/null\n+++ b/libpore/p9_stop_util.H\n@@ -0,0 +1,145 @@\n+/* IBM_PROLOG_BEGIN_TAG */\n+/* This is an automatically generated prolog. */\n+/* */\n+/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_stop_util.H $ */\n+/* */\n+/* OpenPOWER HostBoot Project */\n+/* */\n+/* Contributors Listed Below - COPYRIGHT 2016,2017 */\n+/* [+] International Business Machines Corp. */\n+/* */\n+/* */\n+/* Licensed under the Apache License, Version 2.0 (the \"License\"); */\n+/* you may not use this file except in compliance with the License. */\n+/* You may obtain a copy of the License at */\n+/* */\n+/* http://www.apache.org/licenses/LICENSE-2.0 */\n+/* */\n+/* Unless required by applicable law or agreed to in writing, software */\n+/* distributed under the License is distributed on an \"AS IS\" BASIS, */\n+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */\n+/* implied. See the License for the specific language governing */\n+/* permissions and limitations under the License. */\n+/* */\n+/* IBM_PROLOG_END_TAG */\n+#ifndef __P9_STOP_UTIL_\n+#define __P9_STOP_UTIL_\n+\n+#ifdef _AIX\n+ #define __BYTE_ORDER __BIG_ENDIAN\n+#elif __SKIBOOT__\n+ #include <skiboot.h>\n+#else\n+ #include <endian.h>\n+#endif\n+\n+#ifndef __PPE_PLAT\n+ #include \"p9_stop_api.H\"\n+#endif\n+\n+#ifdef FAPI_2\n+ #include <fapi2.H>\n+#endif\n+\n+///\n+/// @file p9_stop_util.H\n+/// @brief describes some utilty functions for STOP API.\n+///\n+// *HWP HW Owner : Greg Still <stillgs@us.ibm.com>\n+// *HWP FW Owner : Prem Shanker Jha <premjha2@in.ibm.com>\n+// *HWP Team : PM\n+// *HWP Level : 2\n+// *HWP Consumed by : HB:HYP\n+#ifndef __PPE_PLAT\n+#ifdef __cplusplus\n+namespace stopImageSection\n+{\n+#endif\n+#endif //__PPE_PLAT\n+/**\n+ * @brief helper function to swizzle given input data\n+ * @note swizles bytes to handle endianess issue.\n+ */\n+#if( __BYTE_ORDER == __BIG_ENDIAN )\n+\n+// NOP if it is a big endian system\n+#define SWIZZLE_2_BYTE(WORD) WORD\n+#define SWIZZLE_4_BYTE(WORD) WORD\n+#define SWIZZLE_8_BYTE(WORD) WORD\n+\n+#else\n+#define SWIZZLE_2_BYTE(WORD) \\\n+ ( (((WORD) >> 8) & 0x00FF) | (((WORD) << 8) & 0xFF00) )\n+\n+#define SWIZZLE_4_BYTE(WORD) \\\n+ ( (((WORD) >> 24) & 0x000000FF) | (((WORD) >> 8) & 0x0000FF00) | \\\n+ (((WORD) << 8) & 0x00FF0000) | (((WORD) << 24) & 0xFF000000) )\n+\n+#define SWIZZLE_8_BYTE(WORD) \\\n+ ( (((WORD) >> 56) & 0x00000000000000FF) | \\\n+ (((WORD) >> 40) & 0x000000000000FF00)| \\\n+ (((WORD) >> 24) & 0x0000000000FF0000) | \\\n+ (((WORD) >> 8) & 0x00000000FF000000) | \\\n+ (((WORD) << 8) & 0x000000FF00000000) | \\\n+ (((WORD) << 24) & 0x0000FF0000000000) | \\\n+ (((WORD) << 40) & 0x00FF000000000000) | \\\n+ (((WORD) << 56) & 0xFF00000000000000) )\n+#endif\n+\n+/**\n+ * @brief describes details of CPMR header in HOMER.\n+ */\n+typedef struct\n+{\n+ uint64_t attnOpcodes;\n+ uint64_t cpmrMagicWord;\n+ uint32_t buildDate;\n+ uint32_t version;\n+ uint8_t reserve1[7];\n+ uint8_t fusedModeStatus;\n+ uint32_t cmeImgOffset;\n+ uint32_t cmeImgLength;\n+ uint32_t cmeCommonRingOffset;\n+ uint32_t cmeCommonRingLength;\n+ uint32_t cmePstateOffset;\n+ uint32_t cmePstateLength;\n+ uint32_t coreSpecRingOffset;\n+ uint32_t coreSpecRingLen;\n+ uint32_t coreScomOffset;\n+ uint32_t coreScomLength;\n+ uint32_t reserve2[184];\n+} HomerImgDesc_t;\n+\n+/**\n+ * @brief enumerates bit(s) positions of interest for PIR.\n+ */\n+enum\n+{\n+ FUSED_CORE_BIT0 = 0x08,\n+ FUSED_CORE_BIT1 = 0x04,\n+ FUSED_CORE_BIT2 = 0x02,\n+ FUSED_CORE_BIT3 = 0x01,\n+ QUAD_BITS = 0x70\n+};\n+\n+#ifndef __PPE_PLAT\n+/**\n+ * @brief returns core id and thread id by parsing a given PIR.\n+ * @param i_pStopImage points to STOP image associated with a proc chip.\n+ * @param i_pir PIR associated with a core's thread.\n+ * @param o_coreId points to core id value obtained from PIR.\n+ * @param o_threadId points to thread id value obtained from PIR.\n+ * @return SUCCESS if function suceeds, error code otherwise.\n+ */\n+StopReturnCode_t getCoreAndThread( void* const i_pStopImage,\n+ const uint64_t i_pir,\n+ uint32_t* o_coreId,\n+ uint32_t* o_threadId );\n+#ifdef __cplusplus\n+} // namespace stopImageSection ends\n+\n+#endif\n+#endif //__PPE_PLAT\n+#endif\n+\n+\n", "prefixes": [ "v5", "1/8" ] }