diff options
author | Damien Zammit <damien@zamaudio.com> | 2023-02-26 01:31:18 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-02-26 10:02:03 +0100 |
commit | 755921f74772f65d9e06b8c68a8c6617108ee1b4 (patch) | |
tree | 99d20e1fc8e7919fe8968b22525c450320e1f980 /i386/i386at/ioapic.c | |
parent | 304c0ba74a5eb2979808af44937153a65f108dc9 (diff) | |
download | gnumach-755921f74772f65d9e06b8c68a8c6617108ee1b4.tar.gz gnumach-755921f74772f65d9e06b8c68a8c6617108ee1b4.tar.bz2 gnumach-755921f74772f65d9e06b8c68a8c6617108ee1b4.zip |
lapic timer: Calibrate based on 10 PIT sleeps for 10ms
NB: This relies on a fix for QEMU as one-shot PIT mode
is currently broken in qemu.
Message-Id: <20230226013110.50606-1-damien@zamaudio.com>
Diffstat (limited to 'i386/i386at/ioapic.c')
-rw-r--r-- | i386/i386at/ioapic.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c index 24e04653..d2ea84ad 100644 --- a/i386/i386at/ioapic.c +++ b/i386/i386at/ioapic.c @@ -151,8 +151,9 @@ ioapic_toggle_entry(int apic, int pin, int mask) } static uint32_t -pit_measure_apic_hz(void) +pit_measure_10x_apic_hz(void) { + volatile int i; uint32_t start = 0xffffffff; /* Prepare accurate delay for 1/hz seconds */ @@ -162,7 +163,8 @@ pit_measure_apic_hz(void) lapic->init_count.r = start; /* zZz */ - pit_sleep(); + for (i = 0; i < 10; i++) + pit_sleep(); /* Stop APIC timer */ lapic->lvt_timer.r |= LAPIC_DISABLE; @@ -181,13 +183,13 @@ lapic_enable_timer(void) { /* Set up counter */ lapic->init_count.r = calibrated_ticks; - lapic->divider_config.r = LAPIC_TIMER_DIVIDE_16; + lapic->divider_config.r = LAPIC_TIMER_DIVIDE_2; /* Set the timer to interrupt periodically on remapped timer GSI */ lapic->lvt_timer.r = IOAPIC_INT_BASE | LAPIC_TIMER_PERIODIC; /* Some buggy hardware requires this set again */ - lapic->divider_config.r = LAPIC_TIMER_DIVIDE_16; + lapic->divider_config.r = LAPIC_TIMER_DIVIDE_2; /* Enable interrupts for the first time */ printf("LAPIC timer configured on cpu%d\n", cpu_number()); @@ -336,12 +338,13 @@ ioapic_configure(void) lapic_enable(); /* Set one-shot timer */ - lapic->divider_config.r = LAPIC_TIMER_DIVIDE_16; + lapic->divider_config.r = LAPIC_TIMER_DIVIDE_2; lapic->lvt_timer.r = IOAPIC_INT_BASE; - /* Measure number of APIC timer ticks in 1/hz seconds - * but calibrate the timer to expire at rate of hz */ - calibrated_ticks = pit_measure_apic_hz() * hz; + /* Measure number of APIC timer ticks in 10x 1/hz seconds + * but calibrate the timer to expire at rate of hz + * divide by 10 because we waited 10 times longer than we needed */ + calibrated_ticks = pit_measure_10x_apic_hz() / 10; /* Set up counter later */ lapic->lvt_timer.r = LAPIC_DISABLE; |