/* * 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 #include #include #include #include #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_TFRIP ; /* 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(0) MSI_HANDLER(1) MSI_HANDLER(2) MSI_HANDLER(3) MSI_HANDLER(4) MSI_HANDLER(5) MSI_HANDLER(6) MSI_HANDLER(7) MSI_HANDLER(8) MSI_HANDLER(9) MSI_HANDLER(10) MSI_HANDLER(11) MSI_HANDLER(12) MSI_HANDLER(13) MSI_HANDLER(14) MSI_HANDLER(15) 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