From c8334f21d0719699c4fdecca1815a29a13871818 Mon Sep 17 00:00:00 2001 From: cheloha Date: Thu, 25 Aug 2022 17:25:25 +0000 Subject: [PATCH] amd64, i386: add delay_init(): basic delay(9) implementation management Because the clock situation on x86 and amd64 is a terminal clusterfuck, there are many different ways to delay(9). We need a rudimentary mechanism for gracefully switching to progressively better delay(9) implementations as they become available during boot without riddling the code with ifdefs and function pointer comparisons. This patch adds delay_init() to both amd64 and i386. If the quality value passed to delay_init() exceeds the quality value of the current delay_func, delay_init() changes delay_func to the given function pointer and updates the quality value. Both platforms start with delay_func set to i8254_delay() and a quality value of zero: all other delay(9) implementations are preferable. Idea and patch provided by jsg@. With tons of input, research, and advice from jsg@. Link: https://marc.info/?l=openbsd-tech&m=166053729104923&w=2 ok mlarkin@ jsg@ --- sys/arch/amd64/amd64/machdep.c | 12 +++++++++++- sys/arch/amd64/include/cpu.h | 3 ++- sys/arch/i386/i386/machdep.c | 12 +++++++++++- sys/arch/i386/include/cpu.h | 3 ++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 932b1dfeb47..e701b9b8173 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.279 2022/08/07 23:56:06 guenther Exp $ */ +/* $OpenBSD: machdep.c,v 1.280 2022/08/25 17:25:25 cheloha Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -2069,3 +2069,13 @@ check_context(const struct reg *regs, struct trapframe *tf) return 0; } + +void +delay_init(void(*fn)(int), int fn_quality) +{ + static int cur_quality = 0; + if (fn_quality > cur_quality) { + delay_func = fn; + cur_quality = fn_quality; + } +} diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 61436835434..a4af201928e 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.148 2022/08/22 08:57:54 jsg Exp $ */ +/* $OpenBSD: cpu.h,v 1.149 2022/08/25 17:25:25 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -359,6 +359,7 @@ void signotify(struct proc *); * We need a machine-independent name for this. */ extern void (*delay_func)(int); +void delay_init(void (*)(int), int); struct timeval; #define DELAY(x) (*delay_func)(x) diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 8d909cc689e..8611a2c5dcf 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.655 2022/08/22 08:53:55 jsg Exp $ */ +/* $OpenBSD: machdep.c,v 1.656 2022/08/25 17:25:25 cheloha Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -3974,3 +3974,13 @@ cpu_rnd_messybits(void) nanotime(&ts); return (ts.tv_nsec ^ (ts.tv_sec << 20)); } + +void +delay_init(void(*fn)(int), int fn_quality) +{ + static int cur_quality = 0; + if (fn_quality > cur_quality) { + delay_func = fn; + cur_quality = fn_quality; + } +} diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index bfab0f32a22..d9a965dbdd0 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.177 2022/08/22 08:53:55 jsg Exp $ */ +/* $OpenBSD: cpu.h,v 1.178 2022/08/25 17:25:25 cheloha Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -302,6 +302,7 @@ void signotify(struct proc *); * We need a machine-independent name for this. */ extern void (*delay_func)(int); +void delay_init(void(*)(int), int); struct timeval; #define DELAY(x) (*delay_func)(x) -- 2.20.1