CS318 - Pintos
Pintos source browser for JHU CS318 course
pit.c
Go to the documentation of this file.
1 #include "devices/pit.h"
2 #include <debug.h>
3 #include <stdint.h>
4 #include "threads/interrupt.h"
5 #include "threads/io.h"
6 
7 /** Interface to 8254 Programmable Interrupt Timer (PIT).
8  Refer to [8254] for details. */
9 
10 /** 8254 registers. */
11 #define PIT_PORT_CONTROL 0x43 /**< Control port. */
12 #define PIT_PORT_COUNTER(CHANNEL) (0x40 + (CHANNEL)) /**< Counter port. */
13 
14 /** PIT cycles per second. */
15 #define PIT_HZ 1193180
16 
17 /** Configure the given CHANNEL in the PIT. In a PC, the PIT's
18  three output channels are hooked up like this:
19 
20  - Channel 0 is connected to interrupt line 0, so that it can
21  be used as a periodic timer interrupt, as implemented in
22  Pintos in devices/timer.c.
23 
24  - Channel 1 is used for dynamic RAM refresh (in older PCs).
25  No good can come of messing with this.
26 
27  - Channel 2 is connected to the PC speaker, so that it can
28  be used to play a tone, as implemented in Pintos in
29  devices/speaker.c.
30 
31  MODE specifies the form of output:
32 
33  - Mode 2 is a periodic pulse: the channel's output is 1 for
34  most of the period, but drops to 0 briefly toward the end
35  of the period. This is useful for hooking up to an
36  interrupt controller to generate a periodic interrupt.
37 
38  - Mode 3 is a square wave: for the first half of the period
39  it is 1, for the second half it is 0. This is useful for
40  generating a tone on a speaker.
41 
42  - Other modes are less useful.
43 
44  FREQUENCY is the number of periods per second, in Hz. */
45 void
46 pit_configure_channel (int channel, int mode, int frequency)
47 {
48  uint16_t count;
49  enum intr_level old_level;
50 
51  ASSERT (channel == 0 || channel == 2);
52  ASSERT (mode == 2 || mode == 3);
53 
54  /* Convert FREQUENCY to a PIT counter value. The PIT has a
55  clock that runs at PIT_HZ cycles per second. We must
56  translate FREQUENCY into a number of these cycles. */
57  if (frequency < 19)
58  {
59  /* Frequency is too low: the quotient would overflow the
60  16-bit counter. Force it to 0, which the PIT treats as
61  65536, the highest possible count. This yields a 18.2
62  Hz timer, approximately. */
63  count = 0;
64  }
65  else if (frequency > PIT_HZ)
66  {
67  /* Frequency is too high: the quotient would underflow to
68  0, which the PIT would interpret as 65536. A count of 1
69  is illegal in mode 2, so we force it to 2, which yields
70  a 596.590 kHz timer, approximately. (This timer rate is
71  probably too fast to be useful anyhow.) */
72  count = 2;
73  }
74  else
75  count = (PIT_HZ + frequency / 2) / frequency;
76 
77  /* Configure the PIT mode and load its counters. */
78  old_level = intr_disable ();
79  outb (PIT_PORT_CONTROL, (channel << 6) | 0x30 | (mode << 1));
80  outb (PIT_PORT_COUNTER (channel), count);
81  outb (PIT_PORT_COUNTER (channel), count >> 8);
82  intr_set_level (old_level);
83 }
mode
static enum @0 mode
Transmission mode.
intr_level
intr_level
Interrupts on or off?
Definition: interrupt.h:8
intr_set_level
enum intr_level intr_set_level(enum intr_level level)
Enables or disables interrupts as specified by LEVEL and returns the previous interrupt status.
Definition: interrupt.c:81
uint16_t
unsigned short int uint16_t
Definition: stdint.h:23
pit.h
interrupt.h
pit_configure_channel
void pit_configure_channel(int channel, int mode, int frequency)
Configure the given CHANNEL in the PIT.
Definition: pit.c:46
PIT_HZ
#define PIT_HZ
PIT cycles per second.
Definition: pit.c:15
stdint.h
intr_disable
enum intr_level intr_disable(void)
Disables interrupts and returns the previous interrupt status.
Definition: interrupt.c:104
ASSERT
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
outb
static void outb(uint16_t port, uint8_t data)
Writes byte DATA to PORT.
Definition: io.h:66
PIT_PORT_CONTROL
#define PIT_PORT_CONTROL
Interface to 8254 Programmable Interrupt Timer (PIT).
Definition: pit.c:11
io.h
PIT_PORT_COUNTER
#define PIT_PORT_COUNTER(CHANNEL)
Counter port.
Definition: pit.c:12
channel
An ATA channel (aka controller).
Definition: ide.c:64
debug.h