diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2014-03-26 17:06:32 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-04-03 20:28:20 -0500 |
commit | 8c7a27be94470541d184cfec495b6cfe63953733 (patch) | |
tree | 143c2fde82d3d5fc10396b8b14f8c5e503c93c14 /src | |
parent | 9d4827735558fe03ee021afb7dacfa6ac76719bb (diff) | |
download | talos-hostboot-8c7a27be94470541d184cfec495b6cfe63953733.tar.gz talos-hostboot-8c7a27be94470541d184cfec495b6cfe63953733.zip |
Use per-core mutex for XSCOM for P8 errata.
See HW822317. The HMER register in P8 is not implemented to
handle multi-threaded XSCOM properly, so we need to move the
XSCOM mutex from per-thread to per-core. Also, there is an
issue where the 'done' bit can come on 1 cycle before the error
indicators, so need to potentially read the HMER a second time.
Change-Id: I495031a6e425fe7d5c6ffef8dda1e7a71caac9f2
CQ: SW250902
Backport: release-fips810
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/9929
Reviewed-by: Michael Baiocchi <baiocchi@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Tested-by: Jenkins Server
Diffstat (limited to 'src')
-rw-r--r-- | src/include/kernel/cpu.H | 4 | ||||
-rw-r--r-- | src/kernel/cpumgr.C | 32 | ||||
-rw-r--r-- | src/kernel/start.S | 8 | ||||
-rw-r--r-- | src/lib/syscall_mmio.C | 4 |
4 files changed, 42 insertions, 6 deletions
diff --git a/src/include/kernel/cpu.H b/src/include/kernel/cpu.H index 824a65370..478983148 100644 --- a/src/include/kernel/cpu.H +++ b/src/include/kernel/cpu.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2010,2012 */ +/* COPYRIGHT International Business Machines Corp. 2010,2014 */ /* */ /* p1 */ /* */ @@ -89,7 +89,7 @@ struct cpu_t task_t* idle_task; /** XSCOM mutex to serialize access per CPU */ - mutex_t xscom_mutex; + mutex_t* xscom_mutex; /** counter for executePeriodics */ size_t periodic_count; diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C index 624751b5c..ac0e09dff 100644 --- a/src/kernel/cpumgr.C +++ b/src/kernel/cpumgr.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2010,2013 */ +/* COPYRIGHT International Business Machines Corp. 2010,2014 */ /* */ /* p1 */ /* */ @@ -42,6 +42,7 @@ #include <kernel/terminate.H> #include <kernel/hbterminatetypes.H> #include <kernel/kernel_reasoncodes.H> +#include <kernel/cpuid.H> cpu_t** CpuManager::cv_cpus[KERNEL_MAX_SUPPORTED_NODES]; bool CpuManager::cv_shutdown_requested = false; @@ -214,7 +215,34 @@ void CpuManager::startCPU(ssize_t i) reinterpret_cast<uintptr_t>(cpu->kernel_stack_bottom) + kernel_page_offset); - cpu->xscom_mutex = (mutex_t)MUTEX_INITIALIZER; + cpu->xscom_mutex = NULL; + + // xscom workaround for HW822317 : Power8 Errata. + // Need to make the xscom mutex a per-core mutex to prevent + // multi-threaded access to the HMER. + if ((CpuID::getCpuType() == CORE_POWER8_MURANO) || + (CpuID::getCpuType() == CORE_POWER8_VENICE)) + { + const size_t num_threads = getThreadCount(); + size_t cpu_idx = (cpuId / num_threads) * num_threads; + + for(size_t i = 0; i < getThreadCount(); ++i) + { + if ((NULL != cv_cpus[nodeId][cpu_idx + i]) && + (NULL != cv_cpus[nodeId][cpu_idx + i]->xscom_mutex)) + { + cpu->xscom_mutex = + cv_cpus[nodeId][cpu_idx + i]->xscom_mutex; + break; + } + } + } + + if (NULL == cpu->xscom_mutex) + { + cpu->xscom_mutex = new mutex_t; + mutex_init(cpu->xscom_mutex); + } // Create idle task. cpu->idle_task = TaskManager::createIdleTask(); diff --git a/src/kernel/start.S b/src/kernel/start.S index 790281305..b6f09d40e 100644 --- a/src/kernel/start.S +++ b/src/kernel/start.S @@ -707,6 +707,14 @@ system_call_fast_path: ;// Compare was already done in system call path. bne cr0, 2f mfspr r3, HMER + ;// Do XSCOM workaround for Errata HW822317. + ;// If the done bit (10) is on in HMER, it could take another cycle + ;// for any error status to show up. Perform another HMER read. + rldicr. r0, r3, 10, 0 + beq cr0, 1f ;// Done bit not set, jump to exit. + mfspr r0, HMER ;// Read HMER again and OR results. + or r3, r3, r0 + ;// --- end workaround HW822317 b 1f ;// Jump to exit point. ;// Check if this is HMER write (0x801). 2: diff --git a/src/lib/syscall_mmio.C b/src/lib/syscall_mmio.C index 7d593c27e..23dea45f8 100644 --- a/src/lib/syscall_mmio.C +++ b/src/lib/syscall_mmio.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2010,2013 */ +/* COPYRIGHT International Business Machines Corp. 2010,2014 */ /* */ /* p1 */ /* */ @@ -94,5 +94,5 @@ mutex_t * mmio_xscom_mutex() crit_assert(task->affinity_pinned); // Return mutex from cpu structure. - return &task->cpu->xscom_mutex; + return task->cpu->xscom_mutex; } |