summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2013-01-07 13:34:27 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-02-08 16:51:17 -0600
commit0ace043e6f4df6ce20d32524923e732a185853bf (patch)
tree49abd153d81dc2aa204cc64fed49f6ae243f4487
parentcaf328ccd931de4ce4e4d285d1a4e5ddd151abb5 (diff)
downloadtalos-hostboot-0ace043e6f4df6ce20d32524923e732a185853bf.tar.gz
talos-hostboot-0ace043e6f4df6ce20d32524923e732a185853bf.zip
Support for less than 8 threads per core
Modified anywhere that we enable non-master threads to only touch the threads that we are told to update. Change-Id: I5b764e51d85a5c663ac76164e9465831ef0c167c RTC: 48808 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2877 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/kernel/cpumgr.H3
-rw-r--r--src/include/sys/misc.h7
-rw-r--r--src/include/sys/mmio.h3
-rw-r--r--src/kernel/cpumgr.C8
-rw-r--r--src/kernel/syscall.C5
-rw-r--r--src/lib/syscall_misc.C8
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C11
-rw-r--r--src/usr/hwpf/hwp/core_activate/core_activate.C10
-rw-r--r--src/usr/hwpf/hwp/thread_activate/thread_activate.C15
-rw-r--r--src/usr/intr/intrrp.C66
-rw-r--r--src/usr/intr/test/intrtest.H13
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml15
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml5
13 files changed, 150 insertions, 19 deletions
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H
index 264583b5f..23207bf11 100644
--- a/src/include/kernel/cpumgr.H
+++ b/src/include/kernel/cpumgr.H
@@ -135,8 +135,9 @@ class CpuManager
* Create structures to support a core activating and start the core.
*
* @param[in] pir - PIR value of first thread in core.
+ * @param[in] i_threads - Bitstring of threads to enable (left-justified).
*/
- static int startCore(uint64_t pir);
+ static int startCore(uint64_t pir,uint64_t i_threads);
/** @fn forceMemoryPeriodic()
diff --git a/src/include/sys/misc.h b/src/include/sys/misc.h
index c8d3ba510..8c119aca5 100644
--- a/src/include/sys/misc.h
+++ b/src/include/sys/misc.h
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* COPYRIGHT International Business Machines Corp. 2011,2013 */
/* */
/* p1 */
/* */
@@ -86,7 +86,7 @@ ProcessorCoreType cpu_core_type();
uint8_t cpu_dd_level();
/** @fn cpu_thread_count()
- * @brief Get the number of threads per cpu for this proctype
+ * @brief Get the number of available threads per cpu for this proctype
* @return # of threads per cpu
*/
size_t cpu_thread_count();
@@ -95,6 +95,7 @@ size_t cpu_thread_count();
* @brief Have the kernel start a new core.
*
* @param[in] pir - PIR value of the first thread on the core.
+ * @param[in] i_threads - Bitstring of threads to enable (left-justified).
*
* @note The kernel will start all threads on the requested core even
* though the callee only requests with a single PIR value.
@@ -104,7 +105,7 @@ size_t cpu_thread_count();
* @retval -ENXIO - The core ID was outside of the range the kernel is
* prepared to support.
*/
-int cpu_start_core(uint64_t pir);
+int cpu_start_core(uint64_t pir,uint64_t i_threads);
/**
* @enum CpuSprNames
diff --git a/src/include/sys/mmio.h b/src/include/sys/mmio.h
index 610db0124..afdf0d5d1 100644
--- a/src/include/sys/mmio.h
+++ b/src/include/sys/mmio.h
@@ -97,6 +97,9 @@ enum MMIO_Scratch_Register
/** Thread7 Scratch Register - Identifies if Hostboot is active after
* host_start_payload. */
MMIO_SCRATCH_HOSTBOOT_ACTIVE = 0x38,
+ /** Thread7 Scratch Register - Set be SBE for reduced-threads support
+ * for AVPs. */
+ MMIO_SCRATCH_AVP_THREADS = 0x38,
};
/** @fn mmio_scratch_read()
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index 954232b2d..436930de7 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -381,7 +381,7 @@ void CpuManager::executePeriodics(cpu_t * i_cpu)
}
-int CpuManager::startCore(uint64_t pir)
+int CpuManager::startCore(uint64_t pir,uint64_t i_threads)
{
size_t threads = getThreadCount();
pir = pir & ~(threads-1);
@@ -394,7 +394,11 @@ int CpuManager::startCore(uint64_t pir)
for(size_t i = 0; i < threads; i++)
{
- Singleton<CpuManager>::instance().startCPU(pir + i);
+ // Only start the threads we were told to start
+ if( i_threads & (0x8000000000000000 >> i) )
+ {
+ Singleton<CpuManager>::instance().startCPU(pir + i);
+ }
}
__sync_synchronize();
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 9ef1e36b3..615a22e8f 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2010,2012 */
+/* COPYRIGHT International Business Machines Corp. 2010,2013 */
/* */
/* p1 */
/* */
@@ -643,7 +643,8 @@ namespace Systemcalls
void CpuStartCore(task_t *t)
{
TASK_SETRTN(t,
- CpuManager::startCore(static_cast<uint64_t>(TASK_GETARG0(t))));
+ CpuManager::startCore(static_cast<uint64_t>(TASK_GETARG0(t)),
+ static_cast<uint64_t>(TASK_GETARG1(t))));
};
/** Read SPR values. */
diff --git a/src/lib/syscall_misc.C b/src/lib/syscall_misc.C
index b62a10662..7f490e2ac 100644
--- a/src/lib/syscall_misc.C
+++ b/src/lib/syscall_misc.C
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* COPYRIGHT International Business Machines Corp. 2011,2013 */
/* */
/* p1 */
/* */
@@ -66,10 +66,12 @@ size_t cpu_thread_count()
return threads;
}
-int cpu_start_core(uint64_t pir)
+int cpu_start_core(uint64_t pir,uint64_t i_threads)
{
return reinterpret_cast<int64_t>(
- _syscall1(MISC_CPUSTARTCORE, reinterpret_cast<void*>(pir)));
+ _syscall2(MISC_CPUSTARTCORE,
+ reinterpret_cast<void*>(pir),
+ reinterpret_cast<void*>(i_threads)));
}
uint64_t cpu_spr_value(CpuSprNames spr)
diff --git a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C
index f285bc248..bd63fe764 100644
--- a/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C
+++ b/src/usr/hwpf/hwp/build_winkle_images/build_winkle_images.C
@@ -202,6 +202,11 @@ errlHndl_t applyPoreGenCpuRegs( TARGETING::Target *i_cpuTarget,
// and 23.7.3.5 - 6 in Murano Book 4
l_lpcrVal &= ~(0x0000000000002000) ;
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ assert( sys != NULL );
+ uint64_t en_threads = sys->getAttr<ATTR_ENABLED_THREADS>();
+
uint64_t l_hrmorVal = cpu_spr_value(CPU_SPR_HRMOR);
for (TargetHandleList::const_iterator
l_coreIds_iter = l_coreIds.begin();
@@ -250,6 +255,12 @@ errlHndl_t applyPoreGenCpuRegs( TARGETING::Target *i_cpuTarget,
// fill in lpcr for each thread
for ( l_threadId=0; l_threadId < l_cpu_thread_count; l_threadId++ )
{
+ // Skip threads that we shouldn't be starting
+ if( !(en_threads & (0x8000000000000000>>l_threadId)) )
+ {
+ continue;
+ }
+
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"applyPoreGenCpuRegs: core=0x%x,thread=0x%x: ",
l_coreId, l_threadId );
diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C
index f8ca1608c..6efce283e 100644
--- a/src/usr/hwpf/hwp/core_activate/core_activate.C
+++ b/src/usr/hwpf/hwp/core_activate/core_activate.C
@@ -265,9 +265,13 @@ void* call_host_activate_slave_cores( void *io_pArgs )
CHIP_UNIT_ATTR l_coreId =
(*l_core)->getAttr<TARGETING::ATTR_CHIP_UNIT>();
FABRIC_NODE_ID_ATTR l_logicalNodeId =
- l_processor->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();
+ l_processor->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();
FABRIC_CHIP_ID_ATTR l_chipId =
- l_processor->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
+ l_processor->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ assert( sys != NULL );
+ uint64_t en_threads = sys->getAttr<ATTR_ENABLED_THREADS>();
uint64_t pir = l_coreId << 3;
pir |= l_chipId << 7;
@@ -278,7 +282,7 @@ void* call_host_activate_slave_cores( void *io_pArgs )
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_host_activate_slave_cores: Waking %x", pir);
- int rc = cpu_start_core(pir);
+ int rc = cpu_start_core(pir,en_threads);
// We purposefully only create one error log here. The only
// failure from the kernel is a bad PIR, which means we have
diff --git a/src/usr/hwpf/hwp/thread_activate/thread_activate.C b/src/usr/hwpf/hwp/thread_activate/thread_activate.C
index 37096abc3..b8b3642e6 100644
--- a/src/usr/hwpf/hwp/thread_activate/thread_activate.C
+++ b/src/usr/hwpf/hwp/thread_activate/thread_activate.C
@@ -311,8 +311,13 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl )
const fapi::Target l_fapiCore( fapi::TARGET_TYPE_EX_CHIPLET,
(const_cast<TARGETING::Target*>(l_masterCore)));
- // loop around threads 0-6, SBE starts thread 7
- const uint64_t max_threads = cpu_thread_count();
+ // AVPs might enable a subset of the available threads
+ uint64_t max_threads = cpu_thread_count();
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ assert( sys != NULL );
+ uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>();
+
for( uint64_t thread = 0; thread < max_threads; thread++ )
{
// Skip the thread that we're running on
@@ -321,6 +326,12 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl )
continue;
}
+ // Skip threads that we shouldn't be starting
+ if( !(en_threads & (0x8000000000000000>>thread)) )
+ {
+ continue;
+ }
+
// send a magic instruction for PHYP Simics to work...
MAGIC_INSTRUCTION(MAGIC_SIMICS_CORESTATESAVE);
diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C
index 775f050f9..96d24a7f5 100644
--- a/src/usr/intr/intrrp.C
+++ b/src/usr/intr/intrrp.C
@@ -59,6 +59,45 @@ TRAC_INIT(&g_trac_intr, INTR_TRACE_NAME, KILOBYTE, TRACE::BUFFER_SLOW);
TASK_ENTRY_MACRO( IntrRp::init );
+/**
+ * @brief Utility function to get the list of enabled threads
+ * @return Bitstring of enabled threads
+ */
+uint64_t get_enabled_threads( void )
+{
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ assert( sys != NULL );
+ uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>();
+ if( en_threads == 0 )
+ {
+ // Read the scratch reg that the SBE setup
+ // Enabled threads are listed as a bitstring in bits 16:23
+ // A value of zero means the SBE hasn't set them up yet
+ while( en_threads == 0 )
+ {
+ en_threads = mmio_scratch_read(MMIO_SCRATCH_AVP_THREADS);
+
+ //@todo RTC:63991 - Remove this after we get the new SBE image
+ if( en_threads == 0 )
+ {
+ // Default to all threads enabled
+ uint64_t max_threads = cpu_thread_count();
+ en_threads =
+ ((1ull << max_threads) - 1ull) << (48ull - max_threads);
+ }
+ }
+ en_threads = en_threads << 16; //left-justify the threads
+ TRACFCOMP( g_trac_intr,
+ "Enabled Threads = %.16X",
+ en_threads );
+
+ sys->setAttr<TARGETING::ATTR_ENABLED_THREADS>(en_threads);
+ }
+ TRACDCOMP( g_trac_intr, "en_threads=%.16X", en_threads );
+ return en_threads;
+}
+
void IntrRp::init( errlHndl_t &io_errlHndl_t )
{
errlHndl_t err = NULL;
@@ -138,11 +177,18 @@ errlHndl_t IntrRp::_init()
// Set up link registers to forward all intrpts to master cpu.
//
// There is one register set per cpu thread.
- size_t threads = cpu_thread_count();
+ uint64_t max_threads = cpu_thread_count();
+ uint64_t en_threads = get_enabled_threads();
PIR_t pir = iv_masterCpu;
- for(size_t thread = 0; thread < threads; ++thread)
+ for(size_t thread = 0; thread < max_threads; ++thread)
{
+ // Skip threads that we shouldn't be starting
+ if( !(en_threads & (0x8000000000000000>>thread)) )
+ {
+ TRACDCOMP(g_trac_intr,"IntrRp::_init: Skipping thread %d : en_threads=%X",thread,en_threads);
+ continue;
+ }
pir.threadId = thread;
initInterruptPresenter(pir);
}
@@ -410,10 +456,18 @@ void IntrRp::msgHandler()
pir.threadId);
size_t threads = cpu_thread_count();
+ uint64_t en_threads = get_enabled_threads();
+
iv_ipisPending[pir] = IPI_Info_t((1 << threads)-1, msg);
for(size_t thread = 0; thread < threads; ++thread)
{
+ // Skip threads that we shouldn't be starting
+ if( !(en_threads & (0x8000000000000000>>thread)) )
+ {
+ TRACDCOMP(g_trac_intr,"MSG_INTR_ADD_CPU: Skipping thread %d",thread);
+ continue;
+ }
pir.threadId = thread;
initInterruptPresenter(pir);
sendIPI(pir);
@@ -967,6 +1021,8 @@ void IntrRp::shutDown()
iv_cpuList.push_back(iv_masterCpu);
size_t threads = cpu_thread_count();
+ uint64_t en_threads = get_enabled_threads();
+
for(CpuList_t::iterator pir_itr = iv_cpuList.begin();
pir_itr != iv_cpuList.end();
++pir_itr)
@@ -974,6 +1030,12 @@ void IntrRp::shutDown()
PIR_t pir = *pir_itr;
for(size_t thread = 0; thread < threads; ++thread)
{
+ // Skip threads that were never started
+ if( !(en_threads & (0x8000000000000000>>thread)) )
+ {
+ TRACDCOMP(g_trac_intr,"IntrRp::shutDown: Skipping thread %d",thread);
+ continue;
+ }
pir.threadId = thread;
deconfigureInterruptPresenter(pir);
}
diff --git a/src/usr/intr/test/intrtest.H b/src/usr/intr/test/intrtest.H
index c12835d77..56670329e 100644
--- a/src/usr/intr/test/intrtest.H
+++ b/src/usr/intr/test/intrtest.H
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2012 */
+/* COPYRIGHT International Business Machines Corp. 2011,2013 */
/* */
/* p1 */
/* */
@@ -59,8 +59,19 @@ class IntrTest: public CxxTest::TestSuite
size_t threads = cpu_thread_count();
+ //look for an override
+ TARGETING::Target* sys = NULL;
+ TARGETING::targetService().getTopLevelTarget(sys);
+ assert( sys != NULL );
+ uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>();
+
for(size_t thread = 0; thread < threads; ++thread)
{
+ if( !(en_threads & (0x8000000000000000>>thread)) )
+ {
+ continue;
+ }
+
addr = reinterpret_cast<uint32_t *>
(iv_masterAddr + (thread << 12) + 16); // LINK A reg
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 61fa495bc..e9223c7a7 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -10027,4 +10027,19 @@ Measured in GB</description>
</hwpfToHbAttrMap>
</attribute>
+<attribute>
+ <id>ENABLED_THREADS</id>
+ <description>
+ Bitmask of threads to enable for each processor,
+ Zero means enable all architected threads
+ </description>
+ <simpleType>
+ <uint64_t>
+ </uint64_t>
+ </simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
</attributes>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 6b94a88ef..5376ab19c 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -138,9 +138,13 @@
<attribute><id>SBE_IMAGE_OFFSET</id></attribute>
<attribute><id>BOOT_VOLTAGE</id></attribute>
<attribute><id>SYNC_BETWEEN_STEPS</id></attribute>
+ <!-- End sbe_config_update attributes -->
<!-- proc_select_boot_master attributes -->
<attribute><id>PROC_SELECT_BOOT_MASTER</id></attribute>
<attribute><id>PROC_SELECT_SEEPROM_IMAGE</id></attribute>
+ <!-- End proc_select_boot_master attributes -->
+
+ <attribute><id>ENABLED_THREADS</id></attribute>
</targetType>
<targetType>
@@ -364,6 +368,7 @@
<attribute><id>IMT_BASE_ADDR</id></attribute>
<attribute><id>IMT_BAR_SIZE</id></attribute>
<!-- end Memory Map -->
+
<!-- PROC_PCIE attributes -->
<attribute><id>PROC_PCIE_IOP_CONFIG</id></attribute>
<attribute><id>PROC_PCIE_IOP_SWAP</id></attribute>
OpenPOWER on IntegriCloud