xref: /dragonfly/sys/platform/pc64/apic/apic_vector.s (revision caaec4e3)
1/*
2 *	from: vector.s, 386BSD 0.1 unknown origin
3 * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
4 */
5
6#if 0
7#include "opt_auto_eoi.h"
8#endif
9
10#include <machine/asmacros.h>
11#include <machine/lock.h>
12#include <machine/psl.h>
13#include <machine/trap.h>
14#include <machine/segments.h>
15
16#include <machine_base/icu/icu.h>
17#include <bus/isa/isa.h>
18
19#include "assym.s"
20
21#include "apicreg.h"
22#include <machine_base/apic/ioapic_ipl.h>
23#include <machine/intr_machdep.h>
24
25#ifdef foo
26/* convert an absolute IRQ# into bitmask */
27#define IRQ_LBIT(irq_num)	(1UL << (irq_num & 0x3f))
28#endif
29
30#define IRQ_SBITS(irq_num)	((irq_num) & 0x3f)
31
32/* convert an absolute IRQ# into gd_ipending index */
33#define IRQ_LIDX(irq_num)	((irq_num) >> 6)
34
35#define MPLOCKED     lock ;
36
37#define APIC_PUSH_FRAME_TFRIP						\
38	PUSH_FRAME_TFRIP ;	/* 15 regs + space for 5 extras */	\
39	movq $0,TF_XFLAGS(%rsp) ;					\
40	movq $0,TF_TRAPNO(%rsp) ;					\
41	movq $0,TF_ADDR(%rsp) ;						\
42	movq $0,TF_FLAGS(%rsp) ;					\
43	movq $0,TF_ERR(%rsp) ;						\
44	cld ;								\
45
46/*
47 * JG stale? Warning: POP_FRAME can only be used if there is no chance of a
48 * segment register being changed (e.g. by procfs), which is why syscalls
49 * have to use doreti.
50 */
51#define APIC_POP_FRAME(lastinsn)					\
52	POP_FRAME(lastinsn) 						\
53
54#define IOAPICADDR(irq_num) \
55	CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_ADDR
56#define REDIRIDX(irq_num) \
57	CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_IDX
58#define IOAPICFLAGS(irq_num) \
59	CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_FLAGS
60
61#define MASK_IRQ(irq_num)						\
62	IOAPIC_IMASK_LOCK ;			/* into critical reg */	\
63	testl	$IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
64	jne	7f ;			/* masked, don't mask */	\
65	orl	$IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
66						/* set the mask bit */	\
67	movq	IOAPICADDR(irq_num), %rcx ;	/* ioapic addr */	\
68	movl	REDIRIDX(irq_num), %eax ;	/* get the index */	\
69	movl	%eax, (%rcx) ;			/* write the index */	\
70	orl	$IOART_INTMASK,IOAPIC_WINDOW(%rcx) ;/* set the mask */	\
717: ;						/* already masked */	\
72	IOAPIC_IMASK_UNLOCK ;						\
73
74/*
75 * Test to see whether we are handling an edge or level triggered INT.
76 *  Level-triggered INTs must still be masked as we don't clear the source,
77 *  and the EOI cycle would cause redundant INTs to occur.
78 */
79#define MASK_LEVEL_IRQ(irq_num)						\
80	testl	$IOAPIC_IRQI_FLAG_LEVEL, IOAPICFLAGS(irq_num) ;		\
81	jz	9f ;				/* edge, don't mask */	\
82	MASK_IRQ(irq_num) ;						\
839: ;									\
84
85/*
86 * Test to see if the source is currntly masked, clear if so.
87 */
88#define UNMASK_IRQ(irq_num)					\
89	cmpl	$0,%eax ;						\
90	jnz	8f ;							\
91	IOAPIC_IMASK_LOCK ;			/* into critical reg */	\
92	testl	$IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
93	je	7f ;			/* bit clear, not masked */	\
94	andl	$~IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
95						/* clear mask bit */	\
96	movq	IOAPICADDR(irq_num),%rcx ;	/* ioapic addr */	\
97	movl	REDIRIDX(irq_num), %eax ;	/* get the index */	\
98	movl	%eax,(%rcx) ;			/* write the index */	\
99	andl	$~IOART_INTMASK,IOAPIC_WINDOW(%rcx) ;/* clear the mask */ \
1007: ;									\
101	IOAPIC_IMASK_UNLOCK ;						\
1028: ;									\
103
104/*
105 * Interrupt call handlers run in the following sequence:
106 *
107 *	- Push the trap frame required by doreti
108 *	- Mask the interrupt and reenable its source
109 *	- If we cannot take the interrupt set its ipending bit and
110 *	  doreti.
111 *	- If we can take the interrupt clear its ipending bit,
112 *	  call the handler, then unmask and doreti.
113 *
114 * YYY can cache gd base opitner instead of using hidden %fs prefixes.
115 */
116
117#define	INTR_HANDLER(irq_num)						\
118	.text ;								\
119	SUPERALIGN_TEXT ;						\
120IDTVEC(ioapic_intr##irq_num) ;						\
121	APIC_PUSH_FRAME_TFRIP ;						\
122	FAKE_MCOUNT(TF_RIP(%rsp)) ;					\
123	MASK_LEVEL_IRQ(irq_num) ;					\
124	movq	lapic, %rax ;						\
125	movl	$0, LA_EOI(%rax) ;					\
126	movq	PCPU(curthread),%rbx ;					\
127	testl	$-1,TD_NEST_COUNT(%rbx) ;				\
128	jne	1f ;							\
129	testl	$-1,TD_CRITCOUNT(%rbx) ;				\
130	je	2f ;							\
1311: ;									\
132	/* in critical section, make interrupt pending */		\
133	/* set the pending bit and return, leave interrupt masked */	\
134	movq	$1,%rcx ;						\
135	shlq	$IRQ_SBITS(irq_num),%rcx ;				\
136	movq	$IRQ_LIDX(irq_num),%rdx ;				\
137	orq	%rcx,PCPU_E8(ipending,%rdx) ;				\
138	orl	$RQF_INTPEND,PCPU(reqflags) ;				\
139	jmp	5f ;							\
1402: ;									\
141	/* clear pending bit, run handler */				\
142	movq	$1,%rcx ;						\
143	shlq	$IRQ_SBITS(irq_num),%rcx ;				\
144	notq	%rcx ;							\
145	movq	$IRQ_LIDX(irq_num),%rdx ;				\
146	andq	%rcx,PCPU_E8(ipending,%rdx) ;				\
147	pushq	$irq_num ;		/* trapframe -> intrframe */	\
148	movq	%rsp, %rdi ;		/* pass frame by reference */	\
149	incl	TD_CRITCOUNT(%rbx) ;					\
150	sti ;								\
151	call	ithread_fast_handler ;	/* returns 0 to unmask */	\
152	cli ;				/* interlock avoid stacking */	\
153	decl	TD_CRITCOUNT(%rbx) ;					\
154	addq	$8, %rsp ;		/* intrframe -> trapframe */	\
155	UNMASK_IRQ(irq_num) ;						\
1565: ;									\
157	MEXITCOUNT ;							\
158	jmp	doreti ;						\
159
160/*
161 * Handle "spurious INTerrupts".
162 *
163 * NOTE: This is different than the "spurious INTerrupt" generated by an
164 *	 8259 PIC for missing INTs.  See the APIC documentation for details.
165 *	 This routine should NOT do an 'EOI' cycle.
166 *
167 * NOTE: Even though we don't do anything here we must still swapgs if
168 *	 coming from a user frame in case the iretq faults... just use
169 *	 the nominal APIC_PUSH_FRAME sequence to get it done.
170 */
171	.text
172	SUPERALIGN_TEXT
173	.globl Xspuriousint
174Xspuriousint:
175	APIC_PUSH_FRAME_TFRIP
176	/* No EOI cycle used here */
177	FAKE_MCOUNT(TF_RIP(%rsp))
178	MEXITCOUNT
179	APIC_POP_FRAME(jmp doreti_iret)
180
181/*
182 * Handle TLB shootdowns.
183 *
184 * NOTE: interrupts are left disabled.
185 */
186	.text
187	SUPERALIGN_TEXT
188	.globl	Xinvltlb
189Xinvltlb:
190	APIC_PUSH_FRAME_TFRIP
191	movq	lapic, %rax
192	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
193	FAKE_MCOUNT(TF_RIP(%rsp))
194	incl    PCPU(cnt) + V_IPI
195	movq	PCPU(curthread),%rbx
196	incl    PCPU(intr_nesting_level)
197	incl    TD_CRITCOUNT(%rbx)
198	subq	$8,%rsp			/* make same as interrupt frame */
199	movq	%rsp,%rdi		/* pass frame by reference */
200	call	smp_inval_intr		/* called w/interrupts disabled */
201	addq	$8,%rsp			/* turn into trapframe */
202	decl	TD_CRITCOUNT(%rbx)
203	decl	PCPU(intr_nesting_level)
204	MEXITCOUNT
205	/*APIC_POP_FRAME*/
206	jmp	doreti			/* doreti b/c intrs enabled */
207
208/*
209 * Handle sniffs - sniff %rip and %rsp.
210 */
211	.text
212	SUPERALIGN_TEXT
213	.globl	Xsniff
214Xsniff:
215	APIC_PUSH_FRAME_TFRIP
216	movq	lapic, %rax
217	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
218	FAKE_MCOUNT(TF_RIP(%rsp))
219	incl    PCPU(cnt) + V_IPI
220	movq	TF_RIP(%rsp),%rax
221	movq	%rax,PCPU(sample_pc)
222	movq	TF_RSP(%rsp),%rax
223	movq	%rax,PCPU(sample_sp)
224	MEXITCOUNT
225	APIC_POP_FRAME(jmp doreti_iret)
226
227/*
228 * Executed by a CPU when it receives an Xcpustop IPI from another CPU,
229 *
230 *  - We cannot call doreti
231 *  - Signals its receipt.
232 *  - Waits for permission to restart.
233 *  - Processing pending IPIQ events while waiting.
234 *  - Signals its restart.
235 */
236
237	.text
238	SUPERALIGN_TEXT
239	.globl Xcpustop
240Xcpustop:
241	APIC_PUSH_FRAME_TFRIP
242	movq	lapic, %rax
243	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
244
245	movl	PCPU(cpuid), %eax
246	imull	$PCB_SIZE, %eax
247	leaq	CNAME(stoppcbs), %rdi
248	addq	%rax, %rdi
249	call	CNAME(savectx)		/* Save process context */
250
251	/*
252	 * Indicate that we have stopped and loop waiting for permission
253	 * to start again.  We must still process IPI events while in a
254	 * stopped state.
255	 *
256	 * Interrupts must remain enabled for non-IPI'd per-cpu interrupts
257	 * (e.g. Xtimer, Xinvltlb).
258	 */
259#if CPUMASK_ELEMENTS != 4
260#error "assembly incompatible with cpumask_t"
261#endif
262	movq	PCPU(cpumask)+0,%rax	/* stopped_cpus |= 1 << cpuid */
263	MPLOCKED orq %rax, stopped_cpus+0
264	movq	PCPU(cpumask)+8,%rax
265	MPLOCKED orq %rax, stopped_cpus+8
266	movq	PCPU(cpumask)+16,%rax
267	MPLOCKED orq %rax, stopped_cpus+16
268	movq	PCPU(cpumask)+24,%rax
269	MPLOCKED orq %rax, stopped_cpus+24
270
271	movq	PCPU(curthread),%rbx
272	incl    PCPU(intr_nesting_level)
273	incl    TD_CRITCOUNT(%rbx)
274	sti
2751:
276	andl	$~RQF_IPIQ,PCPU(reqflags)
277	call	lwkt_smp_stopped
278	pause
279
280	subq	%rdi,%rdi
281	movq	started_cpus+0,%rax	/* while (!(started_cpus & (1<<id))) */
282	andq	PCPU(cpumask)+0,%rax
283	orq	%rax,%rdi
284	movq	started_cpus+8,%rax
285	andq	PCPU(cpumask)+8,%rax
286	orq	%rax,%rdi
287	movq	started_cpus+16,%rax
288	andq	PCPU(cpumask)+16,%rax
289	orq	%rax,%rdi
290	movq	started_cpus+24,%rax
291	andq	PCPU(cpumask)+24,%rax
292	orq	%rax,%rdi
293	testq	%rdi,%rdi
294	jz	1b
295
296	movq	PCPU(other_cpus)+0,%rax	/* started_cpus &= ~(1 << cpuid) */
297	MPLOCKED andq %rax, started_cpus+0
298	movq	PCPU(other_cpus)+8,%rax
299	MPLOCKED andq %rax, started_cpus+8
300	movq	PCPU(other_cpus)+16,%rax
301	MPLOCKED andq %rax, started_cpus+16
302	movq	PCPU(other_cpus)+24,%rax
303	MPLOCKED andq %rax, started_cpus+24
304
305	movq	PCPU(other_cpus)+0,%rax	/* stopped_cpus &= ~(1 << cpuid) */
306	MPLOCKED andq %rax, stopped_cpus+0
307	movq	PCPU(other_cpus)+8,%rax
308	MPLOCKED andq %rax, stopped_cpus+8
309	movq	PCPU(other_cpus)+16,%rax
310	MPLOCKED andq %rax, stopped_cpus+16
311	movq	PCPU(other_cpus)+24,%rax
312	MPLOCKED andq %rax, stopped_cpus+24
313
314	cmpl	$0,PCPU(cpuid)
315	jnz	2f
316
317	movq	CNAME(cpustop_restartfunc), %rax
318	testq	%rax, %rax
319	jz	2f
320	movq	$0, CNAME(cpustop_restartfunc)	/* One-shot */
321
322	call	*%rax
3232:
324	decl	TD_CRITCOUNT(%rbx)
325	decl	PCPU(intr_nesting_level)
326	MEXITCOUNT
327	/*APIC_POP_FRAME*/
328	jmp	doreti
329
330	/*
331	 * For now just have one ipiq IPI, but what we really want is
332	 * to have one for each source cpu to the APICs don't get stalled
333	 * backlogging the requests.
334	 */
335	.text
336	SUPERALIGN_TEXT
337	.globl Xipiq
338Xipiq:
339	APIC_PUSH_FRAME_TFRIP
340	movq	lapic, %rax
341	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
342	FAKE_MCOUNT(TF_RIP(%rsp))
343
344	incl    PCPU(cnt) + V_IPI
345	movq	PCPU(curthread),%rbx
346	testl	$-1,TD_CRITCOUNT(%rbx)
347	jne	1f
348	subq	$8,%rsp			/* make same as interrupt frame */
349	movq	%rsp,%rdi		/* pass frame by reference */
350	incl	PCPU(intr_nesting_level)
351	incl	TD_CRITCOUNT(%rbx)
352	subq	%rax,%rax
353	sti
354	xchgl	%eax,PCPU(npoll)	/* (atomic op) allow another Xipi */
355	call	lwkt_process_ipiq_frame
356	cli 				/* interlock avoid stacking */
357	decl	TD_CRITCOUNT(%rbx)
358	decl	PCPU(intr_nesting_level)
359	addq	$8,%rsp			/* turn into trapframe */
360	MEXITCOUNT
361	jmp	doreti
3621:
363	orl	$RQF_IPIQ,PCPU(reqflags)
364	MEXITCOUNT
365	APIC_POP_FRAME(jmp doreti_iret)
366
367	.text
368	SUPERALIGN_TEXT
369	.globl Xtimer
370Xtimer:
371	APIC_PUSH_FRAME_TFRIP
372	movq	lapic, %rax
373	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
374	FAKE_MCOUNT(TF_RIP(%rsp))
375
376	subq	$8,%rsp			/* make same as interrupt frame */
377	movq	%rsp,%rdi		/* pass frame by reference */
378	call	pcpu_timer_always
379	addq	$8,%rsp			/* turn into trapframe */
380
381	incl    PCPU(cnt) + V_TIMER
382	movq	TF_RIP(%rsp),%rbx	/* sample addr before checking crit */
383	movq	%rbx,PCPU(sample_pc)
384	movq	PCPU(curthread),%rbx
385	testl	$-1,TD_CRITCOUNT(%rbx)
386	jne	1f
387	testl	$-1,TD_NEST_COUNT(%rbx)
388	jne	1f
389	subq	$8,%rsp			/* make same as interrupt frame */
390	movq	%rsp,%rdi		/* pass frame by reference */
391	incl	PCPU(intr_nesting_level)
392	incl	TD_CRITCOUNT(%rbx)
393	sti
394	call	pcpu_timer_process_frame
395	cli 				/* interlock avoid stacking */
396	decl	TD_CRITCOUNT(%rbx)
397	decl	PCPU(intr_nesting_level)
398	addq	$8,%rsp			/* turn into trapframe */
399	MEXITCOUNT
400	jmp	doreti
4011:
402	orl	$RQF_TIMER,PCPU(reqflags)
403	MEXITCOUNT
404	APIC_POP_FRAME(jmp doreti_iret)
405
406MCOUNT_LABEL(bintr)
407	INTR_HANDLER(0)
408	INTR_HANDLER(1)
409	INTR_HANDLER(2)
410	INTR_HANDLER(3)
411	INTR_HANDLER(4)
412	INTR_HANDLER(5)
413	INTR_HANDLER(6)
414	INTR_HANDLER(7)
415	INTR_HANDLER(8)
416	INTR_HANDLER(9)
417	INTR_HANDLER(10)
418	INTR_HANDLER(11)
419	INTR_HANDLER(12)
420	INTR_HANDLER(13)
421	INTR_HANDLER(14)
422	INTR_HANDLER(15)
423	INTR_HANDLER(16)
424	INTR_HANDLER(17)
425	INTR_HANDLER(18)
426	INTR_HANDLER(19)
427	INTR_HANDLER(20)
428	INTR_HANDLER(21)
429	INTR_HANDLER(22)
430	INTR_HANDLER(23)
431	INTR_HANDLER(24)
432	INTR_HANDLER(25)
433	INTR_HANDLER(26)
434	INTR_HANDLER(27)
435	INTR_HANDLER(28)
436	INTR_HANDLER(29)
437	INTR_HANDLER(30)
438	INTR_HANDLER(31)
439	INTR_HANDLER(32)
440	INTR_HANDLER(33)
441	INTR_HANDLER(34)
442	INTR_HANDLER(35)
443	INTR_HANDLER(36)
444	INTR_HANDLER(37)
445	INTR_HANDLER(38)
446	INTR_HANDLER(39)
447	INTR_HANDLER(40)
448	INTR_HANDLER(41)
449	INTR_HANDLER(42)
450	INTR_HANDLER(43)
451	INTR_HANDLER(44)
452	INTR_HANDLER(45)
453	INTR_HANDLER(46)
454	INTR_HANDLER(47)
455	INTR_HANDLER(48)
456	INTR_HANDLER(49)
457	INTR_HANDLER(50)
458	INTR_HANDLER(51)
459	INTR_HANDLER(52)
460	INTR_HANDLER(53)
461	INTR_HANDLER(54)
462	INTR_HANDLER(55)
463	INTR_HANDLER(56)
464	INTR_HANDLER(57)
465	INTR_HANDLER(58)
466	INTR_HANDLER(59)
467	INTR_HANDLER(60)
468	INTR_HANDLER(61)
469	INTR_HANDLER(62)
470	INTR_HANDLER(63)
471	INTR_HANDLER(64)
472	INTR_HANDLER(65)
473	INTR_HANDLER(66)
474	INTR_HANDLER(67)
475	INTR_HANDLER(68)
476	INTR_HANDLER(69)
477	INTR_HANDLER(70)
478	INTR_HANDLER(71)
479	INTR_HANDLER(72)
480	INTR_HANDLER(73)
481	INTR_HANDLER(74)
482	INTR_HANDLER(75)
483	INTR_HANDLER(76)
484	INTR_HANDLER(77)
485	INTR_HANDLER(78)
486	INTR_HANDLER(79)
487	INTR_HANDLER(80)
488	INTR_HANDLER(81)
489	INTR_HANDLER(82)
490	INTR_HANDLER(83)
491	INTR_HANDLER(84)
492	INTR_HANDLER(85)
493	INTR_HANDLER(86)
494	INTR_HANDLER(87)
495	INTR_HANDLER(88)
496	INTR_HANDLER(89)
497	INTR_HANDLER(90)
498	INTR_HANDLER(91)
499	INTR_HANDLER(92)
500	INTR_HANDLER(93)
501	INTR_HANDLER(94)
502	INTR_HANDLER(95)
503	INTR_HANDLER(96)
504	INTR_HANDLER(97)
505	INTR_HANDLER(98)
506	INTR_HANDLER(99)
507	INTR_HANDLER(100)
508	INTR_HANDLER(101)
509	INTR_HANDLER(102)
510	INTR_HANDLER(103)
511	INTR_HANDLER(104)
512	INTR_HANDLER(105)
513	INTR_HANDLER(106)
514	INTR_HANDLER(107)
515	INTR_HANDLER(108)
516	INTR_HANDLER(109)
517	INTR_HANDLER(110)
518	INTR_HANDLER(111)
519	INTR_HANDLER(112)
520	INTR_HANDLER(113)
521	INTR_HANDLER(114)
522	INTR_HANDLER(115)
523	INTR_HANDLER(116)
524	INTR_HANDLER(117)
525	INTR_HANDLER(118)
526	INTR_HANDLER(119)
527	INTR_HANDLER(120)
528	INTR_HANDLER(121)
529	INTR_HANDLER(122)
530	INTR_HANDLER(123)
531	INTR_HANDLER(124)
532	INTR_HANDLER(125)
533	INTR_HANDLER(126)
534	INTR_HANDLER(127)
535	INTR_HANDLER(128)
536	INTR_HANDLER(129)
537	INTR_HANDLER(130)
538	INTR_HANDLER(131)
539	INTR_HANDLER(132)
540	INTR_HANDLER(133)
541	INTR_HANDLER(134)
542	INTR_HANDLER(135)
543	INTR_HANDLER(136)
544	INTR_HANDLER(137)
545	INTR_HANDLER(138)
546	INTR_HANDLER(139)
547	INTR_HANDLER(140)
548	INTR_HANDLER(141)
549	INTR_HANDLER(142)
550	INTR_HANDLER(143)
551	INTR_HANDLER(144)
552	INTR_HANDLER(145)
553	INTR_HANDLER(146)
554	INTR_HANDLER(147)
555	INTR_HANDLER(148)
556	INTR_HANDLER(149)
557	INTR_HANDLER(150)
558	INTR_HANDLER(151)
559	INTR_HANDLER(152)
560	INTR_HANDLER(153)
561	INTR_HANDLER(154)
562	INTR_HANDLER(155)
563	INTR_HANDLER(156)
564	INTR_HANDLER(157)
565	INTR_HANDLER(158)
566	INTR_HANDLER(159)
567	INTR_HANDLER(160)
568	INTR_HANDLER(161)
569	INTR_HANDLER(162)
570	INTR_HANDLER(163)
571	INTR_HANDLER(164)
572	INTR_HANDLER(165)
573	INTR_HANDLER(166)
574	INTR_HANDLER(167)
575	INTR_HANDLER(168)
576	INTR_HANDLER(169)
577	INTR_HANDLER(170)
578	INTR_HANDLER(171)
579	INTR_HANDLER(172)
580	INTR_HANDLER(173)
581	INTR_HANDLER(174)
582	INTR_HANDLER(175)
583	INTR_HANDLER(176)
584	INTR_HANDLER(177)
585	INTR_HANDLER(178)
586	INTR_HANDLER(179)
587	INTR_HANDLER(180)
588	INTR_HANDLER(181)
589	INTR_HANDLER(182)
590	INTR_HANDLER(183)
591	INTR_HANDLER(184)
592	INTR_HANDLER(185)
593	INTR_HANDLER(186)
594	INTR_HANDLER(187)
595	INTR_HANDLER(188)
596	INTR_HANDLER(189)
597	INTR_HANDLER(190)
598	INTR_HANDLER(191)
599MCOUNT_LABEL(eintr)
600
601	.data
602
603#if CPUMASK_ELEMENTS != 4
604#error "assembly incompatible with cpumask_t"
605#endif
606/* variables used by stop_cpus()/restart_cpus()/Xcpustop */
607	.globl stopped_cpus, started_cpus
608stopped_cpus:
609	.quad	0
610	.quad	0
611	.quad	0
612	.quad	0
613started_cpus:
614	.quad	0
615	.quad	0
616	.quad	0
617	.quad	0
618
619	.globl CNAME(cpustop_restartfunc)
620CNAME(cpustop_restartfunc):
621	.quad 0
622
623	.text
624
625