xref: /minix3/minix/kernel/arch/i386/apic.h (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #ifndef __APIC_H__
2*433d6423SLionel Sambuc #define __APIC_H__
3*433d6423SLionel Sambuc 
4*433d6423SLionel Sambuc #define APIC_ENABLE		0x100
5*433d6423SLionel Sambuc #define APIC_FOCUS_DISABLED	(1 << 9)
6*433d6423SLionel Sambuc #define APIC_SIV		0xFF
7*433d6423SLionel Sambuc 
8*433d6423SLionel Sambuc #define APIC_TDCR_2	0x00
9*433d6423SLionel Sambuc #define APIC_TDCR_4	0x01
10*433d6423SLionel Sambuc #define APIC_TDCR_8	0x02
11*433d6423SLionel Sambuc #define APIC_TDCR_16	0x03
12*433d6423SLionel Sambuc #define APIC_TDCR_32	0x08
13*433d6423SLionel Sambuc #define APIC_TDCR_64	0x09
14*433d6423SLionel Sambuc #define APIC_TDCR_128	0x0a
15*433d6423SLionel Sambuc #define APIC_TDCR_1	0x0b
16*433d6423SLionel Sambuc 
17*433d6423SLionel Sambuc #define APIC_LVTT_VECTOR_MASK	0x000000FF
18*433d6423SLionel Sambuc #define APIC_LVTT_DS_PENDING	(1 << 12)
19*433d6423SLionel Sambuc #define APIC_LVTT_MASK		(1 << 16)
20*433d6423SLionel Sambuc #define APIC_LVTT_TM		(1 << 17)
21*433d6423SLionel Sambuc 
22*433d6423SLionel Sambuc #define APIC_LVT_IIPP_MASK	0x00002000
23*433d6423SLionel Sambuc #define APIC_LVT_IIPP_AH	0x00002000
24*433d6423SLionel Sambuc #define APIC_LVT_IIPP_AL	0x00000000
25*433d6423SLionel Sambuc 
26*433d6423SLionel Sambuc #define IOAPIC_REGSEL		0x0
27*433d6423SLionel Sambuc #define IOAPIC_RW		0x10
28*433d6423SLionel Sambuc 
29*433d6423SLionel Sambuc #define APIC_ICR_DM_MASK		0x00000700
30*433d6423SLionel Sambuc #define APIC_ICR_VECTOR			APIC_LVTT_VECTOR_MASK
31*433d6423SLionel Sambuc #define APIC_ICR_DM_FIXED		(0 << 8)
32*433d6423SLionel Sambuc #define APIC_ICR_DM_LOWEST_PRIORITY	(1 << 8)
33*433d6423SLionel Sambuc #define APIC_ICR_DM_SMI			(2 << 8)
34*433d6423SLionel Sambuc #define APIC_ICR_DM_RESERVED		(3 << 8)
35*433d6423SLionel Sambuc #define APIC_ICR_DM_NMI			(4 << 8)
36*433d6423SLionel Sambuc #define APIC_ICR_DM_INIT		(5 << 8)
37*433d6423SLionel Sambuc #define APIC_ICR_DM_STARTUP		(6 << 8)
38*433d6423SLionel Sambuc #define APIC_ICR_DM_EXTINT		(7 << 8)
39*433d6423SLionel Sambuc 
40*433d6423SLionel Sambuc #define APIC_ICR_DM_PHYSICAL		(0 << 11)
41*433d6423SLionel Sambuc #define APIC_ICR_DM_LOGICAL		(1 << 11)
42*433d6423SLionel Sambuc 
43*433d6423SLionel Sambuc #define APIC_ICR_DELIVERY_PENDING	(1 << 12)
44*433d6423SLionel Sambuc 
45*433d6423SLionel Sambuc #define APIC_ICR_INT_POLARITY		(1 << 13)
46*433d6423SLionel Sambuc 
47*433d6423SLionel Sambuc #define APIC_ICR_LEVEL_ASSERT		(1 << 14)
48*433d6423SLionel Sambuc #define APIC_ICR_LEVEL_DEASSERT		(0 << 14)
49*433d6423SLionel Sambuc 
50*433d6423SLionel Sambuc #define APIC_ICR_TRIGGER		(1 << 15)
51*433d6423SLionel Sambuc 
52*433d6423SLionel Sambuc #define APIC_ICR_INT_MASK		(1 << 16)
53*433d6423SLionel Sambuc 
54*433d6423SLionel Sambuc #define APIC_ICR_DEST_FIELD		(0 << 18)
55*433d6423SLionel Sambuc #define APIC_ICR_DEST_SELF		(1 << 18)
56*433d6423SLionel Sambuc #define APIC_ICR_DEST_ALL		(2 << 18)
57*433d6423SLionel Sambuc #define APIC_ICR_DEST_ALL_BUT_SELF	(3 << 18)
58*433d6423SLionel Sambuc 
59*433d6423SLionel Sambuc #define LOCAL_APIC_DEF_ADDR	0xfee00000 /* default local apic address */
60*433d6423SLionel Sambuc #define IO_APIC_DEF_ADDR	0xfec00000 /* default i/o apic address */
61*433d6423SLionel Sambuc 
62*433d6423SLionel Sambuc #define LAPIC_ID	(lapic_addr + 0x020)
63*433d6423SLionel Sambuc #define LAPIC_VERSION	(lapic_addr + 0x030)
64*433d6423SLionel Sambuc #define LAPIC_TPR	(lapic_addr + 0x080)
65*433d6423SLionel Sambuc #define LAPIC_EOI	(lapic_addr + 0x0b0)
66*433d6423SLionel Sambuc #define LAPIC_LDR	(lapic_addr + 0x0d0)
67*433d6423SLionel Sambuc #define LAPIC_DFR	(lapic_addr + 0x0e0)
68*433d6423SLionel Sambuc #define LAPIC_SIVR	(lapic_addr + 0x0f0)
69*433d6423SLionel Sambuc #define LAPIC_ISR	(lapic_addr + 0x100)
70*433d6423SLionel Sambuc #define LAPIC_TMR	(lapic_addr + 0x180)
71*433d6423SLionel Sambuc #define LAPIC_IRR	(lapic_addr + 0x200)
72*433d6423SLionel Sambuc #define LAPIC_ESR	(lapic_addr + 0x280)
73*433d6423SLionel Sambuc #define LAPIC_ICR1	(lapic_addr + 0x300)
74*433d6423SLionel Sambuc #define LAPIC_ICR2	(lapic_addr + 0x310)
75*433d6423SLionel Sambuc #define LAPIC_LVTTR	(lapic_addr + 0x320)
76*433d6423SLionel Sambuc #define LAPIC_LVTTMR	(lapic_addr + 0x330)
77*433d6423SLionel Sambuc #define LAPIC_LVTPCR	(lapic_addr + 0x340)
78*433d6423SLionel Sambuc #define LAPIC_LINT0	(lapic_addr + 0x350)
79*433d6423SLionel Sambuc #define LAPIC_LINT1	(lapic_addr + 0x360)
80*433d6423SLionel Sambuc #define LAPIC_LVTER	(lapic_addr + 0x370)
81*433d6423SLionel Sambuc #define LAPIC_TIMER_ICR	(lapic_addr + 0x380)
82*433d6423SLionel Sambuc #define LAPIC_TIMER_CCR	(lapic_addr + 0x390)
83*433d6423SLionel Sambuc #define LAPIC_TIMER_DCR	(lapic_addr + 0x3e0)
84*433d6423SLionel Sambuc 
85*433d6423SLionel Sambuc #define IOAPIC_ID			0x0
86*433d6423SLionel Sambuc #define IOAPIC_VERSION			0x1
87*433d6423SLionel Sambuc #define IOAPIC_ARB			0x2
88*433d6423SLionel Sambuc #define IOAPIC_REDIR_TABLE		0x10
89*433d6423SLionel Sambuc 
90*433d6423SLionel Sambuc #define APIC_TIMER_INT_VECTOR		0xf0
91*433d6423SLionel Sambuc #define APIC_SMP_SCHED_PROC_VECTOR	0xf1
92*433d6423SLionel Sambuc #define APIC_SMP_CPU_HALT_VECTOR	0xf2
93*433d6423SLionel Sambuc #define APIC_ERROR_INT_VECTOR		0xfe
94*433d6423SLionel Sambuc #define APIC_SPURIOUS_INT_VECTOR	0xff
95*433d6423SLionel Sambuc 
96*433d6423SLionel Sambuc #ifndef __ASSEMBLY__
97*433d6423SLionel Sambuc 
98*433d6423SLionel Sambuc #include "kernel/kernel.h"
99*433d6423SLionel Sambuc 
100*433d6423SLionel Sambuc EXTERN vir_bytes lapic_addr;
101*433d6423SLionel Sambuc EXTERN vir_bytes lapic_eoi_addr;
102*433d6423SLionel Sambuc EXTERN int ioapic_enabled;
103*433d6423SLionel Sambuc EXTERN int bsp_lapic_id;
104*433d6423SLionel Sambuc 
105*433d6423SLionel Sambuc #define MAX_NR_IOAPICS		32
106*433d6423SLionel Sambuc #define MAX_IOAPIC_IRQS		64
107*433d6423SLionel Sambuc 
108*433d6423SLionel Sambuc EXTERN int ioapic_enabled;
109*433d6423SLionel Sambuc 
110*433d6423SLionel Sambuc struct io_apic {
111*433d6423SLionel Sambuc 	unsigned	id;
112*433d6423SLionel Sambuc 	vir_bytes	addr; /* presently used address */
113*433d6423SLionel Sambuc 	phys_bytes	paddr; /* where is it in phys space */
114*433d6423SLionel Sambuc 	vir_bytes	vaddr; /* address after paging is on */
115*433d6423SLionel Sambuc 	unsigned	pins;
116*433d6423SLionel Sambuc 	unsigned	gsi_base;
117*433d6423SLionel Sambuc };
118*433d6423SLionel Sambuc 
119*433d6423SLionel Sambuc EXTERN struct io_apic io_apic[MAX_NR_IOAPICS];
120*433d6423SLionel Sambuc EXTERN unsigned nioapics;
121*433d6423SLionel Sambuc 
122*433d6423SLionel Sambuc EXTERN u32_t lapic_addr_vaddr; /* we remember the virtual address here until we
123*433d6423SLionel Sambuc 				  switch to paging */
124*433d6423SLionel Sambuc 
125*433d6423SLionel Sambuc int lapic_enable(unsigned cpu);
126*433d6423SLionel Sambuc void ioapic_unmask_irq(unsigned irq);
127*433d6423SLionel Sambuc void ioapic_mask_irq(unsigned irq);
128*433d6423SLionel Sambuc void ioapic_reset_pic(void);
129*433d6423SLionel Sambuc 
130*433d6423SLionel Sambuc EXTERN int ioapic_enabled;
131*433d6423SLionel Sambuc EXTERN unsigned nioapics;
132*433d6423SLionel Sambuc 
133*433d6423SLionel Sambuc void lapic_microsec_sleep(unsigned count);
134*433d6423SLionel Sambuc void ioapic_disable_irqs(u32_t irqs);
135*433d6423SLionel Sambuc void ioapic_enable_irqs(u32_t irqs);
136*433d6423SLionel Sambuc 
137*433d6423SLionel Sambuc int lapic_enable(unsigned cpu);
138*433d6423SLionel Sambuc void lapic_disable(void);
139*433d6423SLionel Sambuc 
140*433d6423SLionel Sambuc void ioapic_disable_all(void);
141*433d6423SLionel Sambuc int ioapic_enable_all(void);
142*433d6423SLionel Sambuc 
143*433d6423SLionel Sambuc int detect_ioapics(void);
144*433d6423SLionel Sambuc void apic_idt_init(int reset);
145*433d6423SLionel Sambuc 
146*433d6423SLionel Sambuc #ifdef CONFIG_SMP
147*433d6423SLionel Sambuc int apic_send_startup_ipi(unsigned cpu, phys_bytes trampoline);
148*433d6423SLionel Sambuc int apic_send_init_ipi(unsigned cpu, phys_bytes trampoline);
149*433d6423SLionel Sambuc unsigned int apicid(void);
150*433d6423SLionel Sambuc void ioapic_set_id(u32_t addr, unsigned int id);
151*433d6423SLionel Sambuc #else
152*433d6423SLionel Sambuc int apic_single_cpu_init(void);
153*433d6423SLionel Sambuc #endif
154*433d6423SLionel Sambuc 
155*433d6423SLionel Sambuc void lapic_set_timer_periodic(const unsigned freq);
156*433d6423SLionel Sambuc void lapic_set_timer_one_shot(const u32_t value);
157*433d6423SLionel Sambuc void lapic_stop_timer(void);
158*433d6423SLionel Sambuc void lapic_restart_timer(void);
159*433d6423SLionel Sambuc 
160*433d6423SLionel Sambuc void ioapic_set_irq(unsigned irq);
161*433d6423SLionel Sambuc void ioapic_unset_irq(unsigned irq);
162*433d6423SLionel Sambuc 
163*433d6423SLionel Sambuc /* signal the end of interrupt handler to apic */
164*433d6423SLionel Sambuc #define apic_eoi() do { *((volatile u32_t *) lapic_eoi_addr) = 0; } while(0)
165*433d6423SLionel Sambuc 
166*433d6423SLionel Sambuc void ioapic_eoi(int irq);
167*433d6423SLionel Sambuc 
168*433d6423SLionel Sambuc void dump_apic_irq_state(void);
169*433d6423SLionel Sambuc 
170*433d6423SLionel Sambuc void apic_send_ipi(unsigned vector, unsigned cpu, int type);
171*433d6423SLionel Sambuc 
172*433d6423SLionel Sambuc void apic_ipi_sched_intr(void);
173*433d6423SLionel Sambuc void apic_ipi_halt_intr(void);
174*433d6423SLionel Sambuc 
175*433d6423SLionel Sambuc #define APIC_IPI_DEST			0
176*433d6423SLionel Sambuc #define APIC_IPI_SELF			1
177*433d6423SLionel Sambuc #define APIC_IPI_TO_ALL			2
178*433d6423SLionel Sambuc #define APIC_IPI_TO_ALL_BUT_SELF	3
179*433d6423SLionel Sambuc 
180*433d6423SLionel Sambuc #define apic_send_ipi_single(vector,cpu) \
181*433d6423SLionel Sambuc 	apic_send_ipi(vector, cpu, APIC_IPI_DEST);
182*433d6423SLionel Sambuc #define apic_send_ipi_self(vector) \
183*433d6423SLionel Sambuc 	apic_send_ipi(vector, 0, APIC_IPI_SELF)
184*433d6423SLionel Sambuc #define apic_send_ipi_all(vector) \
185*433d6423SLionel Sambuc 	apic_send_ipi (vector, 0, APIC_IPI_TO_ALL)
186*433d6423SLionel Sambuc #define apic_send_ipi_allbutself(vector) \
187*433d6423SLionel Sambuc 	apic_send_ipi (vector, 0, APIC_IPI_TO_ALL_BUT_SELF);
188*433d6423SLionel Sambuc 
189*433d6423SLionel Sambuc 
190*433d6423SLionel Sambuc #include <minix/cpufeature.h>
191*433d6423SLionel Sambuc 
192*433d6423SLionel Sambuc #define cpu_feature_apic_on_chip() _cpufeature(_CPUF_I386_APIC_ON_CHIP)
193*433d6423SLionel Sambuc 
194*433d6423SLionel Sambuc #define lapic_read(what)	(*((volatile u32_t *)((what))))
195*433d6423SLionel Sambuc #define lapic_write(what, data)	do {			\
196*433d6423SLionel Sambuc 	(*((volatile u32_t *)((what)))) = data;		\
197*433d6423SLionel Sambuc } while(0)
198*433d6423SLionel Sambuc 
199*433d6423SLionel Sambuc #endif /* __ASSEMBLY__ */
200*433d6423SLionel Sambuc 
201*433d6423SLionel Sambuc #endif /* __APIC_H__ */
202