[PATCH v2 1/2 gnumach] pit, smp: Fix i8254 one shot delay and replace hpet_udelay in smp
Damien Zammit via Bug reports for the GNU Hurd <[email protected]> Tue, 04 Aug 2026 04:08:32 +0000
| Newsgroups | gmane.os.hurd.bugs |
|---|---|
| Message-ID | <[email protected]> |
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 =3D PIT_C0|PIT_SQUAREMODE|PIT_READMODE ;
unsigned int clknumb =3D CLKNUM;=09=09/* interrupt interval for timer 0 */
=20
void
-pit_prepare_sleep(int persec)
+pit_prepare_sleep(int usec)
{
/* Prepare to sleep for 1/persec seconds */
- uint32_t val =3D 0;
+ uint64_t val =3D 0;
uint8_t lsb, msb;
=20
val =3D inb(PITAUX_PORT);
@@ -77,7 +77,7 @@ pit_prepare_sleep(int persec)
val |=3D PITAUX_GATE2;
outb (PITAUX_PORT, val);
outb (PITCTL_PORT, PIT_C2 | PIT_LOADMODE | PIT_ONESHOTMODE);
- val =3D CLKNUM / persec;
+ val =3D (uint64_t)CLKNUM * usec / 1000000;
lsb =3D val & 0xff;
msb =3D 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 -=3D MAX_PIT_USEC;
+ }
+ pit_prepare_sleep(usec);
pit_sleep();
}
=20
void
pit_mdelay(int msec)
{
- pit_prepare_sleep(1000 / msec);
- pit_sleep();
+ pit_udelay(1000 * msec);
}
=20
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=09defined(AT386) || defined(ATX86_64)
#define CLKNUM=09=091193182
+
+/* PIT counter is 16bit, so max microseconds is:
+ * 0xffffll ticks * 1000000 usec per sec / 1193182 ticks per sec */
+#define MAX_PIT_USEC=0954924
#endif=09/* AT386 */
=20
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 vecto=
r)
*/
apic_send_ipi(ALL_EXCLUDING_SELF, STARTUP, PHYSICAL, DE_ASSERT, ED=
GE, vector, bsp_apic_id);
=20
- hpet_udelay(10);
+ pit_udelay(10);
=20
/* Wait for other cpu to accept IPI */
wait_for_ipi();
send_err =3D lapic->error_status.r;
=20
- hpet_udelay(10);
+ pit_udelay(10);
=20
lapic->error_status.r =3D 0;
accept_err =3D lapic->error_status.r & 0xef;
--=20
2.51.0