amd64, i386: add delay_init(): basic delay(9) implementation management
authorcheloha <cheloha@openbsd.org>
Thu, 25 Aug 2022 17:25:25 +0000 (17:25 +0000)
committercheloha <cheloha@openbsd.org>
Thu, 25 Aug 2022 17:25:25 +0000 (17:25 +0000)
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
sys/arch/amd64/include/cpu.h
sys/arch/i386/i386/machdep.c
sys/arch/i386/include/cpu.h

index 932b1df..e701b9b 100644 (file)
@@ -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;
+       }
+}
index 6143683..a4af201 100644 (file)
@@ -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)
index 8d909cc..8611a2c 100644 (file)
@@ -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;
+       }
+}
index bfab0f3..d9a965d 100644 (file)
@@ -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)