Page 1 of 1

PIC / APIC and timers

Posted: Tue Feb 22, 2011 5:36 pm
by mark3094
I've been looking at some of the tutorials on the Brokenthorn.com website (such as http://www.brokenthorn.com/Resources/OSDev15.html).
They talk about programming the PIC and the PIT.

After a bit of research I have found that the PIC has been replaced by the APIC, and the PIT is the older timer, with newer timers such as the 'High Precision Event Timer' being used on newer systems.

Should the PIC and PIT be ignored in favour of the newer technologies?
Is it best to start with the older controllers while learning, and then move up to the APIC, etc?


What I'm trying to figure out is whether it's worth spending time learning the PIC and PIT, or whether I'm wasting my time.



Thanks

Re: PIC / APIC and timers

Posted: Tue Feb 22, 2011 5:44 pm
by NickJohnson
Writing drivers for the PIC and PIT really won't take up much of your time (you probably took more time thinking about it than it would take to write either). I haven't written an APIC driver and I've gotten very far with my OS, so it's clearly not critical. The APIC is only really necessary when you're getting SMP to work.

Re: PIC / APIC and timers

Posted: Tue Feb 22, 2011 6:02 pm
by mark3094
Thanks, I appreciate your help.

Does that mean that the APIC is used in legacy mode to make it work like a PIC, or do modern systems come with a PIC and an APIC? If so, should the APIC be disabled?
And the PIT should be used as the timer?

Re: PIC / APIC and timers

Posted: Tue Feb 22, 2011 7:44 pm
by Brendan
Hi,
mark3094 wrote:Does that mean that the APIC is used in legacy mode to make it work like a PIC, or do modern systems come with a PIC and an APIC? If so, should the APIC be disabled?
For PIC/APIC, modern systems have both. The "BIOS default state" is for the IO APIC to be disabled, and the PIC to be enabled (for backward compatibility, etc). To use the IO APIC you'd disable the PIC (e.g. mask all IRQs in the PIC) and unable the IO APIC (unmask any IRQs you want). For some (ancient) systems you also need to mess with the IMCR (details in Intel's MultiProcessor Specification) to switch from PIC to IO APIC. In theory, for a lot of systems it's technically possible to use both the PIC and the IO APIC at the same time. In practice it's fairly pointless.
mark3094 wrote:And the PIT should be used as the timer?
It's not as simple as "yes or no"...

Here's a list of timers and counters for "PC compatibles":
  • RTC update IRQ - happens once per second. Can assume it is present.
  • RTC periodic IRQ - programmable frequency from about 2 Hz to 8192 Hz. Can assume it is present (but see the notes for HPET).
  • RTC alarm IRQ - maybe good for very long delays and possibly other purposes (e.g. wake computer from sleep in 2 months time). Can assume it is present.
  • PIT channels (3 of them) - possibly good for counters. Can assume it is present.
  • PIT channel 0 IRQ - programmable frequency from about 18.2 Hz to 1.193 MHz (don't expect hardware to handle "too fast" speeds though), supports "one-shot" mode. Can assume it is present (but see the notes for HPET).
  • The local APIC timer/s - programmable frequency depending on base frequency (which depends on bus speed) but typically supports frequencies from about 1 Hz to 33 MHz, supports "one-shot" mode. One local APIC timer per logical CPU on modern systems. No local APIC timer at all on older single-CPU systems.
  • HPET - 1 counter, with 3 or more comparators. Some comparators (at least one) capable of being used as programmable frequency from about 1 Hz to 10 MHz or being used in "one shot" mode. Depending on chipset, HPET may (or may not) be used in to emulate PIT and/or RTC periodic IRQ (via. a combination of special support in HPET and BIOS/firmware SMM). Typically only present in modern systems (maybe since the year 2005?).
  • APIC timer - mostly a relatively slow counter, intended to be used to determine how long devices have been idle for. Typically only present in modern systems (maybe since the year 1995?).
  • TSC - an extremely fast/precise counter, with potential issues (e.g. frequency changes on older CPUs). Good for measuring extremely small delays (e.g. "several nanoseconds"). Present since about 1993, but only guaranteed to be "fixed frequency" on CPUs made in the last few years.
Note: The maximum "programmable frequencies" above are theoretical. It is possible to configure all of these timers to generate IRQs faster than the chipset can handle. In practice (for conservative/safe limits), I wouldn't trust the RTC periodic IRQ above about 2048 Hz and wouldn't trust the PIT above about 4096 Hz (they will work at higher frequencies on some computers/chipsets, but working on some isn't the same as working on all). I'm not too sure what the practical limits for HPET and local APIC timers are - maybe 1 MHz for HPET (if IO APICs are being used - maybe 8192 Hz for PIC) and about "bus_speed / 16" for local APIC. Of course even these "conservative/safe" speeds will depend on how software handles the IRQs - if your IRQ handlers are slow (e.g. do a lot of processing) then you can still have problems.

You can see that different timers and counters have different characteristics. This includes overhead. For example, the RTC periodic IRQ has the highest overhead (as it requires two IO port accesses per IRQ, where IO port accesses for legacy/ISA devices are slow), while the local APIC timers have very little overhead (as they're built into the CPU).

For some things you don't need an IRQ at all (tracking the current time of day, measuring how much CPU time a task used). For some things you do need an IRQ ("sleep()", determining when a task should be pre-empted). For some things you need precision (measuring how much CPU time a task used in nanoseconds), but for some things you don't (finding the current date). For some things you need accuracy (tracking the current time of day) and for other things you don't (measuring how much CPU time a task used).

Basically, different timers and counters have different characteristics, and different parts of your OS have different requirements. The general idea would be for an OS to find out which timers are present (e.g. during boot), then select the best timers for each purpose from this list of detected timers and their characteristics.


Cheers,

Brendan