APIC Timer: Difference between revisions

m
no edit summary
[unchecked revision][unchecked revision]
No edit summary
mNo edit summary
Line 1:
The great benefit of the Local [[APIC]] timer is that it is hardwired to each CPU core, unlike the [[PIT|Programmable Interval Timer]] which is a separate circuit. Because of this, there is no need for any resource management, which makes things easier. The downside is that it's oscillating at (one of) the CPU's frequencies, which varies from machine to machine, while the PIT uses a standard frequency (11931821,193,182 Hz). To make use of it, you have to know how many interrupts/sec it's capable of.
 
== APIC Timer Modes ==
Line 42:
 
== Initializing ==
There are several ways to do this, but all of them use a different, CPU bus frequency independent clock source to do that. Examples: [[RTC|Real Time Clock]], [[TSC|TimeStamp Counter]], PIT or even polling [[CMOS#Getting_Current_Date_and_Time_from_RTC|CMOS registers]]. In this tutorial we will use the good old PIT, as it's the easiest. Steps that need to be done:
* Reset APIC to a well known state
* Enable APIC timer
Line 52:
* Make the APIC timer fire an interrupt at every X ticks
 
The APIC timer can be set to make a tick (decrease counter) at a given frequency, which is called "divide value". This means you have to multiply APIC timer counter ticks by this divide value to get the true CPU bus frequency. You could use a value of 1 (ticks on every bus cycle) up to 128 (ticks on every 128th cycle). See Intel manual vol3A Chapter 9.5.4 onfor details. Note that according to my tests, Bochs seems not to handle divide value of 1 properly, so I will use 16.
 
=== Prerequisites ===
Before we start, let's define some constant and functions.
Line 95 ⟶ 96:
</source>
I will also assume that you have a working [[IDT]], and you have a function to write a gate for a specific interrupt: writegate(intnumber,israddress).
Furthermore, to make things simple, I'll assume that you did not changedchange the default interrupt mapping found in almost every tutorial:
* interrupt 0-31: exceptions
* interrupt 32: timer, IRQ0
Line 211 ⟶ 212:
 
=== Example code in C ===
This code is an example of how to initialize the APIC timer so that it ticks every 10 milliseconds. This is done by letting the APIC timer run, waiting for 10ms using the PIT and then getting the number of ticks that were done from the APIC timer. It assumes that you have functions to "write"/"read" the APIC's registers and "pit_prepare_sleep"/"pit_perform_sleep" to perform an as accurate as possible measuringmeasurement of the timerstimer's frequency.
<source lang="c">
void apic_start_timer() {
Anonymous user