#include <inttypes.h>
#include <round.h>
#include <stdio.h>
+#include "devices/pit.h"
#include "threads/interrupt.h"
-#include "threads/io.h"
+#include "threads/synch.h"
#include "threads/thread.h"
/* See [8254] for hardware details of the 8254 timer chip. */
#endif
/* Number of timer ticks since OS booted. */
-static volatile int64_t ticks;
+static int64_t ticks;
/* Number of loops per timer tick.
Initialized by timer_calibrate(). */
static void busy_wait (int64_t loops);
static void real_time_sleep (int64_t num, int32_t denom);
-/* Sets up the 8254 Programmable Interval Timer (PIT) to
- interrupt PIT_FREQ times per second, and registers the
- corresponding interrupt. */
+/* Sets up the timer to interrupt TIMER_FREQ times per second,
+ and registers the corresponding interrupt. */
void
timer_init (void)
{
- /* 8254 input frequency divided by TIMER_FREQ, rounded to
- nearest. */
- uint16_t count = (1193180 + TIMER_FREQ / 2) / TIMER_FREQ;
-
- outb (0x43, 0x34); /* CW: counter 0, LSB then MSB, mode 2, binary. */
- outb (0x40, count & 0xff);
- outb (0x40, count >> 8);
-
+ pit_configure_channel (0, 2, TIMER_FREQ);
intr_register_ext (0x20, timer_interrupt, "8254 Timer");
}
/* Approximate loops_per_tick as the largest power-of-two
still less than one timer tick. */
loops_per_tick = 1u << 10;
- while (!too_many_loops (loops_per_tick << 1))
- loops_per_tick <<= 1;
+ while (!too_many_loops (loops_per_tick << 1))
+ {
+ loops_per_tick <<= 1;
+ ASSERT (loops_per_tick != 0);
+ }
/* Refine the next 8 bits of loops_per_tick. */
high_bit = loops_per_tick;
enum intr_level old_level = intr_disable ();
int64_t t = ticks;
intr_set_level (old_level);
+ barrier ();
return t;
}
static bool
too_many_loops (unsigned loops)
{
- int64_t start;
-
/* Wait for a timer tick. */
- start = ticks;
+ int64_t start = ticks;
while (ticks == start)
- continue;
+ barrier ();
/* Run LOOPS loops. */
start = ticks;
busy_wait (loops);
/* If the tick count changed, we iterated too long. */
+ barrier ();
return start != ticks;
}
busy_wait (int64_t loops)
{
while (loops-- > 0)
- continue;
+ barrier ();
}
/* Sleep for approximately NUM/DENOM seconds. */