[BACK]Return to spl.S CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / amd64 / amd64

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/amd64/amd64/spl.S between version 1.3 and 1.3.12.8

version 1.3, 2004/06/28 09:13:11 version 1.3.12.8, 2008/02/27 08:36:18
Line 36 
Line 36 
  */   */
   
 /*  /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.   * Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
  * All rights reserved.   * All rights reserved.
  *   *
  * This code is derived from software contributed to The NetBSD Foundation   * This code is derived from software contributed to The NetBSD Foundation
  * by Charles M. Hannum.   * by Charles M. Hannum and Andrew Doran.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 76 
Line 76 
 #define ALIGN_TEXT      .align 16,0x90  #define ALIGN_TEXT      .align 16,0x90
   
 #include <machine/asm.h>  #include <machine/asm.h>
 #include <machine/psl.h>  
 #include <machine/trap.h>  #include <machine/trap.h>
 #include <machine/segments.h>  #include <machine/segments.h>
 #include <machine/frameasm.h>  #include <machine/frameasm.h>
   
 #include "assym.h"  #include "assym.h"
   
         .data  
         .globl  _C_LABEL(netisr)  
         .text          .text
   
 #if 0  #ifndef XEN
 #if defined(PROF) || defined(GPROF)  
 /*  /*
  * XXXX TODO   * softintr()
    *
    * Switch to the LWP assigned to handle interrupts from the given
    * source.  We borrow the VM context from the interrupted LWP.
    *
    * On entry:
    *
    *      %rax            intrsource
    *      %r13            address to return to
  */   */
         .globl  _C_LABEL(splhigh), _C_LABEL(splx)  IDTVEC(softintr)
           pushq   $_C_LABEL(softintr_ret) /* set up struct switchframe */
           pushq   %rbx
           pushq   %r12
           pushq   %r13
           pushq   %r14
           pushq   %r15
           movl    $IPL_HIGH,CPUVAR(ILEVEL)
           movq    CPUVAR(CURLWP),%r15
           movq    IS_LWP(%rax),%rdi       /* switch to handler LWP */
           movq    L_ADDR(%rdi),%rdx
           movq    L_ADDR(%r15),%rcx
           movq    %rdi,CPUVAR(CURLWP)
           movq    %rsp,PCB_RSP(%rcx)
           movq    %rbp,PCB_RBP(%rcx)
           movq    PCB_RSP0(%rdx),%rsp     /* onto new stack */
           sti
           movq    %r15,%rdi               /* interrupted LWP */
           movl    IS_MAXLEVEL(%rax),%esi  /* ipl to run at */
           call    _C_LABEL(softint_dispatch)/* run handlers */
           movq    L_ADDR(%r15),%rcx
           movq    PCB_RSP(%rcx),%rsp
           xchgq   %r15,CPUVAR(CURLWP)     /* must be globally visible */
           popq    %r15                    /* unwind switchframe */
           addq    $(5 * 8),%rsp
           cli
           jmp     *%r13                   /* back to splx/doreti */
   
         ALIGN_TEXT  /*
 _C_LABEL(splhigh):   * softintr_ret()
         movl    $IPL_HIGH,%eax   *
         xchgl   %eax,CPUVAR(ILEVEL)   * Trampoline function that gets returned to by cpu_switchto() when
    * an interrupt handler blocks.  On entry:
    *
    *      %rax            prevlwp from cpu_switchto()
    */
   NENTRY(softintr_ret)
           incl    CPUVAR(MTX_COUNT)       /* re-adjust after mi_switch */
           movl    $0, L_CTXSWTCH(%rax)    /* %rax from cpu_switchto */
           cli
           jmp     *%r13                   /* back to splx/doreti */
   
   /*
    * void softint_trigger(uintptr_t machdep);
    *
    * Software interrupt registration.
    */
   NENTRY(softint_trigger)
           orl     %edi,CPUVAR(IPENDING)   /* atomic on local cpu */
         ret          ret
   
         ALIGN_TEXT  /*
 _C_LABEL(splx):   * int splraise(int s);
         movl    4(%esp),%eax   */
         movl    %eax,CPUVAR(ILEVEL)  ENTRY(splraise)
         testl   %eax,%eax          movl    CPUVAR(ILEVEL),%eax
         jnz     _C_LABEL(Xspllower)          cmpl    %edi,%eax
           cmoval  %eax,%edi
           movl    %edi,CPUVAR(ILEVEL)
         ret          ret
 #endif /* PROF || GPROF */  
 #endif  /*
    * void spllower(int s);
    *
    * Must be the same size as i686_spllower().  This must use
    * pushf/cli/popf as it is used early in boot where interrupts
    * are disabled via eflags/IE.
    */
   ENTRY(spllower)
           cmpl    CPUVAR(ILEVEL), %edi
           jae     1f
           movl    CPUVAR(IUNMASK)(,%rdi,4), %edx
           pushf
           cli
           testl   CPUVAR(IPENDING), %edx
           jnz     2f
           movl    %edi, CPUVAR(ILEVEL)
           popf
   1:
           ret
           ret
   2:
           popf
           jmp     _C_LABEL(Xspllower)
           nop
           nop
           .align  16
   LABEL(spllower_end)
   
   #endif /* !XEN */
   
   /*
    * void cx8_spllower(int s);
    *
    * For cmpxchg8b, edx/ecx are the high words and eax/ebx the low.
    *
    * edx : eax = old level / old ipending
    * ecx : ebx = new level / old ipending
    */
   ENTRY(cx8_spllower)
           movl    CPUVAR(ILEVEL),%edx
           movq    %rbx,%r8
           cmpl    %edx,%edi                       /* new level is lower? */
           jae,pn  1f
   0:
           movl    CPUVAR(IPENDING),%eax
           movl    %edi,%ecx
           testl   %eax,CPUVAR(IUNMASK)(,%rcx,4)/* deferred interrupts? */
           movl    %eax,%ebx
           /*
            * On the P4 this jump is cheaper than patching in junk
            * using cmov.  Is cmpxchg expensive if it fails?
            */
           jnz,pn  2f
           cmpxchg8b CPUVAR(ISTATE)                /* swap in new ilevel */
           jnz,pn  0b
   1:
           movq    %r8,%rbx
           ret
   2:
           movq    %r8,%rbx
   LABEL(cx8_spllower_patch)
           jmp     _C_LABEL(Xspllower)
   
           .align  16
   LABEL(cx8_spllower_end)
   
 /*  /*
    * void Xspllower(int s);
    *
  * Process pending interrupts.   * Process pending interrupts.
  *   *
  * Important registers:   * Important registers:
Line 125  _C_LABEL(splx):
Line 240  _C_LABEL(splx):
  * the sending CPU will never see the that CPU accept the IPI   * the sending CPU will never see the that CPU accept the IPI
  * (see pmap_tlb_shootnow).   * (see pmap_tlb_shootnow).
  */   */
           nop
           .align  4       /* Avoid confusion with cx8_spllower_end */
   
 IDTVEC(spllower)  IDTVEC(spllower)
         pushq   %rbx          pushq   %rbx
         pushq   %r13          pushq   %r13
Line 133  IDTVEC(spllower)
Line 251  IDTVEC(spllower)
         leaq    1f(%rip),%r13           # address to resume loop at          leaq    1f(%rip),%r13           # address to resume loop at
 1:      movl    %ebx,%eax               # get cpl  1:      movl    %ebx,%eax               # get cpl
         movl    CPUVAR(IUNMASK)(,%rax,4),%eax          movl    CPUVAR(IUNMASK)(,%rax,4),%eax
         cli          CLI(si)
         andl    CPUVAR(IPENDING),%eax           # any non-masked bits left?          andl    CPUVAR(IPENDING),%eax           # any non-masked bits left?
         jz      2f          jz      2f
         bsrl    %eax,%eax          bsrl    %eax,%eax
Line 142  IDTVEC(spllower)
Line 260  IDTVEC(spllower)
         jmp     *IS_RECURSE(%rax)          jmp     *IS_RECURSE(%rax)
 2:  2:
         movl    %ebx,CPUVAR(ILEVEL)          movl    %ebx,CPUVAR(ILEVEL)
         sti          STI(si)
         popq    %r12          popq    %r12
         popq    %r13          popq    %r13
         popq    %rbx          popq    %rbx
Line 161  IDTVEC(doreti)
Line 279  IDTVEC(doreti)
         leaq    1f(%rip),%r13          leaq    1f(%rip),%r13
 1:      movl    %ebx,%eax  1:      movl    %ebx,%eax
         movl    CPUVAR(IUNMASK)(,%rax,4),%eax          movl    CPUVAR(IUNMASK)(,%rax,4),%eax
         cli          CLI(si)
         andl    CPUVAR(IPENDING),%eax          andl    CPUVAR(IPENDING),%eax
         jz      2f          jz      2f
         bsrl    %eax,%eax               # slow, but not worth optimizing          bsrl    %eax,%eax               # slow, but not worth optimizing
Line 170  IDTVEC(doreti)
Line 288  IDTVEC(doreti)
         jmp     *IS_RESUME(%rax)          jmp     *IS_RESUME(%rax)
 2:      /* Check for ASTs on exit to user mode. */  2:      /* Check for ASTs on exit to user mode. */
         movl    %ebx,CPUVAR(ILEVEL)          movl    %ebx,CPUVAR(ILEVEL)
 5:      CHECK_ASTPENDING(%r11)  5:
         je      3f  
         testb   $SEL_RPL,TF_CS(%rsp)          testb   $SEL_RPL,TF_CS(%rsp)
         jz      3f          jz      6f
 4:      CLEAR_ASTPENDING(%r11)          .globl doreti_checkast
         sti  doreti_checkast:
           movq    CPUVAR(CURLWP),%r14
           CHECK_ASTPENDING(%r14)
           je      3f
           CLEAR_ASTPENDING(%r14)
           STI(si)
         movl    $T_ASTFLT,TF_TRAPNO(%rsp)       /* XXX undo later.. */          movl    $T_ASTFLT,TF_TRAPNO(%rsp)       /* XXX undo later.. */
         /* Pushed T_ASTFLT into tf_trapno on entry. */          /* Pushed T_ASTFLT into tf_trapno on entry. */
         movq    %rsp,%rdi          movq    %rsp,%rdi
         call    _C_LABEL(trap)          call    _C_LABEL(trap)
         cli          CLI(si)
         jmp     5b          jmp     doreti_checkast
 3:      INTRFASTEXIT  3:
           CHECK_DEFERRED_SWITCH
           jnz     9f
   6:
           INTRFASTEXIT
   9:
           STI(si)
           call    _C_LABEL(do_pmap_load)
           CLI(si)
           jmp     doreti_checkast         /* recheck ASTs */
   
   #ifdef XEN
   NENTRY(call_evtchn_do_event)
           incl    CPUVAR(IDEPTH)
           call    _C_LABEL(evtchn_do_event)
           decl    CPUVAR(IDEPTH)
           ret
   #endif

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.3.12.8

CVSweb <webmaster@jp.NetBSD.org>