summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorMike Baiocchi <mbaiocch@us.ibm.com>2016-11-04 11:30:17 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-03-08 11:06:34 -0500
commitc3d233bbaf7a2f274147d16edbc080bae0ffd714 (patch)
tree8058bc8e764135eecc21cdcd1177814dd4e180c8 /src/usr
parent1301e43641f7d3f315a0abc8112fa88927c9fa9a (diff)
downloadtalos-hostboot-c3d233bbaf7a2f274147d16edbc080bae0ffd714.tar.gz
talos-hostboot-c3d233bbaf7a2f274147d16edbc080bae0ffd714.zip
Hostboot Base TCE Support
This commit adds the base support for hostboot to enable/disable the use of TCEs. It allows for the creation and managment of a TCE table and also initializes the P9 processors to use this table. Change-Id: Idb40f9df5a90d8b7e87b2f5b745cbe7e66109df2 RTC:145071 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/32562 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C8
-rw-r--r--src/usr/intr/intrrp.H23
-rw-r--r--src/usr/isteps/istep16/call_host_ipl_complete.C15
-rw-r--r--src/usr/isteps/istep21/call_host_runtime_setup.C29
-rw-r--r--src/usr/runtime/makefile3
-rw-r--r--src/usr/runtime/tce.C791
-rw-r--r--src/usr/runtime/tce.H169
-rw-r--r--src/usr/runtime/test/makefile3
-rw-r--r--src/usr/runtime/test/tcetest.H391
-rw-r--r--src/usr/util/makefile3
-rw-r--r--src/usr/util/test/testtcemgr.H363
-rw-r--r--src/usr/util/utiltcemgr.C1276
-rw-r--r--src/usr/util/utiltcemgr.H290
13 files changed, 1981 insertions, 1383 deletions
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 7ecccaa2f..91306a765 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -2099,9 +2099,11 @@ errlHndl_t IStepDispatcher::handleCoalesceHostMsg()
{
TRACFCOMP(g_trac_initsvc, ENTER_MRK"IStepDispatcher::handleCoalesceHostMsg");
- // Ensure the library is loaded
- errlHndl_t err = VFS::module_load("libestablish_system_smp.so");
+ // Ensure the library is loaded
+ //@TODO RTC:164474
+ //errlHndl_t err = VFS::module_load("libestablish_system_smp.so");
+ errlHndl_t err = NULL;
if (err)
{
TRACFCOMP(g_trac_initsvc, "handleCoalesceHostMsg: Error loading module, PLID = 0x%x",
@@ -2109,7 +2111,7 @@ errlHndl_t IStepDispatcher::handleCoalesceHostMsg()
}
else
{
- //@TODO RTC:133831
+ //@TODO RTC:164474
//err = ESTABLISH_SYSTEM_SMP::call_host_coalesce_host();
if (err)
{
diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H
index 1788c9760..1d039f21b 100644
--- a/src/usr/intr/intrrp.H
+++ b/src/usr/intr/intrrp.H
@@ -264,29 +264,6 @@ namespace INTR
};
};
- //Derived from 15.8 PSIHB Software Interfaces of the
- // P9 Pervasive Workbook
- struct PSIHB_SW_INTERFACES_t
- {
- uint64_t psihbbar; //Host Bridge Base Address Register - 0x0
- uint64_t fspbar; //FSP Base Address Register - 0x8
- uint64_t fspmmr; //FSP Memory Mask Register - 0x10
- uint64_t reserved1; //Unused / Reserved
- uint64_t psihbcr; //PSI Host Bridge Ctrl/Status Register - 0x20
- uint64_t psisemr; //PSIHB Status / Error Mask Register - 0x28
- uint64_t reserved2; //Unused / Reserved
- uint64_t phbdsr; //PSIHB Debug Setting register - 0x38
- uint64_t phbscr; //PSI Host Bridge Ctrl/Status Register - 0x40
- uint64_t phbccr; //PSI Host Bridge clear ctl/status reg - 0x48
- uint64_t dmaupaddr; //DMA Upper Address Register - 0x50
- uint64_t icr; //Interrupt Control Register - 0x58
- uint64_t esbciaddr; //ESB CI Base Address - 0x60
- uint64_t esbnotifyaddr; //ESB Notification Address - 0x68
- uint64_t ivtofforig; //IVT Offset Origin Register - 0x70
- uint64_t lsiintlevel; //LSI Int Level Register (lab use) - 0x78
- uint64_t lsiintstatus; //LSI Interrupt Status register - 0x80
- };
-
//Found in the PC Register Specification Document
struct XIVE_IC_THREAD_CONTEXT_t
{
diff --git a/src/usr/isteps/istep16/call_host_ipl_complete.C b/src/usr/isteps/istep16/call_host_ipl_complete.C
index 30857d73c..1242367ef 100644
--- a/src/usr/isteps/istep16/call_host_ipl_complete.C
+++ b/src/usr/isteps/istep16/call_host_ipl_complete.C
@@ -44,6 +44,7 @@
#include <targeting/attrrp.H>
#include <sys/internode.h>
#include <runtime/runtime.H>
+#include <util/utiltce.H>
using namespace ERRORLOG;
using namespace TARGETING;
@@ -63,6 +64,20 @@ void* call_host_ipl_complete (void *io_pArgs)
"call_host_ipl_complete entry" );
do
{
+ // Setup the TCEs needed for the FSP to DMA the PAYLOAD
+/* @TODO RTC 168745 - make this call when FSP is ready for TCE Support
+ * and add check that we're on a FSP system
+ * NOTE: add check to do this only on FSP-based systems
+ * l_err = TCE::utilSetupPayloadTces();
+ *
+ * if( l_err )
+ * {
+ * TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ * ERR_MRK"TCE::utilSetupPayloadTces failed");
+ * break;
+ * }
+ */
+
// Initialize the RUNTIME DATA attributes
// that HDAT needs to allocate memory for us.
// -----------------------------------------
diff --git a/src/usr/isteps/istep21/call_host_runtime_setup.C b/src/usr/isteps/istep21/call_host_runtime_setup.C
index 4d4a85220..06b606ab2 100644
--- a/src/usr/isteps/istep21/call_host_runtime_setup.C
+++ b/src/usr/isteps/istep21/call_host_runtime_setup.C
@@ -37,6 +37,7 @@
#include <runtime/customize_attrs_for_payload.H>
#include <targeting/common/util.H>
#include <vpd/vpd_if.H>
+#include <util/utiltce.H>
//SBE interfacing
#include <sbeio/sbeioif.H>
@@ -254,12 +255,38 @@ void* call_host_runtime_setup (void *io_pArgs)
}
#endif
+ // Close PAYLOAD TCEs
+/* @TODO RTC 168745 - make this call when FSP is ready for TCE Support
+ * and add check that we're on a FSP system
+ * NOTE: move this call to the start of this function
+ * NOTE: add check to do this only on FSP-based systems
+ * l_err = TCE::utilClosePayloadTces();
+ * if ( l_err )
+ * {
+ * TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ * "Failed TCE::utilClosePayloadTces" );
+ * // break from do loop if error occured
+ * break;
+ * }
+ *
+ *
+ * // Disable all TCEs
+ * l_err = TCE::utilDisableTces();
+ * if ( l_err )
+ * {
+ * TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ * "Failed TCE::utilDisableTces" );
+ * // break from do loop if error occured
+ * break;
+ * }
+ */
+
} while(0);
if( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "istep start_payload_failed see plid 0x%x", l_err->plid());
+ "istep host_runtime_setup failed see plid 0x%x", l_err->plid());
// Create IStep error log and cross reference error that occurred
l_StepError.addErrorDetails( l_err );
diff --git a/src/usr/runtime/makefile b/src/usr/runtime/makefile
index 8306eae03..14838e18d 100644
--- a/src/usr/runtime/makefile
+++ b/src/usr/runtime/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2016
+# Contributors Listed Below - COPYRIGHT 2012,2017
# [+] International Business Machines Corp.
#
#
@@ -37,7 +37,6 @@ MODULE = runtime
OBJS += populate_hbruntime.o
OBJS += hdatservice.o
OBJS += fakepayload.o
-OBJS += tce.o
OBJS += errlud_hdat.o
OBJS += customize_attrs_for_payload.o
diff --git a/src/usr/runtime/tce.C b/src/usr/runtime/tce.C
deleted file mode 100644
index 0bfce6cbb..000000000
--- a/src/usr/runtime/tce.C
+++ /dev/null
@@ -1,791 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/runtime/tce.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
-/* */
-/* 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 */
-#ifndef __TCE_C
-#define __TCE_C
-
-#include <trace/interface.H>
-#include <errl/errlentry.H>
-#include <errl/errlmanager.H>
-#include <vmmconst.h>
-#include <runtime/tceif.H>
-#include <sys/mmio.h>
-#include <util/align.H>
-#include <sys/mm.h>
-#include <targeting/common/commontargeting.H>
-#include <targeting/common/utilFilter.H>
-#include <kernel/console.H>
-#include "tce.H"
-#include <runtime/runtime_reasoncodes.H>
-#include <assert.h>
-
-trace_desc_t* g_trac_tce = NULL;
-TRAC_INIT(&g_trac_tce, TCE_TRACE_NAME, 4*KILOBYTE);
-
-
-namespace TCE
-{
- /*************************************************************************/
- // External Interface.
- // NAME: createTceTable Table.
- // Responsible for initalizing the TCE entries
- //
- /*************************************************************************/
- errlHndl_t createTceTable()
- {
- return Singleton<TceMgr>::instance().createTceTable();
- };
-
- /************************************************************************/
- // External Interface.
- // NAME: InitTceInHdw
- // Responsible for setting up the Processors to point to the TCE table
- //
- /************************************************************************/
- errlHndl_t initTceInHdw()
- {
- return Singleton<TceMgr>::instance().initTceInHdw();
- };
-
- /************************************************************************/
- // External Interface:
- // NAME: allocateTces
- // Responsible for allocating TCE Entries
- //
- /************************************************************************/
- errlHndl_t allocateTces(uint64_t startingAddress, uint64_t size, uint64_t&
- startingToken)
- {
-
- return Singleton<TceMgr>::instance().allocateTces(startingAddress,
- size,
- startingToken);
- };
-
- /************************************************************************/
- // External Interface:
- // NAME: deallocateTces
- // Responsible for deallocating TCE Entries
- //
- /************************************************************************/
- errlHndl_t deallocateTces(uint64_t startingToken, uint64_t size)
- {
- return Singleton<TceMgr>::instance().deallocateTces(startingToken,
- size);
- };
-
-};
-
- /************************************************************************/
- //
- // NAME: TceMgr
- // Constructor - set up Tce Table pointers
- //
- /************************************************************************/
- TceMgr::TceMgr(uint64_t i_tableAddr, uint64_t i_tableSize)
- :tceEntryInit(0)
- ,tceTableVaPtr(NULL)
- ,tceTablePhysAddr(i_tableAddr)
- ,maxTceEntries(0)
- ,tceTableSize(i_tableSize)
- {
- maxTceEntries = tceTableSize/(sizeof (uint64_t));
- };
-
- /**************************************************************************/
- //
- // NAME: mapTceTable
- // Utilty to map the Tce Table
- //
- /**************************************************************************/
- errlHndl_t TceMgr::mapTceTable()
- {
- errlHndl_t errl = NULL;
-
- do
- {
-
- // check to make sure the TCE table is not larger than 32M..
- if (tceTableSize > THIRTYTWO_MB)
- {
-
- // TCE table size larger than 32M.. code bug likely as the real
- // TCE table is a fixed address and size.
- TRACFCOMP(g_trac_tce,"TceMgr::mapTceTable: Table size too large..cannot map.");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_MAP
- * @reasoncode RUNTIME::RC_TCE_INVALID_SIZE
- * @userdata1 Address of the TCE Table
- * @userdata2 Size of of the table that is too large?
- * @devdesc TCE Table size requested too large.
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_MAP,
- RUNTIME::RC_TCE_INVALID_SIZE,
- tceTablePhysAddr,
- tceTableSize,
- true /*Add HB SW Callout*/);
- break;
-
- }
-
- // Is the TCE TABLE Address page aligned?
- if (tceTablePhysAddr - ALIGN_PAGE_DOWN(tceTablePhysAddr)!=0)
- {
- // Address not page aligned
- TRACFCOMP(g_trac_tce,"TceMgr::mapTceTable: Table Addr not page aligned.");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_MAP
- * @reasoncode RUNTIME::RC_TCE_ADDR_NOT_ALIGNED
- * @userdata1 Address of the TCE Table
- * @userdata2 none
- * @devdesc TCE Table not page aligned.
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_MAP,
- RUNTIME::RC_TCE_ADDR_NOT_ALIGNED,
- tceTablePhysAddr,
- 0,
- true /*Add HB SW Callout*/);
- break;
- }
-
-
- // If the physical address is less than the VMM size, then the
- // address we are mapping in on the heap and is already mapped.
- // NOTE: This is needed for testing a TCE table outside of the
- // default TCE table location.
- if (tceTablePhysAddr < VMM_MEMORY_SIZE)
- {
- tceTableVaPtr = reinterpret_cast<TceEntry *>(tceTablePhysAddr);
-
- }
- else
- {
- // Map the Physical Tce table Pointer
- tceTableVaPtr =
- reinterpret_cast<TceEntry *>(
- mmio_dev_map(reinterpret_cast<void*>(tceTablePhysAddr),
- THIRTYTWO_MB));
-
- if (tceTableVaPtr == NULL)
- {
- // Got a bad rc from dev Map
- TRACFCOMP(g_trac_tce, "TceMgr::mapTceTable: Device map error.");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_MAP
- * @reasoncode RUNTIME::RC_TCE_DEV_MAP_FAIL
- * @userdata1 Address to be mapped
- * @userdata2 return Code from DevMap
- * @devdesc Device Map Fail
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_MAP,
- RUNTIME::RC_TCE_DEV_MAP_FAIL,
- tceTablePhysAddr,
- tceTableSize,
- true /*Add HB SW Callout*/);
- }
- }
- }while(0);
-
- return errl;
- }
-
- /**************************************************************************/
- //
- // NAME: createTceTable
- // Responsible for initalizing the TCE entries
- //
- /**************************************************************************/
- errlHndl_t TceMgr::createTceTable()
- {
-
- errlHndl_t errl = NULL;
-
- TRACFCOMP(g_trac_tce,"TceMgr::creatTceTable: tceTablePhysAddr = %llx tceTableSize = %llx",tceTablePhysAddr, tceTableSize);
-
- do
- {
- // Map the Tce Table
- errl = mapTceTable();
-
- if (errl != NULL)
- {
- break;
- }
-
- // Zero out the TCE table space.
- memset(tceTableVaPtr, 0, tceTableSize);
-
- // make sure that the memset completes.
- sync();
-
- }while(0);
-
- return errl;
- };
-
- /**************************************************************************/
- //
- // NAME: InitTceInHdw
- // Responsible for setting up the Processors to point to the TCE table
- //
- /**************************************************************************/
- errlHndl_t TceMgr::initTceInHdw()
- {
- errlHndl_t errl = NULL;
-
- TRACFCOMP(g_trac_tce,
- "TceMgr::InitTceInHdw: tceTablePhysAddr = %llx",
- tceTablePhysAddr);
- do
- {
-
- // Loop through the processors and read the PSI_BRIDGE_ADDR
- TARGETING::TargetHandleList l_cpuTargetList;
- getAllChips(l_cpuTargetList, TARGETING::TYPE_PROC);
-
- // Map a device at the PSI_BRIDE_ADDR -
- // <attribute><id>PSI_BRIDGE_BASE_ADDR</id>
- // <default>0x0003FFFE80000000</default>
- uint64_t *mmio_ptr = NULL;
-
- // set up the registers for TCE on all procs
- for (TARGETING::TargetHandleList::const_iterator
- l_cpuIter = l_cpuTargetList.begin();
- l_cpuIter != l_cpuTargetList.end();
- ++l_cpuIter)
- {
- const TARGETING::Target* l_pTarget = *l_cpuIter;
- uint64_t PsiBridgeAddr =
- l_pTarget->getAttr<TARGETING::ATTR_PSI_BRIDGE_BASE_ADDR>();
-
- TRACDCOMP(g_trac_tce,"TceMgr::InitTceInHdw:Psi Bridge Addr = %llx huid = %.8X",PsiBridgeAddr, TARGETING::get_huid(l_pTarget));
-
- // Check if the PSI_BRIDEG_BASE_ADDR is nonzero.. (could be for
- // Tuleta)
- if (PsiBridgeAddr != 0)
- {
- // If the PsiBridgeAddr is not page aligned. assert.
- assert((PsiBridgeAddr - ALIGN_PAGE_DOWN(PsiBridgeAddr)) ==
- 0);
-
- // Map the device for the PSI_BRIDGE_ADDR
- mmio_ptr =
- static_cast<uint64_t*>(
- mm_block_map(
- reinterpret_cast<void*>(PsiBridgeAddr),
- PAGESIZE));
-
- if (mmio_ptr == NULL)
- {
- // Got a bad rc from device Map
- TRACFCOMP(g_trac_tce, "TceMgr::_createTceTable: Device map error.");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_INIT_HDW
- * @reasoncode RUNTIME::RC_TCE_DEV_MAP_FAIL
- * @userdata1 Address to be mapped PsiBridgeAddr
- * @userdata2 Tce Phys Addr
- * @devdesc PSI Bridge device Map failed
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_INIT_HDW,
- RUNTIME::RC_TCE_DEV_MAP_FAIL,
- PsiBridgeAddr,
- tceTablePhysAddr,
- true /*Add HB SW Callout*/);
- break;
- }
-
-
- // NOTE>> WILL MAKE DEBUG WHEN DONE TESTING
- TRACFCOMP(g_trac_tce,"TceMgr::InitTceInHdw:phys addr = %llx",tceTablePhysAddr);
-
- // Put the physical TCE addr in PsiBridgeAddr + 18 this is
- // byte offset but since we are uin64_t increment 3 double
- // words.
- *(mmio_ptr + 0x3) = tceTablePhysAddr;
-
- eieio();
-
- // NOTE>> WILL MAKE DEBUG WHEN DONE TESTING
- TRACFCOMP(g_trac_tce,"TceMgr::InitTceInHdw:physaddr in Hardware = %llx",*(mmio_ptr + 0x3));
-
- // Turn on TCE enable (MMIO offset 0x90)
- // the mmio_ptr is uint64_t
- *(mmio_ptr + 0x12) = 0x1;
-
- // NOTE>> WILL MAKE DEBUG WHEN DONE TESTING
- TRACFCOMP(g_trac_tce,"TceMgr::InitTceInHdw:Set MMIO offset 0x90 = %llx",*(mmio_ptr + 0x12));
-
- // unmap the device..
- uint64_t rc =
- mm_block_unmap(reinterpret_cast<void*>(mmio_ptr));
-
- if (rc != 0)
- {
- // Got a bad rc from device unmap
- TRACFCOMP(g_trac_tce,
- "TceMgr::initTce: device unmap error.");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_INIT_HDW
- * @reasoncode RUNTIME::RC_TCE_DEV_UNMAP_FAIL
- * @userdata1 Virtual Addr
- * @userdata2 return Code from devUnMap
- * @devdesc Device UnMap Failure
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_INIT_HDW,
- RUNTIME::RC_TCE_DEV_UNMAP_FAIL,
- reinterpret_cast<uint64_t>(mmio_ptr),
- rc,
- true /*Add HB SW Callout*/);
- break;
- }
-
- mmio_ptr = NULL;
- }
- }
-
- }while(0);
-
- // If succsesfull set init to 1
- if (errl == NULL)
- {
- tceEntryInit = 1;
-
- // Successfully initialized the TCE table and hardware.
- TRACFCOMP(g_trac_tce, "TceMgr::_initTceInHdw: TCE initialized and setup");
- }
-
- return errl;
- }
-
-
- /************************************************************************/
- //
- // NAME: allocateTces
- // Responsible for allocating TCE Entries
- //
- /************************************************************************/
- errlHndl_t TceMgr::allocateTces(uint64_t i_startingAddress,
- uint64_t i_size,
- uint64_t& o_startingToken)
- {
- errlHndl_t errl = NULL;
-
- TRACFCOMP(g_trac_tce,
- "TceMgr::AllocateTce: start for addr = %llx and size = %llx",
- i_startingAddress, i_size);
-
- // Default the starting Token to invalid Token.
- o_startingToken = INVALID_TOKEN_ENTRY;
-
- do
- {
-
- // Check to see if init was run.. If not then error...
- if (!tceEntryInit)
- {
- // TceInit did not run before allocate was called
- TRACFCOMP(g_trac_tce,"TceMgr::AllocateTce: ERROR-initTceInHdw has not run");
-
- // error out because allocate was called before INIT.. Could
- // possibly just call init here.. but need to verify exactly
- // WHEN the init can get called..
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_ALLOCATE
- * @reasoncode RUNTIME::RC_TCE_INIT_NOT_RUN
- * @userdata1 Address to start TCE
- * @userdata2 Size of the address space tring to get TCEs
- * for.
- * @devdesc TCE Table has not been initialized yet
- */
- errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_ALLOCATE,
- RUNTIME::RC_TCE_INIT_NOT_RUN,
- i_startingAddress,
- i_size,
- true /*Add HB SW Callout*/);
- errl->collectTrace(TCE_TRACE_NAME,KILOBYTE);
-
- break;
- }
-
- // Check to see if createTceTable ran before allocate. If not we
- // need to make sure the hardware is mapped.. If we are in
- // multi-node we would run Create on only 1 node and other node
- // could use that table to we don't need to create the table twice.
- if (tceTableVaPtr == NULL)
- {
- // createTceTable has not run
- TRACFCOMP(g_trac_tce,"TceMgr::AllocateTce: ERROR - createTceTable has not run so doing the mapping here.");
-
- errl = mapTceTable();
-
- if (errl != NULL)
- {
- break;
- }
- }
-
- //if not page aligned.. expecting a page aligned address passed in
- if (i_startingAddress - ALIGN_PAGE_DOWN(i_startingAddress) != 0)
- {
- TRACFCOMP(g_trac_tce,"TceMgr::AllocateTce: ERROR-Address not page aligned");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_ALLOCATE
- * @reasoncode RUNTIME::RC_TCE_ADDR_NOT_ALIGNED
- * @userdata1 Address to start TCE
- * @userdata2 Size of the address space tring to get TCEs
- * for.
- * @devdesc The Physical Address for the TCE entry is not
- * page aligned.
- */
- errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_ALLOCATE,
- RUNTIME::RC_TCE_ADDR_NOT_ALIGNED,
- i_startingAddress,
- i_size,
- true /*Add HB SW Callout*/);
- break;
- }
-
- // Calculate the number of TCE entries needed
- uint32_t numTcesNeeded = ALIGN_PAGE_DOWN(i_size)/PAGESIZE;
-
- // If more than the number of TCE entry avail.. error out.
- if (numTcesNeeded > maxTceEntries)
- {
- TRACFCOMP(g_trac_tce,"TceMgr::AllocateTce: ERROR - Too many entries requested");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_ALLOCATE
- * @reasoncode RUNTIME::RC_TCE_INVALID_SIZE
- * @userdata1 Address to start TCE
- * @userdata2 Size of the address space tring to get TCEs
- * for.
- * @devdesc The size requested is too large for the table
- */
- errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_ALLOCATE,
- RUNTIME::RC_TCE_INVALID_SIZE,
- i_startingAddress,
- i_size,
- true /*Add HB SW Callout*/);
- break;
- }
-
- // Find a first consequetive group of TCE entries requested
- int startingIndex = 0;
- bool found = false;
-
- // Start at the beginning and search for the first empty entry
- for (uint32_t tceIndex = 0;
- tceIndex < maxTceEntries;
- tceIndex++)
- {
- if (!tceTableVaPtr[tceIndex].valid)
- {
- uint32_t availIndex = 0;
-
- // if not enough space avail.
- if (numTcesNeeded+tceIndex > maxTceEntries)
- {
- break;
- }
- for (uint32_t IndexInRow = tceIndex;
- IndexInRow < numTcesNeeded + tceIndex;
- IndexInRow++)
- {
- // If the entry is Not valid.. then the entry is
- // available
- if (!tceTableVaPtr[IndexInRow].valid)
- {
- // Increment availIndex
- availIndex++;
- }
- // found a valid entry so need to start the count over.
- else
- {
- // increment past the tce entries we already checked
- tceIndex = IndexInRow+1;
-
- // reset the avail index
- availIndex = 0;
-
- break;
- }
-
- // If we found enough consecutive TCE entires
- if (availIndex >= numTcesNeeded)
- {
- // set the starting index
- startingIndex = tceIndex;
- // mark it found
- found = true;
- break;
- }
- }
- // break out and update the table
- if (found)
- {
- break;
- }
-
- // did not find consecutive TCE entries so continue.
- }
- }
-
-
- if (found)
- {
- // Do a for loop here to loop through the number of TCE entries
- // and set the valid bits.. read address changes.. have to add
- // PAGESIZE to each address
- for (uint32_t i = startingIndex;
- i<numTcesNeeded+startingIndex;
- i++)
- {
- tceTableVaPtr[i].realPageNumber = i_startingAddress +
- (i*PAGESIZE);
- tceTableVaPtr[i].valid = 1;
- tceTableVaPtr[i].writeAccess = 1;
- tceTableVaPtr[i].readAccess = 1;
- }
-
- // We are returning offset into the TCE table for the start of
- // the first TCE entry.
- o_startingToken = startingIndex * PAGESIZE;
-
- TRACFCOMP(g_trac_tce,"TceMgr::AllocateTce: Token = %llx for addr = %llx and size = %llx",o_startingToken, i_startingAddress, i_size);
- }
- else // not found means not enough space for request
- {
- TRACFCOMP(g_trac_tce,"TceMgr::AllocateTce: ERROR -Not enough free entries for this request");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_ALLOCATE
- * @reasoncode RUNTIME::RC_TCE_NOT_ENOUGH_FREE_ENTRIES
- * @userdata1 Address to start TCE
- * @userdata2 Size of the address space trying to get TCEs
- * for.
- * @devdesc The size requested is too large.
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_ALLOCATE,
- RUNTIME::RC_TCE_NOT_ENOUGH_FREE_ENTRIES,
- i_startingAddress,
- i_size,
- true /*Add HB SW Callout*/);
- break;
- }
- }while(0);
-
- TRACFCOMP(g_trac_tce, "TceMgr::AllocateTce: EXIT");
-
- return errl;
- }
-
-
- /*************************************************************************/
- //
- // NAME: deallocateTces
- // Responsible for deallocating TCE Entries
- //
- /*************************************************************************/
- errlHndl_t TceMgr::deallocateTces(uint64_t i_startingToken,
- uint64_t i_size)
- {
-
- errlHndl_t errl = NULL;
- bool isContiguous = true;
-
- TRACFCOMP(g_trac_tce,"TceMgr::DeAllocateTce: START: for Token = %llx for size = %llx",i_startingToken, i_size);
-
- do
- {
- // Get number of TCEs needed.
- uint32_t numTcesNeeded = ALIGN_PAGE_DOWN(i_size)/PAGESIZE;
- uint32_t startingIndex = i_startingToken/PAGESIZE;
-
- // if the Token passed in equals the default token, or the
- // startingIndex is larger than the max number of indexes avail
- if ((i_startingToken == INVALID_TOKEN_ENTRY) ||
- (startingIndex > maxTceEntries))
- {
- // User passed in an invalid token, do not do a deallocate and
- // return
- TRACFCOMP(g_trac_tce,"TceMgr::DeallocateTce: ERROR -invalid Token = %lx, No deallocate.", i_startingToken);
-
- break;
- }
-
- if (startingIndex+numTcesNeeded > maxTceEntries)
- {
- TRACFCOMP(g_trac_tce,"TceMgr::DeallocateTce: ERROR - request goes past the end of the tce table");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_DEALLOCATE
- * @reasoncode RUNTIME::RC_TCE_INVALID_SIZE
- * @userdata1 starting index
- * @userdata2 number of TCEs needed for this request
- * @devdesc The size requested is too large for the table
- * space avail starting at the Token passed in.
- */
- errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_DEALLOCATE,
- RUNTIME::RC_TCE_INVALID_SIZE,
- startingIndex,
- numTcesNeeded,
- true /*Add HB SW Callout*/);
- errl->collectTrace(TCE_TRACE_NAME,KILOBYTE);
-
- errlCommit(errl,RUNTIME_COMP_ID);
-
- numTcesNeeded = numTcesNeeded -
- ((startingIndex+numTcesNeeded)-maxTceEntries);
-
- TRACFCOMP(g_trac_tce,"TceMgr::DeallocateTce: ERROR - clearing from index = %d to end of table", startingIndex);
-
- }
-
- // Currently do not check for valid entries.. Just clear as
- // requested.
- uint64_t realAddress = 0;
-
- for (uint32_t tceIndex = startingIndex;
- tceIndex < (startingIndex + numTcesNeeded);
- tceIndex++)
- {
- if (tceIndex != startingIndex)
- {
- // check that the address space is contiguous
- if (((tceTableVaPtr[tceIndex].realPageNumber -
- realAddress) != PAGESIZE) &&
- ((tceTableVaPtr[tceIndex].realPageNumber -
- realAddress) != 0))
- {
- isContiguous = false;
- }
- }
-
- realAddress = tceTableVaPtr[tceIndex].realPageNumber;
-
- // Clear out the TCE entry to 0
- tceTableVaPtr[tceIndex].WholeTceEntry = 0;
- }
-
- if (!isContiguous)
- {
- // We know the range to delete is not contingous.. the Token and
- // size passed in crosses past individual allocates. We will
- // create error log to indicate that but will clear number of
- // entries requested by caller
- TRACFCOMP(g_trac_tce,"TceMgr::DeallocateTce: ERROR - request was not contiguous TCE entries");
-
- /*@
- * @errortype
- * @moduleid RUNTIME::MOD_TCE_DEALLOCATE
- * @reasoncode RUNTIME::RC_TCE_ENTRY_NOT_CONTIGUOUS
- * @userdata1 i_startingToken
- * @userdata2 Size of the address space trying to deallocate
- * @devdesc The deallocate went across TCE Allocate space.
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- RUNTIME::MOD_TCE_DEALLOCATE,
- RUNTIME::RC_TCE_ENTRY_NOT_CONTIGUOUS,
- i_startingToken,
- i_size,
- true /*Add HB SW Callout*/);
- errl->collectTrace(TCE_TRACE_NAME,KILOBYTE);
- errlCommit(errl,RUNTIME_COMP_ID);
- break;
- }
-
- }while(0);
-
- TRACFCOMP(g_trac_tce,"TceMgr::DeAllocateTce: COMPLETE for Token = %llx for size = %llx",i_startingToken, i_size);
-
- return errl;
- }
-
- /**************************************************************************/
- //
- // NAME: ~TceMgr
- // Destructor
- //
- /**************************************************************************/
- TceMgr::~TceMgr()
- {
- // If the If phys addr and VA table address match and If the physical
- // addr is not less than VMM memory size we need unmap
- // If it was less than VMM Memory it was already mapped outside of the
- // TCE scope and doesn't need to be unmapped here.
- if ((tceTablePhysAddr != reinterpret_cast<uint64_t>(tceTableVaPtr)) &&
- (!(tceTablePhysAddr < VMM_MEMORY_SIZE)))
- {
- if (tceTableVaPtr!= NULL)
- {
- // Unmap the tceTableVaPtr
- uint64_t rc =
- mm_block_unmap(reinterpret_cast<void*>(tceTableVaPtr));
-
- if (rc != 0)
- {
- TRACFCOMP(g_trac_tce,"TceMgr::~TceMgr: ERROR - Unmap failed rc = %d", rc);
- }
- }
- }
- else
- {
-
- TRACFCOMP(g_trac_tce,"TceMgr::~TceMgr: No Unmap required. testing..");
- }
- }
-
-#endif
diff --git a/src/usr/runtime/tce.H b/src/usr/runtime/tce.H
deleted file mode 100644
index 487a4bf67..000000000
--- a/src/usr/runtime/tce.H
+++ /dev/null
@@ -1,169 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/runtime/tce.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* COPYRIGHT International Business Machines Corp. 2013,2014 */
-/* */
-/* 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 */
-#ifndef __TCE_H
-#define __TCE_H
-
-#include <stdint.h>
-#include <builtins.h>
-#include <errl/errlentry.H>
-#include <devicefw/userif.H>
-
-
-
-
-struct TceEntry
-{
- // TCE Table
- union
- {
- uint64_t WholeTceEntry;
- struct {
- uint64_t realPageNumber :52; // real page number
- uint64_t valid :1; // The tces is valid for IO
- uint64_t reserved :9; // reserved bits
- uint64_t writeAccess :1; // Write access allowed
- uint64_t readAccess :1; // Read access allowed
- };
-
- };
-};
-
-
-/** @class TceMgr
- * @brief Responsible for managing the TCE entries
- *
- */
- class TceMgr
- {
-
- private:
- /** Indicator of TCEs being intialized */
- int tceEntryInit;
-
- /** Pointer to the Mapped TCE Table */
- TceEntry *tceTableVaPtr;
- /** physical address of the TCE Table */
- uint64_t tceTablePhysAddr;
-
- //** Max number of TCE entries - via size*/
- uint64_t maxTceEntries;
-
- /** size of the Tce Table */
- uint64_t tceTableSize;
-
-
- /**
- * @brief Responsible for mapping the TCE Table
- *
- * @return errlHndl_t - Return error log if unsuccessful
- *
- */
- errlHndl_t mapTceTable(void);
-
- public:
- /**
- * @brief Constructor. Initializes instance variables.
- * @param[in/default] i_tableAddr - Starting address of the TCE
- * table.. Default address is TCE_TABLE_ADDR. This was added
- * for testing TCE entries and not using the "real" table
- * @param[in/default] i_tableSize - Size of the TCE table. Default value
- * is TCE_TABLE_SIZE
- */
- TceMgr(uint64_t i_tableAddr = TCE_TABLE_ADDR,
- uint64_t i_tableSize = TCE_TABLE_SIZE);
-
- /**
- * Destructor.
- * No action necessary.
- */
- ~TceMgr();
-
- /** Max TCE Entries for the TCE Table */
- enum
- {
- NUM_TCE_TABLE_ENTRIES = 0x80000, // 512k entries
- };
-
- enum
- {
- INVALID_TOKEN_ENTRY = 0xFFFFFFFFFFFFFFFF,
- };
-
-
-
- /**
- * @brief Responsible for initalizing the TCE Table and mapping the
- * TCEtable
- *
- * @return errlHndl_t - Return error log if unsuccessful
- *
- */
- errlHndl_t createTceTable();
-
-
- /**
- * @brief Responsible for setting up the Processors to point to the TCE
- * table
- *
- * @return errlHndl_t - Return error log if unsuccessful
- *
- */
- errlHndl_t initTceInHdw();
-
-
- /**
- * @brief Responsible for allocating TCE Entries
- *
- * @param[in] i_startingAddress - Starting address to TCE
- * @param[in] i_size - Size of the address space
- * @param[out] startingToken - Starting Entry into the table.
- * (this is an offset into the array based on the
- * TCE index * PAGESIZE. Each TCE entry maps to a
- * pagesize of memory)
- *
- * @return errl - Return Error Handle if failed.
- *
- */
- errlHndl_t allocateTces(uint64_t i_startingAddress,
- uint64_t i_size,
- uint64_t& o_startingToken);
-
- /**
- * @brief Responsible for deallocating TCE Entries
- *
- * @param[in] i_startingToken - Token indicating the starting entry to
- * remove
- * @param[in] i_size - Size of memory space to remove TCE entries
- * associated
- *
- * @return errl - Return Error Handle if fatal failure occurred.
- *
- */
- errlHndl_t deallocateTces(uint64_t i_startingToken,
- uint64_t i_size);
-
-
- };
-
-#endif
-
diff --git a/src/usr/runtime/test/makefile b/src/usr/runtime/test/makefile
index bebc21cd2..02c6ba3e6 100644
--- a/src/usr/runtime/test/makefile
+++ b/src/usr/runtime/test/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2016
+# Contributors Listed Below - COPYRIGHT 2012,2017
# [+] International Business Machines Corp.
#
#
@@ -27,7 +27,6 @@ ROOTPATH = ../../../..
MODULE = testruntime
#@TODO RTC 132750
#TESTS += hdatservicetest.H
-#TESTS += tcetest.H
TESTS += test_customize_attrs_for_payload.H
# The testcase depends on the following file, but it is typically only compiled
diff --git a/src/usr/runtime/test/tcetest.H b/src/usr/runtime/test/tcetest.H
deleted file mode 100644
index 2baa4ab7d..000000000
--- a/src/usr/runtime/test/tcetest.H
+++ /dev/null
@@ -1,391 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/usr/runtime/test/tcetest.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
-/* */
-/* 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 */
-
-#ifndef __TEST_TCETEST_H
-#define __TEST_TCETEST_H
-
-/**
- * @file tcetest.H
- *
- */
-
-#include <cxxtest/TestSuite.H>
-
-#include <arch/ppc.H> //for MAGIC
-#include <errl/errlmanager.H>
-#include <runtime/runtime.H>
-#include <targeting/common/commontargeting.H>
-#include <runtime/tceif.H>
-#include "../tce.H"
-#include <util/align.H>
-#include <kernel/console.H>
-#include <sys/mmio.h>
-#include <kernel/pagemgr.H>
-
-extern trace_desc_t* g_trac_tce;
-
-class TCETest: public CxxTest::TestSuite
-{
- public:
- void testTCE(void)
- {
- TRACFCOMP( g_trac_tce, "testTCE> start" );
- errlHndl_t errhdl = NULL;
- uint64_t token0 = 0;
- uint64_t token1 = 0;
- uint64_t token2 = 0;
- uint64_t token3 = 0;
- uint64_t token4 = 0;
- uint64_t token5 = 0;
-
- uint64_t l_tceTable =
- reinterpret_cast<uint64_t>(PageManager::allocatePage(4, true));
-
-
- TceMgr *TceTable = new
- TceMgr(l_tceTable+100,100*(sizeof(uint64_t)));
-
- //---------------------------------------------------
- // TEST 1 - Call Create with unaligned addr
- //---------------------------------------------------
-
- errhdl = TceTable->createTceTable();
-
- if (errhdl == NULL)
- {
- TRACFCOMP( g_trac_tce,"TestTce: T1: Did not get expected error from CreateTce ");
- TS_FAIL("testTcE> T1 Did not get expected error back.");
- }
- else
- {
- TRACFCOMP( g_trac_tce,"TestTce: T1: Got expected error unaligedn addr back from CreateTce ");
- delete errhdl;
- }
-
- // Since we are not page aligned.. Delete the TceTable
- delete TceTable;
-
- // create new TCE table with the aligned address but with a size too
- // large
- TceTable = new TceMgr(l_tceTable, THIRTYTWO_MB + PAGESIZE);
-
-
- //---------------------------------------------------
- // TEST 2 - Call create with aligned addr with large addr
- //---------------------------------------------------
- errhdl = TceTable->createTceTable();
-
- if (errhdl == NULL)
- {
- TRACFCOMP( g_trac_tce,"TestTce: T2: Did not get expected error from CreateTce ");
- TS_FAIL("testTcE> T2 Did not get expected error back.");
- }
- else
- {
- TRACFCOMP( g_trac_tce,"TestTce: T2: Got expected error, size > 32M back from CreateTce ");
- delete errhdl;
- }
-
-
- // Since the size was too big. Delete the TceTable
- delete TceTable;
-
- // create new TCE table with the aligned address and valid size
- TceTable = new TceMgr(l_tceTable,100*(sizeof(uint64_t)));
-
-
- //---------------------------------------------------
- // TEST 3 - Call allocate before init.
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0, ((16*PAGESIZE)), token0);
-
- if (errhdl != NULL)
- {
- delete errhdl;
- errhdl = NULL;
- }
- else
- {
- TRACFCOMP( g_trac_tce,"TestTCE T3: Did not get back expected error");
- TS_FAIL("testTCE:T3: No error when address not page aligned.");
- }
-
- //---------------------------------------------------
- // TEST 4 - Call create with aligned addr
- //---------------------------------------------------
- errhdl = TceTable->createTceTable();
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce,
- "TestTce: T4: Got unexpected error from CreateTce ");
- TS_FAIL("testTcE> T4 got unexpected error back.");
- errlCommit(errhdl,RUNTIME_COMP_ID);
-
- }
-
- //---------------------------------------------------
- // TEST 5 - Call init.
- //---------------------------------------------------
-
- errhdl = TceTable->initTceInHdw();
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce,
- "TestTce: T5: Got unexpected error from InitTCEINHdw ");
- TS_FAIL("testTcE> T5 got unexpected error back.");
- errlCommit(errhdl,RUNTIME_COMP_ID);
-
- }
-
- token0 = 0;
-
- //---------------------------------------------------
- // TEST 6 - trying to allocate too large of size.
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0,
- (520*KILOBYTE*PAGESIZE),
- token0);
-
- if (errhdl != NULL)
- {
- delete errhdl;
- errhdl = NULL;
- }
- else
- {
- TRACFCOMP( g_trac_tce, "testTCE>T6: Did not get expecte error");
- TS_FAIL("testTCE> T6: No errorLog when size too large");
- }
-
-
- //---------------------------------------------------
- // TEST 7 - Address not page aligned.
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x4140, ((16*PAGESIZE)), token0);
-
- if (errhdl != NULL)
- {
- delete errhdl;
- errhdl = NULL;
- }
- else
- {
- TRACFCOMP( g_trac_tce, "testTCE:T7: Did not get back expected error");
- TS_FAIL("testTCE:T7 No error when addr not page aligned");
- }
-
-
- //---------------------------------------------------
- // TEST 8 - valid address with 8 pages in size
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0000000004000000,
- PAGESIZE*8,
- token1);
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE> T8: Got unexpected error ");
- TS_FAIL("testTCE> T8 got unexpected error back.");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
- else if (token1 != 0)
- {
- TRACFCOMP( g_trac_tce, "testTCEs> T8: Did not get back expected Token= %lx", token1);
- TS_FAIL("testTCEs> T8 got wrong Token.");
-
- }
-
- //---------------------------------------------------
- // TEST 9 - valid address with 16 pages in size
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0000000004010000,
- PAGESIZE*16,
- token2);
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE> T9: Got unexpected error ");
- TS_FAIL("testTCE> T9 got unexpected error back.");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
- else if (token2 != 0x8000)
- {
- TRACFCOMP( g_trac_tce, "testTCE> T9: Did not get back expected Token = %lx ", token2);
- TS_FAIL("testTCE> T9 got wrong Token.");
- }
-
-
- //---------------------------------------------------
- // TEST 10 - valid address with 50 pages in size
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0000000004800000,
- PAGESIZE*50,
- token3);
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE> T10: Got unexpected error ");
- TS_FAIL("testTCE> T10 got unexpected error back.");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
- else if (token3 != 0x18000)
- {
- TRACFCOMP( g_trac_tce, "testTCE> T10: Did not get back expected Token = %lx ", token3);
- TS_FAIL("testTCE> T10 got wrong Token.");
- }
-
-
- //---------------------------------------------------
- // TEST 11 - Deallocate token with 16 pages from above
- //---------------------------------------------------
- errhdl = TceTable->deallocateTces(token2,
- PAGESIZE*16);
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T11: Got unexpected error ");
- TS_FAIL("testTCE:T11 Deallocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
-
-
- token2 = 0;
-
- //---------------------------------------------------
- // TEST 12 Allocate 10 pages.. will go into the slot left by the
- // previous allocate
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0000000004010000,
- PAGESIZE*10,
- token2);
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "T12: Got unexpected error ");
- TS_FAIL("testAllocateTCEs> T12 Allocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
- else if (token2 != 0x8000)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T12: Did not get back expected Token = %lx", token2);
- TS_FAIL("testTCE:T12: got wrong Token.");
- }
-
-
- //---------------------------------------------------
- // TEST 13 Allocate 10 pages.. will have ot pass the 6 slots avail from
- // the 16 page dealloate.. So will go past that to find a valid index to
- // fit the 20 entries
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0000000005010000,
- PAGESIZE*20,
- token4);
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T13: Got unexpected error ");
- TS_FAIL("testTCE:T13: Allocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
- else if (token4 != 0x4a000)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T13: Did not get back expected Token = %lx ", token4);
- TS_FAIL("testTCE:T10: got wrong Token.");
- }
-
-
-
- //---------------------------------------------------
- // TEST 14 Allocate 6 pages.. will go into the 6 slots avail from
- // the 16 page dealloate..
- //---------------------------------------------------
- errhdl = TceTable->allocateTces(0x0000000006010000,
- PAGESIZE*6,
- token5);
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T14: Got unexpected error ");
- TS_FAIL("testTCE:T14: Allocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
- else if (token5 != 0x12000)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T14: Did not get back expected Token ");
- TS_FAIL("testTCE:T14: got wrong Token.");
- }
-
-
- //---------------------------------------------------
- // TEST 15 Deallocate 20 pages from above
- //---------------------------------------------------
- errhdl = TceTable->deallocateTces(token4, PAGESIZE*20);
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T15: Got unexpected error ");
- TS_FAIL("testTCE:T15: Deallocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
-
- //---------------------------------------------------
- // TEST 16 Deallocate 10 pages from above
- //---------------------------------------------------
- errhdl = TceTable->deallocateTces(token2, PAGESIZE*10);
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T16: Got unexpected error ");
- TS_FAIL("testTCE:T16: Deallocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
-
- //---------------------------------------------------
- // TEST 17 Deallocate Too large of size. No error returned instead the
- // code should to end of the TCE table and commit errorlog and return
- //---------------------------------------------------
- errhdl = TceTable->deallocateTces(token5, (520*KILOBYTE*PAGESIZE));
-
- if (errhdl != NULL)
- {
- TRACFCOMP( g_trac_tce, "testTCE:T17: Got unexpected error returned");
- TS_FAIL("testTCE:T17: Deallocate got unexpected error");
-
- errlCommit(errhdl,RUNTIME_COMP_ID);
- }
-
- TRACFCOMP(g_trac_tce, "testTCE> complete" );
- }
-
-
-
-};
-#endif
diff --git a/src/usr/util/makefile b/src/usr/util/makefile
index 70df3b790..0c3e100cb 100644
--- a/src/usr/util/makefile
+++ b/src/usr/util/makefile
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2016
+# Contributors Listed Below - COPYRIGHT 2012,2017
# [+] International Business Machines Corp.
#
#
@@ -33,6 +33,7 @@ OBJS += utilfile.o
OBJS += utillidmgr.o
OBJS += utillidpnor.o
OBJS += utilmbox_scratch.o
+OBJS += utiltcemgr.o
SUBDIRS += test.d
SUBDIRS += runtime.d
diff --git a/src/usr/util/test/testtcemgr.H b/src/usr/util/test/testtcemgr.H
new file mode 100644
index 000000000..904e46c12
--- /dev/null
+++ b/src/usr/util/test/testtcemgr.H
@@ -0,0 +1,363 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/util/test/testtcemgr.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] 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 */
+
+#ifndef __TEST_TCETEST_H
+#define __TEST_TCETEST_H
+
+/**
+ * @file tcetest.H
+ *
+ */
+
+#include <cxxtest/TestSuite.H>
+
+#include <errl/errlmanager.H>
+#include <targeting/common/commontargeting.H>
+#include <util/utiltce.H>
+#include <util/util_reasoncodes.H>
+#include "../utiltcemgr.H"
+
+extern trace_desc_t* g_trac_tce;
+
+
+class TCETest: public CxxTest::TestSuite
+{
+ public:
+
+ // This helper functions retrieves the private member variable
+ // iv_allocatedAddrs from the Singleton UtilTceMgr class
+ std::map<uint64_t, uint32_t> getAllocatedAddrsMap(void)
+ {
+ std::map<uint64_t, uint32_t> o_map(TCE::getTceManager().iv_allocatedAddrs);
+ return o_map;
+ };
+
+
+ // This helper function looks for the position associated with the input
+ // address in the Singleton's UtilTceMgr::iv_allocatedAddrs
+ uint32_t getPos(uint64_t i_addr)
+ {
+ uint32_t o_pos = 0xFEFEFEFE; // Default for no position found
+
+ auto map = getAllocatedAddrsMap();
+
+ TRACDCOMP(g_trac_tce,ENTER_MRK"TCETest::getPos: i_addr=0x%llX, map.size=%d", i_addr, map.size());
+
+ // Debug-only loop
+ for (auto mapElement : map )
+ {
+ TRACDCOMP(g_trac_tce,"TCETest::getPos: printIvMap: addr=0x%llX, pos=0x%X", mapElement.first, mapElement.second);
+ }
+
+ // Find i_addr in map; otherwise o_pos = bad default from above
+ auto map_itr = map.find(i_addr);
+ if (map_itr != map.end())
+ {
+ o_pos = map_itr->second;
+ }
+
+ TRACDCOMP(g_trac_tce,EXIT_MRK"TCETest::getPos: i_addr=0x%llX, o_pos=0x%X", i_addr, o_pos);
+
+ return o_pos;
+ }
+
+
+
+ void testTCE(void)
+ {
+ TRACFCOMP( g_trac_tce, ENTER_MRK"testTCE> start" );
+
+ errlHndl_t errhdl = nullptr;
+
+ uint64_t fails = 0x0;
+ uint64_t total = 0x0;
+
+ struct
+ {
+ uint64_t addr; // Start address that TCEs Map To
+ uint64_t size; // Size of memory that TCEs Map To
+ uint32_t pos; // Starting Entry Position in TCE Table
+ } testData[] =
+ {
+ { 0x00, 16*PAGESIZE, 0x0},
+ { 0x0000000004000000, PAGESIZE*8, 0x10},
+ { 0x0000000004010000, PAGESIZE*16, 0x18},
+ { 0x0000000004800000, PAGESIZE*50, 0x28},
+ { 0x0000000004020000, PAGESIZE*10, 0x18},
+ { 0x0000000005010000, PAGESIZE*20, 0x5A},
+ { 0x0000000006010000, PAGESIZE*6, 0x22},
+ };
+
+
+ //---------------------------------------------------
+ // TEST 1 - Call Allocate with unaligned addr
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilAllocateTces(PAGESIZE+1, PAGESIZE);
+
+ if (errhdl == nullptr)
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T1: Did not get expected error from utilAllocateTces");
+ TS_FAIL("testTCE> T1: Did not get expected error back from utilAllocateTces.");
+ ++fails;
+ }
+ else if ( ERRL_GETRC_SAFE(errhdl) == Util::UTIL_TCE_ADDR_NOT_ALIGNED )
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T1: Got expected error unaligned addr back from utilAllocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ delete errhdl;
+ errhdl = nullptr;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T1: got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X (expected rc=0x%X)", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl), Util::UTIL_TCE_ADDR_NOT_ALIGNED);
+ TS_FAIL("testTCE> T1: got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X (expected rc=0x%X)", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl), Util::UTIL_TCE_ADDR_NOT_ALIGNED);
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+
+ //---------------------------------------------------
+ // TEST 2 - Call create with aligned addr with large size
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilAllocateTces(PAGESIZE, 520*KILOBYTE*PAGESIZE);
+
+ if (errhdl == nullptr)
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T2: Did not get expected error from utilAllocateTces");
+ TS_FAIL("testTcE> T2: Did not get expected error back from utilAllocateTces.");
+ ++fails;
+ }
+ else if ( ERRL_GETRC_SAFE(errhdl) == Util::UTIL_TCE_INVALID_SIZE )
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T2: Got expected error of invalid size back from utilAllocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ delete errhdl;
+ errhdl = nullptr;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T2: got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X (expected rc=0x%X)", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl), Util::UTIL_TCE_ADDR_NOT_ALIGNED);
+ TS_FAIL("testTCE> T2: got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X (expected rc=0x%X)", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl), Util::UTIL_TCE_INVALID_SIZE);
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+ //---------------------------------------------------
+ // TEST 3 - Four allocate calls
+ // - init will be called under the covers for the first test
+ //---------------------------------------------------
+ for ( size_t i = 0; i <= 3; ++i )
+ {
+ ++total;
+ errhdl = TCE::utilAllocateTces(testData[i].addr, testData[i].size);
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T3-%d: got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X", i, ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T3-%d: got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X", i, ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+ else if (testData[i].pos !=
+ getPos(testData[i].addr))
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T3-%d: From TCE::utilAllocateTces testData[0].pos=0x%X != map-pos=0x%X", i, testData[i].pos, getPos(testData[i].addr));
+ TS_FAIL("testTCE> T3-%d: From TCE::utilAllocateTces testData[0].pos != map-pos", i);
+ ++fails;
+ }
+ }
+
+ //---------------------------------------------------
+ // TEST 4 - Deallocate token with 16 pages from above
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilDeallocateTces(testData[2].addr, testData[2].size);
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce, "testTCE> T4: Got unexpected error back from TCE::utilDeallocateTces(testData[2].addr=0x%X, testData[2].size=0x%X: error rc=0x%X, plid=0x%X ", testData[2].addr, testData[2].size, ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T4: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+
+ //---------------------------------------------------
+ // TEST 5: Two Allocates:
+ // 1) Allocate 10 pages to go into the available slot left by the
+ // previous deallocate
+ // 2) Allocate 20 pages that will skip past some available slots
+ // left by the previous deallocate
+ //---------------------------------------------------
+ for ( size_t i = 0; i <= 1; ++i )
+ {
+ ++total;
+ errhdl = TCE::utilAllocateTces(testData[i+4].addr, testData[i+4].size);
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce, "testTCE> T5-%d: Got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X", i, ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T5-%d: Got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X", i, ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+ else if (testData[i+4].pos !=
+ getPos(testData[i+4].addr))
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T5-%d: From TCE::utilAllocateTces testData[%d].pos=0x%X != map-pos=0x%X", i, i+4, testData[i+4].pos, getPos(testData[i+4].addr));
+ TS_FAIL("testTCE> T5-%d: From TCE::utilAllocateTces testData[%d].pos != map-pos", i, i+4);
+ ++fails;
+ }
+ }
+
+ //---------------------------------------------------
+ // TEST 6 Allocate 6 pages which should go into the 6
+ // slots available from the 16 page deallocate
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilAllocateTces(testData[6].addr, testData[6].size);
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> T6: Got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T6: Got unexpected error back from TCE::utilAllocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+ else if (testData[6].pos !=
+ getPos(testData[6].addr))
+ {
+ TRACFCOMP( g_trac_tce,"testTCE> T6: From TCE::utilAllocateTces testData[6].pos=0x%X != map-pos=0x%X", testData[6].pos, getPos(testData[6].addr));
+ TS_FAIL("testTCE> T6: From TCE::utilAllocateTces testData[6].pos != map-pos");
+ ++fails;
+ }
+
+ //---------------------------------------------------
+ // TEST 7 Deallocate 20 pages from above
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilDeallocateTces(testData[5].addr, testData[5].size);
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> T7: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T7: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+ //---------------------------------------------------
+ // TEST 8 Deallocate 10 pages from above
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilDeallocateTces(testData[4].addr, testData[4].size);
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> T8: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T8: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+
+ //---------------------------------------------------
+ // TEST 9 Deallocate Too large of size. No error returned instead the
+ // code should go to end of the TCE table and commit errorlog and return
+ //---------------------------------------------------
+ ++total;
+ errhdl = TCE::utilDeallocateTces(0x0, (520*KILOBYTE*PAGESIZE));
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> T9: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T9: Got unexpected error back from TCE::utilDeallocateTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+ //---------------------------------------------------
+ // TEST 10 disable TCEs, which should deallocate all existing TCEs
+ //---------------------------------------------------
+ TRACFCOMP( g_trac_tce,"testTCE> 10: Calling TCE::utilDisableTces");
+ ++total;
+ errhdl = TCE::utilDisableTces();
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> 10: Got unexpected error back from TCE::utilDisableTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> T10: Got unexpected error back from TCE::utilDisableTces: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+
+ /************************************************************/
+ /* @TODO RTC 168745: */
+ /* Make The PAYLOAD calls here in the testcase for now */
+ /* Consider removing when when part of the IPL */
+ /************************************************************/
+
+ TRACFCOMP( g_trac_tce,"testTCE> TA: Calling TCE::utilSetupPayloadTces");
+ ++total;
+ errhdl = TCE::utilSetupPayloadTces();
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> TA: TCE::utilSetupPayloadTces returned unexpected error: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> TA: TCE::utilSetupPayloadTces returned unexpected error: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+ TRACFCOMP( g_trac_tce,"testTCE> TB: Calling TCE::utilClosePayloadTces");
+ ++total;
+ errhdl = TCE::utilClosePayloadTces();
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> TB: TCE::utilClosePayloadTces returned unexpected error: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> TB: TCE::utilClosePayloadTces returned unexpected error: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+ TRACFCOMP( g_trac_tce,"testTCE> TC: Calling TCE::utilDisableTces");
+ ++total;
+ errhdl = TCE::utilDisableTces();
+
+ if (errhdl != nullptr)
+ {
+ TRACFCOMP( g_trac_tce,ERR_MRK"testTCE> TC: TCE::utilDisableTces returned unexpected error: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ TS_FAIL("testTCE> TC: TCE::utilDisableTces returned unexpected error: rc=0x%X, plid=0x%X", ERRL_GETRC_SAFE(errhdl), ERRL_GETPLID_SAFE(errhdl));
+ errlCommit(errhdl,UTIL_COMP_ID);
+ ++fails;
+ }
+
+ TRACFCOMP(g_trac_tce, EXIT_MRK"testTCE> complete - %d/%d fails", fails, total);
+
+ }
+
+};
+#endif
diff --git a/src/usr/util/utiltcemgr.C b/src/usr/util/utiltcemgr.C
new file mode 100644
index 000000000..eb2ee395b
--- /dev/null
+++ b/src/usr/util/utiltcemgr.C
@@ -0,0 +1,1276 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/util/utiltcemgr.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* [+] 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 */
+#ifndef __UTILTCEMGR_C
+#define __UTILTCEMGR_C
+
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <util/utiltce.H>
+#include <util/align.H>
+#include <sys/mmio.h>
+#include <sys/mm.h>
+#include <errno.h>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <kernel/console.H>
+#include "utiltcemgr.H"
+#include <util/util_reasoncodes.H>
+#include <assert.h>
+#include <intr/interrupt.H>
+#include <limits.h>
+#include <hwas/common/hwasCallout.H>
+#include <attributetraits.H>
+#include <pnor/pnorif.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/userif.H>
+
+trace_desc_t* g_trac_tce = nullptr;
+TRAC_INIT(&g_trac_tce, UTILTCE_TRACE_NAME, 4*KILOBYTE);
+
+// ------------------------
+// Macros for unit testing - leave extra trace enabled for now
+#define TRACUCOMP(args...) TRACFCOMP(args)
+//#define TRACUCOMP(args...)
+
+
+namespace TCE
+{
+
+/************************************************************************/
+// Defines
+/************************************************************************/
+// @TODO RTC 168745 Currently hardcoded to 128MB when the original plan was
+// to use PNOR payloadInfo.size, but that only was 19MB
+#define TCE_PAYLOAD_SIZE (128*MEGABYTE)
+
+// TCE Table Address must be 4MB Aligned
+#define TCE_TABLE_ADDRESS_ALIGNMENT (4*MEGABYTE)
+
+/************************************************************************/
+// External Interface:
+// NAME: utilAllocateTces
+// Responsible for allocating TCEs
+//
+/************************************************************************/
+errlHndl_t utilAllocateTces(const uint64_t i_startingAddress,
+ const size_t i_size)
+{
+ return Singleton<UtilTceMgr>::instance().allocateTces(i_startingAddress,
+ i_size);
+};
+
+/************************************************************************/
+// External Interface:
+// NAME: utilDeallocateTces
+// Responsible for deallocating TCEs
+//
+/************************************************************************/
+errlHndl_t utilDeallocateTces(const uint64_t i_startingAddress,
+ const size_t i_size)
+{
+ return Singleton<UtilTceMgr>::instance().deallocateTces(i_startingAddress,
+ i_size);
+};
+
+
+/************************************************************************/
+// External Interface:
+// NAME: utilDisableTces
+// Responsible for disabling TCE on the system, including
+// deallocating TCE Entries and disabling the Processor settings
+//
+/************************************************************************/
+errlHndl_t utilDisableTces(void)
+{
+ return Singleton<UtilTceMgr>::instance().disableTces();
+};
+
+/************************************************************************/
+// External Interface:
+// NAME: getTceManager
+// Returns a copy of Singleton<UtilTceMgr>::instance()
+//
+/************************************************************************/
+UtilTceMgr& getTceManager(void)
+{
+ return Singleton<UtilTceMgr>::instance();
+};
+
+/***********************************************************************************/
+/* Local function to get PAYLOAD base address and size */
+/***********************************************************************************/
+errlHndl_t getPayloadAddrAndSize(uint64_t& o_addr, size_t& o_size)
+{
+ errlHndl_t errl = nullptr;
+
+ o_addr=0x0;
+ o_size=0x0;
+
+ do{
+
+ // Get Target Service and the system target to get ATTR_PAYLOAD_BASE
+ TARGETING::TargetService& tS = TARGETING::targetService();
+ TARGETING::Target* sys = nullptr;
+ (void) tS.getTopLevelTarget( sys );
+ assert(sys, "getPayloadAddrAndSize() system target is NULL");
+
+ o_addr = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>()
+ * MEGABYTE; // Attribute value in MB
+
+ assert((o_addr % PAGESIZE) == 0, "getPayloadAddrAndSize(): o_addr=0x%.16llX not on page boundary", o_addr);
+
+ // Get PAYLOAD PNOR section info from PNOR RP
+ PNOR::SectionInfo_t payloadInfo;
+ errl = getSectionInfo( PNOR::PAYLOAD, //pnorSectionId,
+ payloadInfo );
+
+ if(errl)
+ {
+ TRACFCOMP( g_trac_tce, ERR_MRK"getPayloadAddrAndSize() Error calling getSectionInfo() rc=0x%.4X", errl->reasonCode() );
+ break;
+ }
+
+ o_size = TCE_PAYLOAD_SIZE;
+
+ } while(0);
+
+ TRACFCOMP( g_trac_tce,EXIT_MRK"getPayloadAddrAndSize(): o_addr=0x%.16llX, o_size=0x%.16llX", o_addr, o_size);
+ return errl;
+}
+
+errlHndl_t utilSetupPayloadTces(void)
+{
+ errlHndl_t errl = nullptr;
+
+ uint64_t addr=0x0;
+ size_t size=0x0;
+
+ do{
+
+ TRACFCOMP(g_trac_tce,ENTER_MRK"utilSetupPayloadTces(): get Address and Size");
+
+ errl = getPayloadAddrAndSize(addr, size);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"utilSetupPayloadTces(): ERROR back from getPayloadAddrAndSize()");
+ break;
+ }
+
+ errl = utilAllocateTces(addr, size);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"utilSetupPayloadTces(): ERROR back from utilAllocateTces() using addr=0x%.16llX, size=0x%llX", addr, size);
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_tce,EXIT_MRK"utilSetupPayloadTces(): Address=0x%.16llX, size=0x%X, errl_rc=0x%X", addr, size, ERRL_GETRC_SAFE(errl));
+
+ return errl;
+}
+
+errlHndl_t utilClosePayloadTces(void)
+{
+ errlHndl_t errl = nullptr;
+
+ uint64_t addr=0x0;
+ size_t size=0x0;
+
+ do{
+
+ TRACFCOMP(g_trac_tce,ENTER_MRK"utilClosePayloadTces(): get Address and Size");
+
+ errl = getPayloadAddrAndSize(addr, size);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"utilClosePayloadTces(): ERROR back from getPayloadAddrAndSize()");
+ break;
+ }
+
+ errl = utilDeallocateTces(addr, size);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"utilClosePayloadTces(): ERROR back from utilDeallocateTces() using addr=0x%.16llX, size=0x%llX", addr, size);
+ break;
+ }
+
+ } while(0);
+
+ TRACFCOMP(g_trac_tce,EXIT_MRK"utilClosePayloadTces(): Address=0x%.16llX, size=0x%X, errl_rc=0x%X", addr, size, ERRL_GETRC_SAFE(errl));
+
+ return errl;
+}
+
+
+/************************************************************************/
+//
+// NAME: UtilTceMgr
+// Constructor - set up Tce Table pointers
+//
+/************************************************************************/
+UtilTceMgr::UtilTceMgr(const uint64_t i_tableAddr, const size_t i_tableSize)
+ :iv_isTceHwInitDone(false)
+ ,iv_isTceTableInitDone(false)
+ ,iv_tceTableVaAddr(0)
+ ,iv_tceTablePhysAddr(i_tableAddr)
+ ,iv_tceEntryCount(0)
+ ,iv_tceTableSize(i_tableSize)
+{
+ // Table Address must be 4MB Aligned and default input is TCE_TABLE_ADDR
+ static_assert( TCE_TABLE_ADDR % TCE_TABLE_ADDRESS_ALIGNMENT == 0,"TCE Table must align on 4 MB boundary");
+ assert( i_tableAddr % TCE_TABLE_ADDRESS_ALIGNMENT == 0,"TCE Table must align on 4 MB boundary: 0x%.16llX", i_tableAddr);
+
+ // TCE Entry counts are based on the following assumption
+ static_assert((sizeof(uint64_t) == sizeof(TceEntry_t)), "TceEntry_t struct must be size of uint64_t)");
+
+ // i_tableSize must be a multiple of TCE Entries
+ assert( i_tableSize % sizeof(TceEntry_t) == 0,"TCE Table Size (0x%llX) must be multiple of TceEntry_t size (0x%X))", i_tableSize, sizeof(TceEntry_t));
+
+ iv_tceEntryCount = iv_tceTableSize/(sizeof (uint64_t));
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::UtilTceMgr: iv_tceTableVaAddr=0x%.16llX, iv_tceTablePhysAddr=0x%.16llX, iv_tceTableSize=0x%llX, iv_tceEntryCount=0x%X, iv_allocatedAddrs,size=%d", iv_tceTableVaAddr, iv_tceTablePhysAddr, iv_tceTableSize, iv_tceEntryCount, iv_allocatedAddrs.size());
+
+};
+
+/**************************************************************************/
+//
+// NAME: createTceTable
+// Utilty to map the Tce Table
+//
+/**************************************************************************/
+errlHndl_t UtilTceMgr::createTceTable()
+{
+ errlHndl_t errl = nullptr;
+
+ TRACFCOMP(g_trac_tce,ENTER_MRK"UtilTceMgr::createTceTable: iv_tceTableVaAddr=0x%.16llX, iv_tceTablePhysAddr = 0x%.16llX,iv_tceTableSize = 0x%llX, iv_tceEntryCount=0x%X, iv_isTceTableInitDone=%d", iv_tceTableVaAddr, iv_tceTablePhysAddr, iv_tceTableSize, iv_tceEntryCount, iv_isTceTableInitDone);
+
+ do
+ {
+ // If init was already run, then skip here
+ if (iv_isTceTableInitDone)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::createTceTable: iv_isTceTableInitDone (%d) already true, so skipping init", iv_isTceTableInitDone);
+ break;
+ }
+
+
+ // check to make sure the TCE table is not larger than Max Table Size
+ if (iv_tceTableSize > MAX_TCE_TABLE_SIZE)
+ {
+ // TCE table size larger than 32M.. code bug likely as the real
+ // TCE table is a fixed address and size.
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::createTceTable: Table size 0x%X too large (>0x%llX) - cannot map.", iv_tceTableSize, MAX_TCE_TABLE_SIZE);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_CREATE_TABLE
+ * @reasoncode Util::UTIL_TCE_INVALID_SIZE
+ * @userdata1 Size of of the table that is too large
+ * @userdata2 Max TCE Table Size
+ * @devdesc TCE Table size requested too large.
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_CREATE_TABLE,
+ Util::UTIL_TCE_INVALID_SIZE,
+ iv_tceTableSize,
+ MAX_TCE_TABLE_SIZE,
+ true /*Add HB SW Callout*/);
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+
+ }
+
+
+ // Check that iv_tceEntryCount isn't larger than MAX_NUM_TCE_TABLE_ENTRIES
+ if (iv_tceEntryCount > MAX_NUM_TCE_TABLE_ENTRIES )
+ {
+ // TCE Count is larger than TCE Table Can Support
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::createTceTable: iv_tceEntryCount 0x%X too large (>0x%llX) - cannot map.", iv_tceEntryCount, MAX_NUM_TCE_TABLE_ENTRIES);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_CREATE_TABLE
+ * @reasoncode Util::UTIL_TCE_INVALID_COUNT
+ * @userdata1 Number of TCEs Requested
+ * @userdata2 Max Number of TCEs that TCE Table can hold
+ * @devdesc TCE Table size requested too large.
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_CREATE_TABLE,
+ Util::UTIL_TCE_INVALID_COUNT,
+ iv_tceEntryCount,
+ MAX_NUM_TCE_TABLE_ENTRIES,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+ // Check that the TCE TABLE Address is aligned on 4MB
+ if (iv_tceTablePhysAddr % (4*MEGABYTE))
+ {
+ // Address not page aligned
+ TRACFCOMP(g_trac_tce,ERR_MRK"UtilTceMgr::createTceTable: Table Addr 0x%.16llX not aligned on 4MB Boundary", iv_tceTablePhysAddr);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_CREATE_TABLE
+ * @reasoncode Util::UTIL_TCE_ADDR_NOT_ALIGNED
+ * @userdata1 Phyiscal Address of the TCE Table
+ * @userdata2 <unused>
+ * @devdesc TCE Table not page aligned.
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_CREATE_TABLE,
+ Util::UTIL_TCE_ADDR_NOT_ALIGNED,
+ iv_tceTablePhysAddr,
+ 0,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+ // Allocate Memory for TCE Table
+ // - Reserve a block of physical memory and get a pointer to
+ // virtual memory to manipulate it
+ iv_tceTableVaAddr = reinterpret_cast<uint64_t>(mm_block_map(
+ reinterpret_cast<void*>(iv_tceTablePhysAddr),
+ iv_tceTableSize));
+
+ // Check that a valid Virtual Memory Address was returned
+ if (reinterpret_cast<void*>(iv_tceTableVaAddr) == nullptr)
+ {
+ // Invalid Virtual Address was returned
+ TRACFCOMP(g_trac_tce,ERR_MRK"UtilTceMgr::createTceTable: mm_block_map for Table Addr 0x%.16llX and size=0x%X returned NULL", iv_tceTablePhysAddr, iv_tceTableSize);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_CREATE_TABLE
+ * @reasoncode Util::UTIL_ERC_BAD_PTR
+ * @userdata1 Physical Address of the TCE Table
+ * @userdata2 Requested Size of the TCE Table
+ * @devdesc TCE Table Could Not Be Block-Mapped
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_CREATE_TABLE,
+ Util::UTIL_ERC_BAD_PTR,
+ iv_tceTablePhysAddr,
+ iv_tceTableSize,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+ // Zero out the TCE Table space
+ memset(reinterpret_cast<void*>(iv_tceTableVaAddr), 0, iv_tceTableSize);
+
+ // make sure that the memset completes.
+ sync();
+
+ }while(0);
+
+ // If succsesfull set init to true
+ if ((errl == nullptr) &&
+ (iv_isTceTableInitDone == false))
+ {
+ iv_isTceTableInitDone = true;
+
+ // Successfully initialized the TCE table and hardware.
+ TRACUCOMP(g_trac_tce, "UtilTceMgr::createTceTable: TCE Table initialized and setup: iv_isTceTableInitDone=%d", iv_isTceTableInitDone);
+ }
+
+ TRACFCOMP(g_trac_tce, EXIT_MRK"UtilTceMgr::createTceTable: iv_tceTableVaAddr=0x%.16llX, iv_tceTablePhysAddr = 0x%.16llX,iv_tceTableSize = 0x%llX, iv_tceEntryCount=0x%X, iv_isTceTableInitDone=%d", iv_tceTableVaAddr, iv_tceTablePhysAddr, iv_tceTableSize, iv_tceEntryCount, iv_isTceTableInitDone);
+
+ return errl;
+}
+
+
+/**************************************************************************/
+//
+// NAME: initTceInHdw
+// Responsible for setting up the Processors to point to the TCE table
+//
+/**************************************************************************/
+errlHndl_t UtilTceMgr::initTceInHdw()
+{
+ errlHndl_t errl = nullptr;
+
+ TRACFCOMP(g_trac_tce, ENTER_MRK"UtilTceMgr::initTceInHdw: iv_tceTablePhysAddr = 0x%.16llX, iv_isTceHwInitDone=%d", iv_tceTablePhysAddr, iv_isTceHwInitDone);
+
+ do
+ {
+ // If init was already run, then skip here
+ if (iv_isTceHwInitDone)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: iv_isTceHwInitDone (%d) already true, so skipping init", iv_isTceHwInitDone);
+ break;
+ }
+
+ // Loop through the processors and setup PSI Host Bridge for TCE
+ TARGETING::TargetHandleList l_cpuTargetList;
+ getAllChips(l_cpuTargetList, TARGETING::TYPE_PROC);
+
+ for ( auto l_pTarget : l_cpuTargetList )
+ {
+
+ void * PsiBridgeAddr = nullptr;
+ INTR::PSIHB_SW_INTERFACES_t * l_psihb_ptr = nullptr;
+ TarTceAddrRegister_t l_tar;
+
+ // MMIO Map the PSI Host Bridge
+ errl = mapPsiHostBridge(l_pTarget, PsiBridgeAddr);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: call to mapPsiHostBridge failed with rc=0x%X, plid=0x%X. Committing Log, but continuing the loop", ERRL_GETRC_SAFE(errl), ERRL_GETPLID_SAFE(errl));
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ errlCommit( errl, UTIL_COMP_ID );
+ continue;
+ }
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: Psi Bridge Addr = 0x%.16llX huid = 0x%.8X", PsiBridgeAddr, TARGETING::get_huid(l_pTarget));
+
+ l_psihb_ptr = reinterpret_cast<INTR::PSIHB_SW_INTERFACES_t*>
+ (PsiBridgeAddr);
+
+ // Read back PSIHBBAR
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: Read Back psihbbar = 0x%.16llX", l_psihb_ptr->psihbbar);
+
+
+ // Set TAR - TCE Address Register
+ // Put the TCE Table Starting Physical Address and set up the
+ // system for max of 512K entries
+ l_tar.WholeTAR=0;
+
+ // Since iv_tceTablePhysAddr already checked for 4MB alignment in
+ // createTceTable() we can copy it directly in here
+ l_tar.WholeTAR = iv_tceTablePhysAddr;
+ l_tar.tceEntries = TAR_TCE_ENTRIES_512K;
+
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: iv_tceTablePhysAddr = 0x%.16llX, l_psihb_ptr=0x%.16llX, TAR=0x%.16llX",iv_tceTablePhysAddr, l_psihb_ptr, l_tar.WholeTAR);
+
+ l_psihb_ptr->tceaddr = l_tar.WholeTAR;
+
+ eieio();
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: Read Back tceaddr = 0x%.16llX", l_psihb_ptr->tceaddr);
+
+ // Turn on TCE enable PSI Host Bridge Secure Register
+ l_psihb_ptr->phbsecure = PHBSECURE_TCE_ENABLE;
+
+ eieio();
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: Read Back phbsecure = 0x%.16llX", l_psihb_ptr->phbsecure);
+
+ // Unmap the PSI Host Bridge
+ errl = unmapPsiHostBridge(PsiBridgeAddr);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: call to unmapPsiHostBridge failed with rc=0x%X, plid=0x%X. Committing Log, but continuing the loop", ERRL_GETRC_SAFE(errl), ERRL_GETPLID_SAFE(errl));
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ errlCommit( errl, UTIL_COMP_ID );
+ continue;
+ }
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::initTceInHdw: After unmap: Psi Bridge Addr = 0x%.16llX huid = 0x%.8X", PsiBridgeAddr, TARGETING::get_huid(l_pTarget));
+
+ }
+
+ }while(0);
+
+ // If succsesfull set init to true
+ if ((errl == nullptr) &&
+ (iv_isTceHwInitDone == false))
+ {
+ iv_isTceHwInitDone = true;
+
+ // Successfully initialized the TCE table and hardware.
+ TRACUCOMP(g_trac_tce, "UtilTceMgr::initTceInHdw: TCE initialized and setup");
+ }
+
+ TRACFCOMP(g_trac_tce, EXIT_MRK"UtilTceMgr::initTceInHdw: iv_isTceHwInitDone=%d", iv_isTceHwInitDone);
+
+ return errl;
+}
+
+
+/************************************************************************/
+//
+// NAME: allocateTces
+// Responsible for allocating TCE Entries
+//
+/************************************************************************/
+errlHndl_t UtilTceMgr::allocateTces(const uint64_t i_startingAddress,
+ const size_t i_size)
+{
+ errlHndl_t errl = nullptr;
+ uint32_t numTcesNeeded = 0;
+
+ TceEntry_t *tablePtr = nullptr;
+
+ TRACFCOMP(g_trac_tce,ENTER_MRK"UtilTceMgr::allocateTces: start for addr = 0x%.16llX and size = 0x%X", i_startingAddress, i_size);
+
+ do
+ {
+ // Assert if i_size is not greater than zero
+ assert(i_size > 0, "UtilTceMgr::allocateTces: i_size = %d, not greater than zero", i_size);
+
+ // Expecting a page-aligned starting address
+ if (i_startingAddress % PAGESIZE)
+ {
+ TRACFCOMP(g_trac_tce,ERR_MRK"UtilTceMgr::allocateTces: ERROR-Address 0x%.16llX not page aligned", i_startingAddress);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_ALLOCATE
+ * @reasoncode Util::UTIL_TCE_ADDR_NOT_ALIGNED
+ * @userdata1 Address to start TCE
+ * @userdata2 Size of the address space trying to get TCEs
+ * for.
+ * @devdesc The Physical Address for the TCE entry is not
+ * page aligned.
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_ALLOCATE,
+ Util::UTIL_TCE_ADDR_NOT_ALIGNED,
+ i_startingAddress,
+ i_size,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+ // Calculate the number of TCE entries needed - rounding up
+ numTcesNeeded = ALIGN_PAGE(i_size)/PAGESIZE;
+
+ // If more than the number of TCEs available error out
+ if (numTcesNeeded > iv_tceEntryCount)
+ {
+ TRACFCOMP(g_trac_tce,ERR_MRK"UtilTceMgr::allocateTces: ERROR - Too many entries (0x%X) requested (>0x%X) (i_size=0x%X)", numTcesNeeded, iv_tceEntryCount, i_size);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_ALLOCATE
+ * @reasoncode Util::UTIL_TCE_INVALID_SIZE
+ * @userdata1[0:31] Number of TCEs Needed
+ * @userdate1[32:64] Maximum Number of Tce Entries
+ * @userdata2 Size of the address space trying to get TCEs
+ * @devdesc The size requested is too large for the table
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_ALLOCATE,
+ Util::UTIL_TCE_INVALID_SIZE,
+ TWO_UINT32_TO_UINT64(
+ numTcesNeeded,
+ iv_tceEntryCount),
+ i_size,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+ // @TODO RTC 168745 additional error checking when iv_allocatedAddrs
+ // will be updated to keep track of size, too
+
+ // Check to see if we've already allocated TCEs associated with
+ // this starting address
+ std::map<uint64_t, uint32_t>::iterator map_itr
+ = iv_allocatedAddrs.find(i_startingAddress);
+ if(map_itr != iv_allocatedAddrs.end())
+ {
+ // This starting address has already had TCEs allocated for it
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: ERROR - This starting address 0x%.16llX already has TCEs allocated (pos=0x%X)", i_startingAddress, map_itr->second);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_ALLOCATE
+ * @reasoncode Util::UTIL_TCE_PREVIOUSLY_ALLOCATED
+ * @userdata1 Starting Address
+ * @userdata2 Starting TCE position in TCE Table
+ * @devdesc The starting address was previously allocated
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_ALLOCATE,
+ Util::UTIL_TCE_PREVIOUSLY_ALLOCATED,
+ i_startingAddress,
+ map_itr->second,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+ // Will set map_itr->second with TCE table position later
+
+ // Check to see if createTceTable ran before allocate. If not we
+ // need to create the table and make sure it is mapped.
+ // If we are in multi-node we would run create on only 1 node and
+ // other nodes could use that table
+ if (!iv_isTceTableInitDone)
+ {
+ // createTceTable has not run
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: createTceTable has not run so call createTceTable() here.");
+
+ errl = createTceTable();
+
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: createTceTable() failed with rc=0x%X",ERRL_GETRC_SAFE(errl));
+ break;
+ }
+ }
+
+ // Check to see if HW has been initialized to use the TCEs
+ if (!iv_isTceHwInitDone)
+ {
+ // TceInit did not run before allocate was called so call it here
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: initTceInHdw has not run yet: call it now");
+
+ errl = initTceInHdw();
+
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: initTceInHdw() failed with rc=0x%X",ERRL_GETRC_SAFE(errl));
+ break;
+ }
+ }
+
+ tablePtr = reinterpret_cast<TceEntry_t*>(iv_tceTableVaAddr);
+
+ // Find a first consecutive group of TCEs requested
+ uint32_t startingIndex = 0;
+ bool found = false;
+
+ // Start at the beginning and search for the first empty entry
+ for (uint32_t tceIndex = 0;
+ tceIndex < iv_tceEntryCount;
+ ++tceIndex)
+ {
+ // Look for no-write AND no-read access for the entry to be empty
+ if (tablePtr[tceIndex].readAccess == 0 &&
+ tablePtr[tceIndex].writeAccess == 0)
+ {
+ uint32_t availIndex = 0;
+
+ // if not enough space avail.
+ if (numTcesNeeded+tceIndex > iv_tceEntryCount)
+ {
+ break;
+ }
+ for (uint32_t IndexInRow = tceIndex;
+ IndexInRow < numTcesNeeded + tceIndex;
+ IndexInRow++)
+ {
+ // If the entry has no read or write access then the
+ // entry is available
+ if (tablePtr[IndexInRow].readAccess == 0 &&
+ tablePtr[IndexInRow].writeAccess == 0)
+ {
+ // Increment availIndex
+ availIndex++;
+ }
+ // found a valid entry so need to start the count over.
+ else
+ {
+ // increment past the tce entries we already checked
+ tceIndex = IndexInRow+1;
+
+ // reset the avail index
+ availIndex = 0;
+
+ break;
+ }
+
+ // If we found enough consecutive TCE entries
+ if (availIndex >= numTcesNeeded)
+ {
+ // set the starting index
+ startingIndex = tceIndex;
+ // mark it found
+ found = true;
+ break;
+ }
+ }
+ // break out and update the table
+ if (found)
+ {
+ break;
+ }
+
+ // did not find consecutive TCE entries so continue.
+ }
+ }
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::allocateTces: found=%d, startingIndex=0x%X, numTcesNeeded=0x%X", found, startingIndex, numTcesNeeded);
+
+ if (found)
+ {
+ // Do a for loop here to loop through the number of TCE entries
+ // and set the valid bits. The real page number gets incremented
+ // by 1 for each entry
+ for ( uint32_t i = 0, index=startingIndex;
+ i < numTcesNeeded;
+ ++i, ++index )
+ {
+ tablePtr[index].realPageNumber = (i_startingAddress +
+ (i*PAGESIZE))/PAGESIZE;
+ tablePtr[index].writeAccess = 1;
+ tablePtr[index].readAccess = 1;
+
+ TRACDCOMP(g_trac_tce,INFO_MRK"UtilTceMgr::allocateTces: TCE Entry/Token[%d] (hex) = %llX", index, tablePtr[index]);
+ }
+
+ iv_allocatedAddrs[i_startingAddress] = startingIndex;
+
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: SUCCESSFUL: addr = 0x%.16llX, size = 0x%llX, starting entry=0x%X",i_startingAddress, i_size, startingIndex);
+ }
+ else // not found means not enough space for request
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::allocateTces: ERROR -Not enough free entries for this request: addr=0x%.16llX, size=0x%llX, startingIndex=0x%X, numTcesNeeded=0x%X", i_startingAddress, i_size, startingIndex, numTcesNeeded);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_ALLOCATE
+ * @reasoncode Util::UTIL_TCE_NOT_ENOUGH_FREE_ENTRIES
+ * @userdata1[0:31] Number of TCEs Needed
+ * @userdate1[32:64] Starting Index in TCE Table
+ * @userdata2 Size of address space TCEs are tying to map to
+ * @devdesc Requested size is too large to fit into TCE Table
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_ALLOCATE,
+ Util::UTIL_TCE_NOT_ENOUGH_FREE_ENTRIES,
+ TWO_UINT32_TO_UINT64(
+ numTcesNeeded,
+ startingIndex),
+ i_size,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+ }while(0);
+
+ TRACFCOMP(g_trac_tce, EXIT_MRK"UtilTceMgr::allocateTces: END: addr = 0x%.16llX and size = 0x%X, numTcesNeeded=0x%X", i_startingAddress, i_size, numTcesNeeded);
+ printIvMap(); //Debug
+
+ return errl;
+}
+
+
+/*************************************************************************/
+//
+// NAME: deallocateTces
+// Responsible for deallocating TCE Entries
+//
+/*************************************************************************/
+errlHndl_t UtilTceMgr::deallocateTces(const uint64_t i_startingAddress,
+ const size_t i_size)
+{
+
+ errlHndl_t errl = nullptr;
+ bool isContiguous = true;
+ uint32_t startingIndex = 0;
+
+ TceEntry_t *tablePtr = nullptr;
+
+ TRACFCOMP(g_trac_tce,ENTER_MRK"UtilTceMgr::deallocateTces: Address = 0x%.16llX for size = 0x%X",i_startingAddress, i_size);
+
+ do
+ {
+
+ // Assert if i_size is not greater than zero
+ assert(i_size > 0, "UtilTceMgr::deallocateTces: i_size = %d, not greater than zero", i_size);
+
+ // Expecting a page-aligned starting address
+ if (i_startingAddress % PAGESIZE)
+ {
+ TRACFCOMP(g_trac_tce,ERR_MRK"UtilTceMgr::deallocateTces: ERROR-Address 0x%.16llX not page aligned", i_startingAddress);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_DEALLOCATE
+ * @reasoncode Util::UTIL_TCE_ADDR_NOT_ALIGNED
+ * @userdata1 Address to start TCE
+ * @userdata2 Size of the address space trying to get TCEs
+ * for.
+ * @devdesc The Physical Address for the TCE entry is not
+ * page aligned.
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_DEALLOCATE,
+ Util::UTIL_TCE_ADDR_NOT_ALIGNED,
+ i_startingAddress,
+ i_size,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+
+ // Get number of TCEs needed - rounding up
+ uint32_t numTcesNeeded = ALIGN_PAGE(i_size)/PAGESIZE;
+
+ std::map<uint64_t, uint32_t>::iterator map_itr
+ = iv_allocatedAddrs.find(i_startingAddress);
+ if( map_itr == iv_allocatedAddrs.end() )
+ {
+ // Can't find this starting address. Trace that nothing happens,
+ // but do not create an error log
+ TRACFCOMP(g_trac_tce,INFO_MRK"UtilTceMgr::deallocateTces: Can't find match of Starting Address = 0x%.16llX (size = 0x%X)",i_startingAddress, i_size);
+ break;
+ }
+ else
+ {
+ startingIndex = map_itr->second;
+ }
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::deallocateTces: numTcesNeeded=0x%X, startingAddress = 0x%X", numTcesNeeded, i_startingAddress);
+
+ // @TODO RTC 168745 additional error checking when iv_allocatedAddrs
+ // will be updated to keep track of size, too
+
+ // startingIndex is larger than the max number of indexes avail
+ // --OR-- startingIndex and the number of TCEs needed exceeds the
+ // number of TCEs in the Table
+ if (startingIndex > iv_tceEntryCount ||
+ startingIndex+numTcesNeeded > iv_tceEntryCount)
+ {
+ TRACFCOMP(g_trac_tce,ERR_MRK"UtilTceMgr::deallocateTces: Invalid startingAddress=0x%X and/or numTcesNeeded=0x%X for table with iv_tceEntryCount=0x%X, No deallocate.", i_startingAddress, numTcesNeeded, iv_tceEntryCount);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_DEALLOCATE
+ * @reasoncode Util::UTIL_TCE_INVALID_SIZE
+ * @userdata1[0:31] starting index
+ * @userdata1[32:63] number of TCEs needed for this request
+ * @userdata2 Number of Entries Current TCE Table Supports
+ * @devdesc The size requested is too large based on the
+ * startingAddress the space avilable in the table
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_DEALLOCATE,
+ Util::UTIL_TCE_INVALID_SIZE,
+ TWO_UINT32_TO_UINT64(
+ startingIndex,
+ numTcesNeeded),
+ iv_tceEntryCount,
+ true /*Add HB SW Callout*/);
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+
+ errlCommit(errl,UTIL_COMP_ID);
+
+ break;
+ }
+
+ // Currently do not check for valid entries.. Just clear as
+ // requested.
+ uint64_t previousAddress = 0;
+
+ tablePtr = reinterpret_cast<TceEntry_t*>(iv_tceTableVaAddr);
+
+ for (uint32_t tceIndex = startingIndex;
+ tceIndex < (startingIndex + numTcesNeeded);
+ tceIndex++)
+ {
+
+ // check that the address space is contiguous
+ if ((tceIndex != startingIndex) &&
+ ((tablePtr[tceIndex].realPageNumber -
+ previousAddress) != 1))
+ {
+ isContiguous = false;
+ TRACUCOMP(g_trac_tce,INFO_MRK"UtilTceMgr::deallocateTces: isContiguous set to false (%d) for tablePtr[tceIndex=0x%X]=0x%.16llX, previousAddress_RPN=0x%X", isContiguous, tceIndex, tablePtr[tceIndex].WholeTceEntry, previousAddress);
+ }
+
+ // Save off real address of page pointed to be this TCE for
+ // isContiguous check on next interation
+ previousAddress = tablePtr[tceIndex].realPageNumber;
+
+ // Clear out the TCE entry to 0
+ tablePtr[tceIndex].WholeTceEntry = 0;
+ }
+
+ // Remove the entry from iv_allocatedAddrs even if 'isContiguous' issue
+ iv_allocatedAddrs.erase(i_startingAddress);
+
+ if (!isContiguous)
+ {
+ // We know the range to delete is not contingous. The address and
+ // size inputs crossesd other allocates.
+ // Error log created to indicate this but will clear number of
+ // entries requested by caller
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::deallocateTces: ERROR - request was not contiguous TCE entries");
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_DEALLOCATE
+ * @reasoncode Util::UTIL_TCE_ENTRY_NOT_CONTIGUOUS
+ * @userdata1 Starting address of the TCEs to be deallocated
+ * @userdata2 Size of the address space to be deallocated
+ * @devdesc The deallocate went across TCE Allocate space.
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_PREDICTIVE,
+ Util::UTIL_TCE_DEALLOCATE,
+ Util::UTIL_TCE_ENTRY_NOT_CONTIGUOUS,
+ i_startingAddress,
+ i_size,
+ true /*Add HB SW Callout*/);
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::deallocateTces: not-contiuguos ERROR created (rc=0x%X) and committed", ERRL_GETRC_SAFE(errl));
+ errlCommit(errl,UTIL_COMP_ID);
+ break;
+ }
+
+ }while(0);
+
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::deallocateTces: COMPLETE for Addr = 0x%.16llX for size = 0x%X, errl=0x%X",i_startingAddress, i_size, ERRL_GETRC_SAFE(errl));
+ printIvMap(); //Debug
+
+ return errl;
+}
+
+
+/**************************************************************************/
+//
+// NAME: disableTce
+// Deallocate any TCE entries and disable HW settings
+//
+/**************************************************************************/
+errlHndl_t UtilTceMgr::disableTces(void)
+{
+ errlHndl_t errl = nullptr;
+ int64_t rc = 0;
+
+ TRACUCOMP(g_trac_tce,ENTER_MRK"UtilTceMgr::disableTces: iv_isTceHwInitDone=%d, iv_tceTableVaAddr=0x%.16llX iv_isTceTableInitDone=%d", iv_isTceHwInitDone, iv_tceTableVaAddr, iv_isTceTableInitDone );
+
+ do {
+
+ // If the HW was initialized to use TCEs then disable those settings
+ // it needs to be released here
+ if (iv_isTceHwInitDone)
+ {
+ // Loop through the processors and clear the TCE-related registers
+ // in the PSI Host Bridge
+ TARGETING::TargetHandleList l_cpuTargetList;
+ getAllChips(l_cpuTargetList, TARGETING::TYPE_PROC);
+
+ for ( auto l_pTarget : l_cpuTargetList )
+ {
+ void * PsiBridgeAddr = nullptr;
+ INTR::PSIHB_SW_INTERFACES_t * l_psihb_ptr = nullptr;
+
+ // MMIO Map the PSI Host Bridge
+ errl = mapPsiHostBridge(l_pTarget, PsiBridgeAddr);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::disableTces: call to mapPsiHostBridge failed with rc=0x%X, plid=0x%X. Committing Log, but continuing the loop", ERRL_GETRC_SAFE(errl), ERRL_GETPLID_SAFE(errl));
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ errlCommit( errl, UTIL_COMP_ID );
+ continue;
+ }
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::disableTces: Psi Bridge Addr = 0x%.16llX huid = 0x%.8X", PsiBridgeAddr, TARGETING::get_huid(l_pTarget));
+
+ l_psihb_ptr = reinterpret_cast<INTR::PSIHB_SW_INTERFACES_t*>
+ (PsiBridgeAddr);
+
+ // Read back PSIHBBAR
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::disableTces: Read Back psihbbar = 0x%.16llX", l_psihb_ptr->psihbbar);
+
+ // Turn off TCE enable PSI Host Bridge Secure Register
+ l_psihb_ptr->phbsecure = 0x0;
+
+ eieio();
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::disableTces: Read Back phbsecure = 0x%.16llX", l_psihb_ptr->phbsecure);
+
+ // Clear TAR - TCE Address Register
+ l_psihb_ptr->tceaddr = 0x0;
+
+ eieio();
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::disableTces: Read Back tceaddr = 0x%.16llX", l_psihb_ptr->tceaddr);
+
+ // Unmap the PSI Host Bridge
+ errl = unmapPsiHostBridge(PsiBridgeAddr);
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::disableTces: call to unmapPsiHostBridge failed with rc=0x%X, plid=0x%X. Committing Log, but continuing the loop", ERRL_GETRC_SAFE(errl), ERRL_GETPLID_SAFE(errl));
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ errlCommit( errl, UTIL_COMP_ID );
+ continue;
+ }
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::disableTces: After unmap: Psi Bridge Addr = 0x%.16llX huid = 0x%.8X", PsiBridgeAddr, TARGETING::get_huid(l_pTarget));
+
+ }
+
+ // Clear the class variable
+ iv_isTceHwInitDone=false;
+
+ }
+ else
+ {
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::disableTces: No Need To Uninitialize HW: iv_isTceHwInitDone=%d", iv_isTceHwInitDone);
+ }
+
+ // Cleanup TCE Table In Memory
+ if ( (iv_tceTableVaAddr!= 0) && (iv_isTceTableInitDone==true))
+ {
+
+ // Clear TCE Table
+ memset(reinterpret_cast<void*>(iv_tceTableVaAddr), 0, iv_tceTableSize);
+
+ // Unmap TCE Table In Memory
+ rc = mm_block_unmap(reinterpret_cast<void*>(iv_tceTableVaAddr));
+
+ if ( rc )
+ {
+ // Got a bad rc from mm_block_unmap
+ TRACFCOMP(g_trac_tce, "UtilTceMgr::disableTces: mm_unmap_block failed: rc = 0x%.16llX, iv_tceTableVaAddr=0x%.16llX iv_tceTablePhysAddr=0x%X", rc, iv_tceTableVaAddr, iv_tceTablePhysAddr, rc);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_DISABLE_TCES
+ * @reasoncode Util::UTIL_TCE_BLOCK_UNMAP_FAIL
+ * @userdata1 Starting virtual address of pages to be removed
+ * @userdata2 Return Code from mm_block_unmap
+ * @devdesc mm_block_unmap failed for TCE Table
+ * @custdesc A problem occurred during the IPL of the system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_DISABLE_TCES,
+ Util::UTIL_TCE_BLOCK_UNMAP_FAIL,
+ iv_tceTableVaAddr,
+ rc,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ break;
+ }
+
+ // Clear the class variable
+ iv_isTceTableInitDone=false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::disableTces: iv_tceTableVaAddr == NULL (0x%.16llX) - No Cleanup of TCE Table", iv_tceTableVaAddr);
+ }
+
+ // Clear allocated addresses map
+ iv_allocatedAddrs.clear();
+
+ }while(0);
+
+ TRACUCOMP(g_trac_tce,EXIT_MRK"UtilTceMgr::disableTces");
+ printIvMap(); //Debug
+
+ return errl;
+}
+
+
+/**************************************************************************/
+//
+// NAME: ~UtilTceMgr
+// Destructor
+//
+/**************************************************************************/
+UtilTceMgr::~UtilTceMgr()
+{
+ errlHndl_t errl = nullptr;
+
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::~UtilTceMgr");
+
+ // Call disableTce in case it hasn't already been called
+ errl = disableTces();
+
+ if (errl)
+ {
+ TRACFCOMP(g_trac_tce,"UtilTceMgr::~UtilTceMgr: disableTces Failed rc=0x%X. Committing plid=0x%X", ERRL_GETRC_SAFE(errl), ERRL_GETPLID_SAFE(errl));
+ errlCommit( errl, UTIL_COMP_ID );
+ }
+
+ iv_allocatedAddrs.clear();
+}
+
+// Debug for printing out iv_allocatedAddrs map
+void UtilTceMgr::printIvMap(void) const
+{
+ TRACUCOMP(g_trac_tce,"UtilTceMgr::printIvMap: size=%d", iv_allocatedAddrs.size());
+
+ for ( auto map_itr : iv_allocatedAddrs )
+ {
+ TRACUCOMP(g_trac_tce,"UtilTceMgr: printIvMap: addr=0x%.16llX, pos=0x%X", map_itr.first, map_itr.second);
+ }
+
+}
+
+
+/**************************************************************************/
+//
+// NAME: mapPsiHostBridge:
+// Helper function to Memory Map PSI Host Bridge
+//
+/**************************************************************************/
+errlHndl_t UtilTceMgr::mapPsiHostBridge(const TARGETING::Target * i_tgt,
+ void *& o_psihb_ptr) const
+{
+ errlHndl_t errl = nullptr;
+ void * l_ptr = nullptr;
+ o_psihb_ptr = nullptr;
+
+ // Assert if i_tgt is NULL or not a Processor
+ assert((i_tgt != nullptr) &&
+ (i_tgt->getAttr<TARGETING::ATTR_TYPE>() == TARGETING::TYPE_PROC ),
+ "UtilTceMgr::mapPsiHostBridge: i_tgt=0x%X either NULL or !TYPE_PROC",
+ TARGETING::get_huid(i_tgt));
+
+ uint64_t PsiBridgeAddr =
+ i_tgt->getAttr<TARGETING::ATTR_PSI_BRIDGE_BASE_ADDR>();
+
+ TRACUCOMP(g_trac_tce,ENTER_MRK"UtilTceMgr::mapPsiHostBridge:Psi Bridge Addr = 0x%.16llX huid = 0x%.8X", PsiBridgeAddr, TARGETING::get_huid(i_tgt));
+
+ // Assert if the PSI_BRIDEG_BASE_ADDR is zero or not page aligned
+ assert((PsiBridgeAddr != 0) &&
+ ((PsiBridgeAddr - ALIGN_PAGE_DOWN(PsiBridgeAddr)) == 0),
+ "PsiBridgeAddr (0x%.16llX) is ZERO or not Page Aligned",
+ PsiBridgeAddr);
+
+ // Map the device for the PSI_BRIDGE_ADDR
+ l_ptr = mmio_dev_map(reinterpret_cast<void*>(PsiBridgeAddr), PAGESIZE);
+
+ if (l_ptr == nullptr)
+ {
+ // Got a bad rc from device Map
+ TRACFCOMP(g_trac_tce, "UtilTceMgr::mapPsiHostBtidge: Device map error.");
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_MAP_PSIHB
+ * @reasoncode Util::UTIL_TCE_DEV_MAP_FAIL
+ * @userdata1 Address to be mapped PsiBridgeAddr
+ * @userdata2 Target Unit Id
+ * @devdesc PSI Bridge device Map failed
+ * @custdesc A problem occurred during the IPL of the
+ * system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_MAP_PSIHB,
+ Util::UTIL_TCE_DEV_MAP_FAIL,
+ PsiBridgeAddr,
+ TARGETING::get_huid(i_tgt),
+ true /*Add HB SW Callout*/);
+
+ errl->addHwCallout( i_tgt,
+ HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ }
+ o_psihb_ptr = l_ptr;
+
+ TRACUCOMP(g_trac_tce,EXIT_MRK"UtilTceMgr::mapPsiHostBridge: o_psihb_ptr=0x%.16llX, Psi Bridge Addr = 0x%.16llX, huid = 0x%.8X", o_psihb_ptr, PsiBridgeAddr, TARGETING::get_huid(i_tgt));
+
+ return errl;
+}
+
+
+/**************************************************************************/
+//
+// NAME: unmapPsiHostBridge:
+// Helper function to Unmap PSI Host Bridge from Memory
+//
+/**************************************************************************/
+errlHndl_t UtilTceMgr::unmapPsiHostBridge(void *& io_psihb_ptr) const
+{
+ errlHndl_t errl = nullptr;
+ int64_t rc = 0;
+
+ TRACUCOMP(g_trac_tce,ENTER_MRK"UtilTceMgr::unmapPsiHostBridge: "
+ "io_psihb_ptr = %p", io_psihb_ptr);
+
+ // unmap the device..
+ rc = mmio_dev_unmap(io_psihb_ptr);
+
+ if (rc != 0)
+ {
+ // Got a bad rc from device unmap
+ TRACFCOMP(g_trac_tce, "UtilTceMgr::unmapPsiHostBridge: device unmap "
+ "error: rc=0x%X", rc);
+
+ /*@
+ * @errortype
+ * @moduleid Util::UTIL_TCE_UNMAP_PSIHB
+ * @reasoncode Util::UTIL_TCE_DEV_UNMAP_FAIL
+ * @userdata1 Address to be unmapped
+ * @userdata2 Return Code of mmio_dev_unmap
+ * @devdesc PSI Bridge device Map failed
+ * @custdesc A problem occurred during the IPL of the
+ * system
+ */
+ errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ Util::UTIL_TCE_UNMAP_PSIHB,
+ Util::UTIL_TCE_DEV_UNMAP_FAIL,
+ reinterpret_cast<uint64_t>(io_psihb_ptr),
+ rc,
+ true /*Add HB SW Callout*/);
+
+ errl->collectTrace(UTILTCE_TRACE_NAME,KILOBYTE);
+ }
+ else
+ {
+ io_psihb_ptr = nullptr;
+ TRACUCOMP(g_trac_tce,EXIT_MRK"UtilTceMgr::unmapPsiHostBridge Successful");
+ }
+
+ return errl;
+}
+
+}; // namespace TCE
+
+#endif
diff --git a/src/usr/util/utiltcemgr.H b/src/usr/util/utiltcemgr.H
new file mode 100644
index 000000000..3f8d2b95c
--- /dev/null
+++ b/src/usr/util/utiltcemgr.H
@@ -0,0 +1,290 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/util/utiltcemgr.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* [+] 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 */
+#ifndef __UTILTCEMGR_H
+#define __UTILTCEMGR_H
+
+#include <stdint.h>
+#include <builtins.h>
+#include <errl/errlentry.H>
+#include <devicefw/userif.H>
+#include <intr/interrupt.H>
+#include <map>
+
+// Forward declarations
+class TCETest;
+
+namespace TCE
+{
+
+struct TceEntry_t
+{
+ // Derived from "15.9.6 TCE - Translation Control Entry" of the
+ // P9 Pervasive Workbook
+ union
+ {
+ uint64_t WholeTceEntry;
+ struct {
+ uint64_t reserved_0 :8; // first 8 bits reserved
+ uint64_t realPageNumber :44; // real page number
+ uint64_t reserved_1 :10; // reserved bits
+ uint64_t writeAccess :1; // Write access allowed
+ uint64_t readAccess :1; // Read access allowed
+ };
+
+ };
+
+ // Constructor to default to zero
+ TceEntry_t() :
+ WholeTceEntry(0x0) {};
+
+};
+
+struct TarTceAddrRegister_t
+{
+ // Derived from "15.9.6 TCE - Translation Control Entry" of the
+ // P9 Pervasive Workbook
+ union
+ {
+ uint64_t WholeTAR;
+ struct {
+ uint64_t reserved_0 :8; // first 8 bits reserved
+ uint64_t tceTableStartAddr :34; // real page number
+ uint64_t reserved_1 :6; // reserved since 512k entries
+ uint64_t reserved_2 :13; // reserved
+ uint64_t tceEntries :3; // TCE Entries
+ };
+ };
+
+ // Constructor to default to zero
+ TarTceAddrRegister_t() :
+ WholeTAR(0x0) {};
+
+};
+
+
+/** @class UtilTceMgr
+ * @brief Responsible for managing the TCE entries
+ *
+ */
+class UtilTceMgr
+{
+
+ private:
+ /** Indicator of TCEs being intialized */
+ bool iv_isTceHwInitDone;
+
+ /** Indicator of TCE Table being allocated and initialized in memory */
+ bool iv_isTceTableInitDone;
+
+ /** Virtual Address of the Mapped TCE Table */
+ uint64_t iv_tceTableVaAddr;
+
+ /** Physical Address of the TCE Table */
+ uint64_t iv_tceTablePhysAddr;
+
+ /** Number of TCE entries - via size */
+ size_t iv_tceEntryCount;
+
+ /** size of the Tce Table */
+ size_t iv_tceTableSize;
+
+ /* Cache of starting addresses of allocated TCEs and their
+ * starting entry in the TCE Table
+ * Indexed by starting address, returns position of first entry
+ * in the TCE table associated with this starting address
+ * @TODO RTC 168745 update this to a vector of structs that keeps track of
+ * starting address, first entry, and size of memory covered for
+ * better error handling
+ */
+ std::map<uint64_t, uint32_t> iv_allocatedAddrs;
+
+ /* For Debug purposes */
+ void printIvMap() const;
+
+ /** Max TCE Entries and Size for the TCE Table */
+ enum
+ {
+ MAX_NUM_TCE_TABLE_ENTRIES = 0x080000, // 512k entries - HW Max
+ MAX_TCE_TABLE_SIZE = 0x400000, // 512k * 8 bytes/entry
+ };
+
+ /** Values related to PSIHB_SW_INTERFACES_t registers */
+ enum
+ {
+ TAR_TCE_ENTRIES_512K = 0b100, // TAR bits 61:63=0b100 for 512K entries
+ PHBSECURE_TCE_ENABLE = 0x2000000000000000,
+ };
+
+ /**
+ * @brief Responsible for initalizing the TCE Table and mapping the
+ * TCE Table into memory
+ *
+ * @return errlHndl_t - Return error log if unsuccessful
+ *
+ */
+ errlHndl_t createTceTable();
+
+
+ /**
+ * @brief Responsible for setting up the Processors to point to the TCE
+ * Table
+ *
+ * @return errlHndl_t - Return error log if unsuccessful
+ *
+ */
+ errlHndl_t initTceInHdw();
+
+ /**
+ * @brief Helper function to Memory Map PSI Host Bridge
+ *
+ * @param[in] i_tgt Pointer to Processor Target that is associated
+ * with a specific PSI Host Bridge Memory Map.
+ * Assert if NULL or not a Processor Target
+ *
+ * @param[out] o_psihb_ptr If successful, pointer to memory mapped
+ * location of PSI Host Bridge;
+ * otherwise, NULL
+ *
+ * @return errlHndl_t - Return error log if unsuccessful
+ *
+ */
+ errlHndl_t mapPsiHostBridge(const TARGETING::Target* i_tgt,
+ void *& o_psihb_ptr) const;
+
+
+ /**
+ * @brief Helper function to Unmap PSI Host Bridge from Memory
+ *
+ * @param[in] i_psihb_ptr Pointer to memory mapped location of
+ * PSI Host Bridge
+ *
+ * @return errlHndl_t - Return error log if unsuccessful
+ *
+ */
+ errlHndl_t unmapPsiHostBridge(void *& i_psihb_ptr) const;
+
+
+ /* let the testcase poke around */
+ friend class ::TCETest;
+
+
+ public:
+ /**
+ * @brief Constructor. Initializes instance variables.
+ * @param[in/default] i_tableAddr - Starting physical address of the TCE
+ * Table. Default address is TCE_TABLE_ADDR.
+ * Address must be aligned on a 4MB boundary or will fail.
+ * @param[in/default] i_tableSize - Size of the TCE table. Default value
+ * is TCE_TABLE_SIZE
+ *
+ * @note TCE_TABLE_ADDR and TCE_TABLE_SIZE are defined in vmmconst.h
+ */
+ UtilTceMgr(uint64_t i_tableAddr = TCE_TABLE_ADDR,
+ size_t i_tableSize = TCE_TABLE_SIZE);
+
+ /**
+ * Destructor.
+ */
+ ~UtilTceMgr();
+
+ /**
+ * Delete Copy Constructor
+ */
+ UtilTceMgr(const UtilTceMgr&) = delete;
+
+ /**
+ * Delete Copy Assignment
+ */
+ UtilTceMgr& operator= (const UtilTceMgr&) = delete;
+
+ /**
+ * Delete Move Constructor
+ */
+ UtilTceMgr (UtilTceMgr&&) = delete;
+
+ /**
+ * Delete Move Assignment
+ */
+ UtilTceMgr& operator = (UtilTceMgr&&) = delete;
+
+
+ /**
+ * @brief Responsible for allocating TCEs
+ *
+ * @param[in] i_startingAddress - Starting address that the allocated TCEs
+ * will map to
+ * Needs to be page-aligned or will fail
+ * @param[in] i_size - Size of the address space that TCEs map to
+ * Size must be less than (512K * PAGESIZE) or will fail
+ * Assert if not greater than zero
+ *
+ * Note: First time this is called will cause TCE table to be created and
+ * the Processors to be setup to point at the TCE table
+ *
+ * @return errl - Return Error Handle if failed.
+ *
+ */
+ errlHndl_t allocateTces(uint64_t i_startingAddress,
+ size_t i_size);
+
+ /**
+ * @brief Responsible for deallocating TCEs
+ *
+ * @param[in] i_startingAddress Starting Address that the TCEs that
+ * are to be deallocated map to
+ * Address needs to be page-aligned.
+ * @param[in] i_size - Size of address space that the TCEs that are to
+ * be deallocated map to
+ * Size must be less than (512K * PAGESIZE) or will fail
+ * Assert if not greater than zero
+ *
+ * @return errl - Return Error Handle if fatal failure occurred.
+ *
+ */
+ errlHndl_t deallocateTces(uint64_t i_startingAddress,
+ size_t i_size);
+
+ /**
+ * @brief Responsible for disabling TCEs on the system, including
+ * clearing the TCE table and disabling Processor settings
+ *
+ * @return errl - Return Error Handle if fatal failure occurred.
+ *
+ */
+ errlHndl_t disableTces(void);
+
+}; // class UtilTceMgr
+
+ /**
+ * @brief Returns a copy of the UtilTceMgr Singleton
+ *
+ * @return Returns a copy of Singleton<UtilTceMgr>::instance()
+ */
+ UtilTceMgr& getTceManager(void);
+
+}; // namespace
+
+#endif
+
OpenPOWER on IntegriCloud