iPXE
pic8259.h
Go to the documentation of this file.
1 /*
2  * Basic support for controlling the 8259 Programmable Interrupt Controllers.
3  *
4  * Initially written by Michael Brown (mcb30).
5  */
6 
7 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
8 
9 #ifndef PIC8259_H
10 #define PIC8259_H
11 
12 #include <ipxe/io.h>
13 
14 #define IRQ_PIC_CUTOFF 8
15 
16 /* 8259 register locations */
17 #define PIC1_ICW1 0x20
18 #define PIC1_OCW2 0x20
19 #define PIC1_OCW3 0x20
20 #define PIC1_ICR 0x20
21 #define PIC1_IRR 0x20
22 #define PIC1_ISR 0x20
23 #define PIC1_ICW2 0x21
24 #define PIC1_ICW3 0x21
25 #define PIC1_ICW4 0x21
26 #define PIC1_IMR 0x21
27 #define PIC2_ICW1 0xa0
28 #define PIC2_OCW2 0xa0
29 #define PIC2_OCW3 0xa0
30 #define PIC2_ICR 0xa0
31 #define PIC2_IRR 0xa0
32 #define PIC2_ISR 0xa0
33 #define PIC2_ICW2 0xa1
34 #define PIC2_ICW3 0xa1
35 #define PIC2_ICW4 0xa1
36 #define PIC2_IMR 0xa1
37 
38 /* Register command values */
39 #define OCW3_ID 0x08
40 #define OCW3_READ_IRR 0x02
41 #define OCW3_READ_ISR 0x03
42 #define ICR_EOI_NON_SPECIFIC 0x20
43 #define ICR_EOI_NOP 0x40
44 #define ICR_EOI_SPECIFIC 0x60
45 #define ICR_EOI_SET_PRIORITY 0xc0
46 
47 /* Macros to enable/disable IRQs */
48 #define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR )
49 #define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) )
50 
51 /* Macros for acknowledging IRQs */
52 #define ICR_REG( irq ) ( (irq) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR )
53 #define ICR_VALUE( irq ) ( (irq) % IRQ_PIC_CUTOFF )
54 #define CHAINED_IRQ 2
55 
56 /* Utility macros to convert IRQ numbers to INT numbers and INT vectors */
57 #define IRQ_INT( irq ) ( ( ( (irq) - IRQ_PIC_CUTOFF ) ^ 0x70 ) & 0x7f )
58 
59 /* Other constants */
60 #define IRQ_MAX 15
61 #define IRQ_NONE -1U
62 
63 /**
64  * Check if interrupt is enabled
65  *
66  * @v irq Interrupt number
67  * @ret enabled Interrupt is currently enabled
68  */
69 static inline __attribute__ (( always_inline )) int
70 irq_enabled ( unsigned int irq ) {
71  int imr = inb ( IMR_REG ( irq ) );
72  int mask = IMR_BIT ( irq );
73 
74  return ( ( imr & mask ) == 0 );
75 }
76 
77 /**
78  * Enable interrupt
79  *
80  * @v irq Interrupt number
81  * @ret enabled Interrupt was previously enabled
82  */
83 static inline __attribute__ (( always_inline )) int
84 enable_irq ( unsigned int irq ) {
85  int imr = inb ( IMR_REG ( irq ) );
86  int mask = IMR_BIT ( irq );
87 
88  outb ( ( imr & ~mask ), IMR_REG ( irq ) );
89  return ( ( imr & mask ) == 0 );
90 }
91 
92 /**
93  * Disable interrupt
94  *
95  * @v irq Interrupt number
96  * @ret enabled Interrupt was previously enabled
97  */
98 static inline __attribute__ (( always_inline )) int
99 disable_irq ( unsigned int irq ) {
100  int imr = inb ( IMR_REG ( irq ) );
101  int mask = IMR_BIT ( irq );
102 
103  outb ( ( imr | mask ), IMR_REG ( irq ) );
104  return ( ( imr & mask ) == 0 );
105 }
106 
107 /* Function prototypes
108  */
109 void send_eoi ( unsigned int irq );
110 
111 #endif /* PIC8259_H */
iPXE I/O API
#define IMR_BIT(x)
Definition: pic8259.h:49
Definition: sis900.h:27
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void send_eoi(unsigned int irq)
Send End-Of-Interrupt to the PIC.
Definition: pic8259.c:65
uint8_t inb(volatile uint8_t *io_addr)
Read byte from I/O-mapped device.
static __attribute__((always_inline)) int irq_enabled(unsigned int irq)
Check if interrupt is enabled.
Definition: pic8259.h:69
#define outb(data, io_addr)
Definition: io.h:309
#define IMR_REG(x)
Definition: pic8259.h:48