summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMissy Connell <missyc@us.ibm.com>2013-03-26 09:23:58 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-07-10 16:25:07 -0500
commitc154ece8068c2f0fc366235ba952003e08df48a1 (patch)
tree458f94384d035d85bbb35c535fa3eec2b4b19b05
parent36da1243a5e1026fe10de3194c167cb1ceeb77c8 (diff)
downloadtalos-hostboot-c154ece8068c2f0fc366235ba952003e08df48a1.tar.gz
talos-hostboot-c154ece8068c2f0fc366235ba952003e08df48a1.zip
TCE support
RTC:36952 Change-Id: Icc1e88df4e8a8b50cae4fd9fe3789e98be61604e Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4297 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H17
-rw-r--r--src/include/usr/runtime/tceif.H83
-rw-r--r--src/include/usr/vmmconst.h6
-rw-r--r--src/usr/runtime/makefile3
-rw-r--r--src/usr/runtime/tce.C781
-rw-r--r--src/usr/runtime/tce.H169
-rw-r--r--src/usr/runtime/test/makefile46
-rw-r--r--src/usr/runtime/test/tcetest.H391
8 files changed, 1471 insertions, 25 deletions
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index 4a8f8c0ae..6d3df5bf2 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -38,6 +38,14 @@ namespace RUNTIME
MOD_HDATSERVICE_GET_STANDALONE_SECTION = 0x06, /**< hdatservice.C */
MOD_HDATSERVICE_GET_HOST_DATA_SECTION = 0x07, /**< hdatservice.C */
MOD_HDATSERVICE_VERIFY_HDAT_ADDRESS = 0x08, /**< hdatservice.C */
+ MOD_TCE_CREATE = 0x09, /**< tce.C */
+ MOD_TCE_INIT_HDW = 0x0A, /**< tce.C */
+ MOD_TCE_ALLOCATE = 0x0B, /**< tce.C */
+ MOD_TCE_DEALLOCATE = 0x0C, /**< tce.C */
+ MOD_TCE_INIT = 0x0D, /**< tce.C */
+ MOD_TCE_MAP = 0x0E, /**< tce.C */
+
+
};
enum RuntimeReasonCode
@@ -55,7 +63,14 @@ namespace RUNTIME
RC_INVALID_ADDRESS = RUNTIME_COMP_ID | 0x0B,
RC_INVALID_SECTION = RUNTIME_COMP_ID | 0x0C,
RC_CANNOT_MAP_MEMORY3 = RUNTIME_COMP_ID | 0x0D,
-
+ RC_TCE_INVALID_SIZE = RUNTIME_COMP_ID | 0x0E,
+ RC_TCE_ADDR_NOT_ALIGNED = RUNTIME_COMP_ID | 0x0F,
+ RC_TCE_INIT_NOT_RUN = RUNTIME_COMP_ID | 0x10,
+ RC_TCE_DEV_MAP_FAIL = RUNTIME_COMP_ID | 0x11,
+ RC_TCE_DEV_UNMAP_FAIL = RUNTIME_COMP_ID | 0x12,
+ RC_TCE_NO_ACTIVE_PSI = RUNTIME_COMP_ID | 0x13,
+ RC_TCE_NOT_ENOUGH_FREE_ENTRIES = RUNTIME_COMP_ID | 0x14,
+ RC_TCE_ENTRY_NOT_CONTIGUOUS = RUNTIME_COMP_ID | 0x15,
};
};
diff --git a/src/include/usr/runtime/tceif.H b/src/include/usr/runtime/tceif.H
new file mode 100644
index 000000000..9dcc7ca14
--- /dev/null
+++ b/src/include/usr/runtime/tceif.H
@@ -0,0 +1,83 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/runtime/tceif.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __TCEIF_H
+#define __TCEIF_H
+
+#include <stdint.h>
+#include <builtins.h>
+#include <errl/errlentry.H>
+#include <devicefw/userif.H>
+
+
+namespace TCE
+{
+ /**
+ * @brief Responsible for initalizing the TCE entries
+ *
+ * @return errl - Return Error Handle if failed.
+ *
+ */
+ errlHndl_t createTceTable();
+
+ /**
+ * @brief Responsible for setting up the Processors to point to the TCE
+ * table
+ *
+ * @return errl - Return Error Handle if failed.
+ *
+ */
+ 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)
+ *
+ * Note: Must run createTceTable and InitTceInHdw or allocate will not work
+ *
+ * @return errl - Return Error Handle if failed.
+ *
+ */
+ errlHndl_t allocateTces(uint64_t startingAddress, uint64_t size, uint64_t&
+ 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 startingToken, uint64_t size);
+};
+
+#endif
diff --git a/src/include/usr/vmmconst.h b/src/include/usr/vmmconst.h
index 3a0526347..544f0d32f 100644
--- a/src/include/usr/vmmconst.h
+++ b/src/include/usr/vmmconst.h
@@ -149,4 +149,10 @@ enum BlockPriority
#define DUMP_TEST_MEMORY_ADDR (HSVC_TEST_MEMORY_ADDR + HSVC_TEST_MEMORY_SIZE)
#define DUMP_TEST_MEMORY_SIZE (4*MEGABYTE)
+/** Location of the TCE Table */
+#define TCE_TABLE_ADDR (90*MEGABYTE)
+
+// The size if 512K bytes of entries each uint64_t or 8 bytes in size.
+#define TCE_TABLE_SIZE ((512*KILOBYTE)*sizeof(uint64_t))
+
#endif /* _VMMCONST_H */
diff --git a/src/usr/runtime/makefile b/src/usr/runtime/makefile
index 8482289a0..7f3e5d495 100644
--- a/src/usr/runtime/makefile
+++ b/src/usr/runtime/makefile
@@ -30,7 +30,8 @@
ROOTPATH = ../../..
MODULE = runtime
-OBJS = populate_attributes.o hdatservice.o fakepayload.o
+
+OBJS = populate_attributes.o hdatservice.o fakepayload.o tce.o
SUBDIRS = test.d
diff --git a/src/usr/runtime/tce.C b/src/usr/runtime/tce.C
new file mode 100644
index 000000000..619364671
--- /dev/null
+++ b/src/usr/runtime/tce.C
@@ -0,0 +1,781 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/tce.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* 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", 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);
+
+ 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);
+
+ 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);
+ }
+ }
+ }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);
+ 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);
+ 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);
+
+ 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);
+
+ 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);
+ 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);
+
+ }
+ }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);
+
+ 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);
+
+ errlCommit(errl,RUNTIME_COMP_ID);
+
+ }
+
+ }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
new file mode 100644
index 000000000..b2a7b82c5
--- /dev/null
+++ b/src/usr/runtime/tce.H
@@ -0,0 +1,169 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/runtime/tce.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* 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 16f87433a..2f5472dc4 100644
--- a/src/usr/runtime/test/makefile
+++ b/src/usr/runtime/test/makefile
@@ -1,25 +1,25 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/usr/runtime/test/makefile $
-#
-# IBM CONFIDENTIAL
-#
-# COPYRIGHT International Business Machines Corp. 2012
-#
-# p1
-#
-# Object Code Only (OCO) source materials
-# Licensed Internal Code Source Materials
-# IBM HostBoot Licensed Internal Code
-#
-# The source code for this program is not published or otherwise
-# divested of its trade secrets, irrespective of what has been
-# deposited with the U.S. Copyright Office.
-#
-# Origin: 30
-#
-# IBM_PROLOG_END_TAG
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/runtime/test/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2012,2013
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
ROOTPATH = ../../../..
MODULE = testruntime
@@ -31,6 +31,6 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
-
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/runtime/
include ${ROOTPATH}/config.mk
diff --git a/src/usr/runtime/test/tcetest.H b/src/usr/runtime/test/tcetest.H
new file mode 100644
index 000000000..fefbe1867
--- /dev/null
+++ b/src/usr/runtime/test/tcetest.H
@@ -0,0 +1,391 @@
+
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/runtime/test/tcetest.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* 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
OpenPOWER on IntegriCloud