File tree Expand file tree Collapse file tree 7 files changed +53
-3
lines changed Expand file tree Collapse file tree 7 files changed +53
-3
lines changed Original file line number Diff line number Diff line change @@ -104,6 +104,9 @@ struct cpu_t
104
104
/* * Sequence ID of CPU initialization. */
105
105
uint64_t cpu_start_seqid;
106
106
107
+ /* * Timebase Restore Value (used during core wakeup) */
108
+ uint64_t cpu_restore_tb;
109
+
107
110
/* * Stack of WorkItems to be executed during doorbell wakeup */
108
111
Util::Lockfree::Stack<KernelWorkItem> doorbell_actions;
109
112
};
Original file line number Diff line number Diff line change @@ -56,6 +56,13 @@ void send_doorbell_wakeup(uint64_t i_pir);
56
56
*/
57
57
void send_doorbell_ipc (uint64_t i_pir );
58
58
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
+
59
66
enum
60
67
{
61
68
_DOORBELL_MSG_TYPE = 0x0000000028000000 , /// Comes from the ISA.
Original file line number Diff line number Diff line change @@ -53,6 +53,18 @@ class CpuWakeupDoorbellWorkItem : public KernelWorkItem
53
53
~CpuWakeupDoorbellWorkItem () = default ;
54
54
};
55
55
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
+ };
56
68
57
69
#endif
58
70
Original file line number Diff line number Diff line change @@ -253,6 +253,7 @@ void CpuManager::startCPU(ssize_t i)
253
253
cpu -> idle_task = TaskManager ::createIdleTask ();
254
254
cpu -> idle_task -> cpu = cpu ;
255
255
cpu -> periodic_count = 0 ;
256
+ cpu -> cpu_restore_tb = 0 ;
256
257
257
258
// Call TimeManager setup for a CPU.
258
259
TimeManager ::init_cpu (cpu );
Original file line number Diff line number Diff line change @@ -83,6 +83,20 @@ void send_doorbell_wakeup(uint64_t i_pir)
83
83
doorbell_send (i_pir );
84
84
}
85
85
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
+
86
100
void send_doorbell_ipc (uint64_t i_pir )
87
101
{
88
102
printk ("send_doorbell_ipc to pir: %lx\n" , i_pir );
Original file line number Diff line number Diff line change @@ -347,7 +347,7 @@ namespace KernelMisc
347
347
// NOTE: The deferred work container verifies master core
348
348
// threads 1-3 wake up so a direct doorbell can be sent. For
349
349
// 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 );
351
351
}
352
352
}
353
353
@@ -357,7 +357,6 @@ namespace KernelMisc
357
357
{
358
358
cpu -> scheduler -> setNextRunnable ();
359
359
}
360
-
361
360
}
362
361
363
362
void WinkleCore ::masterPostWork ()
@@ -464,7 +463,6 @@ namespace KernelMisc
464
463
{
465
464
cpu -> scheduler -> setNextRunnable ();
466
465
}
467
-
468
466
}
469
467
470
468
void WinkleAll ::masterPostWork ()
Original file line number Diff line number Diff line change 27
27
#include <kernel/workitem.H>
28
28
#include <kernel/console.H>
29
29
#include <kernel/intmsghandler.H>
30
+ #include <kernel/cpumgr.H>
30
31
31
32
//Define the desired behavior for a CPU core/thread
32
33
// wakeup scenario
@@ -40,3 +41,17 @@ void CpuWakeupDoorbellWorkItem::operator() (void)
40
41
InterruptMsgHdlr ::sendThreadWakeupMsg (pir );
41
42
return ;
42
43
}
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
+ }
You can’t perform that action at this time.
0 commit comments