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@
-/* $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 $ */
/*-
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;
+ }
+}
-/* $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 $ */
/*-
* 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)
-/* $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 $ */
/*-
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;
+ }
+}
-/* $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 $ */
/*-
* 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)