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

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

Diff for /src/sys/arch/sparc/sparc/locore.s between version 1.148 and 1.148.4.11

version 1.148, 2001/09/13 13:25:48 version 1.148.4.11, 2002/08/01 02:43:28
Line 204  _C_LABEL(kgdb_stack):
Line 204  _C_LABEL(kgdb_stack):
  */   */
 cpcb = CPUINFO_VA + CPUINFO_CURPCB  cpcb = CPUINFO_VA + CPUINFO_CURPCB
   
 /* curproc points to the current process that has the CPU */  /* curlwp points to the current LWP that has the CPU */
 curproc = CPUINFO_VA + CPUINFO_CURPROC  curlwp = CPUINFO_VA + CPUINFO_CURLWP
   
 /*  /*
  * cputyp is the current cpu type, used to distinguish between   * cputyp is the current cpu type, used to distinguish between
Line 248  _mapme:
Line 248  _mapme:
 #endif  #endif
 #endif  #endif
   
   #if !defined(SUN4D)
   sun4d_notsup:
           .asciz  "cr .( NetBSD/sparc: this kernel does not support the sun4d) cr"
   #endif
 #if !defined(SUN4M)  #if !defined(SUN4M)
 sun4m_notsup:  sun4m_notsup:
         .asciz  "cr .( NetBSD/sparc: this kernel does not support the sun4m) cr"          .asciz  "cr .( NetBSD/sparc: this kernel does not support the sun4m) cr"
Line 1686  ctw_user:
Line 1690  ctw_user:
         bl,a    ctw_merge               ! all ok if only 1          bl,a    ctw_merge               ! all ok if only 1
          std    %l0, [%sp]           std    %l0, [%sp]
         add     %sp, 7*8, %g5           ! check last addr too          add     %sp, 7*8, %g5           ! check last addr too
         add     %g6, 62, %g6            ! restore %g6 to `pgofset'          add     %g6, 62, %g6            /* restore %g6 to `pgofset' */
         PTE_OF_ADDR(%g5, %g7, ctw_invalid, %g6, NOP_ON_4M_3)          PTE_OF_ADDR(%g5, %g7, ctw_invalid, %g6, NOP_ON_4M_3)
         CMP_PTE_USER_WRITE(%g7, %g6, NOP_ON_4M_4)          CMP_PTE_USER_WRITE(%g7, %g6, NOP_ON_4M_4)
         be,a    ctw_merge               ! all ok: store <l0,l1> and merge          be,a    ctw_merge               ! all ok: store <l0,l1> and merge
Line 2465  softintr_common:
Line 2469  softintr_common:
          */           */
 #if defined(SUN4M)  #if defined(SUN4M)
 _ENTRY(_C_LABEL(sparc_interrupt4m))  _ENTRY(_C_LABEL(sparc_interrupt4m))
   #if !defined(MSIIEP)    /* "normal" sun4m */
         mov     1, %l4          mov     1, %l4
         sethi   %hi(CPUINFO_VA+CPUINFO_INTREG), %l6          sethi   %hi(CPUINFO_VA+CPUINFO_INTREG), %l6
         ld      [%l6 + %lo(CPUINFO_VA+CPUINFO_INTREG)], %l6          ld      [%l6 + %lo(CPUINFO_VA+CPUINFO_INTREG)], %l6
Line 2478  _ENTRY(_C_LABEL(sparc_interrupt4m))
Line 2483  _ENTRY(_C_LABEL(sparc_interrupt4m))
         sll     %l4, 16, %l5          sll     %l4, 16, %l5
         st      %l5, [%l6 + ICR_PI_CLR_OFFSET]          st      %l5, [%l6 + ICR_PI_CLR_OFFSET]
         b,a     softintr_common          b,a     softintr_common
 #endif  #else /* MSIIEP */
           sethi   %hi(MSIIEP_PCIC_VA), %l6
           mov     1, %l4
           ld      [%l6 + PCIC_PROC_IPR_REG], %l5 ! get pending interrupts
           sll     %l4, %l3, %l4
           btst    %l4, %l5        !  has pending hw intr at this level?
           bnz     sparc_interrupt_common
            nop
   
           ! a soft interrupt; clear its bit in softintr clear register
           b       softintr_common
            sth    %l4, [%l6 + PCIC_SOFT_INTR_CLEAR_REG]
   #endif /* MSIIEP */
   #endif /* SUN4M */
   
 _ENTRY(_C_LABEL(sparc_interrupt44c))  _ENTRY(_C_LABEL(sparc_interrupt44c))
 sparc_interrupt_common:  sparc_interrupt_common:
Line 2598  nmi_sun4:
Line 2616  nmi_sun4:
          */           */
         sethi   %hi(INTRREG_VA), %o0          sethi   %hi(INTRREG_VA), %o0
         ldub    [%o0 + %lo(INTRREG_VA)], %o1          ldub    [%o0 + %lo(INTRREG_VA)], %o1
         andn    %o0, IE_ALLIE, %o1          andn    %o1, IE_ALLIE, %o1
         stb     %o1, [%o0 + %lo(INTRREG_VA)]          stb     %o1, [%o0 + %lo(INTRREG_VA)]
         wr      %l0, PSR_ET, %psr       ! okay, turn traps on again          wr      %l0, PSR_ET, %psr       ! okay, turn traps on again
   
Line 2624  nmi_sun4c:
Line 2642  nmi_sun4c:
          */           */
         sethi   %hi(INTRREG_VA), %o0          sethi   %hi(INTRREG_VA), %o0
         ldub    [%o0 + %lo(INTRREG_VA)], %o1          ldub    [%o0 + %lo(INTRREG_VA)], %o1
         andn    %o0, IE_ALLIE, %o1          andn    %o1, IE_ALLIE, %o1
         stb     %o1, [%o0 + %lo(INTRREG_VA)]          stb     %o1, [%o0 + %lo(INTRREG_VA)]
         wr      %l0, PSR_ET, %psr       ! okay, turn traps on again          wr      %l0, PSR_ET, %psr       ! okay, turn traps on again
   
Line 2686  nmi_sun4m:
Line 2704  nmi_sun4m:
         bnz,a   1f                      !          bnz,a   1f                      !
          mov    %o0, %o1                ! shift int clear bit to SOFTINT 15           mov    %o0, %o1                ! shift int clear bit to SOFTINT 15
   
         set     _C_LABEL(nmi_hard), %o3 ! it's a hardint; switch handler          set     _C_LABEL(nmi_hard), %o3 /* it's a hardint; switch handler */
   
         /*          /*
          * Level 15 interrupts are nonmaskable, so with traps off,           * Level 15 interrupts are nonmaskable, so with traps off,
Line 2753  nmi_sun4m:
Line 2771  nmi_sun4m:
   
         !cmp    %o0, 0                  ! was this a soft nmi          !cmp    %o0, 0                  ! was this a soft nmi
         !be     4f          !be     4f
         !XXX - we need to unblock `mask all ints' only on a hard nmi          /* XXX - we need to unblock `mask all ints' only on a hard nmi */
   
         ! enable interrupts again (safe, we disabled traps again above)          ! enable interrupts again (safe, we disabled traps again above)
         sethi   %hi(ICR_SI_CLR), %o0          sethi   %hi(ICR_SI_CLR), %o0
Line 3393  dostart:
Line 3411  dostart:
          * we have to be sure to use only pc-relative addressing.           * we have to be sure to use only pc-relative addressing.
          */           */
   
 #ifdef DDB  
         /*          /*
          * We now use the bootinfo method to pass arguments, and the new           * We now use the bootinfo method to pass arguments, and the new
          * magic number indicates that. A pointer to esym is passed in           * magic number indicates that. A pointer to the kernel top, i.e.
          * %o4[0] and the bootinfo structure is passed in %o4[1].           * the first address after the load kernel image (including DDB
            * symbols, if any) is passed in %o4[0] and the bootinfo structure
            * is passed in %o4[1].
            *
            * A magic number is passed in %o5 to allow for bootloaders
            * that know nothing about the bootinfo structure or previous
            * DDB symbol loading conventions.
          *           *
          * For compatibility with older versions, we check for DDB arguments           * For compatibility with older versions, we check for DDB arguments
          * if the older magic number is there. The loader passes `esym' in           * if the older magic number is there. The loader passes `kernel_top'
          * %o4.           * (previously known as `esym') in %o4.
          * A DDB magic number is passed in %o5 to allow for bootloaders           *
          * that know nothing about DDB symbol loading conventions.  
          * Note: we don't touch %o1-%o3; SunOS bootloaders seem to use them           * Note: we don't touch %o1-%o3; SunOS bootloaders seem to use them
          * for their own mirky business.           * for their own mirky business.
          *           *
          * Pre-NetBSD 1.3 bootblocks had KERNBASE compiled in, and used           * Pre-NetBSD 1.3 bootblocks had KERNBASE compiled in, and used it
          * it to compute the value of `esym'. In order to successfully           * to compute the value of `kernel_top' (previously known as `esym').
          * boot a kernel built with a different value for KERNBASE using           * In order to successfully boot a kernel built with a different value
          * old bootblocks, we fixup `esym' here by the difference between           * for KERNBASE using old bootblocks, we fixup `kernel_top' here by
          * KERNBASE and the old value (known to be 0xf8000000) compiled           * the difference between KERNBASE and the old value (known to be
          * into pre-1.3 bootblocks.           * 0xf8000000) compiled into pre-1.3 bootblocks.
          * We use the magic number passed as the sixth argument to  
          * distinguish bootblock versions.  
          */           */
         set     KERNBASE, %l4          set     KERNBASE, %l4
   
Line 3424  dostart:
Line 3444  dostart:
          nop           nop
   
         /* The loader has passed to us a `bootinfo' structure */          /* The loader has passed to us a `bootinfo' structure */
         ld      [%o4], %l3              ! 1st word is esym          ld      [%o4], %l3              ! 1st word is kernel_top
         add     %l3, %l4, %o5           ! relocate          add     %l3, %l4, %o5           ! relocate: + KERNBASE
         sethi   %hi(_C_LABEL(esym) - KERNBASE), %l3     ! store esym          sethi   %hi(_C_LABEL(kernel_top) - KERNBASE), %l3 ! and store it
         st      %o5, [%l3 + %lo(_C_LABEL(esym) - KERNBASE)]          st      %o5, [%l3 + %lo(_C_LABEL(kernel_top) - KERNBASE)]
   
         ld      [%o4 + 4], %l3          ! 2nd word is bootinfo          ld      [%o4 + 4], %l3          ! 2nd word is bootinfo
         add     %l3, %l4, %o5           ! relocate          add     %l3, %l4, %o5           ! relocate
         sethi   %hi(_C_LABEL(bootinfo) - KERNBASE), %l3 ! store bootinfo          sethi   %hi(_C_LABEL(bootinfo) - KERNBASE), %l3 ! store bootinfo
         st      %o5, [%l3 + %lo(_C_LABEL(bootinfo) - KERNBASE)]          st      %o5, [%l3 + %lo(_C_LABEL(bootinfo) - KERNBASE)]
         b,a     3f          b,a     4f
   
 1:  1:
   #ifdef DDB
         /* Check for old-style DDB loader magic */          /* Check for old-style DDB loader magic */
         set     0x44444231, %l3         ! ddb magic          set     0x44444231, %l3         ! Is it DDB_MAGIC1?
         cmp     %o5, %l3          cmp     %o5, %l3
         be,a    2f          be,a    2f
          clr    %l4                     ! if DDB_MAGIC1, clear %l4           clr    %l4                     ! if DDB_MAGIC1, clear %l4
   
         set     0x44444230, %l3         ! compat magic          set     0x44444230, %l3         ! Is it DDB_MAGIC0?
         cmp     %o5, %l3          cmp     %o5, %l3                ! if so, need to relocate %o4
         bne     3f          bne     3f                      /* if not, there's no bootloader info */
   
                                         ! note: %l4 set to KERNBASE above.                                          ! note: %l4 set to KERNBASE above.
         set     0xf8000000, %l5         ! compute correction term:          set     0xf8000000, %l5         ! compute correction term:
Line 3454  dostart:
Line 3475  dostart:
         tst     %o4                     ! do we have the symbols?          tst     %o4                     ! do we have the symbols?
         bz      3f          bz      3f
          sub    %o4, %l4, %o4           ! apply compat correction           sub    %o4, %l4, %o4           ! apply compat correction
         sethi   %hi(_C_LABEL(esym) - KERNBASE), %l3     ! store esym          sethi   %hi(_C_LABEL(kernel_top) - KERNBASE), %l3 ! and store it
         st      %o4, [%l3 + %lo(_C_LABEL(esym) - KERNBASE)]          st      %o4, [%l3 + %lo(_C_LABEL(kernel_top) - KERNBASE)]
           b,a     4f
 3:  3:
 #endif  #endif
         /*          /*
            * The boot loader did not pass in a value for `kernel_top';
            * let it default to `end'.
            */
           set     end, %o4
           sethi   %hi(_C_LABEL(kernel_top) - KERNBASE), %l3 ! store kernel_top
           st      %o4, [%l3 + %lo(_C_LABEL(kernel_top) - KERNBASE)]
   
   4:
   
           /*
          * Sun4 passes in the `load address'.  Although possible, its highly           * Sun4 passes in the `load address'.  Although possible, its highly
          * unlikely that OpenBoot would place the prom vector there.           * unlikely that OpenBoot would place the prom vector there.
          */           */
Line 3467  dostart:
Line 3499  dostart:
         be      is_sun4          be      is_sun4
          nop           nop
   
 #if defined(SUN4C) || defined(SUN4M)  #if defined(SUN4C) || defined(SUN4M) || defined(SUN4D)
         /*          /*
          * Be prepared to get OF client entry in either %o0 or %o3.           * Be prepared to get OF client entry in either %o0 or %o3.
            * XXX Will this ever trip on sun4d?  Let's hope not!
          */           */
         cmp     %o0, 0          cmp     %o0, 0
         be      is_openfirm          be      is_openfirm
Line 3485  dostart:
Line 3518  dostart:
          nop                            ! }           nop                            ! }
   
         /*          /*
          * are we on a sun4c or a sun4m?           * are we on a sun4c or a sun4m or a sun4d?
          */           */
         ld      [%g7 + PV_NODEOPS], %o4 ! node = pv->pv_nodeops->no_nextnode(0)          ld      [%g7 + PV_NODEOPS], %o4 ! node = pv->pv_nodeops->no_nextnode(0)
         ld      [%o4 + NO_NEXTNODE], %o4          ld      [%o4 + NO_NEXTNODE], %o4
Line 3507  dostart:
Line 3540  dostart:
         cmp     %o0, 'm'          cmp     %o0, 'm'
         be      is_sun4m          be      is_sun4m
          nop           nop
 #endif /* SUN4C || SUN4M */          cmp     %o0, 'd'
           be      is_sun4d
            nop
   #endif /* SUN4C || SUN4M || SUN4D */
   
         ! ``on a sun4d?!  hell no!''          /*
            * Don't know what type of machine this is; just halt back
            * out to the PROM.
            */
         ld      [%g7 + PV_HALT], %o1    ! by this kernel, then halt          ld      [%g7 + PV_HALT], %o1    ! by this kernel, then halt
         call    %o1          call    %o1
          nop           nop
Line 3535  is_sun4m:
Line 3574  is_sun4m:
          nop           nop
         /*NOTREACHED*/          /*NOTREACHED*/
 #endif  #endif
   is_sun4d:
   #if defined(SUN4D)
           set     trapbase_sun4m, %g6     /* XXXJRT trapbase_sun4d */
           mov     SUN4CM_PGSHIFT, %g5
           b       start_havetype
            mov    CPU_SUN4D, %g4
   #else
           set     sun4d_notsup-KERNBASE, %o0
           ld      [%g7 + PV_EVAL], %o1
           call    %o1                     ! print a message saying that the
            nop                            ! sun4d architecture is not supported
           ld      [%g7 + PV_HALT], %o1    ! by this kernel, then halt
           call    %o1
            nop
           /*NOTREACHED*/
   #endif
 is_sun4c:  is_sun4c:
 #if defined(SUN4C)  #if defined(SUN4C)
         set     trapbase_sun4c, %g6          set     trapbase_sun4c, %g6
Line 3607  start_havetype:
Line 3662  start_havetype:
          */           */
         clr     %l0                     ! lowva          clr     %l0                     ! lowva
         set     KERNBASE, %l1           ! highva          set     KERNBASE, %l1           ! highva
         set     _end + (2 << 18), %l2   ! last va that must be remapped  
 #ifdef DDB          sethi   %hi(_C_LABEL(kernel_top) - KERNBASE), %o0
         sethi   %hi(_C_LABEL(esym) - KERNBASE), %o1          ld      [%o0 + %lo(_C_LABEL(kernel_top) - KERNBASE)], %o1
         ld      [%o1+%lo(_C_LABEL(esym) - KERNBASE)], %o1          set     (2 << 18), %o2          ! add slack for sun4c MMU
         tst     %o1          add     %o1, %o2, %l2           ! last va that must be remapped
         bz      1f  
          nop  
         set     (2 << 18), %l2  
         add     %l2, %o1, %l2           ! last va that must be remapped  
 1:  
 #endif  
         /*          /*
          * Need different initial mapping functions for different           * Need different initial mapping functions for different
          * types of machines.           * types of machines.
Line 3677  no_3mmu:
Line 3727  no_3mmu:
 2:  2:
 #endif /* SUN4 */  #endif /* SUN4 */
   
 #if defined(SUN4M)  #if defined(SUN4M) || defined(SUN4D)
         cmp     %g4, CPU_SUN4M          ! skip for sun4m!          cmp     %g4, CPU_SUN4M
         bne     3f          beq     3f
            nop
           cmp     %g4, CPU_SUN4D
           bne     4f
   
   3:
         /*          /*
          * The OBP guarantees us a 16MB mapping using a level 1 PTE at           * The OBP guarantees us a 16MB mapping using a level 1 PTE at
          * the start of the memory bank in which we were loaded. All we           * the start of the memory bank in which we were loaded. All we
Line 3748  remap_notvik:
Line 3802  remap_notvik:
         sta     %l4, [%o1] ASI_BYPASS          sta     %l4, [%o1] ASI_BYPASS
         !b,a    startmap_done          !b,a    startmap_done
   
 3:  4:
 #endif /* SUN4M */  #endif /* SUN4M || SUN4D */
         ! botch! We should blow up.          ! botch! We should blow up.
   
 startmap_done:  startmap_done:
Line 3852  noplab:  nop
Line 3906  noplab:  nop
 1:  1:
 #endif  #endif
   
 #if ((defined(SUN4) || defined(SUN4C)) && defined(SUN4M))  #if (defined(SUN4) || defined(SUN4C)) && (defined(SUN4M) || defined(SUN4D))
   
         /*          /*
          * Patch instructions at specified labels that start           * Patch instructions at specified labels that start
Line 3868  Lgandul: nop
Line 3922  Lgandul: nop
         ld      [%o0 + %lo(Lgandul)], %l0       ! %l0 = NOP          ld      [%o0 + %lo(Lgandul)], %l0       ! %l0 = NOP
   
         cmp     %g4, CPU_SUN4M          cmp     %g4, CPU_SUN4M
           beq,a   2f
            nop
   
           cmp     %g4, CPU_SUN4D
         bne,a   1f          bne,a   1f
          nop           nop
   
         ! this should be automated!  2:      ! this should be automated!
         MUNGE(NOP_ON_4M_1)          MUNGE(NOP_ON_4M_1)
         MUNGE(NOP_ON_4M_2)          MUNGE(NOP_ON_4M_2)
         MUNGE(NOP_ON_4M_3)          MUNGE(NOP_ON_4M_3)
Line 3886  Lgandul: nop
Line 3944  Lgandul: nop
         MUNGE(NOP_ON_4M_12)          MUNGE(NOP_ON_4M_12)
         MUNGE(NOP_ON_4M_13)          MUNGE(NOP_ON_4M_13)
         MUNGE(NOP_ON_4M_14)          MUNGE(NOP_ON_4M_14)
           MUNGE(NOP_ON_4M_15)
         b,a     2f          b,a     2f
   
 1:  1:
Line 3996  _C_LABEL(cpu_hatch):
Line 4055  _C_LABEL(cpu_hatch):
         set     _C_LABEL(proc0), %g3            ! p = proc0          set     _C_LABEL(proc0), %g3            ! p = proc0
         sethi   %hi(_C_LABEL(sched_whichqs)), %g2          sethi   %hi(_C_LABEL(sched_whichqs)), %g2
         sethi   %hi(cpcb), %g6          sethi   %hi(cpcb), %g6
         sethi   %hi(curproc), %g7          sethi   %hi(curlwp), %g7
         st      %g0, [%g7 + %lo(curproc)]       ! curproc = NULL;          st      %g0, [%g7 + %lo(curlwp)]        ! curlwp = NULL;
   
         mov     PSR_S|PSR_ET, %g1               ! oldpsr = PSR_S | PSR_ET;          mov     PSR_S|PSR_ET, %g1               ! oldpsr = PSR_S | PSR_ET;
         sethi   %hi(IDLE_UP), %g5          sethi   %hi(IDLE_UP), %g5
Line 4029  _C_LABEL(cpu_hatch):
Line 4088  _C_LABEL(cpu_hatch):
 #include "sigcode_state.s"  #include "sigcode_state.s"
   
         .globl  _C_LABEL(sigcode)          .globl  _C_LABEL(sigcode)
           .globl  _C_LABEL(upcallcode)
         .globl  _C_LABEL(esigcode)          .globl  _C_LABEL(esigcode)
 _C_LABEL(sigcode):  _C_LABEL(sigcode):
   
Line 4048  _C_LABEL(sigcode):
Line 4108  _C_LABEL(sigcode):
         ! sigreturn does not return unless it fails          ! sigreturn does not return unless it fails
         mov     SYS_exit, %g1           ! exit(errno)          mov     SYS_exit, %g1           ! exit(errno)
         t       ST_SYSCALL          t       ST_SYSCALL
   _C_LABEL(upcallcode):
           ! not yet implemented
           mov     101, %o0
           mov     SYS_exit, %g1           ! exit(101)
           t       ST_SYSCALL
 _C_LABEL(esigcode):  _C_LABEL(esigcode):
   
 /*  /*
Line 4300  ENTRY(write_user_windows)
Line 4365  ENTRY(write_user_windows)
  *      %g4 = lastproc   *      %g4 = lastproc
  *      %g5 = <free>; newpcb   *      %g5 = <free>; newpcb
  *      %g6 = %hi(cpcb)   *      %g6 = %hi(cpcb)
  *      %g7 = %hi(curproc)   *      %g7 = %hi(curlwp)
  *      %o0 = tmp 1   *      %o0 = tmp 1
  *      %o1 = tmp 2   *      %o1 = tmp 2
  *      %o2 = tmp 3   *      %o2 = tmp 3
Line 4336  ENTRY(write_user_windows)
Line 4401  ENTRY(write_user_windows)
 /*  /*
  * switchexit is called only from cpu_exit() before the current process   * switchexit is called only from cpu_exit() before the current process
  * has freed its vmspace and kernel stack; we must schedule them to be   * has freed its vmspace and kernel stack; we must schedule them to be
  * freed.  (curproc is already NULL.)   * freed.  (curlwp is already NULL.)
  *   *
  * We lay the process to rest by changing to the `idle' kernel stack,   * We lay the process to rest by changing to the `idle' kernel stack,
  * and note that the `last loaded process' is nonexistent.   * and note that the `last loaded process' is nonexistent.
  */   */
   ENTRY(switchlwpexit)
   !!Hmm, switchexit() might as well have passed us the `exit2' function to call.
           set     _C_LABEL(lwp_exit2), %g1
           b,a     switchexit0
 ENTRY(switchexit)  ENTRY(switchexit)
           set     _C_LABEL(exit2), %g1
   switchexit0:
         mov     %o0, %g2                ! save proc for exit2() call          mov     %o0, %g2                ! save proc for exit2() call
   
         /*          /*
Line 4376  ENTRY(switchexit)
Line 4447  ENTRY(switchexit)
 #endif  #endif
   
         wr      %g0, PSR_S|PSR_ET, %psr ! and then enable traps          wr      %g0, PSR_S|PSR_ET, %psr ! and then enable traps
         call    _C_LABEL(exit2)         ! exit2(p)          call    %g1                     ! {lwp}exit2(p)
          mov    %g2, %o0           mov    %g2, %o0
   
         /*          /*
Line 4389  ENTRY(switchexit)
Line 4460  ENTRY(switchexit)
          *      %g2 = %hi(whichqs)           *      %g2 = %hi(whichqs)
          *      %g4 = lastproc           *      %g4 = lastproc
          *      %g6 = %hi(cpcb)           *      %g6 = %hi(cpcb)
          *      %g7 = %hi(curproc)           *      %g7 = %hi(curlwp)
          *      %o0 = tmp 1           *      %o0 = tmp 1
          *      %o1 = tmp 2           *      %o1 = tmp 2
          *      %o3 = whichqs           *      %o3 = whichqs
Line 4402  ENTRY(switchexit)
Line 4473  ENTRY(switchexit)
         sethi   %hi(_C_LABEL(sched_whichqs)), %g2          sethi   %hi(_C_LABEL(sched_whichqs)), %g2
         clr     %g4                     ! lastproc = NULL;          clr     %g4                     ! lastproc = NULL;
         sethi   %hi(cpcb), %g6          sethi   %hi(cpcb), %g6
         sethi   %hi(curproc), %g7          sethi   %hi(curlwp), %g7
         st      %g0, [%g7 + %lo(curproc)]       ! curproc = NULL;          st      %g0, [%g7 + %lo(curlwp)]        ! curlwp = NULL;
         b,a     idle_enter_no_schedlock          b,a     idle_enter_no_schedlock
         /* FALLTHROUGH */          /* FALLTHROUGH */
   
Line 4450  idle:
Line 4521  idle:
 #endif  #endif
   
 idle_enter_no_schedlock:  idle_enter_no_schedlock:
         wr      %g1, 0, %psr            ! (void) spl0();          wr      %g1, 0, %psr            ! spl0();
 1:                                      ! spin reading whichqs until nonzero  1:                                      ! spin reading whichqs until nonzero
         ld      [%g2 + %lo(_C_LABEL(sched_whichqs))], %o3          ld      [%g2 + %lo(_C_LABEL(sched_whichqs))], %o3
         tst     %o3          tst     %o3
Line 4459  idle_enter_no_schedlock:
Line 4530  idle_enter_no_schedlock:
 #else  #else
         bnz,a   Lsw_scan          bnz,a   Lsw_scan
 #endif  #endif
           ! NB: annulled delay slot (executed when we leave the idle loop)
          wr     %g1, PSR_PIL, %psr      ! (void) splhigh();           wr     %g1, PSR_PIL, %psr      ! (void) splhigh();
   
         ! Check uvm.page_idle_zero          ! Check uvm.page_idle_zero
Line 4474  idle_enter_no_schedlock:
Line 4546  idle_enter_no_schedlock:
 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)  #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
 idle_leave:  idle_leave:
         /* Before we leave the idle loop, detain the scheduler lock */          /* Before we leave the idle loop, detain the scheduler lock */
         nop;nop;nop;    ! just wrote to %psr; delay before doing a `save'          nop;nop;nop;    /* just wrote to %psr; delay before doing a `save' */
         SAVE_GLOBALS_AND_CALL(sched_lock_idle)          SAVE_GLOBALS_AND_CALL(sched_lock_idle)
         b,a     Lsw_scan          b,a     Lsw_scan
 #endif  #endif
Line 4519  ENTRY(cpu_switch)
Line 4591  ENTRY(cpu_switch)
          *      %g4 = lastproc           *      %g4 = lastproc
          *      %g5 = tmp 0           *      %g5 = tmp 0
          *      %g6 = %hi(cpcb)           *      %g6 = %hi(cpcb)
          *      %g7 = %hi(curproc)           *      %g7 = %hi(curlwp)
          *      %o0 = tmp 1           *      %o0 = tmp 1
          *      %o1 = tmp 2           *      %o1 = tmp 2
          *      %o2 = tmp 3           *      %o2 = tmp 3
Line 4535  ENTRY(cpu_switch)
Line 4607  ENTRY(cpu_switch)
         rd      %psr, %g1                       ! oldpsr = %psr;          rd      %psr, %g1                       ! oldpsr = %psr;
         st      %g1, [%o0 + PCB_PSR]            ! cpcb->pcb_psr = oldpsr;          st      %g1, [%o0 + PCB_PSR]            ! cpcb->pcb_psr = oldpsr;
         andn    %g1, PSR_PIL, %g1               ! oldpsr &= ~PSR_PIL;          andn    %g1, PSR_PIL, %g1               ! oldpsr &= ~PSR_PIL;
         sethi   %hi(curproc), %g7          sethi   %hi(curlwp), %g7
         st      %g0, [%g7 + %lo(curproc)]       ! curproc = NULL;          st      %g0, [%g7 + %lo(curlwp)]        ! curlwp = NULL;
   
 Lsw_scan:  Lsw_scan:
         nop; nop; nop                           ! paranoia          nop; nop; nop                           ! paranoia
Line 4578  Lsw_scan:
Line 4650  Lsw_scan:
         sll     %o4, 3, %o0          sll     %o4, 3, %o0
         add     %o0, %o5, %o5          add     %o0, %o5, %o5
         ld      [%o5], %g3              ! p = q->ph_link;          ld      [%o5], %g3              ! p = q->ph_link;
   
   cpu_switch0:
           /*
            * Here code in common with cpu_preempt() starts.
            * cpu_preempt() sets %g3 to p, and %o5 to p->p_back,
            * so the following will unlink p from the switch_qs list.
            */
         cmp     %g3, %o5                ! if (p == q)          cmp     %g3, %o5                ! if (p == q)
         be      Lsw_panic_rq            !       panic("switch rq");          be      Lsw_panic_rq            !       panic("switch rq");
          EMPTY           EMPTY
Line 4600  Lsw_scan:
Line 4679  Lsw_scan:
          *      %g4 = lastproc           *      %g4 = lastproc
          *      %g5 = newpcb           *      %g5 = newpcb
          *      %g6 = %hi(cpcb)           *      %g6 = %hi(cpcb)
          *      %g7 = %hi(curproc)           *      %g7 = %hi(curlwp)
          *      %o0 = tmp 1           *      %o0 = tmp 1
          *      %o1 = tmp 2           *      %o1 = tmp 2
          *      %o2 = tmp 3           *      %o2 = tmp 3
Line 4608  Lsw_scan:
Line 4687  Lsw_scan:
          */           */
   
         /* firewalls */          /* firewalls */
         ld      [%g3 + P_WCHAN], %o0    ! if (p->p_wchan)          ld      [%g3 + L_WCHAN], %o0    ! if (p->p_wchan)
         tst     %o0          tst     %o0
         bne     Lsw_panic_wchan         !       panic("switch wchan");          bne     Lsw_panic_wchan         !       panic("switch wchan");
          EMPTY           EMPTY
         ldsb    [%g3 + P_STAT], %o0     ! if (p->p_stat != SRUN)          ld      [%g3 + L_STAT], %o0     ! if (p->p_stat != SRUN)
         cmp     %o0, SRUN          cmp     %o0, LSRUN
         bne     Lsw_panic_srun          !       panic("switch SRUN");          bne     Lsw_panic_srun          !       panic("switch SRUN");
          EMPTY           EMPTY
   
Line 4621  Lsw_scan:
Line 4700  Lsw_scan:
          * Committed to running process p.           * Committed to running process p.
          * It may be the same as the one we were running before.           * It may be the same as the one we were running before.
          */           */
         mov     SONPROC, %o0                    ! p->p_stat = SONPROC;          mov     LSONPROC, %o0                   ! p->p_stat = LSONPROC;
         stb     %o0, [%g3 + P_STAT]          st      %o0, [%g3 + L_STAT]
   
         /* p->p_cpu initialized in fork1() for single-processor */          /* p->p_cpu initialized in fork1() for single-processor */
 #if defined(MULTIPROCESSOR)  #if defined(MULTIPROCESSOR)
         sethi   %hi(_CISELFP), %o0              ! p->p_cpu = cpuinfo.ci_self;          sethi   %hi(_CISELFP), %o0              ! p->p_cpu = cpuinfo.ci_self;
         ld      [%o0 + %lo(_CISELFP)], %o0          ld      [%o0 + %lo(_CISELFP)], %o0
         st      %o0, [%g3 + P_CPU]          st      %o0, [%g3 + L_CPU]
 #endif  #endif
   
         sethi   %hi(_C_LABEL(want_resched)), %o0        ! want_resched = 0;          sethi   %hi(_C_LABEL(want_resched)), %o0        ! want_resched = 0;
Line 4637  Lsw_scan:
Line 4716  Lsw_scan:
         /* Done with the run queues; release the scheduler lock */          /* Done with the run queues; release the scheduler lock */
         SAVE_GLOBALS_AND_CALL(sched_unlock_idle)          SAVE_GLOBALS_AND_CALL(sched_unlock_idle)
 #endif  #endif
         ld      [%g3 + P_ADDR], %g5             ! newpcb = p->p_addr;          ld      [%g3 + L_ADDR], %g5             ! newpcb = p->p_addr;
         st      %g0, [%g3 + 4]                  ! p->p_back = NULL;          st      %g0, [%g3 + 4]                  ! p->p_back = NULL;
         ld      [%g5 + PCB_PSR], %g2            ! newpsr = newpcb->pcb_psr;          ld      [%g5 + PCB_PSR], %g2            ! newpsr = newpcb->pcb_psr;
         st      %g3, [%g7 + %lo(curproc)]       ! curproc = p;          st      %g3, [%g7 + %lo(curlwp)]        ! curlwp = p;
   
         cmp     %g3, %g4                ! p == lastproc?          cmp     %g3, %g4                ! p == lastproc?
         be,a    Lsw_sameproc            ! yes, go return 0          be,a    Lsw_sameproc            ! yes, go return 0
Line 4712  Lsw_load:
Line 4791  Lsw_load:
          * can talk about user space stuff.  (Its pcb_uw is currently           * can talk about user space stuff.  (Its pcb_uw is currently
          * zero so it is safe to have interrupts going here.)           * zero so it is safe to have interrupts going here.)
          */           */
         ld      [%g3 + P_VMSPACE], %o3  ! vm = p->p_vmspace;          mov     1, %o0                  ! return value
           ld      [%g3 + L_PROC], %o3     ! p = l->l_proc;
           ld      [%o3 + P_VMSPACE], %o3  ! vm = p->p_vmspace;
         ld      [%o3 + VM_PMAP], %o3    ! pm = vm->vm_map.vm_pmap;          ld      [%o3 + VM_PMAP], %o3    ! pm = vm->vm_map.vm_pmap;
         ld      [%o3 + PMAP_CTX], %o0   ! if (pm->pm_ctx != NULL)          ld      [%o3 + PMAP_CTX], %o1   ! if (pm->pm_ctx != NULL)
         tst     %o0          tst     %o1
         bnz,a   Lsw_havectx             !       goto havecontext;          bnz,a   Lsw_havectx             !       goto havecontext;
          ld     [%o3 + PMAP_CTXNUM], %o0        ! load context number           ld     [%o3 + PMAP_CTXNUM], %o1        ! load context number
   
         /* p does not have a context: call ctx_alloc to get one */          /* p does not have a context: call ctx_alloc to get one */
         save    %sp, -CCFSZ, %sp          save    %sp, -CCFSZ, %sp
Line 4725  Lsw_load:
Line 4806  Lsw_load:
          mov    %i3, %o0           mov    %i3, %o0
   
         ret          ret
          restore           restore        %g0, 1, %o0     ! set return value to 1
   
         /* p does have a context: just switch to it */          /* p does have a context: just switch to it */
 Lsw_havectx:  Lsw_havectx:
         ! context is in %o0          ! context is in %o1
         ! pmap is in %o3  
 #if (defined(SUN4) || defined(SUN4C)) && defined(SUN4M)  #if (defined(SUN4) || defined(SUN4C)) && defined(SUN4M)
         sethi   %hi(_C_LABEL(cputyp)), %o1      ! what cpu are we running on?  NOP_ON_4M_15:
         ld      [%o1 + %lo(_C_LABEL(cputyp))], %o1          b,a     1f
         cmp     %o1, CPU_SUN4M          b,a     2f
         be      1f  
          nop  
 #endif  #endif
   1:
 #if defined(SUN4) || defined(SUN4C)  #if defined(SUN4) || defined(SUN4C)
         set     AC_CONTEXT, %o1          set     AC_CONTEXT, %o2
         retl          retl
          stba   %o0, [%o1] ASI_CONTROL  ! setcontext(vm->vm_pmap.pm_ctxnum);           stba   %o1, [%o2] ASI_CONTROL  ! setcontext(vm->vm_pmap.pm_ctxnum);
 #endif  #endif
 1:  2:
 #if defined(SUN4M)  #if defined(SUN4M)
         /*          /*
          * Flush caches that need to be flushed on context switch.           * Flush caches that need to be flushed on context switch.
Line 4752  Lsw_havectx:
Line 4831  Lsw_havectx:
         set     CPUINFO_VA+CPUINFO_PURE_VCACHE_FLS, %o2          set     CPUINFO_VA+CPUINFO_PURE_VCACHE_FLS, %o2
         ld      [%o2], %o2          ld      [%o2], %o2
         mov     %o7, %g7        ! save return address          mov     %o7, %g7        ! save return address
         jmpl    %o2, %o7        ! this function must not clobber %o0 and %g7          jmpl    %o2, %o7        ! this function must not clobber %o0,%o1 and %g7
          nop           nop
   
         set     SRMMU_CXR, %o1          set     SRMMU_CXR, %o2
         jmp     %g7 + 8          jmp     %g7 + 8
          sta    %o0, [%o1] ASI_SRMMU    ! setcontext(vm->vm_pmap.pm_ctxnum);           sta    %o1, [%o2] ASI_SRMMU    ! setcontext(vm->vm_pmap.pm_ctxnum);
 #endif  #endif
   
 Lsw_sameproc:  Lsw_sameproc:
Line 4768  Lsw_sameproc:
Line 4847  Lsw_sameproc:
 !       wr      %g2, 0 %psr             ! %psr = newpsr; (done earlier)  !       wr      %g2, 0 %psr             ! %psr = newpsr; (done earlier)
         nop          nop
         retl          retl
          nop           mov    %g0, %o0        ! return value = 0
   
   ENTRY(cpu_preempt)
           /*
            * Like cpu_switch, but we're passed the process to switch to.
            *
            * Use the same register usage convention as in cpu_switch().
            */
           mov     %o0, %g4                        ! lastproc = arg1;
           mov     %o1, %g3                        ! newproc = arg2;
           sethi   %hi(_C_LABEL(sched_whichqs)), %g2       ! set up addr regs
           sethi   %hi(cpcb), %g6
           ld      [%g6 + %lo(cpcb)], %o0
           std     %o6, [%o0 + PCB_SP]             ! cpcb->pcb_<sp,pc> = <sp,pc>;
           rd      %psr, %g1                       ! oldpsr = %psr;
           st      %g1, [%o0 + PCB_PSR]            ! cpcb->pcb_psr = oldpsr;
           andn    %g1, PSR_PIL, %g1               ! oldpsr &= ~PSR_PIL;
           sethi   %hi(curlwp), %g7
           st      %g0, [%g7 + %lo(curlwp)]        ! curlwp = NULL;
   
           /*
            * now set up %o4 (which) and %o5 (p->p_back), and continue with
            * common code in cpu_switch().
            */
           ld      [%g3 + L_PRIORITY], %o4
           srl     %o4, 2, %o4
           ld      [%g3 + 4], %o5          ! %o5 = p->p_back
           b,a     cpu_switch0
   
 /*  /*
  * Snapshot the current process so that stack frames are up to date.   * Snapshot the current process so that stack frames are up to date.
Line 4823  ENTRY(proc_trampoline)
Line 4928  ENTRY(proc_trampoline)
          mov    %l1, %o0           mov    %l1, %o0
   
         /*          /*
          * Here we finish up as in syscall, but simplified.  We need to           * Here we finish up as in syscall, but simplified.
          * fiddle pc and npc a bit, as execve() / setregs() will have           * cpu_fork() or sendsig() (if we took a pending signal
          * set npc only, anticipating that trap.c will advance past the           * in child_return()) will have set the user-space return
          * trap instruction; but we bypass that, so we must do it manually.           * address in tf_pc. In both cases, %npc should be %pc + 4.
          */           */
         mov     PSR_S, %l0              ! user psr (no need to load it)          mov     PSR_S, %l0              ! user psr (no need to load it)
         !?wr    %g0, 2, %wim            ! %wim = 2          !?wr    %g0, 2, %wim            ! %wim = 2
         ld      [%sp + CCFSZ + 8], %l1  ! pc = tf->tf_npc from execve/fork          ld      [%sp + CCFSZ + 4], %l1  ! pc = tf->tf_pc from cpu_fork()
         b       return_from_syscall          b       return_from_syscall
          add    %l1, 4, %l2             ! npc = pc+4           add    %l1, 4, %l2             ! npc = pc+4
   
Line 5834  ENTRY(ienab_bic)
Line 5939  ENTRY(ienab_bic)
  * raise(cpu, level)   * raise(cpu, level)
  */   */
 ENTRY(raise)  ENTRY(raise)
   #if !defined(MSIIEP) /* normal suns */
         ! *(ICR_PI_SET + cpu*_MAXNBPG) = PINTR_SINTRLEV(level)          ! *(ICR_PI_SET + cpu*_MAXNBPG) = PINTR_SINTRLEV(level)
         sethi   %hi(1 << 16), %o2          sethi   %hi(1 << 16), %o2
         sll     %o2, %o1, %o2          sll     %o2, %o1, %o2
Line 5845  ENTRY(raise)
Line 5951  ENTRY(raise)
          add    %o1, %o3, %o1           add    %o1, %o3, %o1
         retl          retl
          st     %o2, [%o1]           st     %o2, [%o1]
   #else /* MSIIEP - ignore %o0, only one cpu ever */
           mov     1, %o2
           sethi   %hi(MSIIEP_PCIC_VA), %o0
           sll     %o2, %o1, %o2
           retl
            sth    %o2, [%o0 + PCIC_SOFT_INTR_SET_REG]
   #endif
   
 /*  /*
  * Read Synchronous Fault Status registers.   * Read Synchronous Fault Status registers.
Line 5951  _ENTRY(_C_LABEL(hypersparc_pure_vcache_f
Line 6063  _ENTRY(_C_LABEL(hypersparc_pure_vcache_f
   
 #endif /* SUN4M */  #endif /* SUN4M */
   
   #if !defined(MSIIEP)    /* normal suns */
 /*  /*
  * void lo_microtime(struct timeval *tv)   * void lo_microtime(struct timeval *tv)
  *   *
Line 6008  NOP_ON_4_4C_1:
Line 6121  NOP_ON_4_4C_1:
         set     1000000, %g5                    ! normalize usec value          set     1000000, %g5                    ! normalize usec value
         cmp     %o3, %g5          cmp     %o3, %g5
         bl,a    4f          bl,a    4f
          st     %o2, [%o0]                      ! (should be able to std here)           st     %o2, [%o0]
         add     %o2, 1, %o2                     ! overflow          add     %o2, 1, %o2                     ! overflow
         sub     %o3, %g5, %o3          sub     %o3, %g5, %o3
         st      %o2, [%o0]                      ! (should be able to std here)          st      %o2, [%o0]
 4:  4:
         retl          retl
          st     %o3, [%o0+4]           st     %o3, [%o0+4]
   
   #else /* MSIIEP */
   /* XXX: uwe: can be merged with 4c/4m version above */
   /*
    * ms-IIep version of
    * void microtime(struct timeval *tv)
    *
    * This is similar to 4c/4m microtime.   The difference is that
    * counter uses 31 bits and ticks every 4 CPU cycles (cpu is @100MHz)
    * the magic to divide by 25 is stolen from gcc
    */
   ENTRY(microtime)
           sethi   %hi(_C_LABEL(time)), %g2
   
           sethi   %hi(MSIIEP_PCIC_VA), %g3
           or      %g3, PCIC_SCCR_REG, %g3
   
   2:
           ldd     [%g2+%lo(_C_LABEL(time))], %o2  ! time.tv_sec & time.tv_usec
           ld      [%g3], %o4                      ! system (timer) counter
           ldd     [%g2+%lo(_C_LABEL(time))], %g4  ! see if time values changed
           cmp     %g4, %o2
           bne     2b                              ! if time.tv_sec changed
            cmp    %g5, %o3
           bne     2b                              ! if time.tv_usec changed
            tst    %o4
           !! %o2 - time.tv_sec;  %o3 - time.tv_usec;  %o4 - timer counter
   
   !!! BEGIN ms-IIep specific code
           bpos    3f                              ! if limit not reached yet
            clr    %g4                             !  then use timer as is
   
           set     0x80000000, %g5
           sethi   %hi(_C_LABEL(tick)), %g4
           bclr    %g5, %o4                        ! cleat limit reached flag
           ld      [%g4+%lo(_C_LABEL(tick))], %g4
   
           !! %g4 - either 0 or tick (if timer has hit the limit)
   3:
           inc     -1, %o4                         ! timer is 1-based, adjust
           !! divide by 25 magic stolen from a gcc output
           set     1374389535, %g5
           umul    %o4, %g5, %g0
           rd      %y, %o4
           srl     %o4, 3, %o4
           add     %o4, %g4, %o4                   ! may be bump usec by tick
   !!! END ms-IIep specific code
   
           add     %o3, %o4, %o3                   ! add timer to time.tv_usec
           set     1000000, %g5                    ! normalize usec value
           cmp     %o3, %g5
           bl,a    4f
            st     %o2, [%o0]
           inc     %o2                             ! overflow into tv_sec
           sub     %o3, %g5, %o3
           st      %o2, [%o0]
   4:      retl
            st     %o3, [%o0 + 4]
   #endif /* MSIIEP */
   
 /*  /*
  * delay function   * delay function
  *   *
Line 6120  Llongjmpbotch:
Line 6292  Llongjmpbotch:
          mov    %g6, %o0           mov    %g6, %o0
   
         .data          .data
 #ifdef DDB          .globl  _C_LABEL(kernel_top)
         .globl  _C_LABEL(esym)  _C_LABEL(kernel_top):
 _C_LABEL(esym):  
         .word   0          .word   0
 #endif  
         .globl  _C_LABEL(bootinfo)          .globl  _C_LABEL(bootinfo)
 _C_LABEL(bootinfo):  _C_LABEL(bootinfo):
         .word   0          .word   0

Legend:
Removed from v.1.148  
changed lines
  Added in v.1.148.4.11

CVSweb <webmaster@jp.NetBSD.org>