summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2011-11-09 18:15:33 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-11-16 10:07:41 -0600
commit6f1adaf68285ef70e1c69d57b01c5c7b6d7fb2e6 (patch)
tree9538afbe255b4f4d1e9bf9cd878ad4e89f43844c /src/usr
parent4d9344f1025ee77e24e88249dd3e32f3d4c9a3ba (diff)
downloadtalos-hostboot-6f1adaf68285ef70e1c69d57b01c5c7b6d7fb2e6.tar.gz
talos-hostboot-6f1adaf68285ef70e1c69d57b01c5c7b6d7fb2e6.zip
Support host boot mutex attributes
- Prevented mutex attributes from being copied in target APIs - Added target APIs to get/tryGet mutex attribute references - Added testcases to verify mutex attributes - Added mutex attribute type to XML definition - Added test mutex attribute to system target XML definition - Modified attribute compiler to support mutex attributes and restrictions - Replaced 100000 cycle loop in synctest.H with nanosleep for 10 CTX switches - Added context switch time macros to time.h - Removed context switch time macros from taskwaittest.H and renamed existing macro calls - Removed context switch time macros from synctest.H and renamed existing macro calls Change-Id: I93fecfa75e00e509fa442e4dd5c9e3fd67866e98 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/491 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/targeting/target.C39
-rw-r--r--src/usr/targeting/test/targetingtest.H124
-rw-r--r--src/usr/targeting/xmltohb/attribute_types.xml13
-rw-r--r--src/usr/targeting/xmltohb/target_types.xml1
-rwxr-xr-xsrc/usr/targeting/xmltohb/xmltohb.pl104
-rw-r--r--src/usr/testcore/kernel/taskwaittest.H7
-rw-r--r--src/usr/testcore/lib/synctest.H7
7 files changed, 271 insertions, 24 deletions
diff --git a/src/usr/targeting/target.C b/src/usr/targeting/target.C
index f4950c1e7..d6946e050 100644
--- a/src/usr/targeting/target.C
+++ b/src/usr/targeting/target.C
@@ -125,6 +125,45 @@ void Target::_getAttrPtr(
}
//******************************************************************************
+// Target::_getHbMutexAttr
+//******************************************************************************
+
+mutex_t* Target::_getHbMutexAttr(
+ const ATTRIBUTE_ID i_attribute) const
+{
+ #define TARG_FN "_getHbMutexAttr()"
+
+ void* l_pAttr = NULL;
+ (void)_getAttrPtr(i_attribute,l_pAttr);
+
+ //@TODO Remove assert once release has stablized
+ assert(l_pAttr,"TARGETING::Target::_getHbMutexAttr<%d>: _getAttrPtr "
+ "returned NULL",i_attribute);
+
+ return static_cast<mutex_t*>(l_pAttr);
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
+// Target::_tryGetHbMutexAttr
+//******************************************************************************
+
+bool Target::_tryGetHbMutexAttr(
+ const ATTRIBUTE_ID i_attribute,
+ mutex_t*& o_pMutex) const
+{
+ #define TARG_FN "_tryGetHbMutexAttr()"
+
+ void* l_pAttr = NULL;
+ (void)_getAttrPtr(i_attribute,l_pAttr);
+ o_pMutex = static_cast<mutex_t*>(l_pAttr);
+ return (l_pAttr != NULL);
+
+ #undef TARG_FN
+}
+
+//******************************************************************************
// Target::Target
//******************************************************************************
diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H
index a2a25ab34..c6d732cee 100644
--- a/src/usr/targeting/test/targetingtest.H
+++ b/src/usr/targeting/test/targetingtest.H
@@ -44,6 +44,9 @@
#include <fapiAttributeIds.H>
#include <fapiAttributeService.H>
#include <errl/errlmanager.H>
+#include <sys/sync.h>
+#include <sys/task.h>
+#include <sys/time.h>
// This component
#include <targeting/attributes.H>
@@ -54,6 +57,31 @@
#include <targeting/predicates/predicatectm.H>
#include <targeting/predicates/predicatepostfixexpr.H>
+/**
+ * @brief Struct to hold pointers to a mutex / protected value
+ */
+struct MutexTestData_t
+{
+ mutex_t* pMutex; // Pointer to mutex
+ volatile uint32_t* pVar; // Pointer to value protected by mutex
+};
+
+/**
+ * @brief Function which attempts to write a protected variable
+ *
+ * @param[in] i_pData Pointer to mutex pointer/value pointer structure
+ *
+ * @return N/A
+ */
+void funcTestMutex(void* i_pData)
+{
+ MutexTestData_t* l_pData = static_cast<MutexTestData_t*>(i_pData);
+ mutex_lock(l_pData->pMutex);
+ *(l_pData->pVar) = 1;
+ mutex_unlock(l_pData->pMutex);
+ task_end();
+}
+
class TargetingTestSuite: public CxxTest::TestSuite
{
public:
@@ -1336,6 +1364,102 @@ class TargetingTestSuite: public CxxTest::TestSuite
TS_TRACE(EXIT_MRK "testCentaurs" );
}
+
+ void testHbMutexAttr()
+ {
+ TS_TRACE(ENTER_MRK "testHbMutexAttr" );
+
+ using namespace TARGETING;
+ using namespace fapi;
+
+ do {
+
+ // Get a reference to the target service
+ TargetService& l_targetService = targetService();
+
+ // Get the system target containing the test mutex
+ TARGETING::Target* l_pTarget = NULL;
+ (void) l_targetService.getTopLevelTarget(l_pTarget);
+ if (l_pTarget == NULL)
+ {
+ TS_FAIL("Top level target handle is NULL");
+ break;
+ }
+
+ // Get the mutex attribute (actually a mutex_t* which points to
+ // a mutex)
+ HB_MUTEX_TEST_LOCK_ATTR l_pLock
+ = l_pTarget->getHbMutexAttr<TARGETING::ATTR_HB_MUTEX_TEST_LOCK>();
+
+ // Test: Verify the value pointed to by the mutex_t* is zero
+ if ( (*reinterpret_cast<uint64_t*>(l_pLock)) != 0)
+ {
+ TS_FAIL("Mutex attribute must be initialized to zero, but got %ld",
+ *reinterpret_cast<uint64_t*>(l_pLock));
+ break;
+ }
+
+ // Try to get the attribute, and ensure it's the same
+ HB_MUTEX_TEST_LOCK_ATTR l_pLockTry = NULL;
+ if(l_pTarget->tryGetHbMutexAttr<TARGETING::ATTR_HB_MUTEX_TEST_LOCK>
+ (l_pLockTry))
+ {
+ if(l_pLockTry != l_pLock)
+ {
+ TS_FAIL("Mutex attributes should match, but dont. "
+ "l_pLockTry = %ld, l_pLock = %ld",l_pLockTry,
+ l_pLock);
+ break;
+ }
+ }
+ else
+ {
+ TS_FAIL("Mutex attribute tryGet failed, even though it exists");
+ break;
+ }
+
+ // Create a structue holding pointers to the mutex and a protected value
+ volatile uint32_t l_var = 0;
+ (void)mutex_lock(l_pLock);
+ MutexTestData_t l_mutexTestData = { l_pLock, &l_var };
+
+ // Spawn off a function which tries to write the protected value to
+ // something unexpected. If the mutex is working, the for loop will
+ // always poll the expected value.
+ task_create(funcTestMutex, static_cast<void*>(&l_mutexTestData));
+
+ // Guarantee the child process runs and blocks on the mutex prior to
+ // modifying the protected value. isync to ensure the processor doesn't
+ // speculatively perform the comparison prior to the sleep completing
+ nanosleep(0,TEN_CTX_SWITCHES_NS); isync();
+
+ if(l_var != 0)
+ {
+ TS_FAIL("Protected value must be 0, was %d instead",l_var);
+ break;
+ }
+
+ // Now unlock the mutex, allowing the other thread to overwrite the
+ // protected value; which should happen within 100,000 reads of the
+ // var. This will confirm the other thread was actively trying to
+ // write the controlled value
+ (void)mutex_unlock(l_pLock);
+
+ // Guarantee the child process acquires the mutex and modifies the
+ // protected value; isync to ensure the processor doesn't speculatively
+ // perform the comparison prior to the sleep completing
+ nanosleep(0,TEN_CTX_SWITCHES_NS); isync();
+
+ if(l_var != 1)
+ {
+ TS_FAIL("Protected value must now be 1, was %d instead",l_var);
+ break;
+ }
+
+ } while(0);
+
+ TS_TRACE(EXIT_MRK "testHbMutexAttr");
+ }
};
#endif // End __TESTTARGETING_H
diff --git a/src/usr/targeting/xmltohb/attribute_types.xml b/src/usr/targeting/xmltohb/attribute_types.xml
index 8c0f7dbf8..c7f1d42c9 100644
--- a/src/usr/targeting/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/xmltohb/attribute_types.xml
@@ -951,5 +951,18 @@
<readable/>
</attribute>
+<attribute>
+ <id>HB_MUTEX_TEST_LOCK</id>
+ <description>Host boot mutex for testing</description>
+ <simpleType>
+ <hbmutex>
+ <default>0</default>
+ </hbmutex>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
</attributes>
diff --git a/src/usr/targeting/xmltohb/target_types.xml b/src/usr/targeting/xmltohb/target_types.xml
index fe44b7970..1b97633c3 100644
--- a/src/usr/targeting/xmltohb/target_types.xml
+++ b/src/usr/targeting/xmltohb/target_types.xml
@@ -64,6 +64,7 @@
<attribute><id>SCRATCH_UINT64_ARRAY_1</id></attribute>
<attribute><id>SCRATCH_UINT64_ARRAY_2</id></attribute>
<attribute><id>NUMERIC_POD_TYPE_TEST</id></attribute>
+ <attribute><id>HB_MUTEX_TEST_LOCK</id></attribute>
<attribute><id>DUMMY_RW</id></attribute>
<attribute>
<id>XSCOM_BASE_ADDRESS</id>
diff --git a/src/usr/targeting/xmltohb/xmltohb.pl b/src/usr/targeting/xmltohb/xmltohb.pl
index b067e0e8e..c4443b0bb 100755
--- a/src/usr/targeting/xmltohb/xmltohb.pl
+++ b/src/usr/targeting/xmltohb/xmltohb.pl
@@ -1162,6 +1162,18 @@ sub writeTraitFileTraits {
$traits .= " $trait,";
}
}
+
+ # Mark the attribute as being a host boot mutex or non-host boot mutex
+ if( (exists $attribute->{simpleType})
+ && (exists $attribute->{simpleType}->{hbmutex}) )
+ {
+ $traits .= " hbMutex,";
+ }
+ else
+ {
+ $traits .= " notHbMutex,";
+ }
+
chop($traits);
# Build value type
@@ -1461,6 +1473,34 @@ sub defaultEnum {
}
################################################################################
+# Do nothing
+################################################################################
+
+sub null {
+
+}
+
+################################################################################
+# Enforce special host boot mutex restrictions
+################################################################################
+
+sub enforceHbMutex {
+ my($attribute,$value) = @_;
+
+ if($value != 0)
+ {
+ fatal("HB mutex attribute default must always be 0, "
+ . "was $value instead.");
+ }
+
+ if($attribute->{persistency} ne "volatile-zeroed")
+ {
+ fatal("HB mutex attribute persistency must be volatile-zeroed, "
+ . "was $attribute->{persistency} instead");
+ }
+}
+
+################################################################################
# Get hash ref to supported simple types and their properties
################################################################################
@@ -1470,15 +1510,16 @@ sub simpleTypeProperties {
# Intentionally didn't wrap these to 80 columns to keep them lined up and
# more readable/editable
- $typesHoH{"int8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int8_t" , bytes => 1, bits => 8 , default => \&defaultZero, packfmt => "C" };
- $typesHoH{"int16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int16_t" , bytes => 2, bits => 16, default => \&defaultZero, packfmt => "n" };
- $typesHoH{"int32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int32_t" , bytes => 4, bits => 32, default => \&defaultZero, packfmt => "N" };
- $typesHoH{"int64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int64_t" , bytes => 8, bits => 64, default => \&defaultZero, packfmt =>\&packQuad};
- $typesHoH{"uint8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint8_t" , bytes => 1, bits => 8 , default => \&defaultZero, packfmt => "C" };
- $typesHoH{"uint16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint16_t" , bytes => 2, bits => 16, default => \&defaultZero, packfmt => "n" };
- $typesHoH{"uint32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint32_t" , bytes => 4, bits => 32, default => \&defaultZero, packfmt => "N" };
- $typesHoH{"uint64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint64_t" , bytes => 8, bits => 64, default => \&defaultZero, packfmt =>\&packQuad};
- $typesHoH{"enumeration"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "XMLTOHB_USE_PARENT_ATTR_ID" , bytes => 0, bits => 0 , default => \&defaultEnum, packfmt => "packEnumeration"};
+ $typesHoH{"int8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int8_t" , bytes => 1, bits => 8 , default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "C" };
+ $typesHoH{"int16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int16_t" , bytes => 2, bits => 16, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "n" };
+ $typesHoH{"int32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int32_t" , bytes => 4, bits => 32, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "N" };
+ $typesHoH{"int64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int64_t" , bytes => 8, bits => 64, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt =>\&packQuad};
+ $typesHoH{"uint8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint8_t" , bytes => 1, bits => 8 , default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "C" };
+ $typesHoH{"uint16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint16_t" , bytes => 2, bits => 16, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "n" };
+ $typesHoH{"uint32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint32_t" , bytes => 4, bits => 32, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "N" };
+ $typesHoH{"uint64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint64_t" , bytes => 8, bits => 64, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt =>\&packQuad};
+ $typesHoH{"enumeration"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "XMLTOHB_USE_PARENT_ATTR_ID" , bytes => 0, bits => 0 , default => \&defaultEnum, alignment => 1, specialPolicies =>\&null, packfmt => "packEnumeration"};
+ $typesHoH{"hbmutex"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "mutex_t*" , bytes => 8, bits => 64, default => \&defaultZero, alignment => 8, specialPolicies =>\&enforceHbMutex, packfmt =>\&packQuad};
return \%typesHoH;
}
@@ -1959,6 +2000,7 @@ sub packAttribute {
my $binaryData;
+ my $alignment = 1;
if(exists $attribute->{simpleType})
{
my $simpleType = $attribute->{simpleType};
@@ -1968,6 +2010,8 @@ sub packAttribute {
{
if(exists $simpleTypeProperties->{$typeName})
{
+ $alignment = $simpleTypeProperties->{$typeName}{alignment};
+
if($typeName eq "enumeration")
{
my $enumeration = getEnumerationType($attributes,$simpleType->{enumeration}->{id});
@@ -1982,6 +2026,10 @@ sub packAttribute {
{
$value = unhexify($value);
}
+
+ # Apply special policy enforcement, if any
+ $simpleTypeProperties->
+ {$typeName}{specialPolicies}->($attribute,$value);
if(ref ($simpleTypeProperties->{$typeName}{packfmt}) eq "CODE")
{
@@ -2056,7 +2104,7 @@ sub packAttribute {
fatal("Serialization failed for attribute ID = $attribute->{id}.");
}
- return $binaryData;
+ return ($binaryData,$alignment);
}
################################################################################
@@ -2302,8 +2350,15 @@ sub writeTargetingImage {
if($section eq "pnor-ro")
{
- my $rodata = packAttribute($attributes,$attributeDef,
+ my ($rodata,$alignment) = packAttribute($attributes,
+ $attributeDef,
$attrhash{$attributeId}->{default});
+
+ # Align the data as necessary
+ my $pads = ($alignment - ($offset % $alignment))
+ % $alignment;
+ $roAttrBinData .= pack ("@".$pads);
+ $offset += $pads;
$attributePointerBinData .= packQuad(
$offset + $pnorRoBaseAddress);
@@ -2314,11 +2369,18 @@ sub writeTargetingImage {
}
elsif($section eq "pnor-rw")
{
- my $rwdata = packAttribute($attributes,$attributeDef,
+ my ($rwdata,$alignment) = packAttribute($attributes,
+ $attributeDef,
$attrhash{$attributeId}->{default});
#print "Wrote to pnor-rw value ",$attributeDef->{id}, ",
#", $attrhash{$attributeId}->{default}," \n";
+
+ # Align the data as necessary
+ my $pads = ($alignment - ($rwOffset % $alignment))
+ % $alignment;
+ $rwAttrBinData .= pack ("@".$pads);
+ $rwOffset += $pads;
$attributePointerBinData .= packQuad(
$rwOffset + $pnorRwBaseAddress);
@@ -2330,8 +2392,15 @@ sub writeTargetingImage {
}
elsif($section eq "heap-zero-initialized")
{
- my $heapZeroInitData = packAttribute($attributes,
+ my ($heapZeroInitData,$alignment) = packAttribute(
+ $attributes,
$attributeDef,$attrhash{$attributeId}->{default});
+
+ # Align the data as necessary
+ my $pads = ($alignment - ($heapZeroInitOffset
+ % $alignment)) % $alignment;
+ $heapZeroInitBinData .= pack ("@".$pads);
+ $heapZeroInitOffset += $pads;
$attributePointerBinData .= packQuad(
$heapZeroInitOffset + $heapZeroInitBaseAddr);
@@ -2343,9 +2412,16 @@ sub writeTargetingImage {
}
elsif($section eq "heap-pnor-initialized")
{
- my $heapPnorInitData = packAttribute($attributes,
+ my ($heapPnorInitData,$alignment) = packAttribute(
+ $attributes,
$attributeDef,$attrhash{$attributeId}->{default});
+ # Align the data as necessary
+ my $pads = ($alignment - ($heapPnorInitOffset
+ % $alignment)) % $alignment;
+ $heapPnorInitBinData .= pack ("@".$pads);
+ $heapPnorInitOffset += $pads;
+
$attributePointerBinData .= packQuad(
$heapPnorInitOffset + $heapPnorInitBaseAddr);
diff --git a/src/usr/testcore/kernel/taskwaittest.H b/src/usr/testcore/kernel/taskwaittest.H
index 8c59aedc7..0595d2961 100644
--- a/src/usr/testcore/kernel/taskwaittest.H
+++ b/src/usr/testcore/kernel/taskwaittest.H
@@ -31,9 +31,6 @@
#include <kernel/console.H>
#include <kernel/timemgr.H>
-#define NS_PER_SEC (1000000ull)
-#define TEN_CTX_SWITCHES ((NS_PER_SEC/TimeManager::TIMESLICE_PER_SEC)*10)
-
class TaskWaitTest : public CxxTest::TestSuite
{
public:
@@ -153,13 +150,13 @@ class TaskWaitTest : public CxxTest::TestSuite
static void WaitSomeTime(void* retval)
{
- nanosleep(0,TEN_CTX_SWITCHES);
+ nanosleep(0,TEN_CTX_SWITCHES_NS);
if (retval) task_end2(retval);
}
static void WaitSomeLongerTime(void* retval)
{
- nanosleep(0, 2*TEN_CTX_SWITCHES);
+ nanosleep(0, 2*TEN_CTX_SWITCHES_NS);
if (retval) task_end2(retval);
}
diff --git a/src/usr/testcore/lib/synctest.H b/src/usr/testcore/lib/synctest.H
index e8b0ef1e0..e1de74843 100644
--- a/src/usr/testcore/lib/synctest.H
+++ b/src/usr/testcore/lib/synctest.H
@@ -35,9 +35,6 @@
#include <kernel/timemgr.H>
-#define NS_PER_SEC (1000000ull)
-#define TEN_CTX_SWITCHES ((NS_PER_SEC/TimeManager::TIMESLICE_PER_SEC)*10)
-
class SyncTest: public CxxTest::TestSuite
{
public:
@@ -66,7 +63,7 @@ class SyncTest: public CxxTest::TestSuite
mutex_lock(&mutex);
task_create(func2, this);
task_create(func2, this);
- nanosleep(0,TEN_CTX_SWITCHES);
+ nanosleep(0,TEN_CTX_SWITCHES_NS);
mutex_unlock(&mutex);
barrier_wait(&barrier);
TS_TRACE("ALL THREADS ENDED");
@@ -95,7 +92,7 @@ class SyncTest: public CxxTest::TestSuite
barrier_t * barrier = &(my->barrier);
mutex_lock(mutex);
- for(int i = 0; i < 100000; ++i);
+ nanosleep(0,TEN_CTX_SWITCHES_NS);
TS_TRACE("ME FIRST");
mutex_unlock(mutex);
barrier_wait(barrier);
OpenPOWER on IntegriCloud