2 * Copyright (c) 2001-2004 Jakub Jermar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #ifndef KERN_ia32_APIC_H_
36 #define KERN_ia32_APIC_H_
38 #include <arch/types.h>
44 #define APIC_ID_COUNT 16
46 /* local APIC macros */
50 /** Delivery modes. */
51 #define DELMOD_FIXED 0x0
52 #define DELMOD_LOWPRI 0x1
53 #define DELMOD_SMI 0x2
55 #define DELMOD_NMI 0x4
56 #define DELMOD_INIT 0x5
57 #define DELMOD_STARTUP 0x6
58 #define DELMOD_EXTINT 0x7
60 /** Destination modes. */
61 #define DESTMOD_PHYS 0x0
62 #define DESTMOD_LOGIC 0x1
65 #define TRIGMOD_EDGE 0x0
66 #define TRIGMOD_LEVEL 0x1
69 #define LEVEL_DEASSERT 0x0
70 #define LEVEL_ASSERT 0x1
72 /** Destination Shorthands. */
73 #define SHORTHAND_NONE 0x0
74 #define SHORTHAND_SELF 0x1
75 #define SHORTHAND_ALL_INCL 0x2
76 #define SHORTHAND_ALL_EXCL 0x3
78 /** Interrupt Input Pin Polarities. */
79 #define POLARITY_HIGH 0x0
80 #define POLARITY_LOW 0x1
82 /** Divide Values. (Bit 2 is always 0) */
89 #define DIVIDE_128 0xa
93 #define TIMER_ONESHOT 0x0
94 #define TIMER_PERIODIC 0x1
96 /** Delivery status. */
97 #define DELIVS_IDLE 0x0
98 #define DELIVS_PENDING 0x1
100 /** Destination masks. */
101 #define DEST_ALL 0xff
103 /** Dest format models. */
104 #define MODEL_FLAT 0xf
105 #define MODEL_CLUSTER 0x0
107 /** Interrupt Command Register. */
108 #define ICRlo (0x300/sizeof(uint32_t))
109 #define ICRhi (0x310/sizeof(uint32_t))
114 uint8_t vector
; /**< Interrupt Vector. */
115 unsigned delmod
: 3; /**< Delivery Mode. */
116 unsigned destmod
: 1; /**< Destination Mode. */
117 unsigned delivs
: 1; /**< Delivery status (RO). */
118 unsigned : 1; /**< Reserved. */
119 unsigned level
: 1; /**< Level. */
120 unsigned trigger_mode
: 1; /**< Trigger Mode. */
121 unsigned : 2; /**< Reserved. */
122 unsigned shorthand
: 2; /**< Destination Shorthand. */
123 unsigned : 12; /**< Reserved. */
124 } __attribute__ ((packed
));
129 unsigned : 24; /**< Reserved. */
130 uint8_t dest
; /**< Destination field. */
131 } __attribute__ ((packed
));
133 } __attribute__ ((packed
));
134 typedef struct icr icr_t
;
136 /* End Of Interrupt. */
137 #define EOI (0x0b0/sizeof(uint32_t))
139 /** Error Status Register. */
140 #define ESR (0x280/sizeof(uint32_t))
145 unsigned send_checksum_error
: 1;
146 unsigned receive_checksum_error
: 1;
147 unsigned send_accept_error
: 1;
148 unsigned receive_accept_error
: 1;
150 unsigned send_illegal_vector
: 1;
151 unsigned received_illegal_vector
: 1;
152 unsigned illegal_register_address
: 1;
154 } __attribute__ ((packed
));
156 typedef union esr esr_t
;
158 /* Task Priority Register */
159 #define TPR (0x080/sizeof(uint32_t))
163 unsigned pri_sc
: 4; /**< Task Priority Sub-Class. */
164 unsigned pri
: 4; /**< Task Priority. */
165 } __attribute__ ((packed
));
167 typedef union tpr tpr_t
;
169 /** Spurious-Interrupt Vector Register. */
170 #define SVR (0x0f0/sizeof(uint32_t))
174 uint8_t vector
; /**< Spurious Vector. */
175 unsigned lapic_enabled
: 1; /**< APIC Software Enable/Disable. */
176 unsigned focus_checking
: 1; /**< Focus Processor Checking. */
177 unsigned : 22; /**< Reserved. */
178 } __attribute__ ((packed
));
180 typedef union svr svr_t
;
182 /** Time Divide Configuration Register. */
183 #define TDCR (0x3e0/sizeof(uint32_t))
187 unsigned div_value
: 4; /**< Divide Value, bit 2 is always 0. */
188 unsigned : 28; /**< Reserved. */
189 } __attribute__ ((packed
));
191 typedef union tdcr tdcr_t
;
193 /* Initial Count Register for Timer */
194 #define ICRT (0x380/sizeof(uint32_t))
196 /* Current Count Register for Timer */
197 #define CCRT (0x390/sizeof(uint32_t))
199 /** LVT Timer register. */
200 #define LVT_Tm (0x320/sizeof(uint32_t))
204 uint8_t vector
; /**< Local Timer Interrupt vector. */
205 unsigned : 4; /**< Reserved. */
206 unsigned delivs
: 1; /**< Delivery status (RO). */
207 unsigned : 3; /**< Reserved. */
208 unsigned masked
: 1; /**< Interrupt Mask. */
209 unsigned mode
: 1; /**< Timer Mode. */
210 unsigned : 14; /**< Reserved. */
211 } __attribute__ ((packed
));
213 typedef union lvt_tm lvt_tm_t
;
215 /** LVT LINT registers. */
216 #define LVT_LINT0 (0x350/sizeof(uint32_t))
217 #define LVT_LINT1 (0x360/sizeof(uint32_t))
221 uint8_t vector
; /**< LINT Interrupt vector. */
222 unsigned delmod
: 3; /**< Delivery Mode. */
223 unsigned : 1; /**< Reserved. */
224 unsigned delivs
: 1; /**< Delivery status (RO). */
225 unsigned intpol
: 1; /**< Interrupt Input Pin Polarity. */
226 unsigned irr
: 1; /**< Remote IRR (RO). */
227 unsigned trigger_mode
: 1; /**< Trigger Mode. */
228 unsigned masked
: 1; /**< Interrupt Mask. */
229 unsigned : 15; /**< Reserved. */
230 } __attribute__ ((packed
));
232 typedef union lvt_lint lvt_lint_t
;
234 /** LVT Error register. */
235 #define LVT_Err (0x370/sizeof(uint32_t))
239 uint8_t vector
; /**< Local Timer Interrupt vector. */
240 unsigned : 4; /**< Reserved. */
241 unsigned delivs
: 1; /**< Delivery status (RO). */
242 unsigned : 3; /**< Reserved. */
243 unsigned masked
: 1; /**< Interrupt Mask. */
244 unsigned : 15; /**< Reserved. */
245 } __attribute__ ((packed
));
247 typedef union lvt_error lvt_error_t
;
249 /** Local APIC ID Register. */
250 #define L_APIC_ID (0x020/sizeof(uint32_t))
254 unsigned : 24; /**< Reserved. */
255 uint8_t apic_id
; /**< Local APIC ID. */
256 } __attribute__ ((packed
));
258 typedef union l_apic_id l_apic_id_t
;
260 /** Local APIC Version Register */
261 #define LAVR (0x030/sizeof(uint32_t))
262 #define LAVR_Mask 0xff
263 #define is_local_apic(x) (((x)&LAVR_Mask&0xf0)==0x1)
264 #define is_82489DX_apic(x) ((((x)&LAVR_Mask&0xf0)==0x0))
265 #define is_local_xapic(x) (((x)&LAVR_Mask)==0x14)
267 /** Logical Destination Register. */
268 #define LDR (0x0d0/sizeof(uint32_t))
272 unsigned : 24; /**< Reserved. */
273 uint8_t id
; /**< Logical APIC ID. */
274 } __attribute__ ((packed
));
276 typedef union ldr ldr_t
;
278 /** Destination Format Register. */
279 #define DFR (0x0e0/sizeof(uint32_t))
283 unsigned : 28; /**< Reserved, all ones. */
284 unsigned model
: 4; /**< Model. */
285 } __attribute__ ((packed
));
287 typedef union dfr dfr_t
;
290 #define IOREGSEL (0x00/sizeof(uint32_t))
291 #define IOWIN (0x10/sizeof(uint32_t))
293 #define IOAPICID 0x00
294 #define IOAPICVER 0x01
295 #define IOAPICARB 0x02
296 #define IOREDTBL 0x10
298 /** I/O Register Select Register. */
302 uint8_t reg_addr
; /**< APIC Register Address. */
303 unsigned : 24; /**< Reserved. */
304 } __attribute__ ((packed
));
306 typedef union io_regsel io_regsel_t
;
308 /** I/O Redirection Register. */
309 struct io_redirection_reg
{
313 uint8_t intvec
; /**< Interrupt Vector. */
314 unsigned delmod
: 3; /**< Delivery Mode. */
315 unsigned destmod
: 1; /**< Destination mode. */
316 unsigned delivs
: 1; /**< Delivery status (RO). */
317 unsigned intpol
: 1; /**< Interrupt Input Pin Polarity. */
318 unsigned irr
: 1; /**< Remote IRR (RO). */
319 unsigned trigger_mode
: 1; /**< Trigger Mode. */
320 unsigned masked
: 1; /**< Interrupt Mask. */
321 unsigned : 15; /**< Reserved. */
322 } __attribute__ ((packed
));
327 unsigned : 24; /**< Reserved. */
328 uint8_t dest
: 8; /**< Destination Field. */
329 } __attribute__ ((packed
));
332 } __attribute__ ((packed
));
333 typedef struct io_redirection_reg io_redirection_reg_t
;
336 /** IO APIC Identification Register. */
340 unsigned : 24; /**< Reserved. */
341 unsigned apic_id
: 4; /**< IO APIC ID. */
342 unsigned : 4; /**< Reserved. */
343 } __attribute__ ((packed
));
345 typedef union io_apic_id io_apic_id_t
;
347 extern volatile uint32_t *l_apic
;
348 extern volatile uint32_t *io_apic
;
350 extern uint32_t apic_id_mask
;
352 extern void apic_init(void);
354 extern void l_apic_init(void);
355 extern void l_apic_eoi(void);
356 extern int l_apic_broadcast_custom_ipi(uint8_t vector
);
357 extern int l_apic_send_init_ipi(uint8_t apicid
);
358 extern void l_apic_debug(void);
359 extern uint8_t l_apic_id(void);
361 extern uint32_t io_apic_read(uint8_t address
);
362 extern void io_apic_write(uint8_t address
, uint32_t x
);
363 extern void io_apic_change_ioredtbl(int pin
, int dest
, uint8_t v
, int flags
);
364 extern void io_apic_disable_irqs(uint16_t irqmask
);
365 extern void io_apic_enable_irqs(uint16_t irqmask
);