# TSC API

## Introduction

In order to be able to measure and approximate time as soon as the kernel start the boot process, the TSC API is implemented in a volontarily minimal way. The TSC API is defined inside `shelter/lib/include/cpu/tsc.h` and implemented  inside `shelter/lib/src/cpu/tsc.c`. The API prefix is `sh_tsc_`.

## Overview

One of the TSC API goal being measuring time during the boot process, the provided features regarding this goal are extremely basic. In order for any TSC value to start at 0, we define two concept:
- `kernel_init_tsc`: a TSC value initialized at the very start of the kernel boot process
- `kernel_current_tsc`: a TSC value which is the result of `kernel_init_tsc` substracted to the value returned by `sh_asm_rdtsc()`

Starting with Shelter 0.2, the TSC API also provides primitives to estimate CPU frequency using PIT and TSC, or CPU ID if available.

## API content

The API define the following elements:
- `sh_tsc_TSC_VALUE`: a value of the TSC register, which is a wrapper of a `sh_uint64`
- `sh_tsc_read_value()`: an inline function reading the TSC register using `sh_asm_rdtsc()`, return a `sh_tsc_TSC_VALUE`
- `sh_tsc_init_tsc()`: a function initializing `kernel_init_tsc`. This function should only be called once as soon as the kernel start. Return a `SH_STATUS`
- `sh_tsc_get_kernel_init_tsc()`: return `kernel_init_tsc` under a `sh_tsc_TSC_VALUE`
- `sh_tsc_get_kernel_current_tsc()`: return the result of `sh_asm_rdtsc()` less `kernel_init_tsc`, under a `sh_tsc_TSC_VALUE`
- `sh_tsc_estimate_cpu_freq()`: estimate CPU frequency using PIT and TSC, should only be called once the IDT has been initialized and PIT remapped on the correct IDT vector, and before the start of all APs. It return the estimated frequency under a `sh_uint64`
- `sh_tsc_load_cpu_freq()`: take a `sh_uint64` and load it as CPU frequency, return nothing
- `sh_tsc_has_hypervisor()`: return `SH_TRUE` if the hypervisor bit in CPU ID is set, take no parameters
- `sh_tsc_is_tsc_constant()`: return `SH_TRUE` if the TSC is constant, according to CPU ID
- `sh_tsc_get_cpu_freq_cpuid()`: return in a variable given as a pointer the value of the CPU frequency given by CPU ID id available. Return a `SH_STATUS`
- `sh_tsc_devs_query()`: TSC DevS entry point, should only be called by `sh_devs_query`
