HPET: Difference between revisions

107 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (→‎FSB mapping: looks like I originally accidentally a word)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(8 intermediate revisions by 7 users not shown)
Line 1:
:''This page is not meant as a full description of HPET, only as a lightweight introduction. If you need any information not covered by this article, consult the [http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf HPET specification].''
 
'''HPET''', or High Precision Event Timer, is a piece of hardware designed by Intel and Microsoft to replace older [[PIT]] and [[RTC]]. It consists of (usually 64-bit) main counter (which counts up), as well as from 3 to 32 32-bit or 64 -bit wide comparators. HPET is programmed using memory mapped IO, and the base address of HPET can be found using [[ACPI]].
==Preface==
 
HPET, or High Precision Event Timer, is a piece of hardware designed by Intel and Microsoft to replace older [[PIT]] and [[RTC]]. It consists of (usually 64-bit) main counter (which counts up), as well as from 3 to 32 32 or 64 bit wide comparators. HPET is programmed using memory mapped IO, and the base address of HPET can be found using [[ACPI]].
 
==Detecting HPET using ACPI==
 
The [http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf HPET specification] defines an ACPI 2.0 table that is to be used to detect presence, address and capabilities of HPET present in the system. If this table doesn't exist, you should assume there is no HPET and you should fall back to [[PIT]] or the [[APIC timer]].
 
<sourcesyntaxhighlight lang="cpp">
struct address_structure
{
Line 39 ⟶ 37:
uint8_t reserved:1;
uint8_t legacy_replacement:1;
pci_vendor_tuint16_t pci_vendor_id;
address_structure address;
uint8_t hpet_number;
Line 45 ⟶ 43:
uint8_t page_protection;
} __attribute__((packed));
</syntaxhighlight>
</source>
 
==HPET - timer vs comparators==
Line 112 ⟶ 110:
!Type
|-
|0x000 - 000x70x007
|General Capabilities and ID Register
|Read only
Line 150 ⟶ 148:
|63:32
|COUNTER_CLK_PERIOD
|Main counter tick period in femptosecondsfemtoseconds (10^-15 seconds). Must not be zero, must be less or equal to 0x05F5E100, or 100 nanoseconds.
|-
|31-16
Line 299 ⟶ 297:
 
General initialization:
 
1. Find HPET base address in 'HPET' ACPI table.
 
2. Calculate HPET frequency (f = 10^15 / period).
 
3. Save minimal tick (either from ACPI table or configuration register).
 
4. Initialize comparators.
 
5. Set ENABLE_CNF bit.
 
Timer N initialization:
 
1. Determine if timer N is periodic capable, save that information to avoid re-reading it every time.
 
2. Determine allowed interrupt routing for current timer and allocate an interrupt for it.
 
Line 319 ⟶ 324:
To enable one-shot mode:
 
<sourcesyntaxhighlight lang="cpp">
// "time" is time in femptosecondsfemtoseconds from now to interrupt
if (time < COUNTER_CLK_PERIOD)
{
Line 328 ⟶ 333:
write_register_64(timer_configuration(n), (ioapic_input << 9) | (1 << 2));
write_register_64(timer_comparator(n), read_register(main_counter) + time);
</syntaxhighlight>
</source>
 
I hope the above code is obvious. If it's not, please analyze the meaning of specific fields in registers used above.
Line 336 ⟶ 341:
To enable periodic mode:
 
<sourcesyntaxhighlight lang="cpp">
// "time" is time in femptosecondsfemtoseconds from now to interrupt
if (time < COUNTER_CLK_PERIOD)
{
Line 346 ⟶ 351:
write_register_64(timer_comparator(n), read_register(main_counter) + time);
write_register_64(timer_comparator(n), time);
</syntaxhighlight>
</source>
 
This snippet requires some more comments.
Line 361 ⟶ 366:
==See also==
* [[IOAPIC]]
* [[APIC]]
* [[APIC timer]]
* [[PIT]]
* [[RTC]]
Line 371 ⟶ 378:
[[Category:Common Devices]]
[[Category:Interrupts]]
[[Category:TimeTimers]]