80 lines
2.0 KiB
ArmAsm
80 lines
2.0 KiB
ArmAsm
/*
|
|
# PIT
|
|
|
|
Programmable interrupt timer.
|
|
|
|
Expected output: "a\n" is printed infinitely many times.
|
|
|
|
Generates periodic interrupts (or sound!) with a given frequency to IRQ0,
|
|
which on real mode maps to interrupt 8 by default.
|
|
|
|
Major application: interrupt the running process
|
|
to allow the OS to schedule processes.
|
|
|
|
Read this *now*: http://wiki.osdev.org/PIT
|
|
|
|
Has 3 channels that can generate 3 independent signals
|
|
|
|
- channel 0 at port 0x40: generates interrupts
|
|
- channel 1 at port 0x41: not to be used for some reason
|
|
- channel 2 at port 0x42: linked to the speaker to generate sounds
|
|
|
|
Port 0x43 is used to control signal properties except frequency
|
|
(which goes in the channel ports) for the 3 channels.
|
|
See osdev article for details.
|
|
|
|
## Frequency
|
|
|
|
## 1193181
|
|
|
|
We don't control the frequency of the PIT directly,
|
|
which is fixed at 1193181.
|
|
|
|
Instead, we control a frequency divisor.
|
|
This is an well known type of discrete electronic circuit:
|
|
https://en.wikipedia.org/wiki/Frequency_divider
|
|
|
|
1193181 has 2 occurrences on Linux 4.2.
|
|
|
|
The frequency comes from historical reasons to reuse television hardware.
|
|
|
|
## Maskable interrupts
|
|
|
|
## sti
|
|
|
|
http://wiki.osdev.org/Non_Maskable_Interrupt
|
|
|
|
Interrupts generated by the CPU from 0 - 31 are not maskable: they generate interrupts even with `cli`.
|
|
|
|
Those from the PIC are maskable however.
|
|
|
|
QEMU generates many maskable interrupts by default. TODO: where do they come from? What are they excatly?
|
|
|
|
If we don't set a handler, we usually triple-fault and the machine restarts, thus going into a restart loop.
|
|
|
|
## Bibliography
|
|
|
|
- https://en.wikipedia.org/wiki/Intel_8253 That is the circuit ID for the PIT.
|
|
- http://kernelx.weebly.com/programmable-interval-timer.html
|
|
|
|
TODO learn to turn off the PIT after some iterations
|
|
*/
|
|
|
|
#include "common.h"
|
|
|
|
BEGIN
|
|
IVT_PIT_SETUP
|
|
PIT_GENERATE_FREQUENCY
|
|
PIT_SET_MIN_FREQ
|
|
/* If we comment out sti, nothing happens, because the PIT interrupts are maskable. */
|
|
sti
|
|
jmp .
|
|
handler:
|
|
cli
|
|
PUTC $'a
|
|
PUTC $'\n
|
|
/* EOI: it will not fire again unless we reset it. */
|
|
PIC_EOI
|
|
sti
|
|
iret
|