Remove all remaining SPL code. Replace the mtd_cpl field in the machine
[dragonfly.git] / sys / i386 / apic / apic_vector.s
index 6bc664a..6d2aea9 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *     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 $
- * $DragonFly: src/sys/i386/apic/Attic/apic_vector.s,v 1.8 2003/07/06 21:23:49 dillon Exp $
+ * $DragonFly: src/sys/i386/apic/Attic/apic_vector.s,v 1.19 2005/06/16 21:12:47 dillon Exp $
  */
 
 
-#include <machine/apic.h>
+#include <machine/apicreg.h>
 #include <machine/smp.h>
 #include "i386/isa/intr_machdep.h"
 
@@ -38,7 +38,7 @@
        pushl   12(%esp) ;      /* original caller eip */               \
        pushl   $0 ;            /* dummy error code */                  \
        pushl   $0 ;            /* dummy trap type */                   \
-       subl    $11*4,%esp ;    /* pushal + 3 seg regs (dummy) */       \
+       subl    $12*4,%esp ;    /* pushal + 3 seg regs (dummy) + CPL */ \
 
 /*
  * Warning: POP_FRAME can only be used if there is no chance of a
@@ -53,7 +53,7 @@
        addl    $2*4,%esp ;     /* dummy trap & error codes */          \
 
 #define POP_DUMMY                                                      \
-       addl    $16*4,%esp ;                                            \
+       addl    $17*4,%esp ;                                            \
 
 #define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8
 #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
  *     - Push the trap frame required by doreti
  *     - Mask the interrupt and reenable its source
  *     - If we cannot take the interrupt set its fpending bit and
- *       doreti.
+ *       doreti.  Note that we cannot mess with mp_lock at all
+ *       if we entered from a critical section!
  *     - If we can take the interrupt clear its fpending bit,
  *       call the handler, then unmask and doreti.
  *
@@ -151,21 +152,24 @@ IDTVEC(vec_name) ;                                                        \
        FAKE_MCOUNT(13*4(%esp)) ;                                       \
        MASK_LEVEL_IRQ(irq_num) ;                                       \
        EOI_IRQ(irq_num) ;                                              \
-       incl    PCPU(intr_nesting_level) ;                              \
        movl    PCPU(curthread),%ebx ;                                  \
-       movl    TD_CPL(%ebx),%eax ;                                     \
+       movl    $0,%eax ;       /* CURRENT CPL IN FRAME (REMOVED) */    \
        pushl   %eax ;                                                  \
        cmpl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       jge     1f ;                                                    \
-       testl   $IRQ_LBIT(irq_num), %eax ;                              \
-       jz      2f ;                                                    \
+       jl      2f ;                                                    \
 1: ;                                                                   \
+       /* in critical section, make interrupt pending */               \
        /* set the pending bit and return, leave interrupt masked */    \
        orl     $IRQ_LBIT(irq_num),PCPU(fpending) ;                     \
-       movl    $TDPRI_CRIT, PCPU(reqpri) ;                             \
+       orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
        jmp     5f ;                                                    \
 2: ;                                                                   \
+       /* try to get the MP lock */                                    \
+       call    try_mplock ;                                            \
+       testl   %eax,%eax ;                                             \
+       jz      6f ;                                                    \
        /* clear pending bit, run handler */                            \
+       incl    PCPU(intr_nesting_level) ;                              \
        addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        andl    $~IRQ_LBIT(irq_num),PCPU(fpending) ;                    \
        pushl   intr_unit + (irq_num) * 4 ;                             \
@@ -175,10 +179,25 @@ IDTVEC(vec_name) ;                                                        \
        incl    PCPU(cnt)+V_INTR ;      /* book-keeping make per cpu YYY */ \
        movl    intr_countp + (irq_num) * 4, %eax ;                     \
        incl    (%eax) ;                                                \
+       decl    PCPU(intr_nesting_level) ;                              \
+       call    rel_mplock ;                                            \
        UNMASK_IRQ(irq_num) ;                                           \
 5: ;                                                                   \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
+6: ;                                                                   \
+       /* could not get the MP lock, forward the interrupt */          \
+       movl    mp_lock, %eax ;          /* check race */               \
+       cmpl    $MP_FREE_LOCK,%eax ;                                    \
+       je      2b ;                                                    \
+       incl    PCPU(cnt)+V_FORWARDED_INTS ;                            \
+       subl    $12,%esp ;                                              \
+       movl    $irq_num,8(%esp) ;                                      \
+       movl    $forward_fastint_remote,4(%esp) ;                       \
+       movl    %eax,(%esp) ;                                           \
+       call    lwkt_send_ipiq_bycpu ;                                  \
+       addl    $12,%esp ;                                              \
+       jmp     5f ;                                                    \
 
 /*
  * Restart fast interrupt held up by critical section or cpl.
@@ -190,6 +209,8 @@ IDTVEC(vec_name) ;                                                  \
  *     - Unmask the interrupt
  *     - Pop the dummy frame and do a normal return
  *
+ *     The BGL is held on call and left held on return.
+ *
  *     YYY can cache gd base pointer instead of using hidden %fs
  *     prefixes.
  */
@@ -220,18 +241,14 @@ IDTVEC(vec_name) ;                                                        \
  *     - If we cannot take the interrupt set its ipending bit and
  *       doreti.  In addition to checking for a critical section
  *       and cpl mask we also check to see if the thread is still
- *       running.
- *     - If we can take the interrupt clear its ipending bit,
- *       set its irunning bit, and schedule the thread.  Leave
- *       interrupts masked and doreti.
- *
- *     the interrupt thread will run its handlers and loop if
- *     ipending is found to be set.  ipending/irunning interlock
- *     the interrupt thread with the interrupt.  The handler calls
- *     UNPEND when it is through.
+ *       running.  Note that we cannot mess with mp_lock at all
+ *       if we entered from a critical section!
+ *     - If we can take the interrupt clear its ipending bit
+ *       and schedule the thread.  Leave interrupts masked and doreti.
  *
- *     Note that we do not enable interrupts when calling sched_ithd.
- *     YYY sched_ithd may preempt us synchronously (fix interrupt stacking)
+ *     Note that calls to sched_ithd() are made with interrupts enabled
+ *     and outside a critical section.  YYY sched_ithd may preempt us
+ *     synchronously (fix interrupt stacking).
  *
  *     YYY can cache gd base pointer instead of using hidden %fs
  *     prefixes.
@@ -246,31 +263,23 @@ IDTVEC(vec_name) ;                                                        \
 ;                                                                      \
        MASK_LEVEL_IRQ(irq_num) ;                                       \
        EOI_IRQ(irq_num) ;                                              \
-       incl    PCPU(intr_nesting_level) ;                              \
        movl    PCPU(curthread),%ebx ;                                  \
-       movl    TD_CPL(%ebx),%eax ;                                     \
+       movl    $0,%eax ;       /* CURRENT CPL IN FRAME (REMOVED) */    \
        pushl   %eax ;          /* cpl do restore */                    \
        cmpl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
-       jge     1f ;                                                    \
-       testl   $IRQ_LBIT(irq_num),PCPU(irunning) ;                     \
-       jnz     1f ;                                                    \
-       testl   $IRQ_LBIT(irq_num),%eax ;                               \
-       jz      1f ;                                                    \
+       jl      2f ;                                                    \
 1: ;                                                                   \
        /* set the pending bit and return, leave the interrupt masked */ \
        orl     $IRQ_LBIT(irq_num), PCPU(ipending) ;                    \
-       movl    $TDPRI_CRIT, PCPU(reqpri) ;                             \
+       orl     $RQF_INTPEND,PCPU(reqflags) ;                           \
        jmp     5f ;                                                    \
 2: ;                                                                   \
-       addl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        /* set running bit, clear pending bit, run handler */           \
-       orl     $IRQ_LBIT(irq_num), PCPU(irunning) ;                    \
        andl    $~IRQ_LBIT(irq_num), PCPU(ipending) ;                   \
        sti ;                                                           \
        pushl   $irq_num ;                                              \
        call    sched_ithd ;                                            \
        addl    $4,%esp ;                                               \
-       subl    $TDPRI_CRIT,TD_PRI(%ebx) ;                              \
        incl    PCPU(cnt)+V_INTR ; /* book-keeping YYY make per-cpu */  \
        movl    intr_countp + (irq_num) * 4,%eax ;                      \
        incl    (%eax) ;                                                \
@@ -278,41 +287,6 @@ IDTVEC(vec_name) ;                                                 \
        MEXITCOUNT ;                                                    \
        jmp     doreti ;                                                \
 
-/*
- * Unmask a slow interrupt.  This function is used by interrupt threads
- * after they have descheduled themselves to reenable interrupts and
- * possibly cause a reschedule to occur.  The interrupt's irunning bit
- * is cleared prior to unmasking.
- */
-
-#define INTR_UNMASK(irq_num, vec_name, icu)                            \
-       .text ;                                                         \
-       SUPERALIGN_TEXT ;                                               \
-IDTVEC(vec_name) ;                                                     \
-       pushl %ebp ;     /* frame for ddb backtrace */                  \
-       movl    %esp, %ebp ;                                            \
-       andl    $~IRQ_LBIT(irq_num), PCPU(irunning) ;                   \
-       UNMASK_IRQ(irq_num) ;                                           \
-       popl %ebp ;                                                     \
-       ret ;                                                           \
-
-#if 0
-       /* XXX forward_irq to cpu holding the BGL? */
-
-       ALIGN_TEXT ;                                                    \
-3: ;                   /* other cpu has isr lock */                    \
-       lock ;                                                          \
-       orl     $IRQ_LBIT(irq_num), PCPU(ipending) ;                    \
-       movl    $TDPRI_CRIT,_reqpri ;                                   \
-       testl   $IRQ_LBIT(irq_num), TD_CPL(%ebx) ;              \
-       jne     4f ;                            /* this INT masked */   \
-       call    forward_irq ;    /* forward irq to lock holder */       \
-       POP_FRAME ;                             /* and return */        \
-       iret ;                                                          \
-       ALIGN_TEXT ;                                                    \
-4: ;                                           /* blocked */           \
-       POP_FRAME ;                             /* and return */        \
-       iret
 
 /*
  * Handle "spurious INTerrupts".
@@ -321,9 +295,6 @@ IDTVEC(vec_name) ;                                                  \
  *   8259 PIC for missing INTs.  See the APIC documentation for details.
  *  This routine should NOT do an 'EOI' cycle.
  */
-
-#endif
-
        .text
        SUPERALIGN_TEXT
        .globl Xspuriousint
@@ -363,196 +334,6 @@ Xinvltlb:
        iret
 
 
-#if 0
-#ifdef BETTER_CLOCK
-
-/*
- * Executed by a CPU when it receives an Xcpucheckstate IPI from another CPU,
- *
- *  - Stores current cpu state in checkstate_cpustate[cpuid]
- *      0 == user, 1 == sys, 2 == intr
- *  - Stores current process in checkstate_curproc[cpuid]
- *
- *  - Signals its receipt by setting bit cpuid in checkstate_probed_cpus.
- *
- * stack: 0->ds, 4->fs, 8->ebx, 12->eax, 16->eip, 20->cs, 24->eflags
- */
-
-       .text
-       SUPERALIGN_TEXT
-       .globl Xcpucheckstate
-       .globl checkstate_cpustate
-       .globl checkstate_curproc
-       .globl checkstate_pc
-Xcpucheckstate:
-       pushl   %eax
-       pushl   %ebx            
-       pushl   %ds                     /* save current data segment */
-       pushl   %fs
-
-       movl    $KDSEL, %eax
-       mov     %ax, %ds                /* use KERNEL data segment */
-       movl    $KPSEL, %eax
-       mov     %ax, %fs
-
-       movl    $0, lapic_eoi           /* End Of Interrupt to APIC */
-
-       movl    $0, %ebx                
-       movl    20(%esp), %eax  
-       andl    $3, %eax
-       cmpl    $3, %eax
-       je      1f
-       testl   $PSL_VM, 24(%esp)
-       jne     1f
-       incl    %ebx                    /* system or interrupt */
-1:     
-       movl    PCPU(cpuid), %eax
-       movl    %ebx, checkstate_cpustate(,%eax,4)
-       movl    PCPU(curthread), %ebx
-       movl    TD_PROC(%ebx),%ebx
-       movl    %ebx, checkstate_curproc(,%eax,4)
-       movl    16(%esp), %ebx
-       movl    %ebx, checkstate_pc(,%eax,4)
-
-       lock                            /* checkstate_probed_cpus |= (1<<id) */
-       btsl    %eax, checkstate_probed_cpus
-
-       popl    %fs
-       popl    %ds                     /* restore previous data segment */
-       popl    %ebx
-       popl    %eax
-       iret
-
-#endif /* BETTER_CLOCK */
-#endif
-
-/*
- * Executed by a CPU when it receives an Xcpuast IPI from another CPU,
- *
- *  - Signals its receipt by clearing bit cpuid in checkstate_need_ast.
- *  - MP safe in regards to setting AST_PENDING because doreti is in
- *    a cli mode when it checks.
- */
-
-       .text
-       SUPERALIGN_TEXT
-       .globl Xcpuast
-Xcpuast:
-       PUSH_FRAME
-
-       movl    PCPU(cpuid), %eax
-       lock                            /* checkstate_need_ast &= ~(1<<id) */
-       btrl    %eax, checkstate_need_ast
-       movl    $0, lapic_eoi           /* End Of Interrupt to APIC */
-
-       lock
-       btsl    %eax, checkstate_pending_ast
-       jc      1f
-
-       FAKE_MCOUNT(13*4(%esp))
-
-       movl    PCPU(curthread), %eax
-       pushl   TD_CPL(%eax)            /* cpl restored by doreti */
-
-       orl     $AST_PENDING, PCPU(astpending)  /* XXX */
-       incb    PCPU(intr_nesting_level)
-       sti
-       
-       movl    PCPU(cpuid), %eax
-       lock    
-       btrl    %eax, checkstate_pending_ast
-       lock    
-       btrl    %eax, CNAME(resched_cpus)
-       jnc     2f
-       orl     $AST_PENDING+AST_RESCHED,PCPU(astpending)
-2:             
-       MEXITCOUNT
-       jmp     doreti
-1:
-       /* We are already in the process of delivering an ast for this CPU */
-       POP_FRAME
-       iret                    
-
-
-/*
- *      Executed by a CPU when it receives an XFORWARD_IRQ IPI.
- */
-
-       .text
-       SUPERALIGN_TEXT
-       .globl Xforward_irq
-Xforward_irq:
-       PUSH_FRAME
-
-       movl    $0, lapic_eoi           /* End Of Interrupt to APIC */
-
-       FAKE_MCOUNT(13*4(%esp))
-
-       call    try_mplock
-       testl   %eax,%eax               /* Did we get the lock ? */
-       jz  1f                          /* No */
-
-       incl    PCPU(cnt)+V_FORWARDED_HITS
-       
-       movl    PCPU(curthread), %eax
-       pushl   TD_CPL(%eax)            /* cpl restored by doreti */
-
-       incb    PCPU(intr_nesting_level)
-       sti
-       
-       MEXITCOUNT
-       jmp     doreti                  /* Handle forwarded interrupt */
-1:
-       incl    PCPU(cnt)+V_FORWARDED_MISSES
-       call    forward_irq     /* Oops, we've lost the isr lock */
-       MEXITCOUNT
-       POP_FRAME
-       iret
-3:     
-       call    rel_mplock
-       MEXITCOUNT
-       POP_FRAME
-       iret
-
-/*
- * 
- */
-forward_irq:
-       MCOUNT
-       cmpl    $0,invltlb_ok
-       jz      4f
-
-       cmpl    $0, CNAME(forward_irq_enabled)
-       jz      4f
-
-       movl    mp_lock,%eax
-       cmpl    $MP_FREE_LOCK,%eax
-       jne     1f
-       movl    $0, %eax                /* Pick CPU #0 if noone has lock */
-1:
-       shrl    $24,%eax
-       movl    cpu_num_to_apic_id(,%eax,4),%ecx
-       shll    $24,%ecx
-       movl    lapic_icr_hi, %eax
-       andl    $~APIC_ID_MASK, %eax
-       orl     %ecx, %eax
-       movl    %eax, lapic_icr_hi
-
-2:
-       movl    lapic_icr_lo, %eax
-       andl    $APIC_DELSTAT_MASK,%eax
-       jnz     2b
-       movl    lapic_icr_lo, %eax
-       andl    $APIC_RESV2_MASK, %eax
-       orl     $(APIC_DEST_DESTFLD|APIC_DELMODE_FIXED|XFORWARD_IRQ_OFFSET), %eax
-       movl    %eax, lapic_icr_lo
-3:
-       movl    lapic_icr_lo, %eax
-       andl    $APIC_DELSTAT_MASK,%eax
-       jnz     3b
-4:             
-       ret
-       
 /*
  * Executed by a CPU when it receives an Xcpustop IPI from another CPU,
  *
@@ -620,6 +401,37 @@ Xcpustop:
        popl    %ebp
        iret
 
+       /*
+        * For now just have one ipiq IPI, but what we really want is
+        * to have one for each source cpu to the APICs don't get stalled
+        * backlogging the requests.
+        */
+       .text
+       SUPERALIGN_TEXT
+       .globl Xipiq
+Xipiq:
+       PUSH_FRAME
+       movl    $0, lapic_eoi           /* End Of Interrupt to APIC */
+       FAKE_MCOUNT(13*4(%esp))
+
+       movl    PCPU(curthread),%ebx
+       cmpl    $TDPRI_CRIT,TD_PRI(%ebx)
+       jge     1f
+       subl    $8,%esp                 /* make same as interrupt frame */
+       incl    PCPU(intr_nesting_level)
+       addl    $TDPRI_CRIT,TD_PRI(%ebx)
+       call    lwkt_process_ipiq_frame
+       subl    $TDPRI_CRIT,TD_PRI(%ebx)
+       decl    PCPU(intr_nesting_level)
+       addl    $8,%esp
+       pushl   $0                      /* CPL for frame (REMOVED) */
+       MEXITCOUNT
+       jmp     doreti
+1:
+       orl     $RQF_IPIQ,PCPU(reqflags)
+       MEXITCOUNT
+       POP_FRAME
+       iret
 
 MCOUNT_LABEL(bintr)
        FAST_INTR(0,fastintr0)
@@ -648,12 +460,8 @@ MCOUNT_LABEL(bintr)
        FAST_INTR(23,fastintr23)
        
        /* YYY what is this garbage? */
-#define        CLKINTR_PENDING                                                 \
-       call    clock_lock ;                                            \
-       movl $1,CNAME(clkintr_pending) ;                                \
-       call    clock_unlock ;                                          \
 
-       INTR(0,intr0, CLKINTR_PENDING)
+       INTR(0,intr0,)
        INTR(1,intr1,)
        INTR(2,intr2,)
        INTR(3,intr3,)
@@ -729,39 +537,6 @@ Xrendezvous:
        
        .data
 
-#if 0
-/*
- * Addresses of interrupt handlers.
- *  XresumeNN: Resumption addresses for HWIs.
- */
-       .globl _ihandlers
-_ihandlers:
-/*
- * used by:
- *  ipl.s:     doreti_unpend
- */
-       .long   Xresume0,  Xresume1,  Xresume2,  Xresume3 
-       .long   Xresume4,  Xresume5,  Xresume6,  Xresume7
-       .long   Xresume8,  Xresume9,  Xresume10, Xresume11
-       .long   Xresume12, Xresume13, Xresume14, Xresume15 
-       .long   Xresume16, Xresume17, Xresume18, Xresume19
-       .long   Xresume20, Xresume21, Xresume22, Xresume23
-/*
- * used by:
- *  ipl.s:     doreti_unpend
- *  apic_ipl.s:        splz_unpend
- */
-       .long   _swi_null, swi_net, _swi_null, _swi_null
-       .long   _swi_vm, _swi_null, _softclock
-
-imasks:                                /* masks for interrupt handlers */
-       .space  NHWI*4          /* padding; HWI masks are elsewhere */
-
-       .long   SWI_TTY_MASK, SWI_NET_MASK, SWI_CAMNET_MASK, SWI_CAMBIO_MASK
-       .long   SWI_VM_MASK, SWI_TQ_MASK, SWI_CLOCK_MASK
-#endif /* 0 */
-
-
 #ifdef COUNT_XINVLTLB_HITS
        .globl  xhits
 xhits:
@@ -775,25 +550,10 @@ stopped_cpus:
 started_cpus:
        .long   0
 
-#ifdef BETTER_CLOCK
-       .globl checkstate_probed_cpus
-checkstate_probed_cpus:
-       .long   0       
-#endif /* BETTER_CLOCK */
-       .globl checkstate_need_ast
-checkstate_need_ast:
-       .long   0
-checkstate_pending_ast:
-       .long   0
-       .globl CNAME(resched_cpus)
        .globl CNAME(cpustop_restartfunc)
-CNAME(resched_cpus):
-       .long 0
 CNAME(cpustop_restartfunc):
        .long 0
                
-
-
        .globl  apic_pin_trigger
 apic_pin_trigger:
        .long   0