msi: Add interrupt vectors
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 23 Dec 2011 14:41:17 +0000 (22:41 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 27 Dec 2011 05:44:41 +0000 (13:44 +0800)
This is larged based on apic/apic_vector.s

sys/platform/pc64/conf/files
sys/platform/pc64/x86_64/msi_vector.s [new file with mode: 0644]

index bd77935..d1d8183 100644 (file)
@@ -165,6 +165,7 @@ libkern/stack_protector.c           standard
 # PLATFORM FILES
 #
 platform/pc64/x86_64/exception.S               standard
+platform/pc64/x86_64/msi_vector.s      standard
 platform/pc64/x86_64/ipl.s             standard
 platform/pc64/x86_64/global.s          standard
 platform/pc64/x86_64/support.s         standard
diff --git a/sys/platform/pc64/x86_64/msi_vector.s b/sys/platform/pc64/x86_64/msi_vector.s
new file mode 100644 (file)
index 0000000..9a993e4
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ *     from: vector.s, 386BSD 0.1 unknown origin
+ * $FreeBSD: src/sys/i386/isa/apic_vector.s,v 1.47.2.5 2001/09/01 22:33:38 tegge Exp $
+ */
+
+#include <machine/asmacros.h>
+#include <machine/lock.h>
+#include <machine/psl.h>
+#include <machine/trap.h>
+#include <machine/segments.h>
+
+#include "assym.s"
+
+#ifdef foo
+/* convert an absolute IRQ# into bitmask */
+#define IRQ_LBIT(irq_num)      (1UL << (irq_num & 0x3f))
+#endif
+
+#define IRQ_SBITS(irq_num)     ((irq_num) & 0x3f)
+
+/* convert an absolute IRQ# into gd_ipending index */
+#define IRQ_LIDX(irq_num)      ((irq_num) >> 6)
+
+#define MSI_PUSH_FRAME                                                 \
+       PUSH_FRAME ;            /* 15 regs + space for 5 extras */      \
+       movq $0,TF_XFLAGS(%rsp) ;                                       \
+       movq $0,TF_TRAPNO(%rsp) ;                                       \
+       movq $0,TF_ADDR(%rsp) ;                                         \
+       movq $0,TF_FLAGS(%rsp) ;                                        \
+       movq $0,TF_ERR(%rsp) ;                                          \
+       cld ;                                                           \
+
+/*
+ * Interrupt call handlers run in the following sequence:
+ *
+ *     - Push the trap frame required by doreti
+ *     - If we cannot take the interrupt set its ipending bit and
+ *       doreti.
+ *     - If we can take the interrupt clear its ipending bit,
+ *       call the handler and doreti.
+ *
+ * YYY can cache gd base opitner instead of using hidden %fs prefixes.
+ */
+
+#define        MSI_HANDLER(irq_num)                                            \
+       .text ;                                                         \
+       SUPERALIGN_TEXT ;                                               \
+IDTVEC(msi_intr##irq_num) ;                                            \
+       MSI_PUSH_FRAME ;                                                \
+       FAKE_MCOUNT(TF_RIP(%rsp)) ;                                     \
+       movq    lapic, %rax ;                                           \
+       movl    $0, LA_EOI(%rax) ;                                      \
+       movq    PCPU(curthread),%rbx ;                                  \
+       testl   $-1,TD_NEST_COUNT(%rbx) ;                               \
+       jne     1f ;                                                    \
+       testl   $-1,TD_CRITCOUNT(%rbx) ;                                \
+       je      2f ;                                                    \
+1: ;                                                                   \
+       /* in critical section, make interrupt pending */               \
+       /* set the pending bit and return, leave interrupt masked */    \
+       movq    $1,%rcx ;                                               \
+       shlq    $IRQ_SBITS(irq_num),%rcx ;                              \
+       movq    $IRQ_LIDX(irq_num),%rdx ;                               \
+       orq     %rcx,PCPU_E8(ipending,%rdx) ;                           \
+       orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
+       jmp     5f ;                                                    \
+2: ;                                                                   \
+       /* clear pending bit, run handler */                            \
+       movq    $1,%rcx ;                                               \
+       shlq    $IRQ_SBITS(irq_num),%rcx ;                              \
+       notq    %rcx ;                                                  \
+       movq    $IRQ_LIDX(irq_num),%rdx ;                               \
+       andq    %rcx,PCPU_E8(ipending,%rdx) ;                           \
+       pushq   $irq_num ;              /* trapframe -> intrframe */    \
+       movq    %rsp, %rdi ;            /* pass frame by reference */   \
+       incl    TD_CRITCOUNT(%rbx) ;                                    \
+       sti ;                                                           \
+       call    ithread_fast_handler ;                                  \
+       decl    TD_CRITCOUNT(%rbx) ;                                    \
+       addq    $8, %rsp ;              /* intrframe -> trapframe */    \
+5: ;                                                                   \
+       MEXITCOUNT ;                                                    \
+       jmp     doreti ;                                                \
+
+
+MCOUNT_LABEL(bintr)
+       MSI_HANDLER(16)
+       MSI_HANDLER(17)
+       MSI_HANDLER(18)
+       MSI_HANDLER(19)
+       MSI_HANDLER(20)
+       MSI_HANDLER(21)
+       MSI_HANDLER(22)
+       MSI_HANDLER(23)
+       MSI_HANDLER(24)
+       MSI_HANDLER(25)
+       MSI_HANDLER(26)
+       MSI_HANDLER(27)
+       MSI_HANDLER(28)
+       MSI_HANDLER(29)
+       MSI_HANDLER(30)
+       MSI_HANDLER(31)
+       MSI_HANDLER(32)
+       MSI_HANDLER(33)
+       MSI_HANDLER(34)
+       MSI_HANDLER(35)
+       MSI_HANDLER(36)
+       MSI_HANDLER(37)
+       MSI_HANDLER(38)
+       MSI_HANDLER(39)
+       MSI_HANDLER(40)
+       MSI_HANDLER(41)
+       MSI_HANDLER(42)
+       MSI_HANDLER(43)
+       MSI_HANDLER(44)
+       MSI_HANDLER(45)
+       MSI_HANDLER(46)
+       MSI_HANDLER(47)
+       MSI_HANDLER(48)
+       MSI_HANDLER(49)
+       MSI_HANDLER(50)
+       MSI_HANDLER(51)
+       MSI_HANDLER(52)
+       MSI_HANDLER(53)
+       MSI_HANDLER(54)
+       MSI_HANDLER(55)
+       MSI_HANDLER(56)
+       MSI_HANDLER(57)
+       MSI_HANDLER(58)
+       MSI_HANDLER(59)
+       MSI_HANDLER(60)
+       MSI_HANDLER(61)
+       MSI_HANDLER(62)
+       MSI_HANDLER(63)
+       MSI_HANDLER(64)
+       MSI_HANDLER(65)
+       MSI_HANDLER(66)
+       MSI_HANDLER(67)
+       MSI_HANDLER(68)
+       MSI_HANDLER(69)
+       MSI_HANDLER(70)
+       MSI_HANDLER(71)
+       MSI_HANDLER(72)
+       MSI_HANDLER(73)
+       MSI_HANDLER(74)
+       MSI_HANDLER(75)
+       MSI_HANDLER(76)
+       MSI_HANDLER(77)
+       MSI_HANDLER(78)
+       MSI_HANDLER(79)
+       MSI_HANDLER(80)
+       MSI_HANDLER(81)
+       MSI_HANDLER(82)
+       MSI_HANDLER(83)
+       MSI_HANDLER(84)
+       MSI_HANDLER(85)
+       MSI_HANDLER(86)
+       MSI_HANDLER(87)
+       MSI_HANDLER(88)
+       MSI_HANDLER(89)
+       MSI_HANDLER(90)
+       MSI_HANDLER(91)
+       MSI_HANDLER(92)
+       MSI_HANDLER(93)
+       MSI_HANDLER(94)
+       MSI_HANDLER(95)
+       MSI_HANDLER(96)
+       MSI_HANDLER(97)
+       MSI_HANDLER(98)
+       MSI_HANDLER(99)
+       MSI_HANDLER(100)
+       MSI_HANDLER(101)
+       MSI_HANDLER(102)
+       MSI_HANDLER(103)
+       MSI_HANDLER(104)
+       MSI_HANDLER(105)
+       MSI_HANDLER(106)
+       MSI_HANDLER(107)
+       MSI_HANDLER(108)
+       MSI_HANDLER(109)
+       MSI_HANDLER(110)
+       MSI_HANDLER(111)
+       MSI_HANDLER(112)
+       MSI_HANDLER(113)
+       MSI_HANDLER(114)
+       MSI_HANDLER(115)
+       MSI_HANDLER(116)
+       MSI_HANDLER(117)
+       MSI_HANDLER(118)
+       MSI_HANDLER(119)
+       MSI_HANDLER(120)
+       MSI_HANDLER(121)
+       MSI_HANDLER(122)
+       MSI_HANDLER(123)
+       MSI_HANDLER(124)
+       MSI_HANDLER(125)
+       MSI_HANDLER(126)
+       MSI_HANDLER(127)
+       MSI_HANDLER(128)
+       MSI_HANDLER(129)
+       MSI_HANDLER(130)
+       MSI_HANDLER(131)
+       MSI_HANDLER(132)
+       MSI_HANDLER(133)
+       MSI_HANDLER(134)
+       MSI_HANDLER(135)
+       MSI_HANDLER(136)
+       MSI_HANDLER(137)
+       MSI_HANDLER(138)
+       MSI_HANDLER(139)
+       MSI_HANDLER(140)
+       MSI_HANDLER(141)
+       MSI_HANDLER(142)
+       MSI_HANDLER(143)
+       MSI_HANDLER(144)
+       MSI_HANDLER(145)
+       MSI_HANDLER(146)
+       MSI_HANDLER(147)
+       MSI_HANDLER(148)
+       MSI_HANDLER(149)
+       MSI_HANDLER(150)
+       MSI_HANDLER(151)
+       MSI_HANDLER(152)
+       MSI_HANDLER(153)
+       MSI_HANDLER(154)
+       MSI_HANDLER(155)
+       MSI_HANDLER(156)
+       MSI_HANDLER(157)
+       MSI_HANDLER(158)
+       MSI_HANDLER(159)
+       MSI_HANDLER(160)
+       MSI_HANDLER(161)
+       MSI_HANDLER(162)
+       MSI_HANDLER(163)
+       MSI_HANDLER(164)
+       MSI_HANDLER(165)
+       MSI_HANDLER(166)
+       MSI_HANDLER(167)
+       MSI_HANDLER(168)
+       MSI_HANDLER(169)
+       MSI_HANDLER(170)
+       MSI_HANDLER(171)
+       MSI_HANDLER(172)
+       MSI_HANDLER(173)
+       MSI_HANDLER(174)
+       MSI_HANDLER(175)
+       MSI_HANDLER(176)
+       MSI_HANDLER(177)
+       MSI_HANDLER(178)
+       MSI_HANDLER(179)
+       MSI_HANDLER(180)
+       MSI_HANDLER(181)
+       MSI_HANDLER(182)
+       MSI_HANDLER(183)
+       MSI_HANDLER(184)
+       MSI_HANDLER(185)
+       MSI_HANDLER(186)
+       MSI_HANDLER(187)
+       MSI_HANDLER(188)
+       MSI_HANDLER(189)
+       MSI_HANDLER(190)
+       MSI_HANDLER(191)
+MCOUNT_LABEL(eintr)
+
+       .data
+
+       .text