diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2012-09-16 16:14:13 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-09-24 11:29:39 -0500 |
commit | 363b20b39bc5f36fcba9eabb3c755b6bdf13574b (patch) | |
tree | 62b9e1a285b2af15fb0fc49b12660ae6d15c1364 /src | |
parent | 9dfd209fca2c451eb1314cf1c43cb6d222e4ee7d (diff) | |
download | talos-hostboot-363b20b39bc5f36fcba9eabb3c755b6bdf13574b.tar.gz talos-hostboot-363b20b39bc5f36fcba9eabb3c755b6bdf13574b.zip |
Sync timebase to slave cores.
Change-Id: I196e58be48195f653ab16a74dedafabafbd07bbc
RTC: 47013
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1774
Tested-by: Jenkins Server
Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/kernel/cpumgr.H | 7 | ||||
-rw-r--r-- | src/kernel/cpumgr.C | 38 |
2 files changed, 43 insertions, 2 deletions
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H index 21e29167f..e5015feef 100644 --- a/src/include/kernel/cpumgr.H +++ b/src/include/kernel/cpumgr.H @@ -202,6 +202,13 @@ class CpuManager static InteractiveDebug cv_interactive_debug; + /** Timebase of the master the last time a CPU was started. + * + * This is used when slave CPUs activate to determine if the + * timebases need to be synchronized. + */ + uint64_t iv_lastStartTimebase; + }; #endif diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C index db79a15bf..2667d5b02 100644 --- a/src/kernel/cpumgr.C +++ b/src/kernel/cpumgr.C @@ -47,7 +47,7 @@ size_t CpuManager::cv_cpuSeq = 0; bool CpuManager::cv_forcedMemPeriodic = false; InteractiveDebug CpuManager::cv_interactive_debug; -CpuManager::CpuManager() +CpuManager::CpuManager() : iv_lastStartTimebase(0) { for (int i = 0; i < KERNEL_MAX_SUPPORTED_NODES; i++) cv_cpus[i] = NULL; @@ -139,6 +139,9 @@ void CpuManager::requestShutdown(uint64_t i_status) void CpuManager::startCPU(ssize_t i) { + // Save away the current timebase for TB synchronization. + iv_lastStartTimebase = getTB(); + bool currentCPU = false; if (i < 0) { @@ -209,9 +212,40 @@ void CpuManager::startCPU(ssize_t i) void CpuManager::startSlaveCPU(cpu_t* cpu) { - setDEC(TimeManager::getTimeSliceCount()); + // Activate CPU. activateCPU(cpu); + // Sync timebase with master. + while(getTB() < iv_lastStartTimebase) + { + class SyncTimebase : public DeferredWork + { + public: + void masterPreWork() + { + iv_timebase = getTB(); + } + + void activeMainWork() + { + if (getTB() < iv_timebase) + { + setTB(iv_timebase); + } + } + + private: + uint64_t iv_timebase; + }; + + SyncTimebase* deferred = new SyncTimebase(); + DeferredQueue::insert(deferred); + DeferredQueue::execute(); + } + + // Update decrementer. + setDEC(TimeManager::getTimeSliceCount()); + return; } |