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