root/arch/sparc/kernel/entry.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /* arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
   2  *
   3  * Sparc traps are so ugly, this code is going to go through a lot
   4  * of changes as I find out more interesting things. See head.S for
   5  * the trap table and how it works, this will show you how we get
   6  * to these routines.
   7  *
   8  * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
   9  */
  10 
  11 #include <asm/head.h>
  12 
  13         .text
  14         .align 4
  15 
  16 /* Default trap handler */
  17         .globl my_trap_handler
  18 my_trap_handler:
  19                 rd %wim, %l4
  20                 or %g0, 0x1, %l5
  21                 sll %l5, %l0, %l5
  22                 cmp %l4, %l5        ! are we in the invalid register?
  23         
  24 #if 0 /* work in progress */
  25                 be wash_trap_win
  26 #endif
  27 
  28                 nop
  29                 or %%g0, %l3, %o0
  30                 call _do_hw_interrupt
  31                 or %%g0, %%g0, %o1
  32                 wr %l0, 0x20, %psr  ! re-enable traps and reset the condition codes
  33                 nop
  34                 nop
  35                 nop                 ! click our heels three times, "no place like home"
  36                 jmp %l1
  37                 rett %l2
  38         
  39 /* This is cheese and only works reliably if not coming from userland. */
  40         .globl fill_window_entry
  41 fill_window_entry:
  42         wr      %g0, 0, %wim            ! let us into the invalid window
  43                                         ! without inducing another trap
  44         restore
  45         nop
  46         nop                             ! no guarentees until 3 insns later
  47         restore
  48         restore %g0, 1, %l1
  49         rd      %psr, %l0
  50         sll     %l1, %l0, %l0
  51         wr      %l0, 0, %wim
  52         save    %g0, %g0, %g0
  53 
  54 /* load up the window */
  55         ldd     [%sp], %l0
  56         ldd     [%sp + 8], %l2
  57         ldd     [%sp + 16], %l4
  58         ldd     [%sp + 24], %l6
  59         ldd     [%sp + 32], %i0
  60         ldd     [%sp + 40], %i2
  61         ldd     [%sp + 48], %i4
  62         ldd     [%sp + 56], %i6
  63 
  64         save    %g0, %g0, %g0
  65         save    %g0, %g0, %g0
  66         jmp     %l1
  67         rett    %l2
  68 
  69 /* Cheese number two, give this a bad stack pointer and get scared. */
  70         .globl spill_window_entry
  71 spill_window_entry:
  72         save    %g0, %g0, %g0  ! save into next 'valid' window
  73         std     %l0, [%sp]     ! acquire some scratch registers
  74         rd      %psr, %l0
  75         or      %g0, 0x1, %l1
  76         sll     %l1, %l0, %l0
  77         wr      %l0, 0, %wim   ! make window we are saving the 'invalid' one
  78         std     %l2, [%sp + 8]
  79         std     %l4, [%sp + 16]
  80         std     %l6, [%sp + 24]
  81         std     %i0, [%sp + 32]
  82         std     %i2, [%sp + 40]
  83         std     %i4, [%sp + 48]
  84         std     %i6, [%sp + 56]
  85         restore                ! restore back into the window we want to use
  86         jmp     %l1
  87         rett    %l2            ! return from spill handler
  88 
  89 
  90 /* This is where most generic traps enter, the registers should be:
  91         %l0 == %psr
  92         %l1 == %pc
  93         %l2 == %npc
  94         %l4 == trap_type
  95         %l7 == trap_handler
  96 */
  97 
  98 trap_entry:
  99         srl     %l0, 0x6, %l5   ! shift over to previous priv bit
 100         andcc   %l5, 0x1, %g0   ! 1 == from kernel 0 == from user
 101         bz      2f
 102         nop                     ! we dont handle users yet ;-(
 103         
 104         or      %g0, 0x1, %l5
 105         sll     %l5, %l0, %l5   ! a trick, only least 5 bits are
 106                                 ! significant in a register shift
 107                                 ! count.
 108         rd      %wim, %l6
 109         andcc   %l6, %l5, %g0   ! if (((1<<CWP)&(%wim))==1) we are
 110                                 ! in an 'invalid' window
 111         bz,a    3f
 112         sub     %fp, C_STACK+80, %sp ! cool, just set stack and go
 113                                      ! this window is valid to use
 114         
 115 /* we aparently need to clean the trap window, inline this for speed */ 
 116         or      %g0, %g7, %l7   ! set up g6 and g7 for scratch
 117         or      %g0, %g6, %l6   
 118         
 119         save    %g0, %g0, %g0   ! enter next window after the invalid one
 120         std     %l0, [%sp]      ! and store it on the stack for later
 121         std     %l2, [%sp + 8]  ! retrieval
 122         std     %l4, [%sp + 16]
 123         std     %l6, [%sp + 24]
 124         std     %i0, [%sp + 32]
 125         std     %i2, [%sp + 40]
 126         std     %i4, [%sp + 48]
 127         std     %i6, [%sp + 56]
 128 
 129         rd      %psr, %g7       ! read the current window pointer
 130         or      %g0, 0x1, %g6   ! and mask it over into the %wim
 131         sll     %g6, %g7, %g6   ! value
 132         wr      %g6, 0, %wim    ! make this window the now 'invalid' one
 133         and     %g6, 31, %g6
 134         restore                 ! re-enter the trap window, it is ok now
 135 
 136         or      %g0, %l6, %g6   ! bring back in the old temporaries
 137         or      %g0, %l7, %g7   ! to the locals they were in
 138 
 139         b       3f
 140         sub     %fp, C_STACK+80, %sp ! fix stack pointer
 141 
 142         
 143 /* for now if we get a from-user trap you lose... */
 144 
 145         .data
 146         .align 4
 147 
 148 tfu_youlose:    .asciz "trap from userland, you lose...\n"
 149         
 150         .align 4
 151         .text
 152 
 153 2:      
 154         sethi   %hi(tfu_youlose), %o0
 155         sethi   %hi(prom_printf), %o1
 156         ld      [%o1 + %lo(prom_printf)], %o1
 157         call    %o1     
 158         or      %o0, %lo(tfu_youlose), %o0
 159         
 160         sethi   %hi(prom_halt), %o1
 161         ld      [%o1 + %lo(prom_halt)], %o1
 162         call    %o1                             ! its over
 163         nop
 164         
 165 /* nop and just return, here is where I would jump to the
 166  * appropriate handler.
 167  */
 168 
 169         jmp %1
 170         rett %l2
 171         nop

/* [previous][next][first][last][top][bottom][index][help] */