Skip to content

Commit c9d1f3e

Browse files
wghoffadcrowell77
authored andcommitted
Restore Timebase on Master Core Threads 1-3 after Sleep/Winkle
Change-Id: I329dd64345f2474cb0dad628ccc2244d85be86c2 CQ: SW458971 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/76601 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
1 parent 3df3c9b commit c9d1f3e

File tree

7 files changed

+53
-3
lines changed

7 files changed

+53
-3
lines changed

src/include/kernel/cpu.H

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ struct cpu_t
104104
/** Sequence ID of CPU initialization. */
105105
uint64_t cpu_start_seqid;
106106

107+
/** Timebase Restore Value (used during core wakeup) */
108+
uint64_t cpu_restore_tb;
109+
107110
/** Stack of WorkItems to be executed during doorbell wakeup */
108111
Util::Lockfree::Stack<KernelWorkItem> doorbell_actions;
109112
};

src/include/kernel/doorbell.H

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ void send_doorbell_wakeup(uint64_t i_pir);
5656
*/
5757
void send_doorbell_ipc(uint64_t i_pir);
5858

59+
/** Send a doorbell and also restore the thread's timebase
60+
*
61+
* @param i_pir - PIR to send doorbell to wakeup
62+
* @param i_tb - Timebase value to restore during wakeup
63+
*/
64+
void send_doorbell_restore_tb(uint64_t i_pir, uint64_t i_tb);
65+
5966
enum
6067
{
6168
_DOORBELL_MSG_TYPE = 0x0000000028000000, /// Comes from the ISA.

src/include/kernel/workitem.H

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ class CpuWakeupDoorbellWorkItem : public KernelWorkItem
5353
~CpuWakeupDoorbellWorkItem() = default;
5454
};
5555

56+
//A work item to be created/executed during a Master CPU
57+
// wakeup scenario, it will also restore the timebase
58+
// on the threads being woken up
59+
class CpuTbRestoreDoorbellWorkItem : public KernelWorkItem
60+
{
61+
public:
62+
//Implement operator() function
63+
void operator() (void);
64+
65+
//No data to clean up, use default destructor
66+
~CpuTbRestoreDoorbellWorkItem() = default;
67+
};
5668

5769
#endif
5870

src/kernel/cpumgr.C

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ void CpuManager::startCPU(ssize_t i)
253253
cpu->idle_task = TaskManager::createIdleTask();
254254
cpu->idle_task->cpu = cpu;
255255
cpu->periodic_count = 0;
256+
cpu->cpu_restore_tb = 0;
256257

257258
// Call TimeManager setup for a CPU.
258259
TimeManager::init_cpu(cpu);

src/kernel/doorbell.C

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ void send_doorbell_wakeup(uint64_t i_pir)
8383
doorbell_send(i_pir);
8484
}
8585

86+
void send_doorbell_restore_tb(uint64_t i_pir, uint64_t i_tb)
87+
{
88+
cpu_t *l_cpu = CpuManager::getCpu(i_pir);
89+
l_cpu->cpu_restore_tb = i_tb;
90+
91+
printkd("send_doorbell_restore_tb to pir: %lx\n", i_pir);
92+
//Create WorkItem and put on the stack to be executed during doorbell
93+
// execution
94+
KernelWorkItem* l_work = new CpuTbRestoreDoorbellWorkItem();
95+
l_cpu->doorbell_actions.push(l_work);
96+
//Send doorbell to wakeup core/thread
97+
doorbell_send(i_pir);
98+
}
99+
86100
void send_doorbell_ipc(uint64_t i_pir)
87101
{
88102
printk("send_doorbell_ipc to pir: %lx\n", i_pir);

src/kernel/misc.C

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ namespace KernelMisc
347347
// NOTE: The deferred work container verifies master core
348348
// threads 1-3 wake up so a direct doorbell can be sent. For
349349
// threads on other cores send_doorbell_wakeup() is used.
350-
doorbell_send(l_pir + i);
350+
send_doorbell_restore_tb(l_pir + i, iv_timebase);
351351
}
352352
}
353353

@@ -357,7 +357,6 @@ namespace KernelMisc
357357
{
358358
cpu->scheduler->setNextRunnable();
359359
}
360-
361360
}
362361

363362
void WinkleCore::masterPostWork()
@@ -464,7 +463,6 @@ namespace KernelMisc
464463
{
465464
cpu->scheduler->setNextRunnable();
466465
}
467-
468466
}
469467

470468
void WinkleAll::masterPostWork()

src/kernel/workitem.C

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <kernel/workitem.H>
2828
#include <kernel/console.H>
2929
#include <kernel/intmsghandler.H>
30+
#include <kernel/cpumgr.H>
3031

3132
//Define the desired behavior for a CPU core/thread
3233
// wakeup scenario
@@ -40,3 +41,17 @@ void CpuWakeupDoorbellWorkItem::operator() (void)
4041
InterruptMsgHdlr::sendThreadWakeupMsg(pir);
4142
return;
4243
}
44+
45+
void CpuTbRestoreDoorbellWorkItem::operator() (void)
46+
{
47+
size_t pir = getPIR();
48+
cpu_t *l_cpu = CpuManager::getCpu(pir);
49+
50+
uint64_t l_restore_tb = l_cpu->cpu_restore_tb;
51+
printkd("pir:%ld tb:0x%0x\n", pir, l_restore_tb);
52+
if (l_restore_tb > getTB())
53+
{
54+
setTB(l_restore_tb);
55+
}
56+
return;
57+
}

0 commit comments

Comments
 (0)