root/include/asm-sparc/asmmacro.h

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

INCLUDED FROM


   1 /* asmmacro.h: Assembler macros.
   2  *
   3  * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
   4  */
   5 
   6 #ifndef _SPARC_ASMMACRO_H
   7 #define _SPARC_ASMMACRO_H
   8 
   9 /* #define SMP_DEBUG */
  10 
  11 #define GET_PROCESSOR_ID(reg) \
  12         rd      %tbr, %reg; \
  13         srl     %reg, 12, %reg; \
  14         and     %reg, 3, %reg;
  15 
  16 #define GET_PROCESSOR_MID(reg, tmp) \
  17         GET_PROCESSOR_ID(reg) \
  18         set     C_LABEL(mid_xlate), %tmp; \
  19         ldub    [%tmp + %reg], %reg;
  20 
  21 #define GET_PROCESSOR_OFFSET(reg) \
  22         rd      %tbr, %reg; \
  23         srl     %reg, 10, %reg; \
  24         and     %reg, 0xc, %reg;
  25 
  26 #define PROCESSOR_OFFSET_TO_ID(reg) \
  27         srl     %reg, 2, %reg;
  28 
  29 #define PROCESSOR_ID_TO_OFFSET(reg) \
  30         sll     %reg, 2, %reg;
  31 
  32 /* All trap entry points _must_ begin with this macro or else you
  33  * lose.  It makes sure the kernel has a proper window so that
  34  * c-code can be called.
  35  */
  36 #ifndef SMP_DEBUG
  37 #define SAVE_ALL \
  38         sethi   %hi(trap_setup), %l4; \
  39         jmpl    %l4 + %lo(trap_setup), %l6; \
  40          nop;
  41 #else
  42 #define SAVE_ALL \
  43         GET_PROCESSOR_ID(l4); \
  44         set     C_LABEL(trap_log), %l5; \
  45         sll     %l4, 11, %l6; \
  46         add     %l5, %l6, %l5; \
  47         set     C_LABEL(trap_log_ent), %l6; \
  48         sll     %l4, 2, %l4; \
  49         add     %l6, %l4, %l6; \
  50         ld      [%l6], %l6; \
  51         sll     %l6, 3, %l6; \
  52         st      %l1, [%l5 + %l6]; \
  53         add     %l5, 4, %l5; \
  54         st      %l0, [%l5 + %l6]; \
  55         set     C_LABEL(trap_log_ent), %l5; \
  56         add     %l5, %l4, %l5; \
  57         srl     %l6, 3, %l6; \
  58         add     %l6, 1, %l6; \
  59         and     %l6, 255, %l6; \
  60         st      %l6, [%l5]; \
  61         sethi   %hi(trap_setup), %l4; \
  62         jmpl    %l4 + %lo(trap_setup), %l6; \
  63          nop;
  64 #endif
  65 
  66 /* All traps low-level code here must end with this macro.
  67  * For SMP configurations the ret_trap_entry routine will
  68  * have to appropriate code to actually release the kernel
  69  * entry lock.
  70  */
  71 #define RESTORE_ALL \
  72         b       ret_trap_entry; \
  73          nop;
  74 
  75 #ifndef __SMP__
  76 
  77 #define ENTER_SYSCALL
  78 #define LEAVE_SYSCALL
  79 #define ENTER_IRQ
  80 #define LEAVE_IRQ
  81 
  82 #else
  83 
  84 #define INCREMENT_COUNTER(symbol, tmp1, tmp2) \
  85         set     C_LABEL(symbol), %tmp1; \
  86         ld      [%tmp1], %tmp2; \
  87         add     %tmp2, 1, %tmp2; \
  88         st      %tmp2, [%tmp1];
  89 
  90 #define DECREMENT_COUNTER(symbol, tmp1, tmp2) \
  91         set     C_LABEL(symbol), %tmp1; \
  92         ld      [%tmp1], %tmp2; \
  93         sub     %tmp2, 1, %tmp2; \
  94         st      %tmp2, [%tmp1];
  95 
  96         /* This is so complicated I suggest you don't look at it. */
  97 #define ENTER_MASK(mask) \
  98         GET_PROCESSOR_OFFSET(l4) \
  99         set     C_LABEL(smp_spinning), %l6; \
 100         add     %l6, %l4, %l6; \
 101         mov     1, %l5; \
 102         st      %l5, [%l6]; \
 103         set     C_LABEL(smp_proc_in_lock), %l5; \
 104         ld      [%l5 + %l4], %l6; \
 105         or      %l6, mask, %l6; \
 106         st      %l6, [%l5 + %l4]; \
 107 1: \
 108         set     C_LABEL(kernel_flag), %l5; \
 109         ldstub  [%l5], %l6; \
 110         cmp     %l6, 0; \
 111         be      3f; \
 112          nop; \
 113         set     C_LABEL(active_kernel_processor), %l5; \
 114         GET_PROCESSOR_ID(l4) \
 115         ldub    [%l5], %l6; \
 116         cmp     %l6, %l4; \
 117         be      4f; \
 118          nop; \
 119 2: \
 120         GET_PROCESSOR_MID(l4, l5) \
 121         set     C_LABEL(sun4m_interrupts), %l5; \
 122         ld      [%l5], %l5; \
 123         sll     %l4, 12, %l4; \
 124         add     %l5, %l4, %l5; \
 125         ld      [%l5], %l4; \
 126         sethi   %hi(0x80000000), %l6; \
 127         andcc   %l6, %l4, %g0; \
 128         be      5f; \
 129          nop; \
 130         st      %l6, [%l5 + 4]; \
 131         nop; nop; nop; \
 132         ld      [%l5], %g0; \
 133         nop; nop; nop; \
 134         or      %l0, PSR_PIL, %l4; \
 135         wr      %l4, 0x0, %psr; \
 136         nop; nop; nop; \
 137         wr      %l4, PSR_ET, %psr; \
 138         nop; nop; nop; \
 139         call    C_LABEL(smp_message_irq); \
 140          nop; \
 141         wr      %l0, 0x0, %psr; \
 142         nop; nop; nop; \
 143 5: \
 144         set     C_LABEL(kernel_flag), %l5; \
 145         ldub    [%l5], %l6; \
 146         cmp     %l6, 0; \
 147         bne     2b; \
 148          nop; \
 149         b       1b; \
 150          nop; \
 151 3: \
 152         GET_PROCESSOR_ID(l4) \
 153         set     C_LABEL(active_kernel_processor), %l5; \
 154         stb     %l4, [%l5]; \
 155         GET_PROCESSOR_MID(l4, l5) \
 156         set     C_LABEL(irq_rcvreg), %l5; \
 157         ld      [%l5], %l5; \
 158         st      %l4, [%l5]; \
 159 4: \
 160         GET_PROCESSOR_OFFSET(l4) \
 161         set     C_LABEL(smp_spinning), %l6; \
 162         st      %g0, [%l6 + %l4];
 163 
 164 #define ENTER_SYSCALL \
 165         ENTER_MASK(SMP_FROM_SYSCALL) \
 166         INCREMENT_COUNTER(kernel_counter, l6, l5) \
 167         INCREMENT_COUNTER(syscall_count, l6, l5)
 168 
 169 #define ENTER_IRQ \
 170         ENTER_MASK(SMP_FROM_INT) \
 171         INCREMENT_COUNTER(kernel_counter, l6, l5)
 172 
 173 #define LEAVE_MASK(mask) \
 174         GET_PROCESSOR_OFFSET(l4) \
 175         set     C_LABEL(smp_proc_in_lock), %l5; \
 176         ld      [%l5 + %l4], %l6; \
 177         andn    %l6, mask, %l6; \
 178         st      %l6, [%l5 + %l4];
 179 
 180 #define LEAVE_SYSCALL \
 181         LEAVE_MASK(SMP_FROM_SYSCALL) \
 182         DECREMENT_COUNTER(syscall_count, l6, l5) \
 183         set     C_LABEL(kernel_counter), %l6; \
 184         ld      [%l6], %l5; \
 185         subcc   %l5, 1, %l5; \
 186         st      %l5, [%l6]; \
 187         bne     1f; \
 188          nop; \
 189         set     C_LABEL(active_kernel_processor), %l6; \
 190         mov     NO_PROC_ID, %l5; \
 191         stb     %l5, [%l6]; \
 192         set     C_LABEL(kernel_flag), %l6; \
 193         stb     %g0, [%l6]; \
 194 1:
 195 
 196 #define LEAVE_IRQ \
 197         LEAVE_MASK(SMP_FROM_INT) \
 198         INCREMENT_COUNTER(syscall_count, l6, l5)
 199 
 200 
 201 #define RESTORE_ALL_FASTIRQ \
 202         b       ret_irq_entry; \
 203          nop;
 204 
 205 #endif /* !(__SMP__) */
 206 
 207 #endif /* !(_SPARC_ASMMACRO_H) */

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