1
2
3
4
5
6 #ifndef _SPARC_ASMMACRO_H
7 #define _SPARC_ASMMACRO_H
8
9
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
33
34
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
67
68
69
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
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
206
207 #endif