root/arch/i386/i386/apicvec.s

/* [<][>][^][v][top][bottom][index][help] */
    1 /* $OpenBSD: apicvec.s,v 1.10 2007/05/25 15:55:26 art Exp $ */
    2 /* $NetBSD: apicvec.s,v 1.1.2.2 2000/02/21 21:54:01 sommerfeld Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by RedBack Networks Inc.
   10  *
   11  * Author: Bill Sommerfeld
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. All advertising materials mentioning features or use of this software
   22  *    must display the following acknowledgement:
   23  *        This product includes software developed by the NetBSD
   24  *        Foundation, Inc. and its contributors.
   25  * 4. Neither the name of The NetBSD Foundation nor the names of its
   26  *    contributors may be used to endorse or promote products derived
   27  *    from this software without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   30  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   32  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   33  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   34  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   35  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   36  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   37  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   39  * POSSIBILITY OF SUCH DAMAGE.
   40  */
   41 
   42 #include <machine/i82093reg.h>
   43 #include <machine/i82489reg.h>
   44 
   45 #ifdef __ELF__
   46 #define XINTR(vec) Xintr/**/vec
   47 #else
   48 #define XINTR(vec) _Xintr/**/vec
   49 #endif
   50 
   51         .globl  _C_LABEL(apic_stray)
   52 
   53 #ifdef MULTIPROCESSOR
   54         .globl  XINTR(ipi)
   55 XINTR(ipi):
   56         pushl   $0
   57         pushl   $T_ASTFLT
   58         INTRENTRY
   59         MAKE_FRAME
   60         pushl   CPL
   61         movl    _C_LABEL(lapic_ppr),%eax
   62         movl    %eax,CPL
   63         ioapic_asm_ack()
   64         sti                     /* safe to take interrupts.. */
   65         call    _C_LABEL(i386_ipi_handler)
   66         cli
   67         popl    CPL
   68         INTRFASTEXIT
   69 
   70         .globl XINTR(ipi_ast)
   71 XINTR(ipi_ast):
   72         pushl   %eax
   73         pushl   %ds
   74         movl    $GSEL(GDATA_SEL, SEL_KPL), %eax
   75         movl    %eax, %ds
   76 
   77         ioapic_asm_ack()
   78 
   79         movl    $IPL_SOFTAST, %eax
   80         orl     $(1 << SIR_AST), _C_LABEL(ipending)
   81 
   82         orl     $(LAPIC_DLMODE_FIXED|LAPIC_LVL_ASSERT|LAPIC_DEST_SELF), %eax
   83         movl    %eax, _C_LABEL(local_apic) + LAPIC_ICRLO
   84 
   85         movl    _C_LABEL(local_apic) + LAPIC_ID, %eax
   86         popl    %ds
   87         popl    %eax
   88         iret
   89 
   90         .globl  XINTR(ipi_invltlb)
   91         .p2align 4,0x90
   92 XINTR(ipi_invltlb):
   93         pushl   %eax
   94         pushl   %ds
   95         movl    $GSEL(GDATA_SEL, SEL_KPL), %eax
   96         movl    %eax, %ds
   97 
   98         ioapic_asm_ack()
   99 
  100         movl    %cr3, %eax
  101         movl    %eax, %cr3
  102 
  103         lock
  104         decl    tlb_shoot_wait
  105 
  106         popl    %ds
  107         popl    %eax
  108         iret
  109 
  110         .globl  XINTR(ipi_invlpg)
  111         .p2align 4,0x90
  112 XINTR(ipi_invlpg):
  113         pushl   %eax
  114         pushl   %ds
  115         movl    $GSEL(GDATA_SEL, SEL_KPL), %eax
  116         movl    %eax, %ds
  117 
  118         ioapic_asm_ack()
  119 
  120         movl    tlb_shoot_addr1, %eax
  121         invlpg  (%eax)
  122 
  123         lock
  124         decl    tlb_shoot_wait
  125 
  126         popl    %ds
  127         popl    %eax
  128         iret
  129 
  130         .globl  XINTR(ipi_invlrange)
  131         .p2align 4,0x90
  132 XINTR(ipi_invlrange):
  133         pushl   %eax
  134         pushl   %edx
  135         pushl   %ds
  136         movl    $GSEL(GDATA_SEL, SEL_KPL), %eax
  137         movl    %eax, %ds
  138 
  139         ioapic_asm_ack()
  140 
  141         movl    tlb_shoot_addr1, %eax
  142         movl    tlb_shoot_addr2, %edx
  143 1:      invlpg  (%eax)
  144         addl    $PAGE_SIZE, %eax
  145         cmpl    %edx, %eax
  146         jb      1b
  147 
  148         lock
  149         decl    tlb_shoot_wait
  150 
  151         popl    %ds
  152         popl    %edx
  153         popl    %eax
  154         iret
  155 
  156 #endif
  157 
  158         /*
  159          * Interrupt from the local APIC timer.
  160          */
  161         .globl  XINTR(ltimer)
  162 XINTR(ltimer):
  163         pushl   $0
  164         pushl   $T_ASTFLT
  165         INTRENTRY
  166         MAKE_FRAME
  167         pushl   CPL
  168         movl    _C_LABEL(lapic_ppr),%eax
  169         movl    %eax,CPL
  170         ioapic_asm_ack()
  171         sti
  172 #ifdef MULTIPROCESSOR
  173         call    _C_LABEL(i386_softintlock)
  174 #endif
  175         movl    %esp,%eax
  176         pushl   %eax
  177         call    _C_LABEL(lapic_clockintr)
  178         addl    $4,%esp
  179 #ifdef MULTIPROCESSOR
  180         call    _C_LABEL(i386_softintunlock)
  181 #endif
  182         jmp     _C_LABEL(Xdoreti)
  183 
  184         .globl  XINTR(softclock), XINTR(softnet), XINTR(softtty), XINTR(softast)
  185 XINTR(softclock):
  186         pushl   $0
  187         pushl   $T_ASTFLT
  188         INTRENTRY
  189         MAKE_FRAME
  190         pushl   CPL
  191         movl    $IPL_SOFTCLOCK,CPL
  192         andl    $~(1<<SIR_CLOCK),_C_LABEL(ipending)
  193         ioapic_asm_ack()
  194         sti
  195 #ifdef MULTIPROCESSOR
  196         call    _C_LABEL(i386_softintlock)
  197 #endif
  198         call    _C_LABEL(softclock)
  199 #ifdef MULTIPROCESSOR
  200         call    _C_LABEL(i386_softintunlock)
  201 #endif
  202         jmp     _C_LABEL(Xdoreti)
  203 
  204 #define DONETISR(s, c) \
  205         .globl  _C_LABEL(c)     ;\
  206         testl   $(1 << s),%edi  ;\
  207         jz      1f              ;\
  208         call    _C_LABEL(c)     ;\
  209 1:
  210 
  211 XINTR(softnet):
  212         pushl   $0
  213         pushl   $T_ASTFLT
  214         INTRENTRY
  215         MAKE_FRAME
  216         pushl   CPL
  217         movl    $IPL_SOFTNET,CPL
  218         andl    $~(1<<SIR_NET),_C_LABEL(ipending)
  219         ioapic_asm_ack()
  220         sti
  221 #ifdef MULTIPROCESSOR
  222         call    _C_LABEL(i386_softintlock)
  223 #endif
  224         xorl    %edi,%edi
  225         xchgl   _C_LABEL(netisr),%edi
  226 #include <net/netisr_dispatch.h>
  227 #ifdef MULTIPROCESSOR
  228         call    _C_LABEL(i386_softintunlock)
  229 #endif
  230         jmp     _C_LABEL(Xdoreti)
  231 #undef DONETISR
  232 
  233 XINTR(softtty):
  234         pushl   $0
  235         pushl   $T_ASTFLT
  236         INTRENTRY
  237         MAKE_FRAME
  238         pushl   CPL
  239         movl    $IPL_SOFTTTY,CPL
  240         andl    $~(1<<SIR_TTY),_C_LABEL(ipending)
  241         ioapic_asm_ack()
  242         sti
  243 #ifdef MULTIPROCESSOR
  244         call    _C_LABEL(i386_softintlock)
  245 #endif
  246         call    _C_LABEL(comsoft)
  247 #ifdef MULTIPROCESSOR
  248         call    _C_LABEL(i386_softintunlock)
  249 #endif
  250         jmp     _C_LABEL(Xdoreti)
  251 
  252 XINTR(softast):
  253         pushl   $0
  254         pushl   $T_ASTFLT
  255         INTRENTRY
  256         MAKE_FRAME
  257         pushl   CPL
  258         movl    $IPL_SOFTAST,CPL
  259         andl    $~(1<<SIR_AST),_C_LABEL(ipending)
  260         ioapic_asm_ack()
  261         sti
  262         jmp     _C_LABEL(Xdoreti)
  263 
  264 #if NIOAPIC > 0
  265 
  266 #define voidop(num)
  267 
  268         /*
  269          * I/O APIC interrupt.
  270          * We sort out which one is which based on the value of
  271          * the processor priority register.
  272          *
  273          * XXX use cmove when appropriate.
  274          */
  275 
  276 #define APICINTR(name, num, early_ack, late_ack, mask, unmask, level_mask) \
  277 _C_LABEL(Xintr_/**/name/**/num):                                        \
  278         pushl   $0                                                      ;\
  279         pushl   $T_ASTFLT                                               ;\
  280         INTRENTRY                                                       ;\
  281         MAKE_FRAME                                                      ;\
  282         pushl   CPL                                                     ;\
  283         movl    _C_LABEL(lapic_ppr),%eax                                ;\
  284         orl     $num,%eax                                               ;\
  285         movl    _C_LABEL(apic_maxlevel)(,%eax,4),%ebx                   ;\
  286         movl    %ebx,CPL                                                ;\
  287         mask(num)                       /* mask it in hardware */       ;\
  288         early_ack(num)                  /* and allow other intrs */     ;\
  289         incl    MY_COUNT+V_INTR         /* statistical info */          ;\
  290         sti                                                             ;\
  291         incl    _C_LABEL(apic_intrcount)(,%eax,4)                       ;\
  292         movl    _C_LABEL(apic_intrhand)(,%eax,4),%ebx /* chain head */  ;\
  293         testl   %ebx,%ebx                                               ;\
  294         jz      _C_LABEL(Xstray_/**/name/**/num)                        ;\
  295         APIC_STRAY_INIT                 /* nobody claimed it yet */     ;\
  296 7:                                                                       \
  297         LOCK_KERNEL(IF_PPL(%esp))                                       ;\
  298         movl    IH_ARG(%ebx),%eax       /* get handler arg */           ;\
  299         testl   %eax,%eax                                               ;\
  300         jnz     6f                                                      ;\
  301         movl    %esp,%eax               /* 0 means frame pointer */     ;\
  302 6:                                                                       \
  303         pushl   %eax                                                    ;\
  304         call    *IH_FUN(%ebx)           /* call it */                   ;\
  305         addl    $4,%esp                 /* toss the arg */              ;\
  306         APIC_STRAY_INTEGRATE            /* maybe he claimed it */       ;\
  307         orl     %eax,%eax               /* should it be counted? */     ;\
  308         jz      4f                                                      ;\
  309         addl    $1,IH_COUNT(%ebx)       /* count the intrs */           ;\
  310         adcl    $0,IH_COUNT+4(%ebx)                                     ;\
  311 4:                                                                       \
  312         UNLOCK_KERNEL(IF_PPL(%esp))                                     ;\
  313         movl    IH_NEXT(%ebx),%ebx      /* next handler in chain */     ;\
  314         testl   %ebx,%ebx                                               ;\
  315         jnz     7b                                                      ;\
  316         APIC_STRAY_TEST(name,num)       /* see if it's a stray */       ;\
  317 8:                                                                       \
  318         unmask(num)                     /* unmask it in hardware */     ;\
  319         late_ack(num)                                                   ;\
  320         jmp     _C_LABEL(Xdoreti)                                       ;\
  321 _C_LABEL(Xstray_/**/name/**/num):                                        \
  322         pushl   $num                                                    ;\
  323         call    _C_LABEL(apic_stray)                                    ;\
  324         addl    $4,%esp                                                 ;\
  325         jmp     8b                                                      ;\
  326 
  327 #if defined(DEBUG)
  328 #define APIC_STRAY_INIT \
  329         xorl    %esi,%esi
  330 #define APIC_STRAY_INTEGRATE \
  331         orl     %eax,%esi
  332 #define APIC_STRAY_TEST(name,num) \
  333         testl   %esi,%esi                                               ;\
  334         jz      _C_LABEL(Xstray_/**/name/**/num)
  335 #else /* !DEBUG */
  336 #define APIC_STRAY_INIT
  337 #define APIC_STRAY_INTEGRATE
  338 #define APIC_STRAY_TEST(name,num)
  339 #endif /* DEBUG */
  340 
  341 APICINTR(ioapic,0, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  342 APICINTR(ioapic,1, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  343 APICINTR(ioapic,2, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  344 APICINTR(ioapic,3, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  345 APICINTR(ioapic,4, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  346 APICINTR(ioapic,5, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  347 APICINTR(ioapic,6, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  348 APICINTR(ioapic,7, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  349 APICINTR(ioapic,8, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  350 APICINTR(ioapic,9, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  351 APICINTR(ioapic,10, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  352 APICINTR(ioapic,11, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  353 APICINTR(ioapic,12, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  354 APICINTR(ioapic,13, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  355 APICINTR(ioapic,14, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  356 APICINTR(ioapic,15, voidop, ioapic_asm_ack, voidop, voidop, voidop)
  357 
  358         .globl  _C_LABEL(Xintr_ioapic0),_C_LABEL(Xintr_ioapic1)
  359         .globl  _C_LABEL(Xintr_ioapic2),_C_LABEL(Xintr_ioapic3)
  360         .globl  _C_LABEL(Xintr_ioapic4),_C_LABEL(Xintr_ioapic5)
  361         .globl  _C_LABEL(Xintr_ioapic6),_C_LABEL(Xintr_ioapic7)
  362         .globl  _C_LABEL(Xintr_ioapic8),_C_LABEL(Xintr_ioapic9)
  363         .globl  _C_LABEL(Xintr_ioapic10),_C_LABEL(Xintr_ioapic11)
  364         .globl  _C_LABEL(Xintr_ioapic12),_C_LABEL(Xintr_ioapic13)
  365         .globl  _C_LABEL(Xintr_ioapic14),_C_LABEL(Xintr_ioapic15)
  366         .globl _C_LABEL(apichandler)
  367 
  368 _C_LABEL(apichandler):
  369         .long   _C_LABEL(Xintr_ioapic0),_C_LABEL(Xintr_ioapic1)
  370         .long   _C_LABEL(Xintr_ioapic2),_C_LABEL(Xintr_ioapic3)
  371         .long   _C_LABEL(Xintr_ioapic4),_C_LABEL(Xintr_ioapic5)
  372         .long   _C_LABEL(Xintr_ioapic6),_C_LABEL(Xintr_ioapic7)
  373         .long   _C_LABEL(Xintr_ioapic8),_C_LABEL(Xintr_ioapic9)
  374         .long   _C_LABEL(Xintr_ioapic10),_C_LABEL(Xintr_ioapic11)
  375         .long   _C_LABEL(Xintr_ioapic12),_C_LABEL(Xintr_ioapic13)
  376         .long   _C_LABEL(Xintr_ioapic14),_C_LABEL(Xintr_ioapic15)
  377 
  378 #endif
  379 

/* [<][>][^][v][top][bottom][index][help] */