x86_pic.h
6.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* The IRQ handler of x86 boards.
*
* @ingroup x86-irq
* @{
* @file
* @author René Kijewski <rene.kijewski@fu-berlin.de>
*/
#ifndef X86_PIC_H
#define X86_PIC_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize the Programmable Interrupt Controller.
*
* This function is called during initialization by x86_startup().
* You must not call this function on your own accord.
*/
void x86_init_pic(void);
#define X86_IRQ_COUNT (0x10) /**< Number of IRQ lines */
/**
* @brief Offset of the IRQ master in the interrupt numbers.
*
* x86_interrupts.c expects this value to be `0x20`. Do not change.
*/
#define PIC_MASTER_INTERRUPT_BASE (0x20)
/**
* @brief Offset of the IRQ slave in the interrupt numbers.
*
* The whole IRQ subsystem expects the IRQ slave numbers to come immediately after the master.
*/
#define PIC_SLAVE_INTERRUPT_BASE (PIC_MASTER_INTERRUPT_BASE + 8)
#define PIC_MASTER (0x20)
#define PIC_SLAVE (0xA0)
#define PIC_COMMAND (0x00)
#define PIC_DATA (0x01)
#define PIC_IMR (0x01)
#define PIC_EOI 0x20 /**< End-of-interrupt command code */
#define PIC_READ_IRR 0x0a /**< OCW3 irq ready next CMD read */
#define PIC_READ_ISR 0x0b /**< OCW3 irq service next CMD read */
#define PIC_ICW1_ICW4 (0x01) /**< ICW4 (not) needed */
#define PIC_ICW1_SINGLE (0x02) /**< Single (cascade) mode */
#define PIC_ICW1_INTERVAL4 (0x04) /**< Call address interval 4 (8) */
#define PIC_ICW1_LEVEL (0x08) /**< Level triggered (edge) mode */
#define PIC_ICW1_INIT (0x10) /**< Initialization - required! */
#define PIC_ICW4_8086 (0x01) /**< 8086/88 (MCS-80/85) mode */
#define PIC_ICW4_AUTO (0x02) /**< Auto (normal) EOI */
#define PIC_ICW4_BUF_SLAVE (0x08) /**< Buffered mode/slave */
#define PIC_ICW4_BUF_MASTER (0x0C) /**< Buffered mode/master */
#define PIC_ICW4_SFNM (0x10) /**< Special fully nested (not) */
#define PIC_NUM_PIT (0x0) /**< IRQ line of the Programmable Interrupt Controller **/
#define PIC_NUM_KEYBOARD_CONTROLLER_1 (0x1) /**< IRQ line of the first PS/2 port **/
#define PIC_NUM_SLAVE (0x2) /**< not a valid IRQ line! */
#define PIC_NUM_RS232_2_4 (0x3) /**< IRQ line of COM 2+4 **/
#define PIC_NUM_RS232_1_3 (0x4) /**< IRQ line of COM 1+2 **/
#define PIC_NUM_LPT2 (0x5) /**< IRQ line of the secondary printer or soundcard (available for PCI) **/
#define PIC_NUM_FLOPPY (0x6) /**< IRQ line of the floppy drive. **/
#define PIC_NUM_LPT1 (0x7) /**< IRQ line of the parallel port (available for PCI) **/
#define PIC_NUM_RTC (0x8) /**< IRQ line of the Real Time Clock **/
#define PIC_NUM_9 (0x9) /**< Free to use IRQ line (available for PCI) **/
#define PIC_NUM_ATA_4 (0xa) /**< Free to use IRQ line (available for PCI) **/
#define PIC_NUM_ATA_3 (0xb) /**< Free to use IRQ line (available for PCI) **/
#define PIC_NUM_KEYBOARD_CONTROLLER_2 (0xc) /**< IRQ line of the second PS/2 port **/
#define PIC_NUM_FPU (0xd) /**< not a valid IRQ line! */
#define PIC_NUM_ATA_1 (0xe) /**< IRQ line of the primary IDE controller **/
#define PIC_NUM_ATA_2 (0xf) /**< IRQ line of the secondary IDQ controller **/
#define PIC_MASK_PIT (1 << PIC_NUM_PIT)
#define PIC_MASK_KEYBOARD_CONTROLLER_1 (1 << PIC_NUM_KEYBOARD_CONTROLLER_1)
#define PIC_MASK_SLAVE (1 << PIC_NUM_SLAVE)
#define PIC_MASK_RS232_2_4 (1 << PIC_NUM_RS232_2_4)
#define PIC_MASK_RS232_1_3 (1 << PIC_NUM_RS232_1_3)
#define PIC_MASK_LPT2 (1 << PIC_NUM_LPT2)
#define PIC_MASK_FLOPPY (1 << PIC_NUM_FLOPPY)
#define PIC_MASK_LPT1 (1 << PIC_NUM_LPT1)
#define PIC_MASK_RTC (1 << PIC_NUM_RTC)
#define PIC_MASK_9 (1 << PIC_NUM_9)
#define PIC_MASK_ATA_4 (1 << PIC_NUM_ATA_4)
#define PIC_MASK_ATA_3 (1 << PIC_NUM_ATA_3)
#define PIC_MASK_KEYBOARD_CONTROLLER_2 (1 << PIC_NUM_KEYBOARD_CONTROLLER_2)
#define PIC_MASK_FPU (1 << PIC_NUM_FPU)
#define PIC_MASK_ATA_1 (1 << PIC_NUM_ATA_1)
#define PIC_MASK_ATA_2 (1 << PIC_NUM_ATA_2)
/**
* @brief Callback handler if there was an interrupt on this IRQ line.
* @param irq_num IRQ line in question.
*
* This callback is called out of the interrupt handler (irq_is_in() == true).
* Lengthy operations should be handled in a dedicated thread; use msg_send_int().
* You must no enable interrupt inside the handler.
*/
typedef void (*x86_irq_handler_t)(uint8_t irq_num);
/**
* @brief Set callback function for an IRQ line.
* @param handler The callback function, or NULL to do nothing.
*
* Setting a handler does not enable the interrupt.
* Use x86_pic_enable_irq() or x86_pic_disable_irq() accordingly.
*
* This function must only be called with interrupts disabled.
*
* Beware on unsetting interrupt handlers:
* The PIC default handler will still send an EOI.
* Especially the keyboard controller does not like it,
* if it is told that everything was done but it wasn't.
* A raised #X86_INT_GP might be the least of your problems.
*/
void x86_pic_set_handler(unsigned irq, x86_irq_handler_t handler);
/**
* @brief Set the enabled IRQs
*
* Beware: this is the exact opposite of masking IRQs.
*
* This function should only be called by other subsystems like the PCI subsystem.
*/
void x86_pic_set_enabled_irqs(uint16_t mask);
/**
* @brief Enable (unmask) an IRQ
*
* This function should only be called by other subsystems like the PCI subsystem.
*/
void x86_pic_enable_irq(unsigned num);
/**
* @brief Disable (mask) an IRQ
*
* This function should only be called by other subsystems like the PCI subsystem.
*/
void x86_pic_disable_irq(unsigned num);
#ifdef __cplusplus
}
#endif
#endif /* X86_PIC_H */
/** @} */