summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-09-16 16:14:13 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-09-24 11:29:39 -0500
commit363b20b39bc5f36fcba9eabb3c755b6bdf13574b (patch)
tree62b9e1a285b2af15fb0fc49b12660ae6d15c1364 /src/kernel
parent9dfd209fca2c451eb1314cf1c43cb6d222e4ee7d (diff)
downloadtalos-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/kernel')
-rw-r--r--src/kernel/cpumgr.C38
1 files changed, 36 insertions, 2 deletions
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;
}
OpenPOWER on IntegriCloud