summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2014-03-26 17:06:32 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-04-03 20:28:20 -0500
commit8c7a27be94470541d184cfec495b6cfe63953733 (patch)
tree143c2fde82d3d5fc10396b8b14f8c5e503c93c14 /src/kernel
parent9d4827735558fe03ee021afb7dacfa6ac76719bb (diff)
downloadtalos-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/kernel')
-rw-r--r--src/kernel/cpumgr.C32
-rw-r--r--src/kernel/start.S8
2 files changed, 38 insertions, 2 deletions
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:
OpenPOWER on IntegriCloud