xref: /dragonfly/sys/platform/pc64/apic/apic_vector.s (revision 7f29793e)
1c8fe38aeSMatthew Dillon/*
2c8fe38aeSMatthew Dillon *	from: vector.s, 386BSD 0.1 unknown origin
3c8fe38aeSMatthew Dillon * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
4c8fe38aeSMatthew Dillon */
5c8fe38aeSMatthew Dillon
646d4e165SJordan Gordeev#if 0
7c8fe38aeSMatthew Dillon#include "opt_auto_eoi.h"
846d4e165SJordan Gordeev#endif
9c8fe38aeSMatthew Dillon
10c8fe38aeSMatthew Dillon#include <machine/asmacros.h>
11c8fe38aeSMatthew Dillon#include <machine/lock.h>
12c8fe38aeSMatthew Dillon#include <machine/psl.h>
13c8fe38aeSMatthew Dillon#include <machine/trap.h>
14bfc09ba0SMatthew Dillon#include <machine/segments.h>
15c8fe38aeSMatthew Dillon
16c8fe38aeSMatthew Dillon#include <machine_base/icu/icu.h>
170855a2afSJordan Gordeev#include <bus/isa/isa.h>
18c8fe38aeSMatthew Dillon
19c8fe38aeSMatthew Dillon#include "assym.s"
20c8fe38aeSMatthew Dillon
21c8fe38aeSMatthew Dillon#include "apicreg.h"
2277f86d14SSepherosa Ziehau#include <machine_base/apic/ioapic_ipl.h>
2357a9c56bSSepherosa Ziehau#include <machine/intr_machdep.h>
24c8fe38aeSMatthew Dillon
259611ff20SSepherosa Ziehau#ifdef foo
269611ff20SSepherosa Ziehau/* convert an absolute IRQ# into bitmask */
279611ff20SSepherosa Ziehau#define IRQ_LBIT(irq_num)	(1UL << (irq_num & 0x3f))
289611ff20SSepherosa Ziehau#endif
29c8fe38aeSMatthew Dillon
309611ff20SSepherosa Ziehau#define IRQ_SBITS(irq_num)	((irq_num) & 0x3f)
319611ff20SSepherosa Ziehau
329611ff20SSepherosa Ziehau/* convert an absolute IRQ# into gd_ipending index */
339611ff20SSepherosa Ziehau#define IRQ_LIDX(irq_num)	((irq_num) >> 6)
34c8fe38aeSMatthew Dillon
35c8fe38aeSMatthew Dillon#define MPLOCKED     lock ;
36c8fe38aeSMatthew Dillon
374611d87fSMatthew Dillon#define APIC_PUSH_FRAME_TFRIP						\
384611d87fSMatthew Dillon	PUSH_FRAME_TFRIP ;	/* 15 regs + space for 5 extras */	\
3946d4e165SJordan Gordeev	movq $0,TF_XFLAGS(%rsp) ;					\
4046d4e165SJordan Gordeev	movq $0,TF_TRAPNO(%rsp) ;					\
4146d4e165SJordan Gordeev	movq $0,TF_ADDR(%rsp) ;						\
4246d4e165SJordan Gordeev	movq $0,TF_FLAGS(%rsp) ;					\
4346d4e165SJordan Gordeev	movq $0,TF_ERR(%rsp) ;						\
44c8fe38aeSMatthew Dillon	cld ;								\
45c8fe38aeSMatthew Dillon
46c8fe38aeSMatthew Dillon/*
4746d4e165SJordan Gordeev * JG stale? Warning: POP_FRAME can only be used if there is no chance of a
48c8fe38aeSMatthew Dillon * segment register being changed (e.g. by procfs), which is why syscalls
49c8fe38aeSMatthew Dillon * have to use doreti.
50c8fe38aeSMatthew Dillon */
514611d87fSMatthew Dillon#define APIC_POP_FRAME(lastinsn)					\
524611d87fSMatthew Dillon	POP_FRAME(lastinsn) 						\
53c8fe38aeSMatthew Dillon
5429b21b81SMichael Neumann#define IOAPICADDR(irq_num) \
555ac5ccd2SSepherosa Ziehau	CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_ADDR
5629b21b81SMichael Neumann#define REDIRIDX(irq_num) \
575ac5ccd2SSepherosa Ziehau	CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_IDX
5854d63b2fSMichael Neumann#define IOAPICFLAGS(irq_num) \
595ac5ccd2SSepherosa Ziehau	CNAME(ioapic_irqs) + IOAPIC_IRQI_SIZE * (irq_num) + IOAPIC_IRQI_FLAGS
60c8fe38aeSMatthew Dillon
61c8fe38aeSMatthew Dillon#define MASK_IRQ(irq_num)						\
625ac5ccd2SSepherosa Ziehau	testl	$IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
63c8fe38aeSMatthew Dillon	jne	7f ;			/* masked, don't mask */	\
645ac5ccd2SSepherosa Ziehau	orl	$IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
65906448d8SMichael Neumann						/* set the mask bit */	\
6646d4e165SJordan Gordeev	movq	IOAPICADDR(irq_num), %rcx ;	/* ioapic addr */	\
67c8fe38aeSMatthew Dillon	movl	REDIRIDX(irq_num), %eax ;	/* get the index */	\
6846d4e165SJordan Gordeev	movl	%eax, (%rcx) ;			/* write the index */	\
696dfe7381SMichael Neumann	orl	$IOART_INTMASK,IOAPIC_WINDOW(%rcx) ;/* set the mask */	\
70c8fe38aeSMatthew Dillon7: ;						/* already masked */	\
71c8fe38aeSMatthew Dillon
72c8fe38aeSMatthew Dillon/*
73c8fe38aeSMatthew Dillon * Test to see whether we are handling an edge or level triggered INT.
74c8fe38aeSMatthew Dillon *  Level-triggered INTs must still be masked as we don't clear the source,
75c8fe38aeSMatthew Dillon *  and the EOI cycle would cause redundant INTs to occur.
76c8fe38aeSMatthew Dillon */
77c8fe38aeSMatthew Dillon#define MASK_LEVEL_IRQ(irq_num)						\
785ac5ccd2SSepherosa Ziehau	testl	$IOAPIC_IRQI_FLAG_LEVEL, IOAPICFLAGS(irq_num) ;		\
79c8fe38aeSMatthew Dillon	jz	9f ;				/* edge, don't mask */	\
80c8fe38aeSMatthew Dillon	MASK_IRQ(irq_num) ;						\
81c8fe38aeSMatthew Dillon9: ;									\
82c8fe38aeSMatthew Dillon
83c8fe38aeSMatthew Dillon/*
84c8fe38aeSMatthew Dillon * Test to see if the source is currntly masked, clear if so.
85c8fe38aeSMatthew Dillon */
86c8fe38aeSMatthew Dillon#define UNMASK_IRQ(irq_num)					\
87c8fe38aeSMatthew Dillon	cmpl	$0,%eax ;						\
88c8fe38aeSMatthew Dillon	jnz	8f ;							\
89bbf928c6SMatthew Dillon	IOAPIC_IMASK_LOCK ;						\
905ac5ccd2SSepherosa Ziehau	testl	$IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
91c8fe38aeSMatthew Dillon	je	7f ;			/* bit clear, not masked */	\
925ac5ccd2SSepherosa Ziehau	andl	$~IOAPIC_IRQI_FLAG_MASKED, IOAPICFLAGS(irq_num) ;	\
93906448d8SMichael Neumann						/* clear mask bit */	\
9446d4e165SJordan Gordeev	movq	IOAPICADDR(irq_num),%rcx ;	/* ioapic addr */	\
95c8fe38aeSMatthew Dillon	movl	REDIRIDX(irq_num), %eax ;	/* get the index */	\
9646d4e165SJordan Gordeev	movl	%eax,(%rcx) ;			/* write the index */	\
976dfe7381SMichael Neumann	andl	$~IOART_INTMASK,IOAPIC_WINDOW(%rcx) ;/* clear the mask */ \
98c8fe38aeSMatthew Dillon7: ;									\
999e0e3f85SSepherosa Ziehau	IOAPIC_IMASK_UNLOCK ;						\
100c8fe38aeSMatthew Dillon8: ;									\
101c8fe38aeSMatthew Dillon
102c8fe38aeSMatthew Dillon/*
10335e45e47SSepherosa Ziehau * Interrupt call handlers run in the following sequence:
104c8fe38aeSMatthew Dillon *
105c8fe38aeSMatthew Dillon *	- Push the trap frame required by doreti
106c8fe38aeSMatthew Dillon *	- Mask the interrupt and reenable its source
1079611ff20SSepherosa Ziehau *	- If we cannot take the interrupt set its ipending bit and
108b5d16701SMatthew Dillon *	  doreti.
1099611ff20SSepherosa Ziehau *	- If we can take the interrupt clear its ipending bit,
110c8fe38aeSMatthew Dillon *	  call the handler, then unmask and doreti.
111c8fe38aeSMatthew Dillon *
112c8fe38aeSMatthew Dillon * YYY can cache gd base opitner instead of using hidden %fs prefixes.
113c8fe38aeSMatthew Dillon */
114c8fe38aeSMatthew Dillon
11558e8d3d8SSepherosa Ziehau#define	INTR_HANDLER(irq_num)						\
116c8fe38aeSMatthew Dillon	.text ;								\
117c8fe38aeSMatthew Dillon	SUPERALIGN_TEXT ;						\
1189e0e3f85SSepherosa ZiehauIDTVEC(ioapic_intr##irq_num) ;						\
1194611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP ;						\
1202883d2d8SMatthew Dillon	FAKE_MCOUNT(TF_RIP(%rsp)) ;					\
121bbf928c6SMatthew Dillon	IOAPIC_IMASK_LOCK ;						\
122c8fe38aeSMatthew Dillon	MASK_LEVEL_IRQ(irq_num) ;					\
1233c38fc60SSepherosa Ziehau	movq	lapic_eoi, %rax ;					\
124bbf928c6SMatthew Dillon	IOAPIC_IMASK_UNLOCK ;						\
1253c38fc60SSepherosa Ziehau	callq	*%rax ;							\
12646d4e165SJordan Gordeev	movq	PCPU(curthread),%rbx ;					\
12746d4e165SJordan Gordeev	testl	$-1,TD_NEST_COUNT(%rbx) ;				\
128c8fe38aeSMatthew Dillon	jne	1f ;							\
129f9235b6dSMatthew Dillon	testl	$-1,TD_CRITCOUNT(%rbx) ;				\
130f9235b6dSMatthew Dillon	je	2f ;							\
131c8fe38aeSMatthew Dillon1: ;									\
132c8fe38aeSMatthew Dillon	/* in critical section, make interrupt pending */		\
133c8fe38aeSMatthew Dillon	/* set the pending bit and return, leave interrupt masked */	\
1349611ff20SSepherosa Ziehau	movq	$1,%rcx ;						\
1359611ff20SSepherosa Ziehau	shlq	$IRQ_SBITS(irq_num),%rcx ;				\
1364fb281afSSepherosa Ziehau	movq	$IRQ_LIDX(irq_num),%rdx ;				\
1374fb281afSSepherosa Ziehau	orq	%rcx,PCPU_E8(ipending,%rdx) ;				\
138c8fe38aeSMatthew Dillon	orl	$RQF_INTPEND,PCPU(reqflags) ;				\
139c8fe38aeSMatthew Dillon	jmp	5f ;							\
140c8fe38aeSMatthew Dillon2: ;									\
141c8fe38aeSMatthew Dillon	/* clear pending bit, run handler */				\
1429611ff20SSepherosa Ziehau	movq	$1,%rcx ;						\
1439611ff20SSepherosa Ziehau	shlq	$IRQ_SBITS(irq_num),%rcx ;				\
1449611ff20SSepherosa Ziehau	notq	%rcx ;							\
1454fb281afSSepherosa Ziehau	movq	$IRQ_LIDX(irq_num),%rdx ;				\
1464fb281afSSepherosa Ziehau	andq	%rcx,PCPU_E8(ipending,%rdx) ;				\
14746d4e165SJordan Gordeev	pushq	$irq_num ;		/* trapframe -> intrframe */	\
14846d4e165SJordan Gordeev	movq	%rsp, %rdi ;		/* pass frame by reference */	\
149f9235b6dSMatthew Dillon	incl	TD_CRITCOUNT(%rbx) ;					\
1502d910aafSMatthew Dillon	sti ;								\
151c8fe38aeSMatthew Dillon	call	ithread_fast_handler ;	/* returns 0 to unmask */	\
152ae18e11dSMatthew Dillon	cli ;				/* interlock avoid stacking */	\
153f9235b6dSMatthew Dillon	decl	TD_CRITCOUNT(%rbx) ;					\
15446d4e165SJordan Gordeev	addq	$8, %rsp ;		/* intrframe -> trapframe */	\
155c8fe38aeSMatthew Dillon	UNMASK_IRQ(irq_num) ;						\
156c8fe38aeSMatthew Dillon5: ;									\
157c8fe38aeSMatthew Dillon	MEXITCOUNT ;							\
158c8fe38aeSMatthew Dillon	jmp	doreti ;						\
159c8fe38aeSMatthew Dillon
160c8fe38aeSMatthew Dillon/*
161c8fe38aeSMatthew Dillon * Handle "spurious INTerrupts".
1623338cc67SMatthew Dillon *
1633338cc67SMatthew Dillon * NOTE: This is different than the "spurious INTerrupt" generated by an
164c8fe38aeSMatthew Dillon *	 8259 PIC for missing INTs.  See the APIC documentation for details.
165c8fe38aeSMatthew Dillon *	 This routine should NOT do an 'EOI' cycle.
1663338cc67SMatthew Dillon *
1673338cc67SMatthew Dillon * NOTE: Even though we don't do anything here we must still swapgs if
1683338cc67SMatthew Dillon *	 coming from a user frame in case the iretq faults... just use
1693338cc67SMatthew Dillon *	 the nominal APIC_PUSH_FRAME sequence to get it done.
170c8fe38aeSMatthew Dillon */
171c8fe38aeSMatthew Dillon	.text
172c8fe38aeSMatthew Dillon	SUPERALIGN_TEXT
173c8fe38aeSMatthew Dillon	.globl Xspuriousint
174c8fe38aeSMatthew DillonXspuriousint:
1754611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP
176c8fe38aeSMatthew Dillon	/* No EOI cycle used here */
1773338cc67SMatthew Dillon	FAKE_MCOUNT(TF_RIP(%rsp))
1783338cc67SMatthew Dillon	MEXITCOUNT
1794611d87fSMatthew Dillon	APIC_POP_FRAME(jmp doreti_iret)
180c8fe38aeSMatthew Dillon
181c8fe38aeSMatthew Dillon/*
182c8fe38aeSMatthew Dillon * Handle TLB shootdowns.
1832d910aafSMatthew Dillon *
1842d910aafSMatthew Dillon * NOTE: interrupts are left disabled.
185c8fe38aeSMatthew Dillon */
186c8fe38aeSMatthew Dillon	.text
187c8fe38aeSMatthew Dillon	SUPERALIGN_TEXT
188c8fe38aeSMatthew Dillon	.globl	Xinvltlb
189c8fe38aeSMatthew DillonXinvltlb:
1904611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP
1913c38fc60SSepherosa Ziehau	movq	lapic_eoi, %rax
1923c38fc60SSepherosa Ziehau	callq	*%rax			/* End Of Interrupt to APIC */
1937d4d6fdbSMatthew Dillon	FAKE_MCOUNT(TF_RIP(%rsp))
19479f2da03SMatthew Dillon	incl    PCPU(cnt) + V_IPI
1951a5c7e0fSMatthew Dillon	movq	PCPU(curthread),%rbx
1961a5c7e0fSMatthew Dillon	incl    PCPU(intr_nesting_level)
1971a5c7e0fSMatthew Dillon	incl    TD_CRITCOUNT(%rbx)
1987d4d6fdbSMatthew Dillon	subq	$8,%rsp			/* make same as interrupt frame */
1997d4d6fdbSMatthew Dillon	movq	%rsp,%rdi		/* pass frame by reference */
200*7f29793eSAaron LI	orl	$RQF_XINVLTLB,PCPU(reqflags) /* HVM interlock */
2011a5c7e0fSMatthew Dillon	call	smp_inval_intr		/* called w/interrupts disabled */
2027d4d6fdbSMatthew Dillon	addq	$8,%rsp			/* turn into trapframe */
2031a5c7e0fSMatthew Dillon	decl	TD_CRITCOUNT(%rbx)
2041a5c7e0fSMatthew Dillon	decl	PCPU(intr_nesting_level)
2057d4d6fdbSMatthew Dillon	MEXITCOUNT
206e32d3244SMatthew Dillon	/*APIC_POP_FRAME*/
207e32d3244SMatthew Dillon	jmp	doreti			/* doreti b/c intrs enabled */
208e32d3244SMatthew Dillon
209e32d3244SMatthew Dillon/*
210e32d3244SMatthew Dillon * Handle sniffs - sniff %rip and %rsp.
211e32d3244SMatthew Dillon */
212e32d3244SMatthew Dillon	.text
213e32d3244SMatthew Dillon	SUPERALIGN_TEXT
214e32d3244SMatthew Dillon	.globl	Xsniff
215e32d3244SMatthew DillonXsniff:
2164611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP
2173c38fc60SSepherosa Ziehau	movq	lapic_eoi, %rax
2183c38fc60SSepherosa Ziehau	callq	*%rax			/* End Of Interrupt to APIC */
219e32d3244SMatthew Dillon	FAKE_MCOUNT(TF_RIP(%rsp))
220e32d3244SMatthew Dillon	incl    PCPU(cnt) + V_IPI
22191dc43ddSMatthew Dillon	movq	%rsp,%rdi
22291dc43ddSMatthew Dillon	call	CNAME(hard_sniff)	/* systat -pv and flame sniff */
223e32d3244SMatthew Dillon	MEXITCOUNT
2244611d87fSMatthew Dillon	APIC_POP_FRAME(jmp doreti_iret)
225c8fe38aeSMatthew Dillon
226c8fe38aeSMatthew Dillon/*
227c8fe38aeSMatthew Dillon * Executed by a CPU when it receives an Xcpustop IPI from another CPU,
228c8fe38aeSMatthew Dillon *
2292883d2d8SMatthew Dillon *  - We cannot call doreti
230c8fe38aeSMatthew Dillon *  - Signals its receipt.
231c8fe38aeSMatthew Dillon *  - Waits for permission to restart.
232c8fe38aeSMatthew Dillon *  - Processing pending IPIQ events while waiting.
233c8fe38aeSMatthew Dillon *  - Signals its restart.
234c8fe38aeSMatthew Dillon */
235c8fe38aeSMatthew Dillon
236c8fe38aeSMatthew Dillon	.text
237c8fe38aeSMatthew Dillon	SUPERALIGN_TEXT
238c8fe38aeSMatthew Dillon	.globl Xcpustop
239c8fe38aeSMatthew DillonXcpustop:
2404611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP
2413c38fc60SSepherosa Ziehau	movq	lapic_eoi, %rax
2423c38fc60SSepherosa Ziehau	callq	*%rax			/* End Of Interrupt to APIC */
243c8fe38aeSMatthew Dillon
244c8fe38aeSMatthew Dillon	movl	PCPU(cpuid), %eax
245c8fe38aeSMatthew Dillon	imull	$PCB_SIZE, %eax
24646d4e165SJordan Gordeev	leaq	CNAME(stoppcbs), %rdi
24746d4e165SJordan Gordeev	addq	%rax, %rdi
248c8fe38aeSMatthew Dillon	call	CNAME(savectx)		/* Save process context */
249c8fe38aeSMatthew Dillon
250c8fe38aeSMatthew Dillon	/*
251c8fe38aeSMatthew Dillon	 * Indicate that we have stopped and loop waiting for permission
252c8fe38aeSMatthew Dillon	 * to start again.  We must still process IPI events while in a
253c8fe38aeSMatthew Dillon	 * stopped state.
2542d910aafSMatthew Dillon	 *
2552d910aafSMatthew Dillon	 * Interrupts must remain enabled for non-IPI'd per-cpu interrupts
2562d910aafSMatthew Dillon	 * (e.g. Xtimer, Xinvltlb).
257c8fe38aeSMatthew Dillon	 */
25806c66eb2SMatthew Dillon#if CPUMASK_ELEMENTS != 4
25906c66eb2SMatthew Dillon#error "assembly incompatible with cpumask_t"
26006c66eb2SMatthew Dillon#endif
26106c66eb2SMatthew Dillon	movq	PCPU(cpumask)+0,%rax	/* stopped_cpus |= 1 << cpuid */
26206c66eb2SMatthew Dillon	MPLOCKED orq %rax, stopped_cpus+0
26306c66eb2SMatthew Dillon	movq	PCPU(cpumask)+8,%rax
26406c66eb2SMatthew Dillon	MPLOCKED orq %rax, stopped_cpus+8
26506c66eb2SMatthew Dillon	movq	PCPU(cpumask)+16,%rax
26606c66eb2SMatthew Dillon	MPLOCKED orq %rax, stopped_cpus+16
26706c66eb2SMatthew Dillon	movq	PCPU(cpumask)+24,%rax
26806c66eb2SMatthew Dillon	MPLOCKED orq %rax, stopped_cpus+24
269b19f40a4SMatthew Dillon
270b19f40a4SMatthew Dillon	movq	PCPU(curthread),%rbx
271b19f40a4SMatthew Dillon	incl    PCPU(intr_nesting_level)
272b19f40a4SMatthew Dillon	incl    TD_CRITCOUNT(%rbx)
2732d910aafSMatthew Dillon	sti
274c8fe38aeSMatthew Dillon1:
275c8fe38aeSMatthew Dillon	andl	$~RQF_IPIQ,PCPU(reqflags)
276c8fe38aeSMatthew Dillon	call	lwkt_smp_stopped
2772883d2d8SMatthew Dillon	pause
278c8fe38aeSMatthew Dillon
27906c66eb2SMatthew Dillon	subq	%rdi,%rdi
28006c66eb2SMatthew Dillon	movq	started_cpus+0,%rax	/* while (!(started_cpus & (1<<id))) */
28106c66eb2SMatthew Dillon	andq	PCPU(cpumask)+0,%rax
28206c66eb2SMatthew Dillon	orq	%rax,%rdi
28306c66eb2SMatthew Dillon	movq	started_cpus+8,%rax
28406c66eb2SMatthew Dillon	andq	PCPU(cpumask)+8,%rax
28506c66eb2SMatthew Dillon	orq	%rax,%rdi
28606c66eb2SMatthew Dillon	movq	started_cpus+16,%rax
28706c66eb2SMatthew Dillon	andq	PCPU(cpumask)+16,%rax
28806c66eb2SMatthew Dillon	orq	%rax,%rdi
28906c66eb2SMatthew Dillon	movq	started_cpus+24,%rax
29006c66eb2SMatthew Dillon	andq	PCPU(cpumask)+24,%rax
29106c66eb2SMatthew Dillon	orq	%rax,%rdi
29206c66eb2SMatthew Dillon	testq	%rdi,%rdi
29306c66eb2SMatthew Dillon	jz	1b
294c8fe38aeSMatthew Dillon
29506c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+0,%rax	/* started_cpus &= ~(1 << cpuid) */
29606c66eb2SMatthew Dillon	MPLOCKED andq %rax, started_cpus+0
29706c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+8,%rax
29806c66eb2SMatthew Dillon	MPLOCKED andq %rax, started_cpus+8
29906c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+16,%rax
30006c66eb2SMatthew Dillon	MPLOCKED andq %rax, started_cpus+16
30106c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+24,%rax
30206c66eb2SMatthew Dillon	MPLOCKED andq %rax, started_cpus+24
30306c66eb2SMatthew Dillon
30406c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+0,%rax	/* stopped_cpus &= ~(1 << cpuid) */
30506c66eb2SMatthew Dillon	MPLOCKED andq %rax, stopped_cpus+0
30606c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+8,%rax
30706c66eb2SMatthew Dillon	MPLOCKED andq %rax, stopped_cpus+8
30806c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+16,%rax
30906c66eb2SMatthew Dillon	MPLOCKED andq %rax, stopped_cpus+16
31006c66eb2SMatthew Dillon	movq	PCPU(other_cpus)+24,%rax
31106c66eb2SMatthew Dillon	MPLOCKED andq %rax, stopped_cpus+24
31206c66eb2SMatthew Dillon
31306c66eb2SMatthew Dillon	cmpl	$0,PCPU(cpuid)
314c8fe38aeSMatthew Dillon	jnz	2f
315c8fe38aeSMatthew Dillon
31646d4e165SJordan Gordeev	movq	CNAME(cpustop_restartfunc), %rax
317cec63019SMatthew Dillon	testq	%rax, %rax
318c8fe38aeSMatthew Dillon	jz	2f
31946d4e165SJordan Gordeev	movq	$0, CNAME(cpustop_restartfunc)	/* One-shot */
320c8fe38aeSMatthew Dillon
32146d4e165SJordan Gordeev	call	*%rax
322c8fe38aeSMatthew Dillon2:
323b19f40a4SMatthew Dillon	decl	TD_CRITCOUNT(%rbx)
324b19f40a4SMatthew Dillon	decl	PCPU(intr_nesting_level)
3252883d2d8SMatthew Dillon	MEXITCOUNT
326b19f40a4SMatthew Dillon	/*APIC_POP_FRAME*/
327b19f40a4SMatthew Dillon	jmp	doreti
328c8fe38aeSMatthew Dillon
329c8fe38aeSMatthew Dillon	/*
330c8fe38aeSMatthew Dillon	 * For now just have one ipiq IPI, but what we really want is
331c8fe38aeSMatthew Dillon	 * to have one for each source cpu to the APICs don't get stalled
332c8fe38aeSMatthew Dillon	 * backlogging the requests.
333c8fe38aeSMatthew Dillon	 */
334c8fe38aeSMatthew Dillon	.text
335c8fe38aeSMatthew Dillon	SUPERALIGN_TEXT
336c8fe38aeSMatthew Dillon	.globl Xipiq
337c8fe38aeSMatthew DillonXipiq:
3384611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP
3393c38fc60SSepherosa Ziehau	movq	lapic_eoi, %rax
3403c38fc60SSepherosa Ziehau	callq	*%rax			/* End Of Interrupt to APIC */
3412883d2d8SMatthew Dillon	FAKE_MCOUNT(TF_RIP(%rsp))
342c8fe38aeSMatthew Dillon
34346d4e165SJordan Gordeev	incl    PCPU(cnt) + V_IPI
34446d4e165SJordan Gordeev	movq	PCPU(curthread),%rbx
345f9235b6dSMatthew Dillon	testl	$-1,TD_CRITCOUNT(%rbx)
346f9235b6dSMatthew Dillon	jne	1f
34746d4e165SJordan Gordeev	subq	$8,%rsp			/* make same as interrupt frame */
34846d4e165SJordan Gordeev	movq	%rsp,%rdi		/* pass frame by reference */
349c8fe38aeSMatthew Dillon	incl	PCPU(intr_nesting_level)
350f9235b6dSMatthew Dillon	incl	TD_CRITCOUNT(%rbx)
351e47e3dbaSMatthew Dillon	subq	%rax,%rax
3522d910aafSMatthew Dillon	sti
353e47e3dbaSMatthew Dillon	xchgl	%eax,PCPU(npoll)	/* (atomic op) allow another Xipi */
354c8fe38aeSMatthew Dillon	call	lwkt_process_ipiq_frame
355ae18e11dSMatthew Dillon	cli 				/* interlock avoid stacking */
356f9235b6dSMatthew Dillon	decl	TD_CRITCOUNT(%rbx)
357c8fe38aeSMatthew Dillon	decl	PCPU(intr_nesting_level)
35846d4e165SJordan Gordeev	addq	$8,%rsp			/* turn into trapframe */
359c8fe38aeSMatthew Dillon	MEXITCOUNT
360c8fe38aeSMatthew Dillon	jmp	doreti
361c8fe38aeSMatthew Dillon1:
362c8fe38aeSMatthew Dillon	orl	$RQF_IPIQ,PCPU(reqflags)
363c8fe38aeSMatthew Dillon	MEXITCOUNT
3644611d87fSMatthew Dillon	APIC_POP_FRAME(jmp doreti_iret)
36546d4e165SJordan Gordeev
36646d4e165SJordan Gordeev	.text
36746d4e165SJordan Gordeev	SUPERALIGN_TEXT
36846d4e165SJordan Gordeev	.globl Xtimer
36946d4e165SJordan GordeevXtimer:
3704611d87fSMatthew Dillon	APIC_PUSH_FRAME_TFRIP
3713c38fc60SSepherosa Ziehau	movq	lapic_eoi, %rax
3723c38fc60SSepherosa Ziehau	callq	*%rax			/* End Of Interrupt to APIC */
3732883d2d8SMatthew Dillon	FAKE_MCOUNT(TF_RIP(%rsp))
37446d4e165SJordan Gordeev
375b9f7ba13SMatthew Dillon	subq	$8,%rsp			/* make same as interrupt frame */
376b9f7ba13SMatthew Dillon	movq	%rsp,%rdi		/* pass frame by reference */
377b8a64c88SSepherosa Ziehau	call	pcpu_timer_always
378b9f7ba13SMatthew Dillon	addq	$8,%rsp			/* turn into trapframe */
379b9f7ba13SMatthew Dillon
38046d4e165SJordan Gordeev	incl    PCPU(cnt) + V_TIMER
381433c75c3SMatthew Dillon	movq	TF_RIP(%rsp),%rbx	/* sample addr before checking crit */
382433c75c3SMatthew Dillon	movq	%rbx,PCPU(sample_pc)
38346d4e165SJordan Gordeev	movq	PCPU(curthread),%rbx
384f9235b6dSMatthew Dillon	testl	$-1,TD_CRITCOUNT(%rbx)
385f9235b6dSMatthew Dillon	jne	1f
38646d4e165SJordan Gordeev	testl	$-1,TD_NEST_COUNT(%rbx)
38746d4e165SJordan Gordeev	jne	1f
38846d4e165SJordan Gordeev	subq	$8,%rsp			/* make same as interrupt frame */
38946d4e165SJordan Gordeev	movq	%rsp,%rdi		/* pass frame by reference */
39046d4e165SJordan Gordeev	incl	PCPU(intr_nesting_level)
391f9235b6dSMatthew Dillon	incl	TD_CRITCOUNT(%rbx)
3922d910aafSMatthew Dillon	sti
393b8a64c88SSepherosa Ziehau	call	pcpu_timer_process_frame
394ae18e11dSMatthew Dillon	cli 				/* interlock avoid stacking */
395f9235b6dSMatthew Dillon	decl	TD_CRITCOUNT(%rbx)
39646d4e165SJordan Gordeev	decl	PCPU(intr_nesting_level)
39746d4e165SJordan Gordeev	addq	$8,%rsp			/* turn into trapframe */
39846d4e165SJordan Gordeev	MEXITCOUNT
39946d4e165SJordan Gordeev	jmp	doreti
40046d4e165SJordan Gordeev1:
40146d4e165SJordan Gordeev	orl	$RQF_TIMER,PCPU(reqflags)
40246d4e165SJordan Gordeev	MEXITCOUNT
4034611d87fSMatthew Dillon	APIC_POP_FRAME(jmp doreti_iret)
404c8fe38aeSMatthew Dillon
405c8fe38aeSMatthew DillonMCOUNT_LABEL(bintr)
40658e8d3d8SSepherosa Ziehau	INTR_HANDLER(0)
40758e8d3d8SSepherosa Ziehau	INTR_HANDLER(1)
40858e8d3d8SSepherosa Ziehau	INTR_HANDLER(2)
40958e8d3d8SSepherosa Ziehau	INTR_HANDLER(3)
41058e8d3d8SSepherosa Ziehau	INTR_HANDLER(4)
41158e8d3d8SSepherosa Ziehau	INTR_HANDLER(5)
41258e8d3d8SSepherosa Ziehau	INTR_HANDLER(6)
41358e8d3d8SSepherosa Ziehau	INTR_HANDLER(7)
41458e8d3d8SSepherosa Ziehau	INTR_HANDLER(8)
41558e8d3d8SSepherosa Ziehau	INTR_HANDLER(9)
41658e8d3d8SSepherosa Ziehau	INTR_HANDLER(10)
41758e8d3d8SSepherosa Ziehau	INTR_HANDLER(11)
41858e8d3d8SSepherosa Ziehau	INTR_HANDLER(12)
41958e8d3d8SSepherosa Ziehau	INTR_HANDLER(13)
42058e8d3d8SSepherosa Ziehau	INTR_HANDLER(14)
42158e8d3d8SSepherosa Ziehau	INTR_HANDLER(15)
42258e8d3d8SSepherosa Ziehau	INTR_HANDLER(16)
42358e8d3d8SSepherosa Ziehau	INTR_HANDLER(17)
42458e8d3d8SSepherosa Ziehau	INTR_HANDLER(18)
42558e8d3d8SSepherosa Ziehau	INTR_HANDLER(19)
42658e8d3d8SSepherosa Ziehau	INTR_HANDLER(20)
42758e8d3d8SSepherosa Ziehau	INTR_HANDLER(21)
42858e8d3d8SSepherosa Ziehau	INTR_HANDLER(22)
42958e8d3d8SSepherosa Ziehau	INTR_HANDLER(23)
430c571da4aSSepherosa Ziehau	INTR_HANDLER(24)
431c571da4aSSepherosa Ziehau	INTR_HANDLER(25)
432c571da4aSSepherosa Ziehau	INTR_HANDLER(26)
433c571da4aSSepherosa Ziehau	INTR_HANDLER(27)
434c571da4aSSepherosa Ziehau	INTR_HANDLER(28)
435c571da4aSSepherosa Ziehau	INTR_HANDLER(29)
436c571da4aSSepherosa Ziehau	INTR_HANDLER(30)
437c571da4aSSepherosa Ziehau	INTR_HANDLER(31)
438c571da4aSSepherosa Ziehau	INTR_HANDLER(32)
439c571da4aSSepherosa Ziehau	INTR_HANDLER(33)
440c571da4aSSepherosa Ziehau	INTR_HANDLER(34)
441c571da4aSSepherosa Ziehau	INTR_HANDLER(35)
442c571da4aSSepherosa Ziehau	INTR_HANDLER(36)
443c571da4aSSepherosa Ziehau	INTR_HANDLER(37)
444c571da4aSSepherosa Ziehau	INTR_HANDLER(38)
445c571da4aSSepherosa Ziehau	INTR_HANDLER(39)
446c571da4aSSepherosa Ziehau	INTR_HANDLER(40)
447c571da4aSSepherosa Ziehau	INTR_HANDLER(41)
448c571da4aSSepherosa Ziehau	INTR_HANDLER(42)
449c571da4aSSepherosa Ziehau	INTR_HANDLER(43)
450c571da4aSSepherosa Ziehau	INTR_HANDLER(44)
451c571da4aSSepherosa Ziehau	INTR_HANDLER(45)
452c571da4aSSepherosa Ziehau	INTR_HANDLER(46)
453c571da4aSSepherosa Ziehau	INTR_HANDLER(47)
454c571da4aSSepherosa Ziehau	INTR_HANDLER(48)
455c571da4aSSepherosa Ziehau	INTR_HANDLER(49)
456c571da4aSSepherosa Ziehau	INTR_HANDLER(50)
457c571da4aSSepherosa Ziehau	INTR_HANDLER(51)
458c571da4aSSepherosa Ziehau	INTR_HANDLER(52)
459c571da4aSSepherosa Ziehau	INTR_HANDLER(53)
460c571da4aSSepherosa Ziehau	INTR_HANDLER(54)
461c571da4aSSepherosa Ziehau	INTR_HANDLER(55)
462c571da4aSSepherosa Ziehau	INTR_HANDLER(56)
463c571da4aSSepherosa Ziehau	INTR_HANDLER(57)
464c571da4aSSepherosa Ziehau	INTR_HANDLER(58)
465c571da4aSSepherosa Ziehau	INTR_HANDLER(59)
466c571da4aSSepherosa Ziehau	INTR_HANDLER(60)
467c571da4aSSepherosa Ziehau	INTR_HANDLER(61)
468c571da4aSSepherosa Ziehau	INTR_HANDLER(62)
469c571da4aSSepherosa Ziehau	INTR_HANDLER(63)
470c571da4aSSepherosa Ziehau	INTR_HANDLER(64)
471c571da4aSSepherosa Ziehau	INTR_HANDLER(65)
472c571da4aSSepherosa Ziehau	INTR_HANDLER(66)
473c571da4aSSepherosa Ziehau	INTR_HANDLER(67)
474c571da4aSSepherosa Ziehau	INTR_HANDLER(68)
475c571da4aSSepherosa Ziehau	INTR_HANDLER(69)
476c571da4aSSepherosa Ziehau	INTR_HANDLER(70)
477c571da4aSSepherosa Ziehau	INTR_HANDLER(71)
478c571da4aSSepherosa Ziehau	INTR_HANDLER(72)
479c571da4aSSepherosa Ziehau	INTR_HANDLER(73)
480c571da4aSSepherosa Ziehau	INTR_HANDLER(74)
481c571da4aSSepherosa Ziehau	INTR_HANDLER(75)
482c571da4aSSepherosa Ziehau	INTR_HANDLER(76)
483c571da4aSSepherosa Ziehau	INTR_HANDLER(77)
484c571da4aSSepherosa Ziehau	INTR_HANDLER(78)
485c571da4aSSepherosa Ziehau	INTR_HANDLER(79)
486c571da4aSSepherosa Ziehau	INTR_HANDLER(80)
487c571da4aSSepherosa Ziehau	INTR_HANDLER(81)
488c571da4aSSepherosa Ziehau	INTR_HANDLER(82)
489c571da4aSSepherosa Ziehau	INTR_HANDLER(83)
490c571da4aSSepherosa Ziehau	INTR_HANDLER(84)
491c571da4aSSepherosa Ziehau	INTR_HANDLER(85)
492c571da4aSSepherosa Ziehau	INTR_HANDLER(86)
493c571da4aSSepherosa Ziehau	INTR_HANDLER(87)
494c571da4aSSepherosa Ziehau	INTR_HANDLER(88)
495c571da4aSSepherosa Ziehau	INTR_HANDLER(89)
496c571da4aSSepherosa Ziehau	INTR_HANDLER(90)
497c571da4aSSepherosa Ziehau	INTR_HANDLER(91)
498c571da4aSSepherosa Ziehau	INTR_HANDLER(92)
499c571da4aSSepherosa Ziehau	INTR_HANDLER(93)
500c571da4aSSepherosa Ziehau	INTR_HANDLER(94)
501c571da4aSSepherosa Ziehau	INTR_HANDLER(95)
502c571da4aSSepherosa Ziehau	INTR_HANDLER(96)
503c571da4aSSepherosa Ziehau	INTR_HANDLER(97)
504c571da4aSSepherosa Ziehau	INTR_HANDLER(98)
505c571da4aSSepherosa Ziehau	INTR_HANDLER(99)
506c571da4aSSepherosa Ziehau	INTR_HANDLER(100)
507c571da4aSSepherosa Ziehau	INTR_HANDLER(101)
508c571da4aSSepherosa Ziehau	INTR_HANDLER(102)
509c571da4aSSepherosa Ziehau	INTR_HANDLER(103)
510c571da4aSSepherosa Ziehau	INTR_HANDLER(104)
511c571da4aSSepherosa Ziehau	INTR_HANDLER(105)
512c571da4aSSepherosa Ziehau	INTR_HANDLER(106)
513c571da4aSSepherosa Ziehau	INTR_HANDLER(107)
514c571da4aSSepherosa Ziehau	INTR_HANDLER(108)
515c571da4aSSepherosa Ziehau	INTR_HANDLER(109)
516c571da4aSSepherosa Ziehau	INTR_HANDLER(110)
517c571da4aSSepherosa Ziehau	INTR_HANDLER(111)
518c571da4aSSepherosa Ziehau	INTR_HANDLER(112)
519c571da4aSSepherosa Ziehau	INTR_HANDLER(113)
520c571da4aSSepherosa Ziehau	INTR_HANDLER(114)
521c571da4aSSepherosa Ziehau	INTR_HANDLER(115)
522c571da4aSSepherosa Ziehau	INTR_HANDLER(116)
523c571da4aSSepherosa Ziehau	INTR_HANDLER(117)
524c571da4aSSepherosa Ziehau	INTR_HANDLER(118)
525c571da4aSSepherosa Ziehau	INTR_HANDLER(119)
526c571da4aSSepherosa Ziehau	INTR_HANDLER(120)
527c571da4aSSepherosa Ziehau	INTR_HANDLER(121)
528c571da4aSSepherosa Ziehau	INTR_HANDLER(122)
529c571da4aSSepherosa Ziehau	INTR_HANDLER(123)
530c571da4aSSepherosa Ziehau	INTR_HANDLER(124)
531c571da4aSSepherosa Ziehau	INTR_HANDLER(125)
532c571da4aSSepherosa Ziehau	INTR_HANDLER(126)
533c571da4aSSepherosa Ziehau	INTR_HANDLER(127)
534c571da4aSSepherosa Ziehau	INTR_HANDLER(128)
535c571da4aSSepherosa Ziehau	INTR_HANDLER(129)
536c571da4aSSepherosa Ziehau	INTR_HANDLER(130)
537c571da4aSSepherosa Ziehau	INTR_HANDLER(131)
538c571da4aSSepherosa Ziehau	INTR_HANDLER(132)
539c571da4aSSepherosa Ziehau	INTR_HANDLER(133)
540c571da4aSSepherosa Ziehau	INTR_HANDLER(134)
541c571da4aSSepherosa Ziehau	INTR_HANDLER(135)
542c571da4aSSepherosa Ziehau	INTR_HANDLER(136)
543c571da4aSSepherosa Ziehau	INTR_HANDLER(137)
544c571da4aSSepherosa Ziehau	INTR_HANDLER(138)
545c571da4aSSepherosa Ziehau	INTR_HANDLER(139)
546c571da4aSSepherosa Ziehau	INTR_HANDLER(140)
547c571da4aSSepherosa Ziehau	INTR_HANDLER(141)
548c571da4aSSepherosa Ziehau	INTR_HANDLER(142)
549c571da4aSSepherosa Ziehau	INTR_HANDLER(143)
550c571da4aSSepherosa Ziehau	INTR_HANDLER(144)
551c571da4aSSepherosa Ziehau	INTR_HANDLER(145)
552c571da4aSSepherosa Ziehau	INTR_HANDLER(146)
553c571da4aSSepherosa Ziehau	INTR_HANDLER(147)
554c571da4aSSepherosa Ziehau	INTR_HANDLER(148)
555c571da4aSSepherosa Ziehau	INTR_HANDLER(149)
556c571da4aSSepherosa Ziehau	INTR_HANDLER(150)
557c571da4aSSepherosa Ziehau	INTR_HANDLER(151)
558c571da4aSSepherosa Ziehau	INTR_HANDLER(152)
559c571da4aSSepherosa Ziehau	INTR_HANDLER(153)
560c571da4aSSepherosa Ziehau	INTR_HANDLER(154)
561c571da4aSSepherosa Ziehau	INTR_HANDLER(155)
562c571da4aSSepherosa Ziehau	INTR_HANDLER(156)
563c571da4aSSepherosa Ziehau	INTR_HANDLER(157)
564c571da4aSSepherosa Ziehau	INTR_HANDLER(158)
565c571da4aSSepherosa Ziehau	INTR_HANDLER(159)
566c571da4aSSepherosa Ziehau	INTR_HANDLER(160)
567c571da4aSSepherosa Ziehau	INTR_HANDLER(161)
568c571da4aSSepherosa Ziehau	INTR_HANDLER(162)
569c571da4aSSepherosa Ziehau	INTR_HANDLER(163)
570c571da4aSSepherosa Ziehau	INTR_HANDLER(164)
571c571da4aSSepherosa Ziehau	INTR_HANDLER(165)
572c571da4aSSepherosa Ziehau	INTR_HANDLER(166)
573c571da4aSSepherosa Ziehau	INTR_HANDLER(167)
574c571da4aSSepherosa Ziehau	INTR_HANDLER(168)
575c571da4aSSepherosa Ziehau	INTR_HANDLER(169)
576c571da4aSSepherosa Ziehau	INTR_HANDLER(170)
577c571da4aSSepherosa Ziehau	INTR_HANDLER(171)
578c571da4aSSepherosa Ziehau	INTR_HANDLER(172)
579c571da4aSSepherosa Ziehau	INTR_HANDLER(173)
580c571da4aSSepherosa Ziehau	INTR_HANDLER(174)
581c571da4aSSepherosa Ziehau	INTR_HANDLER(175)
582c571da4aSSepherosa Ziehau	INTR_HANDLER(176)
583c571da4aSSepherosa Ziehau	INTR_HANDLER(177)
584c571da4aSSepherosa Ziehau	INTR_HANDLER(178)
585c571da4aSSepherosa Ziehau	INTR_HANDLER(179)
586c571da4aSSepherosa Ziehau	INTR_HANDLER(180)
587c571da4aSSepherosa Ziehau	INTR_HANDLER(181)
588c571da4aSSepherosa Ziehau	INTR_HANDLER(182)
589c571da4aSSepherosa Ziehau	INTR_HANDLER(183)
590c571da4aSSepherosa Ziehau	INTR_HANDLER(184)
591c571da4aSSepherosa Ziehau	INTR_HANDLER(185)
592c571da4aSSepherosa Ziehau	INTR_HANDLER(186)
593c571da4aSSepherosa Ziehau	INTR_HANDLER(187)
594c571da4aSSepherosa Ziehau	INTR_HANDLER(188)
595c571da4aSSepherosa Ziehau	INTR_HANDLER(189)
596c571da4aSSepherosa Ziehau	INTR_HANDLER(190)
597c571da4aSSepherosa Ziehau	INTR_HANDLER(191)
598c8fe38aeSMatthew DillonMCOUNT_LABEL(eintr)
599c8fe38aeSMatthew Dillon
600c8fe38aeSMatthew Dillon	.data
601c8fe38aeSMatthew Dillon
60206c66eb2SMatthew Dillon#if CPUMASK_ELEMENTS != 4
60306c66eb2SMatthew Dillon#error "assembly incompatible with cpumask_t"
60406c66eb2SMatthew Dillon#endif
605c8fe38aeSMatthew Dillon/* variables used by stop_cpus()/restart_cpus()/Xcpustop */
606c8fe38aeSMatthew Dillon	.globl stopped_cpus, started_cpus
607c8fe38aeSMatthew Dillonstopped_cpus:
608da23a592SMatthew Dillon	.quad	0
60906c66eb2SMatthew Dillon	.quad	0
61006c66eb2SMatthew Dillon	.quad	0
61106c66eb2SMatthew Dillon	.quad	0
612c8fe38aeSMatthew Dillonstarted_cpus:
613da23a592SMatthew Dillon	.quad	0
61406c66eb2SMatthew Dillon	.quad	0
61506c66eb2SMatthew Dillon	.quad	0
61606c66eb2SMatthew Dillon	.quad	0
617c8fe38aeSMatthew Dillon
618c8fe38aeSMatthew Dillon	.globl CNAME(cpustop_restartfunc)
619c8fe38aeSMatthew DillonCNAME(cpustop_restartfunc):
62046d4e165SJordan Gordeev	.quad 0
621c8fe38aeSMatthew Dillon
622c8fe38aeSMatthew Dillon	.text
623c8fe38aeSMatthew Dillon
624