summaryrefslogtreecommitdiffstats
path: root/src/sbefw/core/sbeSecureMemRegionManager.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw/core/sbeSecureMemRegionManager.C')
-rw-r--r--src/sbefw/core/sbeSecureMemRegionManager.C187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/sbefw/core/sbeSecureMemRegionManager.C b/src/sbefw/core/sbeSecureMemRegionManager.C
new file mode 100644
index 00000000..ef81ca87
--- /dev/null
+++ b/src/sbefw/core/sbeSecureMemRegionManager.C
@@ -0,0 +1,187 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/core/sbeSecureMemRegionManager.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017 */
+/* */
+/* */
+/* 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 "sbeSecureMemRegionManager.H"
+#include "sbetrace.H"
+#include "sbeutil.H"
+#include "sbeglobals.H"
+
+#ifndef __SBEFW_SEEPROM__
+SBESecureMemRegionManager mainStoreSecMemRegionManager(
+ &SBE_GLOBAL->mainMemRegions[0],
+ MAX_MAIN_STORE_REGIONS);
+SBEOccSramSecMemRegionManager occSramSecRegionManager(
+ &SBE_GLOBAL->occSramRegions[0],
+ MAX_OCC_SRAM_REGIONS);
+
+secureMemRegion_t SBESecureMemRegionManager::getPartialRegionSize(
+ const secureMemRegion_t i_region)
+{
+ secureMemRegion_t ret = {};
+ for(size_t i = 0; i < iv_regionsOpenCnt; i++)
+ {
+ uint64_t minStartAddr = i_region.startAddress < iv_memRegions[i].startAddress ?
+ i_region.startAddress : iv_memRegions[i].startAddress;
+ uint64_t iRegionEndAddress = i_region.startAddress + i_region.size - 1;
+ uint64_t existingRegionEndAddress = iv_memRegions[i].startAddress + iv_memRegions[i].size - 1;
+ uint64_t maxEndAddr = iRegionEndAddress >= existingRegionEndAddress ?
+ iRegionEndAddress : existingRegionEndAddress;
+
+ // detect overlap
+ if((maxEndAddr - minStartAddr + 1) < (i_region.size + iv_memRegions[i].size))
+ {
+ ret = iv_memRegions[i];
+ // Give preference to first region
+ if(i_region.startAddress >= iv_memRegions[i].startAddress &&
+ i_region.startAddress < (iv_memRegions[i].startAddress +
+ iv_memRegions[i].size))
+ {
+ // Return the existing window to the extent of input window
+ ret.startAddress = i_region.startAddress;
+ ret.size = iv_memRegions[i].startAddress + iv_memRegions[i].size
+ - i_region.startAddress;
+ if(ret.size > i_region.size)
+ ret.size = i_region.size;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+#endif //__SBEFW_SEEPROM__
+#ifdef __SBEFW_SEEPROM__
+
+// Public functions
+sbeSecondaryResponse SBESecureMemRegionManager::add(const uint64_t i_startAddr,
+ const uint32_t i_size,
+ const uint8_t i_mode)
+{
+ #define SBE_FUNC "SBESecureMemRegionManager::add"
+ sbeSecondaryResponse rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ do
+ {
+ if(getPartialRegionSize({i_startAddr, i_size, i_mode}).mode)
+ {
+ SBE_ERROR(SBE_FUNC" SBE_SEC_MEM_REGION_AMEND_ATTEMPTED");
+ rc = SBE_SEC_MEM_REGION_AMEND_ATTEMPTED;
+ break;
+ }
+ if(iv_regionsOpenCnt >= iv_maxRegions)
+ {
+ SBE_ERROR(SBE_FUNC" SBE_SEC_MAXIMUM_MEM_REGION_EXCEEDED");
+ rc = SBE_SEC_MAXIMUM_MEM_REGION_EXCEEDED;
+ break;
+ }
+ SBE_INFO(SBE_FUNC" Adding region Mem[0x%08X%08X], size[0x%08X]",
+ SBE::higher32BWord(i_startAddr),
+ SBE::lower32BWord(i_startAddr),
+ i_size);
+ iv_memRegions[iv_regionsOpenCnt++] = {i_startAddr, i_size, i_mode};
+ SBE_INFO(SBE_FUNC" after addition iv_regionsOpenCnt [%d]",
+ iv_regionsOpenCnt);
+ } while(0);
+ return rc;
+ #undef SBE_FUNC
+}
+
+sbeSecondaryResponse SBESecureMemRegionManager::remove(const uint64_t i_startAddr)
+{
+ #define SBE_FUNC "SBESecureMemRegionManager::remove";
+ size_t i = 0;
+ sbeSecondaryResponse rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ for(; i < iv_regionsOpenCnt; i++)
+ {
+ if(i_startAddr == iv_memRegions[i].startAddress)
+ {
+ break;
+ }
+ }
+ if(i < iv_regionsOpenCnt)
+ {
+ SBE_INFO(SBE_FUNC" Deleting region i[%d], Mem[0x%08X%08X], size[0x%08X]",
+ i,
+ SBE::higher32BWord(iv_memRegions[i].startAddress),
+ SBE::lower32BWord(iv_memRegions[i].startAddress),
+ iv_memRegions[i].size);
+ // Remove the empty slot and maintain contiguous list
+ for(size_t j = i; j < iv_regionsOpenCnt-1; j++)
+ {
+ iv_memRegions[j].startAddress = iv_memRegions[j+1].startAddress;
+ iv_memRegions[j].size = iv_memRegions[j+1].size;
+ iv_memRegions[j].mode = iv_memRegions[j+1].mode;
+ }
+
+ iv_regionsOpenCnt--;
+ SBE_INFO(SBE_FUNC" After deletion : iv_regionsOpenCnt[%d]", iv_regionsOpenCnt);
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC" SBE_SEC_MEM_REGION_NOT_FOUND");
+ rc = SBE_SEC_MEM_REGION_NOT_FOUND;
+ }
+ return rc;
+ #undef SBE_FUNC
+}
+
+#endif //__SBEFW_SEEPROM__
+#ifndef __SBEFW_SEEPROM__
+
+sbeSecondaryResponse SBESecureMemRegionManager::isAccessAllowed(
+ secureMemRegion_t i_region)
+{
+ #define SBE_FUNC "SBESecureMemRegionManager::isAccessAllowed"
+ sbeSecondaryResponse rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ if(SBE_GLOBAL->sbeFWSecurityEnabled)
+ {
+ while(i_region.size > 0)
+ {
+ secureMemRegion_t foundregion = getPartialRegionSize(i_region);
+ // Check if the found region has allowable access level
+ // and that the region overlap is from the beginning itself
+ if((i_region.mode & foundregion.mode) &&
+ (i_region.startAddress == foundregion.startAddress))
+ {
+ SBE_INFO(SBE_FUNC" foundRegion Mem[0x%08X%08X], size[0x%08X]",
+ SBE::higher32BWord(foundregion.startAddress),
+ SBE::lower32BWord(foundregion.startAddress),
+ foundregion.size);
+ i_region.size -= foundregion.size;
+ i_region.startAddress += foundregion.size;
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC" Non secure access to memory blocked "
+ "Addr[0x%08X%08X] Size[0x%08X]",
+ SBE::higher32BWord(i_region.startAddress),
+ SBE::lower32BWord(i_region.startAddress),
+ i_region.size);
+ rc = SBE_SEC_BLACKLISTED_MEM_ACCESS;
+ break;
+ }
+ }
+ }
+ return rc;
+ #undef SBE_FUNC
+}
+#endif //__SBEFW_SEEPROM__
OpenPOWER on IntegriCloud