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

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

Diff for /src/sys/arch/i386/i386/locore.S between version 1.4 and 1.4.2.1

version 1.4, 2002/12/17 20:49:07 version 1.4.2.1, 2002/12/18 05:00:59
Line 1647  ENTRY(longjmp)
Line 1647  ENTRY(longjmp)
   
 /*****************************************************************************/  /*****************************************************************************/
   
         .globl  _C_LABEL(sched_whichqs),_C_LABEL(sched_qs)  
         .globl  _C_LABEL(uvmexp),_C_LABEL(panic)  
   
 #ifdef DIAGNOSTIC  
 NENTRY(switch_error)  
         pushl   $1f  
         call    _C_LABEL(panic)  
         /* NOTREACHED */  
 1:      .asciz  "cpu_switch"  
 #endif /* DIAGNOSTIC */  
   
 /*  /*
  * void cpu_switch(struct proc *)   * void cpu_idle(void)
  * Find a runnable process and switch to it.  Wait if necessary.  If the new  
  * process is the same as the old one, we short-circuit the context save and  
  * restore.  
  *  
  * Note that the stack frame layout is known to "struct switchframe"  
  * in <machine/frame.h> and to the code in cpu_fork() which initializes  
  * it for a new process.  
  */   */
 ENTRY(cpu_switch)  ENTRY(cpu_idle)
         pushl   %ebx          pushl   %ebx
         pushl   %esi          pushl   %esi
         pushl   %edi          pushl   %edi
   
 #ifdef DEBUG  
         cmpl    $IPL_SCHED,CPUVAR(ILEVEL)  
         jae     1f  
         pushl   2f  
         call    _C_LABEL(panic)  
         /* NOTREACHED */  
 2:      .asciz  "not splhigh() in cpu_switch!"  
   
 1:  
 #endif /* DEBUG */  
   
         movl    CPUVAR(CURPROC),%esi          movl    CPUVAR(CURPROC),%esi
   
         /*          /*
          * Clear curproc so that we don't accumulate system time while idle.           * Clear curproc so that we don't accumulate system time while idle.
          * This also insures that schedcpu() will move the old process to           * This also insures that schedcpu() will move the old process to
Line 1694  ENTRY(cpu_switch)
Line 1665  ENTRY(cpu_switch)
          * userret()).           * userret()).
          */           */
         movl    $0,CPUVAR(CURPROC)          movl    $0,CPUVAR(CURPROC)
   
         /*          /*
          * First phase: find new process.           * Save old context.
          *  
          * Registers:  
          *   %eax - queue head, scratch, then zero  
          *   %ebx - queue number  
          *   %ecx - cached value of whichqs  
          *   %edx - next process in queue  
          *   %esi - old process  
          *   %edi - new process  
          */  
   
         /* Look for new process. */  
         cli                             # splhigh doesn't do a cli  
         movl    _C_LABEL(sched_whichqs),%ecx  
         bsfl    %ecx,%ebx               # find a full q  
         jnz     switch_dequeue  
   
         /*  
          * idling:      save old context.  
          *           *
          * Registers:           * Registers:
          *   %eax, %ecx - scratch           *   %eax, %ecx - scratch
Line 1725  ENTRY(cpu_switch)
Line 1679  ENTRY(cpu_switch)
         call    _C_LABEL(pmap_deactivate)       # pmap_deactivate(oldproc)          call    _C_LABEL(pmap_deactivate)       # pmap_deactivate(oldproc)
         addl    $4,%esp          addl    $4,%esp
   
         movl    P_ADDR(%esi),%esi          movl    P_ADDR(%esi),%edi
   
         /* Save stack pointers. */          /* Save stack pointers. */
         movl    %esp,PCB_ESP(%esi)          movl    %esp,PCB_ESP(%edi)
         movl    %ebp,PCB_EBP(%esi)          movl    %ebp,PCB_EBP(%edi)
   
         /* Find idle PCB for this CPU */          /* Find idle PCB for this CPU */
 #ifndef MULTIPROCESSOR  #ifndef MULTIPROCESSOR
Line 1749  ENTRY(cpu_switch)
Line 1703  ENTRY(cpu_switch)
         movl    PCB_ESP(%edi),%esp          movl    PCB_ESP(%edi),%esp
         movl    PCB_EBP(%edi),%ebp          movl    PCB_EBP(%edi),%ebp
   
   
         /* Switch address space. */          /* Switch address space. */
         movl    PCB_CR3(%edi),%ecx          movl    PCB_CR3(%edi),%ecx
         movl    %ecx,%cr3          movl    %ecx,%cr3
Line 1772  ENTRY(cpu_switch)
Line 1725  ENTRY(cpu_switch)
         /* Record new pcb. */          /* Record new pcb. */
         SET_CURPCB(%edi)          SET_CURPCB(%edi)
   
         xorl    %esi,%esi          pushl   %esi
         sti          sti
 idle_unlock:  
   1:
 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)  #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
         call    _C_LABEL(sched_unlock_idle)          call    _C_LABEL(sched_unlock_idle)
 #endif  #endif
Line 1782  idle_unlock: 
Line 1736  idle_unlock: 
         pushl   $IPL_NONE               # spl0()          pushl   $IPL_NONE               # spl0()
         call    _C_LABEL(Xspllower)     # process pending interrupts          call    _C_LABEL(Xspllower)     # process pending interrupts
         addl    $4,%esp          addl    $4,%esp
         jmp     idle_start  
 idle_zero:  NENTRY(mpidle)
         sti  idle_start:
         call    _C_LABEL(uvm_pageidlezero)  
         cli          cli
         cmpl    $0,_C_LABEL(sched_whichqs)          cmpl    $0,_C_LABEL(sched_whichqs)
         jnz     idle_exit          jnz     idle_exit
 idle_loop:  
         /* Try to zero some pages. */          /*
         movl    _C_LABEL(uvm)+UVM_PAGE_IDLE_ZERO,%ecx           * Try to zero some pages.
         testl   %ecx,%ecx           */
         jnz     idle_zero          movl    _C_LABEL(uvm)+UVM_PAGE_IDLE_ZERO,%ecx
           testl   %ecx,%ecx
           jnz      idle_zero
   
         sti          sti
         hlt          hlt
 NENTRY(mpidle)          jmp     idle_start
 idle_start:  idle_zero:
         cli          sti
         cmpl    $0,_C_LABEL(sched_whichqs)          call    _C_LABEL(uvm_pageidlezero)
         jz      idle_loop          jmp     idle_start
 idle_exit:  
   idle_exit:
         movl    $IPL_HIGH,CPUVAR(ILEVEL)                # splhigh          movl    $IPL_HIGH,CPUVAR(ILEVEL)                # splhigh
 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)  #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
         call    _C_LABEL(sched_lock_idle)          call    _C_LABEL(sched_lock_idle)
 #endif  #endif
         movl    _C_LABEL(sched_whichqs),%ecx  
         bsfl    %ecx,%ebx  
         jz      idle_unlock  
   
 switch_dequeue:          popl    %edi
           movl    %edi,CPUVAR(CURPROC)
   
           movl    P_ADDR(%edi),%esi
   
           /* Restore stack pointers. */
           movl    PCB_ESP(%esi),%esp
           movl    PCB_EBP(%esi),%ebp
   
   #ifdef MULTIPROCESSOR
           movl    CPUVAR(GDT),%eax
   #else
           /* Load TSS info. */
           movl    _C_LABEL(gdt),%eax
   #endif
           movl    P_MD_TSS_SEL(%edi),%edx
   
           /* Switch TSS. Reset "task busy" flag before loading. */
           andl    $~0x0200,4(%eax,%edx, 1)
           ltr     %dx
   
           pushl   %edi
           call    _C_LABEL(pmap_activate)         # pmap_activate(p)
           addl    $4,%esp
   
           /* Restore cr0 (including FPU state). */
           movl    PCB_CR0(%esi),%ecx
   #ifdef MULTIPROCESSOR
         /*          /*
          * we're running at splhigh(), but it's otherwise okay to take           * If our floating point registers are on a different cpu,
          * interrupts here.           * clear CR0_TS so we'll trap rather than reuse bogus state.
          */           */
           movl    PCB_FPCPU(%esi),%ebx
           cmpl    CPUVAR(SELF),%ebx
           jz      1f
           orl     $CR0_TS,%ecx
   1:
   #endif
           movl    %ecx,%cr0
   
           /* Record new pcb. */
           SET_CURPCB(%esi)
   
           /* Interrupts are okay again. */
         sti          sti
         leal    _C_LABEL(sched_qs)(,%ebx,8),%eax # select q  
   cpu_idle_exit:
           popl    %edi
           popl    %esi
           popl    %ebx
           ret
   
         movl    P_FORW(%eax),%edi       # unlink from front of process q  
 #ifdef  DIAGNOSTIC  #ifdef DIAGNOSTIC
         cmpl    %edi,%eax               # linked to self (i.e. nothing queued)?  NENTRY(switch_error)
         je      _C_LABEL(switch_error)  # not possible          pushl   $1f
           call    _C_LABEL(panic)
           /* NOTREACHED */
   1:      .asciz  "cpu_switch"
 #endif /* DIAGNOSTIC */  #endif /* DIAGNOSTIC */
         movl    P_FORW(%edi),%edx  
         movl    %edx,P_FORW(%eax)  
         movl    %eax,P_BACK(%edx)  
   
         cmpl    %edx,%eax               # q empty?  /*
         jne     3f   * void cpu_switch(struct proc *oldp, struct proc *newp)
    * Find a runnable process and switch to it.  Wait if necessary.  If the new
    * process is the same as the old one, we short-circuit the context save and
    * restore.
    *
    * Note that the stack frame layout is known to "struct switchframe"
    * in <machine/frame.h> and to the code in cpu_fork() which initializes
    * it for a new process.
    */
   ENTRY(cpu_switch)
           pushl   %ebx
           pushl   %esi
           pushl   %edi
   
         btrl    %ebx,%ecx               # yes, clear to indicate empty          movl    20(%esp),%edi
         movl    %ecx,_C_LABEL(sched_whichqs) # update q status          movl    16(%esp),%esi
   
 3:      /* We just did it. */  #ifdef DEBUG
         xorl    %eax,%eax          cmpl    $IPL_SCHED,CPUVAR(ILEVEL)
         CLEAR_RESCHED(%eax)          jae     1f
           pushl   2f
           call    _C_LABEL(panic)
           /* NOTREACHED */
   2:      .asciz  "not splhigh() in cpu_switch!"
   
   1:
   #endif /* DEBUG */
   
   sw1:
   
 #ifdef  DIAGNOSTIC  #ifdef  DIAGNOSTIC
         cmpl    %eax,P_WCHAN(%edi)      # Waiting for something?          cmpl    $0,P_WCHAN(%edi)        # Waiting for something?
         jne     _C_LABEL(switch_error)  # Yes; shouldn't be queued.          jne     _C_LABEL(switch_error)  # Yes; shouldn't be queued.
         cmpb    $SRUN,P_STAT(%edi)      # In run state?          cmpb    $SRUN,P_STAT(%edi)      # In run state?
         jne     _C_LABEL(switch_error)  # No; shouldn't be queued.          jne     _C_LABEL(switch_error)  # No; shouldn't be queued.
 #endif /* DIAGNOSTIC */  #endif /* DIAGNOSTIC */
   
         /* Isolate process.  XXX Is this necessary? */  
         movl    %eax,P_BACK(%edi)  
   
         /* Record new process. */          /* Record new process. */
         movb    $SONPROC,P_STAT(%edi)   # p->p_stat = SONPROC          movb    $SONPROC,P_STAT(%edi)   # p->p_stat = SONPROC
         SET_CURPROC(%edi,%ecx)          SET_CURPROC(%edi,%ecx)
   
         /* Skip context switch if same process. */          /* We just did it. */
         cmpl    %edi,%esi          xorl    %eax,%eax
         je      switch_return          CLEAR_RESCHED(%eax)
   
         /* If old process exited, don't bother. */          /* If old process exited, don't bother. */
         testl   %esi,%esi          testl   %esi,%esi
         jz      switch_exited          jz      1f
   
         /*          /*
          * Second phase: save old context.           * Save old context.
          *           *
          * Registers:           * Registers:
          *   %eax, %ecx - scratch           *   %eax, %ecx - scratch
Line 1878  switch_dequeue:  
Line 1894  switch_dequeue:  
         movl    %esp,PCB_ESP(%esi)          movl    %esp,PCB_ESP(%esi)
         movl    %ebp,PCB_EBP(%esi)          movl    %ebp,PCB_EBP(%esi)
   
 switch_exited:  1:
         /*          /*
          * Third phase: restore saved context.           * Restore saved context.
          *           *
          * Registers:           * Registers:
          *   %eax, %ebx, %ecx, %edx - scratch           *   %eax, %ebx, %ecx, %edx - scratch
Line 1942  switch_restored:
Line 1958  switch_restored:
         /* Interrupts are okay again. */          /* Interrupts are okay again. */
         sti          sti
   
 /*          /*
  *  Check for restartable atomic sequences (RAS)           *  Check for restartable atomic sequences (RAS)
  */           */
         movl    CPUVAR(CURPROC),%edi          movl    CPUVAR(CURPROC),%edi
         cmpl    $0,P_NRAS(%edi)          cmpl    $0,P_NRAS(%edi)
         je      1f          je      1f
Line 1959  switch_restored:
Line 1975  switch_restored:
         movl    %eax,TF_EIP(%ebx)          movl    %eax,TF_EIP(%ebx)
 1:  1:
   
 switch_return:  
 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)  #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
         call    _C_LABEL(sched_unlock_idle)          call    _C_LABEL(sched_unlock_idle)
 #endif  #endif
Line 1968  switch_return:
Line 1983  switch_return:
         addl    $4,%esp          addl    $4,%esp
         movl    $IPL_HIGH,CPUVAR(ILEVEL)        # splhigh()          movl    $IPL_HIGH,CPUVAR(ILEVEL)        # splhigh()
   
         movl    %edi,%eax               # return (p);  
         popl    %edi          popl    %edi
         popl    %esi          popl    %esi
         popl    %ebx          popl    %ebx
Line 2042  ENTRY(switch_exit)
Line 2056  ENTRY(switch_exit)
         call    _C_LABEL(exit2)          call    _C_LABEL(exit2)
         addl    $4,%esp          addl    $4,%esp
   
   #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
           call    _C_LABEL(sched_lock_idle)
   #endif
   
           call    _C_LABEL(chooseproc)
           movl    %eax,%edi
   
         /* Jump into cpu_switch() with the right state. */          /* Jump into cpu_switch() with the right state. */
         xorl    %esi,%esi          xorl    %esi,%esi
         movl    %esi,CPUVAR(CURPROC)          movl    %esi,CPUVAR(CURPROC)
         jmp     idle_start          jmp     sw1
   
 /*  /*
  * void savectx(struct pcb *pcb);   * void savectx(struct pcb *pcb);

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.4.2.1

CVSweb <webmaster@jp.NetBSD.org>