From a86d258a4b474dd7891ae604361c42726c18b58c Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Wed, 8 Apr 2026 15:29:52 +0200 Subject: [PATCH] CE implement stall command, libsystem Add stall_ms () --- ce/interp.c | 12 ++++++++++++ libsystem/amd64/src.mk | 6 ++++-- libsystem/amd64/stall.c | 30 ++++++++++++++++++++++++++++++ libsystem/stall.h | 8 ++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 libsystem/amd64/stall.c create mode 100644 libsystem/stall.h diff --git a/ce/interp.c b/ce/interp.c index cc22afd..c83a6fd 100644 --- a/ce/interp.c +++ b/ce/interp.c @@ -16,8 +16,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -325,6 +327,8 @@ static void mkvol (struct context* context, const char* volume, const char* str_ cprintf (context, "ERROR Could not create volume: %s\n", str_status[-ret]); } +static void stall (uint64_t ms) { stall_ms (ms); } + static void help (struct context* context) { cprintf (context, "Available commands:\n"); cprintf (context, "help\n"); @@ -340,6 +344,7 @@ static void help (struct context* context) { cprintf (context, "mkvol \n"); cprintf (context, "procinfo\n"); cprintf (context, "quit\n"); + cprintf (context, "stall \n"); } struct cmd_write_proc_ctx { @@ -414,6 +419,13 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context, bool run_ cprintf (context, "ERROR No volume key, filesystem type or device key provided\n"); } else if (strcmp (cmd->name, "procinfo") == 0) { procinfo (context); + } else if (strcmp (cmd->name, "stall") == 0) { + if (cmd->arg_count == 1) { + uint64_t ms = str_to_uint64 (cmd->args[0]); + stall (ms); + } else { + cprintf (context, "ERROR stall requires a timeout argument\n"); + } } else { char volume[VOLUME_MAX]; const char* path; diff --git a/libsystem/amd64/src.mk b/libsystem/amd64/src.mk index 900ee73..a9801a4 100644 --- a/libsystem/amd64/src.mk +++ b/libsystem/amd64/src.mk @@ -1,6 +1,8 @@ -c += amd64/syscall.c +c += amd64/syscall.c \ + amd64/stall.c S += amd64/_start.S o += amd64/_start.o \ - amd64/syscall.o + amd64/syscall.o \ + amd64/stall.o diff --git a/libsystem/amd64/stall.c b/libsystem/amd64/stall.c new file mode 100644 index 0000000..771ce94 --- /dev/null +++ b/libsystem/amd64/stall.c @@ -0,0 +1,30 @@ +#include +#include + +static uint64_t stall_read_tsc (void) { + uint32_t lo, hi; + __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)hi << 32) | lo; +} + +static uint64_t stall_get_tsc_freq_hz (void) { + uint32_t eax, ebx, ecx, edx; + __asm__ volatile ("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0x15)); + + if (eax == 0 || ebx == 0 || ecx == 0) + return 2500000000ULL; + + return (uint64_t)ecx * ebx / eax; +} + +void stall_ms (uint64_t ms) { + uint64_t freq_hz = stall_get_tsc_freq_hz (); + + uint64_t cycles = freq_hz / 1000; + uint64_t wait_cycles = ms * cycles; + + uint64_t now = stall_read_tsc (); + + while ((stall_read_tsc () - now) < wait_cycles) + __asm__ volatile ("pause" ::: "memory"); +} diff --git a/libsystem/stall.h b/libsystem/stall.h new file mode 100644 index 0000000..5625b94 --- /dev/null +++ b/libsystem/stall.h @@ -0,0 +1,8 @@ +#ifndef _LIBSYSTEM_STALL_H +#define _LIBSYSTEM_STALL_H + +#include + +void stall_ms (uint64_t ms); + +#endif // _LIBSYSTEM_STALL_H