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 $
6 #include <machine/asmacros.h>
7 #include <machine/lock.h>
8 #include <machine/psl.h>
9 #include <machine/trap.h>
10 #include <machine/segments.h>
15 /* convert an absolute IRQ# into bitmask */
16 #define IRQ_LBIT(irq_num) (1UL << (irq_num & 0x3f))
19 #define IRQ_SBITS(irq_num) ((irq_num) & 0x3f)
21 /* convert an absolute IRQ# into gd_ipending index */
22 #define IRQ_LIDX(irq_num) ((irq_num) >> 6)
24 #define MSI_PUSH_FRAME \
25 PUSH_FRAME ;
/* 15 regs + space for 5 extras */ \
26 movq $
0,TF_XFLAGS
(%rsp
) ; \
27 movq $
0,TF_TRAPNO
(%rsp
) ; \
28 movq $
0,TF_ADDR
(%rsp
) ; \
29 movq $
0,TF_FLAGS
(%rsp
) ; \
30 movq $
0,TF_ERR
(%rsp
) ; \
34 * Interrupt call handlers run in the following sequence:
36 * - Push the trap frame required by doreti
37 * - If we cannot take the interrupt set its ipending bit and
39 * - If we can take the interrupt clear its ipending bit,
40 * call the handler and doreti.
42 * YYY can cache gd base opitner instead of using hidden %fs prefixes.
45 #define MSI_HANDLER(irq_num) \
48 IDTVEC
(msi_intr
##irq_num) ; \
50 FAKE_MCOUNT
(TF_RIP
(%rsp
)) ; \
52 movl $
0, LA_EOI
(%rax
) ; \
53 movq PCPU
(curthread
),%rbx ; \
54 testl $
-1,TD_NEST_COUNT
(%rbx
) ; \
56 testl $
-1,TD_CRITCOUNT
(%rbx
) ; \
59 /* in critical section, make interrupt pending */ \
60 /* set the pending bit and return, leave interrupt masked */ \
62 shlq $IRQ_SBITS
(irq_num
),%rcx ; \
63 movq $IRQ_LIDX
(irq_num
),%rdx ; \
64 orq
%rcx
,PCPU_E8
(ipending
,%rdx
) ; \
65 orl $RQF_INTPEND
,PCPU
(reqflags
) ; \
68 /* clear pending bit, run handler */ \
70 shlq $IRQ_SBITS
(irq_num
),%rcx ; \
72 movq $IRQ_LIDX
(irq_num
),%rdx ; \
73 andq
%rcx
,PCPU_E8
(ipending
,%rdx
) ; \
74 pushq $irq_num ;
/* trapframe -> intrframe */ \
75 movq
%rsp
, %rdi ;
/* pass frame by reference */ \
76 incl TD_CRITCOUNT
(%rbx
) ; \
78 call ithread_fast_handler ; \
79 decl TD_CRITCOUNT
(%rbx
) ; \
80 addq $
8, %rsp ;
/* intrframe -> trapframe */ \