9a993e4e9eac59548d7c185f0c7c6750d92ce3fb
[dragonfly.git] / sys / platform / pc64 / x86_64 / msi_vector.s
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 #include <machine/asmacros.h>
7 #include <machine/lock.h>
8 #include <machine/psl.h>
9 #include <machine/trap.h>
10 #include <machine/segments.h>
11
12 #include "assym.s"
13
14 #ifdef foo
15 /* convert an absolute IRQ# into bitmask */
16 #define IRQ_LBIT(irq_num)       (1UL << (irq_num & 0x3f))
17 #endif
18
19 #define IRQ_SBITS(irq_num)      ((irq_num) & 0x3f)
20
21 /* convert an absolute IRQ# into gd_ipending index */
22 #define IRQ_LIDX(irq_num)       ((irq_num) >> 6)
23
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) ;                                          \
31         cld ;                                                           \
32
33 /*
34  * Interrupt call handlers run in the following sequence:
35  *
36  *      - Push the trap frame required by doreti
37  *      - If we cannot take the interrupt set its ipending bit and
38  *        doreti.
39  *      - If we can take the interrupt clear its ipending bit,
40  *        call the handler and doreti.
41  *
42  * YYY can cache gd base opitner instead of using hidden %fs prefixes.
43  */
44
45 #define MSI_HANDLER(irq_num)                                            \
46         .text ;                                                         \
47         SUPERALIGN_TEXT ;                                               \
48 IDTVEC(msi_intr##irq_num) ;                                             \
49         MSI_PUSH_FRAME ;                                                \
50         FAKE_MCOUNT(TF_RIP(%rsp)) ;                                     \
51         movq    lapic, %rax ;                                           \
52         movl    $0, LA_EOI(%rax) ;                                      \
53         movq    PCPU(curthread),%rbx ;                                  \
54         testl   $-1,TD_NEST_COUNT(%rbx) ;                               \
55         jne     1f ;                                                    \
56         testl   $-1,TD_CRITCOUNT(%rbx) ;                                \
57         je      2f ;                                                    \
58 1: ;                                                                    \
59         /* in critical section, make interrupt pending */               \
60         /* set the pending bit and return, leave interrupt masked */    \
61         movq    $1,%rcx ;                                               \
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) ;                           \
66         jmp     5f ;                                                    \
67 2: ;                                                                    \
68         /* clear pending bit, run handler */                            \
69         movq    $1,%rcx ;                                               \
70         shlq    $IRQ_SBITS(irq_num),%rcx ;                              \
71         notq    %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) ;                                    \
77         sti ;                                                           \
78         call    ithread_fast_handler ;                                  \
79         decl    TD_CRITCOUNT(%rbx) ;                                    \
80         addq    $8, %rsp ;              /* intrframe -> trapframe */    \
81 5: ;                                                                    \
82         MEXITCOUNT ;                                                    \
83         jmp     doreti ;                                                \
84
85
86 MCOUNT_LABEL(bintr)
87         MSI_HANDLER(16)
88         MSI_HANDLER(17)
89         MSI_HANDLER(18)
90         MSI_HANDLER(19)
91         MSI_HANDLER(20)
92         MSI_HANDLER(21)
93         MSI_HANDLER(22)
94         MSI_HANDLER(23)
95         MSI_HANDLER(24)
96         MSI_HANDLER(25)
97         MSI_HANDLER(26)
98         MSI_HANDLER(27)
99         MSI_HANDLER(28)
100         MSI_HANDLER(29)
101         MSI_HANDLER(30)
102         MSI_HANDLER(31)
103         MSI_HANDLER(32)
104         MSI_HANDLER(33)
105         MSI_HANDLER(34)
106         MSI_HANDLER(35)
107         MSI_HANDLER(36)
108         MSI_HANDLER(37)
109         MSI_HANDLER(38)
110         MSI_HANDLER(39)
111         MSI_HANDLER(40)
112         MSI_HANDLER(41)
113         MSI_HANDLER(42)
114         MSI_HANDLER(43)
115         MSI_HANDLER(44)
116         MSI_HANDLER(45)
117         MSI_HANDLER(46)
118         MSI_HANDLER(47)
119         MSI_HANDLER(48)
120         MSI_HANDLER(49)
121         MSI_HANDLER(50)
122         MSI_HANDLER(51)
123         MSI_HANDLER(52)
124         MSI_HANDLER(53)
125         MSI_HANDLER(54)
126         MSI_HANDLER(55)
127         MSI_HANDLER(56)
128         MSI_HANDLER(57)
129         MSI_HANDLER(58)
130         MSI_HANDLER(59)
131         MSI_HANDLER(60)
132         MSI_HANDLER(61)
133         MSI_HANDLER(62)
134         MSI_HANDLER(63)
135         MSI_HANDLER(64)
136         MSI_HANDLER(65)
137         MSI_HANDLER(66)
138         MSI_HANDLER(67)
139         MSI_HANDLER(68)
140         MSI_HANDLER(69)
141         MSI_HANDLER(70)
142         MSI_HANDLER(71)
143         MSI_HANDLER(72)
144         MSI_HANDLER(73)
145         MSI_HANDLER(74)
146         MSI_HANDLER(75)
147         MSI_HANDLER(76)
148         MSI_HANDLER(77)
149         MSI_HANDLER(78)
150         MSI_HANDLER(79)
151         MSI_HANDLER(80)
152         MSI_HANDLER(81)
153         MSI_HANDLER(82)
154         MSI_HANDLER(83)
155         MSI_HANDLER(84)
156         MSI_HANDLER(85)
157         MSI_HANDLER(86)
158         MSI_HANDLER(87)
159         MSI_HANDLER(88)
160         MSI_HANDLER(89)
161         MSI_HANDLER(90)
162         MSI_HANDLER(91)
163         MSI_HANDLER(92)
164         MSI_HANDLER(93)
165         MSI_HANDLER(94)
166         MSI_HANDLER(95)
167         MSI_HANDLER(96)
168         MSI_HANDLER(97)
169         MSI_HANDLER(98)
170         MSI_HANDLER(99)
171         MSI_HANDLER(100)
172         MSI_HANDLER(101)
173         MSI_HANDLER(102)
174         MSI_HANDLER(103)
175         MSI_HANDLER(104)
176         MSI_HANDLER(105)
177         MSI_HANDLER(106)
178         MSI_HANDLER(107)
179         MSI_HANDLER(108)
180         MSI_HANDLER(109)
181         MSI_HANDLER(110)
182         MSI_HANDLER(111)
183         MSI_HANDLER(112)
184         MSI_HANDLER(113)
185         MSI_HANDLER(114)
186         MSI_HANDLER(115)
187         MSI_HANDLER(116)
188         MSI_HANDLER(117)
189         MSI_HANDLER(118)
190         MSI_HANDLER(119)
191         MSI_HANDLER(120)
192         MSI_HANDLER(121)
193         MSI_HANDLER(122)
194         MSI_HANDLER(123)
195         MSI_HANDLER(124)
196         MSI_HANDLER(125)
197         MSI_HANDLER(126)
198         MSI_HANDLER(127)
199         MSI_HANDLER(128)
200         MSI_HANDLER(129)
201         MSI_HANDLER(130)
202         MSI_HANDLER(131)
203         MSI_HANDLER(132)
204         MSI_HANDLER(133)
205         MSI_HANDLER(134)
206         MSI_HANDLER(135)
207         MSI_HANDLER(136)
208         MSI_HANDLER(137)
209         MSI_HANDLER(138)
210         MSI_HANDLER(139)
211         MSI_HANDLER(140)
212         MSI_HANDLER(141)
213         MSI_HANDLER(142)
214         MSI_HANDLER(143)
215         MSI_HANDLER(144)
216         MSI_HANDLER(145)
217         MSI_HANDLER(146)
218         MSI_HANDLER(147)
219         MSI_HANDLER(148)
220         MSI_HANDLER(149)
221         MSI_HANDLER(150)
222         MSI_HANDLER(151)
223         MSI_HANDLER(152)
224         MSI_HANDLER(153)
225         MSI_HANDLER(154)
226         MSI_HANDLER(155)
227         MSI_HANDLER(156)
228         MSI_HANDLER(157)
229         MSI_HANDLER(158)
230         MSI_HANDLER(159)
231         MSI_HANDLER(160)
232         MSI_HANDLER(161)
233         MSI_HANDLER(162)
234         MSI_HANDLER(163)
235         MSI_HANDLER(164)
236         MSI_HANDLER(165)
237         MSI_HANDLER(166)
238         MSI_HANDLER(167)
239         MSI_HANDLER(168)
240         MSI_HANDLER(169)
241         MSI_HANDLER(170)
242         MSI_HANDLER(171)
243         MSI_HANDLER(172)
244         MSI_HANDLER(173)
245         MSI_HANDLER(174)
246         MSI_HANDLER(175)
247         MSI_HANDLER(176)
248         MSI_HANDLER(177)
249         MSI_HANDLER(178)
250         MSI_HANDLER(179)
251         MSI_HANDLER(180)
252         MSI_HANDLER(181)
253         MSI_HANDLER(182)
254         MSI_HANDLER(183)
255         MSI_HANDLER(184)
256         MSI_HANDLER(185)
257         MSI_HANDLER(186)
258         MSI_HANDLER(187)
259         MSI_HANDLER(188)
260         MSI_HANDLER(189)
261         MSI_HANDLER(190)
262         MSI_HANDLER(191)
263 MCOUNT_LABEL(eintr)
264
265         .data
266
267         .text