AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
clock.c File Reference

x86: the clock, arch_rtime_ns(), the nanoseconds since it started. More...

#include <core/system.h>
#include <core/arch.h>
#include <core/kargs.h>
#include <core/string.h>
#include <platform/misc.h>

Go to the source code of this file.

Macros

#define CALIBRATE_US   50000

Enumerations

enum  { SOURCE_PIT , SOURCE_HPET , SOURCE_TSC }

Functions

static uint64_t rdtsc (void)
 Reads the TSC.
static void cpuid (uint32_t leaf, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
 Runs CPUID for leaf.
static int tsc_invariant (void)
 Returns whether the TSC counts at a constant rate (CPUID 0x80000007, EDX bit 8).
static uint64_t mul_shift32 (uint64_t a, uint64_t b)
 Computes (a * b) >> 32 in 32-bit halves, without needing the 128-bit product.
static uint64_t counter (void)
 Reads the counter the clock uses.
static uint64_t since (uint64_t c)
 Returns the counts since the base, from the counter's value c.
uint64_t arch_rtime_ns (void)
 Reads the monotonic clock, which starts at boot.
uint64_t arch_rtime_us (void)
 Reads the monotonic clock, in microseconds.
uint64_t arch_rtime_ms (void)
 Reads the monotonic clock, in milliseconds.
void x86_clock_tick (void)
 Counts a tick of the timer, and moves the clock's base on to now.
static uint64_t tsc_calibrate (int hpet, const char **by)
 Calibrates the TSC: counts it over CALIBRATE_US, timed by the HPET or the PIT, and returns its mult (0 if it didn't count).
void x86_clock_ticks (uint32_t period_ns)
 Says how often the timer ticks, from now on: with neither TSC nor HPET, the ticks are the clock.
int x86_clock_precise (void)
 Says whether the clock counts finer than the ticks.
void x86_clock_init (void)
 Chooses the clock's counter and calibrates it, at boot, before the timer ticks.
const char * x86_clock_source (void)
 Returns the name of the clock's counter.

Variables

static const char * names [] = {"pit", "hpet", "tsc"}
static int source = SOURCE_PIT
static uint64_t mult
static uint64_t base_count
static uint64_t base_ns
static uint64_t last_ns
static uint32_t tick_period
static uint64_t ticks

Detailed Description

x86: the clock, arch_rtime_ns(), the nanoseconds since it started.

The clock reads a counter, chosen once at boot (x86_clock_init()), the first that the machine has of:

  • the TSC, if the CPU says it is invariant (it counts at the same rate whatever the CPU does), calibrated against the HPET (or the PIT without one) over CALIBRATE_US;
  • the HPET's main counter, whose rate is known;
  • the timer's ticks (every 2 ms, the local APIC's or the PIT's), which was all there was before.

clock=tsc, clock=hpet or clock=pit on the kernel's command line chooses one.

A count becomes nanoseconds as (count * mult) >> 32. Each tick of the timer moves the base on (x86_clock_tick()), so the counts since the base stay few: the HPET's low 32 bits are enough (they wrap in 43 s at 100 MHz), which is one read of its slow registers. The clock never goes back. The kernel runs on one CPU at a time, with interrupts off, so its readers don't race.

Definition in file clock.c.

Macro Definition Documentation

◆ CALIBRATE_US

#define CALIBRATE_US   50000

Definition at line 31 of file clock.c.

Referenced by tsc_calibrate().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
SOURCE_PIT 
SOURCE_HPET 
SOURCE_TSC 

Definition at line 33 of file clock.c.

Function Documentation

◆ arch_rtime_ms()

uint64_t arch_rtime_ms ( void )

Reads the monotonic clock, in milliseconds.

Returns
the time since the clock started, in milliseconds

Definition at line 124 of file clock.c.

References arch_rtime_ms(), and arch_rtime_ns().

◆ arch_rtime_ns()

uint64_t arch_rtime_ns ( void )

Reads the monotonic clock, which starts at boot.

Returns
the time since the clock started, in nanoseconds

Definition at line 99 of file clock.c.

References arch_rtime_ns(), base_ns, counter(), last_ns, mul_shift32(), mult, since(), source, SOURCE_PIT, tick_period, and ticks.

◆ arch_rtime_us()

uint64_t arch_rtime_us ( void )

Reads the monotonic clock, in microseconds.

Returns
the time since the clock started, in microseconds

Definition at line 116 of file clock.c.

References arch_rtime_ns(), and arch_rtime_us().

◆ counter()

uint64_t counter ( void )
static

Reads the counter the clock uses.

Definition at line 85 of file clock.c.

References counter(), rdtsc(), source, SOURCE_TSC, and x86_hpet_read32().

Referenced by arch_rtime_ns(), counter(), x86_clock_init(), and x86_clock_tick().

◆ cpuid()

void cpuid ( uint32_t leaf,
uint32_t * a,
uint32_t * b,
uint32_t * c,
uint32_t * d )
inlinestatic

Runs CPUID for leaf.

Definition at line 54 of file clock.c.

References cpuid().

Referenced by cpuid(), and tsc_invariant().

◆ mul_shift32()

uint64_t mul_shift32 ( uint64_t a,
uint64_t b )
inlinestatic

Computes (a * b) >> 32 in 32-bit halves, without needing the 128-bit product.

Definition at line 76 of file clock.c.

References mul_shift32().

Referenced by arch_rtime_ns(), mul_shift32(), and x86_clock_tick().

◆ rdtsc()

uint64_t rdtsc ( void )
inlinestatic

Reads the TSC.

Definition at line 46 of file clock.c.

References rdtsc().

Referenced by counter(), rdtsc(), and tsc_calibrate().

◆ since()

uint64_t since ( uint64_t c)
static

Returns the counts since the base, from the counter's value c.

Definition at line 91 of file clock.c.

References base_count, since(), source, and SOURCE_TSC.

Referenced by arch_rtime_ns(), since(), and x86_clock_tick().

◆ tsc_calibrate()

uint64_t tsc_calibrate ( int hpet,
const char ** by )
static

Calibrates the TSC: counts it over CALIBRATE_US, timed by the HPET or the PIT, and returns its mult (0 if it didn't count).

*by is set to the timer used.

Definition at line 146 of file clock.c.

References CALIBRATE_US, rdtsc(), tsc_calibrate(), x86_hpet_period_fs(), x86_hpet_read(), and x86_pit_delay().

Referenced by tsc_calibrate(), and x86_clock_init().

◆ tsc_invariant()

int tsc_invariant ( void )
static

Returns whether the TSC counts at a constant rate (CPUID 0x80000007, EDX bit 8).

Definition at line 61 of file clock.c.

References cpuid(), and tsc_invariant().

Referenced by tsc_invariant(), and x86_clock_init().

◆ x86_clock_init()

void x86_clock_init ( void )

Chooses the clock's counter and calibrates it, at boot, before the timer ticks.

Definition at line 200 of file clock.c.

References base_count, base_ns, counter(), kargs_get(), last_ns, mult, NULL, printk(), source, SOURCE_HPET, SOURCE_PIT, SOURCE_TSC, tsc_calibrate(), tsc_invariant(), x86_clock_init(), x86_hpet_init(), and x86_hpet_period_fs().

Referenced by arch_sched_init(), x86_clock_init(), and x86_goto().

◆ x86_clock_precise()

int x86_clock_precise ( void )

Says whether the clock counts finer than the ticks.

Returns
1 with the TSC or the HPET, 0 with the ticks

Definition at line 193 of file clock.c.

References source, SOURCE_PIT, and x86_clock_precise().

Referenced by timer_calibrate(), and x86_clock_precise().

◆ x86_clock_source()

const char * x86_clock_source ( void )

Returns the name of the clock's counter.

Returns
"tsc", "hpet" or "pit"

Definition at line 257 of file clock.c.

References names, source, and x86_clock_source().

Referenced by x86_clock_source(), and x86_goto().

◆ x86_clock_tick()

void x86_clock_tick ( void )

Counts a tick of the timer, and moves the clock's base on to now.

Definition at line 130 of file clock.c.

References base_count, base_ns, counter(), mul_shift32(), mult, since(), source, SOURCE_PIT, ticks, and x86_clock_tick().

Referenced by x86_clock_tick(), x86_goto(), and x86_sched_handler().

◆ x86_clock_ticks()

void x86_clock_ticks ( uint32_t period_ns)

Says how often the timer ticks, from now on: with neither TSC nor HPET, the ticks are the clock.

Parameters
period_nsthe tick's period, in ns

Definition at line 180 of file clock.c.

References printk(), source, SOURCE_PIT, tick_period, and x86_clock_ticks().

Referenced by arch_sched_init(), x86_clock_ticks(), and x86_goto().

Variable Documentation

◆ base_count

uint64_t base_count
static

Definition at line 39 of file clock.c.

Referenced by since(), x86_clock_init(), and x86_clock_tick().

◆ base_ns

uint64_t base_ns
static

Definition at line 39 of file clock.c.

Referenced by arch_rtime_ns(), x86_clock_init(), and x86_clock_tick().

◆ last_ns

uint64_t last_ns
static

Definition at line 39 of file clock.c.

Referenced by arch_rtime_ns(), and x86_clock_init().

◆ mult

uint64_t mult
static

Definition at line 38 of file clock.c.

Referenced by arch_rtime_ns(), x86_clock_init(), and x86_clock_tick().

◆ names

const char* names[] = {"pit", "hpet", "tsc"}
static

Definition at line 35 of file clock.c.

Referenced by x86_clock_source().

◆ source

◆ tick_period

uint32_t tick_period
static

Definition at line 42 of file clock.c.

Referenced by arch_rtime_ns(), and x86_clock_ticks().

◆ ticks

uint64_t ticks
static

Definition at line 43 of file clock.c.

Referenced by arch_rtime_ns(), and x86_clock_tick().