summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/kernel/cpu.H4
-rw-r--r--src/kernel/cpumgr.C32
-rw-r--r--src/kernel/start.S8
-rw-r--r--src/lib/syscall_mmio.C4
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;
}
OpenPOWER on IntegriCloud