Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/arch/sparc/kernel/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 8 kB image not shown  

Quelle  etrap_32.S   Sprache: Sparc

 
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * etrap.S: Sparc trap window preparation for entry into the
 *          Linux kernel.
 *
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
 */


#include <asm/head.h>
#include <asm/asi.h>
#include <asm/contregs.h>
#include <asm/page.h>
#include <asm/psr.h>
#include <asm/ptrace.h>
#include <asm/winmacro.h>
#include <asm/asmmacro.h>
#include <asm/thread_info.h>

/* Registers to not touch at all. */
#define t_psr        l0 /* Set by caller */
#define t_pc         l1 /* Set by caller */
#define t_npc        l2 /* Set by caller */
#define t_wim        l3 /* Set by caller */
#define t_twinmask   l4 /* Set at beginning of this entry routine. */
#define t_kstack     l5 /* Set right before pt_regs frame is built */
#define t_retpc      l6 /* If you change this, change winmacro.h header file */
#define t_systable   l7 /* Never touch this, could be the syscall table ptr. */
#define curptr       g6 /* Set after pt_regs frame is built */

 .text
 .align 4

 /* SEVEN WINDOW PATCH INSTRUCTIONS */
 .globl tsetup_7win_patch1, tsetup_7win_patch2
 .globl tsetup_7win_patch3, tsetup_7win_patch4
 .globl tsetup_7win_patch5, tsetup_7win_patch6
tsetup_7win_patch1: sll %t_wim, 0x6, %t_wim
tsetup_7win_patch2: and %g2, 0x7f, %g2
tsetup_7win_patch3: and %g2, 0x7f, %g2
tsetup_7win_patch4: and %g1, 0x7f, %g1
tsetup_7win_patch5: sll %t_wim, 0x6, %t_wim
tsetup_7win_patch6: and %g2, 0x7f, %g2
 /* END OF PATCH INSTRUCTIONS */

 /* At trap time, interrupts and all generic traps do the
 * following:
 *
 * rd %psr, %l0
 * b some_handler
 * rd %wim, %l3
 * nop
 *
 * Then 'some_handler' if it needs a trap frame (ie. it has
 * to call c-code and the trap cannot be handled in-window)
 * then it does the SAVE_ALL macro in entry.S which does
 *
 * sethi %hi(trap_setup), %l4
 * jmpl %l4 + %lo(trap_setup), %l6
 * nop
 */


 /* 2 3 4  window number
 * -----
 * O T S  mnemonic
 *
 * O == Current window before trap
 * T == Window entered when trap occurred
 * S == Window we will need to save if (1<<T) == %wim
 *
 * Before execution gets here, it must be guaranteed that
 * %l0 contains trap time %psr, %l1 and %l2 contain the
 * trap pc and npc, and %l3 contains the trap time %wim.
 */


 .globl trap_setup, tsetup_patch1, tsetup_patch2
 .globl tsetup_patch3, tsetup_patch4
 .globl tsetup_patch5, tsetup_patch6
trap_setup:
 /* Calculate mask of trap window.  See if from user
 * or kernel and branch conditionally.
 */

 mov 1, %t_twinmask
 andcc %t_psr, PSR_PS, %g0   ! fromsupv_p = (psr & PSR_PS)
 be trap_setup_from_user   ! nope, from user mode
  sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)

 /* From kernel, allocate more kernel stack and
 * build a pt_regs trap frame.
 */

 sub %fp, (STACKFRAME_SZ + TRACEREG_SZ), %t_kstack
 STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)

 /* See if we are in the trap window. */
 andcc %t_twinmask, %t_wim, %g0
 bne trap_setup_kernel_spill  ! in trap window, clean up
  nop

 /* Trap from kernel with a window available.
 * Just do it...
 */

 jmpl %t_retpc + 0x8, %g0 ! return to caller
  mov %t_kstack, %sp  ! jump onto new stack

trap_setup_kernel_spill:
 ld [%curptr + TI_UWINMASK], %g1
 orcc %g0, %g1, %g0
 bne trap_setup_user_spill ! there are some user windows, yuck
 /* Spill from kernel, but only kernel windows, adjust
 * %wim and go.
 */

  srl %t_wim, 0x1, %g2 ! begin computation of new %wim
tsetup_patch1:
 sll %t_wim, 0x7, %t_wim ! patched on 7 window Sparcs
 or %t_wim, %g2, %g2
tsetup_patch2:
 and %g2, 0xff, %g2  ! patched on 7 window Sparcs

 save %g0, %g0, %g0

 /* Set new %wim value */
 wr %g2, 0x0, %wim

 /* Save the kernel window onto the corresponding stack. */
 STORE_WINDOW(sp)

 restore %g0, %g0, %g0

 jmpl %t_retpc + 0x8, %g0 ! return to caller
  mov %t_kstack, %sp  ! and onto new kernel stack

#define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - STACKFRAME_SZ)

trap_setup_from_user:
 /* We can't use %curptr yet. */
 LOAD_CURRENT(t_kstack, t_twinmask)

 sethi %hi(STACK_OFFSET), %t_twinmask
 or %t_twinmask, %lo(STACK_OFFSET), %t_twinmask
 add %t_kstack, %t_twinmask, %t_kstack

 mov 1, %t_twinmask
 sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)

 /* Build pt_regs frame. */
 STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)

#if 0
 /* If we're sure every task_struct is THREAD_SIZE aligned,
   we can speed this up. */

 sethi %hi(STACK_OFFSET), %curptr
 or %curptr, %lo(STACK_OFFSET), %curptr
 sub %t_kstack, %curptr, %curptr
#else
 sethi %hi(~(THREAD_SIZE - 1)), %curptr
 and %t_kstack, %curptr, %curptr
#endif

 /* Clear current_thread_info->w_saved */
 st %g0, [%curptr + TI_W_SAVED]

 /* See if we are in the trap window. */
 andcc %t_twinmask, %t_wim, %g0
 bne trap_setup_user_spill  ! yep we are
  orn %g0, %t_twinmask, %g1  ! negate trap win mask into %g1

 /* Trap from user, but not into the invalid window.
 * Calculate new umask.  The way this works is,
 * any window from the %wim at trap time until
 * the window right before the one we are in now,
 * is a user window.  A diagram:
 *
 *      7 6 5 4 3 2 1 0    window number
 *      ---------------
 *        I     L T        mnemonic
 *
 * Window 'I' is the invalid window in our example,
 * window 'L' is the window the user was in when
 * the trap occurred, window T is the trap window
 * we are in now.  So therefore, windows 5, 4 and
 * 3 are user windows.  The following sequence
 * computes the user winmask to represent this.
 */

 subcc %t_wim, %t_twinmask, %g2
 bneg,a 1f
  sub %g2, 0x1, %g2
1:
 andn %g2, %t_twinmask, %g2
tsetup_patch3:
 and %g2, 0xff, %g2   ! patched on 7win Sparcs
 st %g2, [%curptr + TI_UWINMASK] ! store new umask

 jmpl %t_retpc + 0x8, %g0  ! return to caller
  mov %t_kstack, %sp   ! and onto kernel stack

trap_setup_user_spill:
 /* A spill occurred from either kernel or user mode
 * and there exist some user windows to deal with.
 * A mask of the currently valid user windows
 * is in %g1 upon entry to here.
 */


tsetup_patch4:
 and %g1, 0xff, %g1  ! patched on 7win Sparcs, mask
 srl %t_wim, 0x1, %g2 ! compute new %wim
tsetup_patch5:
 sll %t_wim, 0x7, %t_wim ! patched on 7win Sparcs
 or %t_wim, %g2, %g2 ! %g2 is new %wim
tsetup_patch6:
 and %g2, 0xff, %g2  ! patched on 7win Sparcs
 andn %g1, %g2, %g1  ! clear this bit in %g1
 st %g1, [%curptr + TI_UWINMASK]

 save %g0, %g0, %g0

 wr %g2, 0x0, %wim

 /* Call MMU-architecture dependent stack checking
 * routine.
 */

 b tsetup_srmmu_stackchk
  andcc %sp, 0x7, %g0

 /* Architecture specific stack checking routines.  When either
 * of these routines are called, the globals are free to use
 * as they have been safely stashed on the new kernel stack
 * pointer.  Thus the definition below for simplicity.
 */

#define glob_tmp     g1

 .globl tsetup_srmmu_stackchk
tsetup_srmmu_stackchk:
 /* Check results of callers andcc %sp, 0x7, %g0 */
 bne trap_setup_user_stack_is_bolixed
  sethi   %hi(PAGE_OFFSET), %glob_tmp

 cmp %glob_tmp, %sp
 bleu,a 1f
LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp)  ! read MMU control

trap_setup_user_stack_is_bolixed:
 /* From user/kernel into invalid window w/bad user
 * stack. Save bad user stack, and return to caller.
 */

 SAVE_BOLIXED_USER_STACK(curptr, g3)
 restore %g0, %g0, %g0

 jmpl %t_retpc + 0x8, %g0
  mov %t_kstack, %sp

1:
 /* Clear the fault status and turn on the no_fault bit. */
 or %glob_tmp, 0x2, %glob_tmp  ! or in no_fault bit
LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)  ! set it
SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)  ! set it

 /* Dump the registers and cross fingers. */
 STORE_WINDOW(sp)

 /* Clear the no_fault bit and check the status. */
 andn %glob_tmp, 0x2, %glob_tmp
LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)

 mov AC_M_SFAR, %glob_tmp
LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)

 mov AC_M_SFSR, %glob_tmp
LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore
SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore

 andcc %glob_tmp, 0x2, %g0   ! did we fault?
 bne trap_setup_user_stack_is_bolixed ! failure
  nop

 restore %g0, %g0, %g0

 jmpl %t_retpc + 0x8, %g0
  mov %t_kstack, %sp


Messung V0.5
C=76 H=100 G=88

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.