diff options
Diffstat (limited to 'src/import/chips/p9/procedures')
15 files changed, 1498 insertions, 53 deletions
diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.C b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.C index f36ecb395..209f7e6ca 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.C @@ -24,34 +24,33 @@ /* IBM_PROLOG_END_TAG */ /// -/// @file : p9_cpu_special_wakeup.C -/// @brief : HWP to perform special wakeup of core, EQ or EX. +/// @file : p9_cpu_special_wakeup_core.C +/// @brief : HWP to perform special wakeup of a core // *HWP HW Owner : Greg Still <stillgs@us.ibm.com> // *HWP FW Owner : Prem S Jha <premjha2@in.ibm.com> // *HWP Team : PM -// *HWP Level : 1 -// *HWP Consumed by : OCC:FSP:HOST +// *HWP Level : 2 +// *HWP Consumed by : OCC:FSP:HOST:CRO -// --------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // Includes -// --------------------------------------------------------------------- +// ----------------------------------------------------------------------------- #include <p9_cpu_special_wakeup.H> -using namespace p9specialWakeup; -enum -{ - NUM_SPCWKUP_ENTITIES = 4, - NUM_SPCWKUP_OPS = 3, -}; - -fapi2::ReturnCode -p9_cpu_special_wakeup( const FAPI2_WAKEUP_CHIPLET& i_chipletTarget, - const PROC_SPCWKUP_OPS i_operation, - const PROC_SPCWKUP_ENTITY i_entity ) +/// ---------------------------------------------------------------------------- +/// +/// @brief Sets a normal core chiplet into special wakeup state. +/// @note Code added as a workaround to fix HB-CI failure. Will +/// be removed eventually. +/// +fapi2::ReturnCode p9_cpu_special_wakeup( + const fapi2::Target < fapi2::TARGET_TYPE_CORE>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ) { - FAPI_DBG("Entering p9_cpu_special_wakeup"); + FAPI_DBG("> p9_cpu_special_wakeup"); - FAPI_DBG("Exit p9_cpu_special_wakeup" ); + FAPI_INF("< p9_cpu_special_wakeup" ); return fapi2::FAPI2_RC_SUCCESS; } diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.H b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.H index 90b038e72..28bc65732 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup.H @@ -29,7 +29,7 @@ // *HWP HW Owner : Greg Still <stillgs@us.ibm.com> // *HWP FW Owner : Prem S Jha <premjha2@in.ibm.com> // *HWP Team : PM -// *HWP Level : 1 +// *HWP Level : 2 // *HWP Consumed by : OCC:FSP:HOST #ifndef __P9_CPU_SPECIAL_WAKEUP_H_ @@ -48,19 +48,16 @@ namespace p9specialWakeup { -typedef fapi2::Target < fapi2::TARGET_TYPE_CORE | -fapi2::TARGET_TYPE_EX | -fapi2::TARGET_TYPE_EQ > FAPI2_WAKEUP_CHIPLET; - /** * @brief enumerates all platforms which request special wakeup. */ enum PROC_SPCWKUP_ENTITY { - HOST, - FSP, - OCC, - PHYP = HOST, + OTR = 0, + FSP = 1, + OCC = 2, + HYP = 3, + HOST = HYP, SPW_ALL }; @@ -69,37 +66,147 @@ enum PROC_SPCWKUP_ENTITY */ enum PROC_SPCWKUP_OPS { - SPCWKUP_DISABLE, - SPCWKUP_ENABLE, - SPCWKUP_INIT, - SPCWKUP_FORCE_DEASSERT + SPCWKUP_ENABLE = 0, + SPCWKUP_DISABLE = 1 +}; + +/** + * @brief enumerates types of special wakeup. + */ +enum PROC_SPCWKUP_TYPE +{ + SPW_CORE = 0, + SPW_EQ = 1, + SPW_EX = 2 +}; +// Used by checking infrastructure checking code +static const uint32_t END_OP = SPCWKUP_DISABLE; + +/** + * Id of the string associated with special wakeup. + */ +enum SpecialWakeUpMsg +{ + SPWK_MSG_ASSERT = 0, + SPWK_MSG_DEASSERT = 1, + SPWK_MSG_CLEAN_UP_DEASSERT = 2, }; } //p9specialWakeup ends -// function pointer typedef definition for HWP call support typedef fapi2::ReturnCode (*p9_cpu_special_wakeup_FP_t) -( const p9specialWakeup::FAPI2_WAKEUP_CHIPLET& i_chipletTarget, - const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, - const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ); +( const fapi2::Target < fapi2::TARGET_TYPE_CORE >&, + const p9specialWakeup::PROC_SPCWKUP_OPS, + const p9specialWakeup::PROC_SPCWKUP_ENTITY); + +// function pointer typedef definition for HWP call support +typedef fapi2::ReturnCode (*p9_cpu_special_wakeup_core_FP_t) +( const fapi2::Target < fapi2::TARGET_TYPE_CORE >&, + const p9specialWakeup::PROC_SPCWKUP_OPS, + const p9specialWakeup::PROC_SPCWKUP_ENTITY); + +// function pointer typedef definition for HWP call support +typedef fapi2::ReturnCode (*p9_cpu_special_wakeup_eq_FP_t) +( const fapi2::Target < fapi2::TARGET_TYPE_EQ >&, + const p9specialWakeup::PROC_SPCWKUP_OPS, + const p9specialWakeup::PROC_SPCWKUP_ENTITY); + +// function pointer typedef definition for HWP call support +typedef fapi2::ReturnCode (*p9_cpu_special_wakeup_ex_FP_t) +( const fapi2::Target < fapi2::TARGET_TYPE_EX >&, + const p9specialWakeup::PROC_SPCWKUP_OPS, + const p9specialWakeup::PROC_SPCWKUP_ENTITY); + + extern "C" { -/// @brief Sets core, ex or eq chiplet into special wakeup state. + +/// @brief Asserts/Deasserts core, ex or eq chiplets into special wakeup state. +/// @verbatim +/// - General function +/// Based on "entity" parameter (OCC, FSP, HYP, OTHER), write the +/// appropriate Special Wakeup bit (different address) +/// +/// Poll for SPECIAL WAKEUP DONE +/// +/// Note: the caller has to decide what needs to be target based on the +/// fused operational mode and the address that is needed to be accessed. +/// This procedure does NOT know the address(es) to be accessed. +/// +/// - General flow +/// if TARGET_TYPE_CORE, same as normal core mode +/// if TARGET_TYPE_EQ, same a normal core mode +/// if TARGET_TYPE_EX, sets special wakeup to both cores in the EX +/// The act of waking up an EX will wakeup the shared portion of the EQ +/// (including the CMEs and all L3) as well as the L2 domain associated +/// with the functional core in the targeted EX. The two cores will be +/// restored (including SCOM and SPR restoration. +/// +/// - Polling Timeouts +/// Timeouts need to account for the following: +/// 1) All the chiplets are not in a Deep Idle state and will awaken in +/// < 1us +/// +/// 2) All the chiplets in a STOP 4 or less can be awakened in < 1ms +/// +/// 3) Multiple chiplets in STOP 11/15 will cause a serialization of +/// at least two exits so awakening of < 5ms +/// +/// Procedure Prereq: +/// - Caller must follow these rules: +/// - if system checkstop is present, set ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG +/// to not produce errors if special wake-up done times out +/// - On a successful assertion of special wake-up, deassert afterwards! +/// - On an unsuccessful assertion of special wake-up, do NOT deassert +/// afterwards! +/// @endverbatim +/// /// @param[in] i_chipletTarget fapi2 target associated with core, ex and eq. /// @param[in] i_operation special wakeup operations to be used. -/// @param[in] i_entity entity requesting special wakeup. +/// SPCWKUP_ENABLE - asserts the special wake-up bit associated +/// with i_entity, increment entity specific counter +/// (attribute), and poll for valid special wakeup completion. +/// SPCWKUP_DISABLE - decrement entity specific counter (attribute) +/// associated with i_entity and deasserts the special wake-up +/// bit only if the count is zero. +/// SPCWKUP_INIT - write all entity counters(attributes) to zero. +/// SPCWKUP_FORCE_DEASSERT - deassert the i_entity bit without +/// checking or updating the counter attributes. +/// @param[in] i_entity entity to perform special wake-up upon. Effectively +/// chooses the special wake-up to use. /// @return FAPI2_RC_SUCCESS on success, errorcode otherwise. -/// @note needs support of following attribute: -/// ATTR_PM_SPWUP_FSP -/// ATTR_PM_SPWUP_OCC -/// ATTR_PM_SPWUP_HOST -/// ATTR_PM_SPWUP_OTR -/// ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG - fapi2::ReturnCode - p9_cpu_special_wakeup( const p9specialWakeup::FAPI2_WAKEUP_CHIPLET& i_chipletTarget, - const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, - const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ); +/// +/// @note needs support of following attributes: +/// ATTR_PM_SPWUP_CORE[NUM_ENTITIES] (CORE target) - counter attributes +/// for Cores +/// ATTR_PM_SPWUP_EQ[NUM_ENTITIES] (EQ target) - counter attributes for +/// EQs +/// ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG (PROC target) - bypass Done timeout +/// Done checking to return SUCCESS if a checkstop condition is +/// present. Must be set by the caller to suppress timeout errors +/// from being reported. +/// + fapi2::ReturnCode p9_cpu_special_wakeup( + const fapi2::Target <fapi2::TARGET_TYPE_CORE>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ); + + fapi2::ReturnCode p9_cpu_special_wakeup_core( + const fapi2::Target <fapi2::TARGET_TYPE_CORE>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ); + + fapi2::ReturnCode p9_cpu_special_wakeup_eq( + const fapi2::Target <fapi2::TARGET_TYPE_EQ>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ); + + fapi2::ReturnCode p9_cpu_special_wakeup_ex( + const fapi2::Target <fapi2::TARGET_TYPE_EX>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ); + }// extern "C" ends #endif //__P9_CPU_SPECIAL_WAKEUP_H_ diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.C b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.C new file mode 100644 index 000000000..bdaade361 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.C @@ -0,0 +1,118 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file : p9_cpu_special_wakeup_core.C +/// @brief : HWP to perform special wakeup of a core + +// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner : Prem S Jha <premjha2@in.ibm.com> +// *HWP Team : PM +// *HWP Level : 2 +// *HWP Consumed by : OCC:FSP:HOST:CRO + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +#include <p9_cpu_special_wakeup.H> +#include <p9_cpu_special_wakeup_lib.H> + +/// ---------------------------------------------------------------------------- +/// +/// @brief Sets a normal core chiplet into special wakeup state. +/// +fapi2::ReturnCode p9_cpu_special_wakeup_core( + const fapi2::Target < fapi2::TARGET_TYPE_CORE>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ) +{ + FAPI_DBG("> p9_cpu_special_wakeup_core"); + FAPI_TRY(_special_wakeup<fapi2::TARGET_TYPE_CORE> ( + i_target, + i_operation, + i_entity )); + +fapi_try_exit: + FAPI_INF("< p9_cpu_special_wakeup_core" ); + return fapi2::current_err; +} + +// ----------------------------------------------------------------------------- + +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId ) +{ + FAPI_INF("> spwkup_deassert Core" ); + + uint64_t l_address = i_processing_info.spwkup_address[0]; + FAPI_TRY(_spwkup_deassert(i_chipletTarget, l_address, i_msgId)); + +fapi_try_exit: + FAPI_INF("< spwkup_deassert Core" ); + return fapi2::current_err; +} + +// ----------------------------------------------------------------------------- +/// +/// @brief Set addresses for a core target type +/// +template<> +fapi2::ReturnCode set_addresses(const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ) +{ + FAPI_INF("> set_addresses for Core"); + + uint8_t l_core_num = 0; + + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, i_target, l_core_num), + "fapiGetAttribute of ATTR_CHIP_UNIT_POS"); + + FAPI_DBG("Core %d being procesed.", l_core_num); + + i_structure.spwkup_address[0] = SPCWKUP_ADDR[i_entity][p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.history_address[0] = SPCWKUP_HIST_ADDR[i_entity][p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.netctrl_address[0] = SPCWKUP_NETCTRL0_ADDR[p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.gpmmr_address[0] = SPCWKUP_GPMMR_ADDR[p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.num_addresses = 1; + + FAPI_DBG("i_structure.spwkup_address[%d] = 0x%08llX \n " + "i_structure.history_address[%d] = 0x%08llX \n " + "i_structure.netctrl_address[%d] = 0x%08llX \n " + "i_structure.gpmmr_addresss[%d] = 0x%08llX \n " , + 0, i_structure.spwkup_address[0], + 0, i_structure.history_address[0], + 0, i_structure.netctrl_address[0], + 0, i_structure.gpmmr_address[0]); + +fapi_try_exit: + FAPI_INF("< set_addresses for Core"); + return fapi2::current_err; +} diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.mk b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.mk new file mode 100644 index 000000000..317f78f39 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.mk @@ -0,0 +1,27 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_core.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +PROCEDURE=p9_cpu_special_wakeup_core +$(PROCEDURE)_DEPLIBS+=p9_cpu_special_wakeup_lib +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.C b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.C new file mode 100644 index 000000000..f7e87fca6 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.C @@ -0,0 +1,116 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file : p9_cpu_special_wakeup_eq.C +/// @brief : HWP to perform special wakeup of a core + +// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner : Prem S Jha <premjha2@in.ibm.com> +// *HWP Team : PM +// *HWP Level : 2 +// *HWP Consumed by : OCC:FSP:HOST:CRO + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +#include <p9_cpu_special_wakeup.H> +#include <p9_cpu_special_wakeup_lib.H> + +/// ---------------------------------------------------------------------------- +/// +/// @brief Sets a normal core chiplet into special wakeup state. +/// +fapi2::ReturnCode p9_cpu_special_wakeup_eq( + const fapi2::Target < fapi2::TARGET_TYPE_EQ>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ) +{ + FAPI_DBG("> p9_cpu_special_wakeup_eq"); + FAPI_TRY(_special_wakeup<fapi2::TARGET_TYPE_EQ> ( + i_target, + i_operation, + i_entity )); + +fapi_try_exit: + FAPI_INF("< p9_cpu_special_wakeup_eq" ); + return fapi2::current_err; +} + +/// ---------------------------------------------------------------------------- + +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId) +{ + FAPI_INF("> spwkup_deassert EQ" ); + + uint64_t l_address = i_processing_info.spwkup_address[0]; + FAPI_TRY(_spwkup_deassert(i_chipletTarget, l_address, i_msgId)); + +fapi_try_exit: + FAPI_INF("< spwkup_deassert EQ" ); + return fapi2::current_err; +} + +/// ---------------------------------------------------------------------------- + +template<> +fapi2::ReturnCode set_addresses(const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ) +{ + FAPI_INF("> set_addresses for EQ"); + + uint8_t l_eq_num = 0; + + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, i_target, l_eq_num), + "fapiGetAttribute of ATTR_CHIP_UNIT_POS"); + + FAPI_DBG("EQ %d being procesed.", l_eq_num); + + i_structure.spwkup_address[0] = SPCWKUP_ADDR[i_entity][p9specialWakeup::SPW_EQ] + + 0x01000000 * l_eq_num; + i_structure.history_address[0] = SPCWKUP_HIST_ADDR[i_entity][p9specialWakeup::SPW_EQ] + + 0x01000000 * l_eq_num; + i_structure.netctrl_address[0] = SPCWKUP_NETCTRL0_ADDR[p9specialWakeup::SPW_EQ] + + 0x01000000 * l_eq_num; + i_structure.gpmmr_address[0] = SPCWKUP_GPMMR_ADDR[p9specialWakeup::SPW_EQ] + + 0x01000000 * l_eq_num; + i_structure.num_addresses = 1; + + FAPI_DBG("i_structure.spwkup_address[%d] = 0x%08llX \n " + "i_structure.history_address[%d] = 0x%08llX \n " + "i_structure.netctrl_address[%d] = 0x%08llX \n " + "i_structure.gpmmr_addresss[%d] = 0x%08llX \n " , + 0, i_structure.spwkup_address[0], + 0, i_structure.history_address[0], + 0, i_structure.netctrl_address[0], + 0, i_structure.gpmmr_address[0]); + +fapi_try_exit: + FAPI_INF("< set_addresses for EQ"); + return fapi2::current_err; +} diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.mk b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.mk new file mode 100644 index 000000000..122f3beff --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.mk @@ -0,0 +1,27 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_eq.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +PROCEDURE=p9_cpu_special_wakeup_eq +$(PROCEDURE)_DEPLIBS+=p9_cpu_special_wakeup_lib +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.C b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.C new file mode 100644 index 000000000..33ca069f8 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.C @@ -0,0 +1,151 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file : p9_cpu_special_wakeup_ex.C +/// @brief : HWP to perform special wakeup of an EX "chiplet" + +// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner : Prem S Jha <premjha2@in.ibm.com> +// *HWP Team : PM +// *HWP Level : 2 +// *HWP Consumed by : OCC:FSP:HOST:CRO + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +#include <p9_cpu_special_wakeup.H> +#include <p9_cpu_special_wakeup_lib.H> + +/// ---------------------------------------------------------------------------- +/// +/// @brief Sets an EX "chiplet" into special wakeup state. +/// +fapi2::ReturnCode p9_cpu_special_wakeup_ex( + const fapi2::Target < fapi2::TARGET_TYPE_EX>& i_target, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ) +{ + FAPI_DBG("> p9_cpu_special_wakeup_ex"); + FAPI_TRY(_special_wakeup<fapi2::TARGET_TYPE_EX> ( + i_target, + i_operation, + i_entity )); + +fapi_try_exit: + FAPI_INF("< p9_cpu_special_wakeup_ex" ); + return fapi2::current_err; + +} + +/// ---------------------------------------------------------------------------- + +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId) +{ + FAPI_INF("> spwkup_deassert core EX" ); + + uint64_t l_address; + + for (uint32_t i = 0; i < i_processing_info.num_addresses; ++i) + { + l_address = i_processing_info.spwkup_address[i]; + FAPI_TRY(_spwkup_deassert(i_chipletTarget, l_address, i_msgId)); + } + +fapi_try_exit: + FAPI_INF("< spwkup_deassert EX" ); + return fapi2::current_err; +} + +/// ---------------------------------------------------------------------------- + +template<> +fapi2::ReturnCode set_addresses(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ) +{ + FAPI_INF("> set_addresses for EX"); + + FAPI_DBG("i_processing: setaddr start" + "entity = %d " + "b_xstop_flag = %d " + "b_ignore_xstop_flag = %d " + "b_wakeup_on_entry_flag = %d " + "b_ex_flag = %d \n", + i_structure.entity, + i_structure.b_xstop_flag, + i_structure.b_ignore_xstop_flag, + i_structure.b_wakeup_on_entry_flag, + i_structure.b_ex_flag); + + uint8_t l_ex_num = 0; + uint8_t l_core_num = 0; + uint32_t i = 0; + + // Determine the good cores in the EX + auto l_core_functional_vector = + i_target.getChildren<fapi2::TARGET_TYPE_CORE>(fapi2::TARGET_STATE_FUNCTIONAL); + + FAPI_ASSERT(l_core_functional_vector.size() > 0, + fapi2::SPCWKUP_NOEXCORES(), + "No good cores to special wake-up in targeted EX"); + + for (auto it : l_core_functional_vector) + { + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, it, l_core_num), + "fapiGetAttribute of ATTR_CHIP_UNIT_POS"); + + FAPI_DBG("EX %d being procesed. Setting up for Core %d with index %d", + l_ex_num, l_core_num, i); + + i_structure.spwkup_address[i] = SPCWKUP_ADDR[i_entity][p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.history_address[i] = SPCWKUP_HIST_ADDR[i_entity][p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.netctrl_address[i] = SPCWKUP_NETCTRL0_ADDR[p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + i_structure.gpmmr_address[i] = SPCWKUP_GPMMR_ADDR[p9specialWakeup::SPW_CORE] + + 0x01000000 * l_core_num; + + FAPI_DBG("i_structure.spwkup_address[%d] = 0x%08llX \n " + "i_structure.history_address[%d] = 0x%08llX \n " + "i_structure.netctrl_address[%d] = 0x%08llX \n " + "i_structure.gpmmr_addresss[%d] = 0x%08llX \n " , + i, i_structure.spwkup_address[i], + i, i_structure.history_address[i], + i, i_structure.netctrl_address[i], + i, i_structure.gpmmr_address[i]); + ++i; + } + + i_structure.num_addresses = i; + + +fapi_try_exit: + FAPI_INF("< set_addresses for EX"); + return fapi2::current_err; +} diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.mk b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.mk new file mode 100644 index 000000000..55e9f403d --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.mk @@ -0,0 +1,27 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_ex.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +PROCEDURE=p9_cpu_special_wakeup_ex +$(PROCEDURE)_DEPLIBS+=p9_cpu_special_wakeup_lib +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.C b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.C new file mode 100644 index 000000000..301cecd3e --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.C @@ -0,0 +1,62 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include <p9_cpu_special_wakeup_lib.H> +#include <stdint.h> + +namespace p9specialWakeup +{ +/** + * String names for the Entities. These must match the PROC_SPCWKUP_ENTITY + * enum. + */ + +/** + * Strings associated with special wake up. + */ +const char* SPWK_MSG_LIST[] = +{ + "Assert: ", + "Deassert", + "Clean-up Deassert" +}; + +/** + * String names for the Entities. These must match the PROC_SPCWKUP_ENTITY + * enum. + */ + +const char* PROC_SPCWKUP_ENTITY_NAMES[] = +{ + "OTHER", + "FSP", + "OCC", + "HYP", + "HOST", + "SPW_ALL" +}; + +} + + diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.H b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.H new file mode 100644 index 000000000..684ada990 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.H @@ -0,0 +1,618 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file : p9_cpu_special_wakeup_lib.H +/// @brief : Templated functions to perform special wakeups of +/// core, EQ or EX. + +// *HWP HW Owner : Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner : Prem S Jha <premjha2@in.ibm.com> +// *HWP Team : PM +// *HWP Level : 2 +// *HWP Consumed by : OCC:FSP:HOST:CRO + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- +#include <p9_cpu_special_wakeup.H> +#include <p9_quad_scom_addresses.H> +#include <p9_perv_scom_addresses.H> +#include <p9_perv_scom_addresses_fld.H> +#include <p9_misc_scom_addresses.H> + +static const uint32_t NUM_CHIPLET_TYPES = 2; +static const uint32_t NUM_ENTITIES = 4; + + +/** + * @brief Addresses for each entity + */ + +static const uint64_t SPCWKUP_ADDR[NUM_ENTITIES][NUM_CHIPLET_TYPES] = +{ + {C_PPM_SPWKUP_OTR, EQ_PPM_SPWKUP_OTR}, + {C_PPM_SPWKUP_FSP, EQ_PPM_SPWKUP_FSP}, + {C_PPM_SPWKUP_OCC, EQ_PPM_SPWKUP_OCC}, + {C_PPM_SPWKUP_HYP, EQ_PPM_SPWKUP_HYP} +}; + +static const uint64_t SPCWKUP_HIST_ADDR[NUM_ENTITIES][NUM_CHIPLET_TYPES] = +{ + {C_PPM_SSHOTR, EQ_PPM_SSHOTR}, + {C_PPM_SSHFSP, EQ_PPM_SSHFSP}, + {C_PPM_SSHOCC, EQ_PPM_SSHOCC}, + {C_PPM_SSHHYP, EQ_PPM_SSHHYP} +}; + +static const uint64_t SPCWKUP_NETCTRL0_ADDR[NUM_CHIPLET_TYPES] = +{ + C_NET_CTRL0, EQ_NET_CTRL0 +}; + +static const uint64_t SPCWKUP_GPMMR_ADDR[NUM_CHIPLET_TYPES] = +{ + C_PPM_GPMMR_SCOM, EQ_PPM_GPMMR_SCOM +}; + +static const uint32_t SPECIAL_WAKE_UP_POLL_INTERVAL_NS = 1000000; //1ms +static const uint32_t SPECIAL_WAKEUP_TIMEOUT_NS = (100 * SPECIAL_WAKE_UP_POLL_INTERVAL_NS); //100 ms +static const uint32_t SPWKUP_BIT = 0; +static const uint32_t GPMMR_SPWKUP_DONE_BIT = 0; +static const uint32_t HIST_SPWKUP_DONE_BIT = 1; +static const uint32_t SGPE_ACTIVE_BIT = 8; +static const uint32_t CORES_PER_EX = 2; + +namespace p9specialWakeup +{ +extern const char* SPWK_MSG_LIST[]; +extern const char* PROC_SPCWKUP_ENTITY_NAMES[]; + +} + + +// Information to be used for an operation. Populated based on the entity +struct ProcessingValues_t +{ + p9specialWakeup::PROC_SPCWKUP_ENTITY entity; + bool b_xstop_flag; + bool b_ignore_xstop_flag; + bool b_wakeup_on_entry_flag; + bool b_ex_flag; + uint32_t num_addresses; + uint64_t spwkup_address[CORES_PER_EX]; + uint64_t gpmmr_address[CORES_PER_EX]; + uint64_t history_address[CORES_PER_EX]; + uint64_t netctrl_address[CORES_PER_EX]; +}; + +// ----------------------------------------------------------------------------- +// Templated Functions +// ----------------------------------------------------------------------------- + +/// ---------------------------------------------------------------------------- +/// +/// Get the Chip Target from the input Target +/// +/// @brief find the CHIP target given a K target +/// @param[in] the fapi2 target, +/// @return a CHIP target. +/// +template< fapi2::TargetType K > +inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> get_chip_target( const fapi2::Target<K>& ); + +/// +/// @brief find the CHIP target given a CORE target +/// @param[in] the fapi2 target, +/// @return a CHIP target. +/// +template<> +inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> get_chip_target( const fapi2::Target<fapi2::TARGET_TYPE_CORE>& + i_target ) +{ + return i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); +} + +/// +/// @brief find the CHIP target given a EQ target +/// @param[in] the fapi2 target, +/// @return a CHIP target. +/// +template<> +inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> get_chip_target( const fapi2::Target<fapi2::TARGET_TYPE_EQ>& + i_target ) +{ + return i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); +} + +/// +/// @brief find the CHIP target given a EX target +/// @param[in] the fapi2 target, +/// @return a CHIP target. +/// +template<> +inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> get_chip_target( const fapi2::Target<fapi2::TARGET_TYPE_EX>& + i_target ) +{ + return i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); +} + +/// +/// @brief find the CHIP target given a CHIP target +/// @param[in] the fapi2 target, +/// @return a CHIP target. +/// +template<> +inline fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> get_chip_target( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& + i_target ) +{ + return i_target; +} + +/// ---------------------------------------------------------------------------- +/// +/// @brief Set addresses based on the target type (Template) +/// +template< fapi2::TargetType K > +fapi2::ReturnCode set_addresses(const fapi2::Target<K>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ); + +/// +/// @brief Set addresses for a core target type +/// +template<> +fapi2::ReturnCode set_addresses(const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ); +/// +/// @brief Set addresses for an EQ target type +/// +template<> +fapi2::ReturnCode set_addresses(const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ); +/// +/// @brief Set addresses for an EX +/// +template<> +fapi2::ReturnCode set_addresses(const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_target, + ProcessingValues_t& i_structure, + const uint32_t i_entity ); + +// ----------------------------------------------------------------------------- +// Function Implementations +// ----------------------------------------------------------------------------- + +/// ---------------------------------------------------------------------------- +/// +/// @brief Setup based on entity +/// @param[in] i_chipletTarget fapi2 target +/// @param[in] i_entity Entity to perform special wakeup upon. +/// @param[in] i_processing_info Structure containing processing information +/// +template <fapi2::TargetType K> +fapi2::ReturnCode spwkup_setup_entity( const fapi2::Target<K>& i_chipletTarget, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity, + ProcessingValues_t& i_processing_info ) +{ + FAPI_DBG(">> spwkup_setup_entity"); + + uint8_t l_attr_chip_unit_pos; + fapi2::TargetType l_chiplet_type = i_chipletTarget.getType(); + + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parentTarget; + // Get the parent chip to deal with chip level accesses + l_parentTarget = get_chip_target<K> (i_chipletTarget); + + i_processing_info.entity = i_entity; + i_processing_info.b_ex_flag = ( l_chiplet_type == fapi2::TARGET_TYPE_EX ? true : false ); + // Initialize other control structure settings. + i_processing_info.b_xstop_flag = false; + i_processing_info.b_ignore_xstop_flag = false; + i_processing_info.b_wakeup_on_entry_flag = false; + + FAPI_DBG("i_processing: flags " + "entity = %d " + "b_xstop_flag = %d " + "b_ignore_xstop_flag = %d " + "b_wakeup_on_entry_flag = %d " + "b_ex_flag = %d \n", + i_processing_info.entity, + i_processing_info.b_xstop_flag, + i_processing_info.b_ignore_xstop_flag, + i_processing_info.b_wakeup_on_entry_flag, + i_processing_info.b_ex_flag); + + // Get the chiplet number + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, i_chipletTarget, l_attr_chip_unit_pos), + "fapiGetAttribute of ATTR_CHIP_UNIT_POS"); + + FAPI_DBG("Chiplet number = %d of type %X", l_attr_chip_unit_pos, l_chiplet_type); + + // Steering the addresses to the target + FAPI_TRY(set_addresses(i_chipletTarget, i_processing_info, i_entity)); + + +fapi_try_exit: + FAPI_INF("< spwkup_setup_entity" ); + return fapi2::current_err; +} + +/// ---------------------------------------------------------------------------- +/// +/// @brief Check for checkstop and set flags +/// @param[in] i_chipletTarget fapi2 target +/// @param[in] i_processing_info Structure containing processing information +/// +template <fapi2::TargetType K> +fapi2::ReturnCode spwkup_check_xstop( const fapi2::Target<K>& i_chipletTarget, + ProcessingValues_t& i_processing_info ) +{ + FAPI_DBG(">> spwkup_check_xstop"); + + fapi2::buffer<uint64_t> l_intr_type; + + // Get the parent chip to deal with chip level accesses + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parentTarget; + l_parentTarget = get_chip_target<K> (i_chipletTarget); + + uint8_t l_attr_ignore_xstop = 0; + FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG, + l_parentTarget, + l_attr_ignore_xstop), + "fapiGetAttribute of ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG failed"); + + FAPI_INF("Ignore XSTOP: %s", (l_attr_ignore_xstop ? "YES" : "NO")); + i_processing_info.b_ignore_xstop_flag = l_attr_ignore_xstop ? true : false; + + // Read system checkstop indicator + FAPI_TRY(fapi2::getScom(l_parentTarget, + PERV_PIB_INTERRUPT_TYPE_REG, + l_intr_type), + "GetScom of Interrupt Type failed"); + + if(l_intr_type.getBit<PERV_INTERRUPT_TYPE_REG_CHECKSTOP>()) + { + FAPI_INF( "Checkstop present" ); + i_processing_info.b_xstop_flag = true; + } + + // Error out if system is checkstopped and not told to ignore it +// FAPI_ASSERT((!l_attr_ignore_xstop && i_processing_info.b_xstop_flag), +// fapi2::SPWKUP_CHKSTOP() +// .geIGNOREXSTOP(l_attr_ignore_xstop) +// .set_TARGET(l_parentTarget), +// "This chip is xstopped and the attribute ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG is NOT set" ); + +fapi_try_exit: + FAPI_INF("<< spwkup_check_xstop" ); + return fapi2::current_err; +} + +/// ---------------------------------------------------------------------------- +/// +/// @brief Assert special wake-up and poll for done +/// @param[in] i_chipletTarget fapi2 target +/// @param[in] i_processing_info Structure containing processing information +/// @param[in] i_msgId String to prepend to trace outputs +/// +template <fapi2::TargetType K> +fapi2::ReturnCode spwkup_assert(const fapi2::Target<K>& i_chipletTarget, + ProcessingValues_t& i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId ) +{ + + fapi2::buffer<uint64_t> l_stop_hist_state[2]; + fapi2::buffer<uint64_t> l_gpmmr[2]; + fapi2::buffer<uint64_t> l_netctrl[2]; + fapi2::buffer<uint64_t> l_spwkup[2]; + + uint32_t l_pollcount = 0; + bool b_poll_during_xstop_flag; + + // Get the parent chip to deal with chip level accesses + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parentTarget; + l_parentTarget = get_chip_target<K> (i_chipletTarget); + + uint32_t l_special_wakeup_poll_interval_ns = SPECIAL_WAKE_UP_POLL_INTERVAL_NS; + /// Calculate the maximum number of polls until a timeout is thrown + uint32_t l_special_wakeup_max_polls = (SPECIAL_WAKEUP_TIMEOUT_NS / l_special_wakeup_poll_interval_ns); + + // This is done in two phases: 1) assert the special wake-ups to all elements; + // 2) poll for done from all elements + // This allows for parallism (polling for one while the other is in the process of waking up + for (uint32_t i = 0; i < i_processing_info.num_addresses; ++i) + { + FAPI_TRY(fapi2::getScom(l_parentTarget, i_processing_info.history_address[i], l_stop_hist_state[i]), + "GetScom of STOP History 0x%08llX failed", i_processing_info.history_address[i]); + + FAPI_TRY(fapi2::getScom(l_parentTarget, i_processing_info.spwkup_address[i], l_spwkup[i]), + "GetScom of Special Wake-up failed"); + + FAPI_TRY(fapi2::getScom(l_parentTarget, i_processing_info.gpmmr_address[i], l_gpmmr[i]), + "GetScom of GPMMR 0x%08llX failed", i_processing_info.gpmmr_address[i]); + + // Make a note of spwu is already asserted. This flag is useful + // for debug + i_processing_info.b_wakeup_on_entry_flag = l_spwkup[i].getBit<SPWKUP_BIT>(); + + l_spwkup[i].flush<0>().setBit<SPWKUP_BIT>(); + FAPI_TRY(fapi2::putScom(l_parentTarget, i_processing_info.spwkup_address[i], l_spwkup[i]), + "PutScom of Special Wake-up failed"); + + } // num_addresses + + for (uint32_t i = 0; i < i_processing_info.num_addresses; ++i) + { + // Determine whether to poll for completion of Special wake-up. + // Running and STOP <= 2 - can always be polled as these are not + // dependent on an xstop condition. + // STOP > 2 - poll only if not in an xstop condition + + + // @todo RTC 136801 Check the STOP History Register (and other hardware + // and Hcode state) to determine if polling during xstop + // is valid. Refer to ex_determine_inst_pm_state in P8. + // Don't poll if Xstop for now. + b_poll_during_xstop_flag = false; + + // Poll for completion if conditions are right + if ( (!i_processing_info.b_xstop_flag) || ( i_processing_info.b_xstop_flag && b_poll_during_xstop_flag)) + { + // poll for the set completion + l_pollcount = 0; + l_gpmmr[i].flush<0>(); + + while ( !l_gpmmr[i].getBit<GPMMR_SPWKUP_DONE_BIT>() && l_pollcount < l_special_wakeup_max_polls) + { + FAPI_TRY(fapi2::getScom(l_parentTarget, i_processing_info.gpmmr_address[i], l_gpmmr[i]), + "GetScom of GPMMR failed"); + + FAPI_DBG(" Loop get for Special Wake-up Done => 0x%016llx", l_gpmmr[i]); + + fapi2::delay(l_special_wakeup_poll_interval_ns, 1000000); + ++l_pollcount; + } + + if (l_gpmmr[i].getBit<GPMMR_SPWKUP_DONE_BIT>()) + { + FAPI_INF("Special wakeup done is set. SUCCESS! ... "); + } + else + { + FAPI_TRY(fapi2::getScom(l_parentTarget, i_processing_info.netctrl_address[i], l_netctrl[i]), + "GetScom of Network Control register failed"); + + // The following are put in the procedure (vs the XML) to + // capture for Cronus debug + + FAPI_TRY(fapi2::getScom(l_parentTarget, i_processing_info.spwkup_address[i], l_spwkup[i]), + "GetScom of Special Wake-up register failed"); + + FAPI_DBG(" After set of SPWKUP_REG (0x%08llx) => 0x%016llx", + i_processing_info.spwkup_address[i], l_spwkup[i]); + + // We really can't leave a latent spwu bit enabled. Even + /// though we gave it a very long time to complete, we can't + // take the chance that it fires later. So, lets clear it now. + // This will do no harm since the presumption at this point, + // anyway, is that it failed and so therefore it should be cleared + // too. + // + // Note, we only want to do this for count=0 and if + // procesing_info.b_wakeup_on_entry_flag==false as this would be an indication that we, + // right now, just asserted the spwu from a deasserted state. + // Therefore, we can safely also deassert it. + + if (!i_processing_info.b_wakeup_on_entry_flag) + { + FAPI_TRY(spwkup_deassert(i_chipletTarget, i_processing_info, p9specialWakeup::SPWK_MSG_CLEAN_UP_DEASSERT)); + } + + FAPI_ASSERT(false, + fapi2::SPCWKUP_TIMEOUT() + .set_POLLCOUNT(l_pollcount) + .set_NETCTRL(l_netctrl[i]) + .set_SP_WKUP_REG_ADDRESS(i_processing_info.spwkup_address[i]) + .set_SP_WKUP_REG_VALUE(l_spwkup[i]) + .set_SP_WKUP_REG_ADDRESS(i_processing_info.history_address[i]) + .set_SP_WKUP_REG_VALUE(l_stop_hist_state[i]) + .set_ENTITY(i_processing_info.entity), + "Timed out in setting the CPU in Special wakeup"); + } + } // Done checking + else + { + FAPI_ASSERT(false, + fapi2::SPCWKUP_STOP_IN_CHKSTOP() + .set_CHIPLET_TARGET(i_chipletTarget), + "Special_wakeup requested to an chiplet in a STOP state " + "with the system checkstopped that cannot succeed"); + } + } // num_addresses + +fapi_try_exit: + FAPI_INF("< spwkup_check_xstop" ); + return fapi2::current_err; +} + +/// ---------------------------------------------------------------------------- +/// +/// @brief Templated helper to deassert special wake-up +/// @param[in] i_chipletTarget fapi2 target +/// @param[in] i_processing_info Structure containing processing information +/// @param[in] i_msgId String to prepend to trace outputs +/// +template <fapi2::TargetType K> +fapi2::ReturnCode _spwkup_deassert( const fapi2::Target<K>& i_chipletTarget, + uint64_t i_address, + p9specialWakeup::SpecialWakeUpMsg i_msgId) +{ + FAPI_INF("> spwkup_deassert" ); + + fapi2::buffer<uint64_t> l_data64 = 0; + // Get the parent chip to deal with chip level accesses + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parentTarget; + l_parentTarget = get_chip_target<K> (i_chipletTarget); + + FAPI_TRY(fapi2::putScom(l_parentTarget, i_address, l_data64), + "PutScom of Special Wake-up register failed"); + FAPI_DBG(" %s: After clear putscom of SPWKUP_REG (0x%08llx) => 0x%016llx", + *(p9specialWakeup::SPWK_MSG_LIST[i_msgId]), + i_address, + l_data64); + + // This puts an inherent delay in the propagation of the reset transition. + FAPI_TRY(fapi2::getScom(l_parentTarget, i_address, l_data64), + "GetScom of Special Wake-up failed"); + FAPI_DBG(" %s: After read (delay) of SPWKUP_REG (0x%08llx) 0x%016llx", + *(p9specialWakeup::SPWK_MSG_LIST[i_msgId]), + i_address, + l_data64); + +fapi_try_exit: + FAPI_INF("< spwkup_deassert" ); + return fapi2::current_err; +} + + +/// @brief Deassert special wake-up template +/// @param[in] i_chipletTarget fapi2 target +/// @param[in] i_processing_info Structure containing processing information +/// @param[in] i_msgId Id of the string to prepend to trace outputs +/// +template <fapi2::TargetType K> +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<K>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId); + + + +/// +/// @brief Deassert special wake-up - EQ +/// +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<fapi2::TARGET_TYPE_EQ>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId); + +/// +/// @brief Deassert special wake-up - EX +/// +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<fapi2::TARGET_TYPE_EX>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId); + +/// +/// @brief Deassert special wake-up - Core +/// +fapi2::ReturnCode spwkup_deassert( const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_chipletTarget, + const ProcessingValues_t i_processing_info, + p9specialWakeup::SpecialWakeUpMsg i_msgId); +/// ---------------------------------------------------------------------------- +/// +/// @brief Templated helper to assert/deassert the entity bit as targeted. +/// @param[in] i_chipletTarget fapi2 target +/// @param[in] i_operation special wakeup operations to be used. +/// @param[in] i_entity entity to perform special wake-up upon +/// +template <fapi2::TargetType K> +fapi2::ReturnCode _special_wakeup(const fapi2::Target<K>& i_chipletTarget, + const p9specialWakeup::PROC_SPCWKUP_OPS i_operation, + const p9specialWakeup::PROC_SPCWKUP_ENTITY i_entity ) +{ + FAPI_DBG(">> _special_wakeup"); + + fapi2::ReturnCode l_rc; + fapi2::buffer<uint64_t> occFlagReg; + ProcessingValues_t processing_info; + + char l_targetStr[fapi2::MAX_ECMD_STRING_LEN]; + fapi2::toString(i_chipletTarget, l_targetStr, fapi2::MAX_ECMD_STRING_LEN); + + // Get the parent chip to deal with chip level accesses + fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parentTarget; + l_parentTarget = get_chip_target<K> (i_chipletTarget); + + do + { + // Read system checkstop indicator + FAPI_TRY(fapi2::getScom(l_parentTarget, + PU_OCB_OCI_OCCFLG_SCOM, + occFlagReg), + "GetScom of OCC Flag Register Failed"); + + if( !occFlagReg.getBit<SGPE_ACTIVE_BIT>() ) + { + FAPI_INF("SGPE not active. STOP Sub-System not ready for special wakeup" ); + break; + } + + switch (i_operation) + { + + case p9specialWakeup::SPCWKUP_ENABLE: + // Select the addresses to use based on the entity + FAPI_TRY(spwkup_setup_entity(i_chipletTarget, i_entity, processing_info), + "Error: spwkup_setup_entity failed"); + + // Determine if xstop checking should be ignored based on a caller + // set attribute. + // + // This is used during MPIPL clean-up to a core to clear FIRs that + // will eventually clear the xstop condition. However, to do so + // needs the xstop check to not keep the special wake-up operation + // from happening. + FAPI_TRY(spwkup_check_xstop(i_chipletTarget, processing_info)); + + // Proceed + FAPI_INF("Setting Special Wake-up ...") ; + + FAPI_TRY(spwkup_assert(i_chipletTarget, processing_info, p9specialWakeup::SPWK_MSG_ASSERT )); + + break; + + case p9specialWakeup::SPCWKUP_DISABLE: + FAPI_INF("Clearing Special Wake-up..."); + + // Select the addresses to use based on the entity + FAPI_TRY(spwkup_setup_entity(i_chipletTarget, i_entity, processing_info), + "Error: spwkup_setup_entity failed"); + + FAPI_TRY(spwkup_deassert(i_chipletTarget, processing_info, p9specialWakeup::SPWK_MSG_DEASSERT )); + + break; + + default: + ; + } + + } + while(0); + +fapi_try_exit: + FAPI_INF("< p9_cpu_special_wakeup" ); + return fapi2::current_err; +} diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.mk b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.mk new file mode 100644 index 000000000..ca966e02e --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.mk @@ -0,0 +1,26 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/import/chips/p9/procedures/hwp/pm/p9_cpu_special_wakeup_lib.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +PROCEDURE=p9_cpu_special_wakeup_lib +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.mk b/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.mk index 834f8a540..a1408bcb1 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.mk +++ b/src/import/chips/p9/procedures/hwp/pm/p9_pm_reset.mk @@ -24,7 +24,7 @@ # IBM_PROLOG_END_TAG PROCEDURE=p9_pm_reset -libp9_pm_reset_DEPLIBS += p9_pm_utils p9_pm_firinit p9_pm_occ_control p9_cpu_special_wakeup p9_pm_stop_gpe_init p9_pm_occ_gpe_init p9_pm_corequad_init p9_pm_pba_init p9_pm_occ_sram_init p9_pm_ocb_init p9_pm_pss_init +libp9_pm_reset_DEPLIBS += p9_pm_utils p9_pm_firinit p9_pm_occ_control p9_cpu_special_wakeup_ex p9_pm_stop_gpe_init p9_pm_occ_gpe_init p9_pm_corequad_init p9_pm_pba_init p9_pm_occ_sram_init p9_pm_ocb_init p9_pm_pss_init $(call ADD_MODULE_SRCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/lib) $(call ADD_MODULE_SRCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/common/pmlib/include/registers) $(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml index 3690d5596..4bca4b390 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml @@ -72,6 +72,16 @@ </attribute> <!-- ********************************************************************* --> <attribute> + <id>ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>Flag storage to have the Special Wakeup procedure ignore a + checkstop condition. + </description> + <valueType>uint8</valueType> + <writeable/> + </attribute> + <!-- ********************************************************************* --> + <attribute> <id>ATTR_OCC_LFIR</id> <targetType>TARGET_TYPE_PROC_CHIP</targetType> <description>The attribute stores the Local FIR value of OCC taken diff --git a/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml index a87cd29d4..e17f34f65 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/pm_plat_attributes.xml @@ -943,8 +943,8 @@ </description> <initToZero/> <valueType>uint8</valueType> - <platInit/> - </attribute> + <platInit/> + </attribute> <!-- ********************************************************************* --> <attribute> <id>ATTR_POUNDV_BUCKET_NUM</id> @@ -1421,6 +1421,6 @@ </description> <valueType>uint16</valueType> <platInit/> - </attribute> - <!-- ********************************************************************* --> +</attribute> + <!-- ********************************************************************* --> </attributes> diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_cpu_special_wakeup_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_cpu_special_wakeup_errors.xml new file mode 100644 index 000000000..4f050ae1b --- /dev/null +++ b/src/import/chips/p9/procedures/xml/error_info/p9_cpu_special_wakeup_errors.xml @@ -0,0 +1,157 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/import/chips/p9/procedures/xml/error_info/p9_cpu_special_wakeup_errors.xml $ --> +<!-- --> +<!-- OpenPOWER HostBoot Project --> +<!-- --> +<!-- Contributors Listed Below - COPYRIGHT 2016 --> +<!-- [+] International Business Machines Corp. --> +<!-- --> +<!-- --> +<!-- Licensed under the Apache License, Version 2.0 (the "License"); --> +<!-- you may not use this file except in compliance with the License. --> +<!-- You may obtain a copy of the License at --> +<!-- --> +<!-- http://www.apache.org/licenses/LICENSE-2.0 --> +<!-- --> +<!-- Unless required by applicable law or agreed to in writing, software --> +<!-- distributed under the License is distributed on an "AS IS" BASIS, --> +<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or --> +<!-- implied. See the License for the specific language governing --> +<!-- permissions and limitations under the License. --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- Error definitions for p9_cpu_special_wakeup procedure --> +<hwpErrors> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_TIMEOUT</rc> + <description>Special wakeup to targeted chiplet timed out.</description> + <ffdc>POLLCOUNT</ffdc> + <ffdc>NETCTRL</ffdc> + <ffdc>SP_WKUP_REG_ADDRESS</ffdc> + <ffdc>SP_WKUP_REG_VALUE</ffdc> + <ffdc>HISTORY_ADDRESS</ffdc> + <ffdc>HISTORY_VALUE</ffdc> + <ffdc>ENTITY</ffdc> + <!-- + <collectRegisterFfdc> + <id>REG_FFDC_PROC_SLW_PCBS_REGISTERS</id> + <target>EX_IN_ERROR</target> + </collectRegisterFfdc> + <collectRegisterFfdc> + <id>REG_FFDC_PROC_SLW_REGISTERS</id> + <id>REG_FFDC_PROC_SLW_FIR_REGISTERS</id> + <id>REG_FFDC_PROC_SLW_PMC_REGISTERS</id> + <id>REG_FFDC_PROC_SLW_PBA_REGISTERS</id> + <target>CHIP</target> + </collectRegisterFfdc> + <callout> + <target>EX_IN_ERROR</target> + <priority>HIGH</priority> + </callout> + --> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_CODE_BAD_ENTITY</rc> + <description>An invalid entity (eg besides FSP, OCC, or PHYP ENUM) was passed + to p9_cpu_special_wakeup + </description> + <ffdc>ENTITY</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_CODE_BAD_OP</rc> + <description>An invalid operation (eg besides Set or Clear ENUM) was passed to + p9_cpu_special_wakeup + </description> + <ffdc>OPERATION</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_CHKSTOP</rc> + <description>Special_wakeup requested with the system checkstopped and + ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG not set + </description> + <ffdc>ATTRIGNOREXSTOP</ffdc> + <ffdc>TARGET</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_STOP_IN_CHKSTOP</rc> + <description>Special_wakeup requested to a chiplet in a STOP state with the + system checkstopped. + Calling firmware will have to check for this return code to influence dump flow. + Note: this is NOT a loggable error. + </description> + <ffdc>CHIPLET_TARGET</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_NOT_SET</rc> + <description>Special wake-up done is not set but a platform COUNT greater than + 0 exists. Hardware and code are out of sync. + </description> + <ffdc>CHIPLET_TARGET</ffdc> + <ffdc>HISTORY</ffdc> + <ffdc>GPMMR</ffdc> + <ffdc>ENTITY_COUNT</ffdc> + <ffdc>ENTITY</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + <callout> + <target>CHIPLET_TARGET</target> + <priority>LOW</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_INVALID_PMHISTORY</rc> + <description>Invalid PM History detected in p9_cpu_special_wakeup + </description> + <ffdc>PMHIST</ffdc> + <callout> + <target>EX_IN_ERROR</target> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPWKUP_EX_EVEN_CORE_ERROR</rc> + <description>Appropriate Even Core was not found + </description> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPWKUP_EX_EQ_ERROR</rc> + <description>Appropriate Even Core was not found + </description> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SPCWKUP_NOEXCORES</rc> + <description>No good cores to special wake-up in targeted EX + </description> + </hwpError> + <!-- *********************************************************************** --> +</hwpErrors> |