1 /*-
2  * Copyright (c) 1996, by Peter Wemm and Steve Passe
3  * Copyright (c) 2017-2022 Intel Corporation.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. The name of the developer may NOT be used to endorse or promote products
11  *    derived from this software without specific prior written permission.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27 
28 #ifndef APICREG_H
29 #define APICREG_H
30 
31 #include <asm/page.h>
32 
33 /*
34  * Local && I/O APIC definitions.
35  */
36 
37 /******************************************************************************
38  * global defines, etc.
39  */
40 
41 
42 /******************************************************************************
43  * LOCAL APIC structure
44  */
45 struct lapic_reg {
46 	uint32_t v;
47 	uint32_t pad[3];
48 };
49 
50 struct lapic_regs {			 /*OFFSET(Hex)*/
51 	struct lapic_reg	rsv0[2];
52 	struct lapic_reg	id;	  /*020*/
53 	struct lapic_reg	version;  /*030*/
54 	struct lapic_reg	rsv1[4];
55 	struct lapic_reg	tpr;	  /*080*/
56 	struct lapic_reg	apr;	  /*090*/
57 	struct lapic_reg	ppr;	  /*0A0*/
58 	struct lapic_reg	eoi;	  /*0B0*/
59 	struct lapic_reg	rrd;	  /*0C0*/
60 	struct lapic_reg	ldr;	  /*0D0*/
61 	struct lapic_reg	dfr;	  /*0EO*/
62 	struct lapic_reg	svr;	  /*0F0*/
63 	struct lapic_reg	isr[8];   /*100 -- 170*/
64 	struct lapic_reg	tmr[8];	  /*180 -- 1F0*/
65 	struct lapic_reg	irr[8];	  /*200 -- 270*/
66 	struct lapic_reg	esr;	  /*280*/
67 	struct lapic_reg	rsv2[6];
68 	struct lapic_reg	lvt_cmci; /*2F0*/
69 	struct lapic_reg	icr_lo;   /*300*/
70 	struct lapic_reg	icr_hi;	  /*310*/
71 	struct lapic_reg	lvt[6];	  /*320 -- 370*/
72 	struct lapic_reg	icr_timer;/*380*/
73 	struct lapic_reg	ccr_timer;/*390*/
74 	struct lapic_reg	rsv3[4];
75 	struct lapic_reg	dcr_timer;/*3E0*/
76 	struct lapic_reg	self_ipi; /*3F0*/
77 
78 	/*roundup sizeof current struct to 4KB*/
79 	struct lapic_reg	rsv5[192]; /*400 -- FF0*/
80 } __aligned(PAGE_SIZE);
81 
82 enum LAPIC_REGISTERS {
83 	LAPIC_ID	= 0x2,
84 	LAPIC_VERSION	= 0x3,
85 	LAPIC_TPR	= 0x8,
86 	LAPIC_APR	= 0x9,
87 	LAPIC_PPR	= 0xa,
88 	LAPIC_EOI	= 0xb,
89 	LAPIC_LDR	= 0xd,
90 	LAPIC_DFR	= 0xe, /* Not in x2APIC */
91 	LAPIC_SVR	= 0xf,
92 	LAPIC_ISR0	= 0x10,
93 	LAPIC_ISR1	= 0x11,
94 	LAPIC_ISR2	= 0x12,
95 	LAPIC_ISR3	= 0x13,
96 	LAPIC_ISR4	= 0x14,
97 	LAPIC_ISR5	= 0x15,
98 	LAPIC_ISR6	= 0x16,
99 	LAPIC_ISR7	= 0x17,
100 	LAPIC_TMR0	= 0x18,
101 	LAPIC_TMR1	= 0x19,
102 	LAPIC_TMR2	= 0x1a,
103 	LAPIC_TMR3	= 0x1b,
104 	LAPIC_TMR4	= 0x1c,
105 	LAPIC_TMR5	= 0x1d,
106 	LAPIC_TMR6	= 0x1e,
107 	LAPIC_TMR7	= 0x1f,
108 	LAPIC_IRR0	= 0x20,
109 	LAPIC_IRR1	= 0x21,
110 	LAPIC_IRR2	= 0x22,
111 	LAPIC_IRR3	= 0x23,
112 	LAPIC_IRR4	= 0x24,
113 	LAPIC_IRR5	= 0x25,
114 	LAPIC_IRR6	= 0x26,
115 	LAPIC_IRR7	= 0x27,
116 	LAPIC_ESR	= 0x28,
117 	LAPIC_LVT_CMCI	= 0x2f,
118 	LAPIC_ICR_LO	= 0x30,
119 	LAPIC_ICR_HI	= 0x31, /* Not in x2APIC */
120 	LAPIC_LVT_TIMER	= 0x32,
121 	LAPIC_LVT_THERMAL = 0x33,
122 	LAPIC_LVT_PCINT	= 0x34,
123 	LAPIC_LVT_LINT0	= 0x35,
124 	LAPIC_LVT_LINT1	= 0x36,
125 	LAPIC_LVT_ERROR	= 0x37,
126 	LAPIC_ICR_TIMER	= 0x38,
127 	LAPIC_CCR_TIMER	= 0x39,
128 	LAPIC_DCR_TIMER	= 0x3e,
129 	LAPIC_SELF_IPI	= 0x3f, /* Only in x2APIC */
130 	LAPIC_EXT_FEATURES = 0x40, /* AMD */
131 	LAPIC_EXT_CTRL	= 0x41, /* AMD */
132 	LAPIC_EXT_SEOI	= 0x42, /* AMD */
133 	LAPIC_EXT_IER0	= 0x48, /* AMD */
134 	LAPIC_EXT_IER1	= 0x49, /* AMD */
135 	LAPIC_EXT_IER2	= 0x4a, /* AMD */
136 	LAPIC_EXT_IER3	= 0x4b, /* AMD */
137 	LAPIC_EXT_IER4	= 0x4c, /* AMD */
138 	LAPIC_EXT_IER5	= 0x4d, /* AMD */
139 	LAPIC_EXT_IER6	= 0x4e, /* AMD */
140 	LAPIC_EXT_IER7	= 0x4f, /* AMD */
141 	LAPIC_EXT_LVT0	= 0x50, /* AMD */
142 	LAPIC_EXT_LVT1	= 0x51, /* AMD */
143 	LAPIC_EXT_LVT2	= 0x52, /* AMD */
144 	LAPIC_EXT_LVT3	= 0x53, /* AMD */
145 };
146 
147 #define	LAPIC_MEM_MUL	0x10
148 
149 /*
150  * Although some registers are available on AMD processors only,
151  * it's not a big waste to reserve them on all platforms.
152  * However, we need to watch out for this space being assigned for
153  * non-APIC purposes in the future processor models.
154  */
155 #define	LAPIC_MEM_REGION ((LAPIC_EXT_LVT3 + 1) * LAPIC_MEM_MUL)
156 
157 /******************************************************************************
158  * I/O APIC structure
159  */
160 
161 struct ioapic {
162 	uint32_t ioregsel;
163 	uint32_t rsv0[3];
164 	uint32_t iowin;
165 	uint32_t rsv1[3];
166 };
167 
168 /*
169  * Macros for bits in union ioapic_rte
170  */
171 #define IOAPIC_RTE_MASK_CLR		0x0U	/* Interrupt Mask: Clear */
172 #define IOAPIC_RTE_MASK_SET		0x1U	/* Interrupt Mask: Set */
173 
174 #define IOAPIC_RTE_TRGRMODE_EDGE	0x0U	/* Trigger Mode: Edge */
175 #define IOAPIC_RTE_TRGRMODE_LEVEL	0x1U	/* Trigger Mode: Level */
176 
177 #define IOAPIC_RTE_REM_IRR		0x1U	/* Remote IRR: Read-Only */
178 
179 #define IOAPIC_RTE_INTPOL_AHI		0x0U	/* Interrupt Polarity: active high */
180 #define IOAPIC_RTE_INTPOL_ALO		0x1U	/* Interrupt Polarity: active low */
181 
182 #define IOAPIC_RTE_DELIVS		0x1U	/* Delivery Status: Read-Only */
183 
184 #define IOAPIC_RTE_DESTMODE_PHY		0x0U	/* Destination Mode: Physical */
185 #define IOAPIC_RTE_DESTMODE_LOGICAL	0x1U	/* Destination Mode: Logical */
186 
187 #define IOAPIC_RTE_DELMODE_FIXED	0x0U	/* Delivery Mode: Fixed */
188 #define IOAPIC_RTE_DELMODE_LOPRI	0x1U	/* Delivery Mode: Lowest priority */
189 #define IOAPIC_RTE_DELMODE_INIT		0x5U	/* Delivery Mode: INIT signal */
190 #define IOAPIC_RTE_DELMODE_EXINT	0x7U	/* Delivery Mode: External INTerrupt */
191 
192 /* IOAPIC Redirection Table (RTE) Entry structure */
193 union ioapic_rte {
194 	uint64_t full;
195 	struct {
196 		uint32_t lo_32;
197 		uint32_t hi_32;
198 	} u;
199 	struct {
200 		uint8_t vector:8;
201 		uint64_t delivery_mode:3;
202 		uint64_t dest_mode:1;
203 		uint64_t delivery_status:1;
204 		uint64_t intr_polarity:1;
205 		uint64_t remote_irr:1;
206 		uint64_t trigger_mode:1;
207 		uint64_t intr_mask:1;
208 		uint64_t rsvd_1:39;
209 		uint8_t dest_field:8;
210 	} bits __packed;
211 	struct {
212 		uint32_t vector:8;
213 		uint32_t constant:3;
214 		uint32_t intr_index_high:1;
215 		uint32_t delivery_status:1;
216 		uint32_t intr_polarity:1;
217 		uint32_t remote_irr:1;
218 		uint32_t trigger_mode:1;
219 		uint32_t intr_mask:1;
220 		uint32_t rsvd_1:15;
221 		uint32_t rsvd_2:16;
222 		uint32_t intr_format:1;
223 		uint32_t intr_index_low:15;
224 	} ir_bits __packed;
225 };
226 
227 /******************************************************************************
228  * various code 'logical' values
229  */
230 
231 /******************************************************************************
232  * LOCAL APIC defines
233  */
234 
235 /* default physical locations of LOCAL (CPU) APICs */
236 #define DEFAULT_APIC_BASE	0xfee00000UL
237 
238 /* constants relating to APIC ID registers */
239 #define APIC_ID_MASK		0xff000000U
240 #define	APIC_ID_SHIFT		24U
241 #define	APIC_ID_CLUSTER		0xf0U
242 #define	APIC_ID_CLUSTER_ID	0x0fU
243 #define	APIC_MAX_CLUSTER	0xeU
244 #define	APIC_MAX_INTRACLUSTER_ID 3
245 #define	APIC_ID_CLUSTER_SHIFT	4
246 
247 /* fields in VER */
248 #define APIC_VER_VERSION	0x000000ffU
249 #define APIC_VER_MAXLVT		0x00ff0000U
250 #define MAXLVTSHIFT		16U
251 #define APIC_VER_EOI_SUPPRESSION 0x01000000U
252 #define APIC_VER_AMD_EXT_SPACE	0x80000000U
253 
254 /* fields in LDR */
255 #define	APIC_LDR_RESERVED	0x00ffffffU
256 #define X2APIC_LDR_LOGICAL_ID_MASK	0x0000ffffU
257 #define X2APIC_LDR_CLUSTER_ID_MASK	0xffff0000U
258 
259 /* fields in DFR */
260 #define	APIC_DFR_RESERVED	0x0fffffffU
261 #define	APIC_DFR_MODEL_MASK	0xf0000000U
262 #define	APIC_DFR_MODEL_FLAT	0xf0000000U
263 #define	APIC_DFR_MODEL_CLUSTER	0x00000000U
264 
265 /* fields in SVR */
266 #define APIC_SVR_VECTOR		0x000000ffU
267 #define APIC_SVR_VEC_PROG	0x000000f0U
268 #define APIC_SVR_VEC_FIX	0x0000000fU
269 #define APIC_SVR_ENABLE		0x00000100U
270 #define APIC_SVR_SWDIS		0x00000000U
271 #define APIC_SVR_SWEN		0x00000100U
272 #define APIC_SVR_FOCUS		0x00000200U
273 #define APIC_SVR_FEN		0x00000000U
274 #define APIC_SVR_FDIS		0x00000200U
275 #define APIC_SVR_EOI_SUPPRESSION 0x00001000U
276 
277 /* fields in TPR */
278 #define APIC_TPR_PRIO		0x000000ffU
279 #define APIC_TPR_INT		0x000000f0U
280 #define APIC_TPR_SUB		0x0000000fU
281 
282 /* fields in ESR */
283 #define	APIC_ESR_SEND_CS_ERROR		0x00000001U
284 #define	APIC_ESR_RECEIVE_CS_ERROR	0x00000002U
285 #define	APIC_ESR_SEND_ACCEPT		0x00000004U
286 #define	APIC_ESR_RECEIVE_ACCEPT		0x00000008U
287 #define	APIC_ESR_SEND_ILLEGAL_VECTOR	0x00000020U
288 #define	APIC_ESR_RECEIVE_ILLEGAL_VECTOR	0x00000040U
289 #define	APIC_ESR_ILLEGAL_REGISTER	0x00000080U
290 
291 /* fields in ICR_LOW */
292 #define APIC_VECTOR_MASK	0x000000ffU
293 
294 #define APIC_DELMODE_MASK	0x00000700U
295 #define APIC_DELMODE_FIXED	0x00000000U
296 #define APIC_DELMODE_LOWPRIO	0x00000100U
297 #define APIC_DELMODE_SMI	0x00000200U
298 #define APIC_DELMODE_RR	0x00000300U
299 #define APIC_DELMODE_NMI	0x00000400U
300 #define APIC_DELMODE_INIT	0x00000500U
301 #define APIC_DELMODE_STARTUP	0x00000600U
302 #define APIC_DELMODE_RESV	0x00000700U
303 
304 #define APIC_DESTMODE_MASK	0x00000800U
305 #define APIC_DESTMODE_PHY	0x00000000U
306 #define APIC_DESTMODE_LOG	0x00000800U
307 
308 #define APIC_DELSTAT_MASK	0x00001000U
309 #define APIC_DELSTAT_IDLE	0x00000000U
310 #define APIC_DELSTAT_PEND	0x00001000U
311 
312 #define APIC_RESV1_MASK		0x00002000U
313 
314 #define APIC_LEVEL_MASK		0x00004000U
315 #define APIC_LEVEL_DEASSERT	0x00000000U
316 #define APIC_LEVEL_ASSERT	0x00004000U
317 
318 #define APIC_TRIGMOD_MASK	0x00008000U
319 #define APIC_TRIGMOD_EDGE	0x00000000U
320 #define APIC_TRIGMOD_LEVEL	0x00008000U
321 
322 #define APIC_RRSTAT_MASK	0x00030000U
323 #define APIC_RRSTAT_INVALID	0x00000000U
324 #define APIC_RRSTAT_INPROG	0x00010000U
325 #define APIC_RRSTAT_VALID	0x00020000U
326 #define APIC_RRSTAT_RESV	0x00030000U
327 
328 #define APIC_DEST_MASK		0x000c0000U
329 #define APIC_DEST_NOSHORT	0x00000000U
330 #define APIC_DEST_SELF		0x00040000U
331 #define APIC_DEST_ALLISELF	0x00080000U
332 #define APIC_DEST_ALLESELF	0x000c0000U
333 
334 #define APIC_RESV2_MASK		0xfff00000U
335 
336 #define	APIC_ICRLO_RESV_MASK	(APIC_RESV1_MASK | APIC_RESV2_MASK)
337 
338 /* fields in LVT1/2 */
339 #define APIC_LVT_VECTOR		0x000000ffU
340 #define APIC_LVT_DM		0x00000700U
341 #define APIC_LVT_DM_FIXED	0x00000000U
342 #define APIC_LVT_DM_SMI	0x00000200U
343 #define APIC_LVT_DM_NMI	0x00000400U
344 #define APIC_LVT_DM_INIT	0x00000500U
345 #define APIC_LVT_DM_EXTINT	0x00000700U
346 #define APIC_LVT_DS		0x00001000U
347 #define APIC_LVT_IIPP		0x00002000U
348 #define APIC_LVT_IIPP_INTALO	0x00002000U
349 #define APIC_LVT_IIPP_INTAHI	0x00000000U
350 #define APIC_LVT_RIRR		0x00004000U
351 #define APIC_LVT_TM		0x00008000U
352 #define APIC_LVT_M		0x00010000U
353 
354 
355 /* fields in LVT Timer */
356 #define APIC_LVTT_VECTOR	0x000000ffU
357 #define APIC_LVTT_DS		0x00001000U
358 #define APIC_LVTT_M		0x00010000U
359 #define APIC_LVTT_TM		0x00060000U
360 #define APIC_LVTT_TM_ONE_SHOT	0x00000000U
361 #define APIC_LVTT_TM_PERIODIC	0x00020000U
362 #define APIC_LVTT_TM_TSCDLT	0x00040000U
363 #define APIC_LVTT_TM_RSRV	0x00060000U
364 
365 /* APIC timer current count */
366 #define	APIC_TIMER_MAX_COUNT	0xffffffffU
367 
368 /* fields in TDCR */
369 #define APIC_TDCR_2		0x00U
370 #define APIC_TDCR_4		0x01U
371 #define APIC_TDCR_8		0x02U
372 #define APIC_TDCR_16		0x03U
373 #define APIC_TDCR_32		0x08U
374 #define APIC_TDCR_64		0x09U
375 #define APIC_TDCR_128		0x0aU
376 #define APIC_TDCR_1		0x0bU
377 
378 /* Constants related to AMD Extended APIC Features Register */
379 #define	APIC_EXTF_ELVT_MASK	0x00ff0000U
380 #define	APIC_EXTF_ELVT_SHIFT	16
381 #define	APIC_EXTF_EXTID_CAP	0x00000004U
382 #define	APIC_EXTF_SEIO_CAP	0x00000002U
383 #define	APIC_EXTF_IER_CAP	0x00000001U
384 
385 /* LVT table indices */
386 #define	APIC_LVT_TIMER		0U
387 #define	APIC_LVT_THERMAL	1U
388 #define	APIC_LVT_PMC		2U
389 #define	APIC_LVT_LINT0		3U
390 #define	APIC_LVT_LINT1		4U
391 #define	APIC_LVT_ERROR		5U
392 #define	APIC_LVT_CMCI		6U
393 #define	APIC_LVT_MAX		APIC_LVT_CMCI
394 
395 /* AMD extended LVT constants, seem to be assigned by fiat */
396 #define	APIC_ELVT_IBS		0 /* Instruction based sampling */
397 #define	APIC_ELVT_MCA		1 /* MCE thresholding */
398 #define	APIC_ELVT_DEI		2 /* Deferred error interrupt */
399 #define	APIC_ELVT_SBI		3 /* Sideband interface */
400 #define	APIC_ELVT_MAX		APIC_ELVT_SBI
401 
402 /******************************************************************************
403  * I/O APIC defines
404  */
405 
406 /* window register offset */
407 #define IOAPIC_REGSEL		0x00U
408 #define IOAPIC_WINDOW		0x10U
409 
410 /* indexes into IO APIC */
411 #define IOAPIC_ID		0x00U
412 #define IOAPIC_VER		0x01U
413 #define IOAPIC_ARB		0x02U
414 #define IOAPIC_REDTBL		0x10U
415 #define IOAPIC_REDTBL0		IOAPIC_REDTBL
416 #define IOAPIC_REDTBL1		(IOAPIC_REDTBL+0x02U)
417 #define IOAPIC_REDTBL2		(IOAPIC_REDTBL+0x04U)
418 #define IOAPIC_REDTBL3		(IOAPIC_REDTBL+0x06U)
419 #define IOAPIC_REDTBL4		(IOAPIC_REDTBL+0x08U)
420 #define IOAPIC_REDTBL5		(IOAPIC_REDTBL+0x0aU)
421 #define IOAPIC_REDTBL6		(IOAPIC_REDTBL+0x0cU)
422 #define IOAPIC_REDTBL7		(IOAPIC_REDTBL+0x0eU)
423 #define IOAPIC_REDTBL8		(IOAPIC_REDTBL+0x10U)
424 #define IOAPIC_REDTBL9		(IOAPIC_REDTBL+0x12U)
425 #define IOAPIC_REDTBL10		(IOAPIC_REDTBL+0x14U)
426 #define IOAPIC_REDTBL11		(IOAPIC_REDTBL+0x16U)
427 #define IOAPIC_REDTBL12		(IOAPIC_REDTBL+0x18U)
428 #define IOAPIC_REDTBL13		(IOAPIC_REDTBL+0x1aU)
429 #define IOAPIC_REDTBL14		(IOAPIC_REDTBL+0x1cU)
430 #define IOAPIC_REDTBL15		(IOAPIC_REDTBL+0x1eU)
431 #define IOAPIC_REDTBL16		(IOAPIC_REDTBL+0x20U)
432 #define IOAPIC_REDTBL17		(IOAPIC_REDTBL+0x22U)
433 #define IOAPIC_REDTBL18		(IOAPIC_REDTBL+0x24U)
434 #define IOAPIC_REDTBL19		(IOAPIC_REDTBL+0x26U)
435 #define IOAPIC_REDTBL20		(IOAPIC_REDTBL+0x28U)
436 #define IOAPIC_REDTBL21		(IOAPIC_REDTBL+0x2aU)
437 #define IOAPIC_REDTBL22		(IOAPIC_REDTBL+0x2cU)
438 #define IOAPIC_REDTBL23		(IOAPIC_REDTBL+0x2eU)
439 
440 #define IOAPIC_ID_MASK		0x0f000000U
441 #define IOAPIC_ID_SHIFT		24U
442 
443 /* fields in VER, for redirection entry */
444 #define IOAPIC_MAX_RTE_MASK	0x00ff0000U
445 #define MAX_RTE_SHIFT		16U
446 
447 #endif /* APICREG_H */
448