Hello,
Thanks for fixing this!
Damien Zammit via Bug reports for the GNU Hurd, le mar. 30 juin 2026 10:54:30
+0000, a ecrit:
> The one-shot pit delay was not calibrated properly.
> This fixes the pit_udelay() function so it can be used for
> tiny delays within the kernel. Removes dependence on HPET for smp.
> ---
> i386/i386/pit.c | 16 ++++++++++------
> i386/i386/pit.h | 3 +++
> i386/i386/smp.c | 5 +++--
> 3 files changed, 16 insertions(+), 8 deletions(-)
>
> diff --git a/i386/i386/pit.c b/i386/i386/pit.c
> index 6c006a98..1863e283 100644
> --- a/i386/i386/pit.c
> +++ b/i386/i386/pit.c
> @@ -66,10 +66,10 @@ int pit0_mode = PIT_C0|PIT_SQUAREMODE|PIT_READMODE ;
> unsigned int clknumb = CLKNUM; /* interrupt interval for timer
> 0 */
>
> void
> -pit_prepare_sleep(int persec)
> +pit_prepare_sleep(int usec)
> {
> /* Prepare to sleep for 1/persec seconds */
> - uint32_t val = 0;
> + uint64_t val = 0;
> uint8_t lsb, msb;
>
> val = inb(PITAUX_PORT);
> @@ -77,7 +77,7 @@ pit_prepare_sleep(int persec)
> val |= PITAUX_GATE2;
> outb (PITAUX_PORT, val);
> outb (PITCTL_PORT, PIT_C2 | PIT_LOADMODE | PIT_ONESHOTMODE);
> - val = CLKNUM / persec;
> + val = CLKNUM * usec / 1000000;
Just changing the type of the eventual left-value will not change the
type of the expression. You want to cast CLKNUM into uint64_t before
multiplying it.
We'd also want to assert against too-long usec values, by checking that
val <= 0xffff.
> lsb = val & 0xff;
> msb = val >> 8;
> outb (PITCTR2_PORT, lsb);
> @@ -104,15 +104,19 @@ pit_sleep(void)
> void
> pit_udelay(int usec)
> {
> - pit_prepare_sleep(1000000 / usec);
> + while (usec > MAX_PIT_USEC) {
Ah, indeed!
> + pit_prepare_sleep(MAX_PIT_USEC);
> + pit_sleep();
> + usec -= MAX_PIT_USEC;
> + }
> + pit_prepare_sleep(usec);
> pit_sleep();
> }
>
> void
> pit_mdelay(int msec)
> {
> - pit_prepare_sleep(1000 / msec);
> - pit_sleep();
> + pit_udelay(1000 * msec);
> }
>
> void
> diff --git a/i386/i386/pit.h b/i386/i386/pit.h
> index 49e1051b..350ddc21 100644
> --- a/i386/i386/pit.h
> +++ b/i386/i386/pit.h
> @@ -87,6 +87,9 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> */
> #if defined(AT386) || defined(ATX86_64)
> #define CLKNUM 1193182
> +
> +/* CLKNUM ticks/s * (54924/1000000)s ~= 0xffff */
> +#define MAX_PIT_USEC 54924
Better explicitly write (0xffffll * 1000000/1193182) to explain the
computation.
> #endif /* AT386 */
>
> extern void clkstart(void);
> diff --git a/i386/i386/smp.c b/i386/i386/smp.c
> index dc3a8ba5..6b610020 100644
> --- a/i386/i386/smp.c
> +++ b/i386/i386/smp.c
> @@ -23,6 +23,7 @@
> #include <i386/smp.h>
> #include <i386/cpu.h>
> #include <i386/pio.h>
> +#include <i386/pit.h>
> #include <i386/vm_param.h>
> #include <i386at/idt.h>
> #include <i386at/cram.h>
> @@ -138,13 +139,13 @@ smp_send_ipi_startup_twice(int bsp_apic_id, int vector)
> */
> apic_send_ipi(ALL_EXCLUDING_SELF, STARTUP, PHYSICAL, DE_ASSERT,
> EDGE, vector, bsp_apic_id);
>
> - hpet_udelay(10);
> + pit_udelay(10);
>
> /* Wait for other cpu to accept IPI */
> wait_for_ipi();
> send_err = lapic->error_status.r;
>
> - hpet_udelay(10);
> + pit_udelay(10);
>
> lapic->error_status.r = 0;
> accept_err = lapic->error_status.r & 0xef;
> --
> 2.51.0