On 17/03/2023 13.36, Nicholas Piggin wrote:
This consolidates several implementations, and it no longer leaves
MSR[EE] enabled after the decrementer interrupt is handled, but
rather disables it on return.
The handler no longer allows a continuous ticking, but rather dec
has to be re-armed and EE re-enabled (e.g., via H_CEDE hcall) each
time.
Signed-off-by: Nicholas Piggin <npiggin@xxxxxxxxx>
---
...
diff --git a/lib/powerpc/processor.c b/lib/powerpc/processor.c
index ec85b9d..f1fb50f 100644
--- a/lib/powerpc/processor.c
+++ b/lib/powerpc/processor.c
@@ -10,6 +10,8 @@
#include <asm/ptrace.h>
#include <asm/setup.h>
#include <asm/barrier.h>
+#include <asm/hcall.h>
+#include <asm/handlers.h>
static struct {
void (*func)(struct pt_regs *, void *data);
@@ -54,3 +56,32 @@ void udelay(uint64_t us)
{
delay((us * tb_hz) / 1000000);
}
+
+void sleep(uint64_t cycles)
When I see a sleep() in a C program, I automatically assume that it's
parameter is "seconds", so having a sleep() function here that is taking
cycles as a parameter is confusing. Could you please name the function
differently?
+{
+ uint64_t start, end, now;
+
+ start = now = get_tb();
+ end = start + cycles;
+
+ while (end > now) {
+ uint64_t left = end - now;
+
+ /* Could support large decrementer */
+ if (left > 0x7fffffff)
+ left = 0x7fffffff;
+
+ asm volatile ("mtdec %0" : : "r" (left));
+ handle_exception(0x900, &dec_handler_oneshot, NULL);
+ if (hcall(H_CEDE) != H_SUCCESS) {
+ printf("H_CEDE failed\n");
+ abort();
+ }
+ handle_exception(0x900, NULL, NULL);
+
+ if (left < 0x7fffffff)
+ break;
Shouldn't that be covered by the "end > now" in the while loop condition
check already?
+ now = get_tb();
+ }
+}
Thomas