d3f9b87921c18587d677c76f6c17a5847a8b4914
[people/xl0/gpxe.git] / src / arch / i386 / include / pic8259.h
1 /*
2  * Basic support for controlling the 8259 Programmable Interrupt Controllers.
3  *
4  * Initially written by Michael Brown (mcb30).
5  */
6
7 #ifndef PIC8259_H
8 #define PIC8259_H
9
10 /* For segoff_t */
11 #include "realmode.h"
12
13 #define IRQ_PIC_CUTOFF (8)
14
15 /* 8259 register locations */
16 #define PIC1_ICW1 (0x20)
17 #define PIC1_OCW2 (0x20)
18 #define PIC1_OCW3 (0x20)
19 #define PIC1_ICR (0x20)
20 #define PIC1_IRR (0x20)
21 #define PIC1_ISR (0x20)
22 #define PIC1_ICW2 (0x21)
23 #define PIC1_ICW3 (0x21)
24 #define PIC1_ICW4 (0x21)
25 #define PIC1_IMR (0x21)
26 #define PIC2_ICW1 (0xa0)
27 #define PIC2_OCW2 (0xa0)
28 #define PIC2_OCW3 (0xa0)
29 #define PIC2_ICR (0xa0)
30 #define PIC2_IRR (0xa0)
31 #define PIC2_ISR (0xa0)
32 #define PIC2_ICW2 (0xa1)
33 #define PIC2_ICW3 (0xa1)
34 #define PIC2_ICW4 (0xa1)
35 #define PIC2_IMR (0xa1)
36
37 /* Register command values */
38 #define OCW3_ID (0x08)
39 #define OCW3_READ_IRR (0x03)
40 #define OCW3_READ_ISR (0x02)
41 #define ICR_EOI_NON_SPECIFIC (0x20)
42 #define ICR_EOI_NOP (0x40)
43 #define ICR_EOI_SPECIFIC (0x60)
44 #define ICR_EOI_SET_PRIORITY (0xc0)
45
46 /* Macros to enable/disable IRQs */
47 #define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR )
48 #define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) )
49 #define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 )
50 #define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) )
51 #define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) )
52
53 /* Macros for acknowledging IRQs */
54 #define ICR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR )
55 #define ICR_VALUE(x) ( (x) % IRQ_PIC_CUTOFF )
56 #define CHAINED_IRQ 2
57
58 /* Utility macros to convert IRQ numbers to INT numbers and INT vectors  */
59 #define IRQ_INT(x) ( (x)<IRQ_PIC_CUTOFF ? (x)+0x08 : (x)-IRQ_PIC_CUTOFF+0x70 )
60 #define INT_VECTOR(x) ( (segoff_t*) phys_to_virt( 4 * (x) ) )
61 #define IRQ_VECTOR(x) ( INT_VECTOR ( IRQ_INT(x) ) )
62
63 /* Other constants */
64 typedef uint8_t irq_t;
65 #define IRQ_MAX (15)
66 #define IRQ_NONE (0xff)
67
68 /* Function prototypes
69  */
70 int install_irq_handler ( irq_t irq, segoff_t *handler,
71                           uint8_t *previously_enabled,
72                           segoff_t *previous_handler );
73 int remove_irq_handler ( irq_t irq, segoff_t *handler,
74                          uint8_t *previously_enabled,
75                          segoff_t *previous_handler );
76 int install_trivial_irq_handler ( irq_t irq );
77 int remove_trivial_irq_handler ( irq_t irq );
78 int trivial_irq_triggered ( irq_t irq );
79 int copy_trivial_irq_handler ( void *target, size_t target_size );
80 void send_non_specific_eoi ( irq_t irq );
81 void send_specific_eoi ( irq_t irq );
82 void fake_irq ( irq_t irq );
83 #ifdef DEBUG_IRQ
84 void dump_irq_status ( void );
85 #else
86 #define dump_irq_status()
87 #endif
88
89 /* Other code (e.g. undi.c) needs to know the size of the trivial IRQ
90  * handler code, so we put prototypes and the size macro here.
91  */
92 extern void _trivial_irq_handler ( void );
93 extern char _trivial_irq_handler_size[];
94 #define TRIVIAL_IRQ_HANDLER_SIZE FRAGMENT_SIZE(_trivial_irq_handler)
95
96 #endif /* PIC8259_H */