diff options
Diffstat (limited to 'src/sbefw/core/chipop_handler.C')
-rw-r--r-- | src/sbefw/core/chipop_handler.C | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/sbefw/core/chipop_handler.C b/src/sbefw/core/chipop_handler.C new file mode 100644 index 00000000..b2ae4991 --- /dev/null +++ b/src/sbefw/core/chipop_handler.C @@ -0,0 +1,221 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/sbefw/core/chipop_handler.C $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017,2018 */ +/* */ +/* */ +/* 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 "sbetrace.H" +#include "sbe_sp_intf.H" +#include "sbestates.H" +#include "sberegaccess.H" +#include "sbeglobals.H" + +#include "chipop_handler.H" + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass, + cmdStruct_t **o_ppCmd) +{ + #define SBE_FUNC " sbeGetCmdStructAttr " + uint8_t l_numCmds = 0; + *o_ppCmd = NULL; + + size_t cmdClassIndex = HASH_KEY(i_cmdClass); + if(cmdClassIndex < cmdClassTable.len && + cmdClassTable.cmdClassArr[cmdClassIndex].cmdTable) + { + l_numCmds = cmdClassTable.cmdClassArr[cmdClassIndex].cmdTable->len; + *o_ppCmd = cmdClassTable.cmdClassArr[cmdClassIndex].cmdTable->cmdArr; + } + + return l_numCmds; + #undef SBE_FUNC +} + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +uint8_t sbeValidateCmdClass (const uint8_t i_cmdClass, + const uint8_t i_cmdOpcode) +{ + #define SBE_FUNC " sbeValidateCmdClass " + uint8_t l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED; + + SBE_INFO(SBE_FUNC"i_cmdClass[0x%02X], " + "i_cmdOpcode[0x%02X]", i_cmdClass, i_cmdOpcode); + + do + { + uint8_t l_numCmds = 0; + cmdStruct_t *l_pCmd = NULL; + + l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd); + if (!l_numCmds) + { + SBE_ERROR(SBE_FUNC"SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED " + "i_cmdClass[0x%02X], i_cmdOpcode[0x%02X]", + i_cmdClass, i_cmdOpcode); + // Command class not supported + l_rc = SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED; + break; + } + + // @TODO via RTC : 128654 + // Analyze on merging the validation functions into one + // and also on using loop vs switch case performance + for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd) + { + if (i_cmdOpcode == l_pCmd->cmd_opcode) + { + // Command found + l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + break; + } + } + } while (false); + + return l_rc; + #undef SBE_FUNC +} + +sbeCmdFunc_t sbeFindCmdFunc (const uint8_t i_cmdClass, + const uint8_t i_cmdOpcode) + +{ + #define SBE_FUNC " sbeFindCmdFunc " + uint8_t l_numCmds = 0; + cmdStruct_t *l_pCmd = NULL; + + l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd); + + for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd) + { + if (i_cmdOpcode == l_pCmd->cmd_opcode) + { + break; + } + } + + return l_pCmd ? (l_pCmd->cmd_func) : NULL; + #undef SBE_FUNC +} + +sbeChipOpRc_t sbeIsCmdAllowed (const uint8_t i_cmdClass, + const uint8_t i_cmdOpcode) +{ + #define SBE_FUNC " sbeIsCmdAllowedAtState " + bool l_ret = true; + sbeChipOpRc_t retRc; + uint8_t l_numCmds = 0; + cmdStruct_t *l_pCmd = NULL; + l_numCmds = sbeGetCmdStructAttr (i_cmdClass, &l_pCmd); + + for (uint8_t l_cnt = 0; l_cnt < l_numCmds; ++l_cnt, ++l_pCmd) + { + if (i_cmdOpcode == l_pCmd->cmd_opcode) + { + // Get the Present State + uint64_t l_state = + SbeRegAccess::theSbeRegAccess().getSbeState(); + SBE_INFO(SBE_FUNC "SBE State [0x%08X] Fence State[0x%04X]", + (uint32_t)(l_state & 0xFFFFFFFF),l_pCmd->cmd_state_fence); + + switch(l_state) + { + case SBE_STATE_UNKNOWN: + case SBE_STATE_FAILURE: + // All operations are fenced here, return false + // Reset is the only Option available + break; + + case SBE_STATE_IPLING: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_CONTINUOUS_IPL)? false:true); + break; + } + + case SBE_STATE_ISTEP: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_ISTEP)? false:true); + break; + } + + case SBE_STATE_RUNTIME: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_RUNTIME)? false:true); + break; + } + + case SBE_STATE_DUMP: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_DUMPING)? false:true); + break; + } + + case SBE_STATE_MPIPL: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_MPIPL)? false:true); + break; + } + + case SBE_STATE_DMT: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_DMT)? false:true); + break; + } + + case SBE_STATE_QUIESCE: + { + l_ret = ((l_pCmd->cmd_state_fence & + SBE_FENCE_AT_QUIESCE)? false:true); + break; + } + + default: + l_ret = false; + break; + } + if(false == l_ret) + { + retRc.primStatus = SBE_PRI_INVALID_COMMAND; + retRc.secStatus = SBE_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE; + break; + } + // Check if the command is allowed in current security mode + if((SBE_GLOBAL->sbeFWSecurityEnabled) + && (SBE_FENCE_AT_SECURE_MODE & l_pCmd->cmd_state_fence)) + { + retRc.primStatus = SBE_PRI_UNSECURE_ACCESS_DENIED; + retRc.secStatus = SBE_SEC_BLACKLISTED_CHIPOP_ACCESS; + break; + } + break; + } + } + // For any other state, which is not handled above, return from here + return retRc; + #undef SBE_FUNC +} |