Re: [PATCH v2 1/2 gnumach] pit, smp: Fix i8254 one shot delay and replace hpet_udelay in smp

Samuel Thibault <[email protected]>
Newsgroups gmane.os.hurd.bugs
Organization I am not organized
Message-ID <anOQGZv1n9kSUWYM@end>
Applied both, thanks!

Damien Zammit via Bug reports for the GNU Hurd, le mar. 04 août 2026 04:08:32 +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 |  4 ++++
>  i386/i386/smp.c |  5 +++--
>  3 files changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/i386/i386/pit.c b/i386/i386/pit.c
> index 6c006a98..22a68183 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 = (uint64_t)CLKNUM * usec / 1000000;
>      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) {
> +        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..cc309460 100644
> --- a/i386/i386/pit.h
> +++ b/i386/i386/pit.h
> @@ -87,6 +87,10 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
>  #if	defined(AT386) || defined(ATX86_64)
>  #define CLKNUM		1193182
> +
> +/* PIT counter is 16bit, so max microseconds is:
> + * 0xffffll ticks * 1000000 usec per sec / 1193182 ticks per sec */
> +#define MAX_PIT_USEC	54924
>  #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
> 
> 
> 

-- 
Samuel
* c is away : cuisine; bouffe
<y> oh, moi je fais plutôt cuisine & bouffe en fait :)
<c> oui c'est vrai, certains font cuisine && bouffe (juste au cas où... ;-))
<y> ( cuisine && bouffe ) || restau
<N> voire ((cuisine && bouffe) || restau) & apéritif
 -+- #ens-mim -+-
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.